ADR-000 — Template

Status: Accepted, 2026-08-21 (as the house format; this file is never itself a decision) Supersedes / superseded by:Related: 00-charter §0.5, 04-contracts §4.5

A0.1 When to write an ADR

Write one when a choice is hard to reverse, contested, or surprising to a reader who arrives later. Everything else belongs in a contract or a task spec.

Write an ADR Do not write an ADR
A decision that constrains a module boundary, a storage engine, a cloud shape, or a correctness argument A name — that is a contract change (§4.5)
A decision where the rejected option is the one most readers would expect A default value that will be measured and tuned (charter D-04)
A decision that buys one property by paying with another, and the payment must stay visible A step-by-step how-to — that is 08-operations.md
Accepting a known defect on purpose (e.g. ADR-005) Restating a requirement — cite the FR/NFR/INV id instead

The test: if in six months someone would reasonably ask “why on earth is it like this?”, the answer must already exist as an ADR. Failure mode of skipping it: the next maintainer “fixes” the decision, the tests still pass, and the property it protected is silently gone.

Rules. One decision per file. Numbered ADR-NNN-kebab-title.md, never renumbered. Immutable once Accepted — a change is a new ADR that supersedes it, with both links updated. Never restate a contract; cite it by relative path plus anchor. Every number is a labelled ASSUMPTION unless it is a measurement, in which case say what measured it.

A0.2 The template

Copy from here down.


ADR-NNN —

Status: Proposed | Accepted, YYYY-MM-DD | Superseded by ADR-MMM Deciders: <role(s)> Requirements touched: FR-nn, NFR-nn, INV-nn Contracts touched: Cn §n.n

AN.1 Context

What forces are in play, in 5–12 lines. State the constraint that makes this decision non-obvious, and the one property that must survive. Cite requirement ids rather than re-arguing them. No solutions here.

AN.2 Decision

One sentence in the active voice, present tense: *“We , because ."* Then, if needed, a table of the decision's parts. If this section needs three paragraphs, the ADR is carrying two decisions — split it.

AN.3 Consequences

   
Positive What we now get that we did not have. Name the requirement each item discharges.
Negative What is now harder, slower, or more expensive. Real numbers where they exist.
What we accept The residual defect we are choosing to live with, plus how it is bounded — a budget, an alert, a kill switch, a test. An unbounded accepted defect is not accepted, it is unnoticed.

AN.4 Alternatives considered

Alternative Why it is attractive Why rejected
The specific reason, not “not a good fit”. Name the failure mode it would produce here.

At least two alternatives, one of which a reasonable engineer would have picked. “Do nothing” counts.

AN.5 Revisit when

Trigger Threshold (ASSUMPTION unless measured) Then
A number or an event, never “if it becomes a problem” Which ADR is opened, and what evidence it needs

A0.3 Register

Every decision in the repository. Read the relevant row before proposing a change — reopening a decision without engaging its recorded reasoning is the most common way a contribution is sent back.

ADR Decision Status
001 etcd as the consensus store; the API and SDK carry the correctness Accepted 2026-08-21
002 Fencing token source: ModRevision captured at grant time Accepted 2026-08-21
003 Two databases on two instances, REGIONAL lock / ZONAL pay Accepted 2026-08-21
004 The payout executor is the protected operation Accepted 2026-08-21
005 Autopilot eviction accepted as budgeted unavailability Accepted 2026-08-21
006 Conservative client-side expiry on a monotonic clock — a liveness device, never safety Accepted 2026-08-21
007 A fencing proxy with a persisted high-water mark for a resource that cannot compare-and-set Accepted 2026-08-21
008 Terraform layout, remote state, and forward-pinned provider versions Accepted 2026-08-21
009 Managed Prometheus, and SLOs defined as code in Terraform Accepted 2026-08-21
010 Monorepo with a single Gradle build and one version catalog Accepted 2026-08-21
011 Version control and publication deliberately deferred Superseded by 012
012 Git version control and public publication Accepted 2026-09-14
013 Parallel contribution replaces strict sequencing Accepted 2026-09-14
014 Apache-2.0 with DCO sign-off, no CLA Accepted 2026-09-14

Proposing a new one

  1. Copy the template in A0.2. Take the next free number; never renumber.
  2. Open a pull request labelled type:adr. It needs two maintainer approvals (GOVERNANCE.md §2).
  3. Reversing an existing decision means a new ADR that supersedes it — never an edit to the old file. Update both files’ status lines in the same pull request, and add a row here.
  4. A superseding ADR must engage with the original’s reasoning. “I prefer X” is not an argument against a documented consequence, and these ADRs are specific enough to argue with properly — 012 is the worked example.

Back to top

Apache-2.0. The domain modelled here is fictional; every number is a labelled assumption. Not production-ready — see SECURITY.md.