Issue reports carry only opened: the tracker holds every status, so no copy can drift
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered

The import of slice 3 (ADR 0275) was checked against every folder: no report changed since the
commit it read, and the tracker holds each report's status, owner, fix, design amendment, replay
and closing day. The keys are removed from all 361 reports, cycle.py refuses them in any report,
and the playbooks, skills and READMEs that still pointed at them name the tracker instead.
This commit is contained in:
jochen
2026-10-10 17:44:18 +02:00
parent d82dde3dca
commit daa9f171ae
374 changed files with 71 additions and 1660 deletions
+8 -6
View File
@@ -55,14 +55,16 @@ whose failure has never been observed is a guess about its own correctness.
## cycle.py
The development cycle, checked ([ADR 0080](../../02-DECISIONS/0080-the-development-cycle-is-checked.md)):
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
a to-be design names a decision, an in-progress/implemented design names its owning code, 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](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md));
it failed on a resolved core issue carrying neither before it passed. And an accepted record that puts work
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](../../02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md));
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](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md))
— are refused at the write by `issue-tracker.move`. 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
+12 -13
View File
@@ -17,10 +17,11 @@ What is enforced:
tracker since the import of slice 3 (ADR 0275, to-be 53), where `issue-tracker.move`
refuses at the write what this check refused at merge until then: a status outside
the five, `located` without an owner, `resolved` without a fix, a core issue
resolved without its replay (ADR 0237), `wontfix` without a reason. A report opened
after the import carries none of those keys -- the tracker holds them, and two
places holding one fact drift. The reports opened before keep theirs as the dated
snapshot the import took; they are not judged, and not kept up to date.
resolved without its replay (ADR 0237), `wontfix` without a reason. A report
carries none of those keys, only the day it was `opened:` -- the tracker holds
them, and two places holding one fact drift. The keys the reports opened before
the import carried were removed once the import held them; the commit it read
is on every imported issue.
research a known `status:`; a `graduated` overview says what it `became:`, and every
target it names exists.
decisions every accepted record is REACHABLE from the cycle: cited by a design doc's
@@ -44,12 +45,10 @@ ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))
DESIGN_STATUSES = {"proposed", "designed", "in-progress", "implemented", "abandoned"}
RESEARCH_STATUSES = {"active", "graduated", "abandoned"}
# The keys an issue report carried while its status lived here, and the day from which a report carries
# none of them: the issue tracker holds them (ADR 0275, slice 3 of to-be 53), and `issue-tracker.move`
# enforces the cycle's rules on them at the write. A report opened on or after this day with one of these
# keys is a status written in two places. The reports opened before keep theirs as the import's snapshot.
STATUS_IN_TRACKER_FROM = "2026-10-11"
TRACKER_KEYS = ("status", "located-in", "fixed-by", "amended-design", "replay", "replay-none")
# The keys an issue report carried while its status lived here. The issue tracker holds them now (ADR 0275,
# slice 3 of to-be 53), and `issue-tracker.move` enforces the cycle's rules on them at the write. A report
# carrying one of them is a status written in two places, whenever it was opened.
TRACKER_KEYS = ("status", "located-in", "fixed-by", "amended-design", "replay", "replay-none", "resolved")
# A decision that defers work names the issue that tracks it (issue 354). ADR 0244 left the code
# renames of the node-engine and the tool runner "for a later rename", with no issue, owner or date;
@@ -227,8 +226,8 @@ def main():
seen_records[number] = name
# Since the import of slice 3 (ADR 0275), an issue's status, owner, fix and replay live in the issue
# tracker, and its `move` refuses at the write what this check refused at merge. A report opened from
# STATUS_IN_TRACKER_FROM carries none of those keys; one opened before keeps the import's snapshot.
# tracker, and its `move` refuses at the write what this check refused at merge. A report carries none
# of those keys.
for path in sorted(glob.glob(os.path.join(ROOT, "04-ISSUES", "*", "00-report.md"))):
front = frontmatter(path)
if front is None:
@@ -239,7 +238,7 @@ def main():
bad(path, "opened: says nothing -- the day the issue was opened, YYYY-MM-DD")
continue
carried = [key for key in TRACKER_KEYS if key in front]
if opened >= STATUS_IN_TRACKER_FROM and carried:
if carried:
bad(path, "carries %s, but an issue's status, owner, fix and replay live in the issue tracker "
"(ADR 0275): move it with `issue-tracker.move`, and keep no copy here"
% ", ".join("`%s:`" % key for key in carried))
+4 -2
View File
@@ -45,8 +45,10 @@ A design changes only through a decision.
corrected in place and marked in the record rather than superseded
([`02-DECISIONS/README.md`](../../02-DECISIONS/README.md)).
2. Edit the to-be design document and set `updated:` to today.
3. If the amendment came from an issue, set that issue's `amended-design:` to the document
path.
3. If the amendment came from an issue, give the issue the document path in the issue tracker:
`amended-design` on its `issue-tracker.move` to `resolved`, or `issue-tracker.link` with kind
`design` before then — never in the report's frontmatter
([ADR 0275](../../02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md)).
## When something ships
+13 -10
View File
@@ -38,12 +38,15 @@ An issue takes one of two shapes:
reviewed in a pull request. The folder holds the report and the diagnosis; the tracker holds everything else.
- **Wholly in the tracker** — every other issue. Nothing is written here.
**The reports written before the tracker** (the folders numbered 001 to 364) still carry `status:`, `located-in:`,
`fixed-by:`, `amended-design:`, `replay:` and `replay-none:` in their frontmatter. Those keys are the snapshot the
import of slice 3 took from `main` on the day it ran (the note in ADR 0275 says which day and which commit), and
they are not kept up to date: the tracker is. They are left in place because they are the record of what was known
then, reviewed in pull requests at the time, and because removing 361 keys would say nothing the tracker does not.
Nobody edits them.
**`04-ISSUES/` stays, for the narrative only.** It keeps the public narrative of a design or governance issue: the
symptom as observed, the diagnosis, what was ruled out, and why. A plain bug — a defect whose fix needs no design
question answered — needs no folder; it is whole in the tracker.
**The reports written before the tracker** (the folders numbered 001 to 364) carried `status:`, `located-in:`,
`fixed-by:`, `amended-design:`, `replay:` and `replay-none:` in their frontmatter until the import of slice 3 had
taken them into the tracker and been checked against it, field by field; then one pull request removed them, so
that no status is held in two places. What they said that day is in this repository's history at the commit the
import read, which every imported issue names (`imported.commit` in `issue-tracker.get`).
## Steps
@@ -64,8 +67,8 @@ Nobody edits them.
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:`,
`replay:` or `replay-none:` in a report opened after the import, because the tracker holds them and two places
holding one fact drift.
`replay:` or `replay-none:` in any report, because the tracker holds them and two places holding one fact
drift.
**An issue wholly in the tracker** is done at this step.
2. Investigate. The trail goes in `issue-tracker.note`, and, for a folder-backed issue, in `01-diagnosis.md` in the
@@ -97,5 +100,5 @@ Nobody edits them.
- **A rule states how it is checked.** The cycle's rules on an issue — a status one of the five, `located` with an
owner, `resolved` 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
this repository still holds: no two folders share a number, every report has frontmatter, and a report opened
after the import carries no status key.
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.