mesh-build-image: announce the states it keeps from its code, so readers are granted from its word (issue 1790, ADR 0495 §2 §5)

Kept (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).
This commit is contained in:
2026-10-22 18:12:01 +02:00
parent 56f842c3af
commit 77596f37a3
5 changed files with 90 additions and 3 deletions
@@ -0,0 +1,19 @@
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 reads 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: "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...) }
@@ -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-image"
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.<module>.event.<key>, 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{}})
}
}
@@ -47,6 +47,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)
+1 -1
View File
@@ -3,7 +3,7 @@ module meshbuildimage
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
)
+2 -2
View File
@@ -1,5 +1,5 @@
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=