From 51900367a03c6d3b6992fb42ce9c4fcc060b2bae Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 2026 18:12:01 +0200 Subject: [PATCH] =?UTF-8?q?mesh-build-go:=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. Pinned to mesh-sdk feat/r4e-sdk 9cb4d59. The manifest test's call of the deleted StateReadsNothingDeclares still has to go (the edit is waiting on the operator's permission). --- .../cmd/mesh-build-go/announce.go | 20 ++++++ .../announce_integration_test.go | 63 +++++++++++++++++++ .../mesh-build-go/cmd/mesh-build-go/main.go | 5 ++ modules/mesh-build-go/go.mod | 3 +- modules/mesh-build-go/go.sum | 8 +-- 5 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 modules/mesh-build-go/cmd/mesh-build-go/announce.go create mode 100644 modules/mesh-build-go/cmd/mesh-build-go/announce_integration_test.go diff --git a/modules/mesh-build-go/cmd/mesh-build-go/announce.go b/modules/mesh-build-go/cmd/mesh-build-go/announce.go new file mode 100644 index 00000000..2543242e --- /dev/null +++ b/modules/mesh-build-go/cmd/mesh-build-go/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-go/cmd/mesh-build-go/announce_integration_test.go b/modules/mesh-build-go/cmd/mesh-build-go/announce_integration_test.go new file mode 100644 index 00000000..d009863d --- /dev/null +++ b/modules/mesh-build-go/cmd/mesh-build-go/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-go" + 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-go/cmd/mesh-build-go/main.go b/modules/mesh-build-go/cmd/mesh-build-go/main.go index 3e2c3a5e..a02f9004 100644 --- a/modules/mesh-build-go/cmd/mesh-build-go/main.go +++ b/modules/mesh-build-go/cmd/mesh-build-go/main.go @@ -53,6 +53,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-go/go.mod b/modules/mesh-build-go/go.mod index 15a8c845..bad63444 100644 --- a/modules/mesh-build-go/go.mod +++ b/modules/mesh-build-go/go.mod @@ -3,8 +3,9 @@ module meshbuildgo go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261021192148-78364e318bdc + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261022160024-9cb4d59093a7 github.com/nats-io/nats-server/v2 v2.11.17 + github.com/nats-io/nats.go v1.54.0 ) require ( diff --git a/modules/mesh-build-go/go.sum b/modules/mesh-build-go/go.sum index e35e25ab..28ab5678 100644 --- a/modules/mesh-build-go/go.sum +++ b/modules/mesh-build-go/go.sum @@ -1,9 +1,5 @@ -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=