ADR-045: Worked configurations are executable examples, not prose
Status Active · Filed 2026-08-11 · Influenced by ADR-006 · ADR-044 · Influenced ADR-046 · ADR-047
Context
ADR-044 gave the docs a generated configuration reference, which fixed discoverability: every key is now listed and cannot go missing. It did not fix credibility. The reference and the new “Shaping the record to your project” section both describe configurations in prose, and this project’s founding observation is precisely that prose drifts — every documentation surface with an executable guard held; every surface governed by prose alone had not.
The gap was not hypothetical for long. Building four working projects out of the configurations that had just been documented falsified two of them immediately, and surfaced a third defect:
active = "Accepted"was offered as “whatever in force means for your RFCs”. The status vocabulary is closed and lint-enforced (ADR-003), soactiveselects from five statuses and cannot extend them. The example named a state no document could hold.- “Omit
outputand the view renders beside its sources” was true for a scheme a project invents and false forADR— configuration merges overDEFAULTS, which carriesoutput = "docs/decisions". The documented way to adopt without moving files silently relocated the index. - A
render = "document"scheme with noREADME.stubemitted the heading# Design principlesregardless of prefix, so a SPEC family rendered as a document was titled after this package’s own principles.
None of the three was visible to review. All three were visible in the first minute of running the configuration.
Decision
examples/ holds four complete projects, each demonstrating a different
shape: rfcs-and-specs/, collocated/, many-journals/,
external-citations/. tests/test_examples.py copies each into tmp_path,
points LURIA_ROOT at it, runs luria index and the lint checks, and asserts
the specific capability — that a document-rendered scheme emits its bodies and
a stable anchor, that three journals produce month, year and day books, that
ARXIV-2301.07041 becomes a real arXiv URL.
Two details carry weight.
Nothing generated is committed. The tests build in a temporary directory
and examples/.gitignore keeps the views out of the repository. A committed
view that no CI run regenerates is exactly the stale projection these examples
exist to argue against, and it would be a particularly bad one — sitting in
the directory a newcomer copies from.
The limits are asserted, not just described. Three tests pin things Luria
cannot do: active cannot extend the vocabulary, the shipped ADR scheme
cannot be removed, and omitting its output does not collocate it. A
capability that regresses fails a feature test; a limit that goes
undocumented, or a documented limit that quietly stops being true, has no
guard at all unless someone writes one. examples/README.md states all three,
and a document that states a limit has to be right about it.
Alternatives considered
- Prose examples alone. The status quo. Now known to have been wrong in two places on the day it was written, which is the strongest argument available and was not available before this work.
- Fixtures inside
tests/only. Cheaper and gets the same guard, but the audience is adopters deciding whether Luria fits a shape they have in mind. They will not read a test module, and they cannot copy one. Putting the projects where they can be browsed, and then executing them, is the same source serving both uses (DP-3). - Doctest-style snippets in the guide. Tests the snippet rather than a project. None of the three defects above would have been caught: each needed a real tree to render and lint end to end.
- Committing the generated views so the examples look complete when browsed. Tempting, and it would put a stale view in the one directory people copy from.
Consequences
Four configurations are now claims CI defends, and the guide points at them
rather than only describing them. The three defects found are fixed: the
DEFAULT_DOCUMENT_STUB heading names its own scheme, and both wrong prose
claims in docs/adopting.md are corrected and now have tests behind them.
Two ADR-scheme limits are documented rather than resolved, both from the
same cause — configuration merges over DEFAULTS rather than replacing them.
Making the shipped scheme removable, or its output genuinely unset by
omission, is a change to merge semantics and belongs in its own decision. Until
then the reference, the guide and examples/README.md all say so, and tests
hold them to it.
The ongoing cost is real: a change to render output now breaks example tests
as well as Luria’s own, and examples/** joins template/** in the site’s
exclusions so a sample record is not published beside the real one
(DP-9). That is the intended
direction — the examples are meant to be load-bearing, and a guard that never
fires was not worth adding.