How I Run Three Agents Without Losing My Mind
Running three AI agents at once is a real gain and a fast way to lose a day of work. Both are true. The gain is obvious the first time you watch three problems get solved while you drink your coffee. The loss shows up an hour later, when you go to collect the work and one agent's fix has landed on another agent's commit, a third agent's change is on a branch that no longer exists, and you cannot remember which of the four copies of the repo on your disk is the real one.
This is not a smarts problem. The agents were fine. You just ran a distributed system without knowing it, and every distributed system fails the same way: at the shared writes.
So here is the system I use. It is not a framework. You do not install anything. It is a short list of rules, and the whole thing fits on an index card. I run it by hand and it holds.
Operating Conditions
Name the setup honestly. A few agents, one repository, one machine. And underneath them, by default, one working tree, one HEAD, one index, one build directory. That is the trap. The agents feel like a team you are directing. They are actually several processes writing to the same shared state with no lock and no coordinator, and the coordinator is supposed to be you.
The enemy is not the model. The enemy is shared mutable state. Every rule below is one way to stop two writers from touching the same thing at the same time. That is the entire game.
Rule 1: One writer, one worktree, one branch
This is the rule the other five are just details of. Never put two agents on the same HEAD.
Git already ships the tool. A worktree is a second checkout of the same repository, its own directory, its own branch, sharing the one object store. Give each agent its own.
git worktree add ../myrepo-agent-a -b agent-a
git worktree add ../myrepo-agent-b -b agent-bNow agent A edits in myrepo-agent-a on branch agent-a, agent B edits in myrepo-agent-b on agent-b, and neither can see, stage, or clobber the other's uncommitted work. If your harness spawns subagents with worktree isolation, use it; it is the same idea, automated. When you are done with one, remove it from the main repo root, not from inside it:
cd ../myrepo && git worktree remove ../myrepo-agent-aAnd the corollary that bites people who skip the worktrees and share one tree anyway: under a shared HEAD, git commit --amend and git rebase are landmines. Amend rewrites "the last commit," and between your two turns the last commit may now be a sibling agent's, so your fix gets welded onto their unrelated work. One writer per HEAD, and amend only what you alone own.
Rule 2: Partition before you dispatch
Decide who touches what before you spawn anything, not after they collide.
Assign disjoint files up front. Agent A owns the parser, agent B owns the renderer, agent C owns the tests. Write it down. If two agents need the same file, that is not two agents, that is one agent with a queue.
The subtle part is coupling. Two agents can own different files and still collide at link time, because a change in one file added a new call into the other. Files that do not overlap on disk can overlap in the build graph. So before dispatch, ask the second question: does any of this work introduce a new dependency between the pieces I just split. If yes, sequence those two, do not parallelize them.
Partition you reason about is a guess. Partition you write down before dispatch is a plan.
Rule 3: Commit only your own hunk
If you ever do share one working tree, never stage blindly. git add . and even git add somefile.cpp are last-write-wins on the index: the file you touched may already carry another session's half-finished changes, and a whole-file add sweeps their work into your commit under your message.
The tell is in git status: an MM next to a file means it has staged changes and further unstaged changes, which usually means someone modified it after you staged it. When you see that, do not commit the file. Commit the specific hunk you own:
git add -p somefile.cpp # stage only your hunk, interactively
git commit -m "your change"If your harness cannot run the interactive picker, commit by pathspec for files you fully own and hand-apply your patch for files you share. The principle does not bend: you commit what you wrote, never what happened to be sitting in the file.
Rule 4: Route hot shared files through one curator
Some files are last-write-wins magnets no matter how well you partition: a counter, a single list every feature appends to, a catalog total, a manifest. Two agents both "just add one line" and one of the lines is gone.
Two defenses. First, prefer derived values over hand-typed ones. If the number is len(theList), there is no counter to desync. If the total is computed from one source, there is nothing to hand-edit wrong. Second, for the genuinely single-owner file, make it single-owner: one agent, or you, curates it, and the others hand you their entries. A shared list with N writers is a corruption waiting for a diff.
Rule 5: One lander, and it is you
Integration is a job, and it is serialized, and it has exactly one owner. The agents produce branches. They do not push to master. You land.
The move, per branch, done by one person in one place:
git fetch origin
git checkout agent-a
git merge origin/master # bring master into the branch, resolve here
# build, test the merged result
git checkout master && git merge --ff-only agent-a
git push origin masterRe-check that the branch is still a fast-forward of master right before you push, because master may have moved while you were testing. When only specific hunks of a branch should land and the rest is stale, cherry-pick them instead of merging the whole branch, so you do not drag in regenerated artifacts nobody meant to ship.
And the trap that catches everyone at least once: gh pr merge merges the branch state that is on the server. If you have local commits you never pushed, the merge ships the version without them and orphans your fixes on a branch about to be deleted. Before you merge anything, run git log @{u}..HEAD. If it prints commits, you have unpushed work. Push before you merge.
Rule 6: Verify before you trust the word "done"
An agent reporting success is a claim, not a receipt. In a swarm the claim is even cheaper, because the thing that would contradict it is three directories away.
So collect the receipt. If an agent says it committed a fix, the SHA is in its report; git branch -f keep-a <sha> before anything gets garbage-collected, then confirm the branch exists. If it says the build works, build from that worktree's own binary and prove the change is in it: strings ./that-worktree/build/app | grep "the string you added". If it says the page renders, fetch the page the way the real reader does, not the way that happens to pass. Done is a claim about a commit. It says nothing about whether you can reach it, or whether what you can reach is the thing that changed.
System Status
That is the whole card. One writer per worktree, partition before dispatch, commit your own hunk, curate the hot files, land as one owner, verify the word "done." None of it is clever. All of it is the boring discipline that a person who has run a team already knows, pointed at a team that happens to be made of models.
Here is the part worth saying plainly, because the feeds will not. The gain from three agents is not that you type faster. It is that you stopped being the typist. The model took the code. It did not take the decomposition, the sequencing, or the integration, and those were always the hard parts. Run them well and one person gets a small team's output from one desk. Run them badly and you get three agents generating work faster than you can lose it.
You do not need a control plane for this. You will read that you do; that some framework will orchestrate your fleet and manage your merges and give your agents persistent identities. When you actually have a fleet, ten and more agents you cannot hold in your head, go read about those. At three agents you do not have a fleet. You have a small team, and a small team is run with a short list of rules and a person willing to be the manager. That person is you now. That is the job.
What is the one rule that has saved you the most rework running agents in parallel? Tell me the mechanism, not just "use worktrees." The mechanism is the part that transfers.
Further Reading
- It Said Deployed: why "done" is a claim and not a receipt, in the single-agent case. Rule 6, in one story.
- It Said Done. It Verified the Wrong Binary.: the receipt an agent owes you, and the one-line check that collects it.




No comments yet