diff --git a/00-META/process/01-research.md b/00-META/process/01-research.md index a4118093..c1afd96f 100644 --- a/00-META/process/01-research.md +++ b/00-META/process/01-research.md @@ -30,6 +30,15 @@ An idea arrives in one of two forms, and the first step differs: 2. **Ask the operator to set it up.** A few questions, one at a time, each answerable with a choice and carrying a recommendation: what comes first, what is out of scope, which options must be tried, what done looks like. Three to five questions is usual; the answers are the effort's first findings. + - **Check every option against the mesh's own rules before offering it.** An option that breaks one + (the core values in [`mission.md`](../mission.md), among them *the mesh owns the truth* and + *sovereignty: external dependencies are deliberate and few*; the rules in + [`how-we-build.md`](../how-we-build.md); and everything between modules over the bus, research 036) is + dropped, or offered only with the rule it breaks named. A recommendation the operator has to argue back + costs a version. + - **Explain each question with a concrete picture** in the operator's words: what they would see, do or + lose under each option. No internal names (a record number, a verb, a word the glossary lacks) without + what it is beside it. 3. **Take a number.** `knowledge-base.reserve` with `kind: research` and `for`: the effort's title. The number is spent whether or not the effort is ever proposed; one never proposed is withdrawn after a week. Never pick one by hand. @@ -48,10 +57,25 @@ An idea arrives in one of two forms, and the first step differs: lists them and gives the difference between two. Until issue 844 is delivered, the knowledge base takes a new version of an accepted, active effort only as a progressive insight: give `insight`, saying what the effort held before the new finding, and mark the finding in the text with its date. + - **Propose a version per settled set, not per answer.** While the operator answers a run of questions, + or while experiments run, keep the answers and findings in the session's save point and propose once + when the set is settled. Each version is reviewed and resent whole, so a version per answer multiplies + the reviews. + - **Pre-check before proposing**, against what the review sends back most: every record, issue or design + the text names is in `links`; work put off names the issue that tracks it (an acceptance test is not + put-off work: it is what the build proves, step 6); each figure is given as measured (a range, not a + rounded claim); no word on a glossary *Not:* line. + - **Try at the cheapest level that answers the question.** A program's own behaviour (a library, a + server, a protocol) is tried in process, on the machine's loopback, in minutes. Lab runs (about 12 to + 16 minutes fresh) are for the mesh's own code; before that code exists, a lab run tests nothing an + in-process test does not, and its lab scenario is written as the build's acceptance test instead. 6. **Settle the direction with the operator.** When the questions are answered, write `05-direction.md`: - the proposed decisions in a few lines each, the options rejected and why, what is left open. Ask the - operator to confirm or change it, one point at a time. Then the effort graduates through playbook - [02](02-graduation.md). + the proposed decisions in a few lines each, the options rejected and why, and the build's acceptance + tests: what the build must prove before it is done, carried by its milestones (playbook + [04](04-build-handoff.md)). Nothing else is left open: each question closes by a test, by a decision the + effort records with its reason (a small design limit is the lead's), or by the operator. Ask the + operator to confirm or change the direction, one point at a time, then propose it once. Then the effort + graduates through playbook [02](02-graduation.md). ## Bounds and models @@ -100,6 +124,9 @@ and why, is the more expensive half to rediscover. The rules on an effort are the knowledge base's: `propose` refuses one that breaks a rule that judges one record (the module's table test holds one case per rule), and the rules that judge the whole record set run -after every acceptance and raise a condition when one fails. That this repository holds no effort is -`records.py`'s `no-records` check, on every pull request. An active effort with no new version for seven -days is the smell of research left behind: its lead closes or continues it. +after every acceptance and raise a condition when one fails. The habits of steps 2, 5 and 6 (options checked +against the rules, one version per settled set, the cheapest level, nothing left open) are the lead's, read by +the reviewer; of the pre-check, `propose` refuses a link to nothing and a retired word, and the review returns +a record named but not linked, an untracked deferral and a figure not as measured. That this repository holds +no effort is `records.py`'s `no-records` check, on every pull request. An active effort with no new version +for seven days is the smell of research left behind: its lead closes or continues it. diff --git a/00-META/process/02-graduation.md b/00-META/process/02-graduation.md index 61587959..ad224c30 100644 --- a/00-META/process/02-graduation.md +++ b/00-META/process/02-graduation.md @@ -23,6 +23,16 @@ about an hour, and said to the operator if it runs past. 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 @@ -36,6 +46,8 @@ about an hour, and said to the operator if it runs past. --- ``` + The design lists the direction's acceptance tests: what the build proves before it is done. + 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 @@ -141,4 +153,6 @@ record (its module's table test holds one case per rule), and the four rules tha 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. +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. diff --git a/00-META/process/04-build-handoff.md b/00-META/process/04-build-handoff.md index 40eff9cb..864c6438 100644 --- a/00-META/process/04-build-handoff.md +++ b/00-META/process/04-build-handoff.md @@ -28,10 +28,11 @@ A design becomes **milestones**, and each milestone becomes **issues**: there; if it is not, write it before changing it. Building against an undocumented as-is is how a shipped behaviour gets lost. 4. **Break it into milestones.** Write them into the design, in a section *Milestones*: for each, its number, - its one-sentence outcome, the repositories it touches, and what it depends on. Order them so each is - usable as soon as it is delivered, the smallest useful one first. -5. **Ask the operator to confirm the milestones**, in a short table: number, outcome, repositories, the - parts each repository builds. Change what they change. + its one-sentence outcome, the acceptance tests of the design it proves, the repositories it touches, and + what it depends on. Order them so each is usable as soon as it is delivered, the smallest useful one + first. +5. **Ask the operator to confirm the milestones**, in a short table: number, outcome, the acceptance tests it + proves, repositories, the parts each repository builds. Change what they change. 6. **Open the issues.** For each confirmed milestone, `issue-tracker.open` one issue per repository part, its title the symptom or capability in plain words, its report naming the design, the milestone and the decisions it builds with; link the order with `depends-on`. Write the issue numbers into the milestone's @@ -61,5 +62,5 @@ Read by the lead and the reviewer today; a check in hq's merge-check is tracked issues; an in-progress design without one is the smell of building without a breakdown. - Every issue a milestone names exists in the tracker (`issue-tracker.get`), and an issue in `fixing` names its milestone in its report. -- A milestone whose issues are all `resolved` has had its delivery plan done; its outcome sentence is proven on - the mesh before the next milestone starts. +- A milestone whose issues are all `resolved` has had its delivery plan done; its outcome sentence and + acceptance tests are proven on the mesh before the next milestone starts.