docs(adr): add ADR scaffolding (templates, README, meta-ADR)

Set up docs/adr/ as the canonical home for architecture decisions:

- templates/nygard.md — default four-section format (Status, Context,
  Decision, Consequences) for one-way-door decisions.
- templates/madr.md — MADR v4 with YAML front-matter and explicit
  Considered Options for decisions where rejected alternatives matter.
- README.md — naming convention (NNNN-kebab-case), template-selection
  guidance (Nygard default; MADR for auth, queue mechanics, agent
  integration), status lifecycle, and ADR roster.
- 0000-record-architecture-decisions.md — meta-ADR establishing the
  practice itself, in Nygard format.

Backfilling existing implicit decisions (base-ui-over-radix, float
sort_order, demo-user three-layer policy, etc.) is fase 6 of the
docs-restructure plan.
This commit is contained in:
Janpeter Visser 2026-05-02 21:25:26 +00:00
parent 6e0827399a
commit 8a7d419972
4 changed files with 268 additions and 0 deletions

View file

@ -0,0 +1,66 @@
# ADR-0000: Record architecture decisions
## Status
accepted
## Context
Scrum4Me makes several non-obvious architectural choices that aren't visible
from the code alone — for example, why we use `@base-ui/react` rather than
Radix, why drag-and-drop ordering uses float `sort_order` instead of integer
positions, why authentication runs on iron-session rather than NextAuth,
and why the demo-user policy is enforced in three layers. These decisions
are scattered across `CLAUDE.md`, individual pattern docs, plan files, and
commit messages. New contributors and AI agents working on the codebase
have no fast path to the *why*, which leads to one of two failure modes:
they either re-litigate decisions that were already settled, or they make
changes that violate constraints they didn't know about.
We want a single, predictable place to record significant architectural
choices, with enough context that a reader six months from now can decide
whether the decision still holds.
## Decision
We adopt Architecture Decision Records (ADRs) as the canonical format for
documenting significant architectural choices in this codebase. ADRs live
in `docs/adr/`, are numbered sequentially with a four-digit prefix
(`0001-...md`, `0002-...md`, …), and follow one of two templates:
- **Nygard** ([`templates/nygard.md`](./templates/nygard.md)) — default,
for one-way-door decisions with a clear motivating context.
- **MADR v4** ([`templates/madr.md`](./templates/madr.md)) — for
decisions where weighing multiple alternatives is part of the value
the record provides (auth, queue mechanics, agent integration).
The full conventions — file naming, status lifecycle, template selection
guidance — are documented in [`README.md`](./README.md).
ADRs are immutable once accepted: course corrections create a new ADR
that supersedes the old one rather than editing the original.
## Consequences
### Positive
- Architectural choices have a single, predictable home that an AI agent
or new contributor can find with one `ls docs/adr/`.
- The "why" of each decision is captured at the moment it's made, when
the context is fresh, rather than reconstructed later from commits.
- Superseded decisions remain readable, so future contributors can see the
history of a choice without git archaeology.
- The format scales: writing an ADR is a 15-minute activity for the
default Nygard template, low enough overhead to be worth doing every
time.
### Negative
- Adds a small ritual to every significant architectural decision — easy
to skip when moving fast, leading to a stale or incomplete record if
not enforced through review.
- Backfilling existing decisions requires writing 58 retrospective ADRs
for choices that were never recorded (planned in fase 6 of
[`../plans/docs-restructure-ai-lookup.md`](../plans/docs-restructure-ai-lookup.md)).
- Two templates means a per-decision choice about which to use. Mitigated
by making Nygard the explicit default in `README.md`.

93
docs/adr/README.md Normal file
View file

@ -0,0 +1,93 @@
---
title: Architecture Decision Records
status: active
audience: ai-agent, maintainer, contributor
language: en
last_updated: 2026-05-02
---
# Architecture Decision Records
This directory contains the Architecture Decision Records (ADRs) for Scrum4Me.
## What is an ADR
An ADR is a short document that captures a single significant architectural
decision: the context that forced the decision, the choice we made, and the
consequences of that choice. ADRs are immutable once accepted — if a later
decision changes course, we write a new ADR that supersedes the old one.
We use ADRs because the project mixes several non-obvious choices (Next.js 16
specifics, `@base-ui/react` over Radix, float `sort_order` for drag-and-drop,
iron-session over NextAuth, demo-user three-layer policy, MCP integration
patterns) and an AI agent reading the codebase six months from now needs to
find the *why* without spelunking through commit history.
## File naming
```
NNNN-kebab-case-title.md
```
- `NNNN` — four-digit zero-padded sequential number, starting at `0001`
(`0000` is reserved for the meta-ADR that introduces the practice).
- `kebab-case-title` — lowercase, hyphen-separated, short noun phrase
echoing the decision (`base-ui-over-radix`, not `decided-to-use-baseui`).
- Always `.md`.
## Choosing a template
Two templates live in [`templates/`](./templates/). Default to Nygard.
### Nygard (default — [`templates/nygard.md`](./templates/nygard.md))
Use Nygard for the common case: a decision that is essentially a one-way
door with a clear motivating context and one obvious choice. Four sections:
**Title, Status, Context, Decision, Consequences (Positive / Negative)**.
Aim: ≤60 lines. Reads in under a minute.
### MADR v4 (when alternatives matter — [`templates/madr.md`](./templates/madr.md))
Use MADR when the decision involves weighing multiple alternatives that a
future reader would otherwise re-litigate. Triggers:
- **Authentication / session strategy** (NextAuth vs iron-session vs Clerk).
- **Queue / messaging mechanics** (LISTEN/NOTIFY vs Redis vs SQS).
- **Agent integration patterns** (REST polling vs MCP vs SSE channel).
- **Schema or data-model choices with non-trivial migration cost.**
- Any decision where you want to record the *rejected* options so future
contributors don't propose them again.
MADR adds: YAML front-matter (status, date, decision-makers, consulted,
informed), explicit Decision Drivers, Considered Options, Pros and Cons of
each option, Confirmation, and More Information.
## Status lifecycle
```
proposed → accepted → (optionally) superseded by NNNN
↘ (optionally) deprecated
```
- **proposed** — drafted, awaiting decision-maker sign-off.
- **accepted** — current binding decision; the codebase reflects this.
- **superseded by ADR-NNNN** — replaced. Keep the file; never edit the
Decision section. Add a one-line "Superseded by …" note at the top of
the Status section and link to the new ADR.
- **deprecated** — still current but no longer recommended; usually a
precursor to a future supersession.
Once an ADR is accepted, it is immutable except for the Status field and
typo fixes. Course corrections always create a new ADR.
## Index of ADRs
| # | Title | Status | Template |
|---|---|---|---|
| [0000](./0000-record-architecture-decisions.md) | Record architecture decisions | accepted | Nygard |
When new ADRs are added, the docs index generator (`npm run docs:index`)
will list them in [`../INDEX.md`](../INDEX.md). Update this table by hand
when you add or supersede an ADR — the script aggregates across the whole
docs tree, this README is the canonical ADR-only roster.

View file

@ -0,0 +1,78 @@
---
status: {{proposed | rejected | accepted | deprecated | superseded by ADR-NNNN}}
date: {{YYYY-MM-DD when the decision was last updated}}
decision-makers: {{list everyone who participated in the decision}}
consulted: {{list everyone whose opinions were sought (typically subject-matter experts), and with whom there was a two-way communication}}
informed: {{list everyone who is kept up-to-date on progress, and with whom there is one-way communication}}
---
# ADR-{{NNNN}}: {{short title, representative of solved problem and found solution}}
## Context and Problem Statement
{{Describe the context and problem statement, e.g., in free form using two
to three sentences or in the form of an illustrative story. You may want
to articulate the problem in form of a question and add links to
collaboration boards or issue management systems.}}
## Decision Drivers
- {{decision driver 1, e.g., a force, facing concern, …}}
- {{decision driver 2, e.g., a force, facing concern, …}}
## Considered Options
- {{title of option 1}}
- {{title of option 2}}
- {{title of option 3}}
## Decision Outcome
Chosen option: "{{title of option 1}}", because {{justification — e.g., only
option which meets a knock-out criterion / which resolves a force / …
turned out best (see "Pros and Cons of the Options" below)}}.
### Consequences
- Good, because {{positive consequence, e.g., improvement of one or more
desired qualities, …}}
- Bad, because {{negative consequence, e.g., compromising one or more
desired qualities, …}}
### Confirmation
{{Describe how the implementation of/compliance with the ADR can be
confirmed. E.g., a test, a peer review, a runtime check.}}
## Pros and Cons of the Options
### {{title of option 1}}
{{example | description | pointer to more information | …}}
- Good, because {{argument a}}
- Good, because {{argument b}}
- Neutral, because {{argument c}}
- Bad, because {{argument d}}
### {{title of option 2}}
{{example | description | pointer to more information | …}}
- Good, because {{argument a}}
- Bad, because {{argument b}}
### {{title of option 3}}
{{example | description | pointer to more information | …}}
- Good, because {{argument a}}
- Bad, because {{argument b}}
## More Information
{{You might want to provide additional evidence/confidence for the decision
outcome here and/or document the team agreement on the decision and/or
define when this decision the decision should be realized and if/when it
should be re-visited. Links to other decisions and resources might appear
here as well.}}

View file

@ -0,0 +1,31 @@
# ADR-{{NNNN}}: {{Short noun phrase describing the decision}}
## Status
{{proposed | accepted | superseded by ADR-NNNN | deprecated}}
## Context
{{What is the issue we're seeing that motivates this decision? Describe the
forces at play — technical, organizational, business — that make this choice
necessary now. State facts, not opinions. Keep it short: one or two
paragraphs is usually enough. If a reader needs background that lives
elsewhere, link to it instead of duplicating.}}
## Decision
{{The choice we've made, written in present tense as a declarative statement.
"We will use X." "We adopt Y." Avoid hedging language. One paragraph.}}
## Consequences
### Positive
- {{What becomes easier or possible because of this decision?}}
- {{What problem is no longer relevant?}}
### Negative
- {{What becomes harder, slower, or more expensive?}}
- {{What did we accept as a trade-off?}}
- {{What new risks does this introduce, and how do we mitigate them?}}