🧪 Lab 10 – Isolating Parallel Agents with Git Worktrees
Lab Objective
Practice compartmentalizing concurrent automated work using git worktrees:
- create isolated working directories for parallel tasks from one repository
- prove that work in one worktree cannot disturb another
- simulate a misbehaving task and observe its contained blast radius
- gate the merge back to main on an explicit verification step
- clean up worktrees as part of task completion
The scenario is my multi-agent setup, but the mechanics apply to any situation where several actors — human or automated — must work on one codebase without trampling each other.
Lab Environment
- System: any machine with git ≥ 2.30
- Repo: a scratch repository (safe to destroy)
- Actors: two simulated “agents,” each a shell session working a task
- Boundary: one git worktree per task; main working tree reserved for the operator
Everything below runs in a disposable directory.
Scenario
Two autonomous tasks are scheduled in parallel: one edits documentation, one refactors a script. Both must run at the same time, neither may see the other’s half-finished work, and neither may touch main until its result is verified. Later, one task misbehaves — and we watch the damage stay inside its own compartment.
Commands Practiced
| Command | Purpose |
|---|---|
git worktree add <path> -b <branch> |
Create an isolated working directory on a new branch |
git worktree list |
Inventory active worktrees |
git -C <path> status/diff |
Inspect one compartment from outside |
git merge --no-ff <branch> |
Gated promotion into main |
git worktree remove <path> |
Compartment cleanup |
git branch -D <branch> |
Discard a failed task’s work entirely |
Step 1 - Build the Repo and the Compartments
mkdir -p /tmp/worktree-lab && cd /tmp/worktree-lab
git init -q repo && cd repo
echo "core logic" > app.sh; echo "docs" > README.md
git add -A && git commit -qm "baseline"
# one worktree per task
git worktree add ../task-docs -b agent/docs
git worktree add ../task-refactor -b agent/refactor
git worktree list
Three entries: the main tree and two compartments. Same history, separate working directories, separate branches.
Step 2 - Run Both “Agents” in Parallel
# agent 1: docs task
echo "installation guide" >> ../task-docs/README.md
git -C ../task-docs commit -aqm "docs: add install guide [task:docs-001]"
# agent 2: refactor task, at the same time
echo "refactored logic" > ../task-refactor/app.sh
git -C ../task-refactor commit -aqm "refactor: simplify app [task:ref-002]"
Note the task ids in the commit messages — provenance travels with the change.
Step 3 - Prove the Isolation
git -C ../task-docs diff agent/refactor --stat # sees the other branch's commits, not its dirty state
git status --short # main tree: untouched
cat app.sh # still "core logic"
Each compartment only ever contains its own work. The operator’s tree never changed.
Step 4 - Simulate a Misbehaving Task
# agent 2 goes rogue inside its compartment
rm ../task-refactor/README.md
echo "garbage" > ../task-refactor/app.sh
git -C ../task-refactor status --short
D README.md
M app.sh
# blast radius check: everyone else
git status --short # main: clean
git -C ../task-docs status --short # docs task: clean
The damage exists only inside task-refactor. Containment, demonstrated. The whole compartment can now be discarded:
git worktree remove --force ../task-refactor
git branch -D agent/refactor
The rogue task and all its garbage are gone; nothing else noticed.
Step 5 - Gate the Merge for the Good Task
Verification before promotion — here a simple check standing in for the real verifier:
git diff main agent/docs --stat # exactly the declared file? yes
git merge --no-ff agent/docs -m "merge docs task [task:docs-001] verified"
git worktree remove ../task-docs
Only verified work crossed the boundary into main, and its compartment was destroyed after use.
Step 6 - Sweep for Orphans
git worktree list
git worktree prune
A leftover worktree is an unaccounted-for copy of the codebase. The sweep belongs in routine maintenance, not just labs.
Security Takeaways
- Isolation bounds blast radius. The rogue task destroyed files — inside a compartment built to be destroyed.
- Promotion is the trust boundary. Isolation without a merge gate just delays the collision; verify before anything crosses.
- Provenance travels with the change. Task ids in commits made every change attributable at a glance.
- Discard is a valid outcome. Killing a compartment wholesale is cheaper and safer than untangling bad changes from shared state.
- Compartments need lifecycle. Create, work, verify, merge or discard, remove, prune — leaked worktrees become their own inventory problem.
Where This Applies Beyond My Setup
The same pattern is sandbox promotion in malware analysis, staging-to-production change control, and per-tenant isolation in shared infrastructure: small worlds for untrusted work, inspection at the boundary, and nothing crossing without evidence.
