Workain

Field notes

AI wobbling: why killing a drifting agent fleet costs more than letting it finish

2026-07-28

At speed, a motorcycle’s handlebars can start shaking on their own. The instinct is to grab the brake. That is the one thing that reliably makes it worse — braking loads the front end and feeds the oscillation. You damp it with steady throttle and loose hands.

Today the same thing happened to my agent orchestrator. It started mixing up which task went to which session, and mixing up what came back.

First instinct: kill switch. Stop everything, sort it out in the quiet. And honestly, for a minute it was just alarming and unclear what to do — some of that work was already done, part of it was already deployed, and I couldn’t say what state any of it would be in if I pulled the plug right then.

TL;DR

  1. A half-finished unit of work is the expensive state. Gray defined atomicity in 1981 to make that state impossible; the cost of landing in it anyway has now been measured on coding agents directly.
  2. The worst moment to cut is right after an agent responds to its first error — taking that over from a bare repository cost the next agent 122–191 actions, median. Which is exactly when a watching human reaches for the switch.
  3. An agent fleet is a long transaction, so the usable model is sagas and compensation: every step either completes or has a known way to be undone.
  4. The production move is shedding intake. Throttle what’s arriving; let what’s already executing land.
  5. Hit the switch anyway when something irreversible is in flight, on a security event, on runaway spend, or when you can’t enumerate what’s running.
  6. Coasting is only available if you built for it first — isolated branches, tracked tasks, no auto-merge. Without that inventory the kill switch really is the only tool you have.

The middle is the worst state to be in

Jim Gray settled this in 1981. A transaction is atomic: either all its actions are done and it commits, or none of its effects survive and it aborts. No third option, by design. A committed change you can revert. An aborted one left nothing behind. A half-applied one you have to reconstruct before you can even decide what to do about it.

That reconstruction cost has now been measured on agents specifically. KC and Budathoki interrupted coding agents at three fixed points and measured what it costs a successor to take over — they call it handoff debt (75 source tasks expanded into 181 handoff points and 2,172 takeover runs). Handing over real context instead of a bare repository cut median agent events by 20–59% and prompt tokens by 42–63%. The most expensive place to cut was right after the agent had responded to its first error: taking that over from the repository alone cost the next agent 122–191 actions, median. Which is exactly the moment a watching human decides something is wrong and reaches for the switch.

An agent fleet is a long transaction

Atomicity assumes a unit of work is short and can be rolled back wholesale. A fleet running for hours, touching branches, files, deploys and external services, can’t be. That case — the long-lived transaction — is the one Gray’s own paper flagged as unsolved and left for future work.

It got solved six years later. Garcia-Molina and Salem’s Sagas (SIGMOD, 1987) treats a long transaction as a sequence of smaller ones, with the guarantee that either all of them complete or compensating transactions run to amend a partial execution. You give up freezing the world. You keep the guarantee of never being stranded halfway: every step either completes or has a known way to be undone.

Which turns the operational question into a search for the nearest state where every in-flight unit has either completed or been compensated. How fast you can stop the fleet stops being the useful number.

Stop intake, not execution

The production version of this is unglamorous and well documented. Google’s SRE book, in Addressing Cascading Failures, describes the response to a system going bad as shedding incoming load — returning errors for new requests past a utilization threshold, dropping a fraction of upstream traffic including retries, degrading service quality rather than stopping. Search will scan a smaller slice of the index before it will stop answering. It throttles what is arriving. It does not go around killing what is already executing.

So: hand out no new tasks, let the running ones land, then diagnose. Which is what I did — handed out nothing new, waited, and only then sat down, worked out what had broken, and fixed it.

When to hit the switch anyway

Erlang has been telling people to let it crash for decades, and Erlang is right — because a supervisor restarts the worker into a known clean state. Crash-and-restart is safe when the restart lands somewhere well-defined, which is the same condition as above, from the other side.

Some things warrant the switch immediately, whatever the mess costs:

  • anything destructive or irreversible in flight — data deletion, a production migration, an outbound send;
  • a security event, where the agent’s continued action is itself the harm;
  • runaway spend or a retry storm, where waiting costs more than the rediscovery does;
  • any case where you genuinely cannot tell what the fleet is doing.

It’s a comparison between cost of the mess and cost of continuing. Mine was cheap to coast because the work in flight was ordinary code changes on isolated branches. It would not have been if an agent had been mid-deploy.

What has to be true before you can coast

Coasting was only an option because of things that were already in place before the wobble, none of which I set up for this: tasks tracked individually, work on isolated branches, no auto-merge. That combination is what made “let it finish” a decision rather than a gamble — letting things run couldn’t quietly produce a state nobody would review.

For one person running a few agents, the cheap version is genuinely cheap: one branch per session, a tracked task per session so you can enumerate what’s in flight, no auto-merge.

At team scale the bar is legibility under stress — being able to answer “what is running right now, and what will it touch” during the incident, not reconstruct it afterwards. If nobody can enumerate in-flight work, the kill switch really is the only tool available, and the thing to fix isn’t incident response. It’s the missing inventory. Build that first; the rest of this is unavailable until you do.

References

  1. Gray, J. “The Transaction Concept: Virtues and Limitations.” Tandem TR 81.3, June 1981; VLDB, September 1981. jimgray.azurewebsites.net/papers/thetransactionconcept.pdf
  2. Garcia-Molina, H., Salem, K. “Sagas.” Proc. ACM SIGMOD, 1987. dl.acm.org/doi/10.1145/38713.38742
  3. KC, D., Budathoki, A. “Handoff Debt: The Rediscovery Cost When Coding Agents Take Over Interrupted Tasks.” arXiv:2606.02875, June 2026. arxiv.org/abs/2606.02875
  4. Beyer, B. et al. “Addressing Cascading Failures.” Site Reliability Engineering, Google. sre.google/sre-book/addressing-cascading-failures/