Don't let the medic share a bloodstream with the patient
Lab note · 2026-07-15 · Reserve — an AI-native studio.
Yesterday one of our agents ran fully unattended for the first time — no human at the keyboard, a scheduled job expected to produce a morning artifact by a fixed time. It failed. The interesting part isn’t that it failed; a first unattended run failing is almost the base case. The interesting part is how the safety net failed with it.
We had built what looked like a responsible autonomy stack. A watchdogchecks, a set time after kickoff, whether the artifact exists. If it’s missing, the watchdog escalates to a self-healing step — an agent that reads the logs, diagnoses the failure, and attempts a safe remediation. Belt and suspenders.
Here is the chain that actually played out. The run hit an upstream rate limit and some resource contention (we’d also, unwisely, let other agents run inside the same window — a second lesson). It fell behind. The watchdog fired on schedule — except the watchdog’s timeout was a stale assumption: it had been tuned when the pipeline was faster, and a recent change had made the heavy step take longer than the whole watchdog budget. So the watchdog “correctly” concluded the run was dead while the run was merely slow, and it launched the self-healing agent on top of the still-running job — more contention, not less.
Then the punchline. The self-healing agent needs model capacity to think. By the time it was invoked, the run had exhausted the model quota for the window. The last line of defense couldn’t run, because it drew from the exact same well that had already run dry. The doctor died of the disease it was dispatched to treat.
None of the three failures was exotic. But stacked, they encode one principle we should have written down before shipping autonomy: a recovery mechanism must not depend on the resource whose exhaustion it is meant to recover from. Failure-domain independence isn’t a nice-to-have for the healing path — it’s the entire point of a healing path.
Ops people know this in its classic form: don’t host your monitoring on the box it monitors; don’t put the fire alarm on the circuit that catches fire. What’s new is where the shared resource hidesin an agentic system. It isn’t CPU or disk — it’s model capacity. Every “smart” fallback you add (a diagnosing agent, an LLM-written incident summary, an auto-retry that re-prompts) quietly increases your dependence on the one budget that a runaway failure is most likely to have already burned. The more intelligent your recovery, the more it competes with the incident for the same scarce thing.
The fixes we’re making are boring on purpose: give the watchdog a timeout derived from the pipeline’s current budget, not a number frozen in a calmer era; forbid discretionary agents inside a critical run window; and — the one that matters — reserve a capacity floor the healing path can always draw on, or make the first rung of recovery something that needs no model at all. A safety net you can only deploy when things are already going well is decoration.
← All lab notes