Research 045 findings: serve the record as answers, keep review for what governs, and give light records a home
This commit is contained in:
@@ -21,8 +21,13 @@ became: []
|
||||
## What
|
||||
|
||||
Whether the mesh should **write** its own knowledge (decision records, guidelines, policies, designs and
|
||||
playbooks) through a module's verbs, instead of only **reading** hand-written markdown. The effort
|
||||
frames the questions below and answers none of them yet; the research itself is done separately.
|
||||
playbooks) through a module's verbs, instead of only **reading** hand-written markdown, and whether it
|
||||
should hold light content beside them: meeting notes, architectural drawings and blog posts.
|
||||
|
||||
The operator's purpose, given on 2026-10-11: the record becomes **shared knowledge that agents reach
|
||||
through tools**, so that an agent gets what was decided as an answer instead of reading markdown files,
|
||||
and a session no longer has to start in this repository's folder to know it. A session still starts here
|
||||
for other work, such as writing a record.
|
||||
|
||||
Today the record is read-only. The `records` module reads this repository and serves it to sessions
|
||||
([ADR 0153](../../02-DECISIONS/0153-the-record-is-read-by-a-module-and-the-console-lists-it.md)).
|
||||
@@ -38,6 +43,9 @@ Numbers collide, and the checks find a collision only after it happens. On 2026-
|
||||
number for a different effort. On 2026-10-07 three decision numbers collided in one evening. A
|
||||
record written by a verb could take its number from one counter, the way the issue tracker does.
|
||||
|
||||
Reading is costly too. Answering one question about what holds today means reading several records
|
||||
whole, and the generated decision index is larger than one tool answer may be.
|
||||
|
||||
Some knowledge also has no home. This repository is public, so it may not name nodes or describe
|
||||
operations; the mesh's knowledge about its own installation lives in agents' private notes, in no
|
||||
shared and searchable place.
|
||||
@@ -92,3 +100,8 @@ How this repository works (ADR 0019) and how the development cycle is checked (A
|
||||
`records` module (ADR 0153) and the generated decision index (ADR 0248), the issue tracker and its
|
||||
counters (ADR 0275, to-be 53), approval on a proving channel (ADR 0274), the playbooks in
|
||||
`00-META/process/`, the hq checks in `00-META/checks/`, and the glossary.
|
||||
|
||||
## Documents
|
||||
|
||||
- [01 — Findings](01-findings.md): what exists, measured on 2026-10-11; an answer to each of the eight
|
||||
questions; a first slice; and what needs the operator.
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
# 01 — Findings
|
||||
|
||||
Measured on 2026-10-11 against `main` of this repository, the records module and the issue tracker as they
|
||||
answer through the mesh MCP server, and the hq checks in `00-META/checks/`. Section 0 is what exists; sections 1 to 8
|
||||
answer the overview's eight questions in order; section 9 is the first slice this effort recommends; section 10
|
||||
lists what needs the operator.
|
||||
|
||||
## The purpose, in the operator's words
|
||||
|
||||
The operator gave the purpose on 2026-10-11: the decisions and the rest of the record should become **shared
|
||||
knowledge that agents reach through tools**, instead of reading markdown files, and a session should no longer
|
||||
have to start in this repository's folder to know what was decided. A session still starts here for other work,
|
||||
such as writing a record. On the same day the operator widened the scope: the knowledge base also holds **light
|
||||
content**, such as meeting notes, architectural drawings and blog posts.
|
||||
|
||||
That purpose moves the weight of the overview's questions. Where the truth is stored (option A or B) matters
|
||||
less than **what an answer looks like**: an agent needs the rule that holds now, with the records it rests on,
|
||||
in one call and a few kilobytes.
|
||||
|
||||
An acceptance sentence for the whole effort: *a session started in any folder on any node asks "what holds
|
||||
about the merge window, and why" and gets, in one call of under 4 KiB, the rules in force, the records they
|
||||
come from, what changed them since, and the commit it was read at.*
|
||||
|
||||
## 0. What exists today, measured
|
||||
|
||||
| Fact | Measured |
|
||||
|---|---|
|
||||
| Records on `main` | 274 decision records, 44 research efforts (119 files), 55 to-be and 16 as-is designs, 8 playbooks, 361 issue narratives, the glossary: 951 files |
|
||||
| Size | 6.9 MB of markdown, about 1.7 million tokens at four bytes a token; decision records alone 2.6 MB (about 650,000 tokens) |
|
||||
| One question, today | "what holds about the merge window": `records_search` gives 26 places in 11 documents; reading the five records and the design they point to is 85 KB, about 21,000 tokens |
|
||||
| The decision index | `records_decisions` answers 77 KB in one piece; the agent's tool-answer limit refused it inline, and it had to be read from a file in parts |
|
||||
| What `records_search` does | a literal, case-insensitive phrase match giving document, line and heading; no ranking, no notion of which record is still in force |
|
||||
| Frontmatter of a decision | `topic`, `status`, `date`, `deciders` on all 274; `extends` on 229 (182 with the folder prefix, 47 without); `supersedes-in-part` on 15 (21 links), `supersedes` on 8, `superseded-by` on 9, `rests-on` on 2, `amended` on 1 |
|
||||
| Status of a decision | 265 `accepted`, 9 `superseded`; no record is marked as changed in part, though 21 links say so |
|
||||
| Supersession said only in prose | 6 records say they supersede, amend or replace another and carry no field for it; 7 records carry a "superseded" marker in the body, of which only 1 has the field or the status |
|
||||
| Progressive insights | 39 records carry the dated marker, 55 markers in all; 2 more use an older form |
|
||||
| Change after writing | 189 of 271 traceable decision records were changed after the commit that created them; 34 paths were changed five times or more |
|
||||
| Pace | commits touching decision records: 87 in the last ten days of August, 160 in September, 274 in the first eleven days of October |
|
||||
| Number collisions | 16 decision numbers were taken twice by sessions working at once (2026-09-25 to 10-10), each repaired by a renumbering commit; 15 numbers on `main` are gaps; no research number collided |
|
||||
| A decision's rules | 263 records have a `Decision` section; only 37 of them write it as numbered rules with a bold lead (198 rules in all); the rest write prose |
|
||||
| Drawings | no file but markdown in the repository; no diagram source; 22 designs carry diagrams drawn in text characters |
|
||||
| Knowledge with no home | the repository is public, and its README says what only makes sense to someone who knows this installation "is either a note in the wrong place or a disclosure"; one agent's private notes hold 89 files for one repository on one node, and issue 367 (a session's memory stays on the node where it was learned) is open |
|
||||
| The hq checks | 33 rules: 25 judge one record, 4 the whole record, 4 the prose (section 6) |
|
||||
|
||||
Three things follow.
|
||||
|
||||
1. **The cost of an answer is the problem, not where the files are.** 85 KB for one question, and an index
|
||||
too large for one tool answer, mean a session reads in parts or reads less than it should. Moving the
|
||||
markdown into a store without changing the shape of the answer would keep that cost.
|
||||
2. **The data that makes an answer cheap is missing or loose.** What a record decided is prose in 226 of 263
|
||||
records. Which records changed which is half in fields, half in prose: 6 records say it only in prose, and
|
||||
6 more carry a body marker that no field or status agrees with.
|
||||
Status says `accepted` for records that 21 later links change in part.
|
||||
3. **The records change after they are written, and that is reviewed.** 189 of 271 decision records were
|
||||
edited after creation, every edit through a pull request with a human approval. Whatever is built must keep
|
||||
that review for what governs the mesh.
|
||||
|
||||
## 1. Kinds and their lifecycles
|
||||
|
||||
Two families, which the operator's addition makes plain.
|
||||
|
||||
**Governing kinds** change how the mesh is built or run, and are reviewed before they hold:
|
||||
|
||||
| Kind | Lifecycle | Notes |
|
||||
|---|---|---|
|
||||
| decision | proposed → accepted → superseded; accepted records can be changed in part, and carry dated progressive insights | the 274 records |
|
||||
| design | proposed → designed → in-progress → implemented, in one of two layers (to-be, as-is) | 71 documents |
|
||||
| research | active → graduated or abandoned | 44 efforts |
|
||||
| playbook | in force, or retired | 8, with no frontmatter today |
|
||||
| glossary entry | in force, or retired with its replacement | one file today; an entry is the natural unit |
|
||||
|
||||
A **guideline** and a **policy**, which the overview named, have no record of their own today. What the
|
||||
operator calls a policy is written as a decision; what an agent should do is a shared instruction section
|
||||
(ADR 0274) or a personal rule ([ADR 0273](../../02-DECISIONS/0273-the-agents-home-is-the-modules-and-the-operators-personal-rules-and-lessons-are-registered-through-it.md)).
|
||||
This effort recommends no new governing kind: rules for agents stay with the agent module's register, and the
|
||||
knowledge base links to them instead of holding a second copy.
|
||||
|
||||
**Light kinds** are written, read and kept, but govern nothing:
|
||||
|
||||
| Kind | Lifecycle | Notes |
|
||||
|---|---|---|
|
||||
| note | written, then kept or archived | meeting notes, a brainstorm with one or more agents, a hand-over |
|
||||
| post | draft → published, or withdrawn | a blog post, an explanation for readers outside the mesh |
|
||||
| drawing | current, or replaced by a newer version | an architectural drawing: a file plus a text description |
|
||||
|
||||
A light record needs no review to exist, since nothing obeys it. It can link to the governing records it
|
||||
discusses. A meeting's outcome that should hold becomes a proposed decision, which goes the governing way. The
|
||||
operator's brief for the meshboard asks for a knowledge base with meetings where the operator brainstorms with
|
||||
agents; a note is that meeting's record.
|
||||
|
||||
## 2. Numbering from one counter
|
||||
|
||||
The issue tracker already hands out numbers by compare-and-set on a counter key, and its design plans a
|
||||
decision counter and a research counter as a later slice
|
||||
([to-be 53](../../03-DESIGN/01-to-be/53-the-issue-tracker.md) §4). The 16 concurrent collisions all come from
|
||||
reading the next number off a repository that many branches write at once; one counter removes them.
|
||||
|
||||
- **One sequence per governing kind**: decision, research, design. Numbers keep their meaning in conversation
|
||||
("ADR 0276"), so they stay per kind.
|
||||
- **A light record needs no number.** It gets a key, its date and its title; nobody says "note 1432".
|
||||
- **A reserved number is spent.** A draft that is abandoned leaves its number as withdrawn, with who reserved
|
||||
it and when. Gaps already exist (15 on `main`) and harm nothing; reusing a number would.
|
||||
- **The counter starts above the highest number on `main` and on every open branch**, as the tracker's did.
|
||||
|
||||
Whether the counter lives in the tracker's `counters` bucket or in the knowledge base's own state is a design
|
||||
choice. This effort recommends the knowledge base's own: a number is the knowledge base's to hand out, and the
|
||||
tracker's design planned the extra counters only because nothing else would hold them.
|
||||
|
||||
## 3. Typed links
|
||||
|
||||
What frontmatter expresses today, and how reliably:
|
||||
|
||||
| Link | Today | Reliable |
|
||||
|---|---|---|
|
||||
| extends | `extends`, one target, two spellings | yes, after normalising the spelling |
|
||||
| supersedes / superseded-by | both fields, mirrored | yes, 9 of 9 mirror |
|
||||
| supersedes in part | one direction only; the target still reads `accepted` | no: 21 links have no reverse, and 6 more exist only in prose |
|
||||
| rests on, amended | 2 and 1 records | too rare to trust |
|
||||
| research became | `became` | yes |
|
||||
| design names its decisions | `decisions` | yes |
|
||||
| design names its code | `code`, free text | no |
|
||||
| cites | prose links: 1,785 decision to decision, 716 to-be to decision, 469 decision to issue | readable, untyped |
|
||||
|
||||
The links an answer needs are **supersedes**, **changes in part**, **extends**, **became**, **decided by**
|
||||
(design to decision), **cites**, and for light records **discusses**. The knowledge base stores each link in
|
||||
both directions, so "what changed this record since" is one lookup. That is the question the merge window
|
||||
example needs answered, and today it needs reading five records.
|
||||
|
||||
## 4. Approval
|
||||
|
||||
The overview asked whether accepting a decision should need the operator's warrant on a proving channel, as a
|
||||
shared instruction section does.
|
||||
|
||||
- **Governing kinds already have an approval**: a pull request merged only with a human approval and both
|
||||
required checks green. That is the warrant for a decision, and building a second one beside it would split
|
||||
the evidence. A write verb for a governing kind therefore ends in a pull request (option A).
|
||||
- **Light kinds need none to be written.** An agent may write a note or a draft post on its own; it is the
|
||||
agent's record of what happened, and nothing obeys it.
|
||||
- **Publishing needs the operator.** A post going out, or a light record exported into this public repository,
|
||||
cannot be taken back once read. That act goes through an ask the operator answers on a proving channel
|
||||
([ADR 0274](../../02-DECISIONS/0274-an-agent-proposes-a-shared-instruction-section-and-every-node-takes-it-only-on-the-operators-warrant-which-it-proves-itself.md)).
|
||||
|
||||
## 5. Public and private knowledge
|
||||
|
||||
This repository is public and must stay so. Knowledge about this installation has no shared home: it lives in
|
||||
one agent's notes on one node (89 files), which no other session reads.
|
||||
|
||||
The knowledge base gives it one. **Every record carries a visibility, `public` or `private`.** Governing kinds
|
||||
that come from this repository are public. A light record is private by default. A private record is served to
|
||||
the mesh's own sessions through the mesh MCP server and never written into this repository; a record becomes public
|
||||
only through the publishing act of section 4.
|
||||
|
||||
The check that nothing private leaks has to run where the export runs: the existing `words.py` rules for
|
||||
identifiers, plus a list of the installation's own names held privately by the knowledge base and checked
|
||||
against every record before it is exported. The words check cannot carry that list itself, since the list
|
||||
would then be public.
|
||||
|
||||
Agents' notes to themselves are not this. A lesson or a personal rule belongs to the agent module's register
|
||||
(ADR 0273), and carrying memory between nodes is issue 367's question. The knowledge base is for what the
|
||||
operator and every agent should be able to look up, not for what an agent tells itself.
|
||||
|
||||
## 6. Checks as refusals at write
|
||||
|
||||
Of the 33 rules the hq checks enforce:
|
||||
|
||||
- **25 judge one record** and can become refusals of a write verb, given read access to the others: a link
|
||||
resolves, a cited decision is accepted, supersession is symmetric, a design's layer matches its place, a
|
||||
to-be design names a decision, a number is not taken twice, and the like. Two of them (a cited record that
|
||||
becomes superseded later) can break without the citing record changing, so a write that supersedes must
|
||||
check who cites the record it supersedes.
|
||||
- **4 judge the whole record** (an accepted decision cited by nothing, an allowance nobody uses, two copies of
|
||||
the retired words agreeing) and stay checks over the whole, run on every merge.
|
||||
- **4 judge prose** (retired words, a daemon command line, the progressive-insight marker, a deferral naming its
|
||||
issue) and stay checks on the text.
|
||||
|
||||
For governing kinds, the pull request keeps all 33 as they are. The write verb refuses early what 25 of them
|
||||
would fail later, which saves a round trip but adds no new rule. For light kinds, the verb is the only gate:
|
||||
it refuses a link to a record that does not exist, and an export with a private name in it.
|
||||
|
||||
## 7. Import
|
||||
|
||||
For governing kinds, **nothing is imported once**. The knowledge base reads this repository at every merge,
|
||||
as the records module already does at the commit it names
|
||||
([ADR 0153](../../02-DECISIONS/0153-the-record-is-read-by-a-module-and-the-console-lists-it.md)), and rebuilds
|
||||
its index from it: kinds, numbers, statuses, typed links in both directions, sections, and each decision's
|
||||
rules. That is repeatable by construction, and the index can always be thrown away and rebuilt.
|
||||
|
||||
Two things a reading cannot recover alone:
|
||||
|
||||
- **Loose links.** The 6 supersessions said only in prose, the 7 body markers without a field, the 47 bare
|
||||
`extends` targets and the 21 one-way partial supersessions are repaired in this repository by one pull
|
||||
request, through progressive insights where a record's meaning is touched. The knowledge base does not guess
|
||||
them.
|
||||
- **What a decision decided, short.** 226 of 263 decision sections are prose. An answer needs each record's
|
||||
rules as short statements. This effort recommends a `summary` per record: the rules it decides, one line
|
||||
each, in the record's own frontmatter. For the 274 existing records, a first draft can be written by the
|
||||
agent's judgement ([ADR 0278](../../02-DECISIONS/0278-the-issue-tracker-checks-every-new-issue-for-a-duplicate-through-a-judgement-the-agent-makes-without-tools.md))
|
||||
and is reviewed in pull requests, a topic at a time. From then on, `records.py` refuses a decision without
|
||||
one. A summary nobody reviewed is never served as the record's word.
|
||||
|
||||
For light kinds the knowledge base is the truth, so there is nothing to import, except the meeting notes and
|
||||
other light material that exist today outside the mesh, if the operator wants them in.
|
||||
|
||||
## 8. What git gives, and what each option keeps
|
||||
|
||||
| What git and the forge give today | A: git stays the store | B: a store is the truth, hq its export |
|
||||
|---|---|---|
|
||||
| review on a pull request, line comments | kept | rebuilt or lost |
|
||||
| history of every change with its author | kept | rebuilt per record |
|
||||
| diff and revert | kept | rebuilt |
|
||||
| the required checks on every change | kept | rebuilt as refusals, and the 4 whole-record rules need a new home |
|
||||
| one number per record | the counter of section 2 | the counter of section 2 |
|
||||
| an answer in one call | the index of section 7 | the store |
|
||||
| a home for private and light records | no: the repository is public | yes |
|
||||
|
||||
Option A keeps everything review gives, for the kinds that need review. It cannot hold private or light
|
||||
records. Option B holds those, but would rebuild review, history and the checks, for 189 records out of 271
|
||||
that are edited after they are written.
|
||||
|
||||
**The recommendation is both, divided by kind**, the way the issue tracker already divided issues
|
||||
([ADR 0275](../../02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md)):
|
||||
|
||||
- **Governing kinds**: this repository stays the truth for their text and frontmatter. The knowledge base
|
||||
hands out their numbers, indexes them at every merge, and serves them as answers. Writing one stays a pull
|
||||
request, which a write verb can open.
|
||||
- **Light kinds**: the knowledge base is the truth. It stores them, private by default, and exports one to
|
||||
this repository only on the operator's word.
|
||||
|
||||
## 9. The first slice
|
||||
|
||||
**A Go module serving one seat held once for the mesh, on the control-node, beside the issue tracker.** The
|
||||
working name of the seat is `knowledge-base`; the glossary has no word for it yet (see *Words* below).
|
||||
|
||||
**Storage.** Light records and the index of governing records live in a database in the store, provided to
|
||||
the module. The bus's key-value buckets are the wrong place here: the limits of
|
||||
[ADR 0201](../../02-DECISIONS/0201-a-module-keeps-its-current-state-in-key-value-buckets-it-declares-and-reaches-through-the-runtime.md)
|
||||
§6 (256 KiB a value, 64 MiB a bucket) are below the 6.9 MB the index holds, and an answer needs full-text
|
||||
search ranked by relevance, which the store's server does and a bucket does not. The numbers' counter can
|
||||
stay a bucket key with compare-and-set, as the tracker's is. A drawing's file goes into an object-store
|
||||
bucket ([ADR 0288](../../02-DECISIONS/0288-the-object-store-stays-on-the-maintained-fork-and-garage-is-chosen-only-after-the-consumers-s3-features-are-counted.md));
|
||||
its record holds the description an agent reads, and the link to the file.
|
||||
|
||||
**Verbs, shaped as answers.** Each answer is bounded in size and names the commit of this repository it was
|
||||
read at.
|
||||
|
||||
| Verb | Answers |
|
||||
|---|---|
|
||||
| `ask` | the records that bear on a question, ranked: for each, its number, kind, status, title and summary, and whether it still holds or what changed it |
|
||||
| `get` | one record: its summary, its rules, its links both ways, what changed it since; the full text only when asked for |
|
||||
| `holds` | for a topic or a record, the rules in force now, after every supersession, partial change and progressive insight, each with the record it comes from |
|
||||
| `links` | a record's typed links, both directions |
|
||||
| `reserve` | the next number of a kind, spent whether or not the record lands |
|
||||
| `write` | a light record (note, post, drawing): written, private unless said otherwise |
|
||||
| `publish` | ask the operator to make a light record public, and export it on a yes |
|
||||
|
||||
The records module stays as it is: it is the literal reader of the repository, and `ask` and `get` do not
|
||||
replace a search for a symptom's literal text.
|
||||
|
||||
**How a session reaches it.** The knowledge base's tools reach every session through the mesh MCP server, like every
|
||||
module's. One shared instruction section, proposed and approved by ADR 0274's route, tells every session to ask
|
||||
the knowledge base about decisions and designs before reading files. A session then needs this repository's
|
||||
folder only to write a governing record.
|
||||
|
||||
**Proved by the acceptance sentence above**: the merge window question, asked from a session outside this
|
||||
repository, answered in one call under 4 KiB, naming ADR 0276, the partial change ADR 0282 made to it, and the
|
||||
commit.
|
||||
|
||||
## 10. What needs the operator
|
||||
|
||||
1. **Divided by kind (section 8)**: this repository stays the truth for decisions, designs, research and
|
||||
playbooks, and the knowledge base is the truth only for light records. The alternative is option B for
|
||||
everything.
|
||||
2. **A summary per decision record (section 7)**, drafted by the agent's judgement for the existing 274 and
|
||||
reviewed in pull requests, then required of every new record.
|
||||
3. **Private by default for light records (section 5)**, with publishing on the operator's word.
|
||||
4. **The store's database for the module (section 9)**, instead of the bus's buckets alone.
|
||||
|
||||
## Words
|
||||
|
||||
The glossary has **decision record**, **design**, **playbook** and **the record** (the records module). It has
|
||||
no word for the whole this effort describes, for its seat, or for the light kinds. This effort proposes, for a
|
||||
decision to settle through the glossary's own rules: **knowledge base** for the whole and its seat,
|
||||
**governing record** for a kind that is reviewed before it holds, and **note**, **post** and **drawing** for
|
||||
the light kinds. *Policy* stays the word for a module's upgrade policy, and *guideline* is not proposed, since
|
||||
section 1 finds no record of that kind.
|
||||
Reference in New Issue
Block a user