What is an ADR?
An Architecture Decision Record is a short document capturing one design decision: what we chose, why, and what we considered and rejected. The platform has 33 ADRs as of Phase 1; every meaningful technical decision since the project started has one.
If you’re reading the codebase and wondering why something is shaped a particular way, the answer is usually in an ADR.
What an ADR captures
Section titled “What an ADR captures”Every ADR follows a four-section structure:
- Context. What problem are we solving? What forces are at play? What constraints exist? This section establishes why the decision matters at all.
- Decision. What did we pick? Stated in one or two sentences. No equivocation; an ADR records a commitment.
- Consequences. What becomes easier. What becomes harder. What trade-offs we’re accepting. The honest version of “we chose X” — not just the upsides.
- Alternatives considered. Other options, and why we didn’t pick them. The discipline here is being specific: “simpler” or “more flexible” isn’t a real reason; “saves us from running a Postgres cluster” is.
Each ADR also has a status (Proposed, Accepted, Superseded by ADR-NNNN, or Deprecated) and a date. Older ADRs sometimes link forward to newer ones that supersede or extend them.
Why we write them
Section titled “Why we write them”Three reasons that compound over time:
1. Reasoning gets lost. Six months from now, someone will ask “why are we using Cloudflare D1 instead of Postgres?” The ADR has the answer. Without it, the answer is whatever the person who happens to remember says. Memories are unreliable; an ADR isn’t.
2. New contributors land faster. A new engineer reading the codebase wants to understand not just what it does but why it’s shaped this way. Code shows the what; ADRs show the why. A new hire reading the 33 ADRs in order has a clearer mental model of the system than someone who’s been rummaging through the source for a month.
3. Decisions get challenged honestly. If you can’t write an ADR for a choice, you probably haven’t thought it through. Forcing the four-section structure surfaces fuzzy reasoning. Several decisions on this platform got substantively rethought because the ADR-writing process exposed weak alternatives.
When to write one
Section titled “When to write one”The rule, stated simply: an ADR documents a committed decision that has shaped the codebase. Two implications:
- Don’t write speculative ADRs. Ideas under consideration go
in
docs/open-questions.md, not the ADR folder. An ADR represents a commitment that’s reflected in code. - Don’t skip non-obvious choices. If a future maintainer might ask “why didn’t we just do the obvious thing here?”, there’s an ADR worth writing. The code shouldn’t have to defend itself.
What counts as “shaping the codebase”:
- A new package, app, or service got added (or an existing one got refactored across the trust boundary)
- A library/framework choice that affects multiple packages
- A protocol decision: file format, message schema, error taxonomy
- A security decision: what’s mutable, what’s immutable, what’s validated where
- A scaling/cost decision: choice of provider, choice of pricing tier, choice of caching layer
What doesn’t count:
- Bug fixes
- Refactoring within a package that doesn’t change its interface
- Performance tuning that doesn’t affect the design
- Routine library upgrades
The status lifecycle
Section titled “The status lifecycle”Proposed — under discussion; a PR is open or the code is staged. The ADR exists so reviewers can see the design alongside the code, but the decision isn’t final.
Accepted — in effect, reflected in the repo. Most ADRs spend their life in this state.
Superseded by ADR-NNNN — replaced by a later decision. The old ADR stays in place (history matters); a forward link in the status field points to its replacement. The new ADR’s Context section explains what changed.
Deprecated — no longer in use, not replaced. Rare; usually this happens when a feature is removed entirely.
Where to find them
Section titled “Where to find them”Every ADR lives at docs/adr/NNNN-short-title.md in the repo,
authored as plain Markdown. The docs site mirrors them at build
time (so the full index below is always in sync
with the repo).
For people reading the docs, the recommended path is:
- Skim the full index to see the breadth
- Read the highlighted ADRs — six decisions that shaped the platform’s identity
- Click into individual ADRs when you have a “why is this like this?” question about the code
The highlights are the right place to start if you’re an engineer ramping up; the full index is the right place to come back to when something specific catches your attention.
A note on tooling
Section titled “A note on tooling”We don’t use a tool — no adr-tools, no plugin, no generator.
Just plain Markdown files following a template. The discipline
is in the writing, not in the tooling. A file in the right place
with the right structure is the entire system.
The build-time copy script that mirrors docs/adr/ into the
docs site (apps/docs/scripts/copy-adrs.mjs) is the only
automation, and it’s 70 lines of plain Node.