# Architecture decision records

One file per durable decision, `NNNN-<slug>.md`, numbered in the order they were recorded and
never renumbered. The record is the decision; [`docs/architecture.md`](../architecture.md) is the
system that resulted from the recorded decisions, and [`docs/tech-spec.md`](../tech-spec.md) is
what a change must comply with.

## Status vocabulary

| Status | Means |
|---|---|
| `Proposed` | Written, not yet decided |
| `Accepted` | The human accepted it (E5); a change binds to it. A decision read back from the tree says so on its own line and keeps the reading's provenance |
| `Accepted (reconstructed)` | Read back from the tree after the fact and accepted on that basis; it binds, and the ADR names the tree state it was read from |
| `Accepted — E5 pending` | Read back from the tree but **not yet accepted**: it describes today's behaviour, and it cannot be cited as approval for a further change |
| `Superseded by ADR-NNNN` | Replaced; kept for history, never edited |

## Index

| ADR | Decision | Status |
|---|---|---|
| [0001](0001-architecture-style.md) | Layered modulith; DDD rejected | Accepted (reconstructed) |
| [0002](0002-stack-bundle.md) | Node 22 + `node:sqlite`, zero runtime dependencies; Vue built offline | Accepted (reconstructed) |
| [0003](0003-delivery-report-anchors-at-write.md) | A `met` claim needs its evidence anchor at delivery, not only at close | Accepted |
| [0004](0004-actor-kind-system.md) | The board writes as `system`; acceptance is decided by evidence, not by actor kind | Accepted |
| [0005](0005-the-loop-ships-with-the-board.md) | The loop ships in the board's package, so the board-interface gate is removed | Accepted |
| [0006](0006-first-class-worker-sessions.md) | A worker is its own pooled session, resumed by id in the same round; replay when the native session is gone | Accepted |
| [0007](0007-roles-are-skills-and-the-director-decides.md) | Roles are standalone skills; installation location routes the platform; `meerkat-director` decides and the control turn is gone | Accepted |
| [0008](0008-a-worker-holds-for-the-ladder.md) | A worker holds with a bounded `issue wait`; the director settles by releasing the card; escalation parks and resumes by id | Accepted |
| [0009](0009-a-cycle-stops-at-a-human-decision.md) | A card that keeps coming back is parked as `blocked(decision)`, never auto-cancelled; the board decides, the loop executes | Accepted |
| [0010](0010-director-consumes-the-required-handoff.md) | An accepted card's required handoff is a director triage decision: create/seed/link the downstream cards or record that none is needed | Accepted |
| [0011](0011-card-acceptance-is-one-word.md) | A card carries one acceptance word (`off` · `auto` · `human`); projects carry no default; `human` may close after the review finishes | Proposed |
| [0012](0012-role-kind-order-comes-from-the-install.md) | The install-time `--target` order is the role kind preference; a kind the order omits is appended, never excluded | Accepted |
| [0013](0013-the-role-catalog-is-a-local-taskctl-file.md) | The discovered role set is published as a local `roles.json`; the scan set is the discovered worker roles; the scan-set key is removed | Accepted |

## Writing one

Keep it short: Context (1–3 sentences), Decision, Why. Add Status, Considered Options and
Consequences when they help. A decision that changes a rule in the standard names the rule it
replaces and why. Do not edit an accepted ADR to reverse it — write a new one and mark the old
`Superseded`.
