ADR 0547 (version 42; the operator's choice of 2026-10-25 22:31). Since release 6 nobody publishes memberships, so a seat-holding module newly placed on a node cannot serve its seat (ace's mesh-build-go at 22:29; issue 1945 notes 42, 47).
New module modules/mesh-grants (registered by its module.json; pins mesh-sdk at the group's head):
Publishes memberships on mesh.assignment.<node>.<module>, on change only, built from the manifest the wanted build names (trunk's as fallback). It publishes only a first membership (the stream answers 404) or one that loses nothing from the last (Losses walks the whole last membership: capabilities per kind, seat traffic, serves, seats, states, logs, streams, hears, waits, reaches, Mesh, Receives; lists compared by containment). Anything that would drop something (e.g. verified-sender, which it cannot judge without root-free records) stays in shadow and grants_membership names what would be lost. A refused or failed read is never taken as first.
The user list, assertions and grants: composed and compared only (shadow). take-over refuses, naming the enrolment users and persons not on the bus (issue 1126).
Never exits on a refusal; no lock held across a bus call.
Tools: grants_grants, grants_membership, grants_user_list, grants_compose_now, grants_assert, grants_take_over, grants_hand_back (the last two refused without a person account).
Group with mesh-control (the one grant) and mesh-sdk (the composer copy) PRs of the same branch name.
Checked: go test -race (3 runs), go vet with and without the integration tag in modules/mesh-grants. Unit 574 (one table test with rows), integration 76 (none added).
Review: round 1 blocked (the direct-get grant missing; a republished membership would drop verified-sender and stop the operator's Telegram approvals counting), both fixed; round 2 approved.
ADR 0547 (version 42; the operator's choice of 2026-10-25 22:31). Since release 6 nobody publishes memberships, so a seat-holding module newly placed on a node cannot serve its seat (ace's mesh-build-go at 22:29; issue 1945 notes 42, 47).
New module modules/mesh-grants (registered by its module.json; pins mesh-sdk at the group's head):
- Publishes memberships on `mesh.assignment.<node>.<module>`, on change only, built from the manifest the wanted build names (trunk's as fallback). **It publishes only a first membership (the stream answers 404) or one that loses nothing from the last** (Losses walks the whole last membership: capabilities per kind, seat traffic, serves, seats, states, logs, streams, hears, waits, reaches, Mesh, Receives; lists compared by containment). Anything that would drop something (e.g. verified-sender, which it cannot judge without root-free records) stays in shadow and grants_membership names what would be lost. A refused or failed read is never taken as first.
- The user list, assertions and grants: composed and compared only (shadow). take-over refuses, naming the enrolment users and persons not on the bus (issue 1126).
- Never exits on a refusal; no lock held across a bus call.
- Tools: grants_grants, grants_membership, grants_user_list, grants_compose_now, grants_assert, grants_take_over, grants_hand_back (the last two refused without a person account).
Group with mesh-control (the one grant) and mesh-sdk (the composer copy) PRs of the same branch name.
Checked: go test -race (3 runs), go vet with and without the integration tag in modules/mesh-grants. Unit 574 (one table test with rows), integration 76 (none added).
Review: round 1 blocked (the direct-get grant missing; a republished membership would drop verified-sender and stop the operator's Telegram approvals counting), both fixed; round 2 approved.
Reviewed-by: review-grants@shanks at 26ba7404bfc40351a377d5ccc8e4f6445a600c85
The grants part must compose with the controller's own composer before it can take over the
list; in shadow it proves the two agree, names every input the bus does not carry yet, and
takes no effect. It claims no seat (mesh-sdk's seat list does not name mesh-grants for the
running composer), serves module tools, and keeps running when a read or write is refused.
Since release 6 nobody publishes memberships, so a module placed since cannot serve its seat
or reach a new state (the operator, 2026-10-25 22:31). The part publishes each membership on
the assignments stream only when it differs from the one last published, composes from the
manifest the wanted build names, and says a refused publish and tries again at the next event.
Pins mesh-sdk 881da7f, whose composer grants mesh-grants that publish.
Composed without a root-free judgement, a membership would drop a kind's verified-sender and the
operator's channel approvals would stop being honoured; any loss now stays a shadow difference,
named. A tool no longer waits on a pass's round trip. compose-now says the controller serves no
verb to write a module's grant again.
Deliverynovox/mesh-delivery@26ba7404bfc4 — merged since 2026-10-25T22:44:13Z
Source — source.main moved to novox/mesh-delivery@2a856e2a76. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
composed together: fail — the checker's verdict at the members' heads (925f92f35382): integration: github.com/novox/mesh-controller/cmd/mesh-controller.TestTheDeclarationsStreamGoesOnceEveryNodeRunsTheNewEngine
Transitions
2026-10-25 21:57 (new) → proposed (announced): novox/mesh-delivery#53's head announced
2026-10-25 22:13 proposed → rejected (refused): a verdict names this commit and the trunk's head as its trunk commit, and the gate failed or could not run, or the repository's own check failed
2026-10-25 22:26 rejected → proposed (recheck): the check gates no merge (check-gates-merge false): its verdict is shown, not waited on
2026-10-25 22:26 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-25 22:44 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-delivery@26ba7404bfc4` — **merged** since 2026-10-25T22:44:13Z
**Source** — source.main moved to novox/mesh-delivery@2a856e2a76ea. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Group** `fix/1945-memberships`: novox/mesh-controller@a81717e53cf4, novox/mesh-delivery@26ba7404bfc4, novox/mesh-sdk@b7b5c6ef27a0
- composed together: fail — the checker's verdict at the members' heads (925f92f35382): integration: github.com/novox/mesh-controller/cmd/mesh-controller.TestTheDeclarationsStreamGoesOnceEveryNodeRunsTheNewEngine
**Transitions**
- 2026-10-25 21:57 (new) → proposed (announced): novox/mesh-delivery#53's head announced
- 2026-10-25 22:13 proposed → rejected (refused): a verdict names this commit and the trunk's head as its trunk commit, and the gate failed or could not run, or the repository's own check failed
- 2026-10-25 22:26 rejected → proposed (recheck): the check gates no merge (check-gates-merge false): its verdict is shown, not waited on
- 2026-10-25 22:26 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-25 22:44 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: the operator's Approve of this pull request's merge into main is ended: a head it covers moved on: the heads it covers are no longer the group's heads. Nothing is merged on it. The operator is asked again once the checks pass at the new head.
mesh-delivery: the operator's Approve of this pull request's merge into main is ended: a head it covers moved on: the heads it covers are no longer the group's heads. Nothing is merged on it. The operator is asked again once the checks pass at the new head.
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 (version 42; the operator's choice of 2026-10-25 22:31). Since release 6 nobody publishes memberships, so a seat-holding module newly placed on a node cannot serve its seat (ace's mesh-build-go at 22:29; issue 1945 notes 42, 47).
New module modules/mesh-grants (registered by its module.json; pins mesh-sdk at the group's head):
mesh.assignment.<node>.<module>, on change only, built from the manifest the wanted build names (trunk's as fallback). It publishes only a first membership (the stream answers 404) or one that loses nothing from the last (Losses walks the whole last membership: capabilities per kind, seat traffic, serves, seats, states, logs, streams, hears, waits, reaches, Mesh, Receives; lists compared by containment). Anything that would drop something (e.g. verified-sender, which it cannot judge without root-free records) stays in shadow and grants_membership names what would be lost. A refused or failed read is never taken as first.Group with mesh-control (the one grant) and mesh-sdk (the composer copy) PRs of the same branch name.
Checked: go test -race (3 runs), go vet with and without the integration tag in modules/mesh-grants. Unit 574 (one table test with rows), integration 76 (none added).
Review: round 1 blocked (the direct-get grant missing; a republished membership would drop verified-sender and stop the operator's Telegram approvals counting), both fixed; round 2 approved.
Reviewed-by: review-grants@shanks at
26ba7404bf1ff5049) b4af9cdb7aDelivery
novox/mesh-delivery@26ba7404bfc4— merged since 2026-10-25T22:44:13ZSource — source.main moved to novox/mesh-delivery@2a856e2a76. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Group
fix/1945-memberships: novox/mesh-controller@a81717e53c, novox/mesh-delivery@26ba7404bf, novox/mesh-sdk@b7b5c6ef27Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.mesh-delivery: the operator's Approve of this pull request's merge into main is ended: a head it covers moved on: the heads it covers are no longer the group's heads. Nothing is merged on it. The operator is asked again once the checks pass at the new head.