The operator, 2026-10-16: research defines the modules a feature lands in and the domain extensions and reductions that come with it.
164 lines
11 KiB
Markdown
164 lines
11 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
|
|
|
|
The effort's `05-direction.md`, confirmed by the operator (playbook [01](01-research.md), step 7), is what
|
|
graduates. The lead writes the records and the design on the larger model; it is one sitting, bounded at
|
|
about an hour, and said to the operator if it runs past.
|
|
|
|
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 decisions** (below, *Writing a decision record*): one record per choice that could be
|
|
reversed on its own, not one record for the whole effort.
|
|
- **Write them together, not one after another.** Reserve every number first, then propose each record
|
|
as soon as it is written, without waiting for the review of the one before; the reviews run side by
|
|
side, and the operator's asks for the records that need them arrive together. A record that
|
|
`rests-on` or `extends` a sibling is proposed once that sibling is accepted.
|
|
- **Take the clauses from the confirmed direction** and cite the effort (`cites`, `"research NNN"`) for
|
|
the evidence instead of retyping its findings: a record's Context holds the few facts its decision
|
|
rests on, with the effort named for the rest.
|
|
- **Pre-check each record before proposing it**, as for research (playbook [01](01-research.md), step
|
|
5): every record, issue or design it names is in `links`; each deferral names its issue; each figure
|
|
is given as measured; no word on a glossary *Not:* line.
|
|
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"
|
|
---
|
|
```
|
|
|
|
The design lists the direction's acceptance tests: what the build proves before it is done.
|
|
|
|
The words of the effort's `03-domains.md` go into the glossary in the same change, each in its domain: a
|
|
word added gets its entry, a word whose meaning changed gets its entry rewritten, and a retired word moves to
|
|
its replacement's *Not:* line. A word that already means something else in another domain is named as a
|
|
homonym with the qualified form each domain uses.
|
|
|
|
4. **Hand it to the work breakdown.** The design goes on through playbook [04](04-build-handoff.md):
|
|
milestones, issues, and each milestone built as one feature step (playbook [07](07-feature-branches.md)).
|
|
5. **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`;
|
|
at most three rounds, then the findings go to the operator with a recommendation.
|
|
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. 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.
|