From 8e791896f1782ab9800ce21cfd1ab9248f8a7a88 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 2026 18:02:11 +0200 Subject: [PATCH] =?UTF-8?q?Announce=20the=20states=20the=20delivery=20gate?= =?UTF-8?q?=20keeps=20(issue=201790,=20ADR=200495=20=C2=A72=20=C2=A75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cmd/mesh-delivery-gate/keeps.go | 12 +++++ .../keeps_integration_test.go | 26 ++++++++++ .../cmd/mesh-delivery-gate/keeps_test.go | 51 +++++++++++++++++++ .../cmd/mesh-delivery-gate/main.go | 4 ++ modules/mesh-delivery-gate/go.mod | 2 +- modules/mesh-delivery-gate/go.sum | 18 +------ 6 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps.go create mode 100644 modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_integration_test.go create mode 100644 modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_test.go diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps.go new file mode 100644 index 00000000..74013044 --- /dev/null +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps.go @@ -0,0 +1,12 @@ +package main + +import "git.novox.be/novox/mesh-sdk/go/announce" + +// Kept is every state this module keeps on the bus and whether other modules may read it (novox/hq ADR 0495 clause 2; +// issue 1790): the module says it itself, from its code, before it serves, and a reader is granted what it said +// (clause 3). A state is readable when another module's manifest reads it. keeps_test.go holds the list to the +// manifest's `state`, and keeps_integration_test.go that the module announces it on a bus. +var Kept = []announce.State{{Name: "asks"}, {Name: "deliveries"}, {Name: "groups"}, {Name: "merges"}, {Name: "owed"}, {Name: "pulls"}, {Name: "source"}} + +// announceKept says Kept through keeps, which is stdio.Keeps. +func announceKept(keeps func(...announce.State) error) error { return keeps(Kept...) } diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_integration_test.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_integration_test.go new file mode 100644 index 00000000..6269a4c7 --- /dev/null +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_integration_test.go @@ -0,0 +1,26 @@ +//go:build integration + +package main + +import ( + "testing" + + "git.novox.be/novox/mesh-sdk/go/announce" + "git.novox.be/novox/mesh-sdk/go/announcetest" + "git.novox.be/novox/mesh-sdk/go/process" +) + +// 1790/S (ADR 0495 clause 5): started against a bus of the test's own, the module announces on it every state it keeps, +// readable as other modules' manifests need. +func TestTheModuleAnnouncesEveryStateItKeepsOnTheBus(t *testing.T) { + announcetest.Check(t, "mesh-delivery-gate", Kept, func(url string) func() { + conn, err := process.Connect(process.Account{URL: url, Module: "mesh-delivery-gate", Node: "ace", User: "u", Password: "p"}) + if err != nil { + t.Fatal(err) + } + if err := announceKept(func(s ...announce.State) error { return conn.Keeps(s...) }); err != nil { + t.Fatal(err) + } + return conn.Close + }) +} diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_test.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_test.go new file mode 100644 index 00000000..bfccf856 --- /dev/null +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/keeps_test.go @@ -0,0 +1,51 @@ +package main + +import ( + "encoding/json" + "os" + "path/filepath" + "slices" + "testing" +) + +// 1790/S: the states the module announces are the states its manifest declares, no more, no fewer, and the readable +// ones are the states other modules' manifests read. +func TestTheStatesTheModuleAnnouncesAreTheStatesItsManifestDeclares(t *testing.T) { + raw, err := os.ReadFile(filepath.Join("..", "..", "module.json")) + if err != nil { + t.Fatal(err) + } + var m struct { + State []json.RawMessage `json:"state"` + } + if err := json.Unmarshal(raw, &m); err != nil { + t.Fatal(err) + } + declared := []string{} + for _, s := range m.State { + var name string + if json.Unmarshal(s, &name) != nil { + var o struct{ Name string } + if err := json.Unmarshal(s, &o); err != nil { + t.Fatal(err) + } + name = o.Name + } + declared = append(declared, name) + } + announced := []string{} + for _, s := range Kept { + announced = append(announced, s.Name) + } + slices.Sort(declared) + slices.Sort(announced) + if !slices.Equal(declared, announced) { + t.Errorf("announces %v, the manifest declares %v", announced, declared) + } + want := map[string]bool{} + for _, s := range Kept { + if s.Readable != want[s.Name] { + t.Errorf("state %s readable = %v, other modules' manifests read it: %v", s.Name, s.Readable, want[s.Name]) + } + } +} diff --git a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/main.go b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/main.go index e5ef06db..dc9a8359 100644 --- a/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/main.go +++ b/modules/mesh-delivery-gate/cmd/mesh-delivery-gate/main.go @@ -77,6 +77,10 @@ func main() { h.init() l := &listening{now: "not yet: starting"} go run(h, l, occupancy) + if err := announceKept(stdio.Keeps); err != nil { + logf("%v", err) + os.Exit(1) + } if err := stdio.Serve("", tools(h, l)); err != nil { logf("%v", err) os.Exit(1) diff --git a/modules/mesh-delivery-gate/go.mod b/modules/mesh-delivery-gate/go.mod index b37ee2ea..8a1015b3 100644 --- a/modules/mesh-delivery-gate/go.mod +++ b/modules/mesh-delivery-gate/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-gate go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261020060201-88581d0acaef + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022154726-a90f523edc75 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-gate/go.sum b/modules/mesh-delivery-gate/go.sum index 3807e8df..3bc35fca 100644 --- a/modules/mesh-delivery-gate/go.sum +++ b/modules/mesh-delivery-gate/go.sum @@ -1,15 +1,9 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261013182924-5933eb757d44 h1:r5xIo5qWOXQdCSMxvqJy8kV4U+P/QWXFK6971Ha6wU8= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261013182924-5933eb757d44/go.mod h1:GFuZUElBZ9A++mxgIKo97aXXo+kV0uJ/UkbhQPPIbrY= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261019230201-5786ba190c69 h1:kvtV/SPsdRVUL/BZ3xxGS6U8YrXy/t7TRBjVrD6VLw8= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261019230201-5786ba190c69/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261020060201-88581d0acaef h1:xy3wuGWJpqMAXYdXolocYG6w9xnWqBltVUffoaziIKo= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261020060201-88581d0acaef/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022154726-a90f523edc75 h1:e/aOJLHaNSBPFFHHjUF+0fAfjmtMUy/vDWqetauWp/U= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022154726-a90f523edc75/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= github.com/google/go-tpm v0.9.8/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4= @@ -18,23 +12,15 @@ github.com/nats-io/jwt/v2 v2.8.1 h1:V0xpGuD/N8Mi+fQNDynXohVvp7ZztevW5io8CUWlPmU= github.com/nats-io/jwt/v2 v2.8.1/go.mod h1:nWnOEEiVMiKHQpnAy4eXlizVEtSfzacZ1Q43LIRavZg= github.com/nats-io/nats-server/v2 v2.11.17 h1:GKEghcFK6A+aFx11Yf1LjgLC3txAwvyhnYzhBIQZA8I= github.com/nats-io/nats-server/v2 v2.11.17/go.mod h1:B1sFVz4StNosQ903ak4N1G01Fl/9f8e06mXpFIE2K24= -github.com/nats-io/nats.go v1.51.0 h1:ByW84XTz6W03GSSsygsZcA+xgKK8vPGaa/FCAAEHnAI= -github.com/nats-io/nats.go v1.51.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno= github.com/nats-io/nats.go v1.54.0 h1:vsXoOxjHp/GmPUN+EcI7uOf/uB+iAP+kEsAFNQN0yzA= github.com/nats-io/nats.go v1.54.0/go.mod h1:y+DZoD1oBOYfZTU681eTUiUjI0vbqYGixNVFHcjHJ0k= -github.com/nats-io/nkeys v0.4.15 h1:JACV5jRVO9V856KOapQ7x+EY8Jo3qw1vJt/9Jpwzkk4= -github.com/nats-io/nkeys v0.4.15/go.mod h1:CpMchTXC9fxA5zrMo4KpySxNjiDVvr8ANOSZdiNfUrs= github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg= github.com/nats-io/nkeys v0.4.16/go.mod h1:llLgWoI0o4z/Q57q2R1kHfmocyhGV6VG/U18Glg1Afs= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=