the original text · as pasted

The Swarm: Parallel Coding Agents in Git Worktrees

This is the text the comic was made from, published by its author. ‹ back to the comic

VCN #49 · The Swarm · 2026-08-12 · Frontier Tower F10

doors 19:00 · walkthrough 19:30

Run parallel coding agents in git worktrees. One repo, N agents, no collisions.

One agent is a queue. Your repo has ten independent things to do and it does them one at a time. Tonight we fan the work out, and put it back together on purpose.

Season Off the Leash Night 49 of 50 Room SWRM Format walkthrough → build → demos

$10 early · $20 door · Frontier Tower members free (ask any host)

Your ticket includes z.ai + Claude Code for the session and Nebius Token Factory credits to run the fleet. Bring a laptop and a repo with more than one thing to do.

Rayyan Zahid · Michalis Vasileiadis · Eric Mockler · Devinder Sodhi

vibecodingnights.com

The problem

02

## One agent is a queue.

A single coding agent grinds your repo one task at a time. It is not slow because the model is slow. It is slow because it is a queue with one server.

NOWadd the auth endpointrunning

+1fix the billing rounding bugwaiting

+2write the README nobody has writtenwaiting

+3add tests for the parserwaiting

+4bump the deps and fix the falloutwaiting

Not one of those four waiting tasks needs the one above it to finish first. They are waiting on a scheduling decision you made by accident: one agent, one working tree, one thing at a time.

VCN #49 · The Swarm

Frontier Tower F10

The problem

03

## So open ten agents on the same folder.

This is everyone's first idea, and it half-works for about four minutes. That is what makes it dangerous: the failure does not arrive as an error, it arrives as damaged work.

Same filesTwo agents open _src/config.ts_, both read it, both write it. The second write silently erases the first. Neither agent knows.

Same index_git add_ stages into one shared index. Agent B stages its half-finished work into agent A's commit.

Same HEADOne agent runs _git switch_ and every other agent's working tree changes underneath it, mid-edit.

Same lockfileConcurrent git commands collide on _index.lock_. The loser fails, and an agent that sees a failed command tends to retry it.

One working tree is **one shared mutable surface**. Parallelism on shared mutable state is a race, and you do not get to win a race by adding more runners. The missing primitive is isolation, and git already ships it.

VCN #49 · The Swarm

Frontier Tower F10

The concept

04

## The conductor pattern.

One orchestrator owns the split. It does not write code. It has exactly three jobs, and every one of them is a judgement a worker cannot make, because a worker cannot see the other workers.

SplitCut the backlog into slices that do not share a write surface. _This is the only creative step, and it is where a swarm succeeds or fails._

DispatchStand up one isolated arena per slice, put one agent in each, give it a tight brief and no view of the others. _Mechanical._

MergeCollect finished branches, integrate them one at a time, and triage what collides. _Also mechanical, until it is not._

The conductor's only products are **the plan and the merge**. If you find yourself editing code as the conductor, you have stopped conducting and become a fourth worker with a global view, which is the one role that cannot be isolated.

VCN #49 · The Swarm

Frontier Tower F10

The concept

05

## Worktrees, not branches in place.

Branching is not the primitive you need. Branching gives you many histories. You need many _desks_.

git switch / checkout

Many branches, _one_ working tree. Switching mutates the single set of files on disk, so agents serialize on it. Two agents cannot be on two branches at once.

.git | +-- ONE working tree ^ every agent fights here

git worktree

Many branches, _many_ working trees. Each agent gets its own checked-out directory, its own index, its own HEAD, backed by the same object store.

.git (shared objects) | +-- ../sw/01 task/01 +-- ../sw/02 task/02 +-- ../sw/03 task/03

Same history, **N desks**. One clone's worth of objects on disk, N directories to work in. That is the whole trick, and it has shipped in git since 2.5.

VCN #49 · The Swarm

Frontier Tower F10

The concept

06 · measured tonight

## A worktree is not a sandbox.

It isolates four things. It shares everything else, and the sharing is invisible until it bites.

Isolated per worktree

Shared across all of them

What goes wrong

working tree

.git/config

every agent writing its own identity races; last writer wins

index (staging)

refs / branches

two agents can still target one branch name

HEAD

object store

fine, and it is why N trees are cheap

checked-out branch

hooks, stash

a pre-commit hook fires with global, not per-agent, config

three agents, each setting its identity the obvious way

$ ./agent.sh sw/01 & ./agent.sh sw/02 & ./agent.sh sw/03 & wait error: could not lock config file .../demo/.git/config: File exists error: could not lock config file .../demo/.git/config: File exists \# two failed. all three committed anyway. now read the log: d2298b6 agent-task03-docs task01-auth: implement a6225a4 agent-task03-docs task02-billing: implement da6d3a4 agent-task03-docs task03-docs: implement

The commit _messages_ are right, so the log looks fine at a glance. The **author is wrong on every commit** - it is whichever agent won the race - which is the one field you would use to audit who did what. A worker may write its tree. **It must never write the repo's shared config.**

VCN #49 · The Swarm

measured 2026-08-12, this repo

The concept

07

## One command per task. One arena per agent.

This is the entire setup half of the pattern. Four lines, and every one of them ran on this laptop tonight.

from the main repo

git worktree add ../sw/01 \-b task/01-auth git worktree add ../sw/02 \-b task/02-billing git worktree add ../sw/03 \-b task/03-docs git worktree list

\# .../demo 4f81f30 \[master\] \# .../sw/01 4f81f30 \[task/01-auth\] \# .../sw/02 4f81f30 \[task/02-billing\] \# .../sw/03 4f81f30 \[task/03-docs\]

Each _../sw/NN_ is a full checkout an agent can build in without touching the others. Note what you did **not** pay: no re-clone, no second copy of history. The object store is shared, so the marginal cost of another agent is the working files alone.

VCN #49 · The Swarm

Frontier Tower F10

The replay

08 · measured tonight

## Three agents, one repo, three hours of work in one.

A real run on a scratch repo: split into three independent tasks, three worktrees, three agents fired concurrently, then merged back. Before, and after.

before · git worktree list

.../demo 4f81f30 \[master\] .../sw/01 4f81f30 \[task/01-auth\] .../sw/02 4f81f30 \[task/02-billing\] .../sw/03 4f81f30 \[task/03-docs\]

\# four trees. one .git. \# all three agents start \# from the same commit.

after · git log --graph --all

\* ad6f110 merge task/03 (+seam) |\\ | \* 633fe2b task03: pass 2 | \* da6d3a4 task03: implement \* | 0a87c30 merge task/02 |\\ \\ | \* | 7e0e380 task02: pass 2 | \* | a6225a4 task02: implement \* | 863b639 merge task/01 |\\ \\

Three features advanced in the wall-clock time one agent takes to do one. The fan-out cost four commands. **The fan-in is where the real work was**, and slides 14 to 16 are entirely about that half.

VCN #49 · The Swarm

measured 2026-08-12

The replay

09 · measured tonight

## The teardown that ate a venv, quietly.

N cheap worktrees usually means linking a shared _.venv_ or _node\_modules_ into each one. That trick is what makes the swarm affordable, and it is also what arms this.

a worktree carrying a junction that points outside itself

\# sw/01/.venv --> ../../precious (a junction, i.e. a reparse point)

$ git worktree remove --force ../sw/01 \--- exit: 0 --- \# no output. no error. success.

$ ls ../precious \[ empty \] \# data.txt and data2.txt are gone. \# the DIRECTORY survived. the contents did not.

The removal **followed the link out of the worktree** and deleted the target's contents, then exited 0. _rm -rf_ and _shutil.rmtree_ do the same thing. This fired for real in our own agent fleet nine hours before doors, and there it at least printed an error afterwards. Here it said nothing at all.

VCN #49 · The Swarm

reproduced 2026-08-12

The replay

10

## Three things the dry run changed.

This deck was planned in June and the lab was run today, before it was written. The plan survived mostly intact. Where it did not, the slide changed, not the run.

Slide 6Added outright. The plan said "worktrees give you isolation" and moved on. _They give you four kinds and withhold four more, and the withheld ones corrupt commit authorship silently._

Slide 12The agent brief lost _git config user.email_ and gained environment variables. The obvious line is the broken one.

Slide 16Teardown gained an unlink step before the removal. Without it the cleanup can delete something that was never in the worktree.

Everything elseRan exactly as planned: the adds, the list, the serial merges, the conflict landing on the one shared file, the prune. _No edits needed._

Every VCN lab gets run before it gets taught. It is the cheapest quality gate we have: tonight it cost about twenty minutes and it caught **two failures that pass silently** and would have reached fifty laptops.

VCN #49 · The Swarm

Frontier Tower F10

Lab

step 0 of 5

Step 0

## Pick work that does not share a file.

Open your own repo. Name three tasks that touch _disjoint_ sets of files. Independence is the whole game, and this is the only step where you get to choose it.

stand up three arenas

\# from your repo root. ../sw/ sits NEXT TO the repo, not inside it. git worktree add ../sw/01 \-b task/01 git worktree add ../sw/02 \-b task/02 git worktree add ../sw/03 \-b task/03 git worktree list \# want 4 rows: main + 3

\# from your repo root. ../sw/ sits NEXT TO the repo, not inside it. git worktree add ../sw/01 \-b task/01 git worktree add ../sw/02 \-b task/02 git worktree add ../sw/03 \-b task/03 git worktree list \# want 4 rows: main + 3

\# PowerShell. same commands; mind the backslashes in output. git worktree add ..\\sw\\01 \-b task/01 git worktree add ..\\sw\\02 \-b task/02 git worktree add ..\\sw\\03 \-b task/03 git worktree list \# want 4 rows: main + 3

\# on a cloud box, put the trees on the same volume as .git cd ~/work/your-repo git worktree add ../sw/01 \-b task/01 git worktree add ../sw/02 \-b task/02 git worktree add ../sw/03 \-b task/03 git worktree list

Checkpoint · hard gateFour rows from _git worktree list_, three distinct branch names. If two of your three tasks want the same file, they are _one_ task. Merge them now, before an agent touches anything.

VCN #49 · The Swarm

SWRM

Lab

step 1 of 5

Step 1

## One agent per tree, and give it a name that survives.

One terminal per worktree. z.ai + Claude Code drives each worker; Nebius credits fuel the fleet. The identity lines are not decoration - they are the fix for slide 6.

one terminal per tree · run all three

\# identity via ENV, per process. never \`git config\` - that writes \# the SHARED .git/config and races (slide 6). export GIT\_AUTHOR\_NAME="agent-01" GIT\_AUTHOR\_EMAIL="01@swarm.local" export GIT\_COMMITTER\_NAME="agent-01" GIT\_COMMITTER\_EMAIL="01@swarm.local"

cd ../sw/01 && claude -p "Implement task 01: <scope>. Stay in this directory. Do not read or edit files outside it. Commit when the tests are green."

The brief, in three rules**Tight scope** (one task, named). **Stay in your tree** (no cross-task reads - agents must not coordinate). **Commit on green** (a branch is the handoff, not a diff you paste). Isolation is enforced by the filesystem, not by trust.

VCN #49 · The Swarm

SWRM

Lab

step 2 of 5

Step 2

## Poll the fleet. Do not help.

While the workers run, you are a scheduler: who is alive, who has landed a commit, who is stuck. Resist opening an editor. The moment you edit, you are a fourth worker with a global view.

from the main repo, whenever you want to know

git worktree list \# who exists

\# last commit in each tree - the fleet's status board for d in ../sw/\*; do (cd "$d" && \\ echo "$(basename $d): $(git log --oneline -1)"); done

\# 01: 3ae983f agent-01 task01: second pass \# 02: 7e0e380 agent-02 task02: second pass \# 03: 633fe2b agent-03 task03: second pass

CheckpointEach tree shows a commit authored by _its own_ agent. If two rows share an author name, your identity scoping is broken and you have the slide 6 bug - fix it before you merge, because after the merge the attribution is permanent.

VCN #49 · The Swarm

SWRM

Lab

step 3 of 5

Step 3

## Fan-out is parallel. Fan-in is one at a time.

The temptation is to merge everything at once and let git sort it out. Do not. Merge serially, so that when something conflicts you know exactly _which branch_ introduced it.

from the main repo

git switch main

git merge --no-ff task/01 \# clean: disjoint files git merge --no-ff task/02 \# clean git merge --no-ff task/03 \# CONFLICT (content): src/config.ts

\# --no-ff keeps a merge commit per agent, so the graph still shows \# WHO did what after the fan-in. a fast-forward erases that.

CheckpointTwo clean merges and one conflict is a _normal, healthy_ result - that is exactly what tonight's dry run produced. A swarm that never conflicts probably had tasks too small to be worth fanning out.

VCN #49 · The Swarm

SWRM

Lab

step 4 of 5

Step 4

## Resolve by intent, not by line.

Two agents both edited the one file you thought was nobody's. Neither is wrong. The merge is not a contest to pick a winner - both features are supposed to survive.

src/config.ts · verbatim from tonight's run

export const VERSION = "0.1.0"; <<<<<<< HEAD export const AUTH\_ENABLED = true; \# agent 01 wanted this \======= export const DOCS\_URL = "/docs"; \# agent 03 wanted this \>>>>>>> task/03-docs

\# resolution: KEEP BOTH. neither intent excludes the other. git add src/config.ts && git commit

When it is not this easyHand the conflict to a _fresh_ agent with both intents as context - it has no stake in either branch. And note what the conflict told you: your split was imperfect. That file belonged to one task, not two.

The conflict git cannot show youThe dangerous one is the **semantic** conflict: both branches merge clean, no markers, and the result is still wrong - agent 01 renamed a field, agent 02 wrote a caller for the old name in a different file. Measured at _5 to 10 percent_ of parallel-agent runs (CodeCRDT, arXiv 2510.18893). Git will never flag it. **Run the tests after the LAST merge, not after each one** - that is the only place it surfaces.

VCN #49 · The Swarm

SWRM

Lab

step 5 of 5

Step 5

## Unlink first, then remove.

Stale trees pile up and stale branches pile up faster. But if you linked anything into a worktree to make it cheap, the order of these commands is the difference between a cleanup and a data loss.

teardown · the order matters

\# 1. drop any link you put INSIDE the tree, first. \# rmdir removes the link only. rm -rf follows it and deletes the target. rmdir ../sw/01/.venv \# macOS/Linux: unlink ../sw/01/.venv

\# 2. now the tree can go. git worktree remove ../sw/01 git worktree prune \# clears stale metadata git branch -d task/01 \# -d refuses if unmerged. keep it -d.

Checkpoint_git worktree list_ is back to one row. If you skipped step 1 and something outside the repo is now empty, that is slide 9, and it exited 0 while doing it. Keep _\-d_ rather than _\-D_: the refusal is the only thing standing between you and deleting an agent's unmerged work.

VCN #49 · The Swarm

SWRM

Gotchas · trust gates

17

## When to fan out, and when not to.

You will over-apply this by Friday. Here is the line, and it is sharper than "it depends".

Helps

Hurts

Separate features in separate files

One refactor that touches every file

Docs, tests and a new endpoint, together

Task B needs task A's output to exist

Bulk mechanical edits over disjoint modules

Anything that renames a shared symbol

up to +21% faster

up to -39% SLOWER

Those last two numbers are measured, not ours: _CodeCRDT_ (arXiv 2510.18893) ran 600 trials of parallel LLM code generation and found up to **21% speedup on some task shapes and 39% slowdown on others**. Fanning out is not free and it is not always a win. The test is one sentence: **parallelize work that does not share a write surface.** If two tasks edit the same file, they are one task, and splitting them converts a five-minute edit into a merge you reason about twice.

Gate 1 · before fan-outA human reads the conductor's split. This is the step that decides whether the night is cheap or expensive, and no worker can check it.

Gate 2 · before it shipsA human reads the merged result, not the three branches. _Agents commit. Humans integrate._

VCN #49 · The Swarm

Frontier Tower F10

Leave-with

18

## You came with one agent. You leave with a fleet.

Four things are running on your laptop right now that were not at 7pm.

01A conductor that fans N coding agents across N git worktrees on one repo.

02Isolation per worktree - and a clear map of the four things it does _not_ isolate.

03A fan-in playbook: serial merges, conflict-by-intent, and a teardown that unlinks before it removes.

04The one-sentence test for whether work should be fanned out at all.

Resources

**z.ai + Claude Code** and **Nebius Token Factory** credits came with your ticket. Cheatsheet, conductor prompt template and tonight's lab transcript are in the Telegram.

Community

Wednesdays 7pm F10, Saturdays 10am F9. **vibecodingnights.com** · Telegram link on the Luma page. Teach a night: bring a pattern you shipped.

Next

**#50: Own the Stack** - Saturday, and the last night of Off the Leash. Bring the swarm; we are going to point it at infrastructure.

Bring a repo with more than one thing to do. Split it where nothing overlaps. Let them run.

Rayyan Zahid · Michalis Vasileiadis · Eric Mockler · Devinder Sodhi

vibecodingnights.com