Files
hq/00-META/process/02-graduation.md
T
jschoubben 0afc8cc5f8
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 delivered
Name the commit the knowledge base's records now come from, and link research with touches and decisions with rests-on (review of #312)
2026-10-11 13:25:21 +02:00

137 lines
8.6 KiB
Markdown

# 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`](../mission.md), [`context.md`](../context.md) and
[`effect.md`](../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:
```yaml
---
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`](../../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, `rests-on` for a decision it stands 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](../../04-ISSUES/354-a-decided-rename-was-never-scheduled-and-the-operator-believed-it-live/00-report.md),
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`](../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.