from argparse import Namespace from investibook.db import queries as dbq from investibook.scripts import reconcile_eval_running_state as reconcile def test_reconcile_only_invalidates_running_cases_and_preserves_completed_cases(tmp_path, monkeypatch): data_dir = tmp_path / "data" db_path = data_dir / "db" / "investibook.db" db_path.parent.mkdir(parents=True) monkeypatch.setattr(dbq, "DB_PATH", db_path) monkeypatch.setattr(reconcile, "DATA_DIR", data_dir) dbq._db_init() dbq._db_insert_eval_run( { "id": "evalrun-1", "suite_id": "core-daily-demo", "suite_version": "suite-v1", "registry_revision": "git-1", "trigger_mode": "manual_suite", "execution_status": "running", "comparison_status": "review_only", "promote_eligibility": "not_evaluated", "started_at": "2026-05-01T00:00:00+00:00", "case_count": 2, "summary": {"execution_mode": "acp"}, } ) dbq._db_insert_eval_case_run( { "id": "case-completed", "run_id": "evalrun-1", "case_id": "component-restart-during-incident-window", "case_version": "case-v1", "execution_status": "completed", "comparison_status": "review_only", "started_at": "2026-05-01T00:00:00+00:00", "finished_at": "2026-05-01T00:01:00+00:00", "summary": {"workspace_id": "ws-1"}, } ) dbq._db_insert_eval_judgment( { "id": "judge-pass", "case_run_id": "case-completed", "judgment_verdict": "pass", "passed_checks": 1, "total_checks": 1, "facts": {}, "packet": {}, "audit": {}, } ) dbq._db_insert_eval_case_run( { "id": "case-running", "run_id": "evalrun-1", "case_id": "service-degradation-during-incident-window", "case_version": "case-v1", "execution_status": "running", "comparison_status": "review_only", "started_at": "2026-05-01T00:00:00+00:00", "summary": {"workspace_id": "ws-2"}, } ) monkeypatch.setattr( reconcile, "_parse_args", lambda: Namespace(case="", older_than_minutes=1, apply=True, registry_root=None), ) monkeypatch.setattr(reconcile, "load_case", lambda case_id, registry_root=None: object()) monkeypatch.setattr(reconcile, "_followup_policy_key", lambda case: "scheduled_max_followups:0") assert reconcile.main() == 0 completed_case = dbq._db_get_eval_case_run("case-completed") running_case = dbq._db_get_eval_case_run("case-running") run = dbq._db_get_eval_run_detail("evalrun-1") assert completed_case is not None assert completed_case["execution_status"] == "completed" assert running_case is not None assert running_case["execution_status"] == "invalid" assert run is not None assert run["execution_status"] == "completed" assert run["passed_count"] == 1 assert run["failed_count"] == 0 assert run["invalid_count"] == 1