Repository navigation
Conversation
…ts worktree V2 stores every subagent thread with its parent's worktreePath. Cleanup only considered a worktree path that exactly one thread owned, so any thread that ever used a subagent kept its worktree forever. A worktree is now owned by its single top-level thread when every other thread on it is that thread's own idle subagent. A delegated subagent, which can take messages and recreates a missing checkout from its own branch, must carry the owner's branch. Any other sharing still keeps the worktree. Inactivity uses the latest activity of the owner and its subagents, and the re-check before removal applies the same rule. Fixes pingdotgg#16472 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — This is a localized bug fix to existing worktree cleanup, adding conservative subagent ownership and activity handling while preserving the existing filesystem, Git, session, and busy-state safeguards. The accompanying tests cover the new lineage and sharing cases, and documentation is the only other non-test change. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review. 📝 WalkthroughWalkthroughStorage cleanup now considers a worktree eligible when one idle non-subagent owner shares it only with eligible idle subagents. Cleanup checks activity across all sharers and revalidates ownership and activity before removal. ChangesShared-worktree cleanup
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: ⚪ Minimal · up to The changed cleanup guard is present, and no actionable merge-blocking issue was established. The change is ready for normal merge checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to Cleanup remains narrowly constrained by ownership, activity, and filesystem checks. However, a resumed subagent can race with removal of its shared checkout. Existing recovery controls reduce the impact, but do not fully coordinate these operations. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Problem
Automatic storage cleanup never removes the worktree of a thread that used a subagent (#16472).
V2 stores every subagent thread (provider-native ones, and
delegate_taskchildren) with its parent'sworktreePath.cleanWorktrees(apps/server/src/storageCleanup.ts:215-222) only considered a worktree path that exactly one thread owned, and the re-check before removal requiredlatest.length === 1. So any thread with a subagent kept its worktree forever, whatever its age, merge state or status. That rule came from V1 (#11598), where subagents were not app threads. On the reporter's machine, 17 of 23 finished worktrees in one project were shared with 1–12 subagent threads, and all 133 subagent threads with a worktree used their parent's path.Change
storageCleanupWorktreeOwner(sharers, threadsById, now)decides who owns a checkout:idle/failedstatus, no pending background task or runtime request, and no queued turn. These are the same checks as before, without the branch requirement.ProviderTurnStartServicerecreates a missing checkout only from the thread's ownbranch, so a delegated subagent must have the owner's branch. Provider-native subagents cannot take messages, so theirbranch: nullis fine.storageCleanupThreadIdlekeeps its behavior. Its activity checks moved into a privatestorageCleanupThreadBusyso subagents can reuse them.worktreeAfterDaysnow measures from the latest activity of the owner and its subagents. The re-check before removal runs the same owner rule on a fresh snapshot and compares that activity. The session, terminal, Git, ignored-file and policy checks are unchanged. The storage guide sentence about shared worktrees now covers subagents.Related, not changed here:
completedthreads, so most real owners also wait on that fix. fix(server): free worktrees for terminal thread statuses #15150 edits the status line that moved intostorageCleanupThreadBusy, so expect a trivial conflict.main, so an archived subagent would not be seen here until that lands. That is the same existing gap that already hides archived top-level sharers.Scope and approval
Fixes #16472. The issue was filed today and is not triaged yet. I am happy to adjust the ownership rule if maintainers prefer another direction.
Verification
vp test run apps/server/src/storageCleanup.test.ts: 16 passed. NewV2 storage cleanup worktree ownercases:nullor a different branch → keptcounts the owner's idle subagents, including nested ones, toward the ownerfails.tsc --noEmitinapps/server: no errors in the changed files. The only errors are 10 insrc/process/externalLauncher.test.ts, which already fail onmainat9bd1d8009a.vp lintandvp fmton the changed files are clean.Not checked: a live sweep in a running app, and a subagent turning busy between the Git checks and the re-check. The sweep needs Git, settings, terminal and session services, and no test harness covers it today.
Written by Claude Opus 5.5 in T3 Code's Claude Code harness, reviewed by GPT-6.1-Sol in T3 Code's Codex harness.
🤖 Generated with Claude Code