03.11Rule
Git worktree isolation for parallel AI coding agents
How AR Labs isolates parallel AI coding agents with git worktrees: each task on its own branch and checkout, and a hook that blocks edits to main.
On this page
Worktree isolation is how AR Labs keeps AI coding agents (AI agents that write code, such as Claude Code or Codex) from landing edits on main by mistake, and lets several of them work in parallel without touching each other's files. Every project our agents work on is checked out in at least two places at once. A primary checkout stays on main as the clean integration point. Work happens in a separate git worktree on the task's own branch. Agents edit in the worktree, never in the primary, and a hook (a script run automatically around an agent's action that can block it) enforces that rule.
The problem it prevents
A git worktree is one repository checked out into more than one directory, each on a different branch. The directories cannot see each other's uncommitted files. An agent session usually starts inside the primary checkout, so the project's files are right there, visible and editable, and they are the wrong copy. An edit there lands on main with no branch, review or pull request, or sits unnoticed in the primary's working tree while the agent looks for it in the worktree. Nothing errors. The edit simply goes to the wrong place.
Reading has the same trap with no error at all. One analysis came out wrong because it read the primary's copies of tooling that existed only on a task branch. A task's newest files, including its spec, evidence and walkthrough, exist only in its worktree until the pull request merges.
How it works
The figure shows the only two directions edits can travel. Each agent edits its own task worktree, and work reaches main on the code host through a pull request a person merges. The primary checkout only pulls; an edit aimed at it is refused by the hook.
- Confirm the layout.
git worktree listshows which directory holds which branch. - Start a task. Fetch, then cut the task branch from the freshly fetched target branch. A worktree can never sit on
mainitself, because git will not check the same branch out twice and the primary already holds it. - Do all the work there. The spec, the code, the evidence and the review all sit on one branch in one worktree.
- End the task. Once the pull request has merged, cut the next task's branch, then delete the finished one with the safe form of the command.
cd ~/worktrees/app/dev
git fetch --prune origin
git checkout -B task/app-42.4-export-csv origin/main
git branch -d task/app-42.3-persist-sessiongit branch -d refuses to delete a branch whose work has not merged, so the refusal is the check: a clean deletion is git confirming the work is on main. The lowercase form is used on purpose; the uppercase -D deletes regardless. The check relies on merge commits. With squash merges the branch's commits are not literally on main, so -d refuses even merged work; confirm the merge on the code host before forcing it with -D.
Parallel agents get their own worktrees
When the coding pipeline dispatches work unattended, each task gets its own worktree, on a branch named for the task, cut from the campaign's integration target (the branch its work lands on, main unless the campaign has its own). The first step creates it; every later step of the same task finds it by branch and reuses it, so the spec, code and review stay together. Reviewers get no worktree, because a review only reads.
A project with heavy dependencies can also keep one shared development worktree with its secrets and installed packages in place. A task takes the shared one only when it is clean and free: nothing uncommitted, no merge in progress, no other open task's branch checked out. Otherwise the task gets its own, and the shared worktree is left exactly as it was. A new worktree is prepared before the agent starts: listed ignored files such as local environment settings are copied in, never over an existing file, and the project's setup script installs dependencies.
Enforced by a hook, not by documentation
The rule began as a warning in one project's own docs. That warning sat uncommitted in a single checkout and was invisible from every other one, which is the failure the rule exists to prevent. We moved the rule into two places that do not depend on the target repository's state: a rule file loaded into every session, and a hook.
The hook runs before every file edit or write. It walks up from the target path to the nearest .git entry. A .git file means a linked worktree, and the edit is allowed. A .git directory means a primary checkout; if that repository is one the pipeline dispatches work into, the edit is denied, and the denial names the correct worktree path. The decision is made from files on disk, and once a guarded primary has been identified, any later error still denies, so a malfunction cannot open the gate.
Specs get no exemption. A spec rides the pull request with the code it describes, so it is written on the task branch in a worktree like everything else.
Adopting it
For a team running more than one agent, the minimum is: one worktree per concurrent task, branches cut from a freshly fetched remote reference, git branch -d as the cleanup check, and a pre-edit hook that refuses writes to the primary checkout. Instructions explain the rule; the hook makes sure it holds.
Referenced by 06
- ProjectsAI software factory: coding agents with gateslinks here in its text
- EngineeringHow AR Labs engineers software with AI coding agentslinks here in its text
- EngineeringThe coding pipeline for AI coding agentslinks here in its text
- EngineeringHarness engineering for AI coding agentslinks here in its text
- EngineeringMulti-agent orchestration for AI coding agentslinks here in its text
- SkillsOrchestrate: Claude Code orchestration skill for subagentslinks here in its text