Parallel Agents with Git Worktrees¶

The Backlog Problem¶
Jose Alekhinne / 2026-02-14
What do you do with 30 open tasks?
You could work through them one at a time. One agent, one branch, one commit stream.
Or you could ask: which of these don't touch each other?
I had 30 open tasks in TASKS.md. Some were docs. Some were a new
encryption package. Some were test coverage for a stable module. Some
were blog posts.
They had almost zero file overlap.
Running one agent at a time meant serial execution on work that was fundamentally parallel. I was bottlenecking on me, not on the machine.
The Insight: File Overlap Is the Constraint¶
This is not a scheduling problem. It is a conflict avoidance problem.
Two agents can work simultaneously on the same codebase if and only if they don't touch the same files. The moment they do, you get merge conflicts — and merge conflicts on AI-generated code are expensive because the human has to arbitrate choices they didn't make.
So the question becomes: can you partition your backlog into non-overlapping tracks?
For ctx, the answer was obvious:
| Track | Touches | Tasks |
|---|---|---|
work/docs |
docs/, hack/ |
Blog posts, recipes, runbooks |
work/pad |
internal/cli/pad/, specs |
Scratchpad encryption, CLI, tests |
work/tests |
internal/cli/recall/ |
Recall test coverage |
Three tracks. Near-zero overlap. Three agents.
Git Worktrees: The Mechanism¶
Git has a feature that most people don't use: worktrees.
A worktree is a second (or third, or fourth) working directory that
shares the same .git object database as your main checkout. Each
worktree has its own branch, its own index, its own working tree. But
they all share history, refs, and objects.
git worktree add ../ctx-docs -b work/docs
git worktree add ../ctx-pad -b work/pad
git worktree add ../ctx-tests -b work/tests
Three directories. Three branches. One repository.
This is cheaper than three clones. And because they share objects,
git merge afterwards is fast — it's a local operation on shared data.
The Setup¶
The workflow I landed on:
1. Group tasks by blast radius.
Read TASKS.md. For each pending task, estimate which files and
directories it touches. Group tasks that share files into the same
track. Tasks with no overlap go into separate tracks.
This is the part that requires human judgment. An agent can propose groupings, but you need to verify that the boundaries are real. A task that says "update docs" but actually touches Go code will poison a docs track.
2. Create worktrees as sibling directories.
Not subdirectories. Siblings. If your main checkout is at
~/WORKSPACE/ctx, worktrees go at ~/WORKSPACE/ctx-docs,
~/WORKSPACE/ctx-pad, etc.
Why siblings? Because some tools (and some agents) walk up the directory
tree looking for .git. A worktree inside the main checkout confuses
them.
3. Launch one agent per worktree.
# Terminal 1
cd ../ctx-docs && claude
# Terminal 2
cd ../ctx-pad && claude
# Terminal 3
cd ../ctx-tests && claude
Each agent gets a full working copy with .context/ intact. It reads
the same TASKS.md, the same DECISIONS.md, the same CONVENTIONS.md.
It knows the full project state. It just works on a different slice.
4. Do NOT run ctx init in worktrees.
This is the gotcha. The .context/ directory is tracked in git. Running
ctx init in a worktree would overwrite shared context files — wiping
decisions, learnings, and tasks that belong to the whole project.
The worktree already has everything it needs. Leave it alone.
What Actually Happened¶
I ran three agents for about 40 minutes. Here is roughly what each track produced:
work/docs: Parallel worktrees recipe, blog post edits, recipe
index reorganization, IRC recipe moved from docs/ to hack/.
work/pad: ctx pad show subcommand, --append and --prepend
flags on ctx pad edit, spec updates, 28 new test functions.
work/tests: Recall test coverage, edge case tests.
Merging took about five minutes. Two of the three merges were clean.
The third had a conflict in TASKS.md — both the docs track and the
pad track had marked different tasks as [x].
The TASKS.md Conflict¶
This deserves its own section because it will happen every time.
When two agents work in parallel, they both read TASKS.md at the
start and mark tasks complete as they go. When you merge, git sees two
branches that modified the same file differently.
The resolution is always the same: accept all completions from both
sides. No task should go from [x] back to [ ]. The merge is
additive.
This is one of those conflicts that sounds scary but is trivially mechanical. You're not arbitrating design decisions. You're combining two checklists.
Limits¶
3-4 worktrees, maximum. I tried four once. By the time I merged the third track, the fourth had drifted far enough that its changes needed rebasing. The merge complexity grows faster than the parallelism benefit.
Three is the sweet spot. Two is conservative but safe. Four is possible if the tracks are truly independent.
Group by directory, not by priority. It is tempting to put all the high-priority tasks in one track. Don't. Two high-priority tasks that touch the same files must be in the same track, regardless of urgency. The constraint is file overlap, not importance.
Commit frequently. Smaller commits make merge conflicts easier to resolve. An agent that writes 500 lines in a single commit is harder to merge than one that commits every logical step.
Name tracks by concern. work/docs and work/pad tell you what's
happening. work/track-1 and work/track-2 tell you nothing.
The Pattern¶
This is the same pattern that shows up everywhere in ctx:
The attention budget taught me that you can't dump everything into one context window. You have to partition, prioritize, and load selectively.
Worktrees are the same principle applied to execution: you can't dump every task into one agent's workstream. You have to partition by blast radius, assign selectively, and merge deliberately.
The codebase audit that generated these 30 tasks used eight parallel agents for analysis. Worktrees let me use parallel agents for implementation. Same coordination pattern, different artifact.
And the IRC bouncer post from earlier today argued that
stateless protocols need stateful wrappers. Worktrees are the same:
git branches are stateless forks; .context/ is the stateful wrapper
that gives each agent the project's full memory.
Should This Be a Skill?¶
I asked myself the same question I asked about the codebase
audit: should this be a /ctx-worktree skill?
This time the answer is yes. Unlike the audit prompt — which I tweak every time and run quarterly — the worktree workflow is:
| Criterion | Worktree workflow | Codebase audit |
|---|---|---|
| Frequency | Weekly | Quarterly |
| Stability | Same steps every time | Tweaked every time |
| Scope | Mechanical, bounded | Bespoke, 8 agents |
| Trigger | Large backlog | "I feel like auditing" |
The commands are mechanical: git worktree add, git worktree remove,
branch naming, safety checks. This is exactly what skills are for:
stable contracts for repetitive operations.
So /ctx-worktree exists. It enforces the 4-worktree limit, creates
sibling directories, uses work/ branch prefixes, and reminds you
not to run ctx init in worktrees.
The Takeaway¶
Serial execution is the default. But serial is not always necessary.
If your backlog partitions cleanly by file overlap, you can multiply
your throughput with nothing more exotic than git worktree and
a second terminal window.
The hard part is not the git commands. It is the discipline:
grouping by blast radius instead of priority, accepting that TASKS.md
will conflict, and knowing when three tracks is enough.
If you remember one thing from this post...
Partition by blast radius, not by priority.
Two tasks that touch the same files belong in the same track, no matter how important the other one is.
The constraint is file overlap. Everything else is scheduling.
The practical setup — skill invocation, worktree creation, merge workflow, and cleanup — lives in the recipe: Parallel Agent Development with Git Worktrees.