Skip to content

Decision records

Decision records

The decision catalogue is a cache. Its purpose is that a fork already resolved once is never re-litigated — by a person or an agent.

The rule

An agent that hits an architectural fork with no ADR covering it drafts the ADR, labels the work item needs:adr, and stops.

It does not decide silently and proceed. This is a hard stop condition in the loop.

The reason is asymmetry. A decision recorded badly costs a page of markdown. A decision made silently costs a rewrite when someone later finds it, disagrees, and cannot tell whether it was reasoned or accidental.

What counts as a fork

Needs an ADR:

  • Adding a dependency that does a job something already in the stack could do
  • Choosing between two ways of modelling data
  • Anything contradicting an existing ADR (that’s a superseding ADR)
  • Anything that would be expensive to reverse later
  • Anything a future reader would ask “why on earth is it like this?” about

Does not need an ADR:

  • Naming, formatting, file layout within an established pattern
  • Anything an existing ADR already answers — link to it in the PR instead
  • Implementation detail with no external consequence

When unsure: an ADR is a page of markdown. Write it.

Status lifecycle

StatusMeaning
ProposedDrafted, awaiting a human. This is what an agent creates
AcceptedIn force. Agents are bound by it
SupersededReplaced. Keeps its number and its file forever, with a link forward

ADRs are never deleted and never edited in substance. A decision that changes gets a new ADR that supersedes the old one, and both files carry the cross-link. The history of what was believed and when is the whole value of the catalogue.

Correcting a typo is fine. Changing what the decision says is not.

Template

---
title: "ADR-####: Short decision title"
description: One line, shown on the subsite index.
---
# ADR-####: Short decision title
- **Status:** Proposed | Accepted | Superseded
- **Date:** YYYY-MM-DD
- **Supersedes:** ADR-#### | —
- **Superseded by:** ADR-#### | —
## Context
The forces at play. What made this a question. No solution here.
## Decision
What was decided, in the active voice. Specific enough to be checkable.
## Rationale
Why this one.
## Consequences
What follows — including the bad parts. An ADR with no downsides listed has not
been thought about properly.
## Alternatives considered
What else was on the table and the specific reason it lost. "It was worse" is
not a reason.

Numbering

Four digits, sequential, never reused. Filename ADR-####-kebab-title.md.

Add the row to ../decisions/README.md in the same commit — the index is not generated.

Relationship to AGENTS.md

Different jobs, easy to confuse:

  • ADRwhy a thing is the way it is. Read when you hit a fork.
  • AGENTS.mdwhat you will get wrong by default. Read before writing code.

ADR-0004 explains why Hyperdrive rather than the Neon driver. AGENTS.md says “do not use @neondatabase/serverless” in one line, because that is the pattern your defaults will reach for. Both are needed. See docs-standards.md.