The trap, as measured
In the 36-trial repair study, several agent failures autopsied as no-committed-script: the agent ran close --save-script mid-repair (without first committing via replay --from), got no file and no error, and retried in a loop until its turn budget died. Finding doc with per-trial evidence: wave3/E3-redo/findings/repair-flow-terminal-close-requires-replay-from.md (retained bench artifacts; trials haiku-A-s2-* et al.).
Where the silence lives (current main)
src/daemon/session-script-writer.ts:94-95 — write() returns { written: false } with no error when isRepairArmedWriteBlocked (repair armed, not saveScriptComplete); the doc comment classifies an incomplete repair transaction as a legitimate silent no-op.
src/daemon/handlers/session-close.ts:109-120 — the close path treats written:false without error as { kind: 'committed' }: the close succeeds, the caller sees success text, nothing says the healed script was not written.
What this is NOT
Not a semantics bug: ADR-0012 decision 6 makes closing an uncommitted repair an abort, and that behavior is arguably correct. ADR-0016/#1357 fixed the new session save-script path (refuses loudly in every failure case) — this issue is the remaining old close-time path.
Ask
Keep the abort semantics; make them loud. When close --save-script runs on a repair-armed session without a committed resume, the response should say explicitly: the repair was aborted, no script was written, and the recovery is replay --from <n> --plan-digest <digest> before closing. A silent no-op is a bug amplifier for agents: every retry is billed.
Acceptance
close --save-script on an uncommitted repair returns a message naming the abort + the recovery command; exit reflects that nothing was written.
- Plain
close behavior and committed-repair close behavior unchanged.
- The repair-flow help/skill text mentions the abort-on-close rule next to the resume step.
The trap, as measured
In the 36-trial repair study, several agent failures autopsied as
no-committed-script: the agent ranclose --save-scriptmid-repair (without first committing viareplay --from), got no file and no error, and retried in a loop until its turn budget died. Finding doc with per-trial evidence:wave3/E3-redo/findings/repair-flow-terminal-close-requires-replay-from.md(retained bench artifacts; trialshaiku-A-s2-*et al.).Where the silence lives (current main)
src/daemon/session-script-writer.ts:94-95—write()returns{ written: false }with no error whenisRepairArmedWriteBlocked(repair armed, notsaveScriptComplete); the doc comment classifies an incomplete repair transaction as a legitimate silent no-op.src/daemon/handlers/session-close.ts:109-120— the close path treatswritten:falsewithouterroras{ kind: 'committed' }: the close succeeds, the caller sees success text, nothing says the healed script was not written.What this is NOT
Not a semantics bug: ADR-0012 decision 6 makes closing an uncommitted repair an abort, and that behavior is arguably correct. ADR-0016/#1357 fixed the new
session save-scriptpath (refuses loudly in every failure case) — this issue is the remaining old close-time path.Ask
Keep the abort semantics; make them loud. When
close --save-scriptruns on a repair-armed session without a committed resume, the response should say explicitly: the repair was aborted, no script was written, and the recovery isreplay --from <n> --plan-digest <digest>before closing. A silent no-op is a bug amplifier for agents: every retry is billed.Acceptance
close --save-scripton an uncommitted repair returns a message naming the abort + the recovery command; exit reflects that nothing was written.closebehavior and committed-repair close behavior unchanged.