[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
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:
- the behavior the text describes — the chip session starts in a fresh linked worktree (of the
cwdrepo, for chip A); or - 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
cwddescription, 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 addinstructions 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-
cwdcase, 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 untestedcwd-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.