At the beginning of August I started a plan to let more than one orchestrator work the same repo at the same time. At the end of September I abandoned it. What replaced it took two days.

The Plan

The idea was reasonable. My orchestrator runs tickets one at a time. If I had two machines, I could run two orchestrators, and a batch of tickets would finish as fast as its dependencies allowed instead of strictly in sequence. So I designed a way for them to share the work.

It had a shared ticket pool. A dependency graph so a worker would only take a ticket whose blockers were done. A claim handshake so two workers couldn't grab the same ticket, with the earliest claim winning the race. Worker identities. Liveness signals so you could tell a live worker from a dead one. A reaper to clean up after the dead ones. Budgeting for the GitHub rate limit, since all the workers would share one token. All of it coordinated through comments on a single GitHub issue, because there was no shared filesystem and I didn't want a database.

I was proud of it. It was 82 KB of plan. 😳

The Cold Reads

My process has a rule I call the cold read. When you finish writing something, you hand it to a fresh agent that hasn't seen your reasoning and ask one question: what's missing. I built that rule for tickets. I applied it to the plan.

The first cold read found twelve things. I resolved all twelve. The second found fourteen more. I resolved those. The third, late in September, came back with six blockers, four should-fixes, and three nits, and most of them were interactions between the mechanisms I'd added to resolve the first two rounds.

Every round went the same way. Fix the findings, feel like we're right there, just a couple more questions. Then the couple turns into a dozen, and the dozen are all things the last round's fixes created.

I know that feeling is a mirage. I fell for it three times anyway.

The Conversation

After the third round I said to Claude, more or less: this doesn't feel like we're getting any closer.

It agreed, and pointed out something I'd been avoiding: every cold read had ended with more open questions than the one before. Round one had shrunk the list. Rounds two and three had grown it. The plan wasn't converging. The plane wasn't landing. It was taking off.

So I called a go-around.

The part I'm least proud of: Claude had been suggesting the simple version for weeks, at pretty much every turn. Somewhere in every round there was a "maybe we should try to simplify this," and every time I said some version of "we're almost there." I wasn't ignoring it. I just kept outvoting it.

The Simple Version

One orchestrator per clone. I decide up front which tickets go to which machine. A run is a tracking issue number, given explicitly. No pool, no claims, no liveness, no reaper, no coordination. The only shared-state problem that survives is two runs merging into the same main, and that one has a boring answer: whoever has an open fix PR is fixing it, everyone else waits.

A small skill takes a ticket list and a machine count and hands back the batches, with one hard rule: a dependency never crosses machines. I review the split. That's the entire coordination layer: me reading a list.

Designed and built over two days at the end of September. The plan document is a fraction of the old one's size and has already had its own cold reads, and those converged.

The Lesson

I told a friend two things about this afterward.

First, you'd think I would have learned the lessons of Agile earlier, as many times as I've implemented it. Simplest thing that could possibly work. You aren't gonna need it. I've said both of those to more engineers than I can count. Then I spent seven weeks building a distributed coordination protocol for two laptops.

Second, and this is the bigger one: since I started doing agentic development, I have not once had the problem of not being able to generate code fast enough. Every problem I've had was the opposite. Too many tests, too many tickets, too much code with not enough judgment in the loop. The parallel plan was there to speed up the one thing that was never broken.

I'm the king of solving problems I don't have.

Calling the go-around wasn't the failure. Pilots do that all the time, and the only bad go-around is the one you didn't call. The failure was the three approaches before it, where I could see the runway wasn't where I thought and kept descending because I'd already committed. Next time somebody says "maybe simpler," I'm going to listen the first time. Of course, there's probably a better chance of a leopard changing its spots.

Kevin Phifer is the founder of Theoretically Impossible Solutions LLC, specializing in agentic AI development and consulting. You can reach him at kevin.phifer@theoreticallyimpossible.org.

← Back to Blog