Chapter 6 of 7 · 8 min read
A decision record names the conditions that would reverse it
On this page
In November a new engineer on the contract team read the pipeline's three prompts, noticed how much of the work was sequential, and proposed collapsing it into a single loop. Someone linked the decision record from May — an architecture decision record, or ADR, which is the short versioned document a team keeps beside the code to say what was chosen, on what evidence, and what it ruled out. It said the team had compared a single loop against a three-agent pipeline, that the pipeline scored 90.4% against 86.2% on a held-out set, and that the pipeline was adopted. The meeting that followed ran forty minutes. Was 4.2 points a lot? Nobody could say what would have counted as too little. Was the cost acceptable? Nobody remembered what the budget had been, or whether one existed. Had the loop been given a fair chance? Two people who had been there thought so and could not point at anything. The meeting ended with an action item to re-run the comparison, which is a week of engineering time spent recovering information that had been in someone's head in May and was written nowhere.
The record was accurate and it was not usable. Everything in it described what happened; nothing in it let a reader decide whether the conclusion still held.
The parts a later reader actually needs
A record that can be checked has to carry four things beyond the conclusion. The measured numbers per arm, with intervals and the run identifiers that make them attributable — not pasted charts, but the manifest hashes from chapter 2, so the artefacts can be opened. The thresholds that turned those numbers into a choice, which is the part that is almost always missing, because the people in the room applied them without articulating them. The regressions accepted on purpose, so that a later complaint about latency is recognised as a known cost rather than a discovery. And the conditions under which the decision flips, stated as things that can be measured and checked on a schedule.
The last of those is what separates a decision from a preference with numbers attached. A preference can absorb any new fact; there is no observation that would make its holder abandon it, because no observation was ever nominated. A decision that names three conditions under which it becomes wrong can be checked by someone who was not in the room, and it can be defended against re-litigation by pointing at conditions that have not fired.
Here is the record the May decision should have produced.
# ADR-041 — Contract redline: adopt the three-agent pipeline
Status: accepted (2025-05-22) · Owner: platform-agents · Review: quarterly
## Decision
Adopt the extract → normalise → draft pipeline for contract redlining.
Retire the single-loop implementation from the serving path; keep it in
`arms/loop` as a maintained comparison arm.
## Evidence
Harness runs (pinned manifests, 5 trials/task, interleaved):
confirmation set, 40 held-out docs, 200 runs/arm — run 7be14c02
held-out set, 60 docs, 300 runs/arm — run 9f2c1a7d (pre-fix)
| metric | loop | pipeline | source |
|---------------------|----------|----------|---------------|
| success | 86.2% | 90.4% | 7be14c02 |
| paired gap | — | +4.2 pp (+1.3 to +7.1) | 7be14c02 |
| cost / task | $0.091 | $0.188 | pricing 2025-05-01 |
| latency p50 | 6.1 s | 7.9 s | 7be14c02 |
| latency p95 | 14.6 s | 25.1 s | 7be14c02 |
| duplicated input | 6% | 18% | trace analysis |
## Decision rule (fixed 2025-04-30, before the confirmation run)
1. Adopt the higher-scoring arm only if the paired gap's 95% interval
excludes zero. Otherwise adopt the cheaper arm.
2. Hard ceiling: $0.25 / task at list prices (gross-margin floor of 60%
on the $40 per-contract price).
3. Hard ceiling: p95 ≤ 30 s (the review UI holds a progress state to 30 s
before it must offer an email-when-ready fallback).
4. If both arms pass 1–3, prefer the arm with fewer maintained surfaces.
Result: gap excludes zero (rule 1 → pipeline); $0.188 < $0.25 (rule 2 ok);
25.1 s < 30 s (rule 3 ok, with 4.9 s of headroom).
## Regressions accepted
- p95 latency +72% (14.6 s → 25.1 s). Headroom to the UI ceiling is 4.9 s.
- Cost per task 2.07×. At 9k contracts/month this is $873/month more.
- Three prompts and two boundary contracts to maintain rather than one
prompt; boundary invariants now run on every production request.
- Cold-start p99 is untested above 40 concurrent requests.
## Conditions that reverse this decision
| # | Condition | Threshold | Checked by | Cadence |
|---|-----------|-----------|-----------|---------|
| R1 | Held-out gap shrinks | < +2.0 pp | eval job | quarterly re-baseline |
| R2 | Cost per task rises | > $0.25 | billing export | monthly |
| R3 | Production p95 | > 30 s for 2 consecutive weeks | latency SLO | weekly |
| R4 | Boundary invariants fail | > 1.0% of requests | prod dashboard | weekly |
| R5 | New model build closes the gap | loop ≥ pipeline on re-baseline | eval job | per model pin |
Any condition firing moves this ADR to `under-review` and requires a
re-run of both arms within 15 working days.
## Not decided here
Whether support triage should be decomposed — see ADR-046, which reaches
the opposite conclusion on a workload with 61% duplicated input.Thresholds are only thresholds if they predate the numbers
The decision rule in that record is dated three weeks before the run it governs, and the date is doing real work. A threshold chosen after seeing the results is a description of the results, and it will be satisfied by whatever happened; a team that decides afterwards that four points is the bar has learned nothing it did not already believe. Fixing the rule first also forces the uncomfortable conversations to happen while they are still cheap, because the question "what would make us keep the loop?" is easy to discuss in April and adversarial in May when someone has spent six weeks on the pipeline.
The ceilings in rules 2 and 3 come from somewhere outside the comparison, which is the property that makes them defensible. The cost ceiling is derived from the product's price and its target gross margin, so anyone can check the arithmetic and challenge the margin target rather than the number. The latency ceiling comes from a behaviour the UI already has, which means it can be renegotiated by changing the UI. Thresholds with no external derivation drift toward whatever the preferred arm achieved, and they are recognisable by their roundness — a p95 ceiling of exactly 25 seconds, three weeks after a run that measured 25.1, is a rationalisation wearing a number.
A rule fixed and dated ahead of the run is pre-registered, the term medicine uses for a protocol published before any patient is enrolled, and its value is the same in both settings: whoever reads the result later can see that the bar was not moved to meet it. Where a rule genuinely has to be set after the fact, the honest handling is to say so in the record. A line reading "cost ceiling set 2025-05-20, after the confirmation run, from the pricing model finalised that week" is weaker evidence than a pre-registered rule and stronger than silence, because a reader can discount it appropriately instead of assuming a rigour that was not there.
The losing arm is part of what the record commits to
One line in the decision reads "keep it in arms/loop as a maintained comparison arm", and it is the clause most likely to be dropped by whoever is cleaning up the repository in August. Deleting the loop makes every reversal condition unenforceable, because firing R1 or R5 requires running both arms and the second arm no longer exists. What the team would face at that point is not a re-run but a rebuild: reimplementing the loop against six months of drifted tool schemas, re-tuning it enough to be a fair opponent, and re-labelling fixtures, which is the week the November meeting was about to spend.
Maintaining it is cheaper than it sounds when the arms share their tools and their scoring code, since what has to be kept working is one prompt and a thin runner. Measured over the following two quarters this came to about four hours a month — mostly updating the loop's prompt when a tool schema changed, and one afternoon when the rubric gained a criterion. Against that, each quarterly re-baseline costs $190 of model spend and twenty minutes of wall clock, because everything else is already pinned. Writing those figures into the record turns the maintained arm from an oddity a reviewer might question into a line item with a stated price and a stated purpose.
The evidence section also carries an obligation from the previous chapter that is easy to leave implicit. Both arms were audited once, and the pipeline's audit found and fixed the propagated-constraint defect, which moved it 3.7 points. A reader who does not know that will assume the +4.2 was measured on the design as originally written, and will draw the wrong conclusion about how much of the advantage came from the topology rather than from a boundary fix that any implementation would need. One line in the evidence section — "pipeline audited once, constraint-propagation defect fixed pre-run, worth +3.7 pp; loop audited once, tool truncation fixed, worth +0.6 pp" — is what makes the attribution level checkable later.
Vague reversal conditions are decoration
The reversal table is the part most likely to degrade into prose that cannot be checked. The difference is whether an on-call engineer with a dashboard could tell today whether the condition has fired.
| Written as | Why it never fires | Operational version |
|---|---|---|
| "if the pipeline becomes too slow" | no threshold, no window, no owner | p95 > 30 s for 2 consecutive weeks |
| "if costs become unsustainable" | sustainability is a judgement made in a budget meeting | cost/task > $0.25 at list prices |
| "if a better model changes the picture" | every model changes the picture slightly | loop ≥ pipeline on the quarterly re-baseline |
| "if the boundaries prove fragile" | fragility has no metric | invariant failures > 1.0% of requests |
| "if the team's view changes" | this is the thing the ADR exists to prevent | — |
Each operational version names a metric that already exists, a threshold, a window and a place it is read from — R3 reads the service's latency SLO, the service level objective the team has already committed to and already alerts on, so the reversal condition costs no new instrumentation. A reversal condition written this way is a tripwire: a rule attached to a number a machine is already computing, so that it fires without anyone remembering to look. R5 is the most valuable of the five and the least often written, because it is the condition that a hardware-and-model industry makes fire on its own: a build that reasons better over long contexts erodes the advantage of splitting the work, and the arm that benefits is the one with the longest single context. A team without R5 will notice that erosion eventually, through some unrelated complaint, two model generations after it happened.
What the record does after it is written
An ADR with tripwires stops being a document and becomes a small state machine, which is the point of writing it in that form.
The transition out of under_review has a deadline in the record — fifteen working days — because the state that quietly absorbs an organisation's attention is the one with no exit condition. A tripwire that fires and produces a Slack thread rather than a re-run leaves the decision in a worse position than having no tripwire at all, since the record now says a reversal condition has been met and the system still runs the old way.
Reaffirming rather than reversing is a real outcome and needs its own handling. When a re-run confirms the choice, the thresholds get re-dated and the evidence section gains a new run identifier, so the record accumulates a history of checks. Six months of that history is what lets the November meeting end in four minutes with "R1 was checked in September at +3.9 points and has not fired" instead of an action item to spend a week.
What this record is not
It is not a benchmark report. The numbers in it are a summary, and the artefacts — traces, per-run records, manifests — live in the eval store and are referenced by identifier. Pasting a full result table into an ADR produces a document too long to read and duplicates data that will diverge from its source.
It is not a claim about topologies in general, which is why the closing section points at ADR-046 and its opposite conclusion. A record that generalises beyond its workload is producing exactly the durable, quotable sentence the previous chapter warned about, at greater length and with more authority.
And it is not a commitment. The reversal conditions exist so that changing the decision is a defined procedure with a trigger rather than an admission that the original call was wrong, which lowers the political cost of reversal to something a team can actually pay. The failure mode this guards against is a decision that becomes load-bearing through inertia, where three later systems have been built assuming the pipeline and nobody can afford to check it any more.
All of which assumes somebody runs the checks. A record whose R1 has not been evaluated since the day it was written is a record with no reversal conditions, and by then the study behind it has been decaying on both sides for a quarter.
Evaluating an architecture — read the current version at https://daviddominguez.dev/learn/en/evaluating-an-architecture/a-decision-record-names-the-conditions-that-would-reverse-it