Skip to content

ADRs

Folio keeps a thin set of ADRs in docs/design-docs/adrs/. Each one names a decision that’s hard to revisit later — something the verify gate enforces, or that propagates through the spec.

Catalogue

#TitleStatus
0001Record design docs and ADRs under docs/Accepted
0002Use Python as the reference implementationAccepted
0003Use ODCS subset for contract.yamlAccepted
0004Store records as line-delimited JSONAccepted
0005Use DuckDB SELECT-only for queriesAccepted
0006Use single-writer .lock for sheet writesAccepted
0007Match x-editable-by with fnmatch patternsAccepted
0008Place caches and runtime outside the sheetAccepted
0009AI client Protocol and deterministic stubAccepted

What ADRs in Folio do

Each ADR has a fixed shape:

  • Status — Accepted / Superseded / Deprecated.
  • Context — what was true when the decision was made.
  • Decision — the choice.
  • Consequences — what follows.
  • Confirmation — the test, gate, or invariant that keeps the decision in force.

The Confirmation section is the load-bearing one. It names a make verify check that fails if the decision is silently undone:

ADRConfirmation
0005 (DuckDB)drift-check requires duckdb to be imported under src/folio/.
0006 (filelock)drift-check requires filelock to be imported under src/folio/.
0008 (cache outside)drift-check rejects fixtures with .cache/, .venv/, etc.
0009 (AI Protocol)drift-check requires anthropic to be imported only in src/folio/_ai_kind.py.

Plus the Phase 5 viewer-only invariant: fastapi/uvicorn may only be imported from src/folio_viewer/.

Adding an ADR

When a new decision is sufficiently load-bearing — it changes the spec, shapes new code, or adds a new gate — propose a new ADR by copying template.md and renaming with the next sequential number.

make verify enforces:

  • ADR files are sequentially numbered with no gaps.
  • Every ADR is indexed in adrs/README.md.
  • Every Accepted ADR includes a Confirmation section.

docs/methodology/permanent-fix-protocol.md lays out the workflow: when an agent failure becomes a recurring pattern, an ADR is the way to encode the fix so future agents (and future you) won’t re-introduce it.

Reading order

If you’re getting started:

  1. 0008 (cache outside) — explains the most-asked question.
  2. 0006 (single-writer lock) — explains the concurrency model.
  3. 0005 (DuckDB SELECT) — explains the read surface.
  4. 0007 (fnmatch) — explains the permission model.
  5. 0009 (AI Protocol) — explains the testing model.

The rest are useful context but not load-bearing for day-to-day use.