CB-525: isolate a worker's tool surface to what its launcher mounts

A worker in a provisioned worktree was inheriting the primary's MCP servers by
two independent routes: the repo commits a .mcp.json declaring the IDE servers,
so a fresh checkout mounts them, and the default parity overlay then copied the
primary's own copy over the top.

Those servers are bound to the primary's IntelliJ project, so every path they
hand back points into the primary's checkout. A CB-523 worker made all 59 of its
edits there while running `mvn -f bridged/pom.xml` against its worktree — every
build it ran was of code that did not contain its changes, and it passed. The
worker's own `ls` of the file it had "edited" returned "No such file".

GitWorktrees now neutralizes .mcp.json at provisioning: an explicitly empty
server map, --skip-worktree'd when tracked so it never reads as pending work a
worker might commit. Unconditional, because the overlay was only half the leak.
The bridge itself is unaffected — it reaches a worker through the launcher's
--mcp-config flag, not the project file, so bridge_reply still works.

- BridgedConfig: .mcp.json out of the default parity overlay
- GitWorktrees: isolateToolSurface() on add(), with the rationale in javadoc
- GitWorktreesTest: 4 real-git acceptance tests (2 fail if the call is removed)
- implementer skill: work from $PWD, and quote a green unpiped `mvn clean
  install` from the worktree as the acceptance criterion

mvn clean install: Tests run: 392, Failures: 0, Errors: 0 — BUILD SUCCESS
This commit is contained in:
Dai Ha
2026-08-08 20:42:44 +02:00
parent ccf50f950e
commit 4e6201ecd1
6 changed files with 217 additions and 16 deletions
+37 -9
View File
@@ -9,11 +9,13 @@ The turn contract (one `bridge_reply`, `bridge_ask` for the lead's decisions, ho
never merge, never commit `.mcp.json` or `wiki/`) is in **`CLAUDE.md` → Bridge communication →
Worker** and already applies. This skill is only the *implement-and-hand-off procedure*.
You run in an **isolated git worktree on your own branch** — a full peer of the primary (same
repo, `CLAUDE.md`, skills, MCP), differing in the model behind you and the branch you sit on.
You run in an **isolated git worktree on your own branch** — a full peer of the primary (same repo,
`CLAUDE.md`, skills), differing in the model behind you and the branch you sit on. Your MCP surface
is **only what your launcher mounted** (the bridge): the primary's IDE and forge servers are not
yours, and the worktree's `.mcp.json` is deliberately emptied so you cannot inherit them.
The worktree model is documented in [`docs/Worker-Git-Workflow.md`](../../../docs/Worker-Git-Workflow.md).
## 1. Confirm where you are
## 1. Confirm where you are — then never leave
Before touching anything:
@@ -26,13 +28,36 @@ git status # should be clean at the start
Do **all** work here, on this branch. Never `git checkout main`, never rebase onto or push to
`main`. The branch is your isolation — respect it.
**Every path you read, edit, or build is relative to that root.** Work from `$PWD`; if a tool, a
brief, or your own memory hands you an absolute path, check it starts with your worktree root
before you touch it, and stop if it doesn't. An absolute path pointing anywhere else is the
primary's checkout — editing there while building here means **every build you run is of code that
does not contain your changes**, and it passes while your work goes nowhere. This has happened:
a worker made all 59 of its edits in the primary's tree and never noticed.
```bash
test "$(git rev-parse --show-toplevel)" = "$PWD" || cd "$(git rev-parse --show-toplevel)"
```
## 2. Implement
- Implement exactly the scope the lead named. Keep the diff focused; note anything out of scope
in your reply instead of widening it.
- Match the surrounding code's style, naming, and idioms.
- Run whatever build/test you can — `mvn clean install` from the module root. Read its **full**
output; a piped `mvn ... | tail` hides failures.
**Acceptance criterion — a green build, quoted.** Your work is not done until this passes *inside
your worktree*:
```bash
cd "$(git rev-parse --show-toplevel)/bridged" && mvn clean install
echo "exit=$?"
```
Read its **full** output — never pipe it through `tail`/`head`/`grep`, which hide a failure behind
a zero exit. Then quote the real `Tests run: … Failures: … Errors: …` line and the
`BUILD SUCCESS`/`FAILURE` verbatim in your reply. If it does not go green, say so with the actual
error; a failing build honestly reported is a usable result, a claimed-green one is not. You have
no IDE MCP tools, so `mvn` is your only verification — never claim a check you had no way to run.
## 3. Commit
@@ -41,7 +66,8 @@ git add <the files you changed> # explicitly — never `git add -A` / `git a
git commit -m "<ticket>: <clear one-line summary>"
```
`.mcp.json` will show as modified. Leave it — it is `--skip-worktree` and not yours to commit.
`.mcp.json` is neutralized and `--skip-worktree` in your worktree — never `git add` it, and never
"restore" it from the primary's copy. Same for `wiki/` (a submodule with its own remote).
## 4. Push
@@ -84,8 +110,9 @@ The reply is the entire handoff; the lead cannot see your terminal.
```
PR: <html_url from step 5, or "not created: <reason>" + branch name>
branch: <your branch>
files: <the files you changed>
tests: <what you ran and its REAL result — or "not run: <why>">
root: <git rev-parse --show-toplevel — proves you worked in your own worktree>
files: <worktree-relative paths you changed>
build: <the verbatim "Tests run: …" and BUILD SUCCESS/FAILURE lines — or "not run: <why>">
summary: <2-3 lines: what you implemented and any caveat the reviewer needs>
```
@@ -97,7 +124,8 @@ sequenceDiagram
participant G as git / gitea
L->>I: delegated task (you are in a worktree on your branch)
I->>I: implement + build/test here
I->>I: "implement here — every path under $PWD"
I->>I: "mvn clean install in this worktree, unpiped, until green"
I->>G: git commit (never .mcp.json / wiki)
I->>G: git push -u origin HEAD
I->>G: POST /pulls (GITEA_TOKEN) — open PR to main