[BUG] spawn_task text promises a "fresh worktree" (cwd param + ack), but chip sessions start on the primary checkout — even with cwd set to a git repo

Open 💬 0 comments Opened Jul 13, 2026 by jsalvata

Summary

The mcp__ccd_session__spawn_task tool's model-facing text unconditionally promises worktree isolation for chip-spawned sessions, but the spawned sessions start on the primary checkout (or the plain project root). #64605 reported the behavior side of this and was closed after a maintainer clarified that worktrees are opt-in ("Worktrees aren't on by default, you have to opt in"), with spawn-task UI/UX adjustments promised. As of 2.1.205 the tool's own strings still assert the opposite — which makes the model confidently mislead users and design chip prompts that assume isolation.

New data point relative to #64605: setting the tool's cwd parameter to a valid git repo does not produce a worktree either, even though that parameter's description is where the promise is made.

The two strings

cwd parameter description in the tool schema:

Optional. Absolute path to a different project root than the current session's. The spawned session gets a fresh worktree under this path. Defaults to the current project — only set this when the work clearly belongs in another repo on the user's machine.

Tool result returned to the model on every spawn_task call:

Noted (position 1, task_id: task_…). A chip is showing for the user — they can start it in a fresh worktree with one click, or dismiss it. …

Controlled test (2026-07-13, macOS)

Setup: the session's project root is ~/dev/<workspace> — a plain parent directory holding many cloned repos, not itself a git repo (possibly relevant to the silent fallback). ~/dev/<workspace>/app is a normal git repo, currently on master, with 5 pre-existing linked worktrees under app/.claude/worktrees/. A baseline git worktree list was captured before the test. Two chips were created; both prompts instructed the spawned session to run diagnostics from its starting directory and explicitly forbade creating a worktree itself, so the observation couldn't be contaminated by the model self-provisioning one.

Chip A — cwd: ~/dev/<workspace>/app (exactly the case the schema text describes). The spawned session reported:

pwd                            → ~/dev/<workspace>/app   (primary checkout)
git rev-parse --show-toplevel  → ~/dev/<workspace>/app
git rev-parse --git-dir        → .git
git rev-parse --git-common-dir → .git    (== git-dir ⇒ NOT a linked worktree)
git branch --show-current      → master  (the primary checkout's current branch)
node_modules                   → present (shared tree, not a fresh checkout)

git worktree list, run from the parent session before and after the chip session ran: identical — still exactly the 5 pre-existing worktrees. Nothing was created anywhere.

Chip B — no cwd (default): the spawned session started in ~/dev/<workspace> itself. Its environment block says Is a git repository: false and every git rev-parse fails with "not a git repository".

Expected vs actual

Expected either of:

  1. the behavior the text describes — the chip session starts in a fresh linked worktree (of the cwd repo, for chip A); or
  2. text that matches the real, opt-in contract per the #64605 resolution.

Actual: the text promises (1) unconditionally; the behavior is neither — the session lands directly on the primary checkout's current branch.

Impact

  • The model repeats the false promise verbatim to users. That is first-hand: in the reporting session the user asked "if you create a chip for repo X, will it run on a worktree?", the model answered "yes — guaranteed by the harness", citing the cwd description, and a controlled test then proved it wrong.
  • Chip prompts written on the assumption of isolation make code-changing chips edit the shared checkout on its current branch — the exact contamination #64605 warned about, plus the concurrent-chips-clobbering-each-other case a commenter reported there.
  • Suggested fix beyond re-wording the two strings: include in the task-started notification whether the spawned session actually got a worktree, so the parent model can adapt (e.g., inject manual git worktree add instructions into chip prompts when it won't).

Environment

  • Claude Code 2.1.205, desktop app, macOS (Darwin 25.5.0)
  • Model: claude-fable-5
  • Session root: non-git parent directory (multi-repo workspace layout)

Related (not duplicates)

  • #64605 (closed, completed) — same observable for the no-cwd case, framed against the desktop docs; closed with "worktrees are opt-in" + planned UX clarification. This report covers the tool's own model-facing strings still claiming unconditional worktrees after that resolution, plus the untested cwd-override path.
  • #70456 — worktree isolation silently disabled when the lead CWD is stranded under .claude/worktrees/; different trigger, same "silently not isolated" failure class.
  • #57643, #52243 (closed) — assume chip worktrees are created; discuss which branch they're based on.
  • #70118 — chip "start locally" confirmation UX.
  • #67432 — chip-spawned sessions also start degraded on another axis (no external MCP servers until first user message).

Notes

A full session export (transcript + logs, ~30 MB zip) demonstrating the whole exchange end-to-end is available on request — not attached because it contains employer-internal context. The repro is deterministic without it: in any workspace whose root is not a git repo, call spawn_task with cwd pointing at a git repo inside it, click the chip, and run the four git rev-parse commands above in the spawned session.

---
🤖 Filed by Claude Code on jsalvata's behalf — the "model misled the user" incident described above is first-hand from the filing session.

View original on GitHub ↗