3.7 KiB
name, description
| name | description |
|---|---|
| parallel-worktree-path-hazard | "Use when several agents edit the same repo in different git worktrees at once, or when an edit/read may have landed in the wrong checkout: which path forms bind where, how to detect with git -C status, and the repair protocol (cp + git show HEAD blob write-back) because git checkout/restore is policy-blocked in a shared workspace." |
Concurrent-worktree path hazard (shared repo, many agents)
Measured 2026-10-18 on serverAppConfigs with two agents live at once. The
failure is silent: the tool reports success, the diff looks right, and the
change lives in a different worktree.
Which path form binds where
- Parent/top-level session: a relative
pathresolves against the session CWD — its own worktree — never against the worktree named in the prompt. This is how a change meant forwt-tts-trial-docslanded inwt-20261017-…. - Subagent: an absolute path to its own assigned worktree can resolve
into the parent's worktree when the same relative path exists there
(
edittwice ontodankclaw/.env.example). Itswritewith the same absolute path was fine — the bug isedit/readpath resolution, notwrite.
Rules that hold:
- A subagent passes paths as
../<its-worktree>/<rel>(relative to the parent worktree) forreadandedit; the parent passes absolute paths to any worktree that is not its own CWD. - After every edit batch, prove the landing site, do not trust the tool's echo:
git -C <intended-worktree> status --shortmust list the file. A file you edited that is missing from that list went somewhere else. - Keep each work item on its own branch/worktree, and keep ONE integration
owner (the parent) for shared files —
scripts/deploy-remote.sh,scripts/deploy-plan.py,tests/,serverAppConfigs-docs/index.md,AGENTS.mdare the collision hot spots in this repo. Never rebase a sibling's branch.
Repair protocol (no git checkout, no git restore)
git checkout -- <path> and git restore <path> are policy-blocked in a
shared workspace ("overwriting working-tree files … discards changes other
concurrent agents rely on"). Unstaging (git reset [<path>],
git restore --staged <path>) is allowed but does not undo content. So:
F="path/with spaces if any"
# 1. move the change to the worktree that should own it (both at the same base commit)
cp "<wrong-wt>/$F" "<right-wt>/$F"
# 2. undo in the wrong worktree by writing the committed blob back
git -C "<wrong-wt>" show "HEAD:$F" | tee "<wrong-wt>/$F" > /dev/null
# 3. prove both sides
md5sum <(git -C "<wrong-wt>" show "HEAD:$F") "<wrong-wt>/$F" "<right-wt>/$F"
git -C "<wrong-wt>" status --short # must be empty for that file
git -C "<right-wt>" diff --stat # must show the intended delta
Never fix it blind: if the wrong worktree had its own uncommitted edits to that
file, cp/blob-write-back would destroy them — check
git -C <wrong-wt> status --short FIRST and reconcile content, don't overwrite.
Tidy after a cancelled sibling
A killed subagent can leave a worktree plus an empty branch. Removing them is
safe only when verified empty: git -C <main> log --oneline -3 <branch> (no
unique commits) and git -C <wt> status --short (clean), then
git worktree remove <wt> + git branch -D <branch>. An orphan worktree at a
stale commit is the same class of trap as a leftover bench drop-in: the next
agent reads it as unfinished work.
Report it
File the misresolution to xd://report_issue (false positives are fine) and
record the incident in the repo worklog — a repair nobody wrote down looks like
a hijack later.