diff --git a/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py b/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py index 49224ecc5..bc2966aee 100644 --- a/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py +++ b/apps/api/src/jobs/awooop_ansible_candidate_backfill_job.py @@ -193,7 +193,9 @@ async def verify_ansible_candidate_pre_decision_evidence( AND NULLIF(recent_logs, '') IS NOT NULL AND EXISTS ( SELECT 1 - FROM jsonb_each(coalesce(mcp_health, '{}'::jsonb)) health + FROM jsonb_each( + coalesce(CAST(mcp_health AS jsonb), '{}'::jsonb) + ) health WHERE health.value = 'true'::jsonb ) ) diff --git a/apps/api/tests/test_awooop_ansible_candidate_backfill_job.py b/apps/api/tests/test_awooop_ansible_candidate_backfill_job.py index 32d993825..c3162cd97 100644 --- a/apps/api/tests/test_awooop_ansible_candidate_backfill_job.py +++ b/apps/api/tests/test_awooop_ansible_candidate_backfill_job.py @@ -160,6 +160,46 @@ async def test_backfill_retries_automatically_when_predecision_evidence_is_incom recorder.assert_not_awaited() +@pytest.mark.asyncio +async def test_predecision_verifier_casts_json_health_to_jsonb( + monkeypatch: pytest.MonkeyPatch, +) -> None: + from src.jobs import awooop_ansible_candidate_backfill_job as job + + statements: list[str] = [] + + class ScalarResult: + def scalar(self): + return True + + class FakeDb: + async def execute(self, statement, _parameters): + statements.append(str(statement)) + return ScalarResult() + + @asynccontextmanager + async def fake_db_context(project_id: str = "awoooi"): + assert project_id == "awoooi" + yield FakeDb() + + monkeypatch.setattr(job, "get_db_context", fake_db_context) + snapshot = MagicMock( + snapshot_id="evidence-1", + incident_id="INC-20260627-NODE110", + sensors_succeeded=1, + recent_logs="sanitized logs", + mcp_health={"ssh_diagnose": True}, + ) + + verified = await job.verify_ansible_candidate_pre_decision_evidence( + snapshot=snapshot, + project_id="awoooi", + ) + + assert verified is True + assert "CAST(mcp_health AS jsonb)" in statements[0] + + @pytest.mark.asyncio async def test_backfill_skips_when_worker_disabled(monkeypatch: pytest.MonkeyPatch) -> None: from src.jobs import awooop_ansible_candidate_backfill_job as job