Why. The second review of mesh-catalog #147 found that ${setting:} is substituted only into file content (setting_into.go). The zfs module declares the distribution's timer for the operator's pool as zfs-scrub-weekly@${setting:scrub-pool}.timer, so the home server would have been sent that literal unit name and the apply would have failed. The pool cannot be written into the definition (hq ADR 0112).
What changes.
A service resource's unit now takes ${setting:} from the same layers a file does: the module's defaults, then the mesh's layer, then the node's.
A key that nothing sets is refused by name, as for a file. The refusal leaves the resource unchanged.
The value is refused unless it matches ^[A-Za-z0-9:_.-]+$. The name ends up in systemctl arguments and unit paths, so a space, a slash, a newline, an @, a \ escape, *, $(…) or an empty value must never reach them.
A key that a unit asks for is not called stray, and JudgeSettings sees it.
Tests, written first:internal/catalogue/setting_in_unit_test.go. Against main, all three behaviour tests failed: the unit was composed as zfs-scrub-weekly@${setting:scrub-pool}.timer, and nothing was refused.
Composed with real settings (the adopted anchor with scrub-pool=storage and scrub-cadence=monthly, through Compose):
Refused:"", stor age, a/b, storage\nExecStart=/bin/sh, a@b, $(x), * and a\\x2d, each named by its key, with the resource unchanged.
go vet and go test ./... pass locally. Needed by mesh-catalog #147 before the zfs module goes on the home server.
**Why.** The second review of mesh-catalog #147 found that `${setting:}` is substituted only into file content (`setting_into.go`). The zfs module declares the distribution's timer for the operator's pool as `zfs-scrub-weekly@${setting:scrub-pool}.timer`, so the home server would have been sent that literal unit name and the apply would have failed. The pool cannot be written into the definition (hq ADR 0112).
**What changes.**
- A `service` resource's `unit` now takes `${setting:}` from the same layers a file does: the module's defaults, then the mesh's layer, then the node's.
- A key that nothing sets is refused by name, as for a file. The refusal leaves the resource unchanged.
- The value is refused unless it matches `^[A-Za-z0-9:_.-]+$`. The name ends up in systemctl arguments and unit paths, so a space, a slash, a newline, an `@`, a `\` escape, `*`, `$(…)` or an empty value must never reach them.
- A key that a unit asks for is not called stray, and `JudgeSettings` sees it.
**Tests, written first:** `internal/catalogue/setting_in_unit_test.go`. Against main, all three behaviour tests failed: the unit was composed as `zfs-scrub-weekly@${setting:scrub-pool}.timer`, and nothing was refused.
- **Composed with real settings** (the adopted anchor with `scrub-pool=storage` and `scrub-cadence=monthly`, through `Compose`):
- `zfs.distribution-weekly` → `zfs-scrub-weekly@storage.timer`
- `zfs.distribution-monthly` → `zfs-scrub-monthly@storage.timer`
- the file → `pool=storage\ncadence=monthly\n`
- **Refused:** `""`, `stor age`, `a/b`, `storage\nExecStart=/bin/sh`, `a@b`, `$(x)`, `*` and `a\\x2d`, each named by its key, with the resource unchanged.
`go vet` and `go test ./...` pass locally. Needed by mesh-catalog #147 before the zfs module goes on the home server.
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
A module that holds the distribution's scrub timer for the pool the operator names
(zfs-scrub-weekly@<pool>.timer) cannot write the pool into its definition (hq ADR 0112). Settings were
substituted only into file content, so the unit reached the machine as
"zfs-scrub-weekly@${setting:scrub-pool}.timer", a unit no machine has, and the apply failed far from its
cause (second review of mesh-catalog #147).
A service's unit now takes ${setting:} from the same layers a file does, and is refused by key when
nothing sets it. A value is also refused unless it is only letters, digits, ':', '_', '.' and '-': the
name ends up in unit files and systemctl arguments, and a space, a slash or a newline must never reach
them. A key a unit asks for is not called stray.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Machines
mesh-controller on novox: passed — healthy 3 times over 3m48s
mesh-controller on the rest running it: sent
build-agent on ace: passed — healthy 3 times over 3m39s
build-agent on the rest running it: sent
route-proxy on ace: passed — healthy 3 times over 3m43s
route-proxy on the rest running it: sent
Transitions
2026-10-08 23:51 (new) → proposed (announced): novox/mesh-controller#171's head announced
2026-10-08 23:57 proposed → checked (checked): the verdict names this commit
2026-10-08 23:57 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-09 00:25 ready → proposed (recheck): checked at 23:57Z before #170 merged (both touch catalogue settings); check against today's main before merging
2026-10-09 00:30 proposed → checked (checked): the verdict names this commit
2026-10-09 00:30 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-09 00:33 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 00:33 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 00:48 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-controller@eb5f9d2f531b` — **delivered** since 2026-10-09T00:48:21Z
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
**Machines**
- mesh-controller on novox: passed — healthy 3 times over 3m48s
- mesh-controller on the rest running it: sent
- build-agent on ace: passed — healthy 3 times over 3m39s
- build-agent on the rest running it: sent
- route-proxy on ace: passed — healthy 3 times over 3m43s
- route-proxy on the rest running it: sent
**Transitions**
- 2026-10-08 23:51 (new) → proposed (announced): novox/mesh-controller#171's head announced
- 2026-10-08 23:57 proposed → checked (checked): the verdict names this commit
- 2026-10-08 23:57 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-09 00:25 ready → proposed (recheck): checked at 23:57Z before #170 merged (both touch catalogue settings); check against today's main before merging
- 2026-10-09 00:30 proposed → checked (checked): the verdict names this commit
- 2026-10-09 00:30 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-09 00:33 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 00:33 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 00:48 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on ace as build-1791502365709598177 (builds --log build-1791502365709598177).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T23:23:48Z 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-08T23:23:48Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.037s
ok github.com/novox/mesh-controller/cmd/mesh-controller 166.579s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.017s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/route-proxy 1.114s
ok github.com/novox/mesh-controller/internal/artifacts 1.042s
ok github.com/novox/mesh-controller/internal/broker 2.512s
ok github.com/novox/mesh-controller/internal/builder 1.803s
ok github.com/novox/mesh-controller/internal/catalogue 4.123s
ok github.com/novox/mesh-controller/internal/conditions 2.157s
ok github.com/novox/mesh-controller/internal/envfile 1.047s
ok github.com/novox/mesh-controller/internal/facts 1.072s
ok github.com/novox/mesh-controller/internal/identity 4.058s
ok github.com/novox/mesh-controller/internal/inventory 71.200s
ok github.com/novox/mesh-controller/internal/lease 17.714s
ok github.com/novox/mesh-controller/internal/licences 3.711s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.068s
ok github.com/novox/mesh-controller/internal/link 50.665s
ok github.com/novox/mesh-controller/internal/lint 1.934s
ok github.com/novox/mesh-controller/internal/outward 1.098s
ok github.com/novox/mesh-controller/internal/overlay 1.054s
ok github.com/novox/mesh-controller/internal/secrets 1.435s
ok github.com/novox/mesh-controller/internal/store 3.256s
ok github.com/novox/mesh-controller/internal/testbus 1.219s
ok github.com/novox/mesh-controller/internal/token 1.015s
**Merge check** at `e4d28686`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on ace as `build-1791502365709598177` (`builds --log build-1791502365709598177`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T23:23:48Z 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-08T23:23:48Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.037s
ok github.com/novox/mesh-controller/cmd/mesh-controller 166.579s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.017s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/route-proxy 1.114s
ok github.com/novox/mesh-controller/internal/artifacts 1.042s
ok github.com/novox/mesh-controller/internal/broker 2.512s
ok github.com/novox/mesh-controller/internal/builder 1.803s
ok github.com/novox/mesh-controller/internal/catalogue 4.123s
ok github.com/novox/mesh-controller/internal/conditions 2.157s
ok github.com/novox/mesh-controller/internal/envfile 1.047s
ok github.com/novox/mesh-controller/internal/facts 1.072s
ok github.com/novox/mesh-controller/internal/identity 4.058s
ok github.com/novox/mesh-controller/internal/inventory 71.200s
ok github.com/novox/mesh-controller/internal/lease 17.714s
ok github.com/novox/mesh-controller/internal/licences 3.711s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.068s
ok github.com/novox/mesh-controller/internal/link 50.665s
ok github.com/novox/mesh-controller/internal/lint 1.934s
ok github.com/novox/mesh-controller/internal/outward 1.098s
ok github.com/novox/mesh-controller/internal/overlay 1.054s
ok github.com/novox/mesh-controller/internal/secrets 1.435s
ok github.com/novox/mesh-controller/internal/store 3.256s
ok github.com/novox/mesh-controller/internal/testbus 1.219s
ok github.com/novox/mesh-controller/internal/token 1.015s
```
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
Third review of mesh-catalog #147. A setting anywhere else in a unit's name could make the unit another
unit or another kind; it is now refused where the manifest is read. A value beginning with '-' would be
read by systemctl as an option, and a long one is no pool's name.
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on shanks as build-1791503516706395670 (builds --log build-1791503516706395670).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T23:47:08Z 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-08T23:47:08Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.036s
ok github.com/novox/mesh-controller/cmd/mesh-controller 193.408s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.041s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.054s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.055s
ok github.com/novox/mesh-controller/examples/route-proxy 1.210s
ok github.com/novox/mesh-controller/internal/artifacts 1.082s
ok github.com/novox/mesh-controller/internal/broker 2.795s
ok github.com/novox/mesh-controller/internal/builder 1.964s
ok github.com/novox/mesh-controller/internal/catalogue 4.987s
ok github.com/novox/mesh-controller/internal/conditions 2.227s
ok github.com/novox/mesh-controller/internal/envfile 1.042s
ok github.com/novox/mesh-controller/internal/facts 1.058s
ok github.com/novox/mesh-controller/internal/identity 4.803s
ok github.com/novox/mesh-controller/internal/inventory 84.725s
ok github.com/novox/mesh-controller/internal/lease 17.704s
ok github.com/novox/mesh-controller/internal/licences 4.360s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.053s
ok github.com/novox/mesh-controller/internal/link 53.238s
ok github.com/novox/mesh-controller/internal/lint 2.194s
ok github.com/novox/mesh-controller/internal/outward 1.084s
ok github.com/novox/mesh-controller/internal/overlay 1.076s
ok github.com/novox/mesh-controller/internal/secrets 1.544s
ok github.com/novox/mesh-controller/internal/store 3.501s
ok github.com/novox/mesh-controller/internal/testbus 1.229s
ok github.com/novox/mesh-controller/internal/token 1.014s
**Merge check** at `eb5f9d2f`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on shanks as `build-1791503516706395670` (`builds --log build-1791503516706395670`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-08T23:47:08Z 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-08T23:47:08Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.036s
ok github.com/novox/mesh-controller/cmd/mesh-controller 193.408s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.041s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.054s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.055s
ok github.com/novox/mesh-controller/examples/route-proxy 1.210s
ok github.com/novox/mesh-controller/internal/artifacts 1.082s
ok github.com/novox/mesh-controller/internal/broker 2.795s
ok github.com/novox/mesh-controller/internal/builder 1.964s
ok github.com/novox/mesh-controller/internal/catalogue 4.987s
ok github.com/novox/mesh-controller/internal/conditions 2.227s
ok github.com/novox/mesh-controller/internal/envfile 1.042s
ok github.com/novox/mesh-controller/internal/facts 1.058s
ok github.com/novox/mesh-controller/internal/identity 4.803s
ok github.com/novox/mesh-controller/internal/inventory 84.725s
ok github.com/novox/mesh-controller/internal/lease 17.704s
ok github.com/novox/mesh-controller/internal/licences 4.360s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.053s
ok github.com/novox/mesh-controller/internal/link 53.238s
ok github.com/novox/mesh-controller/internal/lint 2.194s
ok github.com/novox/mesh-controller/internal/outward 1.084s
ok github.com/novox/mesh-controller/internal/overlay 1.076s
ok github.com/novox/mesh-controller/internal/secrets 1.544s
ok github.com/novox/mesh-controller/internal/store 3.501s
ok github.com/novox/mesh-controller/internal/testbus 1.229s
ok github.com/novox/mesh-controller/internal/token 1.014s
```
build-agent keeps data (ADR 0233): what it holds is backed up before it moves
route-proxy provides route: its consumers are sent again after it
route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on shanks as build-1791505542851415146 (builds --log build-1791505542851415146).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T00:16:57Z 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-09T00:16:57Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.041s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.700s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.019s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/route-proxy 1.208s
ok github.com/novox/mesh-controller/internal/artifacts 1.095s
ok github.com/novox/mesh-controller/internal/broker 2.716s
ok github.com/novox/mesh-controller/internal/builder 1.944s
ok github.com/novox/mesh-controller/internal/catalogue 4.901s
ok github.com/novox/mesh-controller/internal/conditions 2.236s
ok github.com/novox/mesh-controller/internal/envfile 1.043s
ok github.com/novox/mesh-controller/internal/facts 1.066s
ok github.com/novox/mesh-controller/internal/identity 4.786s
ok github.com/novox/mesh-controller/internal/inventory 83.241s
ok github.com/novox/mesh-controller/internal/lease 17.711s
ok github.com/novox/mesh-controller/internal/licences 4.292s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.063s
ok github.com/novox/mesh-controller/internal/link 53.017s
ok github.com/novox/mesh-controller/internal/lint 2.147s
ok github.com/novox/mesh-controller/internal/outward 1.091s
ok github.com/novox/mesh-controller/internal/overlay 1.069s
ok github.com/novox/mesh-controller/internal/secrets 1.540s
ok github.com/novox/mesh-controller/internal/store 3.414s
ok github.com/novox/mesh-controller/internal/testbus 1.192s
ok github.com/novox/mesh-controller/internal/token 1.015s
**Merge check** at `eb5f9d2f`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Delivery plan** — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
- tier 0: mesh-controller
- tier 1: build-agent
- tier 2: route-proxy
- ace: receives build-agent, route-proxy
- g14: receives build-agent
- novox: receives mesh-controller, build-agent, route-proxy
- shanks: receives build-agent
- build-agent keeps data (ADR 0233): what it holds is backed up before it moves
- route-proxy provides route: its consumers are sent again after it
- route-proxy keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on shanks as `build-1791505542851415146` (`builds --log build-1791505542851415146`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 52 tool(s); WARNING: controller stay(s) up and say(s) not how it is ready — judged by liveness alone, refused from 2026-11-18 (ADR 0240 rule 8)
long-running resources without health: 1
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 0 module(s) changed against 4 machine(s), as the snapshot of 2026-10-09T00:16:57Z 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-09T00:16:57Z
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 3 module(s) in 3 tier(s): build-agent, mesh-controller, route-proxy
--- its merge-check.sh (go toolchain)
ok github.com/novox/mesh-controller/cmd/mesh-builder 1.041s
ok github.com/novox/mesh-controller/cmd/mesh-controller 187.700s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.019s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/route-proxy 1.208s
ok github.com/novox/mesh-controller/internal/artifacts 1.095s
ok github.com/novox/mesh-controller/internal/broker 2.716s
ok github.com/novox/mesh-controller/internal/builder 1.944s
ok github.com/novox/mesh-controller/internal/catalogue 4.901s
ok github.com/novox/mesh-controller/internal/conditions 2.236s
ok github.com/novox/mesh-controller/internal/envfile 1.043s
ok github.com/novox/mesh-controller/internal/facts 1.066s
ok github.com/novox/mesh-controller/internal/identity 4.786s
ok github.com/novox/mesh-controller/internal/inventory 83.241s
ok github.com/novox/mesh-controller/internal/lease 17.711s
ok github.com/novox/mesh-controller/internal/licences 4.292s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.063s
ok github.com/novox/mesh-controller/internal/link 53.017s
ok github.com/novox/mesh-controller/internal/lint 2.147s
ok github.com/novox/mesh-controller/internal/outward 1.091s
ok github.com/novox/mesh-controller/internal/overlay 1.069s
ok github.com/novox/mesh-controller/internal/secrets 1.540s
ok github.com/novox/mesh-controller/internal/store 3.414s
ok github.com/novox/mesh-controller/internal/testbus 1.192s
ok github.com/novox/mesh-controller/internal/token 1.015s
```
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.
Why. The second review of mesh-catalog #147 found that
${setting:}is substituted only into file content (setting_into.go). The zfs module declares the distribution's timer for the operator's pool aszfs-scrub-weekly@${setting:scrub-pool}.timer, so the home server would have been sent that literal unit name and the apply would have failed. The pool cannot be written into the definition (hq ADR 0112).What changes.
serviceresource'sunitnow takes${setting:}from the same layers a file does: the module's defaults, then the mesh's layer, then the node's.^[A-Za-z0-9:_.-]+$. The name ends up in systemctl arguments and unit paths, so a space, a slash, a newline, an@, a\escape,*,$(…)or an empty value must never reach them.JudgeSettingssees it.Tests, written first:
internal/catalogue/setting_in_unit_test.go. Against main, all three behaviour tests failed: the unit was composed aszfs-scrub-weekly@${setting:scrub-pool}.timer, and nothing was refused.scrub-pool=storageandscrub-cadence=monthly, throughCompose):zfs.distribution-weekly→zfs-scrub-weekly@storage.timerzfs.distribution-monthly→zfs-scrub-monthly@storage.timerpool=storage\ncadence=monthly\n"",stor age,a/b,storage\nExecStart=/bin/sh,a@b,$(x),*anda\\x2d, each named by its key, with the resource unchanged.go vetandgo test ./...pass locally. Needed by mesh-catalog #147 before the zfs module goes on the home server.A module that holds the distribution's scrub timer for the pool the operator names (zfs-scrub-weekly@<pool>.timer) cannot write the pool into its definition (hq ADR 0112). Settings were substituted only into file content, so the unit reached the machine as "zfs-scrub-weekly@${setting:scrub-pool}.timer", a unit no machine has, and the apply failed far from its cause (second review of mesh-catalog #147). A service's unit now takes ${setting:} from the same layers a file does, and is refused by key when nothing sets it. A value is also refused unless it is only letters, digits, ':', '_', '.' and '-': the name ends up in unit files and systemctl arguments, and a space, a slash or a newline must never reach them. A key a unit asks for is not called stray.Delivery
novox/mesh-controller@eb5f9d2f531b— delivered since 2026-10-09T00:48:21ZDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
e4d28686mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791502365709598177(builds --log build-1791502365709598177).Merge check at
eb5f9d2fmesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791503516706395670(builds --log build-1791503516706395670).Merge check at
eb5f9d2fmesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: build-agent, mesh-controller, route-proxy)mesh/repo-check: PASS — its merge-check.sh passedDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791505542851415146(builds --log build-1791505542851415146).