The Agent Runtime Problem: Four Things a while-Loop Doesn't Give You
Almost every agent you can install today is a while loop. Send the context, take the response, execute the tools, push the results onto an array, repeat. It is a good loop. It is roughly two hundred lines, it works, and for the first year of this technology it was enough, because the thing on the other end ran for ninety seconds while a human watched.
That assumption is gone. Agents now run unattended for hours, several at a time, on machines the person who started them has walked away from. And the moment that became normal, four problems appeared that the loop has no vocabulary for — and, more to the point, that the word framework has no vocabulary for either.
I have spent the last few months reading the systems that are trying to answer them: Pi's AgentHarness specification, herdr's daemon, the loop Jarred Sumner used to port Bun from Zig to Rust, and the two payment stacks — x402 and Cloudflare's agent wallets — that are trying to give an agent a way to pay for things.
They have almost nothing in common. Different languages, different companies, different problem statements, no shared vocabulary. But read them together and the shape is unmistakable: they are four quarters of one system, and every one of them is being built by people who do not think they are building the same thing.
Why "framework" is the wrong word
The distinction I want is old and worth restating, because the industry is using the wrong half of it.
A framework is something you call. It gives you abstractions — a prompt template, a tool registry, a retry decorator — and your process owns the lifetime. When your process dies, the framework dies with it, and this is fine, because a framework never promised otherwise.
A runtime is something that owns you. It holds the state your process was mutating, it survives the process, and it can answer questions about work it is currently doing. A JVM is a runtime. Postgres is a runtime. tmux, arguably, is a runtime for terminals.
Everything currently marketed as an "agent framework" is, accurately, a framework. That is not an insult; it is a scope. The problem is that the workload moved into runtime territory — long-running, crash-exposed, concurrent, spending money — while the tooling stayed in framework territory, and the gap between those two is where every operational horror story of the last year comes from.
Here is the test I keep coming back to. Kill -9 the process. What does the system still know? A framework: nothing. A runtime: everything that was committed, plus enough about what was in flight to decide what to do next.
Four things fail that test in four different ways.
Problem one: the loop cannot be resumed
Take the naive loop literally and walk a crash through it.
The model returns two tool calls. The first one starts deleting files. The process is killed halfway through. On restart, what does the system know? The tool ran — the files are gone — but nothing recorded that it ran, because the record was going to be the push that never happened. The conversation now has a tool call with no result, which most providers will reject outright, and the underlying side effect already happened once and is about to happen again.
The nastiest variant is the provider request itself. Die mid-stream and you do not know whether you were billed, whether you were served, or whether a partial answer exists anywhere.
Pi's AgentHarness spec is the most complete answer I have read, and its first move is to refuse the hardest part:
Partial streams are process-local, never persisted. A settled response is persisted completely before anything classifies it.
That refusal is the enabling move. Once you accept that one specific step is unrecoverable, you can arrange every other step so recovery is a lookup rather than a guess. The rule the whole 2,900-line document reduces to:
Commit: "about to do X; its output will use ids R and U." Do X. Commit: the complete output, its usage, and the next total state.
Two commits around one uncertain call. The intent commit mints the ids the settlement will use, so recovery does not have to reconstruct what probably happened — it reads one register, collects the ids that register names, and asks storage which of them exist. Because a transaction is all-or-none, there is exactly one uncertain interval in the entire system: intent durable, settlement absent.
The generalisable part is not the spec. It is the recognition that an agent turn is a distributed transaction that nobody was treating as one. Every effect that reaches outside the process — a billed request, a filesystem write, a network call — is a two-phase commit whether you designed it as one or not. If you did not, the phases are still there; you just have no name for the state between them.
The other transferable piece: a tool has to declare whether it is safe to replay. Pi stores that declaration alongside the arguments, and on recovery re-executes only if the stored declaration and the current one both say safe. Otherwise it writes a synthetic error under the already-reserved result id and moves on. That is a small idea with a large blast radius, and you can add it to a while loop this afternoon.
Problem two: nothing owns the session
The second problem has nothing to do with correctness and everything to do with the fact that a terminal belongs to a human who is no longer there.
Run a coding agent and it spawns a terminal. Close the laptop, drop the SSH connection, or let the agent process crash, and the terminal goes with it. Tolerable for one agent for ten minutes. Not tolerable for six agents for six hours — at which point the actual failure is subtler than lost work: the agent that finished twenty minutes ago has been idle since, and the one that hit a permission prompt has been blocked just as long, and you had no way to know either.
tmux solves half of this and has been solving it since 2007. Sessions survive disconnects; you can attach from your phone. But tmux owns sessions on a human's behalf and has no idea what is running inside a pane. Asking "which agent is blocked?" means bell characters, hook scripts, or a polling loop you wrote yourself.
herdr's answer is a daemon that owns every session on a machine, and its differentiator is one sentence from the repo: "every pane is marked working, blocked, or idle. when an agent stops and needs an answer, herdr says so." You do not configure it. The runtime infers it.
But the part that actually earns the category name is the second one: "the cli and socket api are the same surface agents drive." That is the dividing line between a multiplexer and a runtime, and it is worth stating generally:
A multiplexer is something you operate. A runtime is something a program calls.
Every integration with a multiplexer is a script gluing keystrokes together. A runtime has an API, which means an orchestrator agent can treat it as infrastructure rather than as a terminal it happens to be sitting in. That is why one of them accumulates a plugin ecosystem and the other accumulates dotfiles.
Problem three: the author cannot be the reviewer
The first two problems are infrastructure. The third is the one people get wrong even when their infrastructure is perfect, and it is the only one of the four where the answer is a process rather than a component.
In eleven days in May 2026, Bun's 535,496 lines of Zig became Rust — one engineer, roughly 64 Claude instances, 6,502 commits, about $165,000 in tokens. Most of the coverage since has argued about whether the headline is true. The transferable thing is the loop, and it is almost independent of the scale it ran at:
- One implementer, two reviewers that see only the diff and are told to assume it is wrong, one separate fixer.
- The spec came first, as an artefact rather than a prompt: three hours of conversation became
PORTING.md, and a whole workflow analysing every struct field producedLIFETIMES.tsv. Sixty-four agents produced consistent code because they were all bound to the same document. - The compiler and the test suite were the ground truth: ~16,000 compiler errors as a work queue, 1.4 million
expect()calls as the acceptance gate, zero tests deleted or skipped.
The parallelism was a cost decision. The split context window was the engineering. A reviewer that can see the implementer's reasoning is not reviewing; it is agreeing with itself, and it will agree with itself at any scale you can afford.
I keep this one on the list of runtime problems even though it looks like a workflow question, because the thing that makes it work is infrastructural: an artefact store that many agents bind to, a work queue with an external source of truth, and isolation between roles that the runtime enforces rather than the prompt requests. That is a scheduler with an opinion about who may read what. Nobody ships it yet; everyone rebuilds it per project.
And the cheapest lesson in the whole story survives the scale-down intact. You cannot spend $165,000 on a refactor. You can absolutely stop letting the agent that wrote the code review the code.
Problem four: no name, and no way to pay
The fourth problem is the one that sounds like science fiction until you notice it is already blocking mundane work. An agent that can browse can also hit a paywall, a rate limit, or an API that wants a key it does not have. Its options today are: have a human pre-provision every credential it will ever need, or stop.
Two things are missing, and they are usually conflated. An agent has no identity it can present — no way to say I am this agent, acting for this person, within these limits — and no payment rail built for thousands of sub-dollar purchases with no human at the keyboard. Cards fail on both counts: minimum fees swallow a $0.02 purchase, and chargebacks assume a cardholder who can dispute.
x402 answers the second by reviving HTTP 402. The server responds 402 Payment Required with machine-readable pricing, the client pays with a signed stablecoin authorization, retries, and gets the resource. It is deliberately minimal: payment is the credential, so there is no account, no key, no session. That minimalism is its strength for paid APIs and its limitation everywhere else.
Cloudflare's wallets answer the first, and the two-tier structure is the interesting bit: an Account Wallet you own, Virtual Wallets you delegate to individual agents, and policy enforced at each hop before anything gets signed. That is the shape of the real problem — not "can the agent pay" but "what is the blast radius when it pays wrongly."
Since both posts already carry a full comparison table, the useful thing to add here is the selection rule, which is shorter than either table:
- You are selling an API or a data feed, and you want agent money today. x402. One line of middleware on the server, one wrapper on the client, and it is the only one of these with real production volume on the sell side.
- You are spending, and you care about limits and audit. A delegation model — Cloudflare's virtual wallets, or Google's AP2 mandates. The question you are actually answering is "what did it buy, on whose authority," and a stateless rail cannot answer it.
- You are already a Stripe merchant and want one integration. MPP, and wait. The fiat path is the whole reason to choose it.
- You are doing retail checkout inside a chat product. ACP. Different problem, human-confirmed, and not really an agent-autonomy story at all.
- Sub-cent Bitcoin payments. L402, and you already knew that.
The honest caveat on all of it: as of mid-2026, more than 95% of x402 activity is still protocol signalling rather than commerce. This quadrant has the clearest standards and the least real usage, which is exactly the inverse of the first two.
Nobody has four
Line the four up and the scorecard is unflattering in a useful way.
| durable state | session ownership | orchestration loop | identity + money | |
|---|---|---|---|---|
| Pi / AgentHarness | ✅ specified in depth | — | partial (lanes) | — |
| herdr | session-level | ✅ the whole product | — | — |
| Bun's port loop | — | — | ✅ demonstrated | — |
| x402 / CF wallets | — | — | — | ✅ two halves of it |
your while loop |
— | — | — | — |
Every column has a credible answer. No row has two. That is the actual state of the art in 2026, and it means the thing most people call "my agent stack" is four independent bets held together by a shell script.
I do not think this is a scandal. It is what an emerging layer looks like before anyone knows where the seams go — the same way "web server," "application server" and "database" took a decade to settle into the boundaries that now feel obvious. But it does mean the useful question when you evaluate any agent tool is not what can it do, it is which of the four does it own, and what happens to the other three.
What to build against today
If you run agents unattended and you are not going to write a 2,900-line spec this quarter, four things are cheap and disproportionately effective:
Make every tool declare whether it is safe to replay, and store that declaration with the arguments, not in the code. It costs a field. It is the difference between a recovery policy and a coin flip.
Commit the intent before the effect, and the result after it, and never let those be the same write. You do not need three stores to do this. You need to stop treating "append to the array" as the record.
Put your sessions somewhere that outlives the agent process, and make sure something can tell you which of them is blocked. If that is a tmux server plus a hook script you wrote, fine — but know that it is the component you are hand-rolling.
Never let the agent that wrote the code review the code. Two reviewers, diff only, told to assume it is wrong. This is free, it works at any scale, and it is the single highest-yield line in this entire post.
The while loop is not wrong. It is just the innermost layer of something that turned out to have four more, and the industry is currently discovering them in the order that hurt the most.
Read against the sources linked throughout, as of 22 August 2026. Every quoted line comes from the project's own documentation; the scorecard is my reading of what each project claims to own, not a feature audit.