137 lines
8.6 KiB
Markdown
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.
|