Skip to content

refactor: retire merged checkouts directly, without the review ceremony (#16016) - #16040

Merged
atomantic merged 3 commits into
mainfrom
claim/issue-16016
Nov 14, 2026
Merged

atomantic merged 3 commits into
mainfrom
claim/issue-16016

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

Second and final slice of #16016 (slice 1 was #16033). Every held-checkout retirement path now uses one direct rule, and the digest-bound review machinery is gone:

  • A checkout whose PR merged at its exact head is removed with its branch; its uncommitted, untracked and ignored files go with it (merged ⇒ disposable).
  • Merged commits — on the default branch (ancestor or patch-equivalent) or inside a later merged PR head — retire a clean checkout.
  • Anything else is unmerged work and stays in place, visible in the inventory. Live owners, locks, human handoffs and unreadable policy still hold. A merged review-then-merge obligation no longer holds (it has nothing left to gate).

The same rule now drives branch-reconcile's automatic pass, the Schedule view's single-step Retire checkout, pending-merge receipts (which also bind the receipt's own PR and exact head), release-candidate locks and agent completion audits.

Changes

  • Deleted heldCheckoutReview.js, branchReconcileRetirement.js, checkoutDeliveryContinuation.js, resumedCheckoutDelivery.js, server/lib/testCacheRetirementProof.js (plus barrel/catalog rows).
  • heldCheckoutRecovery.js (1,522 → ~480 lines): direct retirement only. Removed content/administration snapshots and byte budgets, Vitest cache-schema recognition, supersession kinds and preservation, proof-object fetches and the review policy. Added readForgeDelivery (exact / contained / none / unreadable), readMergedDelivery, and the automatic pass retireCompletedCheckouts. Also hosts assertAutomaticRetirementAllowed.
  • New mergedPrEvidence.js: the forge reads other services still need (findMergedPullRequest, slimmed readMergedPrDelivery, exact or ancestor delivery only).
  • branchCompletionPolicy.js: dropped the retirement-review policy engine (reviewedRetirementPolicy, mergedReceiptRetirementPolicy, reviewedDeliveryHandoffValid).
  • Branch reconcile: no REVIEW_RETIREMENT dispatch, reservation, digest signature or reconcileRetirements metadata.
  • Agent completion (agentRepoStateVerification.js, small hunks only, to stay clear of Retire post-absence checkout-incarnation and historical claim lineage cleanup machinery #16011): merged delivery retires directly; a merged-PR checkout that still holds unmerged work files a plain repository-cleanup recovery instead of a retirement review; an unreadable delivery holds as delivery-evidence-unavailable.
  • Windows: the service unlinks untracked or ignored directory links (junctions Git for Windows leaves behind) just before removal, never following them, and restores them if Git refuses.
  • Client copy, docs/features/branch-reconciliation.md, docs/features/chief-of-staff.md and the services catalog describe the direct model.
  • Tests: the seven held-checkout suites and two review-flow integration suites are consolidated into one real-Git suite (heldCheckoutRecovery.test.js) plus mergedPrEvidence.test.js.

Net (before the main merge): 49 files, about +1,300 / −7,300 lines.

Decisions

  • Operator retire stays merged-only. The issue text could be read as letting the single-step endpoint discard unmerged work. AGENTS.md ("An unmerged checkout keeps uncommitted and untracked work in place") and slice 1's review (no auto-accepted supersession) both rule that out, so unmerged checkouts stay held until their work is delivered.
  • Later merged head counts as merged. A checkout behind a PR head that was updated elsewhere and then merged (often squash-merged) retires when clean. Slice 1's single-step retire already handled this case, and strict exact-head matching would have stranded those checkouts.
  • Merged claims in their grace window are no longer reviewed early; cleanupMerged's existing grace gate lifts them after an hour.
  • Existing supersededSourceEvidence (preserved prototype bytes from the removed mode) is left untouched in schedule state. It is no longer written or read, and is not stripped, since it may hold the only copy of operator-accepted bytes.
  • In-flight tasks created before this change keep their reconcileRetirements / retirementReview completion checks (compatibility with persisted tasks).

Test plan

  • npm run pregate: lint, structural guards (import growth, dead exports, barrel, catalog) and selected server/client suites pass.
  • All 74 server suites that reference a changed module pass (3,894 tests), plus the client BranchReconcileOutcome test.
  • New real-Git cases: review obligation settled once merged; unmerged work kept beside a PR merged at another head; contained delivery (clean retires, dirty kept); dirty exact-head merge with an initialized submodule; pending-merge receipt (exact head, moved head, lock, forge refusal); branch-only rows (merged, unmerged, already-absent with/without forge proof); readMergedDelivery tri-state; directory links never followed and restored on refusal. Key cases were mutation-checked (each fails when its behavior is removed).

Local review

The configured required reviewer (codex, model gpt-6.1-terra, effort high, ~max=2) ran 2 rounds, both with complete coverage (49/49 files). Its round budget is spent, so the local phase is recorded as partial.

  • Round 1 (reviewed c8f306acc9): two findings.
    • Accepted: Windows directory links. Fixed in 0df0931386: links are unlinked just before removal without being followed, and restored if Git refuses. Tests added.
    • Rejected: re-adding the inventoried checkout-incarnation recheck (rationale below).
  • Round 2 (reviewed 0df0931386): repeated only the incarnation finding, which stays rejected for the same reason.
  • After round 2, main was merged in to resolve conflicts with refactor: settle handed-off cleanup runs by direct absence (#16011) #16036 (Retire post-absence checkout-incarnation and historical claim lineage cleanup machinery #16011). This PR now also drops inspectAbsentCheckout from the service, as upstream did. That conflict resolution was not reviewed locally because the budget was spent; pregate and the 139 related suites (6,185 tests) pass on the merged head.

Why the incarnation finding is rejected. No code writes checkoutIncarnation onto inventory rows any more, so the old recheck already did nothing for current rows. In the direct model, every safety property is re-proven against the live checkout at the final removal gate: merged head, clean (or exact-head-merged) content, no live or claim owner, and unchanged path, HEAD, branch, lock and checkout-pointer identity. A checkout whose Git administration was recreated therefore cannot carry unmerged work past that gate. The recheck only mattered when a content digest taken at preview time had to stay bound to one generation. AGENTS.md also rejects durability findings on ephemeral worktree state, and #16011 is removing this dev/ino incarnation tracking.

Related

Closes #16016

…ny (#16016)

Branch reconciliation, the Schedule view's single-step Retire checkout,
pending-merge receipts, release candidates and agent completion audits now
share one direct rule. A checkout whose PR merged at its exact head is
removed with its branch, uncommitted and untracked files included. Merged
commits on the default branch, or inside a later merged PR head, retire a
clean checkout. Unmerged work stays in place and visible in the inventory.

- No REVIEW_RETIREMENT agent dispatch, review digest, content and Git
  administration snapshots, supersession preservation or proof-object
  fetches remain. Live owners, locks, human handoffs and unreadable
  policy still hold; a merged review-then-merge obligation no longer does.
- Deleted heldCheckoutReview.js, branchReconcileRetirement.js,
  checkoutDeliveryContinuation.js, resumedCheckoutDelivery.js and
  lib/testCacheRetirementProof.js. The merged-PR forge reads other
  services still use moved to the slimmer mergedPrEvidence.js.
- branchCompletionPolicy.js drops its retirement-review policy engine.
- An agent's merged-PR checkout that still holds unmerged work files a
  plain repository-cleanup recovery instead of a retirement review.
- Consolidated the held-checkout suites into one real-Git test file.

Closes #16016
Git for Windows leaves directory junctions behind when it removes a
worktree. Just before removal the retirement service now unlinks each
untracked or ignored link to a directory, never following it or touching
its target, and recreates those links if Git refuses the removal.
# Conflicts:
#	server/services/agentRepoStateVerification.test.js
#	server/services/heldCheckoutRecovery.js
#	server/services/heldCheckoutRecovery.test.js
@atomantic atomantic added implementer:opus-5-5 PR opened by the opus-5-5 model reviewer:gpt-6-1-terra Locally reviewed by the gpt-6-1-terra model labels Nov 14, 2026
@atomantic
atomantic enabled auto-merge November 14, 2026 06:45
@atomantic
atomantic merged commit d8a773a into main Nov 14, 2026
19 checks passed
@atomantic
atomantic deleted the claim/issue-16016 branch November 14, 2026 06:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

implementer:opus-5-5 PR opened by the opus-5-5 model reviewer:gpt-6-1-terra Locally reviewed by the gpt-6-1-terra model

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Retire two-step digest-bound held-checkout review ceremony and REVIEW_RETIREMENT sub-agent

2 participants