Uh oh!
There was an error while loading. Please reload this page.
feat(worktrees): manage lifecycle on orchestrator v2 - #5589
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Reviewed the new worktree services against the Effect service conventions. Four convention issues found: two standalone *Shape service interfaces, a redundant singleton operation discriminator plus free-form message on the new worktree error classes, and a hidden optional service dependency in ProviderTurnStartService.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Effect service conventions review of the worktree management services. Prior findings on WorktreeLifecycle/WorktreeRevivalService shape interfaces, the unstructured worktree error payloads, and the Effect.serviceOption acquisition of WorktreeRevivalService all look addressed. A few smaller convention issues remain.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
25de21d to
0af2a6eCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
0f4d58b to
8f7ca24CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
22bd872 to
a27c1ccCompare61184a3 to
d56b638CompareThere was a problem hiding this comment.
One finding: raw git stderr is copied into a new error attribute. Everything flagged in earlier runs (service-shape interfaces, make/layer naming, the single-use mutationError helper, the parseWorktreeBranchPaths shim, structural stages on the new worktree errors, and the hidden WorktreeRevivalService requirement) is resolved in this revision.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Reviewed the Effect service conventions in this update. Previously flagged items (inline service interfaces, plain make/layer names, structural error stages with derived messages, required WorktreeRevivalService acquisition in ProviderTurnStartService, shared worktree porcelain parser, bounded git worktree list error context) all look resolved. One remaining error-modeling nit below.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This change adds a substantial server-owned worktree lifecycle with automatic filesystem cleanup, worktree recreation, provider-session restarts, new authorized RPCs, and a production settings surface. Its broad cross-cutting behavior and destructive side effects exceed the scope of a low-risk additive change. You can add or adjust custom eligibility rules. Learn more. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
One finding on the new GitVcsDriver.listWorkspaces truncation error: its context fields are hardcoded/fabricated rather than derived from the actual command and output.
Posted via Macroscope — Effect Service Conventions
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
a186d64 to
5b1a115CompareReplace the stacked two-line rows with one line per worktree (branch, thread, last use, sync state, action), put the cleanup policy back into two plain settings rows with short copy, drop the row icons and workspace path, and show every blocker instead of a +N suffix. Removed rows disappear as soon as the server confirms removal, and mounting the section no longer issues a second inventory read for the first subscription revision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Detached worktrees were tagged status_unavailable and could never be removed. Compare their HEAD against the default ref like a branch without an upstream: safe once merged, otherwise blocked as unpushed. The inventory read statusDetailsLocal per worktree, which spawns git five times for diffs and remote lookups it never used. Read one git status instead, run it alongside the ahead-of-default count, and issue the per-group listing, branch sync, and default ref lookups together. On a 2-vCPU dev environment with 8 worktrees the inventory dropped from 5.0 s to 0.6 s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
af91468 to
9fa4806CompareThere was a problem hiding this comment.
One finding on the worktree refresh header action; the rest of the changed web UI looks consistent with the shared primitives.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
The base branch's listRefs already requires Git 2.36 for -z and tests that a worktree path containing a newline round-trips, so the newline-separated parser kept for Git 2.34 compatibility no longer buys anything and fails that test. Parse NUL-terminated records everywhere instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reaper forked its own sweep loop during startup, so a runtime that never reached activation could still prune worktrees. Expose the loop and fork it with forkParked like the worker and relay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The set of locally hidden removed paths kept any path the inventory still listed, so a worktree revived at the same path stayed hidden until remount. Clear the set on the next inventory read instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Typing the optional settings layer with an unknown error channel trips the Effect diagnostics on every test that provides it. Derive it from layerTest. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a274d35. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
The reaper sweep, the inventory status read, and the prune revalidation caught every cause, including interruption, so a scope close or shutdown during a sweep could be swallowed and the loop kept running. Re-raise interrupt-only causes and keep degrading everything else. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A project rooted outside any repository made the whole worktree inventory fail, hiding every managed worktree from Settings. Skip such projects; a listing failure inside a real repository still fails the inventory. Also re-raise interrupt-only causes in the inventory status read and the prune revalidation instead of degrading them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a26d9ad to
d6ed793Compareceea97b to
d2f1f51Compare
Important
Stacked pull request. This targets
t3code/codex-turn-mappingfrom #2829. After #2829 merges, rebase this branch and retarget the PR tomain.Problem
Thread worktrees accumulate without a server-owned way to inspect or clean them. The previous cleanup prompt only worked in the desktop client, and a removed worktree could strand the next provider turn.
Solution
git statusper worktree, concurrently with the ahead-of-default count, and fetch the per-repository listing, branch sync, and default ref together. On a 2-vCPU environment with 8 worktrees the inventory went from 5.0 s to 0.6 s. Mounting the section no longer issues a duplicate read.The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses
git worktree list --porcelain -zeverywhere (main already requires-zinlistRefs), keeps the reaper behind the activation boundary, lets interrupts stop sweeps and status reads, and skips projects outside a Git repository instead of failing the inventory.Safety
Screenshots
Verification
Initial implementation and the refresh were produced with GPT-5.6 Sol via Codex in T3 Code. The one-line settings layout, detached-HEAD handling, inventory speed-up, and review follow-ups were done by Claude Fable 5 via Claude Code in T3 Code.
Note
Add server-side worktree lifecycle management to orchestrator v2
WorktreeService,WorktreeRevivalService,WorktreeLifecycle,WorktreeReaper, andWorktreeDeletionCleanupservices that handle listing, pruning, reviving, and reaping worktrees on the serverProviderTurnStartServicenow revives the thread's worktree before starting a provider turn, serializes session starts perProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changedvcs.listWorktrees,vcs.subscribeWorktreeInventory,vcs.pruneWorktrees) with auth scopes, and aworktreeManagementcapability flag so clients gate features on server supportautoPruneAfterDaysdefault 14,deleteOrphanedImmediatelydefault false), and pruning;useThreadActionsskips legacy client-side orphan cleanup when the capability is presentGitWorkflowServicemethods (preparePullRequestThread,createWorktree,removeWorktree) now run under aWorktreeLifecyclemutation permit and signal inventory changesProviderTurnStartServiceno longer emitsprovider-session.updatedandprovider-thread.updatedevents during the initial running transition; consumers relying on those events in that phase will need to userun.updated,run-attempt.updated, ornode.updatedinsteadMacroscope summarized bdc613b.
Note
High Risk
Touches provider turn startup, shared session close/reopen, and automatic worktree deletion; race-sensitive paths are tested but mistakes could strand runs or remove worktrees incorrectly.
Overview
Adds server-owned Git worktree lifecycle for orchestration v2: inventory from
git worktree list, safe pruning rules, automatic retention/orphan cleanup, and revival of missing thread worktrees before provider turns run.Git & workflow: New
listWorkspaces/ shared porcelain parsing (GitWorktree.ts), with output-size limits.GitWorkflowServiceroutes create/remove/prepare-PR-thread work throughWorktreeLifecycle(serialized mutations + inventory revision stream).Orchestration:
ProviderTurnStartServicecallsWorktreeRevivalService.reviveForThread, then serializes startup perProviderSessionIdviaKeyedSerialExecutor. If a worktree was revived or its generation/path changed, it closes and reopens the shared provider session so cwd stays correct, with careful handling when runs are superseded mid-restart.Background jobs:
WorktreeDeletionCleanupreacts tothread.deletedevents;WorktreeReaperperiodically prunes inactive safe worktrees per settings. Both delegate toWorktreeServicefor last-moment safety checks.Product surface: Enables
worktreeManagementserver capability and RPC auth forvcsListWorktrees,subscribeWorktreeInventory, andvcsPruneWorktrees. Layers wired inserver.ts/ startup after the effect worker starts.Reviewed by Cursor Bugbot for commit bdc613b. Bugbot is set up for automated code reviews on this repo. Configure here.