diff --git a/apps/api/src/services/awooop_truth_chain_service.py b/apps/api/src/services/awooop_truth_chain_service.py index e33266f41..c733ffcea 100644 --- a/apps/api/src/services/awooop_truth_chain_service.py +++ b/apps/api/src/services/awooop_truth_chain_service.py @@ -619,7 +619,11 @@ def _truth_status( if gateway_mcp_total == 0: blockers.append("awooop_mcp_gateway_audit_empty") - if legacy_mcp_total == 0 and incident is not None: + # The first-class gateway is the authoritative MCP audit path. The + # retired legacy bridge may be absent without blocking an incident that + # already has gateway receipts; requiring both would turn a superseded + # compatibility path into a permanent false blocker. + if gateway_mcp_total == 0 and legacy_mcp_total == 0 and incident is not None: blockers.append("legacy_mcp_audit_missing") if outbound_visible_total == 0: blockers.append("outbound_mirror_not_visible_for_source") diff --git a/apps/api/tests/test_awooop_truth_chain_service.py b/apps/api/tests/test_awooop_truth_chain_service.py index 5035b449c..5fdeac667 100644 --- a/apps/api/tests/test_awooop_truth_chain_service.py +++ b/apps/api/tests/test_awooop_truth_chain_service.py @@ -318,6 +318,42 @@ def test_truth_status_keeps_verified_controlled_apply_autonomous_when_incident_o assert "incident_open_after_successful_execution" in status["blockers"] +def test_truth_status_does_not_require_retired_legacy_mcp_when_gateway_has_receipts() -> None: + status = _truth_status( + incident={"incident_id": "INC-FIRST-CLASS-MCP", "status": "RESOLVED"}, + approvals=[], + evidence_rows=[], + automation_ops=[], + drift=None, + drift_repeat_count=0, + gateway_mcp_total=3, + legacy_mcp_total=0, + outbound_visible_total=1, + auto_repair_executions=[], + ) + + assert "awooop_mcp_gateway_audit_empty" not in status["blockers"] + assert "legacy_mcp_audit_missing" not in status["blockers"] + + +def test_truth_status_keeps_mcp_gap_when_no_audit_path_has_receipts() -> None: + status = _truth_status( + incident={"incident_id": "INC-NO-MCP", "status": "INVESTIGATING"}, + approvals=[], + evidence_rows=[], + automation_ops=[], + drift=None, + drift_repeat_count=0, + gateway_mcp_total=0, + legacy_mcp_total=0, + outbound_visible_total=1, + auto_repair_executions=[], + ) + + assert "awooop_mcp_gateway_audit_empty" in status["blockers"] + assert "legacy_mcp_audit_missing" in status["blockers"] + + def test_truth_status_marks_repeated_pending_drift_as_human_needed() -> None: status = _truth_status( incident=None,