Jochen: a normal application has 3-5 ADRs, maybe 10 for a large one, and we are at 65. Fair, and the cause is mine -- I recorded every FINDING as a decision rather than every fork in the road. Two merges, both cases where one decision had been split across many records because it was taken over several days rather than at once. 0019 absorbs ten records about how this repository works: what it is and that it is public, the folder flow, the two design layers, the issue front door, status in frontmatter, playbooks, the naming rule, the product name. Those were never ten decisions -- they were one, seen from ten angles as the repository took shape. 0016 absorbs the five about the lab: a node is a virtual machine, a router is scenery, a scenario declares the underlay, a scenario is a closed address space, and the two scenario classes. Same pattern -- one design, split by the order it was worked out in. The consolidated 0019 also raises the bar for what earns a record, since that is what produced 65: a record is warranted when there is a genuine fork -- a direction reversed, an alternative that will be proposed again, something contested. A finding is not a decision, and a bug is certainly not. Everything else belongs in the design document where the reasoning is actually read. The checker earned its place here. Deleting nine records left 13 dangling links across the repository and it named every one, including in AGENTS.md. Nothing was found by reading. Remaining clusters worth the same treatment: the host (8 records), delivery (5), modules (6), connectivity (4), substrate and control plane (4). That would be 52 down to roughly 30.
68 lines
2.9 KiB
Markdown
68 lines
2.9 KiB
Markdown
# 02-DECISIONS
|
||
|
||
Architecture decision records — the "why" trail behind the rules in
|
||
[`00-META`](../00-META/) and the specifications in [`03-DESIGN`](../03-DESIGN/).
|
||
|
||
**Numbered `02` because a decision precedes the design it authorises.** Research concludes,
|
||
the decision is recorded here, and only then is the design written. Following the folder
|
||
numbers walks the process in the order it happens.
|
||
|
||
One file per decision, numbered, never deleted. A superseded record has its `status:` changed
|
||
and gains a pointer to what replaced it — **its text is never edited**. The reasoning that was
|
||
rejected is the expensive half to rediscover.
|
||
|
||
The records run in the order the decisions were taken, oldest first.
|
||
|
||
**Every decision is a record.** There is no ledger and no index file — if a decision is worth
|
||
recording it is worth a record, and if it is not worth a record it is not recorded
|
||
([ADR 0019](0019-how-this-repository-works.md)). A "decision" small enough to be one line is
|
||
almost always a **rule**, and a rule belongs in
|
||
[`00-META/how-we-build.md`](../00-META/how-we-build.md), where it is enforced and keeps the
|
||
incident that earned it.
|
||
|
||
## Frontmatter
|
||
|
||
```yaml
|
||
---
|
||
status: proposed | accepted | superseded
|
||
date: YYYY-MM-DD # when the decision was taken, not when it was written down
|
||
deciders: name
|
||
reconstructed: true|false # true when the record was written after the fact from evidence
|
||
superseded-by: # 02-DECISIONS/NNNN-....md, when status is superseded
|
||
extends: # 02-DECISIONS/NNNN-....md, when this record widens an earlier one
|
||
---
|
||
```
|
||
|
||
## Body
|
||
|
||
```
|
||
# N. Title in plain language
|
||
|
||
## Context what was true, with evidence
|
||
## Considered Options numbered, each with why it was rejected
|
||
## Decision what was decided
|
||
## Consequences what follows, including what got harder
|
||
## References commits, pull requests, knowledge-base entries, prior art
|
||
```
|
||
|
||
State evidence, not assertion. *"Zero of 124 modules declare `brain` as a dependency"*
|
||
outranks *"the dependency rule is not followed"*.
|
||
|
||
## Reconstructed records
|
||
|
||
Records 0001–0014 were written on 2026-08-23, after the decisions they describe. Records 0015 onward were taken as records. Those
|
||
decisions were taken in implementation rather than in a document; the records state what was
|
||
decided and the evidence it was decided from, and each carries `reconstructed: true` and says
|
||
so in its first lines.
|
||
|
||
A reconstructed record is not a transcript. Where the deliberation is not recoverable, the
|
||
options section states what the alternatives were and why the chosen one won on the evidence
|
||
available — not a discussion that did not happen. Where a date is not establishable it says so
|
||
rather than guessing.
|
||
|
||
## Index
|
||
|
||
The index is **generated, not maintained** — run the `hq-status` skill, which reads the
|
||
frontmatter of every record. A hand-written index drifts from the folder it describes, and
|
||
this one had already done so after a single addition.
|