The operator could not read the mesh's notifications: the condition's only words were its summary, written for an agent. Beside the summary (unchanged) every condition now carries headline, explanation and resolved, in the events and in conditions.
internal/conditions/plain.go: the three fields, the plain rule (no hash, numbered id, dotted name, Go duration, clock time, flag, markup, line break; plus the content rule), a wording registry per kind, the scope's words as fallback, and the escalation sentence when a healer gave up.
cmd/mesh-controller/plain_words.go: a wording for every kind the controller raises; richer words at the producers that know more (a walk's modules, a failed unit's name, a hand-act's cause, a held delivery's repository).
Tests: internal/conditions/plain_test.go, cmd/mesh-controller/plain_words_test.go (the real notifications of hq issue 320, before and after), and a suite-wide lint in sayable_test.go that fails a kind without plain words.
Second commit, unrelated but blocking: three forge tests in internal/catalogue resolved the catalogue's gitea manifest against its code artifact only; since hq ADR 0251 (catalogue commit 8059f35) it also builds npm-registry, so they fail on main as on every branch. The tests now give both.
Run here: gofmt, vet, and the whole suite against a throwaway postgres: all pass.
Goes with novox/mesh-catalog feat/plain-notifications (the messenger shows the words) and novox/hq feat/plain-notifications (ADR 0253).
The operator could not read the mesh's notifications: the condition's only words were its summary, written for an agent. Beside the summary (unchanged) every condition now carries `headline`, `explanation` and `resolved`, in the events and in `conditions`.
- `internal/conditions/plain.go`: the three fields, the plain rule (no hash, numbered id, dotted name, Go duration, clock time, flag, markup, line break; plus the content rule), a wording registry per kind, the scope's words as fallback, and the escalation sentence when a healer gave up.
- `cmd/mesh-controller/plain_words.go`: a wording for every kind the controller raises; richer words at the producers that know more (a walk's modules, a failed unit's name, a hand-act's cause, a held delivery's repository).
- Tests: `internal/conditions/plain_test.go`, `cmd/mesh-controller/plain_words_test.go` (the real notifications of hq issue 320, before and after), and a suite-wide lint in `sayable_test.go` that fails a kind without plain words.
**Second commit, unrelated but blocking:** three forge tests in `internal/catalogue` resolved the catalogue's gitea manifest against its `code` artifact only; since hq ADR 0251 (catalogue commit 8059f35) it also builds `npm-registry`, so they fail on main as on every branch. The tests now give both.
Run here: gofmt, vet, and the whole suite against a throwaway postgres: all pass.
Goes with novox/mesh-catalog `feat/plain-notifications` (the messenger shows the words) and novox/hq `feat/plain-notifications` (ADR 0253).
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…
The operator could not read the desktop notifications: they carried plan ids,
commits, keys and verb syntax. The words the operator reads now travel with the
condition, so every channel says them (hq ADR 0253).
composed together: pass — every machine composes with the change as it did without (4 of 4 compose)
Machines
mesh-controller on novox: passed — healthy 3 times over 3m38s
mesh-controller on the rest running it: sent
build-agent on g14: passed — healthy 3 times over 3m44s
build-agent on the rest running it: sent
route-proxy on ace: passed — healthy 3 times over 3m18s
route-proxy on the rest running it: sent
Transitions
2026-10-08 12:01 (new) → proposed (announced): novox/mesh-controller#141's head announced
2026-10-08 12:05 proposed → checked (checked): the verdict names this commit
2026-10-08 12:05 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-08 12:20 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-08 12:20 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-08 12:35 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@1a4305213d08` — **delivered** since 2026-10-08T12:35:19Z
**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/plain-notifications`, in order: novox/hq@356c5f23f441 → novox/mesh-controller@1a4305213d08 → novox/mesh-catalog@f00b5a19b1be
- novox/mesh-controller@1a4305213d08 before novox/mesh-catalog@f00b5a19b1be: built by
- composed together: pass — every machine composes with the change as it did without (4 of 4 compose)
**Machines**
- mesh-controller on novox: passed — healthy 3 times over 3m38s
- mesh-controller on the rest running it: sent
- build-agent on g14: passed — healthy 3 times over 3m44s
- build-agent on the rest running it: sent
- route-proxy on ace: passed — healthy 3 times over 3m18s
- route-proxy on the rest running it: sent
**Transitions**
- 2026-10-08 12:01 (new) → proposed (announced): novox/mesh-controller#141's head announced
- 2026-10-08 12:05 proposed → checked (checked): the verdict names this commit
- 2026-10-08 12:05 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-08 12:20 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-08 12:20 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-08 12:35 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 shanks as build-1791458988237769308 (builds --log build-1791458988237769308).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:21:31Z 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-08T11:21:31Z
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.031s
ok github.com/novox/mesh-controller/cmd/mesh-controller 161.844s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.046s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.065s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.049s
ok github.com/novox/mesh-controller/examples/route-proxy 1.206s
ok github.com/novox/mesh-controller/internal/artifacts 1.075s
ok github.com/novox/mesh-controller/internal/broker 2.675s
ok github.com/novox/mesh-controller/internal/builder 1.806s
--- FAIL: TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt (0.00s)
foundation_manifests_test.go:186: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
--- FAIL: TestTheForgesSshPortIsTheMeshsFixedConventionByDefault (0.01s)
foundation_manifests_test.go:286: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
--- FAIL: TestANodeMayGiveTheForgesSshPortADifferentNumber (0.01s)
foundation_manifests_test.go:306: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
FAIL
FAIL github.com/novox/mesh-controller/internal/catalogue 3.727s
ok github.com/novox/mesh-controller/internal/conditions 2.239s
ok github.com/novox/mesh-controller/internal/envfile 1.050s
ok github.com/novox/mesh-controller/internal/facts 1.054s
ok github.com/novox/mesh-controller/internal/identity 4.660s
ok github.com/novox/mesh-controller/internal/inventory 79.195s
ok github.com/novox/mesh-controller/internal/lease 17.700s
ok github.com/novox/mesh-controller/internal/licences 4.230s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.054s
ok github.com/novox/mesh-controller/internal/link 45.957s
ok github.com/novox/mesh-controller/internal/lint 2.074s
ok github.com/novox/mesh-controller/internal/outward 1.088s
ok github.com/novox/mesh-controller/internal/overlay 1.072s
ok github.com/novox/mesh-controller/internal/secrets 1.530s
ok github.com/novox/mesh-controller/internal/store 3.445s
ok github.com/novox/mesh-controller/internal/testbus 1.237s
ok github.com/novox/mesh-controller/internal/token 1.015s
FAIL
**Merge check** at `1fce5410`
- `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: TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt (0.00s)
**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-1791458988237769308` (`builds --log build-1791458988237769308`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:21:31Z 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-08T11:21:31Z
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.031s
ok github.com/novox/mesh-controller/cmd/mesh-controller 161.844s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.046s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.065s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.049s
ok github.com/novox/mesh-controller/examples/route-proxy 1.206s
ok github.com/novox/mesh-controller/internal/artifacts 1.075s
ok github.com/novox/mesh-controller/internal/broker 2.675s
ok github.com/novox/mesh-controller/internal/builder 1.806s
--- FAIL: TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt (0.00s)
foundation_manifests_test.go:186: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
--- FAIL: TestTheForgesSshPortIsTheMeshsFixedConventionByDefault (0.01s)
foundation_manifests_test.go:286: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
--- FAIL: TestANodeMayGiveTheForgesSshPortADifferentNumber (0.01s)
foundation_manifests_test.go:306: the forge's manifest does not resolve against its own build: gitea says it builds npm-registry and the build did not produce it — the build did not do what the manifest asked, which is a different fault from a resource asking for the wrong thing
FAIL
FAIL github.com/novox/mesh-controller/internal/catalogue 3.727s
ok github.com/novox/mesh-controller/internal/conditions 2.239s
ok github.com/novox/mesh-controller/internal/envfile 1.050s
ok github.com/novox/mesh-controller/internal/facts 1.054s
ok github.com/novox/mesh-controller/internal/identity 4.660s
ok github.com/novox/mesh-controller/internal/inventory 79.195s
ok github.com/novox/mesh-controller/internal/lease 17.700s
ok github.com/novox/mesh-controller/internal/licences 4.230s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.054s
ok github.com/novox/mesh-controller/internal/link 45.957s
ok github.com/novox/mesh-controller/internal/lint 2.074s
ok github.com/novox/mesh-controller/internal/outward 1.088s
ok github.com/novox/mesh-controller/internal/overlay 1.072s
ok github.com/novox/mesh-controller/internal/secrets 1.530s
ok github.com/novox/mesh-controller/internal/store 3.445s
ok github.com/novox/mesh-controller/internal/testbus 1.237s
ok github.com/novox/mesh-controller/internal/token 1.015s
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…
The catalogue's forge also builds its npm registry since hq ADR 0251, so the three
forge tests resolved it against half its build and failed on main as on every branch.
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-1791459315650099426 (builds --log build-1791459315650099426).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:31:31Z 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-08T11:31:31Z
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.042s
ok github.com/novox/mesh-controller/cmd/mesh-controller 165.398s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.008s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.009s
ok github.com/novox/mesh-controller/examples/route-proxy 1.153s
ok github.com/novox/mesh-controller/internal/artifacts 1.043s
ok github.com/novox/mesh-controller/internal/broker 2.361s
ok github.com/novox/mesh-controller/internal/builder 2.263s
ok github.com/novox/mesh-controller/internal/catalogue 3.845s
ok github.com/novox/mesh-controller/internal/conditions 2.134s
ok github.com/novox/mesh-controller/internal/envfile 1.027s
ok github.com/novox/mesh-controller/internal/facts 1.031s
ok github.com/novox/mesh-controller/internal/identity 4.234s
ok github.com/novox/mesh-controller/internal/inventory 69.507s
ok github.com/novox/mesh-controller/internal/lease 17.692s
ok github.com/novox/mesh-controller/internal/licences 3.787s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.008s
ok github.com/novox/mesh-controller/internal/link 43.686s
ok github.com/novox/mesh-controller/internal/lint 1.810s
ok github.com/novox/mesh-controller/internal/outward 1.037s
ok github.com/novox/mesh-controller/internal/overlay 1.025s
ok github.com/novox/mesh-controller/internal/secrets 1.420s
ok github.com/novox/mesh-controller/internal/store 3.136s
ok github.com/novox/mesh-controller/internal/testbus 1.159s
ok github.com/novox/mesh-controller/internal/token 1.016s
**Merge check** at `7df72edd`
- `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-1791459315650099426` (`builds --log build-1791459315650099426`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:31:31Z 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-08T11:31:31Z
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.042s
ok github.com/novox/mesh-controller/cmd/mesh-controller 165.398s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.008s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.009s
ok github.com/novox/mesh-controller/examples/route-proxy 1.153s
ok github.com/novox/mesh-controller/internal/artifacts 1.043s
ok github.com/novox/mesh-controller/internal/broker 2.361s
ok github.com/novox/mesh-controller/internal/builder 2.263s
ok github.com/novox/mesh-controller/internal/catalogue 3.845s
ok github.com/novox/mesh-controller/internal/conditions 2.134s
ok github.com/novox/mesh-controller/internal/envfile 1.027s
ok github.com/novox/mesh-controller/internal/facts 1.031s
ok github.com/novox/mesh-controller/internal/identity 4.234s
ok github.com/novox/mesh-controller/internal/inventory 69.507s
ok github.com/novox/mesh-controller/internal/lease 17.692s
ok github.com/novox/mesh-controller/internal/licences 3.787s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.008s
ok github.com/novox/mesh-controller/internal/link 43.686s
ok github.com/novox/mesh-controller/internal/lint 1.810s
ok github.com/novox/mesh-controller/internal/outward 1.037s
ok github.com/novox/mesh-controller/internal/overlay 1.025s
ok github.com/novox/mesh-controller/internal/secrets 1.420s
ok github.com/novox/mesh-controller/internal/store 3.136s
ok github.com/novox/mesh-controller/internal/testbus 1.159s
ok github.com/novox/mesh-controller/internal/token 1.016s
```
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…
The operator could not tell from a notification whether to act, and was told to
have an agent do it. Each condition now says "Nothing for you to do." or
"Needs you:" with one thing they can do themselves, and carries the actions the
operator channel performs when chosen (hq ADR 0253).
Revised after the operator read the first wording (commit 1a43052): every condition now also carries needs (one thing the operator can do themselves, or empty) and actions (label, seat verb, arguments; an empty why is the operator channel's to fill). The explanation opens with the verdict: "Nothing for you to do." or "Needs you: ". The plain rule now refuses words that send the operator to an agent or a session, and "by hand" in needs. A walk waiting past its bound offers Start/Stop (mesh-controller.plans go|stop), a held delivery Release/Stop (mesh-delivery.release|stop), a failed service Restart (node-service-manager.restart), failed units and data shrank/missing Silence for a week. Under its bound the waiting walk needs nothing, so the messenger keeps it quiet (hq ADR 0253 §5). Full suite passes here against a throwaway postgres.
Revised after the operator read the first wording (commit 1a43052): every condition now also carries `needs` (one thing the operator can do themselves, or empty) and `actions` (label, seat verb, arguments; an empty `why` is the operator channel's to fill). The explanation opens with the verdict: "Nothing for you to do." or "Needs you: <needs>". The plain rule now refuses words that send the operator to an agent or a session, and "by hand" in `needs`. A walk waiting past its bound offers Start/Stop (`mesh-controller.plans go|stop`), a held delivery Release/Stop (`mesh-delivery.release|stop`), a failed service Restart (`node-service-manager.restart`), failed units and data shrank/missing Silence for a week. Under its bound the waiting walk needs nothing, so the messenger keeps it quiet (hq ADR 0253 §5). Full suite passes here against a throwaway postgres.
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-1791460864427732564 (builds --log build-1791460864427732564).
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:31:31Z 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-08T11:31:31Z
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.054s
ok github.com/novox/mesh-controller/cmd/mesh-controller 162.060s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.019s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.014s
ok github.com/novox/mesh-controller/examples/route-proxy 1.216s
ok github.com/novox/mesh-controller/internal/artifacts 1.043s
ok github.com/novox/mesh-controller/internal/broker 2.740s
ok github.com/novox/mesh-controller/internal/builder 1.864s
ok github.com/novox/mesh-controller/internal/catalogue 4.477s
ok github.com/novox/mesh-controller/internal/conditions 2.161s
ok github.com/novox/mesh-controller/internal/envfile 1.029s
ok github.com/novox/mesh-controller/internal/facts 1.034s
ok github.com/novox/mesh-controller/internal/identity 4.567s
ok github.com/novox/mesh-controller/internal/inventory 75.368s
ok github.com/novox/mesh-controller/internal/lease 17.607s
ok github.com/novox/mesh-controller/internal/licences 4.093s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 44.833s
ok github.com/novox/mesh-controller/internal/lint 2.010s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.029s
ok github.com/novox/mesh-controller/internal/secrets 1.517s
ok github.com/novox/mesh-controller/internal/store 3.317s
ok github.com/novox/mesh-controller/internal/testbus 1.191s
ok github.com/novox/mesh-controller/internal/token 1.023s
**Merge check** at `1a430521`
- `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-1791460864427732564` (`builds --log build-1791460864427732564`).
```
--- the gate: build-agent, mesh-controller, route-proxy
mesh-controller: ok, 50 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-08T11:31:31Z 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-08T11:31:31Z
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.054s
ok github.com/novox/mesh-controller/cmd/mesh-controller 162.060s
ok github.com/novox/mesh-controller/examples/objectstore-provisioner 1.013s
ok github.com/novox/mesh-controller/examples/postgres-provisioner 1.019s
ok github.com/novox/mesh-controller/examples/redis-provisioner 1.014s
ok github.com/novox/mesh-controller/examples/route-proxy 1.216s
ok github.com/novox/mesh-controller/internal/artifacts 1.043s
ok github.com/novox/mesh-controller/internal/broker 2.740s
ok github.com/novox/mesh-controller/internal/builder 1.864s
ok github.com/novox/mesh-controller/internal/catalogue 4.477s
ok github.com/novox/mesh-controller/internal/conditions 2.161s
ok github.com/novox/mesh-controller/internal/envfile 1.029s
ok github.com/novox/mesh-controller/internal/facts 1.034s
ok github.com/novox/mesh-controller/internal/identity 4.567s
ok github.com/novox/mesh-controller/internal/inventory 75.368s
ok github.com/novox/mesh-controller/internal/lease 17.607s
ok github.com/novox/mesh-controller/internal/licences 4.093s
ok github.com/novox/mesh-controller/internal/licences/adapters 1.010s
ok github.com/novox/mesh-controller/internal/link 44.833s
ok github.com/novox/mesh-controller/internal/lint 2.010s
ok github.com/novox/mesh-controller/internal/outward 1.042s
ok github.com/novox/mesh-controller/internal/overlay 1.029s
ok github.com/novox/mesh-controller/internal/secrets 1.517s
ok github.com/novox/mesh-controller/internal/store 3.317s
ok github.com/novox/mesh-controller/internal/testbus 1.191s
ok github.com/novox/mesh-controller/internal/token 1.023s
```
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.
The operator could not read the mesh's notifications: the condition's only words were its summary, written for an agent. Beside the summary (unchanged) every condition now carries
headline,explanationandresolved, in the events and inconditions.internal/conditions/plain.go: the three fields, the plain rule (no hash, numbered id, dotted name, Go duration, clock time, flag, markup, line break; plus the content rule), a wording registry per kind, the scope's words as fallback, and the escalation sentence when a healer gave up.cmd/mesh-controller/plain_words.go: a wording for every kind the controller raises; richer words at the producers that know more (a walk's modules, a failed unit's name, a hand-act's cause, a held delivery's repository).internal/conditions/plain_test.go,cmd/mesh-controller/plain_words_test.go(the real notifications of hq issue 320, before and after), and a suite-wide lint insayable_test.gothat fails a kind without plain words.Second commit, unrelated but blocking: three forge tests in
internal/catalogueresolved the catalogue's gitea manifest against itscodeartifact only; since hq ADR 0251 (catalogue commit 8059f35) it also buildsnpm-registry, so they fail on main as on every branch. The tests now give both.Run here: gofmt, vet, and the whole suite against a throwaway postgres: all pass.
Goes with novox/mesh-catalog
feat/plain-notifications(the messenger shows the words) and novox/hqfeat/plain-notifications(ADR 0253).Delivery
novox/mesh-controller@1a4305213d08— delivered since 2026-10-08T12:35:19ZDelivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Group
feat/plain-notifications, in order: novox/hq@356c5f23f4 → novox/mesh-controller@1a4305213d → novox/mesh-catalog@f00b5a19b1Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
1fce5410mesh/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: TestTheForgesOwnAddressFollowsThePortTheNodeGaveIt (0.00s)Delivery plan — builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step
Run by the build seat on shanks as
build-1791458988237769308(builds --log build-1791458988237769308).Merge check at
7df72eddmesh/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-1791459315650099426(builds --log build-1791459315650099426).Revised after the operator read the first wording (commit
1a43052): every condition now also carriesneeds(one thing the operator can do themselves, or empty) andactions(label, seat verb, arguments; an emptywhyis the operator channel's to fill). The explanation opens with the verdict: "Nothing for you to do." or "Needs you: ". The plain rule now refuses words that send the operator to an agent or a session, and "by hand" inneeds. A walk waiting past its bound offers Start/Stop (mesh-controller.plans go|stop), a held delivery Release/Stop (mesh-delivery.release|stop), a failed service Restart (node-service-manager.restart), failed units and data shrank/missing Silence for a week. Under its bound the waiting walk needs nothing, so the messenger keeps it quiet (hq ADR 0253 §5). Full suite passes here against a throwaway postgres.Merge check at
1a430521mesh/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-1791460864427732564(builds --log build-1791460864427732564).