Skip to content

Route agent-recoverable runtime gates to self-repair#2534

Merged
huangruiteng merged 2 commits into
mainfrom
codex/runtime-user-gate-overreach-20260725
Jul 25, 2026
Merged

Route agent-recoverable runtime gates to self-repair#2534
huangruiteng merged 2 commits into
mainfrom
codex/runtime-user-gate-overreach-20260725

Conversation

@huangruiteng

Copy link
Copy Markdown
Owner

Summary

  • detect execution-shaped user gates that lack decision scope and link to the current agent's capability-runnable todo
  • route only those malformed gates to bounded control-plane self-repair without notifying the user
  • preserve owner routing for scoped decisions, global gates, owner-held capabilities, and unavailable runtime capabilities

Validation

  • pytest -q tests/control_plane/test_user_gate_lane_progress.py tests/control_plane/test_capability_gate.py (18 passed)
  • focused decision-scope, monitor-replan, scheduler-interaction, and quota projection suite (53 passed)
  • loopx canary premerge --from-git-diff (17 selected checks passed; no failures, skips, warnings, or manual holds)
  • ruff check on changed Python surfaces
  • public/private boundary scan clean

Scope

Built-in control_plane/quota repair classification only. This does not grant capabilities or authority; it consumes observed capabilities and keeps credentials/production access owner-held.

@huangruiteng

Copy link
Copy Markdown
Owner Author

Pre-merge validation receipt

Changed surfaces:

  • control_plane/quota: classify only exact-linked, fully observed, agent-recoverable execution gates as self-repair
  • work_items/interaction_contract: suppress user action/notification for that repair class
  • focused quota/user-gate regression coverage

Checks run:

  • focused user-gate and capability tests: 18 passed
  • decision-scope, monitor-replan, scheduler interaction, and quota projection tests: 53 passed
  • Ruff on changed files: passed
  • loopx canary premerge --from-git-diff: standard tier, 17/17 selected checks passed
  • public/private boundary scan: clean

Failures: none. Skips: none. Manual holds: none.

Coverage is sufficient because it exercises the new positive classification, preserves scoped-decision and owner-capability gates, and runs the broader quota, scheduler, heartbeat, maintainability, and catalog canaries.

@huangruiteng

Copy link
Copy Markdown
Owner Author

Findings

  • [P1] Preserve authoritative todo-source precedence before suppressing the user gate. In loopx/control_plane/quota/stall_repair.py:124-150, _source_todo_items() always appends compact summary rows to source_items. That conflicts with the existing contract of select_quota_todo_source_items() ("authoritative pre-hot-path todo source") and with build_required_decision_scope_consistency(), which uses source rows exclusively when they are available. I reproduced the failure at exact head 6ff653a0: with user_todo_source_items=[] (the authoritative source has no open gate), an old gate still present in user_todo_summary causes build_runtime_capability_user_gate_repair_hint() to return runtime_capability_user_gate_overreach. The downstream path then sets notify=DONT_NOTIFY and routes self-repair from stale data. A completed or removed user gate can therefore be treated as live, while the same shape on the agent side can resurrect a stale target. Please use source items exclusively when they are not None, fall back to summary rows only when no source projection exists, and add a negative regression for an empty authoritative user source plus a stale summary gate.

Open questions

  • None for the intended product rule. The rule is sound once gate and target identity come from the authoritative source.

Product and architecture judgment

The motivation is valid: an execution-shaped gate without decision scope should not strand an agent when the linked todo is owned by that agent and all non-owner capabilities are currently runnable. The checks for global gates, explicit decision scopes, other-agent ownership, required decision scopes, owner-held capabilities, and missing capabilities form a sensible fail-closed boundary. The remaining blocker is source authority, not the routing policy itself.

Code volume and simplification

The diff is +320/-6: production is +204/-6 across three files, with +116 focused test lines. The behavior is cohesive and most of that volume is justified, but the new 27-line source/summary collector is partly avoidable and duplicates the open-item selection rules already owned by loopx/control_plane/todos/decision_scope.py. Reusing or promoting one shared authoritative-source helper would both reduce code and prevent the precedence bug. The expanded repair payload is otherwise appropriate because it keeps the decision inspectable.

Validation performed

  • uv run --with pytest pytest -q tests/control_plane/test_user_gate_lane_progress.py tests/control_plane/test_capability_gate.py: 18 passed
  • Exact-head stale-summary reproducer: authoritative user source empty, compact summary still contains the old gate; the new helper incorrectly returned a repair hint
  • Remote head rechecked and unchanged at 6ff653a0e05e90b54e5a9d7090cf1759202790ed; GitHub pytest is green

Merge decision

Request changes / hold. After authoritative-source precedence and its negative regression are fixed, the PR should be ready for a focused exact-head re-review.

@huangruiteng

Copy link
Copy Markdown
Owner Author

Resolved the authoritative-source precedence blocker in fab7ad35.

  • _source_todo_items() now falls back to compact summary rows only when the authoritative source is absent (None); an explicit empty source remains authoritative.
  • The runtime-gate scanner now receives a clean summary containing only the selected rows, so stale first_open_items or backlog_items cannot reintroduce a removed gate.
  • Added a negative regression for an empty authoritative user source plus a stale summary gate.

Validation:

  • focused quota, capability-gate, and decision-scope tests: 39 passed
  • Ruff on changed Python files: passed
  • exact stale-summary reproducer: now returns no repair hint
  • loopx canary premerge --from-git-diff: 17/17 selected checks passed; no failures, skips, warnings, or manual holds

@huangruiteng
huangruiteng merged commit 5e82fe6 into main Jul 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant