feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(worktrees): manage lifecycle on orchestrator v2 - #5589

Open
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2
Open

feat(worktrees): manage lifecycle on orchestrator v2#5589
StiensWout wants to merge 272 commits into
pingdotgg:t3code/codex-turn-mappingfrom
StiensWout:t3code/worktree-management-v2

Conversation

@StiensWout

@StiensWoutStiensWout commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Stacked pull request. This targets t3code/codex-turn-mapping from #2829. After #2829 merges, rebase this branch and retarget the PR to main.

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

  • Derive a per-environment inventory from Git and V2 thread projections.
  • Protect worktrees with active threads, local changes, unpushed commits, or unavailable status. Revalidate immediately before non-forced removal.
  • Apply configurable retention and optional immediate cleanup after the last linked thread is deleted.
  • Recreate a missing worktree from its retained branch before provider startup, then restart the shared provider session when its working directory changes.
  • Add a project-grouped Worktrees inventory to Settings → Source Control for every compatible connected environment: one line per worktree (branch, linked thread, last use, sync state, and either Remove or the blockers), two plain settings rows for the cleanup policy, and rows that disappear as soon as removal is confirmed.
  • Treat a detached worktree like a branch without an upstream: safe once its commit is on the default branch, otherwise blocked as unmerged. Previously it was marked status-unavailable forever.
  • Read the inventory with one git status per 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.
  • Keep local branches and checkpoint refs so cleanup remains reversible through automatic revival.

The refresh also removes the unused public revive RPC, fixes provider-start supersession after a mandatory session reopen, parses git worktree list --porcelain -z everywhere (main already requires -z in listRefs), 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

  • All worktree mutations share one server-side permit.
  • Inventory combines projects that share a Git common directory, including nested project roots.
  • Paths are canonicalized, and revival rejects symlink-ancestor escapes outside the managed worktree root.
  • Automatic and manual cleanup never force-removes a worktree or deletes its branch.

Screenshots

LightDark
Worktree settings, lightWorktree settings, dark

Verification

  • Targeted typechecks pass for server, contracts, client runtime, and web.
  • Targeted lint, formatting, and diff checks pass.
  • The isolated worktree dev environment starts and serves the app successfully.
  • Added tests were reduced by 669 lines, keeping focused Git, lifecycle, cleanup, revival, and destructive-safety coverage. Later rounds add coverage for detached worktrees, mixed repository and plain-directory projects, and NUL-terminated worktree listings.

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

  • Introduces WorktreeService, WorktreeRevivalService, WorktreeLifecycle, WorktreeReaper, and WorktreeDeletionCleanup services that handle listing, pruning, reviving, and reaping worktrees on the server
  • ProviderTurnStartService now revives the thread's worktree before starting a provider turn, serializes session starts per ProviderSessionId, and closes/reopens the provider session when the worktree was revived or its generation/path changed
  • Adds three WebSocket RPCs (vcs.listWorktrees, vcs.subscribeWorktreeInventory, vcs.pruneWorktrees) with auth scopes, and a worktreeManagement capability flag so clients gate features on server support
  • Adds client UI in Source Control settings for viewing worktree inventory, configuring retention (autoPruneAfterDays default 14, deleteOrphanedImmediately default false), and pruning; useThreadActions skips legacy client-side orphan cleanup when the capability is present
  • GitWorkflowService methods (preparePullRequestThread, createWorktree, removeWorktree) now run under a WorktreeLifecycle mutation permit and signal inventory changes
  • Risk: ProviderTurnStartService no longer emits provider-session.updated and provider-thread.updated events during the initial running transition; consumers relying on those events in that phase will need to use run.updated, run-attempt.updated, or node.updated instead

Macroscope 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. GitWorkflowService routes create/remove/prepare-PR-thread work through WorktreeLifecycle (serialized mutations + inventory revision stream).

Orchestration:ProviderTurnStartService calls WorktreeRevivalService.reviveForThread, then serializes startup per ProviderSessionId via KeyedSerialExecutor. 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:WorktreeDeletionCleanup reacts to thread.deleted events; WorktreeReaper periodically prunes inactive safe worktrees per settings. Both delegate to WorktreeService for last-moment safety checks.

Product surface: Enables worktreeManagement server capability and RPC auth for vcsListWorktrees, subscribeWorktreeInventory, and vcsPruneWorktrees. Layers wired in server.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.

@coderabbitai

coderabbitaiBot commented Aug 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 241aad84-47f4-4428-b412-3c651f409505

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 7, 2026
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeRevivalService.ts Outdated
Comment threadapps/server/src/vcs/WorktreeLifecycle.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 25de21d to 0af2a6eCompareAugust 7, 2026 12:10
@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. and removed vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 9, 2026
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 0f4d58b to 8f7ca24CompareAugust 10, 2026 09:10
Comment threadapps/server/src/vcs/WorktreeDeletionCleanup.ts
Comment threadapps/web/src/components/SidebarV2.tsx Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch from 22bd872 to a27c1ccCompareAugust 10, 2026 17:05
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from 61184a3 to d56b638CompareAugust 11, 2026 11:57
@StiensWoutStiensWout changed the title [WIP] Manage worktree lifecycle on orchestrator V2[WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWoutStiensWout changed the title [WIP] feat(worktrees): server-managed worktree lifecycle on orchestrator v2feat(worktrees): server-managed worktree lifecycle on orchestrator v2Aug 11, 2026
@StiensWout
StiensWout marked this pull request as ready for review August 11, 2026 12:03

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadpackages/contracts/src/worktrees.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

Comment threadapps/server/src/vcs/WorktreeService.ts

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/server/src/vcs/GitVcsDriver.ts Outdated
Comment threadapps/server/src/orchestration-v2/ProviderTurnStartService.ts
Comment threadapps/server/src/vcs/GitVcsDriverCore.ts Outdated
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a186d64 to 5b1a115CompareAugust 12, 2026 23:19
StiensWoutand others added 5 commits August 28, 2026 12:14
Replace 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>
@StiensWout
StiensWoutforce-pushed the t3code/worktree-management-v2 branch from af91468 to 9fa4806CompareAugust 28, 2026 11:08

@macroscopeappmacroscopeappBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx Outdated
Comment threadapps/server/src/serverRuntimeStartup.ts Outdated
Comment threadapps/server/src/vcs/WorktreeReaper.ts Outdated
Comment threadapps/server/src/vcs/WorktreeService.ts
StiensWoutand others added 4 commits August 28, 2026 13:19
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>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Fix All in Cursor

❌ 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.

Comment threadapps/server/src/vcs/GitWorktree.ts
StiensWoutand others added 2 commits August 28, 2026 13:27
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>
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from a26d9ad to d6ed793CompareAugust 29, 2026 06:34
@juliusmarminge
juliusmarmingeforce-pushed the t3code/codex-turn-mapping branch 6 times, most recently from ceea97b to d2f1f51CompareSeptember 2, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@StiensWout@juliusmarminge@maria-rcks@mwolson@PixPMusic@nsxdavid@Yusuf007R