This week four Claude Code agents worked through eleven bug reports in my app at the same time, and one merge conflict came out of it.

Most of the rules that got it down to one were written after something broke. Here they are in the order the day runs.

Check the bug reports before anyone fixes them

Before handing out fourteen bug reports, my lead session had one agent check each against the latest code. Three were already fixed by other sessions in the past weeks, and nine were only partly true. Without that pass, agents would have rebuilt three things that already worked. That left eleven.

Split the work by the files it touches

The lead groups the bugs so that no two groups touch the same files. This time that gave four groups: money and tokens, wording, emails, films.

Two groups still overlapped in one file. One agent had refactored a function the other had edited, so the lead kept the refactor and applied the edit inside it by hand. That was the only conflict.

Never share a working tree

Every agent gets its own git worktree, made fresh from origin/main:

git fetch origin git worktree add -b fix-emails ../scratch/fix-emails origin/main 

No agent works in the main checkout, and nobody switches branches in it. Several sessions run at once, and one git checkout in a shared folder changes the files under all of them.

A fresh worktree has no node_modules. On Windows, each one gets a junction to the main install instead of its own copy. From the main checkout:

cmd /c mklink /J ..\scratch\fix-emails\node_modules C:\work\app\node_modules 

Remove the junction with cmd /c rmdir ..\scratch\fix-emails\node_modules before removing the worktree. A recursive delete can follow the junction and empty the real node_modules. In PowerShell, rmdir means Remove-Item, not the cmd command, so spell out cmd /c.

Builders build, one place commits

The agents write code and run the typecheck. They don't run the full suite and they don't commit. The lead session does both, in one release worktree, after reading every diff.

That's where the mistakes get caught:

  • One agent's test stored a matcher object where the real value belonged, so a later check compared against the matcher instead of the value.
  • Another kept a test that expected the old behaviour it had just removed.
  • A third added two routes that the permissions test didn't know about.

All three were caught in one place, before any of them reached a commit.

Ship from a clean copy, in batches

The release is cherry-picked onto a fresh worktree at origin/main. If main moved in the meantime, the release is rebased before the final checks, never after. Deploys cost build minutes, so pieces are committed as they land but pushed and deployed together, unless something is hurting a customer right now.

A test that only fails under load is still a bug

With tests running in parallel shards, one film test failed in the full run and passed alone. That's tempting to ignore. But every time one of these got chased down, it had a real cause: a shared temp file, a port, or a timeout that only shows when the machine is busy.

What's the rule you added after your agents broke something?