Merge pull request 'R4g finish: hq's checks as Go tests, the old word struck, the marker (issues 1296, 1935)' (#473) from feat/r4g-finish into main

Reviewed-on: #473
This commit was merged in pull request #473.
This commit is contained in:
2026-10-24 20:56:42 +00:00
24 changed files with 115 additions and 982 deletions
+3 -3
View File
@@ -67,11 +67,11 @@ A drawn overview of them, the cycle, a feature's steps, the review loop and an i
## The cycle is checked
The flow above is a rule, and a rule states how it is checked:
[`00-META/checks/cycle.py`](../checks/cycle.py) refuses a to-be design that names no
the cycle test in [`00-META/checks/`](../checks/) refuses a to-be design that names no
decision, an `in-progress`/`implemented` design that names no owning code, two issue folders
sharing a number or an issue report carrying a status key; a `graduated` research effort that
does not say what it became is refused by the knowledge base's `propose` (ADR 0290). Run it with `records.py`, `index.py` and
`words.py` before any HQ merge (`go test ./...` at the root runs all four as Go tests, and `sh merge-check.sh` runs the Python ones until the delivery of R4g is done: ADR 0527). The issue rules the check
does not say what it became is refused by the knowledge base's `propose` (ADR 0290). Run it with the records, index and
words tests before any HQ merge: `go test ./...` at the root runs all four, and the checker runs the same as `mesh/check` (ADR 0527). The issue rules the check
once held — `located` with an owner, `resolved` with a fix, a core issue with its replay — are
refused at the write by the issue tracker's `move`
(ADR 0275). What the checks cannot see — that code work actually started from a
+2 -2
View File
@@ -119,7 +119,7 @@ for the operator's Approve on a channel that proves who answered.
- Do not put status in prose. It is the effort's `status`, and the prose must not restate it.
- Do not give a `became` link while the effort is open — playbook 02 gives it at closure.
- Do not write into `03-DESIGN` from an open effort.
- Do not write an effort, or a copy of one, into this repository: `records.py` refuses a new path under
- Do not write an effort, or a copy of one, into this repository: the records test refuses a new path under
`01-RESEARCH/`.
## Closing
@@ -136,5 +136,5 @@ after every acceptance and raise a condition when one fails. The habits of steps
against the rules, one version per settled set, the cheapest level, nothing left open) are the lead's, read by
the reviewer; of the pre-check, `propose` refuses a link to nothing and a retired word, and the review returns
a record named but not linked, an untracked deferral and a figure not as measured. That this repository holds
no effort is `records.py`'s `no-records` check, on every pull request. An active effort with no new version
no effort is the records test's `no-records` check, on every pull request. An active effort with no new version
for seven days is the smell of research left behind: its lead closes or continues it.
+3 -3
View File
@@ -153,7 +153,7 @@ Implementation state is a third axis, independent of both design and decision.
- Do not edit an as-is document to describe an intention. That is what the to-be layer is for.
- Do not change a decision record's meaning. Supersede it. Correcting a fact it got wrong, while
the decision stands, is a progressive insight — marked and dated in the record, never silent.
- Do not write a decision record, or a copy of one, into this repository: `records.py` refuses a new path
- Do not write a decision record, or a copy of one, into this repository: the records test refuses a new path
under `02-DECISIONS/` other than its README.
## How it is checked
@@ -162,8 +162,8 @@ The rules on a record are the knowledge base's: `propose` refuses one that break
record (its module's table test holds one case per rule), and the four rules that judge the whole record set
(an accepted decision cited by nothing, a supersession named by one side only, a changed clause nothing
changes, an accepted record extending a superseded one) run after every acceptance and raise a condition
when one fails. In this repository, `records.py` checks that a design's `decisions:` entries and every
"ADR NNNN" in the text are well formed, and that no record is written here; `index.py` checks the reading
when one fails. In this repository, the records test checks that a design's `decisions:` entries and every
"ADR NNNN" in the text are well formed, and that no record is written here; the index test checks the reading
order's six topics, which the knowledge base reads. The three habits of graduating step 2 (side by side, clauses
from the direction, the pre-check) are the lead's, read by the reviewer; `propose` refuses a link to nothing,
a deferral no issue tracks and a retired word, and the review returns a record named but not linked.
+3 -3
View File
@@ -66,7 +66,7 @@ import read, which every imported issue names (`imported.commit` in `issue-track
```
Then `# NNN. The title`, the title as the tracker holds it, and the symptom as observed, as in the tracker's
report. **No status key**: `cycle.py` refuses `status:`, `located-in:`, `fixed-by:`, `amended-design:`,
report. **No status key**: the cycle test refuses `status:`, `located-in:`, `fixed-by:`, `amended-design:`,
`replay:` or `replay-none:` in any report, because the tracker holds them and two places holding one fact
drift.
@@ -107,7 +107,7 @@ import read, which every imported issue names (`imported.commit` in `issue-track
it, pointing at the new issue. Somebody arriving at a record to learn why the code is the way it
is must not have to already know there was a sequel.
- A number never moves. A folder carries the number the tracker gave; a folder whose number collides with
another (one numbered before the tracker, or by hand) is a fault, and `cycle.py` refuses two records
another (one numbered before the tracker, or by hand) is a fault, and the cycle test refuses two records
sharing a number.
- An issue whose answer is a general lesson should also have that lesson written where a search by
the symptom's literal words finds it, so the next person searching it finds it. Both, not either.
@@ -117,6 +117,6 @@ import read, which every imported issue names (`imported.commit` in `issue-track
- **A rule states how it is checked.** The cycle's rules on an issue — a status one of the six, `diagnosing` and
`fixing` with a worker and no other current one, `located` with an owner, `resolved` only from `fixing` and with a
fix, a core issue with its replay, `wontfix` with a reason — are refused at the write by
`issue-tracker.move` (mesh-catalog `modules/mesh-issues`, its table test over the rules). `cycle.py` checks what
`issue-tracker.move` (mesh-catalog `modules/mesh-issues`, its table test over the rules). the cycle test checks what
this repository still holds: no two folders share a number, every report has frontmatter with the day it was
`opened:`, and no report carries a status key.
+1 -1
View File
@@ -66,7 +66,7 @@ A design becomes **milestones**, and each milestone becomes **issues**:
## How it is checked
Read by the lead and the reviewer today; a check in hq's merge-check is tracked by issue 845.
Read by the lead and the reviewer today; a check among hq's Go tests is tracked by issue 845.
- A design in `status: in-progress` has a *Milestones* section, each milestone with its outcome and its
issues; an in-progress design without one is the smell of building without a breakdown.
+3 -3
View File
@@ -421,7 +421,7 @@ const P = [
prod:"A research effort in the knowledge base, status active, every version kept. Nothing in hq.",
next:"02",bounds:"Setup 30 min · proposing 15 min · each experiment 30 min · direction 30 min · report every 10 min",
prev:["Research that measured nothing","A recommendation the operator must argue back","Efforts copied into hq"],
check:"propose refuses rule breaks; the knowledge base reviews; records.py on every PR."},
check:"propose refuses rule breaks; the knowledge base reviews; the records test on every PR."},
{n:"02",name:"Graduation & design change",kind:"idea",c:"--dec",
trig:"A research effort concludes, or an existing design must change.",
who:"The lead, on the larger model; the decision is recorded before the design moves.",
@@ -429,7 +429,7 @@ const P = [
prod:"Decision records; a to-be design with frontmatter; glossary entries; later the as-is.",
next:"04",bounds:"One sitting of about an hour",
prev:["A decision rewritten silently","A deferral nothing tracks","A design amended without a decision"],
check:"propose refuses; records.py and index.py; set-wide rules raise conditions."},
check:"propose refuses; the records and index tests; set-wide rules raise conditions."},
{n:"03",name:"Issues",kind:"symptom",c:"--sym",
trig:"Something is wrong: an unenforced rule, a stated behaviour that does not happen, a silent failure.",
who:"Anyone opens; a worker claims it by moving it.",
@@ -437,7 +437,7 @@ const P = [
prod:"A tracker record with notes and links; for a design issue, its narrative folder in hq.",
next:"02 · 07 · 08",bounds:"A worker idle for a day is stale",
prev:["Numbers that collide","Two agents starting the same work","Status held in two places"],
check:"The tracker's move refuses at the write; cycle.py checks the folders."},
check:"The tracker's move refuses at the write; the cycle test checks the folders."},
{n:"04",name:"Work breakdown & handoff",kind:"idea",c:"--dec",
trig:"A to-be design is settled and its building is about to start.",
who:"The lead who will run the feature, on the larger model.",