On novox, de-spiegel has been held since the node began composing its own modules: "nothing sets the required config value praktijk-name". The operator set that value and its three siblings on 2026-10-28 (Approve on Telegram), and mesh-config holds them under set, but nothing under resolved. mesh-config read each module's declarations from the controller's mesh-controller.declared-config and its assignments from mesh-controller.assignments, and silently skipped an assigned module whose declarations that mirror lacked. de-spiegel lives in its own repository and its keys came with novox/de-spiegel #6; the controller's mirror never held them. The hold then spread to mailu and route-proxy, so every site behind route-proxy has stayed down.
The operator, 2026-10-29: "the controller should have never had anything to do with module assignment and configuration"; "the configuration should live on the nats broker"; "no more code in the controller that touches build, delivery and config"; switch at once, no dark phase.
What changes
Assignments: read from placement alone (mesh-delivery-assigner.placement, key placement.<node>); the controller's assignments are no longer read.
Declarations: each placed module's trunk manifest from the indexer (mesh-delivery-indexer.modules, .manifests), with the manifest of the build its want names (mesh-delivery-assigner.wants, mesh-delivery-builder.builds) laid over it key by key, as the node composer picks manifests. Only config and settings are read. Manifests are cached by digest.
A placed module whose manifest cannot be read is listed under unresolved with why (config list), logged, and keeps its last resolved values; it never blocks another module and is never skipped silently.
Event-driven: watches placement, wants, the indexer's modules and the predefined list; no timer added.
Manifest reads: drop mesh-controller.assignments and mesh-controller.declared-config; add the four bus reads above. README updated.
This departs from ADR 0565 §4 (build dark beside the controller's mirrors, switch on a take-over): the operator chose to switch at once; the correction is proposed to the knowledge base.
Quick fix or thorough fix
Quick: add de-spiegel to the controller's declared-config mirror. One module, and it keeps the controller on the config path.
Thorough, chosen: every module's declarations from its own manifests on the bus, for any repository, and an unreadable one said loudly; the controller leaves the config path.
How it is checked
One table-driven test with four cases on de-spiegel's real config replaces three tests of the assignments mirror (38 test functions, was 40; budget 500/50). go build, go vet -tags integration and go test pass.
Reviewed live: all 328 resolved values on 89 node/module pairs today are placed and unchanged against their trunk manifests; de-spiegel's four keys resolve on novox.
Live after delivery: mesh-config.config {action:list, module:de-spiegel} shows the four keys under resolved; de-spiegel, mailu and route-proxy are no longer held on novox; de-spiegel and link2pay get wants; the sites behind route-proxy answer.
Still reading controller state, not changed here: the predefined list, the hand-act log and pull-request declarations (ADR 0565 §2, §10-11).
Reopened 2026-10-29 as recovery only
The operator said yes (17:56 CET) to this change as a temporary fix so de-spiegel returns today; design 47's config model replaces it. The checker did not take the reopened pull request back as a candidate, so one empty commit (0d71d8b) moves the head; the tree is identical to the reviewed 96a37f58.
Reviewed-by: rev-config@shanks at 96a37f58ca
Reviewed-by: lead-47@shanks at 0d71d8b56c (empty commit on the reviewed tree)
## Why
On novox, de-spiegel has been held since the node began composing its own modules: "nothing sets the required config value praktijk-name". The operator set that value and its three siblings on 2026-10-28 (Approve on Telegram), and mesh-config holds them under `set`, but nothing under `resolved`. mesh-config read each module's declarations from the controller's `mesh-controller.declared-config` and its assignments from `mesh-controller.assignments`, and silently skipped an assigned module whose declarations that mirror lacked. de-spiegel lives in its own repository and its keys came with novox/de-spiegel #6; the controller's mirror never held them. The hold then spread to mailu and route-proxy, so every site behind route-proxy has stayed down.
The operator, 2026-10-29: "the controller should have never had anything to do with module assignment and configuration"; "the configuration should live on the nats broker"; "no more code in the controller that touches build, delivery and config"; switch at once, no dark phase.
## What changes
- Assignments: read from placement alone (`mesh-delivery-assigner.placement`, key `placement.<node>`); the controller's assignments are no longer read.
- Declarations: each placed module's trunk manifest from the indexer (`mesh-delivery-indexer.modules`, `.manifests`), with the manifest of the build its want names (`mesh-delivery-assigner.wants`, `mesh-delivery-builder.builds`) laid over it key by key, as the node composer picks manifests. Only `config` and `settings` are read. Manifests are cached by digest.
- A placed module whose manifest cannot be read is listed under `unresolved` with why (`config list`), logged, and keeps its last resolved values; it never blocks another module and is never skipped silently.
- Event-driven: watches placement, wants, the indexer's modules and the predefined list; no timer added.
- Manifest `reads`: drop `mesh-controller.assignments` and `mesh-controller.declared-config`; add the four bus reads above. README updated.
- This departs from ADR 0565 §4 (build dark beside the controller's mirrors, switch on a take-over): the operator chose to switch at once; the correction is proposed to the knowledge base.
## Quick fix or thorough fix
- Quick: add de-spiegel to the controller's declared-config mirror. One module, and it keeps the controller on the config path.
- Thorough, chosen: every module's declarations from its own manifests on the bus, for any repository, and an unreadable one said loudly; the controller leaves the config path.
## How it is checked
- One table-driven test with four cases on de-spiegel's real config replaces three tests of the assignments mirror (38 test functions, was 40; budget 500/50). `go build`, `go vet -tags integration` and `go test` pass.
- Reviewed live: all 328 resolved values on 89 node/module pairs today are placed and unchanged against their trunk manifests; de-spiegel's four keys resolve on novox.
- Live after delivery: `mesh-config.config {action:list, module:de-spiegel}` shows the four keys under `resolved`; de-spiegel, mailu and route-proxy are no longer held on novox; de-spiegel and link2pay get wants; the sites behind route-proxy answer.
Still reading controller state, not changed here: the predefined list, the hand-act log and pull-request declarations (ADR 0565 §2, §10-11).
## Reopened 2026-10-29 as recovery only
The operator said yes (17:56 CET) to this change as a temporary fix so de-spiegel returns today; design 47's config model replaces it. The checker did not take the reopened pull request back as a candidate, so one empty commit (0d71d8b) moves the head; the tree is identical to the reviewed 96a37f58.
Reviewed-by: rev-config@shanks at 96a37f58ca76d5af3f8d1d9de36af52d6e2e7b02
Reviewed-by: lead-47@shanks at 0d71d8b56c55effc73dc813389268794b876a5f4 (empty commit on the reviewed tree)
The controller's declared-config mirror never held de-spiegel's keys, and Resolve skipped
an assigned module it held no declarations of, silently: de-spiegel stayed held on novox
with its values set. Declarations now come from the indexer's trunk manifest with the
wanted build's laid over it per node; which module runs where from the seat
mesh-placement alone. A placed module with no readable manifest is listed as unresolved
with why, logged, and keeps its last resolved values.
Deliverynovox/mesh-catalog@0d71d8b56c55 — merged since 2026-10-29T19:47:59Z
Source — source.main moved to novox/mesh-catalog@96b129e544. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-10-29 17:10 (new) → proposed (announced): novox/mesh-catalog#558's head announced
2026-10-29 17:10 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
2026-10-29 19:47 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@0d71d8b56c55` — **merged** since 2026-10-29T19:47:59Z
**Source** — source.main moved to novox/mesh-catalog@96b129e54441. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-10-29 17:10 (new) → proposed (announced): novox/mesh-catalog#558's head announced
- 2026-10-29 17:10 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
- 2026-10-29 19:47 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
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
On novox, de-spiegel has been held since the node began composing its own modules: "nothing sets the required config value praktijk-name". The operator set that value and its three siblings on 2026-10-28 (Approve on Telegram), and mesh-config holds them under
set, but nothing underresolved. mesh-config read each module's declarations from the controller'smesh-controller.declared-configand its assignments frommesh-controller.assignments, and silently skipped an assigned module whose declarations that mirror lacked. de-spiegel lives in its own repository and its keys came with novox/de-spiegel #6; the controller's mirror never held them. The hold then spread to mailu and route-proxy, so every site behind route-proxy has stayed down.The operator, 2026-10-29: "the controller should have never had anything to do with module assignment and configuration"; "the configuration should live on the nats broker"; "no more code in the controller that touches build, delivery and config"; switch at once, no dark phase.
What changes
mesh-delivery-assigner.placement, keyplacement.<node>); the controller's assignments are no longer read.mesh-delivery-indexer.modules,.manifests), with the manifest of the build its want names (mesh-delivery-assigner.wants,mesh-delivery-builder.builds) laid over it key by key, as the node composer picks manifests. Onlyconfigandsettingsare read. Manifests are cached by digest.unresolvedwith why (config list), logged, and keeps its last resolved values; it never blocks another module and is never skipped silently.reads: dropmesh-controller.assignmentsandmesh-controller.declared-config; add the four bus reads above. README updated.Quick fix or thorough fix
How it is checked
go build,go vet -tags integrationandgo testpass.mesh-config.config {action:list, module:de-spiegel}shows the four keys underresolved; de-spiegel, mailu and route-proxy are no longer held on novox; de-spiegel and link2pay get wants; the sites behind route-proxy answer.Still reading controller state, not changed here: the predefined list, the hand-act log and pull-request declarations (ADR 0565 §2, §10-11).
Reopened 2026-10-29 as recovery only
The operator said yes (17:56 CET) to this change as a temporary fix so de-spiegel returns today; design 47's config model replaces it. The checker did not take the reopened pull request back as a candidate, so one empty commit (
0d71d8b) moves the head; the tree is identical to the reviewed96a37f58.Reviewed-by: rev-config@shanks at
96a37f58caReviewed-by: lead-47@shanks at
0d71d8b56c(empty commit on the reviewed tree)Delivery
novox/mesh-catalog@0d71d8b56c55— merged since 2026-10-29T19:47:59ZSource — source.main moved to novox/mesh-catalog@96b129e544. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.