Builds hq issue 425: the first slice of the knowledge base, as decided in ADR 0290 and designed in to-be 55.
What it holds
A new Go module, modules/mesh-knowledge. It declares and claims the seat knowledge-base, once for the mesh, and is meant for the control node. It holds every decision record and research effort whole:
number, kind, title, topic, status, date and deciders;
clauses, each with a status (proposed, in force, changed, superseded) and a source (written, drafted, confirmed);
typed links (supersedes, changes to a clause, extends, became, cites), each stored once and read from both ends;
the reasoning, in sections;
every version, with who made it, when and why.
The verbs
ask, get, holds, links, history, reserve, propose, review, import, return, as ADR 0290 rule 6 and to-be 55 §7 name them. ask, get and holds stay within a bound they state (4 KiB by default) and say what they cut. The module's own tool knowledge_health answers its health. No verb takes an argument naming the caller.
How each row of to-be 55 §10 is tested
Row
Test
A proposal that breaks a per-record rule is refused, naming every reason
TestEveryPerRecordRuleRefusesAProposal: one case per rule, 29 cases; the test fails if a rule has no case. TestARefusalNamesEveryReasonAtOnce
Accepted only after a review by someone else; with the warrant when the record needs the operator
TestAReviewByTheAuthorIsRefused, TestAReviewByAnUnprovenCallerIsRefused, TestARecordThatNeedsTheOperatorIsAcceptedOnlyOnTheWarrant (not accepted without the warrant, accepted with it, the warrant kept), TestAWarrantForAnotherVersionDoesNotAccept, TestTheOperatorsDeclineLeavesTheRecordProposed
A whole-set rule that fails is loud
TestAnAcceptanceThatLeavesADecisionCitedByNothingMakesTheModuleUnhealthy, and TestEachWholeSetRuleFails for all 4 rules
Every version is kept and comparable
TestThreeVersionsAreKeptAndTheFirstAndThirdCompareExactly: applying the difference of versions 1 and 3 to version 1 gives version 3 line for line
The import changes nothing on a second run, and loses nothing
TestTheImportWritesEveryRecordWholeAndASecondRunChangesNothing over 11 real hq records; TestTheImportNeverOverwrites; TestTheWholeOfMainImports (322 records, no refusal, no whole-set finding)
A drafted clause is never served as in force
TestADraftedClauseIsNeverServedAsInForce: holds answers none and ask and get mark them. Two separate judgements: TestClausesAreDraftedThenConfirmedByASeparateJudgementThatSeesOnlyTheRecordAndTheDrafts
An answer stays within its bound
TestEveryAnswerStaysWithinItsBoundOverTheWholeOfMain: the full import of main at commit 331e8d0b (in testdata/hq-main.tar.gz), every get and holds, and a fixed list of 13 questions at 3 bounds
Live
not run: the module is not assigned. TestTheMergeWindowQuestionIsAnsweredInOneCallUnderFourKiB asks the acceptance question over main: ADR 0276 comes first, with its clauses in force and the change by ADR 0282, in 3.1 to 3.6 KB
Also tested: the bus (TestTheKnowledgeBaseOverTheBus: the bundle is started as the runtime starts it, and the runtime is played over a real NATS server, with the tracker's reserve, the records module, the judgement and the router on the other side), the manifest, migrations against the consolidated schema on a real postgres, and the daemons' lines against the catalogue's copy.
Each test fails without the code it tests. 12 mutations were checked, and each one turned its test red: author check removed, unproven check removed, operator ask skipped, warrant not held, drafted clauses served, the store overwriting on import, the whole set not judged, one rule removed, versions not kept, ask unbounded, confirming in the drafting call.
go test -race ./... passes in the module, on memory and on a private postgres. merge-check.sh passes, with MESH_GATE set to a controller built from mesh-controller main: the module check is ok, and the count of resources without health stays 69.
The database
The module requires a postgres-database provision named knowledge, declared the way claude-licence-manager (the one Go module with a database) declares it: binds, secrets, and a database.url file. The schema is migrations/0001-…sql plus the consolidated schema.sql. TestTheConsolidatedSchemaIsTheMigrationsApplied holds the two equal. A run-once prepare process applies the schema. A fresh database gets the consolidated schema. The bundle refuses to serve while the schema is behind. ask ranks with postgres full-text search.
Health and the condition
The controller refuses a module that judges itself only by its own tool. So the module follows the mounts module's act/judge split:
keep (judged by its unit) judges the whole record set every 5 minutes and stores the findings;
watch (judged by knowledge_health) writes a verdict file every minute, and the health tool reads that file.
When a finding exists, the module is unhealthy and the mesh raises its condition, naming the rule and the records.
What release needs
assigning to novox, and a postgres provider for the postgres-database provision. The default settings are judge-model sonnet, drafting on, reserved-for 168h, and none needs setting;
issue-tracker.reserve (issue 424). The code uses its contract {kind, for} → {kind, number}; until it exists, reserve refuses and writes nothing;
the runtime proving the caller (issue 365). Until then every review is refused, because a review cannot be told from its author's own, so the live acceptance "a record proposed, reviewed and accepted" waits on 365;
one import, then the record-by-record comparison of issue 426. No import was run against the live mesh.
Outside the module, this PR changes .gitignore only: two lines for the built binary.
hq issue 425 · ADR 0290 · to-be 55
Builds hq issue 425: the first slice of the knowledge base, as decided in ADR 0290 and designed in to-be 55.
## What it holds
A new Go module, `modules/mesh-knowledge`. It declares and claims the seat `knowledge-base`, once for the mesh, and is meant for the control node. It holds every decision record and research effort whole:
- number, kind, title, topic, status, date and deciders;
- clauses, each with a status (proposed, in force, changed, superseded) and a source (written, drafted, confirmed);
- typed links (supersedes, changes to a clause, extends, became, cites), each stored once and read from both ends;
- the reasoning, in sections;
- every version, with who made it, when and why.
## The verbs
`ask`, `get`, `holds`, `links`, `history`, `reserve`, `propose`, `review`, `import`, `return`, as ADR 0290 rule 6 and to-be 55 §7 name them. `ask`, `get` and `holds` stay within a bound they state (4 KiB by default) and say what they cut. The module's own tool `knowledge_health` answers its health. No verb takes an argument naming the caller.
## How each row of to-be 55 §10 is tested
| Row | Test |
|---|---|
| A proposal that breaks a per-record rule is refused, naming every reason | `TestEveryPerRecordRuleRefusesAProposal`: one case per rule, 29 cases; the test fails if a rule has no case. `TestARefusalNamesEveryReasonAtOnce` |
| Accepted only after a review by someone else; with the warrant when the record needs the operator | `TestAReviewByTheAuthorIsRefused`, `TestAReviewByAnUnprovenCallerIsRefused`, `TestARecordThatNeedsTheOperatorIsAcceptedOnlyOnTheWarrant` (not accepted without the warrant, accepted with it, the warrant kept), `TestAWarrantForAnotherVersionDoesNotAccept`, `TestTheOperatorsDeclineLeavesTheRecordProposed` |
| A whole-set rule that fails is loud | `TestAnAcceptanceThatLeavesADecisionCitedByNothingMakesTheModuleUnhealthy`, and `TestEachWholeSetRuleFails` for all 4 rules |
| Every version is kept and comparable | `TestThreeVersionsAreKeptAndTheFirstAndThirdCompareExactly`: applying the difference of versions 1 and 3 to version 1 gives version 3 line for line |
| The import changes nothing on a second run, and loses nothing | `TestTheImportWritesEveryRecordWholeAndASecondRunChangesNothing` over 11 real hq records; `TestTheImportNeverOverwrites`; `TestTheWholeOfMainImports` (322 records, no refusal, no whole-set finding) |
| A drafted clause is never served as in force | `TestADraftedClauseIsNeverServedAsInForce`: `holds` answers none and `ask` and `get` mark them. Two separate judgements: `TestClausesAreDraftedThenConfirmedByASeparateJudgementThatSeesOnlyTheRecordAndTheDrafts` |
| An answer stays within its bound | `TestEveryAnswerStaysWithinItsBoundOverTheWholeOfMain`: the full import of main at commit `331e8d0b` (in `testdata/hq-main.tar.gz`), every `get` and `holds`, and a fixed list of 13 questions at 3 bounds |
| Live | not run: the module is not assigned. `TestTheMergeWindowQuestionIsAnsweredInOneCallUnderFourKiB` asks the acceptance question over main: ADR 0276 comes first, with its clauses in force and the change by ADR 0282, in 3.1 to 3.6 KB |
Also tested: the bus (`TestTheKnowledgeBaseOverTheBus`: the bundle is started as the runtime starts it, and the runtime is played over a real NATS server, with the tracker's reserve, the records module, the judgement and the router on the other side), the manifest, migrations against the consolidated schema on a real postgres, and the daemons' lines against the catalogue's copy.
**Each test fails without the code it tests.** 12 mutations were checked, and each one turned its test red: author check removed, unproven check removed, operator ask skipped, warrant not held, drafted clauses served, the store overwriting on import, the whole set not judged, one rule removed, versions not kept, `ask` unbounded, confirming in the drafting call.
`go test -race ./...` passes in the module, on memory and on a private postgres. `merge-check.sh` passes, with `MESH_GATE` set to a controller built from mesh-controller main: the module check is ok, and the count of resources without health stays 69.
## The database
The module requires a `postgres-database` provision named `knowledge`, declared the way `claude-licence-manager` (the one Go module with a database) declares it: `binds`, `secrets`, and a `database.url` file. The schema is `migrations/0001-…sql` plus the consolidated `schema.sql`. `TestTheConsolidatedSchemaIsTheMigrationsApplied` holds the two equal. A run-once `prepare` process applies the schema. A fresh database gets the consolidated schema. The bundle refuses to serve while the schema is behind. `ask` ranks with postgres full-text search.
## Health and the condition
The controller refuses a module that judges itself only by its own tool. So the module follows the mounts module's act/judge split:
- `keep` (judged by its unit) judges the whole record set every 5 minutes and stores the findings;
- `watch` (judged by `knowledge_health`) writes a verdict file every minute, and the health tool reads that file.
When a finding exists, the module is unhealthy and the mesh raises its condition, naming the rule and the records.
## What release needs
- assigning to novox, and a postgres provider for the `postgres-database` provision. The default settings are `judge-model` sonnet, `drafting` on, `reserved-for` 168h, and none needs setting;
- `issue-tracker.reserve` (issue 424). The code uses its contract `{kind, for}` → `{kind, number}`; until it exists, `reserve` refuses and writes nothing;
- the runtime proving the caller (issue 365). Until then every review is refused, because a review cannot be told from its author's own, so the live acceptance "a record proposed, reviewed and accepted" waits on 365;
- one import, then the record-by-record comparison of issue 426. No import was run against the live mesh.
Outside the module, this PR changes `.gitignore` only: two lines for the built binary.
hq issue 425 · ADR 0290 · to-be 55
mesh/merge-gate pass: builds new: modules/mesh-knowledge, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compo…
An agent learns what a decision says only by reading whole records. This module
holds every decision record and research effort whole in a database in the store,
with clauses that carry their own status and source, typed links read from both
ends, and every version. It answers ask, get and holds within a stated bound, and
takes a record through reserve, propose (refused on any of the 29 per-record
rules), review by someone other than the author, and acceptance, on the
operator's proven warrant when the record needs it. The 4 whole-set rules make
the module unhealthy when they fail. The import reads hq at a commit through the
records module, never overwrites, and changes nothing when run again. Prose
decisions get drafted clauses that a second judgement must confirm before they
are served.
Correction to the description: 11 mutations were checked, not 12. The list in the description is complete, and each of the 11 turned its test red. The import mutation was made in the store (create-if-absent removed), because the verb's own check alone is backed by the store's refusal.
Correction to the description: 11 mutations were checked, not 12. The list in the description is complete, and each of the 11 turned its test red. The import mutation was made in the store (create-if-absent removed), because the verb's own check alone is backed by the store's refusal.
Deliverynovox/mesh-catalog@ec00e13e2235 — delivered since 2026-10-11T03:49:14Z
Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
Transitions
2026-10-11 03:15 (new) → proposed (announced): novox/mesh-catalog#206's head announced
2026-10-11 03:19 proposed → checked (checked): the verdict names this commit
2026-10-11 03:19 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-11 03:49 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-11 03:49 published → delivered (done): nothing for a walk to move
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@ec00e13e2235` — **delivered** since 2026-10-11T03:49:14Z
**Delivery plan** — builds new: modules/mesh-knowledge, sent nowhere; no bus step
**Transitions**
- 2026-10-11 03:15 (new) → proposed (announced): novox/mesh-catalog#206's head announced
- 2026-10-11 03:19 proposed → checked (checked): the verdict names this commit
- 2026-10-11 03:19 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-11 03:49 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-11 03:49 published → delivered (done): nothing for a walk to move
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
read by no module's build: .gitignore
Run by the build seat on shanks as build-1791687561604076719 (builds --log build-1791687561604076719).
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T02:59:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T02:59:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.003s
words: 12 retired words and 70 daemons' lines, none in the 41208 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.013s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 80.810s
--- its merge-check-typescript.sh (typescript toolchain)
**Merge check** at `ba7b4557`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
**Delivery plan** — builds new: modules/mesh-knowledge, sent nowhere; no bus step
- read by no module's build: .gitignore
Run by the build seat on shanks as `build-1791687561604076719` (`builds --log build-1791687561604076719`).
```
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T02:59:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T02:59:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.003s
words: 12 retired words and 70 daemons' lines, none in the 41208 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.013s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 80.810s
--- its merge-check-typescript.sh (typescript toolchain)
```
mesh/merge-gate pass: builds new: modules/mesh-knowledge, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compo…
A revision came from anyone and a review was refused only to the first author,
so a co-writer could approve, and a record proposed before callers are proven
would later be reviewable by its own unproven author. Now a revision is taken
only from the proven author, a reserved number only from whoever reserved it,
and a review is refused from any writer of any version or for any record with
an unproven writer. The rules held records from no date, so a correction to an
older record was refused by rules hq never held it to; each dated rule now holds
from hq's own start date, and a new record cannot be dated before its
reservation. history and the question to ask are bounded like the other answers.
All seven points of the review are addressed in 10ab959d. Each new test failed before the code it tests.
A proposal is revised only by its author, as the runtime proves them. A review is refused from anyone who wrote any version of the record (the record now keeps a list of its writers).
A review is refused when any version's writer was unproven. The refusal tells the author to propose the record again under a new number.
Each dated rule (RuleFrom in rules.go) holds a record from hq's own start date: retired words from 2026-10-07; daemons' lines and deferrals from 2026-10-09; clauses, sections and the live-citation rule from 2026-10-11. A progressive insight keeps its record's date, and a new record cannot be dated before its reservation. The test proposes an insight to the real ADR 0011 over the whole of main.
The README says the caller needs an SDK change (issue 365), and that callerOf is the one place it is read.
history takes a bound and says what it cut, and the work of a difference is capped (the difference stays exact). A question to ask is at most 500 characters.
The README no longer says reserve waits on issue 424.
A number reserved by a proven caller is proposed only by that caller.
go test -race passes, and so does merge-check.sh.
All seven points of the review are addressed in 10ab959d. Each new test failed before the code it tests.
1. A proposal is revised only by its author, as the runtime proves them. A review is refused from anyone who wrote any version of the record (the record now keeps a list of its writers).
2. A review is refused when any version's writer was unproven. The refusal tells the author to propose the record again under a new number.
3. Each dated rule (`RuleFrom` in `rules.go`) holds a record from hq's own start date: retired words from 2026-10-07; daemons' lines and deferrals from 2026-10-09; clauses, sections and the live-citation rule from 2026-10-11. A progressive insight keeps its record's date, and a new record cannot be dated before its reservation. The test proposes an insight to the real ADR 0011 over the whole of main.
4. The README says the caller needs an SDK change (issue 365), and that `callerOf` is the one place it is read.
5. `history` takes a bound and says what it cut, and the work of a difference is capped (the difference stays exact). A question to `ask` is at most 500 characters.
6. The README no longer says reserve waits on issue 424.
7. A number reserved by a proven caller is proposed only by that caller.
`go test -race` passes, and so does `merge-check.sh`.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
read by no module's build: .gitignore
Run by the build seat on ace as build-1791688230461355883 (builds --log build-1791688230461355883).
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T03:09:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T03:09:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.002s
words: 12 retired words and 70 daemons' lines, none in the 41257 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.012s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 71.196s
--- its merge-check-typescript.sh (typescript toolchain)
**Merge check** at `10ab959d`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
**Delivery plan** — builds new: modules/mesh-knowledge, sent nowhere; no bus step
- read by no module's build: .gitignore
Run by the build seat on ace as `build-1791688230461355883` (`builds --log build-1791688230461355883`).
```
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T03:09:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T03:09:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.002s
words: 12 retired words and 70 daemons' lines, none in the 41257 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.012s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.006s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 71.196s
--- its merge-check-typescript.sh (typescript toolchain)
```
mesh/merge-gate pass: builds new: modules/mesh-knowledge, sent nowhere; no bus step; every machine composes with the change as it did without (4 of 4 compo…
hq's words check never read a decision record, so a correction to any decision
of October 7 to 10 was refused for words it was allowed to write. The links an
accepted record holds are kept by its correction without being judged again.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
read by no module's build: .gitignore
Run by the build seat on g14 as build-1791688504456242520 (builds --log build-1791688504456242520).
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T03:09:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T03:09:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.003s
words: 12 retired words and 70 daemons' lines, none in the 41261 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.010s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.005s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 92.448s
--- its merge-check-typescript.sh (typescript toolchain)
**Merge check** at `ec00e13e`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
**Delivery plan** — builds new: modules/mesh-knowledge, sent nowhere; no bus step
- read by no module's build: .gitignore
Run by the build seat on g14 as `build-1791688504456242520` (`builds --log build-1791688504456242520`).
```
--- the gate: new:modules/mesh-knowledge
note: mesh-knowledge uses the seat "operator-channel", which no module declares and the mesh does not define among the manifests given; registration judges it against the whole catalogue, and passing the declaring module's manifest too judges it here
mesh-knowledge: ok, 1 tool(s), invokes seat:issue-tracker.reserve, claude-code.claude_code_judge, records.records_status, records.records_list, records.records_read, seat:operator-channel.notify, ready: keep by unit every 30s; watch by its tool knowledge_health every 1m0s
long-running resources without health: 0
files asking for a setting without saying whether it is trusted: 0
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-11T03:09:01Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-11T03:09:01Z
modules the change moves:
- mesh-knowledge (added)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-delivery, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 0 module(s) in 0 tier(s)
notes:
- .gitignore read by no module's build, and rebuild nothing (issue 280)
--- its merge-check.sh (go toolchain)
ok git.novox.be/novox/mesh-catalog/checks/words 0.003s
words: 12 retired words and 70 daemons' lines, none in the 41261 strings of 670 files
ok git.novox.be/novox/mesh-catalog/checks/agenthome 0.010s
agent-home: no archive and no file written into under the agent's home
ok git.novox.be/novox/mesh-catalog/checks/paths 0.005s
paths: no module names another's state on its machine (3 known, listed to go)
long-running resources without health: 69, as kept
testing modules/mesh-knowledge
ok mesh-knowledge/cmd/mesh-knowledge 92.448s
--- its merge-check-typescript.sh (typescript toolchain)
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Builds hq issue 425: the first slice of the knowledge base, as decided in ADR 0290 and designed in to-be 55.
What it holds
A new Go module,
modules/mesh-knowledge. It declares and claims the seatknowledge-base, once for the mesh, and is meant for the control node. It holds every decision record and research effort whole:The verbs
ask,get,holds,links,history,reserve,propose,review,import,return, as ADR 0290 rule 6 and to-be 55 §7 name them.ask,getandholdsstay within a bound they state (4 KiB by default) and say what they cut. The module's own toolknowledge_healthanswers its health. No verb takes an argument naming the caller.How each row of to-be 55 §10 is tested
TestEveryPerRecordRuleRefusesAProposal: one case per rule, 29 cases; the test fails if a rule has no case.TestARefusalNamesEveryReasonAtOnceTestAReviewByTheAuthorIsRefused,TestAReviewByAnUnprovenCallerIsRefused,TestARecordThatNeedsTheOperatorIsAcceptedOnlyOnTheWarrant(not accepted without the warrant, accepted with it, the warrant kept),TestAWarrantForAnotherVersionDoesNotAccept,TestTheOperatorsDeclineLeavesTheRecordProposedTestAnAcceptanceThatLeavesADecisionCitedByNothingMakesTheModuleUnhealthy, andTestEachWholeSetRuleFailsfor all 4 rulesTestThreeVersionsAreKeptAndTheFirstAndThirdCompareExactly: applying the difference of versions 1 and 3 to version 1 gives version 3 line for lineTestTheImportWritesEveryRecordWholeAndASecondRunChangesNothingover 11 real hq records;TestTheImportNeverOverwrites;TestTheWholeOfMainImports(322 records, no refusal, no whole-set finding)TestADraftedClauseIsNeverServedAsInForce:holdsanswers none andaskandgetmark them. Two separate judgements:TestClausesAreDraftedThenConfirmedByASeparateJudgementThatSeesOnlyTheRecordAndTheDraftsTestEveryAnswerStaysWithinItsBoundOverTheWholeOfMain: the full import of main at commit331e8d0b(intestdata/hq-main.tar.gz), everygetandholds, and a fixed list of 13 questions at 3 boundsTestTheMergeWindowQuestionIsAnsweredInOneCallUnderFourKiBasks the acceptance question over main: ADR 0276 comes first, with its clauses in force and the change by ADR 0282, in 3.1 to 3.6 KBAlso tested: the bus (
TestTheKnowledgeBaseOverTheBus: the bundle is started as the runtime starts it, and the runtime is played over a real NATS server, with the tracker's reserve, the records module, the judgement and the router on the other side), the manifest, migrations against the consolidated schema on a real postgres, and the daemons' lines against the catalogue's copy.Each test fails without the code it tests. 12 mutations were checked, and each one turned its test red: author check removed, unproven check removed, operator ask skipped, warrant not held, drafted clauses served, the store overwriting on import, the whole set not judged, one rule removed, versions not kept,
askunbounded, confirming in the drafting call.go test -race ./...passes in the module, on memory and on a private postgres.merge-check.shpasses, withMESH_GATEset to a controller built from mesh-controller main: the module check is ok, and the count of resources without health stays 69.The database
The module requires a
postgres-databaseprovision namedknowledge, declared the wayclaude-licence-manager(the one Go module with a database) declares it:binds,secrets, and adatabase.urlfile. The schema ismigrations/0001-…sqlplus the consolidatedschema.sql.TestTheConsolidatedSchemaIsTheMigrationsAppliedholds the two equal. A run-onceprepareprocess applies the schema. A fresh database gets the consolidated schema. The bundle refuses to serve while the schema is behind.askranks with postgres full-text search.Health and the condition
The controller refuses a module that judges itself only by its own tool. So the module follows the mounts module's act/judge split:
keep(judged by its unit) judges the whole record set every 5 minutes and stores the findings;watch(judged byknowledge_health) writes a verdict file every minute, and the health tool reads that file.When a finding exists, the module is unhealthy and the mesh raises its condition, naming the rule and the records.
What release needs
postgres-databaseprovision. The default settings arejudge-modelsonnet,draftingon,reserved-for168h, and none needs setting;issue-tracker.reserve(issue 424). The code uses its contract{kind, for}→{kind, number}; until it exists,reserverefuses and writes nothing;Outside the module, this PR changes
.gitignoreonly: two lines for the built binary.hq issue 425 · ADR 0290 · to-be 55
Correction to the description: 11 mutations were checked, not 12. The list in the description is complete, and each of the 11 turned its test red. The import mutation was made in the store (create-if-absent removed), because the verb's own check alone is backed by the store's refusal.
Delivery
novox/mesh-catalog@ec00e13e2235— delivered since 2026-10-11T03:49:14ZDelivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
ba7b4557mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
Run by the build seat on shanks as
build-1791687561604076719(builds --log build-1791687561604076719).All seven points of the review are addressed in
10ab959d. Each new test failed before the code it tests.RuleFrominrules.go) holds a record from hq's own start date: retired words from 2026-10-07; daemons' lines and deferrals from 2026-10-09; clauses, sections and the live-citation rule from 2026-10-11. A progressive insight keeps its record's date, and a new record cannot be dated before its reservation. The test proposes an insight to the real ADR 0011 over the whole of main.callerOfis the one place it is read.historytakes a bound and says what it cut, and the work of a difference is capped (the difference stays exact). A question toaskis at most 500 characters.go test -racepasses, and so doesmerge-check.sh.Merge check at
10ab959dmesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
Run by the build seat on ace as
build-1791688230461355883(builds --log build-1791688230461355883).Merge check at
ec00e13emesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: new:modules/mesh-knowledge)mesh/repo-check: PASS — its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)Delivery plan — builds new: modules/mesh-knowledge, sent nowhere; no bus step
Run by the build seat on g14 as
build-1791688504456242520(builds --log build-1791688504456242520).