Architecture Decision Records (ADR)
Coffer records every major technical or architectural decision as a numbered, immutable ADR. ADRs capture why — code shows what, this directory shows why we chose what we chose.
When to write an ADR
Write one for any decision that meets at least one of these:
- Hard to change later without breaking compatibility or rewriting large areas.
- Affects more than one module, or imposes structural constraints on future work.
- Has non-obvious trade-offs that future engineers (or future you) will question.
- Diverges from a default, a popular convention, or a project rule (constitution clause, prior ADR).
Do not write an ADR for:
- Library version bumps that don't change API surface.
- Routine bug fixes.
- Scope decisions that belong in a spec's
## Assumptionsor## Out of Scope. - Naming or formatting preferences.
File naming and lifecycle
- Filename:
ADR-NNN-short-kebab-case-title.md— NNN is a zero-padded ordinal (ADR-001-…,ADR-002-…, …). Never renumber. - ADRs are append-only. To change a decision, write a new ADR that Supersedes the old one; mark the old one
Status: Superseded by ADR-NNN. - One decision per file.
- Keep each ADR short — usually under 200 lines. If you need more, you're describing implementation, not the decision.
Status values
| Status | Meaning |
|---|---|
Proposed | Drafted, not yet adopted. |
Accepted | In effect. |
Superseded by ADR-NNN | No longer the live answer; link to its replacement. |
Deprecated | Withdrawn without replacement (rare). |
Template (Michael Nygard format)
markdown
# ADR-NNN: <short title in title case>
**Status**: Proposed | Accepted | Superseded by ADR-NNN
**Date**: YYYY-MM-DD
**Deciders**: <names / roles>
**Related**: ADR-…, spec/…, issue/PR/…
## Context
<What forces are at play? What problem are we solving? Existing constraints,
related ADRs, relevant constitutional clauses.>
## Decision
<The choice, in one or two clear sentences. Then the supporting reasoning.>
## Consequences
<What becomes easier? What becomes harder? What new obligations or follow-ons?>
## Alternatives Considered
<Each rejected option with a one-paragraph reason for rejection. This is the
section that future readers most often want — don't skip it.>Index
| ADR | Title | Status |
|---|---|---|
| 001 | Resource framework designed upfront, not after the second feature | Accepted |
| 002 | Code layout: layer-first with kind subdirectories | Accepted |
| 003 | Resource identifier format: <kind>:<name>, not URN | Accepted |
| 004 | MCP capability state: preferences in DB, list live-queried from upstream | Accepted |
| 005 | One upstream subprocess set per downstream client session | Accepted |
| 006 | Daemon detect-or-spawn pattern; daemon outlives any single client | Accepted |
| 007 | Information architecture: every managed entity is a resource kind | Accepted |
| 008 | Distribution: PyInstaller-bundled daemon + shim as Tauri sidecars | Accepted |
| 009 | Cross-platform skill delivery: symlink / junction / copy-fallback | Accepted |
| 012 | Retrieval stack: markdown files as truth, SQLite FTS5 + sqlite-vec, configurable embeddings | Accepted |
| 013 | Agent-native shared memory projection | Accepted |
| 014 | Channel adapter framework: thin adapters over the chat platform seams | Accepted |
| 015 | Envelope-encrypted credential store (Fernet ciphertext in SQLite, file-default master key) | Accepted |
| 016 | Multi-machine sync over a user-owned git repository | Accepted |
| 017 | Industrial-grade harness, built in layers | Proposed |
| 018 | Tool retrieval for aggregation overload (coffer__search_tools) | Accepted — amended by 024 |
| 019 | Close the eval flywheel (loop engineering) | Accepted |
| 020 | Transcript distillation: read agent transcripts, write memory facts | Accepted |
| 021 | Reposition Agent Chat as the Vault Console | Accepted — partially superseded by 024 |
| 023 | Channel entrypoint differentiation layer | Accepted |
| 024 | The built-in agent is an internal capability, not a chat persona | Accepted |
| 025 | Remove the tool-approval system; owner-pairing is the gate | Accepted |
| 026 | Per-agent MCP server scoping at the gateway | Reverted (2026-06-20) |
| 027 | Skill content trust layer (heuristic scan, warn-don't-block) | Accepted |
| 028 | Knowledge base documents are co-managed (agent-writable) with stable identity | Accepted |
| 029 | Consume the official MCP Registry for server discovery | Reverted |
| 034 | Retrieval mode is an internal engine detail; external surfaces expose query→answer | Accepted |
| 035 | Adopt native memory: read the agent's own per-project store, import into Coffer | Accepted |
| 037 | Rules via runtime SessionStart injection; handoff pull-on-demand | Accepted |