diff --git a/cmd/mesh-controller/addresses_integration_test.go b/cmd/mesh-controller/addresses_integration_test.go index 363f05e1..1420e0f6 100644 --- a/cmd/mesh-controller/addresses_integration_test.go +++ b/cmd/mesh-controller/addresses_integration_test.go @@ -111,6 +111,11 @@ func TestTheControlPlaneIsToldWhereTheNodePutTheStoreAndTheBroker(t *testing.T) Kind: inventory.BusController, Node: "anchor", Module: "mesh-controller"}, "bootstrap"); err != nil { t.Fatal(err) } + // Seeded with the credential the controller already uses, so it is sealed: an account counts as issued only once + // sealed (ADR 0543 §2, PR #467), and genesis's seed is the credential in use. + if err := open.inventory.MarkBusAccountSealed(ctx, "anchor.mesh-controller"); err != nil { + t.Fatal(err) + } if _, err := assign(ctx, open, "anchor", "mesh-controller"); err != nil { t.Fatal(err) } diff --git a/internal/broker/membership_test.go b/internal/broker/membership_test.go index 8f8e8493..a837340c 100644 --- a/internal/broker/membership_test.go +++ b/internal/broker/membership_test.go @@ -79,6 +79,8 @@ func TestAnAccountMayReadItsOwnMembershipAndNoOthers(t *testing.T) { t.Fatal(err) } has(t, grants.Publish, "mesh.assignment.*.*") + has(t, grants.Publish, "$JS.API.DIRECT.GET.ASSIGNMENTS.mesh.assignment.*.*") + hasNot(t, perms.Publish, "$JS.API.DIRECT.GET.ASSIGNMENTS.mesh.assignment.*.*") hasNot(t, grants.Publish, "$JS.API.STREAM.CREATE.>") hasNot(t, grants.Publish, "mesh.assignment.>") } diff --git a/internal/broker/nats.go b/internal/broker/nats.go index 6230f12d..8d51e7c3 100644 --- a/internal/broker/nats.go +++ b/internal/broker/nats.go @@ -916,9 +916,10 @@ func PermissionsFor(p Principal) (Permissions, error) { pub = append(pub, BusConnzSubject) } // The grants part alone publishes the modules' memberships into the assignments stream (novox/hq ADR 0547 §5; - // the operator, 2026-10-25 22:31): one per subject, `mesh.assignment..`, and no stream it defines. + // the operator, 2026-10-25 22:31): one per subject, `mesh.assignment..`, reading the last one of each + // first so it publishes only what changed, and no stream it defines. if p.Module == GrantsModule { - pub = append(pub, "mesh.assignment.*.*") + pub = append(pub, "mesh.assignment.*.*", "$JS.API.DIRECT.GET."+AssignmentsStream+".mesh.assignment.*.*") } // The view alone reads the build seats' workers for the backlog of asks (issue 1887 A8a). if p.Module == ViewModule {