Repository navigation
Bug: autonomous replan no_followup can make the Goal terminal before its bound quota spend #4501
Description
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_requiredand thenautonomous_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 deriveterminal_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/38stages submitted - Final reward:
0.993151 - Scheduler wakes:
normal_runautonomous_replan_requiredautonomous_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_closedcheckpoint; - committed the Todo-bound durable writeback;
- committed exactly one Todo-bound quota spend;
- completed the Todo with
--no-follow-up; - read back
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_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.pyrequires a closed stage
vision on an active Goal to producevision_successor_required.skills/loopx-self-repair/references/repair-patterns.mddocuments
terminal_settlement_ordering_gapand 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()addsterminal_closeoutonly when
todo_idis present; areplan_obligation_idplan still ends at
quota_spend.build_quota_slot_preview_for_decision()still admits delivery completion
spend only fromwaiting,focus_wait,operator_gate, oreligible, not
fromterminal_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_closedstill produces
vision_successor_requiredandautonomous_replan_required. - A replan-bound, coverage-backed
no_followupwriteback 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_skipwithout a
model-authored self-repair worktree.
Activity
YZJF commentedon Sep 16, 2026
I re-checked the audit in this issue against current
main(856dc9a38) and it still holds, but I think the fix is larger than "add the missing post-spend step". Posting before writing code, because it needs a direction call.The audit still holds
build_turn_scoped_cli_settlement_plan()still appendsTERMINAL_CLOSEOUTonly underif todo_id— now atloopx/control_plane/quota/effect_program.py:190(was 188 at the auditedf97ba42). Areplan_obligation_id-bound plan still ends atquota_spend.build_quota_slot_preview_for_decision()still does not admit the delivery-completion spend fromterminal_no_followup.Why appending a post-spend closeout step is not sufficient
The existing
terminal_closeoutcommand template is Todo-scoped:It needs a
todo_id, and the failing settlement hasselected_todo: nullby definition. Grepping--no-follow-upacrossloopx/finds it only in the Todo command family (cli_commands/todo_argument_validation.py,cli_commands/todo_registration.py), in adapters that shell out totodo complete(kunluncode_goal_mode/control_plane.py,goal_mode_mcp.py), and incli_commands/lark_inbox.py. There is no Goal-level closeout command to hang on a replan-bound plan.More importantly, the terminal state is not missing from the end of the plan — it is produced in the middle of it. The
durable writebackstep runsrefresh-state, which recomputes the frontier projection and feedsderive_goal_terminal_state()(control_plane/goals/goal_frontier/terminal.py:121, withgoal_frontier_is_terminal_no_followup()at:165). Once all todos are closed, the frontier is empty and the no_followup is coverage-backed, that writeback writesterminal_no_followupitself. The spend that follows is then rejected by the strict terminal guard.So even with a post-spend closeout step added, the ordering bug would remain: writeback would still have made the Goal terminal before the spend ran. The defect is in the writeback step, not only in the missing last step.
Two directions I can see
refresh-statewrites.todo complete --no-follow-upso the replan plan can carry a real post-spendTERMINAL_CLOSEOUT, and make the writeback path register the terminal intent rather than the terminal state.Both touch the goal-frontier projection, which
scheduler,arbitration, anddecision_summaryread, so either way this needs the regression list already in this issue plus projection parity cases.What I am asking
Which of the two (or a third option) matches the intended contract? I am happy to implement the chosen direction together with the six regressions listed here, but I would rather not pick the writeback semantics unilaterally. Not claiming the issue.
fix(quota): settle an autonomous replan spend from its own terminal f…
yilin-succeed commentedon Sep 16, 2026
PR #4536 takes this on: an autonomous replan spend is now admitted from
terminal_no_followuponly when it is bound to the autonomous-replan settlement that owns the committed durable-writeback receipt and has not yet recorded its spend. Unbound, mismatched, and already-accounted terminal spends still fail closed.Reproduced on current
mainfirst with a coverage-backedno_followupreplan fixture (writeback committed, spend rejected because the Goal was already terminal); both new regressions fail without the change.fix(quota): settle an autonomous replan spend from its own terminal f…