git:20260908.d184cd7 to git:20261021.26ee555

6 added, 6 removed. Audit A to A.

---
name: architecture-decision-record
- description: Capture an architectural decision as an ADR once it has been reached — a choice that constrains future work, had viable alternatives that were rejected, and would be expensive to revisit. Use when a design discussion has converged on such a decision, when the user asks for an ADR, or when a decision needs superseding. Do NOT use for reversible implementation choices, library picks with no lasting constraint, or to minute a discussion that has not concluded.
+ description: Capture an architectural decision as an ADR once it has been reached — a choice that constrains future work, had viable alternatives that were rejected, and would be expensive to revisit. Use when a design discussion has converged on such a decision, when the user asks for an ADR, or when a recorded decision changes. Do NOT use for reversible implementation choices, library picks with no lasting constraint, or to minute a discussion that has not concluded.
license: MIT
---
# Architecture Decision Record
An ADR records **why** the system is shaped the way it is, for a reader who was not in the room and cannot ask.
## ALWAYS apply the three tests before writing
Write an ADR only when a decision has been **reached** and meets all three:
1. **It constrains future work.** Later changes must live with it.
2. **Viable alternatives were rejected**, and the rejection is not self-evident.
3. **It would be expensive to revisit** — reversing it means reworking code, data, or infrastructure.
A decision that fails any test is a normal implementation choice. It belongs in the code and the component's documentation, not here.
**NEVER open an ADR because a discussion started.** Agents and users weigh trade-offs constantly — which library, how to shape a service, whether to add a cache. Minuting all of that buries the handful of records that matter, and this repository's retrieval already ranks documents by standing. The trigger is *convergence*, not debate.
Worked distinctions:
| Situation | ADR? | Why |
|---|---|---|
| "Should this service use a queue or direct calls?" — still being argued | **No** | No decision yet. Wait for convergence. |
| Decided: schema deploys as one idempotent SQL file, no migration framework | **Yes** | Constrains every future schema change; alternatives existed; reversing means retrofitting migrations. |
| Chose `System.Text.Json` over `Newtonsoft.Json` in one service | **No** | Reversible in an afternoon, constrains nothing else. |
| Decided: the browser never holds an access token; the BFF owns the session | **Yes** | A security boundary the whole front end is built around. |
| Named a class `OrderProcessor` rather than `OrderService` | **No** | Not a decision, a preference. |
| Decided: agent roles stay synchronised across all six harnesses | **Yes** | Every future agent change inherits the obligation. |
## NEVER write one without approval
The ADR is a governed document and creating documentation requires user approval. Present the decision, the alternatives, and the consequences **in the conversation first**, and ask. Write the file only after an explicit yes.
If the user declines, do not write it and do not raise it again in the same session.
## Placement and identity
- Active ADRs live in the path declared as **Architecture Decision Records** in the repository root `AGENTS.md` Config Registry; superseded ones move to the archive path recorded there. Read the repository documentation standard for the lifecycle, and the documentation ontology for the frontmatter schema, before writing.
+ Active ADRs live in the path declared as **Architecture Decision Records** in the repository root `AGENTS.md` Config Registry; a record wholly replaced by one on a different subject moves to the archive path recorded there. Read the repository documentation standard for the lifecycle, and the documentation ontology for the frontmatter schema, before writing.
- Filename: `ADR-{YYYY-MM-DD}-{kebab-slug}.md`
- Frontmatter `id`: `adr/{YYYY-MM-DD}-{kebab-slug}` — the date is the decision date, and it never changes afterwards.
- `doc-type: adr`, `status: current`.
- - `supersedes`: the `id` of any ADR this one replaces. Otherwise `[]`.
+ - `supersedes`: the `id` of an ADR this one genuinely replaces, a record on a different subject. Otherwise `[]`. A changed decision is never a new record.
- `code-refs` / `api-endpoints`: symbols and routes the decision governs, when the decision is about specific code. These are validated against the code graph, so every entry must resolve.
## Structure
```markdown
---
id: adr/{date}-{slug}
title: "ADR-{date}: {Short Decision Title}"
doc-type: adr
status: current
owner: {team from the catalog}
last-reviewed: {date}
code-refs: []
api-endpoints: []
decided-by: []
supersedes: []
---
# ADR-{date}: {Short Decision Title}
**Status:** Accepted
**Date:** {date}
## Context
The forces in play: the constraint, the problem, what was true at the time. Enough that a
reader who was not present can judge whether the reasoning still holds. State facts, not
narrative — no meeting history, no attributions.
## Decision
What was decided, in the active voice and one paragraph. "Schema is deployed via a single
idempotent SQL file applied by sqlcmd." Not "we discussed and felt that…".
## Alternatives considered
Each viable option that was rejected, and why. An ADR with no rejected alternatives is
either not a decision or is hiding the interesting part.
## Consequences
What this commits the system to — including the costs. An ADR that lists only benefits is
advocacy, not a record. State what becomes harder, what is now manual, what a future
change will have to work around.
```
- ## Superseding
+ ## Changing a decision
- **NEVER edit the decision out of an accepted ADR.** A reversal is itself a decision, and the record of what was believed before is what makes the reversal legible.
+ **An accepted ADR is edited in place to state only the decision in force.** When a decision changes, rewrite the record so it says what is true now, and remove the superseded wording rather than keeping it beside the new text as history. git holds the history. An `Amended <date>: <one-line reason>` note is optional when the change matters to a reader.
- To supersede: write a new ADR naming the old one's `id` in `supersedes`, set the old one's `status` to `superseded`, add a line under its title pointing to the replacement, and move it to the archive path. Documents that referenced the old decision through `decided-by` are updated to point at the new one.
+ Only a decision on a different subject that replaces an existing record gets a new ADR. That ADR names the replaced `id` in `supersedes`. The replaced record's `status` is set to `superseded`, it moves to the archive path, and documents that referenced it through `decided-by` are updated to point at the new one.
## Linking the decision to what it governs
A decision no one can find does not constrain anything. Add the ADR's `id` to the `decided-by` frontmatter of every document the decision governs — that key is what carries the decision through the documentation graph to the components it binds.
## Verify before finishing
Run the repository's documentation validation and drift checks. `code-refs` and `api-endpoints` resolve against the code graph, and a `decided-by` or `supersedes` pointing at a non-existent id fails validation.