Skip to content

fix(ce-work): codify worktree isolation for parallel subagent dispatch#698

Merged
tmchow merged 5 commits intomainfrom
worktree-hidden-cuddling-brooks
Apr 26, 2026
Merged

fix(ce-work): codify worktree isolation for parallel subagent dispatch#698
tmchow merged 5 commits intomainfrom
worktree-hidden-cuddling-brooks

Conversation

@tmchow
Copy link
Copy Markdown
Collaborator

@tmchow tmchow commented Apr 26, 2026

Summary

  • Phase 1 Step 4's parallel-subagent flow described shared-directory dispatch with reactive collision recovery; worktree isolation only happened when the model spontaneously chose isolation: "worktree" (an emergent Opus behavior, not a skill instruction).
  • Direct subagent dispatch to use isolation: "worktree" and run_in_background: true on Claude Code's Agent tool, with a documented fallback for platforms without built-in worktree primitives (Codex spawn_agent, Pi subagent).
  • Reframe the "Parallel subagent constraints" block as the shared-directory fallback (no commits, no test runs by subagents) and add a new worktree-aware post-batch flow that resolves overlap at merge time instead of via the discovered-collision cross-check.

Stable/beta sync: applied identically to ce-work and ce-work-beta — the parallel-subagent body is shared verbatim between them.

Test plan

  • bun run release:validate — passes (no manifest drift; doc-only edits)
  • bun test — 939 pass, 0 fail
  • Diff is two-file, +36/-8, scoped to Phase 1 Step 4 of both SKILL.md files

There is no code-level regression test for skill behavioral instructions; the verification is editorial review of the new isolation directive and the worktree-mode post-batch flow.

Fixes #682

CE

Phase 1 Step 4's parallel-subagent flow described shared-directory dispatch
with reactive collision recovery, leaving worktree isolation as emergent
model behavior. Direct subagent dispatch to use isolation: "worktree" on
Claude Code's Agent tool (with run_in_background: true), reframe the
existing constraints as the shared-directory fallback for platforms without
worktree support, and add a worktree-aware merge path that resolves overlap
at merge time instead of via the discovered-collision cross-check.

Stable/beta sync: applied identically to ce-work and ce-work-beta — the
parallel-subagent body is shared.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f569c294b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/compound-engineering/skills/ce-work/SKILL.md
Comment thread plugins/compound-engineering/skills/ce-work/SKILL.md Outdated
tmchow added 2 commits April 25, 2026 21:59
- Phase 2's "Parallel subagent mode" note now splits commit ownership by
  isolation mode, matching Phase 1 Step 4: worktree-isolated subagents
  commit inside their own worktree branch (orchestrator merges after the
  batch); shared-directory fallback subagents do not commit (orchestrator
  stages and commits after the batch). Resolves the contradiction where
  Phase 2 flatly forbade subagent commits while Phase 1 Step 4's new
  worktree-isolated branch allowed them.
- Worktree cleanup step now uses the absolute path returned in the
  subagent's result, with a `git rev-parse --show-toplevel` fallback
  for platforms whose subagent primitive does not return a path. The
  prior `git worktree remove .claude/worktrees/agent-<id>` was
  CWD-relative and failed when /ce-work ran from a subdirectory.

Both edits propagated to ce-work-beta — the affected sections are
shared verbatim between stable and beta.
…allel mode

The previous worktree-isolated wording had two gaps surfaced during
post-merge validation of #698:

1. Post-batch step 3 said "resolve conflicts at merge time" without
   saying how. Hand-resolving silently picks a side and discards one
   unit's intent. Now: abort the merge and re-dispatch the conflicting
   unit serially against the now-merged tree — the worktree-mode
   equivalent of shared-directory's "re-run affected units serially"
   recovery.

2. The Parallel Safety Check unconditionally downgraded to serial on
   any file overlap. That rule was written for shared-directory write
   races. With worktree isolation, overlap is no longer a write race —
   it's a predictable merge conflict the orchestrator handles. Split
   the rule: downgrade to serial only when isolation is unavailable;
   when it's available, proceed in parallel and log the predicted
   overlap so the post-batch flow knows where to expect conflicts.

Stable/beta sync: applied identically to ce-work and ce-work-beta.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70d5c5ef4b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/compound-engineering/skills/ce-work/SKILL.md Outdated
tmchow added 2 commits April 25, 2026 22:28
A live probe with isolation: "worktree" surfaced three issues with the
post-batch worktree cleanup step:

1. The Claude Code harness locks per-subagent worktrees with the reason
   "claude agent agent-<id> (pid <n>)". Plain `git worktree remove
   <path>` fails with "cannot remove a locked working tree." The skill
   now uses `--force --force` to override the lock; safe because the
   work is already merged at that point.

2. The previous fallback `git rev-parse --show-toplevel` returned the
   *orchestrator's worktree*, not the main repo, when the orchestrator
   itself ran from a worktree (e.g., one created by /ce-worktree). The
   resulting path was wrong and cleanup silently failed. The skill now
   uses `dirname "$(git rev-parse --path-format=absolute
   --git-common-dir)"`, which returns the main-repo root from both
   main checkouts and worktrees.

3. `git worktree remove` removes the working directory but leaves the
   `worktree-agent-<id>` branch behind. Without explicit cleanup,
   these accumulate (the compound-engineering repo currently has 26+
   such orphan branches). The skill now adds `git branch -D
   <branch-name>` after worktree removal, using the branch name the
   harness returns alongside the path.

Verified empirically: dispatched a real subagent with isolation:
"worktree" from inside .claude/worktrees/hidden-cuddling-brooks;
the harness placed the per-subagent worktree at <main-repo>/.claude/
worktrees/agent-<id> (sibling to the orchestrator's worktree, not
nested), and returned both the absolute path and branch name in the
result.

Stable/beta sync: applied identically to ce-work and ce-work-beta.
Self-review surfaced four follow-ups on the worktree-isolated post-batch
flow that landed in 666c669:

1. Step 6 was a single dense bullet covering five concerns (worktree
   removal, lock override, branch deletion, fallback path derivation,
   `--show-toplevel` rationale). Split into three sub-bullets, one
   command each.

2. `git worktree remove --force --force` and `git branch -D` together
   bypass git's "uncommitted changes" check, "is this worktree locked"
   check, and "is this branch merged" check. If a future flow change
   ever invokes cleanup before merging, the work would silently
   disappear. Switched to `git worktree unlock <path>` then plain
   `git worktree remove <path>` (overrides only the lock, not other
   safety checks), and `git branch -d <name>` (lowercase: refuses
   unmerged branches). All three commands fail loudly if state is
   wrong rather than discarding work.

3. Removed the cross-platform fallback path derivation
   (`dirname "$(git rev-parse --path-format=absolute --git-common-dir)"`).
   It only applied to a hypothetical platform that exposes worktree
   isolation but doesn't return the worktree path — no platform we
   target hits that path. Codex/Pi already use the shared-directory
   fallback, where worktrees aren't created at all.

4. Trimmed the trailing audience-enumeration sentence from Phase 2's
   "Parallel subagent mode" note. The bullet split above already
   covers commit ownership; restating "applies to inline, serial,
   worktree-isolated subagents, and shared-directory orchestrator
   commits" reads as defensive boilerplate.

Stable/beta sync: applied identically to ce-work and ce-work-beta.
@tmchow tmchow merged commit 053c1db into main Apr 26, 2026
2 checks passed
@github-actions github-actions Bot mentioned this pull request Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ce-work): codify worktree isolation for parallel subagent dispatch

1 participant