Item 2 (join 11): the builder's bed declares no build-seat worker beside the SDK's, and answers the seat mesh-builds

The SDK's DeclareAskWorkers now declares each queue's two workers, main's and the named asks' (accept.<queue>.<asker>),
and the puller takes from both; the bed declared main's worker again filtering both forms, which overlaps the named
worker and the work queue refused ("filtered consumer not unique", 15 tests). The kind is a bed declaring by hand
what the SDK declares: the builder's bed was the only one whose own consumer overlaps the SDK's, and now declares
none. Behind it, the builder's seat server admits no caller of mesh-builds.reserved until the seat list holds
mesh-builds' definition (A-278); the bed's seat-definitions answers it from the contracts module's own file.

Builds: design 47 G §544, §600, A-115, A-278

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 13:02:03 +01:00
parent 8e50fab811
commit 24d0bae793
2 changed files with 22 additions and 13 deletions
@@ -6,6 +6,8 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"testing"
@@ -116,6 +118,21 @@ func (h *catalogHolder) buildSeats(t *testing.T, nc *nats.Conn, holders map[stri
defs[d.Seat] = d
}
}
// A seat of this repository's contracts module that the SDK's copy does not hold (mesh-builds) is read from its own file.
for seat := range holders {
if _, ok := defs[seat]; ok {
continue
}
raw, err := os.ReadFile(filepath.Join("..", "..", "..", "mesh-delivery-contracts", "seats", seat, "seat.json"))
if err != nil {
t.Fatalf("the definition of the seat %s: %v", seat, err)
}
d, err := seatdef.Parse(raw)
if err != nil {
t.Fatalf("the definition of the seat %s: %v", seat, err)
}
defs[seat] = d
}
for seat, on := range map[string]string{"node-build-go": "go", "node-build-node": "typescript", "node-build-image": seatdef.OnKindImage} {
d := defs[seat]
d.Acts = []seatdef.ActingRule{{Step: seatdef.StepBuild, On: on}}
@@ -165,18 +165,9 @@ func (f *fakeBuildModules) serve(t *testing.T, module string, nodes ...string) {
if err := runner.DeclareAskWorkers(f.ctx, f.js, language, 30*time.Second); err != nil {
t.Fatal(err)
}
// Design 47 G §600: each queue's worker takes an ask in both forms, main's and the builder's (accept.<queue>.builder); the
// build modules' helper above filters main's alone, so the worker is declared again with both.
stream, _ := sdkstep.AskStream(language)
for _, kind := range sdkstep.AskKinds {
worker, _ := sdkstep.AskWorker(language, kind)
main, _ := sdkstep.AskSubject(language, kind)
byBuilder, _ := sdkstep.AskSubjectBy(language, kind, sdkstep.AskerBuilder)
if _, err := f.js.CreateOrUpdateConsumer(f.ctx, stream, jetstream.ConsumerConfig{Durable: worker, FilterSubjects: []string{main, byBuilder},
AckPolicy: jetstream.AckExplicitPolicy, AckWait: 30 * time.Second, MaxDeliver: 5}); err != nil {
t.Fatal(err)
}
}
// Design 47 G §544, §600: the build modules' helper declares each queue's two workers, main's and the named asks'
// (accept.<queue>.<asker>), and the puller takes from both; the bed declares none of its own, since a worker filtering
// both forms overlaps the named worker, which a work queue refuses.
put := func(key string, value any) (uint64, error) {
raw, _ := value.(json.RawMessage)
return kv.Put(f.ctx, key, raw)
@@ -289,7 +280,8 @@ func startBedWith(t *testing.T, closed bool) *bed {
// each have their durable consumer.
b.catalog = newCatalogHolder(t, ctx, js, ctl)
b.catalog.buildSeats(t, ctl, map[string]string{"node-build-go": testGo, "node-build-node": testNode, "node-build-image": testImage,
"git": "mesh-delivery-forge-bridge", "mesh-catalog": "mesh-delivery-indexer"}) // the floor's sources are the holders of git and mesh-catalog
"git": "mesh-delivery-forge-bridge", "mesh-catalog": "mesh-delivery-indexer", // the floor's sources are the holders of git and mesh-catalog
"mesh-builds": builds.BuilderModule}) // the builder's own seat, whose verb reserved it answers once its definition is read (A-115, A-278)
readers := []string{"n1_" + builds.BuilderModule, "n2_" + builds.BuilderModule}
// The seat mesh-module-assigner's holder is read from the seat's verb assignments, as the builder finds it at run time (A-119).
assignerSub, err := ctl.Subscribe("mesh.seat.mesh-module-assigner.call.assignments.>", func(m *nats.Msg) {