From bf8f5c5c25e4ce01885e93f80eed2a5448f20ff6 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 17:11:53 +0100 Subject: [PATCH] mesh-grants: the bus module's process consumer hears the seat events said to it by name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its durable consumer filtered only its consumes, composed as module subjects, so the operator channel's decided for its own asks could not be heard there (design 25 § 12.3: it wakes on the warrant). Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- modules/mesh-grants/internal/buscompose/buscompose_test.go | 5 +++-- modules/mesh-grants/internal/buscompose/busstate.go | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/mesh-grants/internal/buscompose/buscompose_test.go b/modules/mesh-grants/internal/buscompose/buscompose_test.go index 35d557d2..f6977bdc 100644 --- a/modules/mesh-grants/internal/buscompose/buscompose_test.go +++ b/modules/mesh-grants/internal/buscompose/buscompose_test.go @@ -1095,7 +1095,7 @@ func theBusModulesProcessKeepsBusState(t *testing.T) { {Module: "node-tools", ToolRunner: true}, {Module: "nats", SnapshotsTheBus: true, Holds: []Seat{{Name: catalogue.BrokerSeat, Serves: BrokerVerbs(), Emits: []string{"created", "refused"}}}, - Consumes: []string{"mesh-delivery-indexer.manifest-accepted"}, Uses: []Seat{{Name: "operator-channel", Accepts: []string{"condition"}, ByCaller: []string{"condition"}}}, + Consumes: []string{"mesh-delivery-indexer.manifest-accepted"}, Uses: []Seat{{Name: "operator-channel", Accepts: []string{"condition"}, Emits: []string{"decided"}, ByCaller: []string{"condition", "decided"}}}, Streams: []ModuleStream{{Module: "nats", Name: "BROKER_EVENTS", Events: []string{"created", "refused"}, MaxAgeDays: 30, MaxMiB: 256}}, Processes: []ProcessPrincipal{{Process: "keeper", State: []string{"asked"}, Keeps: true}, {Process: "other"}, {Process: "nats-tools", Tools: true, Removes: []string{catalogue.RemovesEngineActs}}}}, @@ -1194,7 +1194,8 @@ func theBusModulesProcessKeepsBusState(t *testing.T) { made := false for _, mc := range AccountConsumers(users) { if mc.Consumer.Stream == "EVENTS" && mc.Consumer.Name == "a_nats_keeper" && - slices.Equal(mc.Consumer.Filters, []string{"mesh.mod.mesh-delivery-indexer.event.manifest-accepted"}) { + slices.Equal(mc.Consumer.Filters, []string{"mesh.mod.mesh-delivery-indexer.event.manifest-accepted", + "mesh.seat.operator-channel.event.decided.nats"}) { made = true } } diff --git a/modules/mesh-grants/internal/buscompose/busstate.go b/modules/mesh-grants/internal/buscompose/busstate.go index 27b73d5b..7b960106 100644 --- a/modules/mesh-grants/internal/buscompose/busstate.go +++ b/modules/mesh-grants/internal/buscompose/busstate.go @@ -92,6 +92,13 @@ func keeperConsumer(p Principal) (Consumer, bool) { filters = append(filters, s) } } + // And the events of the seats its module uses that are said to it by name, the operator channel's `decided` for its own + // asks among them (design 25 § 12.3: the process wakes on the warrant, heard on its durable consumer, never on a timer). + for _, s := range SeatTrafficOf(p.Module, nil, p.Uses, nil).Subscribe { + if strings.Contains(s, ".event.") { + filters = append(filters, s) + } + } if len(filters) == 0 { return Consumer{}, false }