Files
hq/00-META/process/02-graduation.md
T
jschoubben 418261213c
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
Remove the decision records and research efforts, which the knowledge base now holds whole (issue 426)
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.
2026-10-11 12:56:09 +02:00

8.6 KiB

Playbook 02 — Graduation and design change

Trigger. A research effort concludes, or an existing design must change.

Who runs it. Anyone, with the decision recorded before the design moves.

Where a decision lives. A decision record lives whole in the knowledge base, the seat knowledge-base, reached through the mesh MCP server from any node and any folder (ADR 0290): its number, title, topic, status, date, deciders, its clauses, its typed links, its reasoning and every version. This repository holds none, and keeps no copy. What was decided is read with knowledge-base.ask (a question in plain words), knowledge-base.get (one record by number; reasoning: true for its why) and knowledge-base.holds (the clauses in force for a topic or a record).

Graduating research

  1. Check it against GENESIS. An effort graduates only if its conclusion is traceable to mission.md, context.md and effect.md. If it conflicts, either the effort is wrong or GENESIS is — say which, in writing, before proceeding.

  2. Record the decision (below, Writing a decision record).

  3. Write the design. Create the document under 03-DESIGN/01-to-be/ with frontmatter:

    ---
    layer: to-be
    status: designed
    code: []             # owning code repo(s); set at build handoff, empty before
    updated: YYYY-MM-DD
    decisions:
      - "ADR NNNN"
    ---
    
  4. Close the effort. knowledge-base.propose the effort again, whole, with status: graduated and a became link to the decision record ("NNNN") and to the design document (its path). An effort that stops without a decision is proposed with status: abandoned and a became link to what replaced it.

Writing a decision record

  1. Take a number. knowledge-base.reserve with kind: decision and for: the record's title. The number comes from the issue tracker's counter and is spent whether or not the record is accepted; one never proposed is withdrawn after a week. Never pick a number by hand.

  2. Propose it. knowledge-base.propose with the number, a one-line title in plain language, its topic (one of the six of the reading order, 02-DECISIONS/README.md), date (when the decision was taken, not when it was written down), deciders, and:

    • clauses: what was decided, in order, each one statement opening with a bold lead ("**What is decided.** …");
    • sections: the reasoning, in order: Context (what was true, with evidence), Considered Options (numbered, each with why it was rejected), Consequences (what follows, including what got harder), How it is checked (a rule states how it is checked), References;
    • links: extends for a record it builds on, supersedes for one it replaces whole, changes with the clause it replaces part of ("0276 §4", and from for the clause of this record that does it), cites for any record, effort, issue or design it names;
    • homes: the documents of this repository that cite it, such as the design's path;
    • needs-operator: true when it holds only once the operator approves it.

    State evidence, not assertion. "Zero of 124 modules declare brain as a dependency" outranks "the dependency rule is not followed". Record the options that were rejected — that is the half worth keeping.

  3. A record that puts work off — a rename, a check, a case it does not handle — names the issue that tracks it, in the sentence that defers it ("tracked by issue N"), or the deferral is not accepted: a deferral nothing tracks reads as done (issue 354, ADR 0244's code renames). propose refuses it (rule deferral).

  4. Review and acceptance. propose refuses, naming every reason at once and writing nothing, a record that breaks one of the rules that judge one record: a link to nothing, a clause without a bold lead, a superseded record cited alone, an unknown topic, a retired word of the glossary, a daemon's line, a deferral no issue tracks. The knowledge base then reviews the proposal itself, through a judgement that sees only the record, the records it links and the rules, and answers approve or changes. On changes the record stays proposed with the findings: revise it by proposing it again, whole, with why. On approve it is accepted, or, when it says needs-operator, it waits for the operator's Approve on a channel that proves who answered. Nothing proposed is in force. knowledge-base.get shows a record's reviews and the operator's ask when it waits for one.

Changing a decision

A record's meaning is never rewritten. A decision is changed by a new record, and a correction of fact by a progressive insight.

  • Reversing a decision, changing its scope, rejecting an option it accepted, or making a consequence false that a later record cites is a new record that supersedes the old one whole, or changes the clauses it replaces. On its acceptance the old record or clauses become superseded or changed, and every answer says by what. The test is not how large the edit looks; it is whether a reader who acted on the old text would now be wrong about what was decided rather than about a detail the decision did not rest on.
  • A progressive insight corrects a fact a record asserted that turned out wrong while the decision it supports stays right: a count taken before anyone measured, a file named that does not exist. It is knowledge-base.propose of the accepted record with insight: what was found, what the record said before, and what it says instead. It is a new version, marked as one, dated, and reviewed like a proposal; it adds and never quietly replaces; the decision, the options weighed and the consequences stand untouched. If the correction changes what was decided, it is not an insight — write the new record.
  • Where a later record changes the mechanism an older one states without reversing it, the later record changes the older one's clause, so a reader who arrives at the older record by a citation sees what changed it since.

Amending an existing design

A design changes only through a decision.

  1. Write the decision record (above). If it reverses an earlier one, it supersedes it.
  2. Edit the to-be design document, add the record to its decisions: as "ADR NNNN", and set updated: to today.
  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).

When something ships

Implementation state is a third axis, independent of both design and decision.

  1. Write or update the matching document under 03-DESIGN/00-as-is/ so it describes what now runs — including anything that shipped differently from the intent. A design that shipped bent is an as-is fact, not a design amendment.
  2. Set the to-be document's status: implemented and its code: to the owning repositories from repos.md.
  3. status: implemented must be defensible from the owning repository's main branch, not from intent. If it cannot be checked, it is in-progress.

Do not

  • Do not move a to-be document into 00-as-is/. Write the as-is document; both stand.
  • 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 under 02-DECISIONS/ other than its README.

How it is checked

The rules on a record are the knowledge base's: propose refuses one that breaks a rule that judges one 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 order's six topics, which the knowledge base reads.