Architecture Decision Records
Numbered, immutable once Accepted in their core decision. Format: Status / Context / Decision / Consequences.
| Number | Title | Status |
|---|---|---|
| ADR-0001 | Visibility and simulation precede enforcement | Accepted |
| ADR-0002 | Persistent gRPC streams with desired-state delta sync | Accepted |
| ADR-0003 | Enforce via native OS firewalls with an owned, atomically replaced ruleset | Accepted |
| ADR-0004 | Token-gated enrollment, URI SAN identity, embedded CA behind an interface | Accepted |
| ADR-0005 | Single Go binary, modular monolith, stateless replicas, Postgres | Superseded by ADR-0017 |
| ADR-0006 | sqlc + pgx for data access, goose for migrations — no ORM | Accepted |
| ADR-0007 | Protobuf is the source of truth for the agent contract; transports are thin callers of the domain | Accepted |
| ADR-0008 | UI is a static Vite + React SPA embedded in the control-plane binary | Accepted |
| ADR-0009 | Postgres-only flow storage in v1, behind a FlowStore interface with a columnar-ready schema | Accepted |
| ADR-0010 | v1 enforces inbound only; outbound arrives in v2 as a layered model | Accepted |
| ADR-0011 | Fail static, local kill switch, resource budgets, no self-update | Accepted |
| ADR-0012 | Relay tier and regional federation are designed seams, deferred implementations | Accepted |
| ADR-0013 | Apache-2.0, DCO sign-off, project trademark retained | Accepted |
| ADR-0014 | docs/ is the shared source of truth; PRs are reviewed against ADRs, including by automated review | Accepted |
| ADR-0015 | The v1 agent wire contract | Accepted |
| ADR-0016 | Enrollment, workload identity, and credential issuance | Accepted |
| ADR-0017 | Single Go binary, stateless replicas, Postgres for state, and the one exception: signing-key custody | Accepted |
| ADR-0018 | Render everything on change, version by diff, keep rendered state in Postgres | Accepted |
| ADR-0019 | Flow storage as windows plus totals, peers resolved at ingest, bounded retention, and the query shapes the schema serves | Accepted |
| ADR-0020 | Enforcement as one owned table replaced atomically, per-rule sets, connection marks for attribution, logged drops, simulation on the same chain, and policy that outlives the daemon | Accepted |
| ADR-0021 | Operator surface: a second listener and single-operator authentication | Accepted |
| ADR-0022 | One label grammar, admitted wherever a label enters | Accepted |
These ADRs are the source of truth for automated and human PR review — a change that contradicts the core decision of an Accepted ADR needs a superseding ADR first.
Changing an ADR
Two mechanisms, and which one applies is decided by whether the core decision survives:
- Supersession is reserved for the case where an ADR's core decision is reversed or replaced. The superseding ADR takes the next number, carries a
Supersedes: ADR-XXXXheader, and restates the full current decision; the old ADR's status line becomesSuperseded by ADR-YYYYand its body is never edited. The pull request that carries a supersession names the maintainer sign-off for it explicitly in its description. - Everything else is an in-place amendment: additive detail, clarification, narrowing of scope, or correction of a subsidiary point while the core decision stands. An in-place amendment corrects the body text so the document always states the current decision, and records the change in a dated note under an
## Amendmentsheading in the ADR itself, referencing the ADR or pull request that carries the new detail; git history preserves the prior text. Amendments never restate the document, and they never touch the core decision. - Titles state the current decision and are corrected by amendment like any other text, with the correction recorded in the dated note; the ADR number is the permanent citation key, and the file name keeps it.
Narrowing is a form of amendment; there is no Narrows: header.
main is the record: an ADR number is consumed only when the ADR carrying it is on main, so a number used by a draft on a branch that never merged is free for the next ADR.
An ADR written to resolve a review finding is scoped to that finding. New architectural decisions encountered along the way get their own commissioned ADR, not bullets inside the fix.