Agent worktree cleanup and external-repo reaping still archive under the claim-ownership lock
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 43/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- javascript, node.js
Research direction
Read server/services/worktreeManager.js, server/services/branchReconcile.js, and the retirement helper in server/services/cosClaimOwnershipState.js; first review the existing unlocked archive pattern from #12682. Split the listed cleanup and reaping paths so archive or backup work runs outside the ownership lock while preserving the fence and removal checks. Add deterministic tests that hold the archive open and verify the lock settles and the checkout is fenced, then run the worktreeManager, worktreeReap, and branchReconcile suites.
Written by the indexing model from the issue text.
Description
Discovered while working issue #12682.
Problem
#12682 moved checkout archiving out of the shared claim-ownership lock (withClaimOwnershipLock) for operator held-checkout retirement, branch-reconcile merged retirement and detached-tree reaping, and reapMergedWorktrees. It added a per-checkout retirement fence (reserveCheckoutRetirementFence / checkoutRetirementFenceReason in server/services/cosClaimOwnershipState.js) that refuses binds and reconcile admissions for the checkout being archived.
Three paths still run slow archive or backup I/O while holding the lock. Every claim-ownership bind/release/reserve queues behind that lock with a 15 s budget (CLAIM_OWNERSHIP_QUEUE_TIMEOUT_MS), so each can still cause ownership-queue-timeout refusals:
removeWorktree()inserver/services/worktreeManager.js: agent cleanup runsremoveWorktreeNowinsidewithClaimOwnershipLock, and itspreserveOrHold()callspreserveMergedCheckoutat three points (the missing-directory prune, the merged/clean path and the discard path). This runs on every agent completion that owns a worktree.cleanupExternalRepoWorktrees()in the same file: theremoveIfStillOrphanedcallback callspreserveMergedCheckoutunder the lock.- Superseded reap in
server/services/branchReconcile.js:retireBranchruns thepreparehook (backupSupersededBranch, which copies dirty files) inside the first critical section. It is opt-in (reapSuperseded).
Chosen approach
Use the shared helper retireWithUnlockedArchive({ admit, archive, finish, busy }) from server/services/cosClaimOwnershipState.js, added by #12682. It implements this three-phase pattern:
- Under the lock, run the owner, policy and status checks, then take the fence with
reserveCheckoutRetirementFence({ repoPath, path, branch }). If the fence is refused, hold withcheckout-retirement-reserved. - Release the lock and run the archive or backup.
- Re-take the lock for
verifyRemoval(owners pluspreservation.verifyfingerprints), removal and branch deletion. Release the fence inside that critical section, and again in an outerfinally.
For removeWorktreeNow, split the function at each preserveOrHold() call rather than wrapping it whole. Keep the merge-back and discard semantics exactly as they are now.
Acceptance criteria
- No
preserveMergedCheckoutorbackupSupersededBranchcall runs whilewithClaimOwnershipLockis held.rg preserveMergedCheckout server/servicesshows each remaining call between two lock sections. - For each path, a deterministic test holds the archive open and shows that
withClaimOwnershipLock(() => …)settles and the checkout is fenced while the archive is pending. See theexpectArchiveOutsideOwnershipLockhelper inserver/services/branchReconcile.test.jsand theworktreeReap.test.jscase added by #12682. - Existing worktreeManager, worktreeReap and branchReconcile suites still pass.
model:heavy because this reorders lock and fence boundaries around destructive removal. effort:high because the merge-back and discard paths in removeWorktreeNow each need their preservation invariants re-proven.
Depends on #12682
- Dominant language
- JavaScript
- Stars
- 38
- Forks
- 32
- Avg merge
- 34m
- Merged PRs (30d)
- 993
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from atomantic/PortOS
-
effort:medium enhancement model:medium plan
Difficulty 4/5 1-2 days Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Reconcile dead-owner settlement reservations left by crashed publicationsPossibly taken @atomantic claimed this today. Openbug effort:high in-progress model:medium plan
atomantic/PortOS#12740 · 1 assignee ·
Maintainers usually reply within 1 day
-
CI planner runs the full suite for requirements-only Python pin changesPossibly taken @atomantic claimed this today. Opencode-quality effort:low in-progress model:medium plan
atomantic/PortOS#12739 · 1 assignee ·
Maintainers usually reply within 1 day
-
Worktrees made outside the claim prompt never get dependency links, and a cache-only node_modules blocks a later linkPossibly taken @atomantic claimed this today. Openbug effort:medium in-progress model:medium plan
atomantic/PortOS#12734 · 1 assignee ·
Maintainers usually reply within 1 day
-
Held-checkout archiving holds the claim-ownership lock and starves ownership checks for minutesPossibly taken @atomantic claimed this today. Openbug effort:high in-progress model:heavy planner:opus-5-5
atomantic/PortOS#12682 · 1 assignee ·
Maintainers usually reply within 1 day
All issues in atomantic/PortOS
Similar issues
-
documentation
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
PhyberApex/slds-json-schema-renderer#372 ·
Maintainers usually reply within 1 day
-
usage: a custom provider's balance meters ("…%" in the balance path) ignore the Left/Used switchOpen
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
[BUG] rag: sentence content can cross the reported sentence boundariesPossibly taken @LJK-ikun claimed this today. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
ericcornelissen/depreman#591 ·
Maintainers usually reply within 1 day
-
bug/1-unconfirmed kind/bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
prisma/orm#30818 · 1 comment ·
Maintainers usually reply within 1 day