Too Much for One Agent
PromptPack is a specification for defining an agent. PromptArena is where we build and test the agents that specification defines. PromptKit is the runtime that executes them. Omnia is the multi-tenant platform that runs the result in production.
“Platform” undersells it. Omnia is fifteen deployable services, eight core and seven enterprise, reconciling seventeen custom resource definitions between them. They talk over WebSocket, bidirectional gRPC, HTTP, Redis streams and server-sent events, across thirty-odd distinct service-to-service edges. Sessions compact hot to warm to cold across Redis, Postgres and a cold tier. Cross-session memory is an entity-relation-observation store on Postgres with pgvector. Every tool call an agent makes is a round trip to a policy sidecar injected into its own pod, which answers allow or deny and fails closed.
Multi-tenancy runs through all of that, so every path is workspace-scoped, and the agent’s external listener has a management twin on a separate port with a different JWT audience so the two planes can never be mistaken for each other. Then the whole thing has to run on AWS, Azure and GCP: three sets of identity primitives, three networking models, three separate ways to be wrong about DNS.
No single agent holds that. Not with a bigger context window, and not in the next model generation either. We found that out the ordinary way: we pointed one agent at too much of it. Spaghetti, and then a Gordian knot on top of the spaghetti, which is worse, because at least spaghetti can be unpicked one strand at a time.
I got lucky on the timing. I’d watched the same thing happen on client projects at HollandTech, so I recognised the shape early enough to do something about it, instead of eighteen months later during a rewrite. That’s the only reason this post isn’t a considerably more expensive story.
What “More Context” Actually Buys You
The instinct when an agent gets something wrong across a boundary is to give it more. Bigger window. Index the other repositories. Put a summariser in front of the lot so it can ask about anything.
That’s the wrong direction, and it fails twice.
Something has to filter. Point an agent at every repository and a retrieval layer decides what it sees. That filter is where the fidelity goes, and you cannot see what it dropped. The agent doesn’t report “I was shown a summary of the payments service and it omitted the idempotency rules.” It just writes code as though those rules don’t exist.
What it can read, it will use. An agent that can see another service’s internals will build against them, because they’re right there and they work. That’s a dependency nobody agreed to and nobody is tracking, and it breaks the day those internals change.
There’s evidence for that now, and it’s worse than I’d assumed. More Code, Less Reuse, published in January, found that LLM agents “frequently disregard code reuse opportunities, resulting in higher levels of redundancy compared to human developers.” That much I’d have guessed. What I wouldn’t: reviewers expressed more neutral-to-positive sentiment towards AI-generated pull requests than human ones. The authors put it plainly: the “surface-level plausibility of AI code masks redundancy, leading to the silent accumulation of technical debt.”
Put those together and the failure mode is invisible at review time. It doesn’t look like bad code, it looks like fine code, and it gets waved through slightly faster than a human’s would. So the usual answer is to add review, add process, be more careful. All of it aimed at a checkpoint that has already been shown not to catch this.
Duplication and coupling look like opposite problems, and they’re the same one. An agent optimises for what is visible and immediate, not for what is agreed. Show it another service’s internals and it couples to them, because that’s the shortest path. Give it a vast context and it writes fresh code instead of finding the right abstraction, because that’s also the shortest path. Both times it’s doing precisely what you asked, taking the nearest route, and neither route goes past anyone who could have said no.
So We Gave It Less
The mitigation isn’t clever. An agent sees its own bounded context, kept small and coherent. Everything beyond it is a contract.
What matters is that we made it a fact rather than a rule. Services are defined as boundaries and the code is physically isolated: separate repositories, separate working trees, and the agent’s read and write scope controlled per context. The agent working on the runtime cannot read the platform’s internals. Not “is instructed not to”. Cannot.
That distinction is doing all the work. It’s the same one that separates a staging environment from a real boundary: a constraint living in a naming convention gets reasoned around, and a constraint living in the enforcement path doesn’t. An agent that can’t see a thing can’t couple to it, can’t duplicate it, and can’t have a persuasive opinion about it.
And it works. The repositories now hold over two million lines, and they were written far faster than I could have written them. I’m not going to pretend that’s all agent output or that line count is a quality metric. But nothing collapsed into a knot, because no single agent was ever in a position to tie one.
The Bill
Here’s the part that doesn’t make it into the framework diagrams.
It needs human eyes on every decision that crosses a boundary. Every one. When the runtime needs something from the platform, the boundary that stops the agent reaching across is also the boundary that stops the work crossing, so a human carries it. I decide what the contract should be, whether the proposed shape is safe, whether the other side can absorb it, what breaks downstream. The constraint that makes the agent safe makes me the bottleneck.
And it has to be a human, because every one of those is an architecture decision, which is the one category of work agents are reliably worst at. They’re superb implementers and they are confidently wrong about the calls that matter, which is survivable inside a bounded context where the blast radius is one service, and not survivable where two of them meet.
The load is continuous. A standing tax on every cross-boundary thought.
It turns out this isn’t a local quirk of how we work. How Coding Agents Fail Their Users, published in May, analysed 20,574 real-world coding-agent sessions and found that 91.49% of visible misalignment resolutions required explicit user correction. Seven recurring failure forms, one of which is, word for word, overstepping action boundaries. And the honest reading: 90.50% of those episodes cost effort and trust instead of causing irreversible damage.
So mostly it’s friction, not catastrophe. But friction arriving on nine out of ten interventions, forever, is the actual operating cost of the model everyone is quietly running.
Two Options, Both Bad
Once you’ve paid that bill for a while you notice there are only two moves available.
Go full YOLO: let the agent do what it likes, across everything, and accept what comes back. It’s genuinely faster, right up until it isn’t. This is the Forrest Gump failure: extraordinary speed, sustained well past the point where anyone checked the direction, and you find out at eighty per cent complete, which is where projects have always gone to die.
Or accept the human bottleneck: keep the boundaries, keep the isolation, and keep a person in every doorway.
We run a bit of both, and I’d be lying if I claimed otherwise. Some corners have a small enough blast radius that letting an agent run is obviously correct. That judgement is really a position on a ladder rather than a binary: assist, then execute under review, then operate. Different parts of the stack sit on different rungs.
But I’ve been doing this long enough to say it flatly. There is always a price to pay for YOLO. It gets charged later, to someone with less context about why the code looks like that, usually during an incident.
Neither option is a strategy. Both are ways of choosing when to be billed.
What’s Actually Missing
Notice what the bottleneck actually is. No agent here is doing anything dangerous. They simply cannot agree anything with each other, so a human carries every agreement across by hand.
Which means the thing agents have not touched is the gathering: getting everyone pointed the same way, getting a decision to actually happen, getting one change past several teams and out of the door. I wrote that piece about organisations, and then noticed I’d built a small one out of software and inherited the same arithmetic. Writing the code stopped being the constraint some time ago. Agreeing the change never did.
That’s a protocol problem, and an old one.
If two bounded contexts are going to settle a change without a human mediating every exchange, the boundary has to carry something machine-readable. Concretely: a request that states an outcome and a reason and never an implementation. An expectation backed by a failing test rather than a paragraph of prose. A proposal from the provider, possibly for a different and safer shape than the one that was asked for. And — the move the whole thing turns on — an objection: the provider can say no, and say why, in terms of consumers, semantics, versioning and migration risk.
Then the parts that make it verifiable rather than conversational: the change set across every affected repository, the evidence from tests and contracts and policy, the merge plan giving the safe order for the coordinated pull requests to land, and a recorded decision so the same argument isn’t re-litigated in six weeks by a different agent with a different prompt.
None of this is new. Speech acts as a basis for agent communication go back to KQML and were standardised in FIPA-ACL in 2002. Task allocation by announce-bid-award is Reid Smith’s Contract Net protocol, published in 1980. Deriving a provider’s obligations from what its consumers actually rely on is consumer-driven contracts, which Ian Robinson wrote up in 2006. The prior art has been sitting there for forty-five years waiting for a reason to be useful, and a pair of agents that cannot be allowed to read each other’s code is a very good reason.
That’s what we’re building as CloudBasis. It doesn’t remove the human. It moves them: from attention on every exchange to approval at defined points, with the negotiation recorded as an artefact instead of evaporating into a Slack thread.
What We Haven’t Proved
The benchmark hasn’t been run. I’m not going to give you a number for how much of that cognitive load this actually removes, because we don’t have one.
The counter-proposal path, where the provider declines and offers a different shape, is the most interesting thing in the protocol and the least exercised. It’s easy to build a system where the answer is always yes and call it a negotiation.
And none of this retroactively fixes two million lines written under the bottleneck model. The boundaries are real and the isolation is real, but every contract currently in force was negotiated by a human, in their head, and most of them were never written down as anything a machine could check. Which makes this the same job every enterprise programme for forty years has actually been doing: getting what people know out of their heads and into a system. I’ve spent a good while arguing that’s the work. It’s mildly humbling to find my own architecture sitting in my head, undocumented and load-bearing.
One thing I am confident about is the diagnosis. Giving the agent more context is not the fix, because the failure was never ignorance. It’s that nothing on the other side of the boundary can say no. Right now the only thing that can is me.
Further Reading
- More Code, Less Reuse: Investigating Code Quality and Reviewer Sentiment towards AI-generated Pull Requests — Huang et al., January 2026. Agents duplicate rather than reuse, and reviewers like the results slightly more than human work. The second half is the alarming half.
- How Coding Agents Fail Their Users: A Large-Scale Analysis of Developer-Agent Misalignment in 20,574 Real-World Sessions — Tang et al., May 2026. Seven failure forms, including overstepping action boundaries, and the 91.49% correction rate.
- The Contract Net Protocol: High-Level Communication and Control in a Distributed Problem Solver — Reid G. Smith, IEEE Transactions on Computers, December 1980. Announce, bid, award. Still the clearest treatment.
- FIPA ACL Message Structure Specification — the 2002 standardisation of performatives, later inherited by the IEEE. Worth reading for how much of this was settled before anyone needed it.
- Consumer-Driven Contracts: A Service Evolution Pattern — Ian Robinson, 2006. Where the “expectation backed by a test” idea comes from.
- Staging Is Not Containment — the companion argument about boundaries that exist in the enforcement path, not in a naming convention.