Make supersession machine-readable
The last post in this series found architecture records that had stopped giving one answer. Three of ours shared one number, all marked Accepted, so a reference to that number resolved to all three. I framed that as the records confusing the agent. That was backwards.
TL;DR:
- The agent was the accurate one. It reported that a question had more than one answer, which was true.
- We wrote the ambiguity in ourselves, and the reason is specific: our review rules lived in people’s heads, not in the repository.
- So a naming convention cannot fix it. A convention is a rule in a head. It is the thing that already failed.
- What fixes it is a chain a machine can follow, plus a build check that fails when a pointer resolves to two documents.
The agent was the accurate one
Thor Henning Hetland, a founder and CTO who runs several engineering companies, replied to that post and turned it over:
Three conflicting ADR-024s is a human-process problem that AI scaled into visibility. The agent isn’t confused — it’s accurate about ambiguity you embedded in the corpus.
“Which of these applies?” is unanswerable by design, not by capability.
That is a better diagnosis, and it changes what you do next. If the agent is broken you tune retrieval and write a better prompt. If the corpus holds a genuine contradiction, neither helps, because there is no correct answer to return.
Why we had three
The interesting question is not how an agent trips over three records with one number. It is how a team writes three.
We had a handful, written by senior engineers. Then an agent joined the work and we could not keep up with reviewing what it produced. Records started appearing for all kinds of reasons, and the count went from about ten to 41 in three months.
We had told the agent to read them and keep them updated. We never told it at what granularity, because the rules we actually followed were never written in the repository. They were habits, held by the people who had been there.
An agent inherits your written standards, not your habits.
What it costs
Our newest data-feed record does the right thing. Under its status line it lists what it replaces, in plain text:
Supersedes: ADR-012 (Fixture Timings Scheduler), ADR-016 (Timer-Based Phase
Detection), ADR-019 (Sportradar Inplay Integration), ADR-021 (Score24
Multi-Feed Phase Detection)
Updates: ADR-024 (Binary InPlay Resolver)
A human reads that with no trouble. Resolve it by number, and ADR-021 matches two files. One is the superseded phase detection. The other is our end-user authentication design, which is load-bearing and current.
So an agent following that line retires our auth architecture, on the authority of a document about football data feeds. The only thing preventing it is the title in the brackets, and nothing indexes, validates or requires that.
The fix is not a naming convention
Thor’s last sentence is the one this post is named after: naming conventions become irrelevant once supersession is machine-readable. Four things, and they take an afternoon.
- An identifier that is not a number in a filename. Numbers collide because two people write on the same day without looking. Use a slug, or enforce uniqueness in the build.
supersedesandsuperseded_byin the front matter, as lists of identifiers. Our six annotated records phrase it three different ways, because a sentence can be phrased any way.- A validity window. A record is true between two dates. With it an agent can answer “what governed this in March?”, which is the question you have during an incident.
- A check in the build. Fail when an identifier is duplicated, when a pointer resolves to two documents, or when the two directions disagree.
None of this is new, and that is the useful part. Michael Nygard’s original 2011 post already asks you to keep a superseded record rather than delete it.
What the standards do not do is make the pointer resolvable. Nygard’s status is prose, “marked as ‘deprecated’ or ‘superseded’ with a reference to its replacement”. MADR 4.0.0 keeps it there too: no supersedes field, just superseded by ADR-0123 inside the status string.
The bidirectional half is already solved in a tool. Nat Pryce’s adr-tools has adr new -s 9, which flags the new record and rewrites the old one’s status in one command.
The check is what makes the other three real. Without it they decay back into habits, which is what the CLAUDE.md post paid to learn.
What this does not fix
A machine-readable chain resolves happily to a record that was wrong the day it was written. It does that with more apparent authority than the prose version. Every field is also a field somebody has to fill in, and a format that feels like a form gets written less often. Four is the smallest set I would defend.
Conclusion
The agent was never confused. It reported, at speed, that our corpus contained a question with more than one answer. We had lived with that for a year, because a human quietly picks the nearest one and moves on.
What would change my mind: the claim is that structure beats convention here. Suppose a team adds identifiers, chains, windows and a build check. If their agents still cite retired decisions at the same rate, the problem was retrieval or corpus size. Measure citations of superseded records before and after.
This is a response to Thor Henning Hetland’s comment on the previous post. The supersession chain and the validity window are both his. So is the title.
Next in this series: the hub, which connects the four places design intent can live.
Methodology & limitations (click to expand)
Prior art
- Documenting Architecture Decisions, Michael Nygard, 15 November 2011. The origin of the format, and of the status this post argues is not enough: a reversed decision is kept and “marked as superseded”, because “it’s still relevant to know that it was the decision, but is no longer the decision.”
- MADR 4.0.0 (Markdown Architectural Decision Records, September 2024). The current community template, and the reason the complaint here is not a straw man: supersession is a phrase inside the free-text
statusvalue,superseded by ADR-0123, not a structured field a resolver can follow. - adr-tools, Nat Pryce.
adr new -s 9creates the replacement and rewrites the superseded record’s status in one command, which is the bidirectional half of the scheme above, already implemented and a decade old.
Data sources
41 architecture decision records from the streaming-platform archive, read directly rather than sampled, excluding the template. Eight numbers are duplicated across 17 of the 41, one of them three times, and six records carry a supersession marker. The reframe is quoted verbatim from a public comment on the previous post.
What this does not show
- No measurement of agent behaviour. I did not run an agent against this corpus and count wrong citations. The failure described is what the data structurally permits, not an observed error rate.
- No after state. The scheme above was never implemented here, because access ended in May 2026. It is a recommendation, not a result, and the falsifiability line is the test that would settle it.
- The ambiguity is by number only. A resolver that also matched the parenthetical title would do better. The point is that nothing required the title to be there.
- “About ten records before agents” is my recollection, not a count from the archive.
Get new posts by email
One email per post, about two a month. The numbers and the caveats, same as here. No sequence, no pitch, unsubscribe in one click.
Almost there. Check your inbox and click the link to confirm.
That did not go through. Try again, or email hello@lenikirilov.com and I will add you by hand.
No tracking pixels. I never pass the address on. How this is handled.