hq issue 356, ADR 0272's progressive insight of 2026-10-09 (the operator's rule): the operator types one command, nox (mesh-cli); the node-engine and the controller are daemons, and a person never types their names. A module's condition had told the operator to run the node-engine's hand-over at the machine, and nothing held the catalogue's texts to the rule.
Reviewers' checklist
Validate every caller value.readLines refuses a retired-lines entry that is not <daemon> <command> (exit 2); an empty list is exit 2 ("the check would pass on anything"), as the words list already is.
Trust-changing acts. None: a check, read-only.
Every test fails with its check removed.TestADaemonsLineIsFoundWhole: twelve pattern cases — a line found whole, across a line break, in a code span, after a prompt; not found joined to another word, as a plain-English verb, as prose naming the daemon beside a noun ("the mesh-controller module is assigned"), or as a command that needs an argument without one; and nox-mesh-host hand-over found while nox node hand-over is not — plus one finding's exact words. TestRetiredLinesAreReadAsDaemonAndCommand: the list's format, the … marker, a malformed entry refused.
Fail closed. A finding is exit 1 and names the file, the line and the words; the list cannot be empty or malformed.
What changes
checks/words/lines.go: the daemons' lines, read from retired-lines at the catalogue's root — a copy of what hq's words.py --list lines prints, which hq's check compares when MESH_CATALOG_DIR is set (the same arrangement as retired-words). A command marked … is a line only with an argument after it, matched as a line is written (at the start of a line or a code span, a prompt allowed), because "the mesh-controller module" is prose. Run over every module's strings and manifest descriptions after the retired words, by merge-check.sh as before.
retired-lines: 70 lines — the controller's commands, the old mesh-host <command> forms, and nox-mesh-host hand-over, which has the operator's line nox node hand-over <node> <path>. The node-engine's install-time subcommands (nox-mesh-host key, enrol, reconcile, …) are not listed: they are typed at a machine no mesh reaches yet.
Texts fixed: mesh-vault's tool description (nox secret recover --from-export on the control-node), route-adapter's README (nox settings set route-adapter "$(cat settings.json)" --node <node>).
Checks.merge-check.sh locally: checks/words tests pass and the check finds nothing in 36184 strings of 627 files; checks/paths passes; MESH_GATE is not built here, so the manifests' check printed NOT CHECKED (this PR touches no manifest). hq's words.py with MESH_CATALOG_DIR pointed at this tree passes, the copy compared. Not merged.
Order. Independent of the engine's and the controller's PRs; hq's PR carries the list's source.
hq issue 356, ADR 0272's progressive insight of 2026-10-09 (the operator's rule): the operator types one command, `nox` (`mesh-cli`); the node-engine and the controller are daemons, and a person never types their names. A module's condition had told the operator to run the node-engine's `hand-over` at the machine, and nothing held the catalogue's texts to the rule.
**Reviewers' checklist**
- **Validate every caller value.** `readLines` refuses a `retired-lines` entry that is not `<daemon> <command>` (exit 2); an empty list is exit 2 ("the check would pass on anything"), as the words list already is.
- **Trust-changing acts.** None: a check, read-only.
- **Every test fails with its check removed.** `TestADaemonsLineIsFoundWhole`: twelve pattern cases — a line found whole, across a line break, in a code span, after a prompt; not found joined to another word, as a plain-English verb, as prose naming the daemon beside a noun ("the mesh-controller module is assigned"), or as a command that needs an argument without one; and `nox-mesh-host hand-over` found while `nox node hand-over` is not — plus one finding's exact words. `TestRetiredLinesAreReadAsDaemonAndCommand`: the list's format, the ` …` marker, a malformed entry refused.
- **Fail closed.** A finding is exit 1 and names the file, the line and the words; the list cannot be empty or malformed.
**What changes**
- `checks/words/lines.go`: the daemons' lines, read from `retired-lines` at the catalogue's root — a copy of what hq's `words.py --list lines` prints, which hq's check compares when `MESH_CATALOG_DIR` is set (the same arrangement as `retired-words`). A command marked ` …` is a line only with an argument after it, matched as a line is written (at the start of a line or a code span, a prompt allowed), because "the mesh-controller module" is prose. Run over every module's strings and manifest descriptions after the retired words, by `merge-check.sh` as before.
- `retired-lines`: 70 lines — the controller's commands, the old `mesh-host <command>` forms, and `nox-mesh-host hand-over`, which has the operator's line `nox node hand-over <node> <path>`. The node-engine's install-time subcommands (`nox-mesh-host key`, `enrol`, `reconcile`, …) are not listed: they are typed at a machine no mesh reaches yet.
- Texts fixed: mesh-vault's tool description (`nox secret recover --from-export` on the control-node), route-adapter's README (`nox settings set route-adapter "$(cat settings.json)" --node <node>`).
**Checks.** `merge-check.sh` locally: `checks/words` tests pass and the check finds nothing in 36184 strings of 627 files; `checks/paths` passes; `MESH_GATE` is not built here, so the manifests' check printed NOT CHECKED (this PR touches no manifest). hq's `words.py` with `MESH_CATALOG_DIR` pointed at this tree passes, the copy compared. Not merged.
**Order.** Independent of the engine's and the controller's PRs; hq's PR carries the list's source.
mesh/delivery covered after its failure: a later walk that contains it was delivered: plan-1792148283013560219 (novox/mesh-catalog at 3db85a0d into main,…
A condition told the operator to type the node-engine's binary at the machine, and nothing held the catalogue's texts to ADR 0272. The words check gains retired-lines — the controller's and the node-engine's commands, copied from hq's words.py --list lines, which compares it — and refuses one in any string a module's tools can show or any manifest description. The vault's and the route adapter's texts now say the nox line.
Deliverynovox/mesh-catalog@dd14526870be — failed since 2026-10-09T17:35:29Z
Covered: covered after its failure: a later walk that contains it was delivered: plan-1792148283013560219 (novox/mesh-catalog at 3db85a0d into main, done, contains its merge ac7400d2)
Delivery plan — builds mesh-vault → novox; no bus step
tier 0: mesh-vault
novox: receives mesh-vault
mesh-vault provides secret: its consumers are sent again after it
mesh-vault keeps data (ADR 0233): what it holds is backed up before it moves
Machines
mesh-vault on novox: judging — 0 healthy judging(s) so far
build-agent on ace: passed — carried by plan-1791567255449410220
route-proxy on ace: passed — carried by plan-1791567255449410220
Transitions
2026-10-09 16:36 (new) → proposed (announced): novox/mesh-catalog#165's head announced
2026-10-09 16:38 proposed → checked (checked): the verdict names this commit
2026-10-09 16:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-09 17:34 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-09 17:34 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
2026-10-09 17:35 delivering → failed (failed): its walk failed: a gate on a first machine (what it carried put back), a build, a machine
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@dd14526870be` — **failed** since 2026-10-09T17:35:29Z
**Covered**: covered after its failure: a later walk that contains it was delivered: plan-1792148283013560219 (novox/mesh-catalog at 3db85a0d into main, done, contains its merge ac7400d2)
**Delivery plan** — builds mesh-vault → novox; no bus step
- tier 0: mesh-vault
- novox: receives mesh-vault
- mesh-vault provides secret: its consumers are sent again after it
- mesh-vault keeps data (ADR 0233): what it holds is backed up before it moves
**Machines**
- mesh-vault on novox: judging — 0 healthy judging(s) so far
- build-agent on ace: passed — carried by plan-1791567255449410220
- route-proxy on ace: passed — carried by plan-1791567255449410220
**Transitions**
- 2026-10-09 16:36 (new) → proposed (announced): novox/mesh-catalog#165's head announced
- 2026-10-09 16:38 proposed → checked (checked): the verdict names this commit
- 2026-10-09 16:38 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-09 17:34 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-09 17:34 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
- 2026-10-09 17:35 delivering → failed (failed): its walk failed: a gate on a first machine (what it carried put back), a build, a machine
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
The record: hq #256 (issue 356), which carries the list's source (words.py --list lines) and compares this copy. The engine's and the controller's sides are mesh-host #74 and mesh-controller #187.
The record: hq #256 (issue 356), which carries the list's source (`words.py --list lines`) and compares this copy. The engine's and the controller's sides are mesh-host #74 and mesh-controller #187.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: mesh-vault)
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 mesh-vault → novox; no bus step
tier 0: mesh-vault
novox: receives mesh-vault
mesh-vault provides secret: its consumers are sent again after it
mesh-vault keeps data (ADR 0233): what it holds is backed up before it moves
read by no module's build: checks/words/lines.go, checks/words/main.go, checks/words/main_test.go, retired-lines
Run by the build seat on shanks as build-1791563763421966019 (builds --log build-1791563763421966019).
--- the gate: mesh-vault
mesh-vault: ok, keeps state (valuable), ledger (valuable), root (valuable)
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-09T16:31:14Z 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-09T16:31:14Z
modules the change moves:
- mesh-vault (changed)
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 1 module(s) in 1 tier(s): mesh-vault
notes:
- checks/words/lines.go, checks/words/main.go, checks/words/main_test.go and retired-lines 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 36184 strings of 627 files
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: 70, as kept
modules/mesh-vault is TypeScript: merge-check-typescript.sh type-checks and tests it
--- its merge-check-typescript.sh (typescript toolchain)
type-checking modules/mesh-vault (TypeScript)
testing modules/mesh-vault (TypeScript)
✔ a first delivery is a grant, the same value again is nothing, a new value is a rotation (2.861296ms)
✔ the ledger holds fingerprints and never the value, in files nobody else can read (0.889038ms)
✔ withdrawing forgets a holder, and listing is by login (9.437216ms)
✔ a login is a name, not a path (1.273412ms)
✔ what the mesh delivers is read from the contributions file and fingerprinted, never returned (0.675746ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 113.846366
**Merge check** at `dd145268`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: mesh-vault)
- `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 mesh-vault → novox; no bus step
- tier 0: mesh-vault
- novox: receives mesh-vault
- mesh-vault provides secret: its consumers are sent again after it
- mesh-vault keeps data (ADR 0233): what it holds is backed up before it moves
- read by no module's build: checks/words/lines.go, checks/words/main.go, checks/words/main_test.go, retired-lines
Run by the build seat on shanks as `build-1791563763421966019` (`builds --log build-1791563763421966019`).
```
--- the gate: mesh-vault
mesh-vault: ok, keeps state (valuable), ledger (valuable), root (valuable)
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-09T16:31:14Z 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-09T16:31:14Z
modules the change moves:
- mesh-vault (changed)
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 1 module(s) in 1 tier(s): mesh-vault
notes:
- checks/words/lines.go, checks/words/main.go, checks/words/main_test.go and retired-lines 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 36184 strings of 627 files
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: 70, as kept
modules/mesh-vault is TypeScript: merge-check-typescript.sh type-checks and tests it
--- its merge-check-typescript.sh (typescript toolchain)
type-checking modules/mesh-vault (TypeScript)
testing modules/mesh-vault (TypeScript)
✔ a first delivery is a grant, the same value again is nothing, a new value is a rotation (2.861296ms)
✔ the ledger holds fingerprints and never the value, in files nobody else can read (0.889038ms)
✔ withdrawing forgets a holder, and listing is by login (9.437216ms)
✔ a login is a name, not a path (1.273412ms)
✔ what the mesh delivers is read from the contributions file and fingerprinted, never returned (0.675746ms)
ℹ tests 5
ℹ suites 0
ℹ pass 5
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 113.846366
```
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.
hq issue 356, ADR 0272's progressive insight of 2026-10-09 (the operator's rule): the operator types one command,
nox(mesh-cli); the node-engine and the controller are daemons, and a person never types their names. A module's condition had told the operator to run the node-engine'shand-overat the machine, and nothing held the catalogue's texts to the rule.Reviewers' checklist
readLinesrefuses aretired-linesentry that is not<daemon> <command>(exit 2); an empty list is exit 2 ("the check would pass on anything"), as the words list already is.TestADaemonsLineIsFoundWhole: twelve pattern cases — a line found whole, across a line break, in a code span, after a prompt; not found joined to another word, as a plain-English verb, as prose naming the daemon beside a noun ("the mesh-controller module is assigned"), or as a command that needs an argument without one; andnox-mesh-host hand-overfound whilenox node hand-overis not — plus one finding's exact words.TestRetiredLinesAreReadAsDaemonAndCommand: the list's format, the…marker, a malformed entry refused.What changes
checks/words/lines.go: the daemons' lines, read fromretired-linesat the catalogue's root — a copy of what hq'swords.py --list linesprints, which hq's check compares whenMESH_CATALOG_DIRis set (the same arrangement asretired-words). A command marked…is a line only with an argument after it, matched as a line is written (at the start of a line or a code span, a prompt allowed), because "the mesh-controller module" is prose. Run over every module's strings and manifest descriptions after the retired words, bymerge-check.shas before.retired-lines: 70 lines — the controller's commands, the oldmesh-host <command>forms, andnox-mesh-host hand-over, which has the operator's linenox node hand-over <node> <path>. The node-engine's install-time subcommands (nox-mesh-host key,enrol,reconcile, …) are not listed: they are typed at a machine no mesh reaches yet.nox secret recover --from-exporton the control-node), route-adapter's README (nox settings set route-adapter "$(cat settings.json)" --node <node>).Checks.
merge-check.shlocally:checks/wordstests pass and the check finds nothing in 36184 strings of 627 files;checks/pathspasses;MESH_GATEis not built here, so the manifests' check printed NOT CHECKED (this PR touches no manifest). hq'swords.pywithMESH_CATALOG_DIRpointed at this tree passes, the copy compared. Not merged.Order. Independent of the engine's and the controller's PRs; hq's PR carries the list's source.
Delivery
novox/mesh-catalog@dd14526870be— failed since 2026-10-09T17:35:29ZCovered: covered after its failure: a later walk that contains it was delivered: plan-1792148283013560219 (novox/mesh-catalog at
3db85a0dinto main, done, contains its mergeac7400d2)Delivery plan — builds mesh-vault → novox; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.The record: hq #256 (issue 356), which carries the list's source (
words.py --list lines) and compares this copy. The engine's and the controller's sides are mesh-host #74 and mesh-controller #187.Merge check at
dd145268mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: mesh-vault)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 mesh-vault → novox; no bus step
Run by the build seat on shanks as
build-1791563763421966019(builds --log build-1791563763421966019).