Architecture decision records need rejected options

Your decision records all say Accepted. That is not a healthy sign, it means you have been writing down what you did rather than what you chose between.

Open your decision records and read only the status lines. If every one of them says accepted, you have a journal.

A journal is a record of what happened. It is genuinely useful and it is not what somebody needs when they arrive next year with an idea. What they need is to know their idea was already considered, by people who knew things they do not, and rejected for a reason that is probably still true.

A set of records where everything was accepted, and one where it was not On the left, six records all marked accepted, which records what happened rather than what was decided. On the right, the same six with one rejected and one superseded, which is what a real sequence of decisions produces. every one accepted 0001 accepted 0002 accepted 0003 accepted 0004 accepted 0005 accepted 0006 accepted a journal what deciding looks like 0001 accepted 0002 accepted 0003 superseded by 0006 0004 rejected 0005 accepted 0006 accepted documentation
The value is in the paths not taken. Those are the ones somebody proposes again next year, having no way to know they were already considered. Illustrative — the shape of the argument, not measured data.

The section that carries all the value

A decision record with one option in it is a summary. The part worth writing is the alternatives, each with the consequence that killed it.

That is not a formatting preference. Six months later the accepted option is visible in the code: anybody can read what you built.

The rejected ones exist nowhere except in that document, and they are exactly the things a new person, or an assistant given the codebase, will propose with complete confidence.

So the rule is blunt: at least two options, at least one rejected. If you cannot name an alternative, you did not make a decision, you described your first idea, and the record should probably not exist.

The template that enforces it is four headings:

# NNNN. <the decision, as a sentence>

- Status: Proposed | Accepted | Rejected | Superseded by NNNN
- Date: YYYY-MM-DD

## Context
What is true that forces a decision. No solutions here.

## Options considered
### A. <option>  (chosen)
What it is, and the consequence that decided it.
### B. <option>  (rejected)
...

## Decision
The chosen option, one sentence, present tense.

## Consequences
What becomes easier, what becomes harder, what is now expensive to reverse.

Records that are not accepted

Two statuses do most of the work and are the two most teams never use.

Rejected, as a whole document. Somebody proposed something reasonable, it was considered properly, and it was not adopted. Writing that down feels strange the first time and it stops the same conversation happening twice a year. In one service I keep, the record for a shared types package is entirely rejected, and it exists because “why don’t we just publish a shared package” is asked roughly every six months.

Superseded, which is the immutability rule in practice. A decision that turns out to be wrong is not edited. It keeps its text, gains a line pointing at what replaced it, and the new one explains what changed.

status what it means
Accepted in force
Rejected considered as a whole and not adopted. Kept, because it recurs
Superseded by NNNN was in force, no longer. Text unchanged

That feels like clutter until the first time you need it. In the same service, record 3 says generated wire types should share the domain’s names. It is wrong. It survived exactly as long as it took to write the first class that needed both, and record 6 replaced it. Deleting 3 would have made the set tidier and thrown away the only evidence that the tidy-looking option was tried.

Immutability, and what it actually forbids

Fixing a typo is fine. Rewriting the reasoning is not, and the difference matters because the record of having believed something is part of the record.

The version people reach for instead is a living document that always reflects current thinking. It reads better and it answers a different question: it tells you what is true now, which the code also tells you. It cannot tell you what was tried, which is the only thing the document knows and the code does not.

How this connects to everything else

A decision record is the durable end of a spectrum that starts with a conversation and ends with a test. The most durable form of a rule is one that fails a build; the record is where the reason lives, because a test tells you what is enforced and never why.

That pairing is worth being deliberate about. The rule goes in the test, so it cannot drift. The argument goes in the record, so the next person arguing against it is arguing with the reasons rather than with the fact that it is there.

A five-minute check

Read your last ten records and count the ones with a rejected option in them. If it is fewer than half, you are writing summaries.

Then find a decision your team has argued about more than once, and write the record for it now, with the alternatives and why each one lost. It is the cheapest way to stop having that argument, and you will find out while writing it whether you actually agreed.


If your team keeps re-litigating decisions it already made, that’s the work I do.


Working through this in your own team?

I help engineering teams adopt AI coding assistants without giving up engineering rigour, and design the architecture underneath. If that's on your plate, let's talk.