ADR-056: A scheme declares which statuses it uses and what they mean

Status Active · Filed 2026-08-16 · Issue #102 · Influenced DP-012

Context

ADR-003 closed the status vocabulary to five words and put a lint behind it. Its evidence was an audit of 121 records where the field had entropied into thirty forms, and its finding was general: every documentation surface guarded by an executable check had held; every surface governed by prose convention alone had drifted.

The five words have held. The layer above them has not, and it was never covered: a status means something different in every scheme, and that meaning has only ever lived in prose — a _template.md comment, plus whatever decisions a project writes.

Downstream evidence, from a project using six schemes over a corpus of arguments. It wrote three decisions to pin its status semantics, and twice found the record doing something else:

  • One scheme had fifty-one of fifty-one records at the in-force status, because extraction defaults there and nothing contradicted it — including twenty-three whose own bodies exhibited a counterexample. Its fail_on named retired-citations, so the enforcement it had adopted luria for could not fire, and a green build meant only that nobody had judged anything.
  • A sibling scheme’s template said status carried a judgment that a tag_groups axis was actually carrying. Nine records disagreed with their own template.

Both were caught by a person re-reading. That is the failure mode ADR-003 exists to remove, one level up from where it removed it.

Decision

An optional statuses.yaml in a scheme’s directory, beside tags.yaml and shaped like it: the vocabulary lives in YAML with the records, while any rule about it stays in luria.toml — the same split tags.yaml and tag_groups already use.

Active:
  label: Asserted
  blurb: the record asserts this proposition
Rejected:
  label: Defeated
  blurb: the corpus contains it and it is wrong

Three consequences, and the boundaries matter more than the feature:

  • The five words stay closed. A key outside them is a lint error, not a new status. This decision narrows ADR-003’s vocabulary per scheme and never extends it.
  • A record whose status the scheme does not declare fails the lint. That is the narrowing, and it is what makes declaring worth doing.
  • The meaning renders above the index table, in the generated view, next to the column it explains.

Declaring nothing changes nothing. No file means all five words and no legend, which is every existing project.

Alternatives considered

  • Let a scheme add words. The obvious reading of “configurable status”, and it gives back exactly what ADR-003 bought. Thirty forms across 121 records is what an open vocabulary produced here, and a per-scheme open vocabulary is the same thing with more places to do it. A project that wants a sixth distinction has tags, which are open by design.
  • A {statuses} placeholder in the stub. Symmetrical with {categories} and {table}, and it fails the one job: a project that adds statuses.yaml and forgets the placeholder gets no legend and no complaint. Rendering it automatically means adopting the file is enough. If a project later wants it elsewhere, a placeholder can be added then without breaking this.
  • Put the vocabulary in luria.toml. One less file, and it splits the two browsing axes across two homes — tags in YAML, statuses in TOML — for no reason a reader could reconstruct.
  • Enforce meanings rather than declare them. What would actually have caught both downstream failures is a check for a scheme whose status never varies: a field where every record agrees carries no information. That is real and is worth having, and it is a different unit of work — this decision is about where the meaning lives, not about auditing whether it is used.
  • Status quo. The meaning stays in a template comment, which is read once by whoever mints a record and never by anyone browsing the index.

Consequences

A reader of a generated index can now learn what Rejected means in this scheme without finding the project’s decision record. That is the change with the most reach: the template comment was only ever seen by authors.

statuses.yaml is a fourth thing that can be in a scheme directory, after the records, _template.md and tags.yaml. All four are optional except the records, and the shape is now consistent enough to state: a scheme directory holds its records, a template for minting one, and one file per browsing axis saying what that axis’s values mean.

This does not check that a declared vocabulary is used. A scheme can declare five statuses and file everything at one, which is the first downstream failure above, still uncaught. The alternatives section names the check that would catch it; it is deliberately not in this decision.