The execution loop's two terminal dispositions disagree about what happens to a run's claims, and the disagreement is observable to an orchestrator.
applyExecutionTerminalRelease (packages/cli/src/services/execution.ts):
release-runbook → releaseRunbook(runbookId, { retainClaimsAsTerminal: true }), with the rationale stated inline: "Natural child completion: retain the claim as a terminal tombstone so rd pass/fail --claim-id can confirm-or-conflict against the child's outcome (idempotent post-work commands). Explicit teardown (abort/stop/complete) keeps deleting the claim."
stack-pop → releaseRunbook(runbookId), which takes the default and deletes every claim controlling the run (projectRunbookRelease, the else arm).
Meanwhile the fenced command mutation retains tombstones in both modes, with a comment saying explicitly that this must not be keyed on the mode.
So the same run reaching the same terminal state leaves a claim id resolving terminal or missing depending on which disposition the loop happened to be given — and stack-pop is the default for every non-claim-addressed run.
Why it is filed rather than fixed
PR #780 changed stack-pop from the positional popRunbook() to releaseRunbook(runbookId). Claim disposition was deliberately held constant there — the bare form deletes claims exactly as the positional pop did — because changing addressing and retention in one commit would make a regression in either untraceable to the other.
What to decide
- Whether
stack-pop should retain tombstones like its sibling and like the fence. The argument for: an orchestrator holding a run-control claim gets the same answer regardless of which internal disposition ran. The argument against: stack-pop covers explicit teardown paths, and the release-runbook comment above draws the line at exactly that distinction — so the current split may be intentional and merely undocumented.
- Whether the mode union still earns its shape once both arms call the same method with the same addressing and differ only in one boolean. Note this is not a licence to collapse it to a boolean: the exhaustive
switch carries a comment explaining that "not release-runbook" must not come to mean "stack-pop", and defer-to-caller is a third arm that releases nothing. Any collapse has to preserve that.
Acceptance
Related: #597 (unify terminal session-release behind one machine-owned seam) and #734 — both concern which seam owns a terminal release, and this is the claim-disposition half of the same question.
The execution loop's two terminal dispositions disagree about what happens to a run's claims, and the disagreement is observable to an orchestrator.
applyExecutionTerminalRelease(packages/cli/src/services/execution.ts):release-runbook→releaseRunbook(runbookId, { retainClaimsAsTerminal: true }), with the rationale stated inline: "Natural child completion: retain the claim as a terminal tombstone sord pass/fail --claim-idcan confirm-or-conflict against the child's outcome (idempotent post-work commands). Explicit teardown (abort/stop/complete) keeps deleting the claim."stack-pop→releaseRunbook(runbookId), which takes the default and deletes every claim controlling the run (projectRunbookRelease, theelsearm).Meanwhile the fenced command mutation retains tombstones in both modes, with a comment saying explicitly that this must not be keyed on the mode.
So the same run reaching the same terminal state leaves a claim id resolving
terminalormissingdepending on which disposition the loop happened to be given — andstack-popis the default for every non-claim-addressed run.Why it is filed rather than fixed
PR #780 changed
stack-popfrom the positionalpopRunbook()toreleaseRunbook(runbookId). Claim disposition was deliberately held constant there — the bare form deletes claims exactly as the positional pop did — because changing addressing and retention in one commit would make a regression in either untraceable to the other.What to decide
stack-popshould retain tombstones like its sibling and like the fence. The argument for: an orchestrator holding a run-control claim gets the same answer regardless of which internal disposition ran. The argument against:stack-popcovers explicit teardown paths, and therelease-runbookcomment above draws the line at exactly that distinction — so the current split may be intentional and merely undocumented.switchcarries a comment explaining that "not release-runbook" must not come to mean "stack-pop", anddefer-to-calleris a third arm that releases nothing. Any collapse has to preserve that.Acceptance
terminalvsmissing— so the contract is observable rather than implied.stack-poparm; today onlyrelease-runbookexplains itself.Related: #597 (unify terminal session-release behind one machine-owned seam) and #734 — both concern which seam owns a terminal release, and this is the claim-disposition half of the same question.