The bottleneck moved from code to coordination
When agents can write the code, most of a ten-agent workforce is spent waiting — and waiting is a process-engineering problem
For two years the whole industry optimized one number: how good is the model at writing code. It worked. Cross a threshold — reliable enough agents, a codebase architected so that mistakes are contained rather than catastrophic, and CI plus integration tests that actually catch regressions — and something quietly flips. Writing the code stops being the hard part.
That’s not a prediction; plenty of teams are already there on well-shaped repos. And the interesting thing about clearing a bottleneck is that it doesn’t end the story — it just reveals the next one. When any single change is cheap to produce and safe to land, the friction doesn’t disappear. It moves. It moves to coordination.
What made the code cheap
Three things have to be true at once, and each is doing real work:
- Agents are reliable enough. A competent agent, given a well-scoped task, lands a correct change most of the time — and knows when it’s stuck.
- The codebase is architected for safety. Clear seams, narrow interfaces, idempotent operations, blast-radius limits. A wrong edit fails loudly and locally instead of corrupting something three modules away.
- CI and integration testing are a real safety net. Regressions get caught before they merge, so you can let many hands move quickly without holding your breath.
Get those three and you can point ten agents at a backlog. Which is exactly when the new problem shows up.
So where did the friction go? Watch the agents wait.
Put ten-plus agents on one product and watch what they actually spend time on. A surprising amount of it is nothing. Waiting:
- Agent B needs the interface Agent A is still writing — so B waits on A’s merge.
- A pull request sits through a review cycle: request review, get comments, fix, re-request, converge. Round-trips, not keystrokes.
- A fan-out of twelve slices has to fan back in — the integration step can’t start until the slowest slice lands.
- Two agents reach for the same file and one has to back off, rebase, and retry.
- A change needs a human decision — a product tradeoff, an approval — and everything downstream blocks on a person who isn’t looking yet.
None of that is a coding problem. You cannot fix it with a smarter model. It is the shape of the dependency graph and the latency of the hand-offs between agents.
With ten agents, the constraint isn’t how fast any one of them writes code. It’s how much of the time the other nine are blocked on it.
Waiting is a first-class thing, not an accident
The instinct is to treat waiting as a bug — spin faster, poll harder, add a retry. But most of these waits are legitimate: the review genuinely has to happen; the dependency genuinely has to land first; the human genuinely has to decide. The problem isn’t that the wait exists. It’s that nothing in the system is designed to represent a wait, reason about it, and wake up cleanly when it resolves.
So teams reinvent it, badly: a script that sleeps and re-checks; a spreadsheet of “who’s blocked on whom”; an agent burning tokens re-reading a PR every minute to see if review came back; state that lives only in one process, so a restart loses the whole plan. That’s a scheduler and a dependency resolver, hand-rolled and leaky, once per team.
This is a process-engineering problem
Step back and the shape is familiar. You have units of work with dependencies between them. Some run in parallel, some must serialize. Some pause on an external signal — a review verdict, a merge, a human approval — and resume when it arrives. Some fan out into N instances and join when all N finish. You want the whole thing to survive a process dying or a machine rebooting, and pick up exactly where it left off.
That is not a novel AI problem. It is the oldest problem in workflow orchestration, and the field has a mature vocabulary for it: tasks and dependencies, parallel and multi-instance branches, message correlation, timers, and — crucially — wait states as a first-class primitive. A durable process engine doesn’t poll for a review to come back; it parks the branch on a wait state and is woken by the event. It doesn’t lose the plan on restart; the plan is a journalled graph, not a variable in memory.
This is the bet behind Nano. Nano Workforce models the software lifecycle — plan, implement, review, test, merge, QA, retro — as a durable graph, and the agents are workers it schedules against that graph. Dependencies are edges. Review cycles are wait states with timeouts and escalation. Fan-out/fan-in is a multi-instance activity with a join. A human decision is a user task the graph blocks on without burning a single token while it waits. The engine is Rust, Camunda 8 API compatible, and small enough to run on a workstation — because coordinating ten agents shouldn’t require a cluster.
The point isn’t “use a workflow engine because workflow engines exist.” It’s that the problem you hit at ten agents is a workflow problem, and rebuilding a durable scheduler by hand — one team at a time, one sleep-loop at a time — is the actual tax.
The takeaway
The next 10x in agent-assisted development probably isn’t a model that writes better functions. On a codebase that’s already safe to change, the functions are cheap. The next 10x is in the gaps between the agents: scheduling the work, representing the waits, resolving the dependencies, and never losing the plan when a process dies.
When the code writes itself, coordination is the job.
See how the layers fit together on the Nano architecture page, or try the durable engine in your browser at nanobpm.io/demo.