Bug: autonomous replan no_followup can make the Goal terminal before its bound quota spend
Summary
An LHTB apex-ib244-matter run exposed two separate behaviors that should not
be conflated:
- A closed agent vision while the registry Goal remains active produces
vision_successor_required and then autonomous_replan_required. This is
expected fail-closed behavior.
- When that autonomous replan resolves the frontier with a coverage-backed
no_followup, its durable writeback can derive terminal_no_followup
before the same settlement identity records its quota spend. The strict
terminal guard then rejects that pending spend. This is an ordering bug.
The result is an unnecessary control-plane self-repair turn after the benchmark
work itself is already complete.
Observed run
- LoopX revision used by the run:
1c7b40ea403f9949b22f32071eec237199e52554
- Benchmark result:
38/38 stages submitted
- Final reward:
0.993151
- Scheduler wakes:
normal_run
autonomous_replan_required
autonomous_replan_required
- scheduler poll returns
terminal_no_followup
Wake 1: benchmark completion and Todo settlement
The agent completed all 38 stages. The first material refresh correctly
reported a missing required vision checkpoint. The agent then:
- recorded an evidence-linked
vision_closed checkpoint;
- committed the Todo-bound durable writeback;
- committed exactly one Todo-bound quota spend;
- completed the Todo with
--no-follow-up;
- read back
heartbeat_settled_skip for that Turn.
The vision checkpoint gate and its repair were expected.
Wake 2/3: expected Goal-level replan
On the next fresh Turn, quota projected:
{
"decision": "autonomous_replan_required",
"effective_action": "autonomous_replan_required",
"selected_todo": null,
"autonomous_replan_obligation": {
"triggers": [
{
"kind": "vision_successor_required",
"text": "the current stage vision is closed while the registry goal remains active; establish a successor vision before continuing"
}
]
}
}
This replan is expected: Todo no_followup is not by itself Goal completion.
The Goal still needs either a successor vision or an evidence-backed terminal
frontier decision.
The first replan wake returned without settling the obligation, so the
scheduler correctly presented the same obligation again. The following wake
validated that 38/38 was complete and selected
coverage_backed_no_followup, with an agent vision whose state was
no_followup and whose path outcome was stop.
Failure
The autonomous-replan settlement plan was:
validation -> durable_writeback -> quota_spend
The durable writeback succeeded and derived Goal state
terminal_no_followup. The immediately following, correctly bound
quota spend-slot was rejected because quota accounting no longer admitted
delivery completion spend from a terminal state.
At the point of failure:
validation receipt: committed
durable writeback receipt: committed
quota spend receipt: absent
Goal state: terminal_no_followup
effect identity: unchanged and correctly replan-bound
This matches the documented terminal_settlement_ordering_gap: terminal state
became visible between two ordered steps of the same effect.
Why this is a bug
The terminal guard is correct to reject new work and unrelated spends after a
Goal is terminal. However, a writeback from the current typed settlement must
not make the remaining step of that exact settlement impossible.
The replan itself is not the bug. The bug is that final Goal-level
no_followup is applied as part of pre-spend writeback instead of as a
conditional post-spend closeout under the same effect identity.
Current main audit
Audited remote main at:
f97ba42219442e4b46819e4795050dd8c41d2389
Current main correctly retains the expected vision behavior:
tests/control_plane/test_goal_vision_succession.py requires a closed stage
vision on an active Goal to produce vision_successor_required.
skills/loopx-self-repair/references/repair-patterns.md documents
terminal_settlement_ordering_gap and recommends post-spend terminal
closeout.
Current main also adds a conditional terminal_closeout step for Todo-bound
settlements. However, the exact autonomous-replan path remains uncovered:
build_turn_scoped_cli_settlement_plan() adds terminal_closeout only when
todo_id is present; a replan_obligation_id plan still ends at
quota_spend.
build_quota_slot_preview_for_decision() still admits delivery completion
spend only from waiting, focus_wait, operator_gate, or eligible, not
from terminal_no_followup.
- The focused regressions created during the run are not present on current
main.
Therefore this issue is recognized and partly addressed for Todo closeout, but
the observed autonomous-replan terminal path is not demonstrably fixed.
Expected behavior
For an autonomous replan whose accepted semantic outcome is
coverage_backed_no_followup, preserve the strict terminal guard while making
the settlement order explicit:
validation
-> durable writeback
-> quota spend
-> conditional terminal closeout
Requirements:
- all four steps use the same typed effect identity and replan obligation;
- terminal mutation requires matching writeback and spend receipts;
- retrying terminal closeout must not repeat writeback or spend;
- unrelated or unbound terminal spends remain rejected;
- cancellation, failed validation, failed writeback, and rejected spend must
short-circuit before terminal mutation.
Suggested regression coverage
- Active Goal plus
vision_closed still produces
vision_successor_required and autonomous_replan_required.
- A replan-bound, coverage-backed
no_followup writeback does not strand the
matching quota spend.
- Terminal closeout occurs only after matching writeback and spend receipts.
- Replay produces no additional spend or writeback.
- A terminal Goal still rejects an unbound spend and a mismatched replan
obligation.
- The generic CLI heartbeat path reaches
heartbeat_settled_skip without a
model-authored self-repair worktree.
Bug: autonomous replan
no_followupcan make the Goal terminal before its bound quota spendSummary
An LHTB
apex-ib244-matterrun exposed two separate behaviors that should notbe conflated:
vision_successor_requiredand thenautonomous_replan_required. This isexpected fail-closed behavior.
no_followup, its durable writeback can deriveterminal_no_followupbefore the same settlement identity records its quota spend. The strict
terminal guard then rejects that pending spend. This is an ordering bug.
The result is an unnecessary control-plane self-repair turn after the benchmark
work itself is already complete.
Observed run
1c7b40ea403f9949b22f32071eec237199e5255438/38stages submitted0.993151normal_runautonomous_replan_requiredautonomous_replan_requiredterminal_no_followupWake 1: benchmark completion and Todo settlement
The agent completed all 38 stages. The first material refresh correctly
reported a missing required vision checkpoint. The agent then:
vision_closedcheckpoint;--no-follow-up;heartbeat_settled_skipfor that Turn.The vision checkpoint gate and its repair were expected.
Wake 2/3: expected Goal-level replan
On the next fresh Turn, quota projected:
{ "decision": "autonomous_replan_required", "effective_action": "autonomous_replan_required", "selected_todo": null, "autonomous_replan_obligation": { "triggers": [ { "kind": "vision_successor_required", "text": "the current stage vision is closed while the registry goal remains active; establish a successor vision before continuing" } ] } }This replan is expected: Todo
no_followupis not by itself Goal completion.The Goal still needs either a successor vision or an evidence-backed terminal
frontier decision.
The first replan wake returned without settling the obligation, so the
scheduler correctly presented the same obligation again. The following wake
validated that 38/38 was complete and selected
coverage_backed_no_followup, with an agent vision whose state wasno_followupand whose path outcome wasstop.Failure
The autonomous-replan settlement plan was:
The durable writeback succeeded and derived Goal state
terminal_no_followup. The immediately following, correctly boundquota spend-slotwas rejected because quota accounting no longer admitteddelivery completion spend from a terminal state.
At the point of failure:
This matches the documented
terminal_settlement_ordering_gap: terminal statebecame visible between two ordered steps of the same effect.
Why this is a bug
The terminal guard is correct to reject new work and unrelated spends after a
Goal is terminal. However, a writeback from the current typed settlement must
not make the remaining step of that exact settlement impossible.
The replan itself is not the bug. The bug is that final Goal-level
no_followupis applied as part of pre-spend writeback instead of as aconditional post-spend closeout under the same effect identity.
Current
mainauditAudited remote
mainat:Current main correctly retains the expected vision behavior:
tests/control_plane/test_goal_vision_succession.pyrequires a closed stagevision on an active Goal to produce
vision_successor_required.skills/loopx-self-repair/references/repair-patterns.mddocumentsterminal_settlement_ordering_gapand recommends post-spend terminalcloseout.
Current main also adds a conditional
terminal_closeoutstep for Todo-boundsettlements. However, the exact autonomous-replan path remains uncovered:
build_turn_scoped_cli_settlement_plan()addsterminal_closeoutonly whentodo_idis present; areplan_obligation_idplan still ends atquota_spend.build_quota_slot_preview_for_decision()still admits delivery completionspend only from
waiting,focus_wait,operator_gate, oreligible, notfrom
terminal_no_followup.main.
Therefore this issue is recognized and partly addressed for Todo closeout, but
the observed autonomous-replan terminal path is not demonstrably fixed.
Expected behavior
For an autonomous replan whose accepted semantic outcome is
coverage_backed_no_followup, preserve the strict terminal guard while makingthe settlement order explicit:
Requirements:
short-circuit before terminal mutation.
Suggested regression coverage
vision_closedstill producesvision_successor_requiredandautonomous_replan_required.no_followupwriteback does not strand thematching quota spend.
obligation.
heartbeat_settled_skipwithout amodel-authored self-repair worktree.