Worktree sessions can edit files in the parent main checkout with no guardrail
Summary
When a Claude Code session is launched inside a git worktree, the harness sets the working directory to the worktree, announces "You are operating in a git worktree" in the system prompt, and includes the worktree path. But it does not prevent the agent from issuing Edit/Write/NotebookEdit calls against absolute paths that point into the parent main checkout (outside the worktree).
The result: an agent can dirty the working tree on whatever branch the main checkout has checked out (typically master/main), bypassing the branch isolation the worktree was supposed to provide. There is no prompt, no warning, no confirmation — the edit just lands.
Repro
- From a main checkout on
master(clean), launch a Claude Code session inside a worktree:
````
<repo-root>/.claude/worktrees/<wt-name>/
- Ask the agent to edit a source file. The agent, working from
cd-style context or absolute paths, can call:
```
Edit { file_path: "<repo-root>/io_utils.py", ... }
`
instead of
``
Edit { file_path: "<repo-root>/.claude/worktrees/<wt-name>/io_utils.py", ... }
- The harness accepts the call.
git statusin the main checkout now showsmodified: io_utils.pyonmaster.
Expected
One of:
- Block
Edit/Write/NotebookEditcalls whose resolved absolute path is inside the parent main checkout but outside the active worktree, with a clear rejection message. - At minimum, prompt the user for confirmation (similar to the existing prompts for sensitive paths).
The detection is simple: git rev-parse --show-toplevel vs git rev-parse --git-common-dir differ inside a worktree; the worktree root and main-checkout root are both knowable.
Why this matters
The whole point of EnterWorktree / running a session in a worktree is branch isolation — keep the agent's edits on a feature branch, ship a PR, leave master clean. Today that guarantee is advisory only: it relies on the agent's good behavior and absolute-path discipline. Users currently have to write their own PreToolUse hooks to enforce what the harness implies but doesn't enforce.
Workaround (for other users hitting this)
A PreToolUse hook on Edit/Write/NotebookEdit that compares the resolved file_path against git rev-parse --show-toplevel and rejects anything outside the worktree but inside the parent main checkout. Roughly 20 lines of Python. But this should be a harness-level guarantee, not a per-user patch.
Environment
- Platform: Windows 11, PowerShell + Git Bash
- Worktrees managed via the built-in worktree workflow (
.claude/worktrees/<name>/) - Reproduces with both Sonnet and Opus
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗