15 KiB
layer, status, code, updated, decisions
| layer | status | code | updated | decisions | ||
|---|---|---|---|---|---|---|
| to-be | designed | 2026-10-12 |
|
55 — The knowledge base
The mesh keeps its decision records and research efforts whole in a module of its own, mesh-knowledge, one
instance on the control-node, holding the seat knowledge-base: each record's number, status, topic, typed links,
its clauses with their own status, and its reasoning, with every version kept. A record is proposed, checked when it
is written, reviewed by the knowledge base's own judgement and accepted there; the operator's Approve is asked when a record needs
it. Agents ask what holds, and why, in one bounded call.
(ADR 0290,
from research 045.)
A clause is one numbered statement a decision record makes, with its own status. The knowledge base is the
module that holds the records; the seat it holds is knowledge-base. The glossary holds both words.
Acceptance. A session started in any folder on any node asks "what holds about the merge window, and why" and gets, in one call under 4 KiB, the clauses in force, the records they come from, what changed them since, and how to read the reasoning behind each.
This document designs the first slice in detail, tracked by issue 425. The slices after it are in § 9.
1. The parts
control-node
mesh-knowledge (seat knowledge-base, held once for the mesh)
├ its process, launched by the node runtime
├ a database in the store records, versions, clauses, links; ranked full-text search
├ verbs ask, get, holds, links, history, reserve, propose, import, return
│ served by the control-node's tool runner
├ events proposed, reviewed, accepted, changed, imported, drafted, confirmed, returned
└ consumes the router's warrants: the operator's Approve for a record that needs it (§ 5)
mesh-issues (control-node) the counters for decision and research numbers (§ 6)
claude-code (same node) claude_code_judge: review a proposal (§ 5), draft and confirm clauses (§ 7)
records (any node) records_read at a commit: the import's source (§ 8)
messenger (control-node) the router: the operator's ask and its warrant
any agent session, on any node
mesh MCP server ── mesh_search, mesh_describe, mesh_call ──▶ the verbs, over the bus
The module is written in Go against the SDK. It holds no checkout of this repository; the import reads it through the records module, as the issue tracker's import does.
2. What one record holds
numberandkind(decision or research), its key together;title,topic,status,date,deciders;- its reasoning, in sections: for a decision, context, the options weighed, consequences, how it is checked, references; for a research effort, its overview and each of its documents by name; markdown, as written;
- for a decision, its clauses (§ 3);
- its links, typed, each stored once and read from both ends;
- its versions: every change is a new version with who made it, when, and why in one line;
historylists them and gives the difference between any two. A progressive insight is a version marked as one, dated, saying what stood before.
| Link | From → to |
|---|---|
supersedes |
a record → a record it replaces whole |
changes |
a clause or a record → a clause it replaces part of |
extends |
a record → a record it builds on |
became |
a research effort → a decision record or design |
rests-on |
a decision → a decision it stands on |
touches |
a research effort → a record, issue or design it bears on (by link), or an area (as text) |
cites |
any record → any record or issue it names |
3. Clauses
A clause holds its record's number and its own (0276 §4), its wording, a status and a source:
| Status | Meaning |
|---|---|
proposed |
its record is not accepted yet |
in force |
holds, and nothing later changes it |
changed |
a later clause replaces part of it; the changes link names which |
superseded |
its record is superseded, or a later clause replaces it whole |
| Source | Meaning |
|---|---|
written |
written as a clause by the record's author |
drafted |
written by the judgement from a prose Decision section at the import; never served as in force |
confirmed |
drafted, then confirmed by a second, independent judgement (§ 7) |
4. Writing a record
reserve gives a number (§ 6). propose takes the record whole: its fields, its clauses, its reasoning in sections,
its links, and for each changes the clauses it changes. It is refused, with every reason at once, when one of the
29 rules of the hq checks that judge one record or its prose fails, among them:
- a link names a record or clause that does not exist;
- a decision has no clause, or a clause has no bold lead;
- a record it supersedes or changes is not accepted, or one it cites as live is superseded without naming the record that replaced it;
- its topic is not one of the reading order's;
- a research effort graduates without naming what it became;
- its text uses a retired word of the glossary, or a daemon's command line.
A proposed record can be revised by its author as new versions until it is accepted. Nothing proposed is ever served as in force.
5. Review and acceptance
When propose takes a record (or a new version of a proposed one), the knowledge base reviews it itself: it asks for
a judgement in a separate call, with no tools, that sees only the record, the records it links and the rules, and
answers approve or changes with its findings, the way the issue tracker's triage judges an issue. The judgement
goes through the agent module's judge (claude_code_judge) today, and through the mesh's inference layer once one
exists; nothing in this design depends on which. On changes, the record stays proposed, the findings are kept with
that version, and its author revises it with a new version, which is reviewed again. A judgement that cannot be had
(the judge unreachable, or its answer unreadable) leaves the record proposed and says so; it is never taken as an
approval. On approve:
- a record that does not need the operator is accepted at once;
- a record whose author marked it
needs operatorgets an ask on the router with Approve and Decline, shown on a channel that proves who answered (ADR 0274); the knowledge base accepts it only on the warrant for Approve, which it keeps with the record.
On acceptance the record and its clauses move to accepted and in force, every clause its changes and
supersedes name moves to changed or superseded, and accepted and changed events are emitted. Then the 4
rules that judge the whole record set run (an accepted decision cited by nothing, and the like). A failure does not
undo the acceptance. It is a fault of the records, which their authors repair, not of the module: it is told to the
operator once, as a warning naming the rule and the records, and cleared once the rule holds again. The module's
health names it and stays healthy, because health says only whether the module works, and a finding never holds a
rollout at the module's first-node gate (the operator's decision of 2026-10-12 on issue 504, as issue 508 decided for a proposal never
reviewed).
The rule cited is also judged ahead, in the review, before the judgement: a decision that names no home and that no
accepted record links is not accepted. Its review, by the knowledge base itself, asks changes naming the rule (issue
504). It is not refused at propose, because no record can link a number only reserved: a record that cites a new
decision is proposed after it and accepted, and the new decision is proposed again.
An accepted record is changed only by a new record, or by a progressive insight: a new version marked as one, which is reviewed like a proposal.
6. Numbers
reserve takes a kind and asks the issue tracker for the next number of that sequence (issue 424, ADR 0275 rule 8).
The number is spent: a record that is never accepted keeps it as withdrawn, with who reserved it and when. The
knowledge base keeps no counter.
7. Drafting and confirming clauses at the import
For a decision whose Decision section is prose, the import asks the agent's judgement
(ADR 0278)
for its clauses: the section in, numbered statements out, each one sentence, each saying nothing the section does not.
They are stored drafted. A second judgement, in a separate call that sees only the record and the drafts, answers
per clause whether the record says exactly that; an accepted clause becomes confirmed, a rejected one stays
drafted with the reason. Which clause of an older record a supersedes-in-part changes is judged and confirmed the
same way. When every record of a topic has been through both, the operator is told once per topic, with the counts
confirmed and still drafted. return with a record's number and a reason sends it back to be drafted again.
A drafted clause may be changed, and a linked clause keeps its number (ADR 0321, issue 494). A later record's
changes may name a drafted clause, confirmed or not, as it may one in force or changed; only a superseded or proposed
clause is refused. On that record's acceptance the drafted clause is marked changed, naming the clause that changed
it, keeps its number and stays drafted: it is still never served as in force, and get and ask say both. Because
a redraft numbers a record's clauses anew, return refuses a record any of whose clauses another record changed or
links by number, in a version served or proposed, naming each such link; a record that changes the drafted clause is
the way to correct it. A record no other record links by clause is returned as before.
8. The import
import takes a commit of this repository (and dry-run) and writes every decision record and research effort
whole, at its own number, as its first version, naming the commit. It creates what is absent, never overwrites, never
advances a counter; a second run changes nothing and says so. Records written in this repository after the import,
while the first slice does not take writes yet, are taken in by running it again.
Refresh. import with refresh re-reads, at the commit given, every record whose versions were all written by
the import, a refresh, or the knowledge base's own drafting and confirming of clauses, with nothing waiting over
it, and writes the corrected record as a new version naming why; a record anyone else wrote a version of is
never touched. Clauses already drafted and confirmed are kept when the Decision section's text is unchanged, and
drafted again when it changed. It repairs what an earlier import misread (issue 487) and is idempotent: a second run changes
nothing. dry-run lists what it would change. Once this repository holds no records, import refuses rather than
reporting nothing created (issue 488).
Before the records leave this repository (issue 426), every record is compared with its file at the import's commit, field by field and section by section, and the result is written on issue 426.
9. The slices after the first
| Slice | Delivers | Done when the operator sees | Tracked by |
|---|---|---|---|
| 1 | this document: the module, the import, clauses, answers, propose, its own review and acceptance |
the acceptance sentence above, live, and a record proposed, reviewed and accepted without a pull request | issue 425 |
| 2 | the decision records and research efforts leave this repository; path mentions become "ADR NNNN" and "research NNN"; playbooks 01 and 02 changed | this repository holds no decision record, and get answers every one |
issue 426 |
| 3 | designs, playbooks and glossary entries as kinds | holds answers for a design's decisions and a glossary word |
issue 428 |
| 4 | meeting notes, drawings and blog posts | not decided; needs its own decision | issue 429 |
Numbers from the issue tracker, which reserve needs, are the tracker's own slice, tracked by issue 424. This
repository keeps no copy of the records, generated or otherwise (issue 435, answered by the operator).
10. How it is checked
| Rule | Checked by |
|---|---|
| A proposal that breaks a per-record rule is refused, naming every reason | the module's table test, one case per rule of § 4 |
| A record is accepted only after the knowledge base's own judgement approves it, and, when it needs the operator, only on the warrant | the module's tests: a proposal whose judgement answers changes, or cannot be had, stays proposed; a needs operator record unaccepted without the warrant, accepted with it |
| A decision is not accepted cited by nothing | the module's test: a decision with no home and no record linking it gets changes from the review, with no judgement asked; with a home, or once a record citing it is accepted, it is accepted |
| A whole-set rule that fails is loud, and leaves the module healthy | the module's test: a correction that leaves a decision cited by nothing tells the operator once, as a warning naming the rule and the record, not again after a restart, and clears it once a record cites it; the module's health stays healthy throughout |
| Every version is kept and comparable | the module's test: three versions, history lists them, the difference of the first and third is exact |
| The import changes nothing on a second run, and loses nothing | the module's test over a fixture repository; and the comparison of § 8 on issue 426 |
| A drafted clause is never served as in force | the module's test: holds over a record with only drafted clauses answers none, and ask marks them |
| A drafted clause may be changed, and a linked clause is never renumbered | the module's tests: a record changing a drafted clause is accepted, and the clause is then changed, keeps its number, stays drafted and is not served; return of a record whose clause another record changed or links by number is refused naming the link, and writes nothing |
| An answer stays within its bound | the module's test over the full import of main at a recorded commit: every ask, get and holds of a fixed question list |
| A record written in this repository meanwhile writes its clauses | records.py, check clauses, on every hq pull request, until the records left this repository (issue 426); since then records.py, check no-records, refuses any record written here |
| Live | the acceptance sentence, asked from a session outside this repository |
What it leaves out
Semantic or vector search; a browser view; line comments on a proposal (the judgement's findings name the section and clause instead); and the rules of how-we-build, which are not decision records. Each needs a decision of its own.