Numbers taken by reading a repository many branches write at once collide; one counter in a module of the mesh's own, advanced by compare-and-set, ends that at the source. The operator delegated the five open questions on 2026-10-10; each is decided as the research recommended. The glossary gains the issue tracker, retires "ticketing system" and lists ticket as a homonym, since ADR 0258 already uses it for an answer's one-time token.
Checks
python3 00-META/checks/records.py structure: links, citations, supersession, topics
python3 00-META/checks/index.py every record's topic is in the reading order, and no list of records is stored
python3 00-META/checks/index.py --print the records, by topic, in reading order (generated, never written)
python3 00-META/checks/words.py the glossary's retired words are not used, no daemon's line is written, and no word is defined twice
python3 00-META/checks/words.py --list tools the words the catalogue's copy must list
python3 00-META/checks/words.py --list lines the daemons' lines the catalogue's copy must list
Non-zero exit on any problem, so it can be a gate rather than a report.
Why this exists. Until now nothing in this repository was verified by anything but reading,
which is how a superseded decision stayed live in the constitution for days and in
01-to-be/README.md alongside it. Both were found by a person looking. how-we-build §5 says
an unenforced rule is indistinguishable from a wrong one, and costs more, because people
believe it — this repository was carrying several.
Every check here failed on something real before it passed. A check that has never failed is indistinguishable from one that cannot.
| Check | Asserts | Found |
|---|---|---|
links |
every relative link resolves | — (run ad hoc during authoring; now permanent) |
rests-on |
decisions: and extends: name records that exist and are accepted |
the class behind both incidents |
live-citation |
a governing document citing a superseded record names its replacement in the same paragraph | 01-to-be/README.md citing ADR 0022 as live guidance |
supersession |
if A says it was superseded by B, B says it supersedes A | ADR 0012 never declared that it superseded 0011 |
numbering |
the number in the filename is the number in the heading | — |
topics |
every record names a topic of the reading order in 02-DECISIONS/README.md |
— |
| (index.py) | the reading order is written, every record's topic is one of it, and the README stores no list of records (ADR 0248) | a stored list made every two open decisions conflict (issue 297); it failed on the README of main before the list was removed |
status-vs-code |
a to-be document naming specific code is not still designed |
ten documents, several with a What was built section, describing lab-proven code |
What is deliberately not checked
02-DECISIONS/and01-RESEARCH/may cite superseded records freely. A decision record discusses history; research records what was observed. Flagging those would produce noise on correct documents, and a check that cries wolf gets suppressed — which costs more than not having it.03-DESIGN/00-as-is/may rest on a superseded record. It describes what runs, and what runs was built under whatever was decided at the time (ADR 0006: as-is describing a superseded decision is exactly what as-is is for).- Whether a citation's prose is still true. Only whether the record it points at is live. A document can cite an accepted record and describe it wrongly, and nothing here notices.
So "governing" means 00-META/ and 03-DESIGN/01-to-be/ — the documents that tell somebody
what to do.
Adding a check
State what incident it would have caught, and make it fail before you make it pass. A check whose failure has never been observed is a guess about its own correctness.
cycle.py
The development cycle, checked (ADR 0080):
a to-be design names a decision, an in-progress/implemented design names its owning code, a
located/fixed issue names its owner, a fixed/resolved issue says what fixed it, a graduated
research overview says what it became, and no two issue records share a number (issue 155 — the
number is how a record is cited, and main lags every open pull request, so two people reading it
allocate the same one). And a core issue — one opened from 2026-10-07 whose located-in names a core
repository — resolves only with replay: (an id in mesh-lab's replays register) or replay-none: saying
why none is possible (ADR 0237);
it failed on a resolved core issue carrying neither before it passed. And an accepted record that puts work
off — "until renamed", "left for later", "not decided here", "postponed", "future work", "deferred", "a later
change" — names the issue that tracks it, as tracking it ("tracked by issue N", or "issue N tracks"), in that
paragraph or list item, or in a dated progressive insight that speaks about it: one in the same section, or one
that quotes it. An issue cited for another reason tracks nothing, and one insight does not excuse every deferral
in a record. A rejected option is not work put off and is not held, judged by its ## section, so an option under a
### subheading of "Considered Options" is skipped too
(issue 354:
ADR 0244 deferred the code renames with no issue, and two days later the operator believed them done). Held to
it: a record dated from 2026-10-09, and an older one corrected under the rule. Measured from ADR 0244's date
it found deferrals without an issue in ADR 0241, 0244 and 0270; held from 2026-10-09 it failed on 0270 and 0273
(whose "not decided here" sits beside a citation of issue 340 that tracks none of it), and on 0244's four
deferral places once its insight brought it under the rule — on three of them while the insight, in §6, named
the issue without quoting them — before each named its issue (355, 357, 354). python3 00-META/checks/cycle.py
words.py
One word per thing, checked (ADR 0244).
It reads the glossary's Not: lines (the retired words, each with its scope) and Identifier until
renamed lines, and fails on a retired word or a bare identifier in running prose — what is left once code,
quotations, struck-through text, link targets, comments and frontmatter are taken out — in 00-META/,
03-DESIGN/, AGENTS.md, README.md, and research and issues dated from 2026-10-07. Decision records are
never checked. It also fails when a glossary head word heads two entries or is also retired.
words-allowed.md names a document that could not be reworded at once, with a date, or
a graduated research effort kept as written. With MESH_CATALOG_DIR set it compares the catalogue's copy
of the tools' retired words (retired-words) with the glossary.
It also fails on a daemon's line (ADR 0272,
its insight of 2026-10-09): the operator types one command, nox, and a document names a nox line, never the
controller's or the node-engine's binary followed by one of its commands. The lines are the check's own list
(DAEMON_LINES); a command that is a line only with an argument after it is matched as a line is written. Looked
for in the same documents, from 2026-10-09 for research and issues, in the document's own words — code blocks and
spans included, quotations and block quotes taken out. With MESH_CATALOG_DIR set it compares the catalogue's copy
(retired-lines) with the list.
It failed on something real before it passed: 581 uses of retired words in 63 documents on its first run, besides the glossary itself and research 034 —
"the host" for the node-engine in 30 designs, "control plane" in 10, the glossary's own entry for the tool runner —
and two glossary contradictions (the "console", the deprecated broker's seat), fixed in the change that
added it. A retired word's plural (s or es on its last word) is matched as the word: until 2026-10-07
it was not, so "alerts", "rollouts" and "the hosts" (the node-engines) passed while their singulars
failed; the plural failed on 15 uses in 10 documents before it passed. A verb that reads like a plural
("a node hosts") is a finding too, and is reworded. Homonyms (plan, gate, tier, ask, store, record, check) are not checked by it: a
word list cannot tell one sense from another, so they are reviewed.