Repository navigation
refactor: settle handed-off cleanup runs by direct absence (#16011) - #16036
Merged
Merged
Conversation
A cleanup run whose task has moved to another owner no longer waits for a successor to prove it delivered the exact same captured head. Once the run's own checkout, local branch and worktree entry are gone and no live run owns the branch, its physical cleanup settles directly. The run keeps its original result, and its cleanup line reports the local worktree as cleaned up without claiming the code merged. The periodic completion sweep now settles these runs as well; before, only a matching retirement receipt could. This removes settleSeededPredecessor with its 25-hop resume-chain proof, the moved-predecessor receipt wake, the successor retirement writer, and the now-unused inspectAbsentCheckout. Refs #16011
A cleanup run can briefly look handed off right after it completes, because its own cleanup handoff is written to the task after the run is marked complete. Settling its physical cleanup in that window would leave the task waiting on a run that no longer verifies delivery. The absent-checkout writer now re-reads the task as it settles a captured checkout and proceeds only when the task has completed or names another cleanup owner. Neither state can be handed back to the run, so an unowned task, the run's own pending handoff or an unreadable task stays pending for the next pass. Refs #16011
atomantic
enabled auto-merge
November 14, 2026 06:06
This was referenced Nov 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Third slice of #16011. It retires the last multi-generation post-absence settlement sub-machine: settling a predecessor once a successor proves it delivered the same head.
Done ✓
already-absent-after-handoff, with no integration claim, so the agent card shows the worktree as cleaned up without saying the code merged.agentFinalizationwrites a run's cleanup handoff after the run is marked complete.checkout:retiredreceipt could, throughsettleSeededPredecessor.settleSeededPredecessor;explicitSameHeadResumechain walk;checkout:retiredwake;recordSuccessorCheckoutRetirementand the successor branch of the retirement writer;inspectAbsentCheckoutinheldCheckoutRecovery.js, whose only caller wassettleSeededPredecessor.settleAbsentSeedRetirementand the new handed-off settlement share one absence/owner check,settleAbsentScope.Remaining ▢ (tracked on #16011)
readAbsentTaskSnapshot/settleAbsentTaskCompletion, the removed-task replay that reads the compressed completion snapshot, can fold into the same direct-absence settlement. This does not depend on Retire two-step digest-bound held-checkout review ceremony and REVIEW_RETIREMENT sub-agent #16016.captureCheckoutSeeds/filesystemIdentity/readCompletedCheckoutIdentityincarnation capture andsameTaskRetirementBindingare still used by:branchCompletionPolicy,heldCheckoutRecovery,checkoutDeliveryContinuationandresumedCheckoutDelivery, which the in-flight Retire two-step digest-bound held-checkout review ceremony and REVIEW_RETIREMENT sub-agent #16016 is retiring;They should follow Retire two-step digest-bound held-checkout review ceremony and REVIEW_RETIREMENT sub-agent #16016.
Found while tracing ownership: #16037. The pre-existing own-seed absence settlement can strand a cleanup-held task whose owner's capture never completed. It predates #16032 and is filed separately; this PR does not change that path.
Local review
The configured required reviewer (
gpt-6.1-terra,~max=2) ran 2 rounds.cf93291) raised one finding, accepted and fixed inc6dcb28. The finding: a barecleanup-owner-changedverdict can be transient right after completion, because the run's own cleanup handoff is written to the task aftercompleteAgent. Settling in that window could leave the task without a delivery verifier. The fix: the writer now settles a captured checkout only once the task completed or names another cleanup owner. The writer test pins this.c6dcb28, the published head) was clean, with no findings.Test plan
agentRepoStateVerification: a new case covers settlement through both the sweep and the receipt wake. It also covers each hold: the run still owns cleanup, a live owner, the checkout present in either path spelling, the local ref present, a registered worktree. It fails on the pre-change source.cosAgentLifecycle: a new writer contract case covers a completed task, another named owner, a pending handoff, the run's own handoff, a missing task, a CAS refusal, the wrong path and a non-cleanup run. Its three refusal states fail without the ownership guard.agentRepoStateVerification,cosAgentLifecycle,heldCheckoutRecoveryandcompletedCheckoutEvidencesuites, plus 19 adjacent completion, retirement and held-checkout suites (653 tests).npm run pregatepassed.Refs #16011