ADR 0547 clause 7/8 (accepted by the operator 2026-10-25), the bridge, with the controller unchanged. Tonight the bus user list reached the bus only by the operator's hand step (three times): the list travels inside the nats module's composition, applied only with a want of nats, so a new account or grant composed by the controller never reached the bus; twice that left a part crash-looping on a grant not yet loaded.
The node agent watches the node's compositions and takes the newest one signed by a trusted key (the same VerifyComposed and key set as an apply) whose node and module match its key and that carries <module>.bus-users.
When that list's digest differs from the file on disk, it writes the file alone through the apply's file step (0600), reads it back and records it as the module's. The bus module's entrypoint already reloads the server when the file changes. It needs no want, never goes back to an older list, and looks again after every apply of the bus module.
Guards: a list sent by digest is fetched and verified first; a list without the user controller, or with fewer than half the users of the file on disk, is refused: the file stays, the have says why.
It writes what it did into the bus module's have (user-list: wanted vs digest, users, source, error), read with mesh-delivery-view.node_haves {node: novox, module: nats}; nats.nats_user_can reports in_force once the bus reloaded.
Group with mesh-sdk's PR of the same branch name (this pins its head 0be0ffd). Merges cleanly with #142 (git merge-tree).
Checked: go test -race ./... and go vet -tags integration ./...; try-1792962013247173089 passed (unit and integration). Net zero new top-level tests. This is the node-engine on every node; the follower acts only where the composition carries a bus user list (the bus node).
Review: round 1 blocked on the user count (a by-digest list counted 0 users); fixed with the node/module match and the shrink guard in round 2.
ADR 0547 clause 7/8 (accepted by the operator 2026-10-25), the bridge, with the controller unchanged. Tonight the bus user list reached the bus only by the operator's hand step (three times): the list travels inside the nats module's composition, applied only with a want of nats, so a new account or grant composed by the controller never reached the bus; twice that left a part crash-looping on a grant not yet loaded.
- The node agent watches the node's compositions and takes the newest one signed by a trusted key (the same `VerifyComposed` and key set as an apply) whose node and module match its key and that carries `<module>.bus-users`.
- When that list's digest differs from the file on disk, it writes the file alone through the apply's file step (0600), reads it back and records it as the module's. The bus module's entrypoint already reloads the server when the file changes. It needs no want, never goes back to an older list, and looks again after every apply of the bus module.
- Guards: a list sent by digest is fetched and verified first; a list without the user `controller`, or with fewer than half the users of the file on disk, is refused: the file stays, the have says why.
- It writes what it did into the bus module's have (`user-list`: wanted vs digest, users, source, error), read with `mesh-delivery-view.node_haves` {node: novox, module: nats}; `nats.nats_user_can` reports in_force once the bus reloaded.
Group with mesh-sdk's PR of the same branch name (this pins its head 0be0ffd). Merges cleanly with #142 (git merge-tree).
Checked: go test -race ./... and go vet -tags integration ./...; try-1792962013247173089 passed (unit and integration). Net zero new top-level tests. This is the node-engine on every node; the follower acts only where the composition carries a bus user list (the bus node).
Review: round 1 blocked on the user count (a by-digest list counted 0 users); fixed with the node/module match and the shrink guard in round 2.
Reviewed-by: review-bridge@shanks at 5e71ab6ae6127f385aaf0903723ac80fdf0f2edf
The list reached the bus only through a want of the bus module, which nobody writes (ADR 0539 §15): on 2026-10-25 it
stood from 11:23 to 20:50 and was put back by hand. The node agent now follows its composition bucket for the newest
signed composition carrying the user list, writes that file alone through the apply's file step when it differs
(mode 0600, read back, recorded as the module's), moves nothing that reads it (the bus module's entrypoint reloads the
server in place), never goes back to an older list, looks again after every apply of the bus module, and says source,
revision, wanted and written digests, users and any error in the bus module's have (mesh-sdk UserListWritten).
Read with mesh-delivery-view.node_haves (module nats); the bus's own nats_user_can says in_force once it reloaded.
B1: the controller sends the user list by digest (over 64 KiB), so its users are counted from the list as resolved, not
from the composition's inline content, which is empty then.
R1: a composition signed for another node or module than its key names is no source.
R2: a list without the controller's own user, or one that drops more than half the users of the file on the machine,
is not written; the have says why and the file on the machine is kept.
Deliverynovox/mesh-host@5e71ab6ae612 — merged since 2026-10-25T21:16:09Z
Source — source.main moved to novox/mesh-host@d75c66dc7e. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
composed together: pass — the checker's verdict at the members' heads (e88fd6c706c7)
Transitions
2026-10-25 21:04 (new) → proposed (announced): novox/mesh-host#143's head announced
2026-10-25 21:08 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
2026-10-25 21:08 ready → proposed (trunk moved): out of date: judged against trunk 5f16cf507a, the trunk is now e196058f6fb0; judged again on a recheck or when it is merged
2026-10-25 21:15 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
2026-10-25 21:16 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-host@5e71ab6ae612` — **merged** since 2026-10-25T21:16:09Z
**Source** — source.main moved to novox/mesh-host@d75c66dc7e27. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Group** `fix/1945-user-list-follows`: novox/mesh-host@5e71ab6ae612, novox/mesh-sdk@0be0ffd6159e
- composed together: pass — the checker's verdict at the members' heads (e88fd6c706c7)
**Transitions**
- 2026-10-25 21:04 (new) → proposed (announced): novox/mesh-host#143's head announced
- 2026-10-25 21:08 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
- 2026-10-25 21:08 ready → proposed (trunk moved): out of date: judged against trunk 5f16cf507a0f, the trunk is now e196058f6fb0; judged again on a recheck or when it is merged
- 2026-10-25 21:15 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
- 2026-10-25 21:16 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.
ADR 0547 clause 7/8 (accepted by the operator 2026-10-25), the bridge, with the controller unchanged. Tonight the bus user list reached the bus only by the operator's hand step (three times): the list travels inside the nats module's composition, applied only with a want of nats, so a new account or grant composed by the controller never reached the bus; twice that left a part crash-looping on a grant not yet loaded.
VerifyComposedand key set as an apply) whose node and module match its key and that carries<module>.bus-users.controller, or with fewer than half the users of the file on disk, is refused: the file stays, the have says why.user-list: wanted vs digest, users, source, error), read withmesh-delivery-view.node_haves{node: novox, module: nats};nats.nats_user_canreports in_force once the bus reloaded.Group with mesh-sdk's PR of the same branch name (this pins its head 0be0ffd). Merges cleanly with #142 (git merge-tree).
Checked: go test -race ./... and go vet -tags integration ./...; try-1792962013247173089 passed (unit and integration). Net zero new top-level tests. This is the node-engine on every node; the follower acts only where the composition carries a bus user list (the bus node).
Review: round 1 blocked on the user count (a by-digest list counted 0 users); fixed with the node/module match and the shrink guard in round 2.
Reviewed-by: review-bridge@shanks at
5e71ab6ae6Delivery
novox/mesh-host@5e71ab6ae612— merged since 2026-10-25T21:16:09ZSource — source.main moved to novox/mesh-host@d75c66dc7e. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Group
fix/1945-user-list-follows: novox/mesh-host@5e71ab6ae6, novox/mesh-sdk@0be0ffd615Transitions
5f16cf507a, the trunk is now e196058f6fb0; judged again on a recheck or when it is mergedThe commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.