ADR-004: The decision index is generated from frontmatter
Status Active · Filed 2026-08-03 · Influenced DP-002 · DP-003
Context
The index carried a hand-maintained table — one row per decision — plus per-category link lists. Every contribution that added a decision edited that file, always in the same region. It was therefore both problems at once: the lock DP-2 names, and the drifting projection DP-3 names, since every row duplicated data the decision already owned.
Both bit. Three decisions authored in one session collided in the same table region, and a cherry-pick between two of them conflicted. And at migration time 45 of 155 rows disagreed with their own decision’s status.
Decision
Generate the index and the per-tag pages from frontmatter. luria index
builds; luria lint fails on a stale result, so divergence is a failure rather
than a discovery.
- Prose lives in
README.stubwith{categories}and{table}placeholders — humans edit prose in markdown, not in a generator. - Tag order and blurbs live in
tags.yaml, and a tag used by a decision but absent from that file still renders. Adding a tag needs no code change. - Every rendered field is rebased for the directory it lands in — not just the row’s own link. A summary and a status note are prose too, and they render into both the index and the tag pages one directory deeper. Missing this left four supersession links 404ing on the tag pages of the project this was extracted from, undetected until something finally resolved a generated page’s links.
Alternatives considered
- A fragment directory, like the changelog. Would fix the lock and not the drift. When the shared file’s content is derivable, generation beats collection outright: there is no step to forget.
- Keep the table, add a test that it matches. Rung 2 of DP-3 where rung 1 is available. The test would be the drifting list in a costume.
- No index. A directory listing is an index of sorts, and it can’t show status or summary — which is what makes the index worth reading at all.
Consequences
- Adding a decision is one new file. No shared edit, no conflict.
- The index is read far more often than the decisions, so
summaryis where the effort goes. - Generated files are excluded from the reference rewriter — the generator wins, and rewriting its output would be undone on the next build.