diff --git a/modules/mesh-grants/cmd/mesh-grants/integration_test.go b/modules/mesh-grants/cmd/mesh-grants/integration_test.go index 2ed1c835..b2ce0815 100644 --- a/modules/mesh-grants/cmd/mesh-grants/integration_test.go +++ b/modules/mesh-grants/cmd/mesh-grants/integration_test.go @@ -18,11 +18,11 @@ import ( "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" - "git.novox.be/novox/mesh-delivery/sdk/views" "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/membership" "git.novox.be/novox/mesh-sdk/go/process" "git.novox.be/novox/mesh-sdk/go/seal" + "git.novox.be/novox/mesh-sdk/go/views" "mesh-grants/internal/grants" ) diff --git a/modules/mesh-grants/cmd/mesh-grants/main.go b/modules/mesh-grants/cmd/mesh-grants/main.go index 7a192dbd..9e0c8153 100644 --- a/modules/mesh-grants/cmd/mesh-grants/main.go +++ b/modules/mesh-grants/cmd/mesh-grants/main.go @@ -36,7 +36,7 @@ import ( "git.novox.be/novox/mesh-sdk/go/announce" "git.novox.be/novox/mesh-sdk/go/process" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" "mesh-grants/internal/grants" ) diff --git a/modules/mesh-grants/cmd/mesh-grants/tools.go b/modules/mesh-grants/cmd/mesh-grants/tools.go index 636d16e9..0b140f3e 100644 --- a/modules/mesh-grants/cmd/mesh-grants/tools.go +++ b/modules/mesh-grants/cmd/mesh-grants/tools.go @@ -10,7 +10,7 @@ import ( "sync" "time" - "git.novox.be/novox/mesh-delivery/sdk/views" + "git.novox.be/novox/mesh-sdk/go/views" stdio "git.novox.be/novox/mesh-sdk/go" "git.novox.be/novox/mesh-sdk/go/handacts" diff --git a/modules/mesh-grants/go.mod b/modules/mesh-grants/go.mod index bb7210ea..ee23823d 100644 --- a/modules/mesh-grants/go.mod +++ b/modules/mesh-grants/go.mod @@ -9,7 +9,6 @@ require ( ) require ( - git.novox.be/novox/mesh-delivery/sdk v0.0.0-00010101000000-000000000000 github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/klauspost/compress v1.20.0 // indirect @@ -21,5 +20,3 @@ require ( golang.org/x/sys v0.48.0 // indirect golang.org/x/time v0.15.0 // indirect ) - -replace git.novox.be/novox/mesh-delivery/sdk => ../../sdk diff --git a/modules/mesh-grants/grants_test.go b/modules/mesh-grants/grants_test.go index f5e59d03..d634d5b5 100644 --- a/modules/mesh-grants/grants_test.go +++ b/modules/mesh-grants/grants_test.go @@ -21,12 +21,12 @@ import ( "github.com/nats-io/nats.go/jetstream" - "git.novox.be/novox/mesh-delivery/sdk/views" "git.novox.be/novox/mesh-sdk/go/asks" "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" "git.novox.be/novox/mesh-sdk/go/membership" "git.novox.be/novox/mesh-sdk/go/seal" + "git.novox.be/novox/mesh-sdk/go/views" "mesh-grants/internal/buscompose" "mesh-grants/internal/grants" @@ -378,14 +378,18 @@ const ( // brokerSeat is one verb of the bus's seat as a membership serves it: nats claims the seat in fixture and no membership // composed there serves it, so a membership or list that drops it leaves the seat with no holder (issue 1945). -func brokerSeat() (seat, verb string) { - s, _ := catalogue.SeatNamed(catalogue.BrokerSeat) - verb = "v" - if len(s.Serves) > 0 { - verb = s.Serves[0].Name - } - return s.Name, verb -} +// heldSeat is a seat the fixture's bus module claims beside mesh-broker (natsHeldManifest), and a verb of it: a seat the +// catalogue defines without verbs, its holder declaring them, so a verb the composition no longer grants is lost, never +// retired. mesh-broker's own verbs are all optional, and the composition grants its reading verbs to every holder, so +// losing one of them loses no holder. +func heldSeat() (seat, verb string) { return heldSeatName, "v" } + +// heldSeatName is that seat, and natsHeldManifest the fixture's bus module claiming it beside mesh-broker. +const ( + heldSeatName = "mesh-dns-resolver" + natsHeldManifest = `{"module":"nats","version":"1","claims":[{"name":"mesh-broker"},{"name":"` + heldSeatName + `"}],` + + `"own-secrets":{"broker":"/var/lib/nats/broker"}}` +) // fixture is a mesh of two machines: a runs the bus and mod-x, b runs mod-y; the bus node's agent loaded a list. func fixture() *fakeBus { @@ -1561,8 +1565,9 @@ func TestGrants(t *testing.T) { // Issue 1945, 2026-10-27 09:21: a list that would leave a seat the list in force holds with no holder, // while a placed module still claims it, is held, as such a membership is: not written, the warning // raised naming the seat. A list that only adds is written; one whose loaded grants cannot be read is held. + b.manifestOf("nats", natsHeldManifest) inForce := slices.Clone(b.loaded) - seat, verb := brokerSeat() + seat, verb := heldSeat() seatGrant := "mesh.seat." + seat + ".call." + verb + ".*" for i := range b.loaded { if b.loaded[i].User == "a.nats" { @@ -1627,7 +1632,7 @@ func TestGrants(t *testing.T) { t.Run("memberships: published unless a seat would lose its last holder or a holder a capability it asks for", func(t *testing.T) { const key = "a.mod-x" - brokerName, brokerVerb := brokerSeat() + brokerName, brokerVerb := heldSeat() // The telegram module's claim of its channel, as mesh-catalog's telegram manifest has it (c05aa5e6), on mod-x. const telegramClaim = `[{"name":"channel","scope":"mesh","kind":"telegram","capabilities":["deliver","verified-sender"]}]` verified := func(m map[string]any) map[string]any { @@ -1684,6 +1689,7 @@ func TestGrants(t *testing.T) { } { t.Run(row.name, func(t *testing.T) { b := fixture() + b.manifestOf("nats", natsHeldManifest) if row.claims != "" { b.manifestOf("mod-x", strings.Replace(xManifest, `"own-secrets"`, `"claims":`+row.claims+`,"own-secrets"`, 1)) } @@ -1885,6 +1891,7 @@ func TestGrants(t *testing.T) { t.Run("memberships held back: every one is said and listed", func(t *testing.T) { b := fixture() + b.manifestOf("nats", natsHeldManifest) b.loaded = shadowOf(t, b) recs, _ := grants.Records(grants.ReadInputs(b, &grants.Manifests{})) b.own[grants.StateMemberships] = map[string][]byte{} @@ -1892,7 +1899,7 @@ func TestGrants(t *testing.T) { raw, _ := json.Marshal(grants.Memberships(recs)[key].Membership) var m map[string]any _ = json.Unmarshal(raw, &m) - seat, verb := brokerSeat() + seat, verb := heldSeat() m["seats"] = []any{map[string]any{"seat": seat, "verb": verb, "subject": "mesh.seat." + seat + ".tool." + verb}} raw, _ = json.Marshal(m) b.own[grants.StateMemberships][key] = raw @@ -1918,7 +1925,7 @@ func TestGrants(t *testing.T) { <-done held, err := partOn(b).MembershipOf("", "") h, _ := held.(map[string]any) - if seat, _ := brokerSeat(); err != nil || h["count"] != 2 || !strings.Contains(fmt.Sprint(h["held"]), "the last holder of "+seat) { + if seat, _ := heldSeat(); err != nil || h["count"] != 2 || !strings.Contains(fmt.Sprint(h["held"]), "the last holder of "+seat) { t.Errorf("grants_membership with neither node nor module = %v, %v", held, err) } if _, err := partOn(b).MembershipOf("a", ""); err == nil { diff --git a/modules/mesh-grants/internal/grants/firstviews.go b/modules/mesh-grants/internal/grants/firstviews.go index 8a42e848..ab9b1923 100644 --- a/modules/mesh-grants/internal/grants/firstviews.go +++ b/modules/mesh-grants/internal/grants/firstviews.go @@ -10,8 +10,8 @@ import ( "sync" "time" - "git.novox.be/novox/mesh-delivery/sdk/views" "git.novox.be/novox/mesh-sdk/go/asks" + "git.novox.be/novox/mesh-sdk/go/views" ) // **The grants part's first views** (novox/hq ADR 0615 §1, §4 to §6, ADR 0621, ADR 0622; design 25 § 12.2; DLV-F4r,