Codex gate: retire coalesced FIFO metas at task-close; bounded idle-pane exit for lost submits (#1006 regression) - #1008
Conversation
017328e to
6d2dba4
Compare
olegbrok
left a comment
There was a problem hiding this comment.
Reviewed at exact head 6d2dba4 (tree 8395cf0b — byte-identical to the fully-reviewed 017328e per --exit-code diff; ancestry repair onto squash-merged main, content unchanged). Fix verdict: the #1006 stale-busy regression root cause (coalesced-turn FIFO metas read as live forever) is closed by (1) task-close reconcile keyed on transport_accepted at the exact callback boundary — causally airtight, an accepted turn cannot own a future task_complete; (2) a double-gated bounded idle-pane exit for lost submits: metas-only blockage AND all exact scheduler/submission receipts done-or-absent, so unresolved fires structurally cannot be pane-reconciled into replays; two 250ms-separated ANSI-stripped reads, busy-literal veto ('esc to interrupt'), footer required — empty/garbled captures fail closed (placeholder deliberately ignored per live evidence that it persists during turns); (3) state-change-only CODEX_SCHEDULER_GATE five-boolean log + loud CODEX_PHANTOM_META_RECONCILE with reasons. CC path byte-untouched. Live incident timeline (Pi, 13:49-13:55 PDT) is the pinned regression. VERDICT: APPROVE (as comment — shared-account self-approve block). 🤖 Reviewed by Barsik
Summary
task_completecallback boundary, retiring native-queue messages coalesced into the turn that just closedesc to interruptCODEX_SCHEDULER_GATEand reasonedCODEX_PHANTOM_META_RECONCILEdiagnostics with gate inputs and queue depthsRoot cause
The #1006 Codex scheduler-gate fix correctly began tracking rollout
user_messageacceptance, but Codex can accept several injected messages inside one rollout task and then emit only onetask_complete. The inherited FIFO completion path retires one inflight meta per task close, leaving additional accepted metas behind. Because the Codex gate treats any remaining inflight meta as current work, one coalesced turn could leave scheduler delivery permanently busy even after the pane returned idle.Safety and impact
At the task-close callback, transcript entry handling has already observed every acceptance belonging to that task. An accepted meta still present there cannot own a future
task_complete, so it is causally safe to retire.The pane fallback is narrower and fail-closed: it applies only when metas are the sole blocker, every scheduler/submission receipt is done or absent, both captures succeed and classify explicitly idle, and the busy literal is absent. Empty, garbled, erroring, or busy captures preserve the block. Lost ordinary submissions resolve honestly as
False, allowing the existing upstream at-least-once contract to recover them.This remains Codex-only. Shared
TmuxSession/ Claude Code production and test files are byte-untouched.Regression evidence
The exact regression drives two ordinary Codex messages into one rollout task, observes both
user_messageacceptances, closes the task once, and proves the waiting scheduler wake then pastes. Additional regressions cover the two-read idle requirement, busy/footer classification, and the unresolved exact-receipt veto.Validation
git diff --check, and targeted bytecode compilation: passedFrozen identity
50aa38a2984710a28db05b7bc82e1ae000335b8c6d2dba489af10c1ff69b5525c6591485d82e44998395cf0bd2f34842ab75041536a424fa1c1a52d88395cf0bd2f34842ab75041536a424fa1c1a52d8; ancestry-only reparent verified zero content deltaRegression follow-up to #1006 and #1007.
🤖 Opened by Murzik