2026-08-29 · Updated 2026-08-29 · 10 min read
The coding-agent failure and recovery taxonomy, version 1
A versioned, citable taxonomy of coding-agent failure: nine stable classes with permanent identifiers, each carrying the symptoms that announce it, the detection that confirms it from evidence rather than testimony, and the recovery its evidence state permits — with attribution across the stack layers and a stability policy that keeps citations from drifting.
By Juno AI INC · failure-modes · recovery · taxonomy
When a coding-agent run goes wrong, the first question is not what broke but what may still be believed. A silent terminal, a half-finished worktree, a bill with no result beside it — each of these surfaces routes to opposite actions depending on what durable evidence proves: relaunch, resume, refuse to re-run, or regrade. This page turns that decision into a reference. Nine failure classes hold permanent identifiers, CAF-1 through CAF-9, and each carries the symptoms that announce it, the detection that confirms it from evidence rather than testimony, and the recovery its evidence permits. It is written for engineers holding a broken run who need to name its class in minutes instead of re-deriving it from anecdote. Version 1 carries the evidence date 2026-08-29; the stability policy near the end is what makes these identifiers safe to lean on.
Two rules frame the classes. First, attribution belongs to the classification: most classes lean toward a home layer — proposal, runtime, coordination, or measurement — because the costliest triage mistake is punishing a model for a machinery defect, or rebuilding machinery because a proposal was bad. Recorded practice agrees: the benchmark package of this site's ecosystem types a harness failure separately from candidate outcomes, so a result the machinery itself produced is never billed to the model. Second, recovery is keyed to evidence state, never to the agent's account of itself. A class exists to answer the two questions an incident actually asks: what may I believe, and what may I safely do next.
Scope, sources, and admissibility
Three evidence classes feed the page, all already under this site's control. The grounding contracts come from the committed sources of the released YYLO ecosystem — the runner scripts' boundary, staleness, and empty-answer rules, and the benchmark package's marker, lock, and failure-typing contracts — each re-derived from source on 2026-08-29, not recalled from prose. The recorded incidents come from this research program's published, versioned artifacts, principally the repository benchmark case library, whose mining record preserved a grader that no candidate could satisfy. The attribution layer names come from this site's harness taxonomy. Nothing here leans on a demand estimate, and no class encodes how often anything happens: frequency claims would need an instrument this taxonomy does not have, so a class earns its place by discriminating, never by being common.
Admission is the discriminating rule just promised: a class enters only when two incidents a triager would otherwise confuse route to different recoveries. A class every incident matches is a synonym for incident; a class that changes no action is decoration; both are excluded by construction, and coverage follows from the rule rather than from ambition. Three neighbors hold adjacent ground; they are named here, not restated. Preventing these failures in advance — budgets, stop conditions, checkpoint semantics — is bounded-failure design's job. The benchmark package's own recovery machinery, down to its typed statuses and commands, belongs to the interrupted-run recovery treatment. And the inward phenomenology of one unattended loop degrading across its own passes is a diagnosis that belongs to the loop shape exhibiting it, not to a cross-harness incident taxonomy.
The classes, version 1
- CAF-1 — Stall. A run keeps its process and its bounds and stops converting either into verifiable work-state. Symptoms: output goes quiet or churns — plans re-stated, an edit re-attempted then dropped — while the state that defines progress holds still across iterations. Detection: machinery compares the work-state from iteration to iteration and exits after a declared number of no-change rounds; the paired contract fails a step whose command exits zero with no answer, closing off silent non-work. Recovery: interrupt first — a signal that stops the active child and blocks later launches is the safe exit — then diagnose from the evidence in hand; relaunching without a diagnosis buys the same stall again. Told apart from
CAF-2by the diff: a stalled run leaves nothing to argue with. - CAF-2 — Derailment. Change accumulates and may even pass mechanical checks while diverging from the acceptance the work was admitted under. Symptoms: diffs grow but map to nothing requested; results satisfy a reading of the task nobody wrote; reported progress stays plausible. Detection: grade the output against acceptance criteria held outside the agent's own record — its diary always agrees with itself. Recovery: stop, roll the change back through version control, keep the attempt's evidence append-only, and re-admit the work under criteria the next run cannot read around.
- CAF-3 — Boundary escape. Mutation lands outside the write surface the run was admitted to. Symptoms: edits appear in paths no step declared, or beyond the worktree the run was given. Detection: hash every tracked and untracked path before the dispatch and again after it, then diff the changed set against the admitted list; the verdict travels with the run as recorded evidence. Recovery: stop before any successor launches, record the escape, and clean up deliberately — never silently, mid-run, where the record cannot see it.
- CAF-4 — Interruption. The producing process dies mid-run: a reclaimed CI runner, a closed laptop, a dropped connection, a kill. Symptoms: no process, partial artifacts, a run that ends without a verdict. Detection: the attempt index outlives the process, and recovery inspection names the first step that no surviving evidence vouches for. Recovery: inspect first, in the mode that dispatches nothing; resume at the reported step with inputs re-verified against their recorded hashes. A directory listing is not a completion record.
- CAF-5 — Indeterminate dispatch. Durable evidence proves work was dispatched, and nothing durable proves what came back; remote execution and spend may have happened and died with the connection. Symptoms: a dispatch marker stands with no terminal beside it. Detection: markers that survive crashes sort every attempt into terminal, dispatched-without-terminal, or never-started; the middle set is this class, and the inspection contract itself forbids automatically re-running its members. Recovery: refuse redispatch; type the attempt with its honest unknowns — no session, no patch, spend unknown rather than zero — and let the run finish with the hole labeled. A new attempt, under a new identity, inherits nothing it did not earn.
- CAF-6 — Rejection at the boundary. The provider or platform refuses the call outright: rate limits, missing or malformed credentials, a model or version identity that does not match the plan. Symptoms: terminal provider errors rather than degraded output — identity and credential problems surface at preflight, a quota wall can fall at any point in the run. Detection: identity and credential checks reject the run before a durable dispatch intent is ever written, so a preflight refusal is provably unspent; a quota wall hit mid-run is not that case — there the verified prefix speaks for what already ran — and provider-side failures surface as terminal nonzero exits, not as soft silence. Recovery: follow the policy declared before launch — wait or raise, never improvise — repair the credential or identity, and relaunch; the verified prefix decides what actually re-runs.
- CAF-7 — Unearned completion. Completion is claimed where no independent evidence decides it. Symptoms: success prose over failing or absent verification; results without receipts; work that collapses on first contact with review. Detection: ask what decides done — a command's exit status and a receipt bound to the work's identity, or testimony. Recorded machinery catches the smallest form in the act: a step marked successful whose answer artifact is empty is flagged as a defect, because silence graded as success is the cheapest counterfeit there is. Recovery: treat the claim as unproven, re-validate independently, and record the claim itself as part of the attempt's evidence.
- CAF-8 — Contested ownership. Two processes claim one work surface or one plan at the same time. Symptoms: interleaved records, conflicting diffs, a task claimed twice, shared state with no single writer. Detection: cross-process locks bound to the plan's identity and stamped with owner process and host — only an owner proven dead may be reclaimed, and a live one never is — plus readiness queries that answer admission only, so dependency-open work never enters the ready set. Recovery: serialize mutation per target, route work explicitly so a second claimant fails loudly instead of interleaving, and reclaim only on proof of death.
- CAF-9 — Instrument failure. The measuring machinery fails while the candidate may be fine: an unconfigured grader, checks that cannot pass on any candidate, an environment that drifted beneath the suite. Symptoms: red results invariant to the change under test; verdicts the instrument produced but the candidate carries. Detection: run the instrument against the untouched base and against a known-good reference before trusting it against the candidate — an instrument that fails either way measures nothing — and keep audit tallies that count grader failures apart from candidate outcomes. Recovery: repair the instrument, then regrade the retained attempts from their recorded artifacts; re-dispatching candidates to fix a broken grader spends money to learn nothing.
Attribution: which layer failed
Naming the class is half the triage; the other half is charging it to the correct layer, and the layer vocabulary already exists in the harness taxonomy: model (CHT-1), agent (CHT-2), harness (CHT-3), control plane (CHT-5), and evaluation (CHT-6) — the sixth term, IDE (CHT-4), names a human editing surface and carries no class on this page. Each class leans somewhere. CAF-6 is a boundary event between proposal serving and dispatch. CAF-3, CAF-4, CAF-5, and CAF-8 live in the coordination and runtime layers. CAF-9 is a measurement defect. CAF-1, CAF-2, and CAF-7 are the classes where the first suspect is proposal-side behavior that machinery failed to catch. The lean is a starting hypothesis, not a verdict: attribution is a finding from evidence — the marker set, the boundary record, the receipt chain — never an assumption drawn from irritation. The recorded machinery keeps this discipline honest by typing harness-caused outcomes away from candidate outcomes and by counting grader failures apart from both, which is precisely the separation a post-incident review needs before anyone is blamed.
Matching recovery to evidence state
Under every class sits one question: what does the evidence permit? An incident leaves the work in one of four states, and the state — not the class alone — fixes the safe action. Never started: nothing left the machine, so starting is a first dispatch, not a repeat. Verified prefix: hash-bound artifacts vouch for a completed stretch, so resume at the first unvouched step and re-verify inputs before replay. Indeterminate: dispatch is proven and outcome is not, so re-running is forbidden — record the unknown and continue under a new identity. Claimed complete: the claim is the incident, so validate independently before anything trusts it. The classes land on these states naturally — CAF-4 leaves you between verified prefix and indeterminate, CAF-5 is indeterminate by definition, CAF-7 is claimed complete — and the recovery text above applies the state rule per class.
Two owners hold the neighboring ground for this section. The benchmark package's three-way status split and its resume-regrade-discard decision tree, down to the typed commands, live in the interrupted-run recovery guide. Designing so the four states stay cheap to reach — budgets, semantic stops, staleness detection, checkpoints that persist evidence ahead of claimed progress — is a method owned end to end by bounded-failure design. This page's contribution is the naming layer above both: with stable class identifiers, an incident report can say CAF-5 where it used to carry a paragraph of anecdote, and the next reader knows exactly which recoveries were on the table.
Stability policy
The identifiers are permanent: CAF-1 through CAF-9 keep their numbers and their meanings for the life of this page, and an identifier whose class is ever withdrawn is withdrawn with it. A clarification that rewords a symptom or tightens a detection clause without moving a class boundary lands as an in-place edit, recorded in the changelog with its date. Splitting a class, merging two, or changing which recovery a class routes to requires a new version number with its own fresh date, and version 1 goes on resolving by way of the changelog. Every grounding contract is re-checked quarterly against the committed sources behind it; a review that finds nothing to change writes that finding down and the number stands.
Changelog
- First publication: version 1, dated 2026-08-29. Ships the nine classes, the admission rule, the attribution mapping, and this policy. Nothing precedes it, and no identifier has been renumbered.
Citing a class
Cite the identifier together with the version and the date; that pairing is what keeps a citation honest as later versions arrive. The form this page recommends for a single class:
An incident report that names CAF-7 tells the next reader which detection to re-run and which recoveries were considered; the version number and date keep that promise from drifting into folklore. This taxonomy does not score products, does not rank harnesses, and does not estimate how often any class occurs — it names what went wrong in a way two engineers can mean the same thing by, and it hands that name to whoever writes the next post-mortem.