mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
ADR 0290 rule 9: once the import is checked record by record, hq keeps no copy. The records and efforts are removed; every link or path to them reads "ADR NNNN" or "research NNN"; a design's decisions: lists "ADR NNNN". 02-DECISIONS keeps a pointer README with the reading order's six topics, which the knowledge base reads through the records module; 01-RESEARCH keeps a pointer README. The checks drop the rules that judged records (the knowledge base holds each at propose; checks/README.md says where) and refuse a record written here again. Playbooks 01 and 02 and the skills write and read records with the knowledge base's verbs.
117 lines
9.9 KiB
Markdown
117 lines
9.9 KiB
Markdown
# Checks
|
|
|
|
```
|
|
python3 00-META/checks/records.py structure: links, no record written here, citations in the form "ADR NNNN"
|
|
python3 00-META/checks/index.py the reading order's topics are written, and no list of records is stored
|
|
python3 00-META/checks/cycle.py the development cycle: a design's layer, status, decisions and code; an issue report's frontmatter
|
|
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) |
|
|
| `no-records` | `02-DECISIONS/` and `01-RESEARCH/` hold their README and nothing else: a decision record or research effort lives in the knowledge base (ADR 0290 rule 9) | written with the change that removed the records (issue 426); it failed on a record file put back in `02-DECISIONS/` before it passed |
|
|
| `decisions-form` | every entry of a design's `decisions:` is "ADR NNNN", four digits | written with issue 426; it failed on an entry `ADR 290` before it passed |
|
|
| `mention-form` | every "ADR N" in the text has four digits, and every "research N" three; a code span is an example and is not read | written with issue 426; it failed on `ADR 12` and `research 45` before it passed |
|
|
| *(index.py)* | the reading order's six topics are written in `02-DECISIONS/README.md`, none twice, and the README stores no list of records (ADR 0248). The knowledge base reads these lines and refuses a record whose topic is not one of them | a stored list made every two open decisions conflict ([issue 297](../../04-ISSUES/297-two-open-decisions-always-conflict/00-report.md)); 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 |
|
|
|
|
## Where the rules on records went
|
|
|
|
The decision records and research efforts left this repository for the knowledge base (ADR 0290, issue 426),
|
|
and the rules these checks held over them left with them. The knowledge base holds each as a rule of its own,
|
|
named in its refusal: `knowledge-base.propose` refuses a record that breaks one of the rules that judge one
|
|
record, naming every reason at once, and the four rules that judge the whole record set run after every
|
|
acceptance and raise a condition when one fails (mesh-knowledge's `rules.go`, one table-test case per rule).
|
|
|
|
| Rule here until issue 426 | Where it lives now |
|
|
|---|---|
|
|
| `records.py` `rests-on`, for a record's `extends:` | the knowledge base's `rests-on` at propose, and the whole-set rule `rests-on-live` |
|
|
| `records.py` `rests-on`, for a design's `decisions:` naming an accepted record | **nowhere yet**: this repository cannot read the knowledge base. The reviewer checks each new entry with `knowledge-base.get`. Designs become the knowledge base's own kind under issue 428 |
|
|
| `records.py` `live-citation`, in a record | the knowledge base's `live-citation` |
|
|
| `records.py` `live-citation`, in `00-META/` and `03-DESIGN/01-to-be/` | **nowhere yet**, as above: the reviewer checks a cited record's status with `knowledge-base.get`; issue 428 |
|
|
| `records.py` `supersession` | the knowledge base's `supersedes-accepted` and `self-link`, and the whole-set rule `supersession` |
|
|
| `records.py` `partial-supersession` | the knowledge base's `changes` link to a clause, `changes-in-force` and `supersedes-accepted`, and the whole-set rule `partial` |
|
|
| `records.py` `clauses` | the knowledge base's `has-clause`, `clause-numbering`, `clause-lead` and `clause-size` |
|
|
| `records.py` `numbering` | the knowledge base's `title` and `reserved` |
|
|
| `records.py` `topics`, `index.py` (a record's topic) | the knowledge base's `topic`, against the reading order `index.py` still checks |
|
|
| `records.py` `insights` | the knowledge base's `insight-form`; an accepted record changes by a new version marked as a progressive insight |
|
|
| `index.py --print` | `knowledge-base.holds` with a topic |
|
|
| `cycle.py` research: a known status, `became:` when graduated | the knowledge base's `research-status`, `overview` and `became` |
|
|
| `cycle.py` no two decision records share a number | the knowledge base's `reserved`, and the issue tracker's counter behind `knowledge-base.reserve` |
|
|
| `cycle.py` an accepted decision cited by nothing | the knowledge base's whole-set rule `cited`: a record accepted there is cited by another record or names a home (`homes` at propose) |
|
|
| `cycle.py` a deferral names the issue that tracks it | the knowledge base's `deferral` |
|
|
| `words.py` over research efforts from 2026-10-07, and `kept` in `words-allowed.md` | the knowledge base's `retired-word` and `daemon-line`, from this glossary |
|
|
|
|
## What is deliberately not checked
|
|
|
|
- **Whether a record a document cites exists, or is still accepted.** A checkout cannot read the knowledge
|
|
base, and a check that called the mesh would make every merge here depend on it. Until designs become the
|
|
knowledge base's own kind (issue 428), the reviewer asks `knowledge-base.get` for each record a change
|
|
cites in `00-META/` or `03-DESIGN/01-to-be/` (the documents that tell somebody what to do). An as-is
|
|
document 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.** A document can cite an accepted record and describe it
|
|
wrongly, and nothing here notices.
|
|
|
|
## 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):
|
|
every design parses, its `layer:` matches its folder and its `status:` is known; a to-be design names a
|
|
decision in `decisions:`; an in-progress or implemented design names its owning code; 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). An issue report carries the day it was `opened:`
|
|
and no status key — `status:`, `located-in:`, `fixed-by:`, `amended-design:`, `replay:`, `replay-none:` or
|
|
`resolved:` — because an issue's status lives in the issue tracker (ADR 0275); it failed on all 361 reports
|
|
that carried them before they were removed. The rules on an issue's status this check held until then — an
|
|
owner for a located issue, a fix for a resolved one, and a core issue's `replay` or `replay-none` (ADR 0237)
|
|
— are refused at the write by `issue-tracker.move`. Its rules on research efforts and decision records left
|
|
with them (the table above). `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 issues opened from 2026-10-07. Decision records and research
|
|
efforts live in the knowledge base, which holds a proposed record to the same words (the table above). It
|
|
also fails when a glossary head word heads two entries or is also retired.
|
|
[`words-allowed.md`](words-allowed.md) names a document that could not be reworded at once, with a date. 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 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.
|