Skip to content

integration-test skill misses 'wrong binary' (worktree pointing at parent repo's binary) #154

@obj-p

Description

@obj-p

Problem

The integration-test skill's Step 2 uses `preview_build_info` to detect a stale binary (running process older than its on-disk binary, addressed in #147 / #150). It does not detect a worse failure mode: the running MCP server is the wrong binary entirely — sitting in a different directory than the developer is working in.

Reproduction

  1. Make a worktree nested in the repo: `git worktree add .claude/worktrees/feat -b fix/feat`
  2. `cd .claude/worktrees/feat`, edit code, `swift build`
  3. Launch (or `/resume`) Claude Code; run `/integration-test`
  4. Step 2 reports `stale: false` ✓ — but `preview_build_info`'s `binaryPath` is `/.build/.../previewsmcp`, not the worktree's. `mcp__previewsmcp__*` tool calls hit the parent's binary throughout the run.

Hit live during PR #153 validation. The skill produced a green report against a binary that didn't have any of the PR's changes.

Why it happens

`.mcp.json` uses a relative `command: ".build/debug/previewsmcp"`. Claude Code resolves that against the main repo's project root, not the worktree's. `/resume` makes it worse: it preserves the original launch project root regardless of where the user re-launched from. `${workspaceFolder}` and similar variables don't reliably expand in `.mcp.json` (anthropics/claude-code#3239, #9427), and the spawned MCP server inherits Claude Code's CWD, so wrapper scripts using `$PWD` don't help. Net: no in-repo fix to the resolution itself; this is upstream Claude Code behavior.

Proposed fix (skill-side)

Extend the integration-test skill's Step 2 with a second check after `preview_build_info`:

  • Compute `expectedBinary` from the skill's working directory: `/.build//debug/previewsmcp`, resolving symlinks.

  • Compare against `binaryPath` from `preview_build_info`. If different, abort:

    MCP server is running `` but you're working in ``. Tool calls won't reflect your changes. Type `/exit`, `cd` to the worktree directory, and relaunch `claude` (avoid `/resume` — it preserves the original project root).

  • Keep the existing `stale: true` check; this is an independent failure mode.

No change to `preview_build_info` itself — keep it use-case-agnostic. The skill is the only programmatic caller and the only place that has the developer-mode context (CWD, expected build layout) needed to make this judgment.

Documentation

Add a short section to `AGENTS.md` near the existing "Refresh stdio" guidance: worktree-based development needs a fresh `claude` launch from the worktree directory; `/resume` preserves the original project root and silently sends MCP tool calls to the parent's binary. Reference this issue.

Out of scope

The upstream Claude Code path-resolution / `/resume` behavior. Tracking that in a separate report against `anthropics/claude-code`.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions