---
name: ddia-architecture-decisions
description: Record or review architectural decisions (ADRs) and design objective architecture checks (fitness functions). Use when a consequential, hard-to-reverse choice is made, when documenting why an option was rejected, or when an invariant should be enforced automatically.
---
# Architecture Decisions and Governance
Hard Parts ch.15 (trade-off analysis) and the evolutionary-architecture method; DDIA ch.1
for the trade-off posture. The durable statement of this principle lives in
`../../principles/decisions-are-governable.md`.
## When to use
- A decision is consequential and expensive to reverse (new store, new boundary, new
consistency commitment, a rejected option that will recur).
- An architectural invariant should become mechanically checkable.
- Reviewing whether a proposed decision deserves an ADR.
- Periodic governance: are decisions still honored?
## When NOT to use
Implementation details, library picks, anything cheap to change, or the nth micro-decision
in a day — ADRs are for durable constraints.
## Procedure A — writing/reviewing an ADR
### 1. Is it an architectural decision?
Expensive to reverse + constrains future choices = yes. "Which ORM" is a detail; "Zero is
the sync plane for structural state" is a decision. When in doubt: would a future
contributor need to know *why* to avoid re-breaking it?
### 2. The record (≤1 page)
```markdown
# ADR-NNNN:
Status: proposed | accepted | superseded by ADR-M | revisited YYYY-MM-DD
Date: / Commit:
## Context
What forced this: requirements, constraints, evidence. Include numbers where they exist.
## Alternatives considered
Real candidates with honest costs — including "do nothing" / "keep current".
## Decision
What we chose, stated as a rule a future reader can check code against.
## Consequences
What this makes easier / harder / required / forbidden.
## Revisit when
Observable triggers that reopen this. (A decision without triggers is dogma.)
```
### 3. ADR review checklist
- Alternatives are real (not strawmen) and include keep-as-is.
- Consequences are honest about cost, not a sales pitch.
- Revisit triggers are observable, not vibes.
- The decision statement is checkable — "X is the authority for Y" not "X is preferred".
## Procedure B — fitness functions (objective architecture checks)
### 1. Is the invariant checkable?
Worth automating only if: important + objective + cheap + stable. Fuzzy rules stay as
review checklist items — don't mechanize judgment.
### 2. Candidate shapes
- **Dependency rules**: forbidden imports between modules/packages ("workflows never import
provider SDKs"; "browser-safe package never imports node-only"). Cheap static check.
- **Ownership rules**: only component X writes table T — a lint over the codebase.
- **Layering**: no upward dependencies; domain purity at declared boundaries.
- **Contract checks**: OpenAPI/schema compatibility diffs, consumer-driven contract tests.
- **Replay gates**: durable-execution histories replay before deploy.
- **Budgets**: payload caps, history size, API shape invariants — measurable thresholds.
- **Docs-vs-code drift**: generated inventory compared to a committed manifest.
### 3. Placement
- Put the check at the cheapest layer that catches it: lint > unit test > CI lane > runtime
assertion > audit job.
- Every check names the invariant it protects and what failure means — a failing check
that nobody understands gets deleted.
### 4. Distinguish three failure meanings
| Check fires | Meaning | Response |
| --- | --- | --- |
| Fitness function red | The SYSTEM drifted from intent | Human architectural review — the code may be right or the invariant may need amending |
| Profile/docs drift check red | The DOCS stopped matching code | Update the docs (code is authoritative for behavior) |
| ADR contradicts code | A deliberate decision is being silently reversed | Surface for explicit re-decision — never silently edit the record |
## Procedure C — periodic governance
Cheap governance that actually runs:
- When reviewing any change: does it violate a recorded ADR/invariant? If yes — require
explicit re-decision, not silent override.
- When a new invariant lands: is it checkable? If yes and cheap → fitness function; if
judgment-only → add to the review checklist.
- Revisit triggers that fired → re-open the ADR, update status, link forward.
## Output
ADR file(s) in the project's decision location (or a PR note for review), any new fitness
check with its invariant named, and the list of decisions-deferred with triggers.