AiBook · Jeremy Schoemaker · 2026 · ch-27.html

The Merge From Hell

(Spine Ch. 27.)

“JAMES: I AM SO HUNGRY. CHRIS: YOU ARE NOT HUNGRY. RICH: I DECLARE CHRIS TO BE FAULTY. CHRIS: I DECLARE RICH TO BE FAULTY. JAMES: I DECLARE JAMES TO BE SLIPPING INTO A DIABETIC COMA. RICH: I have already left for the cafeteria.” James Mickens, The Saddest Moment, USENIX ;login: logout (2013)

Seventeen branches, named and ordered, sitting in a handoff that said they needed merging. I started at the top like a good soldier. Git told me they were unmerged. The diff on one of them, 71 commits behind, reported 10,418 deletions of code that nobody had ever deleted. Somewhere in there I was about to merge a branch written specifically to revert a leaked payload, which would have put the payload back. That was 7 August 2026, and I spent the day proving something about those seventeen branches that the tool everybody reaches for could not tell me.

Bottom line: Fan-out is cheap. You can spawn twelve agents on twelve branches for the price of a sandwich, and the dashboard will look glorious. Merge is the job. Merge is where the conflicting edits, the duplicated work, and the contradictory conclusions come due at once, and none of that is on the dashboard. The math that makes fan-out attractive (N agents, N times the work) assumes reconciliation is free. It isn’t. It’s most of the cost, it lands on one human, and it lands last.


When it bites


The pattern

A July 2026 arXiv study of agent-authored pull requests on GitHub (Xu, Subramanian, Karthik, arXiv:2607.04697) looked at what happens when agent PRs overlap in time. 40.2% of repositories in the sample contained co-active agent-authored PR pairs, and 79.4% of all agent PRs happen in a co-active context. Parallel is the default shape now, not the exception.

Then the number that should change how you staff this: cross-agent parallel PRs hit a 41.7% textual merge conflict rate, against 19.8% for intra-agent PRs. That’s textual conflict, the kind git can see. It’s the cheap half.

The expensive half has no tooling and no number. Cognition wrote the clearest version of it in June 2025 in “Don’t Build Multi-Agents”: actions carry implicit decisions, conflicting decisions carry bad results, and subagents cannot see what parallel subagents are doing. Every file an agent writes is a hundred small commitments it never announced: naming, error shape, where validation lives. Git diffs text. It has no opinion about two agents having quietly disagreed about what an error is.

Galileo Labs put a name on the downstream symptom in April 2025: failures in complex multi-agent systems are common but incredibly difficult to diagnose, precisely because the agents were autonomous.

Isolation helps and is not the answer. Git worktrees went load-bearing for AI coding in Q1 2026, and the practical rule by April was that you need them the moment two agents edit the same repo for more than ten minutes (Nimbalyst, April 2026, unverified, but it matches what everyone I know does). Worktrees stop agents from stomping each other’s working tree. They reconcile nothing.

The research volume tells you where the attention went: multi-agent orchestration papers jumped from 820 in 2024 to 2,500-plus in 2025. The literature on reconciliation is one arXiv paper and a Cognition blog post telling you not to do it.

A fan-out dashboard with twelve green agents on it is the Dancing Baby (1996). It renders beautifully, everybody stops to watch it, and it is not doing any work.


One worked example

airank, 7 August 2026. A handoff said seventeen branches were unmerged. A handoff’s branch list is a Geocities page with an Under Construction GIF on it: somebody meant it when they wrote it, and it has been wrong ever since.

The first thing I did was ask git, and git answered a different question than the one I asked. git branch --no-merged answers “is this branch’s tip SHA an ancestor of main,” not “did this branch’s contribution land.” Those come apart the second anybody rebases, cherry-picks, or reimplements the same idea by hand.

The diffs made it worse. A three-dot diff hides everything main gained since the fork point, so a branch still looks like it has unique work. A two-dot diff on one branch that was 71 commits behind reported 10,418 deletions of code nobody ever deleted, an artifact of asking about a fork point while pretending you asked about content.

I want to be clear about who the idiot is here. Jeremy Schoemaker, running Linux boxes since the dial-up days, took a number that said 10,418 deletions and briefly believed a branch had eaten ten thousand lines of his own product. I did not check what the number measured. I checked how bad I felt about it.

What worked was boring: hash the files the branch touched, sweep for files it adds that main doesn’t have, grep main for the contribution it claims to make. Three checks about content, none about ancestry.

Result: all seventeen had already landed on main by other routes. Zero needed merging, and merging them would have been destructive, not just wasteful. One branch was a deliberate revert of a leaked payload, so merging it would have re-leaked. Another reintroduced a heuristic the codebase had already tried, tested, and rejected, with the rejection sitting right there in a comment on main. Zero merges deployed, suite still 291 passing.

One day later, 8 August 2026, the same failure wore different clothes. A handoff claimed duplicate products were corrupting every observation in the dataset. Before writing the dedup, I ran the count two ways. Grouping on product_name alone flagged 58 duplicates. Grouping on brand plus name plus use_case_segment flagged 4. A 93% false positive rate, entirely from picking the wrong axis to measure on.

The 54 that vanished were not noise. ChatGPT returns segmented answers: “HubSpot free tier for 1-2 people” and “HubSpot for marketing teams” are distinct observations. A naive dedup on name would have deleted 54 real distinctions to fix 4 real duplicates, run clean, passed the tests, and quietly made the dataset worse, and I would have written it up as a win. Pwned by my own GROUP BY.

12 August 2026 closed the loop. A multi-model jury (10 surfaces, 5 models, 3 rounds) shipped a bug in Round 1 and caught it in Round 3. Round 1 added relative time formatting to the bot list. Timestamps coming off the Eloquent model were cast to datetime and arrived as ISO 8601. The same-looking timestamp coming off a raw SQL aggregate alias bypassed the cast entirely and arrived as a bare string. One formatter, two shapes. Safari printed NaN. Chrome silently rendered a time that was wrong by 5 hours and looked completely fine.

Two parallel workers, one on the model layer and one on the query, each shipped a correct thing. The Chrome failure is the one that matters: it did not throw or fail a test, it just displayed a plausible number. It took a jury of five models three rounds to tell me what my own eyes had signed off on.

Jury stop votes went 0 out of 45 in Round 1 to 28 out of 45 in Round 2.

People ask me for the number, the N where you stop adding agents to one repo, and I do not have it. My biggest wave on record is eleven agents in eleven worktrees on the night of 13 August 2026, and all eleven jobs landed. What eleven cost me was a morning: the siblings shared one MinIO bucket and ate each other’s fixtures, which is Ch. 49’s story. My belief is that a crossover exists, and the only reason I believe it is that the one wave I bothered to write down cost me a morning of stitching. That is a hunch with a bruise attached, not a measurement. Nobody recorded whether a twelfth would have cost more to merge than it earned, which is a hell of a gap for a guy with a whole chapter about measuring things.


The quiet failure

The loud failure is the conflict: twelve red files, <<<<<<< HEAD, an afternoon gone. Painful, visible, budgetable. You will not lose a company to it.

The quiet failure:

Two agents made contradictory decisions, the merge applied cleanly, and nothing anywhere recorded that a decision was made.

Agent A put retry logic in the client. Agent B put it in the service, because Agent B never saw Agent A. Both merge, nothing conflicts, and you now retry twice with different backoff. You find out during an incident, when a downstream gets four times the traffic you modeled, and the history shows two reasonable commits with no line to blame.

Second: the deduplication that deletes. 58 flagged, 4 real, 54 legitimate distinctions in the bin. Removing duplicate work and removing variation you needed are the same operation, separated only by the grouping key.


Do / don’t

Do

Don’t


Where this sits in the book

Ch. 25 is the fan-out, and its point is that your five agents are five clients of one connection pool, one rate limit, one database. This chapter is the invoice that shows up after. Ch. 15 is the same disease upstream (a plan is a persuasive artifact that decays); the seventeen-branches story appears in both as the cleanest example of an inherited conclusion that cost a day. Ch. 59 is this chapter in judgment terms instead of git terms: somebody reads N outputs, decides which is right, and stitches the survivors into one shipping thing. That work scales linearly with N.


Sources and receipts

Thesis is Jeremy’s (“fan-out is cheap, merge is the job”): argument, not citation.

Verified:

What I could not verify:

What I could not verify: