Skip to content

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 ## Assumptions or ## 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

StatusMeaning
ProposedDrafted, not yet adopted.
AcceptedIn effect.
Superseded by ADR-NNNNo longer the live answer; link to its replacement.
DeprecatedWithdrawn 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

ADRTitleStatus
001Resource framework designed upfront, not after the second featureAccepted
002Code layout: layer-first with kind subdirectoriesAccepted
003Resource identifier format: <kind>:<name>, not URNAccepted
004MCP capability state: preferences in DB, list live-queried from upstreamAccepted
005One upstream subprocess set per downstream client sessionAccepted
006Daemon detect-or-spawn pattern; daemon outlives any single clientAccepted
007Information architecture: every managed entity is a resource kindAccepted
008Distribution: PyInstaller-bundled daemon + shim as Tauri sidecarsAccepted
009Cross-platform skill delivery: symlink / junction / copy-fallbackAccepted
012Retrieval stack: markdown files as truth, SQLite FTS5 + sqlite-vec, configurable embeddingsAccepted
013Agent-native shared memory projectionAccepted
014Channel adapter framework: thin adapters over the chat platform seamsAccepted
015Envelope-encrypted credential store (Fernet ciphertext in SQLite, file-default master key)Accepted
016Multi-machine sync over a user-owned git repositoryAccepted
017Industrial-grade harness, built in layersProposed
018Tool retrieval for aggregation overload (coffer__search_tools)Accepted — amended by 024
019Close the eval flywheel (loop engineering)Accepted
020Transcript distillation: read agent transcripts, write memory factsAccepted
021Reposition Agent Chat as the Vault ConsoleAccepted — partially superseded by 024
023Channel entrypoint differentiation layerAccepted
024The built-in agent is an internal capability, not a chat personaAccepted
025Remove the tool-approval system; owner-pairing is the gateAccepted
026Per-agent MCP server scoping at the gatewayReverted (2026-06-20)
027Skill content trust layer (heuristic scan, warn-don't-block)Accepted
028Knowledge base documents are co-managed (agent-writable) with stable identityAccepted
029Consume the official MCP Registry for server discoveryReverted
034Retrieval mode is an internal engine detail; external surfaces expose query→answerAccepted
035Adopt native memory: read the agent's own per-project store, import into CofferAccepted
037Rules via runtime SessionStart injection; handoff pull-on-demandAccepted