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

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).
This commit is contained in:
2026-10-22 18:12:01 +02:00
parent 77596f37a3
commit 51900367a0
5 changed files with 92 additions and 7 deletions
@@ -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...) }
@@ -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.<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{}})
}
}
@@ -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)
+2 -1
View File
@@ -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 (
+2 -6
View File
@@ -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=