Why (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool: node-service-manager.journal only gave a unit's last lines, and a person reached for a shell.
What changes (internal/catalogue/seats.go, serviceManagerVerbs):
journal takes since, until (RFC 3339 or relative to now, e.g. -30min), priority (0-7 or a name) and match (a fixed string, not a pattern), beside unit, lines (at most 2000) and scope. The holder validates every value and passes it to journalctl as one argv word (--since=<v>), never through a shell, and redacts secrets before the match is applied.
failed is a new verb: every failed unit in both managers, or in one when scope is given. It was the systemd module's own systemd_failed.
Delivery group: the claimant changes in novox/mesh-catalog on the branch of the same name (feat/journal-window-on-the-seat). Neither merges alone. With this controller, a claim that does not serve failed is refused. With the running controller, a claim that serves failed is refused as unpromised. Merge this first, then the catalogue PR, once a controller carrying these verbs runs (the build-agent precedent, mesh-catalog 0581256).
Tests: the seat-verb tests are updated (operators_machine_test.go, seat_dependencies_test.go). go test ./... passes against the catalogue branch beside it. Against catalogue main, TestModuleCheckPassesTheCatalogue fails as expected, because systemd does not yet serve failed.
**Why** (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool: `node-service-manager.journal` only gave a unit's last lines, and a person reached for a shell.
**What changes** (`internal/catalogue/seats.go`, `serviceManagerVerbs`):
- `journal` takes `since`, `until` (RFC 3339 or relative to now, e.g. `-30min`), `priority` (0-7 or a name) and `match` (a fixed string, not a pattern), beside `unit`, `lines` (at most 2000) and `scope`. The holder validates every value and passes it to journalctl as one argv word (`--since=<v>`), never through a shell, and redacts secrets before the match is applied.
- `failed` is a new verb: every failed unit in both managers, or in one when `scope` is given. It was the systemd module's own `systemd_failed`.
**Delivery group:** the claimant changes in novox/mesh-catalog on the branch of the same name (`feat/journal-window-on-the-seat`). Neither merges alone. With this controller, a claim that does not serve `failed` is refused. With the running controller, a claim that serves `failed` is refused as unpromised. Merge this first, then the catalogue PR, once a controller carrying these verbs runs (the build-agent precedent, mesh-catalog 0581256).
**Tests:** the seat-verb tests are updated (`operators_machine_test.go`, `seat_dependencies_test.go`). `go test ./...` passes against the catalogue branch beside it. Against catalogue main, `TestModuleCheckPassesTheCatalogue` fails as expected, because systemd does not yet serve `failed`.
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…
An incident is read for the minutes it happened in, and the seat's journal
verb could only give a unit's last lines: reading the controller's journal
around the control node's mail being recreated had no tool, and a person
reached for a shell. The verb now takes since, until, priority and a
fixed-string match, which its holder validates and redacts.
failed was the systemd module's own tool; on the seat, whatever holds the
role answers it and every machine is asked the same way. Its claimant in
mesh-catalog serves it on the branch of the same name.
mesh-controller on novox: passed — healthy 3 times over 3m45s
mesh-controller on the rest running it: sent
build-agent on ace: passed — healthy 3 times over 3m37s
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-07 18:05 (new) → proposed (announced): novox/mesh-controller#114's head announced
2026-10-07 18:30 proposed → checked (checked): the verdict names this commit
2026-10-07 18:30 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-07 18:35 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-07 18:35 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-07 18:54 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@13b6fc6d97f3` — **delivered** since 2026-10-07T18:54:14Z
**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
**Group** `feat/journal-window-on-the-seat`, in order: novox/mesh-controller@13b6fc6d97f3 → novox/mesh-catalog@66106d93accd
- novox/mesh-controller@13b6fc6d97f3 before novox/mesh-catalog@66106d93accd: built by
**Machines**
- mesh-controller on novox: passed — healthy 3 times over 3m45s
- mesh-controller on the rest running it: sent
- build-agent on ace: passed — healthy 3 times over 3m37s
- 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-07 18:05 (new) → proposed (announced): novox/mesh-controller#114's head announced
- 2026-10-07 18:30 proposed → checked (checked): the verdict names this commit
- 2026-10-07 18:30 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-07 18:35 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-07 18:35 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-07 18:54 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-1791393863338413952 (builds --log build-1791393863338413952).
the hub — it takes over the tunnel it found on wg0: range 192.0.2.0/24, port 51900, 1 peer(s) carried until they enrol
at hosting, so it peers directly with anything else there
anchor is at 192.0.2.1 on the overlay
credentials issued for it before this placement keep their old broker address — `module issue` them again and push (novox/hq issue 059)
the hub — it takes over the tunnel it found on wg0: range 192.0.2.0/24, port 51900, 0 peer(s) carried until they enrol
at here, so it peers directly with anything else there
anchor composes its routed names under example.test
anchor has no public domain, so it composes no routed names
run `push anchor` to take them off it
anchor composes its routed names under example.test
run `push anchor` to send it
added joiner (ee660354-c86d-4c09-b11f-a319e1c10175), adopted
added plain (540b5789-c668-4f9d-a7ad-541aecb6a701)
plan-213: done — r at abc, 1 tier(s)
spare owns nothing now — sent so it drops what it last held
tier 0: plan-retry: tier 0 done; asking tier 1: b
tier 1: tier 0: rebuild asked as build-1791394304159778982, joining plan-join at tier 0 (novox/a at c0ffee): the plan takes this build as a's outcome; the plan had failed and builds again from this tier
rebuild asked as build-1791394304197382070
build-1791394305525809915: could not build https://forge.example/novox/a.git:
cancelled by hand
plan-cancel: a failed to build in tier 0; the tiers after it are not asked
cancelled build-1791394305525809915 (https://forge.example/novox/a.git, waiting): deleted from the node-build-agent queue and recorded failed, cancelled by hand — a plan that asked for it fails with that
build-1791394306976353271: could not build https://forge.example/novox/w1.git:
cancelled by hand
build-1791394306977353271: could not build https://forge.example/novox/w2.git:
cancelled by hand
build-1791394306975353271: could not build https://forge.example/novox/dead.git:
cancelled by hand
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: killed build-running
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: ace is not building build-other
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: ace is paused
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
g14: nothing on g14 answers node-build-agent.resume: its holder is not running, or is older than the verb
plan-rollout: tier 0 done; asking tier 1: b
tier 1: plan-own: done — novox/a at c0ffee, 1 tier(s)
build-at-commit was built at commit 01234567; a rebuild asks what a follows now, main — `replay build-at-commit` builds that commit
rebuild asked as build-1791394321459740935
plan-1: mesh-controller settled from the build records as built (build-2)
plan-3: postgres settled from the build records as built (build-mine)
plan-2: x settled from the build records as failed (b)
release-1791394326469769967: 2 build(s) wait for a gate on anchor, laptop; one machine at a time, each judged
release-1791394326469769967: sent anchor 1 build(s) that waited for a gate; judging them there
release-1791394326469769967: sent laptop 2 build(s) that waited for a gate; judging them there
release-1791394330010233260: 2 build(s) wait for a gate on anchor, laptop; one machine at a time, each judged
release-1791394330010233260: sent anchor 1 build(s) that waited for a gate; judging them there
app's build c2 failed its gate on anchor and was put back to c1: anchor failed what it was sent
release-1791394330010233260: failed its gate on anchor: anchor failed what it was sent — app failed its gate on anchor in tier 0: anchor failed what it was sent; put back app to c1 on anchor, in one send
this act by hand could NOT be recorded in the hand-act log, and is done anyway: this control plane has no MESH_BUS_NATS, so it cannot reach the mesh's bus
release-1791394330402832186: 1 build(s) wait for a gate on laptop; one machine at a time, each judged
release-1791394330402832186 releases it; `plans release-1791394330402832186` says where it is
release-1791394330402832186: sent laptop 1 build(s) that waited for a gate; judging them there
plan-crashloop: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
app's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: its container app.server on anchor keeps restarting (2 restart(s) counted)
plan-crashloop: app failed its gate on anchor in tier 0: not healthy within -1s of its apply: its container app.server on anchor keeps restarting (2 restart(s) counted); put back app to c1 on anchor, in one send; none reported left as it was
laptop is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
laptop is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
build-1791390743164927599: the build seat did not say whether c1aaaaaa is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390803164927599: the build seat did not say whether c2bbbbbb is on its repository's trunk (it predates ADR 0238); registered as before
app at c2bbbbbb was made from the source build-1791390743164927599 was: registered with its artifacts, no move
build-1791390863164927599: the build seat did not say whether c3cccccc is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390923164927599: the build seat did not say whether c4dddddd is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390744507244285: the build seat did not say whether n1111111 is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390804507244285: the build seat did not say whether n2222222 is on its repository's trunk (it predates ADR 0238); registered as before
nats at n2222222 was made from the source build-1791390744507244285 was: registered with its artifacts, no move
every machine running nats runs the build the mesh holds (n2222222): nothing to upgrade
build-1791390864507244285: the build seat did not say whether n3333333 is on its repository's trunk (it predates ADR 0238); registered as before
plan-gate: app built from the source every machine running it runs: no move, nothing sent
plan-gate: done — novox/mesh-catalog at c2, 1 tier(s)
plan-gate: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
status could not be composed (after 0s): the store did not answer — `status` answers the last summary, with its age
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
this act by hand could NOT be recorded in the hand-act log, and is done anyway: this control plane has no MESH_BUS_NATS, so it cannot reach the mesh's bus
plan-97b1b2b closed at tier 1 of 2; what was asked still builds and registers, nothing further is asked
plan-tier: tier 0 built; sent 12 module(s) to anchor first in one send (m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12), the rest once its gate passes
plan-tier: m01 passed its gate on anchor (healthy 3 times over 0s); the rest are sent
plan-tier: tier 0 built; sent m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12 to laptop, one send each
plan-tier: done — novox/mesh-catalog at c2, 1 tier(s)
plan-tier: tier 0 built; sent 3 module(s) to anchor first in one send (app1, app2, node-tools), the rest once its gate passes
node-tools's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound)
plan-tier: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound); app1 was not found wanting and is left as it is; node-tools failed its gate on anchor in tier 0: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound); put back node-tools to c1 on anchor, in one send; none reported left as it was
plan-tier: tier 0 built; sent 3 module(s) to anchor first in one send (app1, app2, app3), the rest once its gate passes
app1's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
app2's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
app3's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
plan-tier: app1 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; app2 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; app3 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; put back app1 to c1, app2 to c1, app3 to c1 on anchor, in one send; none reported left as it was
plan-gate: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
plan-gate: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: anchor has not reported on what it was sent; app was left as it was — anchor already ran app c2, or a build identical to it, before the send, so nothing of it moved and nothing is put back
plan-gate: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: anchor has not reported on what it was sent; app was left as it was — anchor already ran app c2, or a build identical to it, before the send, so nothing of it moved and nothing is put back; none reported left as it was
tier 0: FAIL
FAIL github.com/novox/mesh-controller/cmd/mesh-controller 423.490s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.026s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.040s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.033s
ok github.com/novox/mesh-controller/examples/route-proxy 1.124s
ok github.com/novox/mesh-controller/internal/artifacts 1.051s
ok github.com/novox/mesh-controller/internal/broker 2.382s
ok github.com/novox/mesh-controller/internal/builder 1.302s
ok github.com/novox/mesh-controller/internal/catalogue 3.590s
ok github.com/novox/mesh-controller/internal/conditions 1.978s
ok github.com/novox/mesh-controller/internal/envfile 1.035s
ok github.com/novox/mesh-controller/internal/facts 1.041s
ok github.com/novox/mesh-controller/internal/identity 55.071s
ok github.com/novox/mesh-controller/internal/inventory 274.063s
ok github.com/novox/mesh-controller/internal/lease 17.670s
ok github.com/novox/mesh-controller/internal/licences 41.460s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.034s
ok github.com/novox/mesh-controller/internal/link 92.132s
ok github.com/novox/mesh-controller/internal/lint 1.752s
ok github.com/novox/mesh-controller/internal/outward 1.058s
ok github.com/novox/mesh-controller/internal/overlay 1.048s
ok github.com/novox/mesh-controller/internal/secrets 1.407s
ok github.com/novox/mesh-controller/internal/store 23.251s
ok github.com/novox/mesh-controller/internal/testbus 1.214s
ok github.com/novox/mesh-controller/internal/token 1.017s
FAIL
**Merge check** at `40e42606`
- `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`: **FAIL** — its merge-check.sh failed: FAIL github.com/novox/mesh-controller/cmd/mesh-controller 423.490s
**Change 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-1791393863338413952` (`builds --log build-1791393863338413952`).
```
the hub — it takes over the tunnel it found on wg0: range 192.0.2.0/24, port 51900, 1 peer(s) carried until they enrol
at hosting, so it peers directly with anything else there
anchor is at 192.0.2.1 on the overlay
credentials issued for it before this placement keep their old broker address — `module issue` them again and push (novox/hq issue 059)
the hub — it takes over the tunnel it found on wg0: range 192.0.2.0/24, port 51900, 0 peer(s) carried until they enrol
at here, so it peers directly with anything else there
anchor composes its routed names under example.test
anchor has no public domain, so it composes no routed names
run `push anchor` to take them off it
anchor composes its routed names under example.test
run `push anchor` to send it
added joiner (ee660354-c86d-4c09-b11f-a319e1c10175), adopted
added plain (540b5789-c668-4f9d-a7ad-541aecb6a701)
plan-213: done — r at abc, 1 tier(s)
spare owns nothing now — sent so it drops what it last held
tier 0: plan-retry: tier 0 done; asking tier 1: b
tier 1: tier 0: rebuild asked as build-1791394304159778982, joining plan-join at tier 0 (novox/a at c0ffee): the plan takes this build as a's outcome; the plan had failed and builds again from this tier
rebuild asked as build-1791394304197382070
build-1791394305525809915: could not build https://forge.example/novox/a.git:
cancelled by hand
plan-cancel: a failed to build in tier 0; the tiers after it are not asked
cancelled build-1791394305525809915 (https://forge.example/novox/a.git, waiting): deleted from the node-build-agent queue and recorded failed, cancelled by hand — a plan that asked for it fails with that
build-1791394306976353271: could not build https://forge.example/novox/w1.git:
cancelled by hand
build-1791394306977353271: could not build https://forge.example/novox/w2.git:
cancelled by hand
build-1791394306975353271: could not build https://forge.example/novox/dead.git:
cancelled by hand
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: killed build-running
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: ace is not building build-other
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
ace: ace is paused
could not read what is assigned, so the build is asked of node-build-agent: this process has neither MESH_STORE_INVENTORY nor MESH_STORE_INVENTORY_FILE, so it was not granted the inventory store. A context reaches only the store it exclusively owns (novox/hq ADR 0008), so this is either the wrong context or a missing grant — it is never something to work around by reusing another context's connection
g14: nothing on g14 answers node-build-agent.resume: its holder is not running, or is older than the verb
plan-rollout: tier 0 done; asking tier 1: b
tier 1: plan-own: done — novox/a at c0ffee, 1 tier(s)
build-at-commit was built at commit 01234567; a rebuild asks what a follows now, main — `replay build-at-commit` builds that commit
rebuild asked as build-1791394321459740935
plan-1: mesh-controller settled from the build records as built (build-2)
plan-3: postgres settled from the build records as built (build-mine)
plan-2: x settled from the build records as failed (b)
release-1791394326469769967: 2 build(s) wait for a gate on anchor, laptop; one machine at a time, each judged
release-1791394326469769967: sent anchor 1 build(s) that waited for a gate; judging them there
release-1791394326469769967: sent laptop 2 build(s) that waited for a gate; judging them there
release-1791394330010233260: 2 build(s) wait for a gate on anchor, laptop; one machine at a time, each judged
release-1791394330010233260: sent anchor 1 build(s) that waited for a gate; judging them there
app's build c2 failed its gate on anchor and was put back to c1: anchor failed what it was sent
release-1791394330010233260: failed its gate on anchor: anchor failed what it was sent — app failed its gate on anchor in tier 0: anchor failed what it was sent; put back app to c1 on anchor, in one send
this act by hand could NOT be recorded in the hand-act log, and is done anyway: this control plane has no MESH_BUS_NATS, so it cannot reach the mesh's bus
release-1791394330402832186: 1 build(s) wait for a gate on laptop; one machine at a time, each judged
release-1791394330402832186 releases it; `plans release-1791394330402832186` says where it is
release-1791394330402832186: sent laptop 1 build(s) that waited for a gate; judging them there
plan-crashloop: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
app's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: its container app.server on anchor keeps restarting (2 restart(s) counted)
plan-crashloop: app failed its gate on anchor in tier 0: not healthy within -1s of its apply: its container app.server on anchor keeps restarting (2 restart(s) counted); put back app to c1 on anchor, in one send; none reported left as it was
laptop is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
laptop is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
build-1791390743164927599: the build seat did not say whether c1aaaaaa is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390803164927599: the build seat did not say whether c2bbbbbb is on its repository's trunk (it predates ADR 0238); registered as before
app at c2bbbbbb was made from the source build-1791390743164927599 was: registered with its artifacts, no move
build-1791390863164927599: the build seat did not say whether c3cccccc is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390923164927599: the build seat did not say whether c4dddddd is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390744507244285: the build seat did not say whether n1111111 is on its repository's trunk (it predates ADR 0238); registered as before
build-1791390804507244285: the build seat did not say whether n2222222 is on its repository's trunk (it predates ADR 0238); registered as before
nats at n2222222 was made from the source build-1791390744507244285 was: registered with its artifacts, no move
every machine running nats runs the build the mesh holds (n2222222): nothing to upgrade
build-1791390864507244285: the build seat did not say whether n3333333 is on its repository's trunk (it predates ADR 0238); registered as before
plan-gate: app built from the source every machine running it runs: no move, nothing sent
plan-gate: done — novox/mesh-catalog at c2, 1 tier(s)
plan-gate: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
status could not be composed (after 0s): the store did not answer — `status` answers the last summary, with its age
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is left out of the rest of the mesh: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
anchor is not counted as on the network: it does not resolve: these assignments cannot be applied:
- rival-one and rival-two both claim "the-seat", and only one thing may hold it per node
this act by hand could NOT be recorded in the hand-act log, and is done anyway: this control plane has no MESH_BUS_NATS, so it cannot reach the mesh's bus
plan-97b1b2b closed at tier 1 of 2; what was asked still builds and registers, nothing further is asked
plan-tier: tier 0 built; sent 12 module(s) to anchor first in one send (m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12), the rest once its gate passes
plan-tier: m01 passed its gate on anchor (healthy 3 times over 0s); the rest are sent
plan-tier: tier 0 built; sent m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12 to laptop, one send each
plan-tier: done — novox/mesh-catalog at c2, 1 tier(s)
plan-tier: tier 0 built; sent 3 module(s) to anchor first in one send (app1, app2, node-tools), the rest once its gate passes
node-tools's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound)
plan-tier: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound); app1 was not found wanting and is left as it is; node-tools failed its gate on anchor in tier 0: not healthy within -1s of its apply: raised since it was sent: machine.anchor.core-behind — anchor runs the node tools it was last sent, not yet reported applied, and no plan is rolling them out (its settle window runs to the gate's bound); put back node-tools to c1 on anchor, in one send; none reported left as it was
plan-tier: tier 0 built; sent 3 module(s) to anchor first in one send (app1, app2, app3), the rest once its gate passes
app1's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
app2's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
app3's build c2 failed its gate on anchor and was put back to c1: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full
plan-tier: app1 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; app2 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; app3 failed its gate on anchor in tier 0: not healthy within -1s of its apply: anchor as a whole: raised since it was sent: machine.anchor.disk-full — anchor's root file system is full; put back app1 to c1, app2 to c1, app3 to c1 on anchor, in one send; none reported left as it was
plan-gate: tier 0 built; sent 1 module(s) to anchor first in one send (app), the rest once its gate passes
plan-gate: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: anchor has not reported on what it was sent; app was left as it was — anchor already ran app c2, or a build identical to it, before the send, so nothing of it moved and nothing is put back
plan-gate: the send to anchor in tier 0 failed its gate: not healthy within -1s of its apply: anchor has not reported on what it was sent; app was left as it was — anchor already ran app c2, or a build identical to it, before the send, so nothing of it moved and nothing is put back; none reported left as it was
tier 0: FAIL
FAIL github.com/novox/mesh-controller/cmd/mesh-controller 423.490s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.026s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.040s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.033s
ok github.com/novox/mesh-controller/examples/route-proxy 1.124s
ok github.com/novox/mesh-controller/internal/artifacts 1.051s
ok github.com/novox/mesh-controller/internal/broker 2.382s
ok github.com/novox/mesh-controller/internal/builder 1.302s
ok github.com/novox/mesh-controller/internal/catalogue 3.590s
ok github.com/novox/mesh-controller/internal/conditions 1.978s
ok github.com/novox/mesh-controller/internal/envfile 1.035s
ok github.com/novox/mesh-controller/internal/facts 1.041s
ok github.com/novox/mesh-controller/internal/identity 55.071s
ok github.com/novox/mesh-controller/internal/inventory 274.063s
ok github.com/novox/mesh-controller/internal/lease 17.670s
ok github.com/novox/mesh-controller/internal/licences 41.460s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.034s
ok github.com/novox/mesh-controller/internal/link 92.132s
ok github.com/novox/mesh-controller/internal/lint 1.752s
ok github.com/novox/mesh-controller/internal/outward 1.058s
ok github.com/novox/mesh-controller/internal/overlay 1.048s
ok github.com/novox/mesh-controller/internal/secrets 1.407s
ok github.com/novox/mesh-controller/internal/store 23.251s
ok github.com/novox/mesh-controller/internal/testbus 1.214s
ok github.com/novox/mesh-controller/internal/token 1.017s
FAIL
```
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…
failed was required, so the controller refused the systemd module running
today and the module serving it was refused by the controller running
today: neither could land first. It is now optional (Verb.Optional, #117).
Two things kept either change from reaching a mesh whose seat rows already
exist: re-seeding added a verb but never an argument to one, and the
console refuses an argument the row does not name, so the journal window
would stay unreachable; and the optional mark is never stored, so a verb
seeded into a row came back required. A row's verb now gains the arguments
the binary names, and the working set takes the optional mark from the
compiled seat, which also keeps mesh-delivery's checks optional once seeded.
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-1791397243309190493 (builds --log build-1791397243309190493).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 46 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-07T18:18:34Z 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-07T18:18:34Z
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-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 464.694s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.030s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.012s
ok github.com/novox/mesh-controller/examples/route-proxy 1.223s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
ok github.com/novox/mesh-controller/internal/broker 2.562s
ok github.com/novox/mesh-controller/internal/builder 1.490s
ok github.com/novox/mesh-controller/internal/catalogue 4.274s
ok github.com/novox/mesh-controller/internal/conditions 2.011s
ok github.com/novox/mesh-controller/internal/envfile 1.051s
ok github.com/novox/mesh-controller/internal/facts 1.047s
ok github.com/novox/mesh-controller/internal/identity 49.166s
ok github.com/novox/mesh-controller/internal/inventory 294.196s
ok github.com/novox/mesh-controller/internal/lease 17.730s
ok github.com/novox/mesh-controller/internal/licences 46.212s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.045s
ok github.com/novox/mesh-controller/internal/link 87.582s
ok github.com/novox/mesh-controller/internal/lint 1.966s
ok github.com/novox/mesh-controller/internal/outward 1.080s
ok github.com/novox/mesh-controller/internal/overlay 1.059s
ok github.com/novox/mesh-controller/internal/secrets 1.489s
ok github.com/novox/mesh-controller/internal/store 11.701s
ok github.com/novox/mesh-controller/internal/testbus 1.226s
ok github.com/novox/mesh-controller/internal/token 1.014s
**Merge check** at `13b6fc6d`
- `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-1791397243309190493` (`builds --log build-1791397243309190493`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 46 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-07T18:18:34Z 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-07T18:18:34Z
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-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 464.694s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.011s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.030s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.012s
ok github.com/novox/mesh-controller/examples/route-proxy 1.223s
ok github.com/novox/mesh-controller/internal/artifacts 1.069s
ok github.com/novox/mesh-controller/internal/broker 2.562s
ok github.com/novox/mesh-controller/internal/builder 1.490s
ok github.com/novox/mesh-controller/internal/catalogue 4.274s
ok github.com/novox/mesh-controller/internal/conditions 2.011s
ok github.com/novox/mesh-controller/internal/envfile 1.051s
ok github.com/novox/mesh-controller/internal/facts 1.047s
ok github.com/novox/mesh-controller/internal/identity 49.166s
ok github.com/novox/mesh-controller/internal/inventory 294.196s
ok github.com/novox/mesh-controller/internal/lease 17.730s
ok github.com/novox/mesh-controller/internal/licences 46.212s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.045s
ok github.com/novox/mesh-controller/internal/link 87.582s
ok github.com/novox/mesh-controller/internal/lint 1.966s
ok github.com/novox/mesh-controller/internal/outward 1.080s
ok github.com/novox/mesh-controller/internal/overlay 1.059s
ok github.com/novox/mesh-controller/internal/secrets 1.489s
ok github.com/novox/mesh-controller/internal/store 11.701s
ok github.com/novox/mesh-controller/internal/testbus 1.226s
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 g14 as build-1791396320095208789 (builds --log build-1791396320095208789).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 46 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-07T18:27:34Z 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-07T18:27:34Z
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-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.834s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.009s
ok github.com/novox/mesh-controller/examples/route-proxy 1.189s
ok github.com/novox/mesh-controller/internal/artifacts 1.048s
ok github.com/novox/mesh-controller/internal/broker 2.362s
ok github.com/novox/mesh-controller/internal/builder 1.243s
ok github.com/novox/mesh-controller/internal/catalogue 3.486s
ok github.com/novox/mesh-controller/internal/conditions 1.947s
ok github.com/novox/mesh-controller/internal/envfile 1.025s
ok github.com/novox/mesh-controller/internal/facts 1.029s
ok github.com/novox/mesh-controller/internal/identity 6.101s
ok github.com/novox/mesh-controller/internal/inventory 100.632s
ok github.com/novox/mesh-controller/internal/lease 17.692s
ok github.com/novox/mesh-controller/internal/licences 5.181s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 47.424s
ok github.com/novox/mesh-controller/internal/lint 1.748s
ok github.com/novox/mesh-controller/internal/outward 1.030s
ok github.com/novox/mesh-controller/internal/overlay 1.019s
ok github.com/novox/mesh-controller/internal/secrets 1.380s
ok github.com/novox/mesh-controller/internal/store 3.887s
ok github.com/novox/mesh-controller/internal/testbus 1.171s
ok github.com/novox/mesh-controller/internal/token 1.013s
**Merge check** at `13b6fc6d`
- `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 g14 as `build-1791396320095208789` (`builds --log build-1791396320095208789`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 46 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-07T18:27:34Z 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-07T18:27:34Z
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-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.834s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.010s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.016s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.009s
ok github.com/novox/mesh-controller/examples/route-proxy 1.189s
ok github.com/novox/mesh-controller/internal/artifacts 1.048s
ok github.com/novox/mesh-controller/internal/broker 2.362s
ok github.com/novox/mesh-controller/internal/builder 1.243s
ok github.com/novox/mesh-controller/internal/catalogue 3.486s
ok github.com/novox/mesh-controller/internal/conditions 1.947s
ok github.com/novox/mesh-controller/internal/envfile 1.025s
ok github.com/novox/mesh-controller/internal/facts 1.029s
ok github.com/novox/mesh-controller/internal/identity 6.101s
ok github.com/novox/mesh-controller/internal/inventory 100.632s
ok github.com/novox/mesh-controller/internal/lease 17.692s
ok github.com/novox/mesh-controller/internal/licences 5.181s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 47.424s
ok github.com/novox/mesh-controller/internal/lint 1.748s
ok github.com/novox/mesh-controller/internal/outward 1.030s
ok github.com/novox/mesh-controller/internal/overlay 1.019s
ok github.com/novox/mesh-controller/internal/secrets 1.380s
ok github.com/novox/mesh-controller/internal/store 3.887s
ok github.com/novox/mesh-controller/internal/testbus 1.171s
ok github.com/novox/mesh-controller/internal/token 1.013s
```
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 (novox/hq): the operator's direction of 2026-10-07 that a machine's journal for a time window be readable through the seat the module occupies. During the incident of the control node's mail being recreated, reading the controller's journal for a window had no tool:
node-service-manager.journalonly gave a unit's last lines, and a person reached for a shell.What changes (
internal/catalogue/seats.go,serviceManagerVerbs):journaltakessince,until(RFC 3339 or relative to now, e.g.-30min),priority(0-7 or a name) andmatch(a fixed string, not a pattern), besideunit,lines(at most 2000) andscope. The holder validates every value and passes it to journalctl as one argv word (--since=<v>), never through a shell, and redacts secrets before the match is applied.failedis a new verb: every failed unit in both managers, or in one whenscopeis given. It was the systemd module's ownsystemd_failed.Delivery group: the claimant changes in novox/mesh-catalog on the branch of the same name (
feat/journal-window-on-the-seat). Neither merges alone. With this controller, a claim that does not servefailedis refused. With the running controller, a claim that servesfailedis refused as unpromised. Merge this first, then the catalogue PR, once a controller carrying these verbs runs (the build-agent precedent, mesh-catalog 0581256).Tests: the seat-verb tests are updated (
operators_machine_test.go,seat_dependencies_test.go).go test ./...passes against the catalogue branch beside it. Against catalogue main,TestModuleCheckPassesTheCataloguefails as expected, because systemd does not yet servefailed.Delivery
novox/mesh-controller@13b6fc6d97f3— delivered since 2026-10-07T18:54:14ZDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Group
feat/journal-window-on-the-seat, in order: novox/mesh-controller@13b6fc6d97 → novox/mesh-catalog@66106d93acMachines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
40e42606mesh/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: FAIL — its merge-check.sh failed: FAIL github.com/novox/mesh-controller/cmd/mesh-controller 423.490sChange plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on ace as
build-1791393863338413952(builds --log build-1791393863338413952).Merge check at
13b6fc6dmesh/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-1791397243309190493(builds --log build-1791397243309190493).Merge check at
13b6fc6dmesh/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 g14 as
build-1791396320095208789(builds --log build-1791396320095208789).