Context
ADR-077 made the examples publishable. It did not make them
maintained. Their generated views were gitignored, on the argument written
into examples/.gitignore:
None of it is committed:
tests/test_examples.pybuilds each example in a temporary directory and generates there, so nothing here can become a stale committed view — which is the failure these examples exist to argue against.
That argument conflates two different things. The failure
DP-3 names is a hand-maintained
projection, not a committed one; its first and strongest remedy is derive it,
and a view that CI regenerates on every push is derived. This project’s own
docs/ are committed on exactly that basis.
So the examples were the one place in the repository where a generated view could not be read without running the tool, and where nothing checked that the sources and the views agreed. Same shape, opposite rules — the reading DP-16 says to take seriously rather than tolerate.
The gap was structural rather than an oversight: luria index had no idea the
nested records existed. outputs() renders from current(), and the root
config has no VALUE, SCENE or LIT scheme, so it would render nothing
for them — and nothing is indistinguishable from current
(DP-15). Committing views that no
command regenerates would have made the original argument true.
Decision
outputs() and view_dirs() reach into nested records, each rendered under
its own config. run() and staleness() are unchanged and inherit it: the
writing loop writes those paths, the staleness diff compares them, the orphan
rule covers their view directories. One level deep, with an explicit flag on
the recursion so the absent second level reads as a decision.
The views are therefore committed, examples/.gitignore empties out, and
luria index --check fails on a stale nested view exactly as it does on one of
this project’s. The CI action needs no change at all — it runs luria index,
and that now means all of it.
include_records moves from [luria.site] to [luria]. Publishing was
the first thing that needed the list; it is not the only thing, and it was
never a site fact. A key that luria index must reach into the site table to
read is precisely the awkwardness
DP-16 describes — a distinction the
layout had stopped expressing. Config.nested_records() is now the single
answer, because index, --check and site must agree: a record that is
published but never regenerated is worse than either alone
(DP-4).
luria site reads a nested record’s views instead of building them.
Staging used to copy each child to a temporary directory and generate there,
which existed only because the views were not committed. It now stages from the
record itself, on the same contract the parent already runs on — the Pages
build follows the job that regenerates.
Consequences
The count line names the records rather than folding them into the tally: “Wrote 78 file(s) from 77 ADRs, 14 DPs, 60 devlog entries, plus examples/collocated, examples/constitution, …”. “78 files from 77 ADRs” is arithmetic nobody can check, and a nested record that silently rendered nothing would look exactly like one that rendered correctly.
An adopter with several records in one repository gets regeneration, staleness
checking and publishing from one luria index and one luria site, which is
the general case this repository happened to hit first.
The cost is the one every auto-fix bot here already charges: a push touching an
example draws a [skip ci] regeneration commit, and the next push wants a
git pull first.
tests/test_examples.py still builds each example in tmp_path and generates
there. That is now about isolation rather than about avoiding a committed view
— the suite must not depend on the checkout being current — and the committed
views are covered instead by --check, which is a stronger guarantee than the
arrangement it replaces.