From 30cffa2de715f5039469de0a0534f8cea3cd6695 Mon Sep 17 00:00:00 2001 From: JasonBuildAI Date: Sun, 18 Oct 2026 16:05:59 +0800 Subject: [PATCH 1/4] fix(quota): fail closed when the Goal's active state is missing `loopx status` reports a per-goal `state_file_missing` finding with the reconnect/retire repair, but `loopx quota should-run --goal-id` still returned should_run=true with normal delivery allowed and a required read of the missing ACTIVE_GOAL_STATE.md. `goal_status_health_ok` only consulted the status contract diagnostics and `global_registry.ok`, so an automatic host turn kept being authorized for a Goal that has no state to advance. Treat the per-goal `state_file_missing` finding as a status health failure. Source-registry provenance findings are deliberately shadowed by the status projection and stay non-blocking. Before/after on a native Windows source checkout at a54c030ee: a Goal whose state file was deleted returned status_health_ok=true, decision=run, should_run=true, normal_delivery_allowed=true; the same command now returns status_health_ok=false, decision=skip, should_run=false, and a healthy Goal still returns run. The two new regressions fail without the fix and pass with it. Signed-off-by: JasonBuildAI --- loopx/control_plane/quota/decision_summary.py | 30 +++++ tests/control_plane/test_contract_health.py | 108 ++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/loopx/control_plane/quota/decision_summary.py b/loopx/control_plane/quota/decision_summary.py index 19fa5f23b3..c72cb507af 100644 --- a/loopx/control_plane/quota/decision_summary.py +++ b/loopx/control_plane/quota/decision_summary.py @@ -77,6 +77,34 @@ def quota_decision_agent_id(decision: dict[str, Any]) -> str | None: return normalize_todo_claimed_by(agent_identity.get("agent_id")) +# A Goal whose declared active state file is gone cannot be advanced by an +# automatic turn: there is no Goal intent, acceptance or stop condition to read. +# `loopx status` already reports the per-goal `state_file_missing` finding with +# its reconnect/retire repair, so the quota gate must not keep authorizing +# compute for it. Source-registry provenance findings are deliberately shadowed +# by the status projection and stay out of this guard. +_GOAL_STATE_UNAVAILABLE_FINDINGS = frozenset({"state_file_missing"}) + + +def _goal_active_state_missing( + status_payload: dict[str, Any], + *, + goal_id: str, +) -> bool: + global_registry = status_payload.get("global_registry") + if not isinstance(global_registry, dict): + return False + findings = global_registry.get("findings") + if not isinstance(findings, list): + return False + return any( + isinstance(finding, dict) + and str(finding.get("goal_id") or "") == goal_id + and finding.get("kind") in _GOAL_STATE_UNAVAILABLE_FINDINGS + for finding in findings + ) + + def goal_status_health_ok( status_payload: dict[str, Any], *, @@ -85,6 +113,8 @@ def goal_status_health_ok( ) -> bool: """Keep global guards fail-closed without importing unrelated goal errors.""" + if _goal_active_state_missing(status_payload, goal_id=goal_id): + return False contract = ( status_payload.get("contract") if isinstance(status_payload.get("contract"), dict) diff --git a/tests/control_plane/test_contract_health.py b/tests/control_plane/test_contract_health.py index 0748778763..c7c246a4af 100644 --- a/tests/control_plane/test_contract_health.py +++ b/tests/control_plane/test_contract_health.py @@ -338,3 +338,111 @@ def test_quota_uses_selected_goal_health_in_an_all_goal_status() -> None: assert decision["status_health_ok"] is True assert decision["normal_delivery_allowed"] is True assert decision["should_run"] is True + + +def test_missing_active_state_finding_blocks_only_its_goal() -> None: + status = { + "contract": {"ok": True}, + "global_registry": { + "ok": True, + "findings": [ + { + "kind": "state_file_missing", + "severity": "action", + "goal_id": GOAL_A, + }, + { + "kind": "stale_source_registry", + "severity": "action", + "goal_id": GOAL_A_LONG, + }, + ], + }, + } + + assert goal_status_health_ok(status, goal_id=GOAL_A, fallback=True) is False + assert ( + goal_status_health_ok(status, goal_id=GOAL_A_LONG, fallback=True) is True + ) + assert goal_status_health_ok(status, goal_id="goal-other", fallback=True) is True + + +def test_quota_does_not_authorize_a_goal_whose_declared_state_is_missing() -> None: + quota = { + "compute": 1.0, + "window_hours": 24, + "slot_minutes": 1, + "allowed_slots": 10, + "spent_slots": 0, + "state": "eligible", + "reason": "eligible fixture", + } + agent_todos = { + "schema_version": "todo_summary_v0", + "total_count": 1, + "open_count": 1, + "done_count": 0, + "first_open_items": [ + { + "todo_id": "todo_goal_a", + "index": 1, + "text": "[P1] Advance goal A.", + "role": "agent", + "status": "open", + "task_class": "advancement_task", + } + ], + } + status = { + "ok": True, + "contract": { + "ok": True, + "summary": {"errors": 0, "warnings": 0, "checks": 1}, + }, + "global_registry": { + "ok": True, + "findings": [ + { + "kind": "state_file_missing", + "severity": "action", + "goal_id": GOAL_A, + "recommended_action": ( + f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" + ), + } + ], + }, + "attention_queue": { + "items": [ + { + "goal_id": GOAL_A, + "status": "connected_without_run", + "waiting_on": "codex", + "severity": "action", + "source": "run_history", + "recommended_action": "Run the first adapter tick.", + "quota": quota, + "project_asset": { + "next_action": "Advance goal A.", + "agent_todos": agent_todos, + }, + } + ] + }, + "run_history": { + "goals": [ + { + "id": GOAL_A, + "registry_member": True, + "status": "active", + "quota": quota, + } + ] + }, + } + + decision = build_quota_should_run(status, goal_id=GOAL_A) + + assert decision["status_health_ok"] is False + assert decision["should_run"] is False + assert decision["normal_delivery_allowed"] is False From 3b6a3d735784aeba76e7909a4d93bd2d2a128391 Mon Sep 17 00:00:00 2001 From: JasonBuildAI Date: Sun, 18 Oct 2026 16:31:00 +0800 Subject: [PATCH 2/4] fix(quota): point the missing-state skip at the repair action The first commit fails the automatic turn closed, but the skip packet still carried the live lane's generic "run the first read-only adapter tick" action and reason. A host that displays the packet's guidance would still be pointed at work it cannot do. Reuse the status finding's reconnect/retire recommended_action for the packet's reason, recommended_action, state, status and source when the gate blocks for a missing active state file. The end-to-end regression now asserts the repair guidance, the blocked_health state, the state_file_missing status, the global_registry source and must_attempt=false; it fails with only the first commit and passes here. Signed-off-by: JasonBuildAI --- loopx/control_plane/quota/decision_summary.py | 31 +++++++++------- loopx/control_plane/quota/should_run.py | 35 +++++++++++++++++++ tests/control_plane/test_contract_health.py | 10 ++++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/loopx/control_plane/quota/decision_summary.py b/loopx/control_plane/quota/decision_summary.py index c72cb507af..f080693567 100644 --- a/loopx/control_plane/quota/decision_summary.py +++ b/loopx/control_plane/quota/decision_summary.py @@ -83,26 +83,33 @@ def quota_decision_agent_id(decision: dict[str, Any]) -> str | None: # its reconnect/retire repair, so the quota gate must not keep authorizing # compute for it. Source-registry provenance findings are deliberately shadowed # by the status projection and stay out of this guard. -_GOAL_STATE_UNAVAILABLE_FINDINGS = frozenset({"state_file_missing"}) +_GOAL_MISSING_STATE_FINDING = "state_file_missing" -def _goal_active_state_missing( +def goal_missing_state_blocker( status_payload: dict[str, Any], *, goal_id: str, -) -> bool: +) -> dict[str, Any] | None: + """Return the status finding that says this Goal's active state is gone.""" + global_registry = status_payload.get("global_registry") if not isinstance(global_registry, dict): - return False + return None findings = global_registry.get("findings") if not isinstance(findings, list): - return False - return any( - isinstance(finding, dict) - and str(finding.get("goal_id") or "") == goal_id - and finding.get("kind") in _GOAL_STATE_UNAVAILABLE_FINDINGS - for finding in findings - ) + return None + for finding in findings: + if not isinstance(finding, dict): + continue + kind = finding.get("kind") + if ( + isinstance(kind, str) + and kind == _GOAL_MISSING_STATE_FINDING + and str(finding.get("goal_id") or "") == goal_id + ): + return dict(finding) + return None def goal_status_health_ok( @@ -113,7 +120,7 @@ def goal_status_health_ok( ) -> bool: """Keep global guards fail-closed without importing unrelated goal errors.""" - if _goal_active_state_missing(status_payload, goal_id=goal_id): + if goal_missing_state_blocker(status_payload, goal_id=goal_id) is not None: return False contract = ( status_payload.get("contract") diff --git a/loopx/control_plane/quota/should_run.py b/loopx/control_plane/quota/should_run.py index c24ac56fce..89e67d3ee6 100644 --- a/loopx/control_plane/quota/should_run.py +++ b/loopx/control_plane/quota/should_run.py @@ -23,6 +23,7 @@ observe_goal_local_workspace, ) from ..quota.decision_summary import ( + goal_missing_state_blocker as _goal_missing_state_blocker, quota_plan_items as _quota_plan_items, ) from ..quota.goal_boundary import ( @@ -472,6 +473,35 @@ def build_quota_paused_should_run_payload( return payload +def _apply_missing_state_health_guidance( + payload: dict[str, Any], + status_payload: dict[str, Any], + *, + goal_id: str, +) -> None: + """Name the registry health blocker and its repair on a health skip. + + The live quota lane can still carry the generic "run the first adapter + tick" action while status has already reported the Goal's active state file + as missing. Replace that guidance on a skip so the packet points at the + same reconnect/retire repair as the status finding. + """ + + if payload.get("should_run") is True: + return + blocker = _goal_missing_state_blocker(status_payload, goal_id=goal_id) + if blocker is None: + return + recommended = str(blocker.get("recommended_action") or "").strip() + message = str(blocker.get("message") or "").strip() + payload["state"] = "blocked_health" + payload["status"] = "state_file_missing" + payload["source"] = "global_registry" + payload["reason"] = recommended or message or payload.get("reason") + if recommended: + payload["recommended_action"] = recommended + + def build_quota_should_run( status_payload: dict[str, Any], *, @@ -609,6 +639,11 @@ def build_quota_should_run( direct_sources ), ) + _apply_missing_state_health_guidance( + payload, + status_payload, + goal_id=safe_goal_id, + ) _record_unread_app_scheduler_state_source( resolved_scheduler_context, direct_sources, diff --git a/tests/control_plane/test_contract_health.py b/tests/control_plane/test_contract_health.py index c7c246a4af..d8ef6524c9 100644 --- a/tests/control_plane/test_contract_health.py +++ b/tests/control_plane/test_contract_health.py @@ -446,3 +446,13 @@ def test_quota_does_not_authorize_a_goal_whose_declared_state_is_missing() -> No assert decision["status_health_ok"] is False assert decision["should_run"] is False assert decision["normal_delivery_allowed"] is False + assert decision["state"] == "blocked_health" + assert decision["status"] == "state_file_missing" + assert decision["source"] == "global_registry" + assert decision["reason"] == ( + f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" + ) + assert decision["recommended_action"] == ( + f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" + ) + assert decision["interaction_contract"]["agent_channel"]["must_attempt"] is False From 18222bf4046419ad016dbf1e6adf870efe462af1 Mon Sep 17 00:00:00 2001 From: JasonBuildAI Date: Sun, 18 Oct 2026 16:44:02 +0800 Subject: [PATCH 3/4] fix(quota): scope missing-state guidance to the health skip The previous commit rewrote the top-level state, status, reason and recommended action of any skip packet that coexisted with a state_file_missing finding. That relabeled operator-gate and terminal-closure skips as blocked_health, which can hide a legitimate user prompt or block terminal completion of a canonically closed Goal. Restrict the rewrite to the eligible quota skip that the health gate itself blocked: status health false, effective_action=quota_skip, state=eligible and no safe bypass. Other skip routes keep their own state, effective action and interaction/user channel. Add helper-level regressions for operator-gate, terminal-closure, monitor-quiet, safe-bypass and should-run packets, and keep the target health skip assertions. Signed-off-by: JasonBuildAI --- loopx/control_plane/quota/should_run.py | 14 ++- tests/control_plane/test_contract_health.py | 98 +++++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/loopx/control_plane/quota/should_run.py b/loopx/control_plane/quota/should_run.py index 89e67d3ee6..8e71f1130a 100644 --- a/loopx/control_plane/quota/should_run.py +++ b/loopx/control_plane/quota/should_run.py @@ -483,12 +483,22 @@ def _apply_missing_state_health_guidance( The live quota lane can still carry the generic "run the first adapter tick" action while status has already reported the Goal's active state file - as missing. Replace that guidance on a skip so the packet points at the - same reconnect/retire repair as the status finding. + as missing. Replace that guidance on the eligible health skip so the packet + points at the same reconnect/retire repair as the status finding. Other + skip routes (operator gate, terminal closure, monitor quiet, automation + upgrade) keep their own channel and interaction contract. """ if payload.get("should_run") is True: return + if payload.get("status_health_ok") is not False: + return + if payload.get("effective_action") != EffectiveAction.QUOTA_SKIP.value: + return + if payload.get("state") != "eligible": + return + if payload.get("safe_bypass_allowed") is True: + return blocker = _goal_missing_state_blocker(status_payload, goal_id=goal_id) if blocker is None: return diff --git a/tests/control_plane/test_contract_health.py b/tests/control_plane/test_contract_health.py index d8ef6524c9..9f1b8bb67a 100644 --- a/tests/control_plane/test_contract_health.py +++ b/tests/control_plane/test_contract_health.py @@ -12,6 +12,9 @@ project_contract_health_for_goal, ) from loopx.control_plane.quota.decision_summary import goal_status_health_ok +from loopx.control_plane.quota.should_run import ( + _apply_missing_state_health_guidance, +) from loopx.quota import build_quota_should_run @@ -456,3 +459,98 @@ def test_quota_does_not_authorize_a_goal_whose_declared_state_is_missing() -> No f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" ) assert decision["interaction_contract"]["agent_channel"]["must_attempt"] is False + + +def _missing_state_status(): + return { + "global_registry": { + "ok": True, + "findings": [ + { + "kind": "state_file_missing", + "severity": "action", + "goal_id": GOAL_A, + "message": f"`{GOAL_A}` active state file is missing", + "recommended_action": ( + f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" + ), + } + ], + } + } + + +def test_missing_state_guidance_rewrites_only_the_eligible_health_skip() -> None: + payload = { + "should_run": False, + "status_health_ok": False, + "effective_action": "quota_skip", + "state": "eligible", + "safe_bypass_allowed": False, + "reason": "status or contract health is not ok; skip automatic compute", + "recommended_action": "run the first read-only adapter tick", + "interaction_contract": {"mode": "skip"}, + } + + _apply_missing_state_health_guidance( + payload, + _missing_state_status(), + goal_id=GOAL_A, + ) + + assert payload["state"] == "blocked_health" + assert payload["status"] == "state_file_missing" + assert payload["source"] == "global_registry" + assert payload["reason"] == ( + f"preview `loopx retire-global-goal --goal-id {GOAL_A}`" + ) + assert payload["recommended_action"] == payload["reason"] + assert payload["effective_action"] == "quota_skip" + assert payload["interaction_contract"] == {"mode": "skip"} + + +def test_missing_state_guidance_keeps_other_skip_routes_unchanged() -> None: + payloads = [ + { + "should_run": False, + "status_health_ok": True, + "effective_action": "operator_gate_notify", + "state": "operator_gate", + "user_channel": {"notify": "NOTIFY", "action_required": True}, + }, + { + "should_run": False, + "status_health_ok": False, + "effective_action": "terminal_no_followup", + "state": "terminal_no_followup", + "interaction_contract": {"mode": "terminal_no_followup"}, + }, + { + "should_run": False, + "status_health_ok": False, + "effective_action": "monitor_quiet_skip", + "state": "monitor_quiet_skip", + }, + { + "should_run": False, + "status_health_ok": False, + "effective_action": "quota_skip", + "state": "eligible", + "safe_bypass_allowed": True, + }, + { + "should_run": True, + "status_health_ok": False, + "effective_action": "normal_run", + "state": "eligible", + }, + ] + + for payload in payloads: + before = json.loads(json.dumps(payload)) + _apply_missing_state_health_guidance( + payload, + _missing_state_status(), + goal_id=GOAL_A, + ) + assert payload == before From 97e9f2caf5194af603fe2e0d9a46b9c70603b479 Mon Sep 17 00:00:00 2001 From: JasonBuildAI Date: Sun, 18 Oct 2026 16:49:30 +0800 Subject: [PATCH 4/4] test(quota): exercise operator gate with blocked health The cross-state regression used status_health_ok=true for the operator-gate packet, so it did not mirror the real coexistence shape: an operator gate plus a missing-state finding makes status health false. Use the real false variant; the effective_action check still keeps the gate state and user channel unchanged. Signed-off-by: JasonBuildAI --- tests/control_plane/test_contract_health.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/control_plane/test_contract_health.py b/tests/control_plane/test_contract_health.py index 9f1b8bb67a..12f14b76ad 100644 --- a/tests/control_plane/test_contract_health.py +++ b/tests/control_plane/test_contract_health.py @@ -513,7 +513,7 @@ def test_missing_state_guidance_keeps_other_skip_routes_unchanged() -> None: payloads = [ { "should_run": False, - "status_health_ok": True, + "status_health_ok": False, "effective_action": "operator_gate_notify", "state": "operator_gate", "user_channel": {"notify": "NOTIFY", "action_required": True},