Agent `isolation: "worktree"` intermittently does not isolate — subagent tool calls operate on parent tree
Summary
Agent tool dispatches with isolation: "worktree" intermittently fail to actually isolate. The harness creates the worktree (visible in git worktree list), but the subagent's Bash + Edit/Write tool calls operate against the parent session's working tree instead of the isolation worktree. Result: the parent tree is silently checked out onto the subagent's feature branch, accumulates edits, and (when the parent is the main tree) ends up holding a branch + commits it never authored.
Observed in Claude Code on Linux (isidore) and macOS, across multiple model variants (builder-haiku, builder-sonnet), and from both main-tree and sibling-worktree parent sessions. Intermittent within a single session — same parent, same subagent type can succeed and no-op back-to-back.
Environment
- Claude Code CLI, multiple recent versions over ~30 days (recurrence first noted 2026-04-23, most recent 2026-05-21)
- Linux (Ubuntu 6.8) and macOS parent sessions both affected
- Subagents:
builder-haiku,builder-sonnet— pattern not subagent-specific - Parent session contexts: detached HEAD on
origin/main, detached HEAD onorigin/staging, sibling-slot worktree on<slot>-idlebranch — all affected
Two distinct failure modes
A. Bash CWD bleed
Subagent's Bash calls (notably git checkout -b, git commit, git push) execute against the parent's CWD instead of the isolation worktree. Symptom: parent tree's git branch --show-current changes to the subagent's branch; isolation worktree (when one exists) remains empty.
B. Edit/Write absolute-path bleed
Even when (A) is correctly isolated and git operations land in the isolation worktree, the subagent's Edit and Write tool calls resolve target paths against the parent's project root, not the subagent's CWD. Symptom: subagent correctly commits N files to its isolation worktree's branch, but the same N files also appear as untracked / unstaged modifications in the parent tree.
Evidence of (B)
From a single dispatch — subagent committed a2927b5 cleanly to claude/convoy-a-agent-coord in .claude/worktrees/agent-a46b7485/, AND the parent tree (a different worktree entirely) accumulated:
D .claude/hooks/guard-main-checkout.sh
M .claude/settings.json
M scripts/worktree-bootstrap.sh
?? .claude/hooks/enforce-builder-isolation.sh
— the exact files the subagent's task instructed it to modify. The subagent's commit shows those changes properly applied; the parent's working tree shows a second copy of the same edits.
Repro
Not deterministic in our hands. Pattern observed across 8 recurrences in ~30 days. Intermittent counter-example: 4 consecutive no-ops in one session followed by a correctly-isolated dispatch with identical parameters.
Minimal repro shape (does not always reproduce):
- Open Claude Code in a git worktree (any worktree — main or sibling).
- Dispatch a subagent (
builder-haikuis fastest) withisolation: "worktree". Task: "create a new filetest.txt, commit, and report your CWD." - After dispatch completes, check:
git -C .claude/worktrees/agent-<id>/ log -1— did the commit land there?git branch --show-currentin parent — did the parent's branch change?git statusin parent — didtest.txtappear?
In our failure cases, the parent's branch changes and the file appears in the parent tree, while the registered isolation worktree is empty or has only the initial checkout.
Frequency
3 events logged in the first ~24h since we instrumented a detector hook (SubagentStop that compares pre/post branch + HEAD):
succeeded: 1
no-op-branch-changed: 2
Sample is too thin to publish a rate; over the preceding ~30 days there are 8 documented anecdotal recurrences (Bash CWD bleed) and 1 documented (B) Edit/Write bleed.
Suspected root cause (speculative)
Either (a) the Bash tool inherits the parent shell's CWD and never cds into the isolation worktree before invoking commands, or (b) the harness sets CWD for Bash but the Edit/Write tools resolve relative paths against a projectRoot resolved from the parent session rather than the isolation worktree's root. The (B) evidence above suggests these are separately broken — fixing only the Bash CWD wouldn't address Edit/Write bleed.
Impact
- Main-tree parent sessions accumulate stray branches + edits, violating our project rule that main tree never holds a feature branch.
- Sibling-worktree parent sessions get silently hijacked onto the subagent's branch mid-session, racing against the parent's own edits.
- Workarounds we've shipped (a
SubagentStopscrubber that restores idle slot state, a detector that logs no-op outcomes) contain the blast radius but don't fix the bug.
What we'd like
Confirmation of root cause (Bash CWD inheritance? Edit/Write path resolution? Race in the worktree-setup sequence?) and a deterministic fix at the harness level. Happy to share our event log + scrubber/detector hook implementations if useful.
References (our project's tracking)
Internal issue: <https://github.com/toddwilkens/quality-tools/issues/807> — full comment thread has 8 distinct recurrences with timestamps and parent/subagent context. Stopgap PR: <https://github.com/toddwilkens/quality-tools/pull/1446>.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗