In October 2026 my AI agents were producing approved code changes faster than they could merge. So I built a merge train, a process that lands approved changes in batches. Four days after it became the only way to merge, I removed it.
Why I built it
Each code change needed an independent reviewer agent to approve its exact version, then a clean merge with the main branch, then a test build. Builder agents worked in parallel, so main moved all the time. A change approved in the morning often no longer merged cleanly by noon. It went back for a rebase, which means updating the change to match the new main, and then back to review. One change went back more than once this way.
At one point, a long list of work waited in review. Some of it had already merged and waited for a check. The rest sat in approved changes that kept going back for a rebase.
The train was the standard answer for a busy repository. It collects every approved change from every agent and runs one preflight, a set of checks before the merge, on all of them merged together. If the preflight passes, the train lands the changes in order. If it fails, the train bisects: it splits the batch in half again and again to find the change that broke it, drops that change and lands the rest. Then one test build runs after each train.
One agent owned every merge. The other agents handed over their approved changes and stopped running their own merges. On paper this meant fewer preflights, fewer test builds and no more rebase loop.
How it fell apart
The preflight on the merged batch took over an hour. That number decided everything else, because every bisect round cost another hour.
On the first day with the train as the only way to merge, several trains ran and each failed on a small defect in a single change. None of them was a real product bug, and each one stopped the whole train. For a long stretch nothing merged while many approved changes waited. A later train failed on one trivial comment issue.
One train failed even after its preflight passed. Two changes were stacked, which means the second built on top of the first, and the train ran the second one first. The first change’s merge came out empty and the train landed nothing.
Four days in, 171 of 175 open changes had an approval, and only 3 of the 9 trains had landed.
The main cause was the batch gate itself. It multiplies one change’s defect across every change in the batch. If each change has a small chance of a small problem, a batch of twenty almost always has one. The bisect finds it, but each round costs a full preflight.
I also took a decision out of the loop without making it any smaller. Before, each agent merged its own change and a defect cost one change. With the train, one defect cost every agent’s work for an hour or more.
I patched it as I went: a per-change check at approval time, a style check, and automatic ordering of stacked changes. Each patch helped. The batch still landed only 3 of 9 trains.
Going back to one at a time
We went back to per-change merges, inside the schedule we already had. Each change merges on its own after an exact-version approval and a clean merge with main, oldest approval first. A test build follows each merge, and a regular gate runs the broad checks once on the current main branch. If that goes red, we bisect there, after the merge, where it blocks nobody’s approval. A full test run happens every night, and a red result becomes a task in the next batch instead of a hold on approved work.
The train did teach me which cheap checks matter most: style checks and a clean merge. They belong at the moment a change gets its approval, not in a shared batch.
I removed the train because the numbers said so, 3 of 9 landed. Next time I’d decide that number before building, not find it four days in. A gate that takes over an hour, with bisect on top, doesn’t fit a team that approves changes all day, so I’d measure the gate time before batching anything.
More on how the rest of the team runs is in Where I still stand in an agent team.
Email hello@jeffkent.dev to talk about delivery for an agent team.




