From 075b61901c781e4d89f37426648051e184e8bed7 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 2026 18:08:06 +0200 Subject: [PATCH] =?UTF-8?q?mesh-build-node:=20announce=20the=20states=20it?= =?UTF-8?q?=20keeps=20from=20its=20code,=20so=20readers=20are=20granted=20?= =?UTF-8?q?from=20its=20word=20(issue=201790,=20ADR=200495=20=C2=A72=20?= =?UTF-8?q?=C2=A75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kept (toolchains, keys, steps, each read by another module today) is said with stdio.Keeps before the module serves; announcetest.Check holds the announcement equal to the code. The module is pinned to mesh-sdk feat/r4e-sdk 9cb4d59. --- .../cmd/mesh-build-node/announce.go | 20 ++++++ .../announce_integration_test.go | 63 +++++++++++++++++++ .../cmd/mesh-build-node/main.go | 5 ++ modules/mesh-build-node/go.mod | 19 +++++- modules/mesh-build-node/go.sum | 33 ++++++++-- 5 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 modules/mesh-build-node/cmd/mesh-build-node/announce.go create mode 100644 modules/mesh-build-node/cmd/mesh-build-node/announce_integration_test.go diff --git a/modules/mesh-build-node/cmd/mesh-build-node/announce.go b/modules/mesh-build-node/cmd/mesh-build-node/announce.go new file mode 100644 index 00000000..2543242e --- /dev/null +++ b/modules/mesh-build-node/cmd/mesh-build-node/announce.go @@ -0,0 +1,20 @@ +package main + +// What this module keeps on the bus, announced from its code (novox/hq ADR 0495 §2 §5; issue 1790): every state it +// keeps, each readable by others, since another module reads each today (the builder, the checker and the indexer read toolchains; the builder and the checker read steps; gitea reads keys). A state of its own that it +// did not name here is refused at the call (stdio.Keeps). + +import ( + stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-sdk/go/announce" +) + +// Kept are the states the module keeps. +var Kept = []announce.State{ + {Name: "toolchains", Readable: true}, + {Name: "keys", Readable: true}, + {Name: "steps", Readable: true}, +} + +// keepStates announces Kept as this module's (stdio.Keeps): main calls it before it serves. +func keepStates() error { return stdio.Keeps(Kept...) } diff --git a/modules/mesh-build-node/cmd/mesh-build-node/announce_integration_test.go b/modules/mesh-build-node/cmd/mesh-build-node/announce_integration_test.go new file mode 100644 index 00000000..2b1acae8 --- /dev/null +++ b/modules/mesh-build-node/cmd/mesh-build-node/announce_integration_test.go @@ -0,0 +1,63 @@ +//go:build integration + +package main + +import ( + "bufio" + "encoding/json" + "io" + "testing" + + "github.com/nats-io/nats.go" + + stdio "git.novox.be/novox/mesh-sdk/go" + "git.novox.be/novox/mesh-sdk/go/announcetest" +) + +// 1790 (ADR 0495 §5): served as the runtime serves it, the module announces on the bus every state it keeps, as its +// code declares them. The runtime's part, publishing what the bundle asks to publish, is played by relay. +func TestTheModuleAnnouncesEveryStateItKeeps(t *testing.T) { + const module = "mesh-build-node" + announcetest.Check(t, module, Kept, func(url string) func() { + t.Setenv("MESH_MODULE", module) + t.Setenv("MESH_NODE", "shanks") + nc, err := nats.Connect(url) + if err != nil { + t.Fatal(err) + } + if err := keepStates(); err != nil { + t.Fatal(err) + } + inR, inW := io.Pipe() + outR, outW := io.Pipe() + go func() { _ = stdio.ServeOn(module, nil, inR, outW) }() + go relay(t, module, nc, outR, inW) + return func() { _ = inW.Close(); _ = outW.Close(); nc.Close() } + }) +} + +// relay is the runtime's side of the channel: each mesh/publish the bundle asks is published on its module's event +// subject, mesh.mod..event., and answered. +func relay(t *testing.T, module string, nc *nats.Conn, from io.Reader, to io.Writer) { + sc := bufio.NewScanner(from) + sc.Buffer(make([]byte, 1<<20), 1<<24) + enc := json.NewEncoder(to) + for sc.Scan() { + var m struct { + ID json.RawMessage `json:"id"` + Method string `json:"method"` + Params struct { + Key string `json:"key"` + Body json.RawMessage `json:"body"` + } `json:"params"` + } + if json.Unmarshal(sc.Bytes(), &m) != nil || m.Method != "mesh/publish" { + continue + } + if err := nc.Publish("mesh.mod."+module+".event."+m.Params.Key, m.Params.Body); err != nil { + t.Errorf("publishing %s: %v", m.Params.Key, err) + } + _ = nc.Flush() + _ = enc.Encode(map[string]any{"id": m.ID, "result": map[string]any{}}) + } +} diff --git a/modules/mesh-build-node/cmd/mesh-build-node/main.go b/modules/mesh-build-node/cmd/mesh-build-node/main.go index 841d4bbd..1d334cac 100644 --- a/modules/mesh-build-node/cmd/mesh-build-node/main.go +++ b/modules/mesh-build-node/cmd/mesh-build-node/main.go @@ -57,6 +57,11 @@ func main() { go m.Start(ctx) } go startKeeper(ctx) + // Every state it keeps, said on the bus before it serves (ADR 0495 §2; issue 1790). + if err := keepStates(); err != nil { + logf("announcing the states it keeps: %v", err) + os.Exit(1) + } if err := stdio.Serve("", m.Tools(m.StepTools())); err != nil { logf("%v", err) os.Exit(1) diff --git a/modules/mesh-build-node/go.mod b/modules/mesh-build-node/go.mod index 4b453f9b..ba4a2bf3 100644 --- a/modules/mesh-build-node/go.mod +++ b/modules/mesh-build-node/go.mod @@ -2,4 +2,21 @@ module meshbuildnode go 1.26.0 -require git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc +require ( + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022160024-9cb4d59093a7 + github.com/nats-io/nats.go v1.54.0 +) + +require ( + 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 + github.com/minio/highwayhash v1.0.4 // indirect + github.com/nats-io/jwt/v2 v2.8.1 // indirect + github.com/nats-io/nats-server/v2 v2.11.17 // indirect + github.com/nats-io/nkeys v0.4.16 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/time v0.15.0 // indirect +) diff --git a/modules/mesh-build-node/go.sum b/modules/mesh-build-node/go.sum index 8097dd56..28ab5678 100644 --- a/modules/mesh-build-node/go.sum +++ b/modules/mesh-build-node/go.sum @@ -1,6 +1,27 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3 h1:OKxU64kHN1yQ/GOa6LwoUwVmiQ74d83WMSZJRFPVm9c= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021093645-465beb4ea5e3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5 h1:1BiPKRPTYpgex8rSHWT9az0BteOafGWRDzd/Ba6GAcA= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021185947-afbe371003a5/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc h1:ZJScJSnF6LgFl55/VJ9RT/lNroVWun469sXtx0nlVYw= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022160024-9cb4d59093a7 h1:wK9O1CgNk7mo3IdJqW/CCx/hebg+1F0rkvW8CvJfnRM= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022160024-9cb4d59093a7/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.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA= +github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI= +github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clgl4= +github.com/minio/highwayhash v1.0.4/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= +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.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.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.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.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= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=