BG4, BN4, BI4: the three build modules' pullers say the seat's events

Builds: design 47 G §496, §602, §603

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 05:33:26 +01:00
parent 48a9402ca0
commit c1008aeedf
15 changed files with 123 additions and 6 deletions
@@ -84,7 +84,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul
return raw, err
}
}
return &steprun.Puller{Source: source, Language: sdkstep.AskGo, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
var say func(string, any, string) error
if m.SayEvent != nil {
say = steprun.SayOn(sdkstep.AskGo, m.Node, m.SayEvent)
}
return &steprun.Puller{Source: source, Language: sdkstep.AskGo, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Logf: m.Say, Has: m.Has,
Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) {
if err := m.Check(ctx); err != nil {
@@ -0,0 +1,30 @@
package main
import (
"testing"
sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
)
// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects.
func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) {
var subjects []string
m := &Module{Node: "ace", Capacity: func() int { return 0 },
SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }}
p := m.Puller(nil, steprun.NewFakeAsks())
if p.Say == nil {
t.Fatal("the puller says no event")
}
seat, _ := sdkstep.BuildSeat(sdkstep.AskGo)
for _, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if err := p.Say(event, nil, "id"); err != nil {
t.Fatal(err)
}
}
for i, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want {
t.Errorf("%s said on %s, want %s", event, subjects[i], want)
}
}
}
@@ -17,8 +17,8 @@ import (
"path/filepath"
"strings"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
)
// layBuilds lays each of builds as the package it names in every module directory dirs (relative to tree) of the
@@ -37,6 +37,7 @@ func main() {
}
ctx := context.Background()
m := &Module{
SayEvent: stdio.SeatPublish,
Node: strings.TrimSpace(os.Getenv("MESH_NODE")),
Recipe: Current(),
Toolchains: stdio.State(seat.StateToolchains).Put,
@@ -24,6 +24,10 @@ const CheckRound = 10 * time.Minute
// Module is the Go build module's one running state: the node it runs on, its recipe, the toolchain guard and the
// states it writes (toolchains, steps).
type Module struct {
// SayEvent publishes an event of the go build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the
// puller's ask-taken, step-progress and step-ended (design 47 G §496, §602).
SayEvent func(subject string, body any, id string) error
Node string
Recipe Recipe
// Probe reads the installed Go version (ProbeGo).
@@ -62,7 +62,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul
if m.ReadPauses.Get != nil {
load = func(key string) ([]byte, error) { return m.ReadPauses.Get(key) }
}
return &steprun.Puller{Source: source, Language: sdkstep.AskImage, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
var say func(string, any, string) error
if m.SayEvent != nil {
say = steprun.SayOn(sdkstep.AskImage, m.Node, m.SayEvent)
}
return &steprun.Puller{Source: source, Language: sdkstep.AskImage, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Eligible: m.Eligible, Logf: m.Say,
Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) {
if err := m.Check(ctx); err != nil {
@@ -0,0 +1,30 @@
package main
import (
"testing"
sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
)
// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects.
func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) {
var subjects []string
m := &Module{Node: "ace", Capacity: func() int { return 0 },
SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }}
p := m.Puller(nil, steprun.NewFakeAsks())
if p.Say == nil {
t.Fatal("the puller says no event")
}
seat, _ := sdkstep.BuildSeat(sdkstep.AskImage)
for _, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if err := p.Say(event, nil, "id"); err != nil {
t.Fatal(err)
}
}
for i, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want {
t.Errorf("%s said on %s, want %s", event, subjects[i], want)
}
}
}
@@ -32,6 +32,7 @@ func logf(format string, a ...any) { fmt.Fprintf(os.Stderr, "[mesh-build-image]
func main() {
ctx := context.Background()
m := &Module{
SayEvent: stdio.SeatPublish,
Node: strings.TrimSpace(os.Getenv("MESH_NODE")),
RecordAct: handActRecorder,
Steps: stdio.State(seat.StateSteps).Put,
@@ -20,6 +20,10 @@ const CheckRound = 10 * time.Minute
// Module is the image build module's one running state.
type Module struct {
// SayEvent publishes an event of the image build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the
// puller's ask-taken, step-progress and step-ended (design 47 G §496, §602).
SayEvent func(subject string, body any, id string) error
Node string
// RecordAct writes an act in the hand-act log of the seat mesh-hand-acts (§463, §480): a drop writes it first.
RecordAct func(what, why string) error
@@ -7,8 +7,8 @@ package main
import (
"fmt"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
seat "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-contracts/go/seats/nodebuildimage"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
stdio "git.novox.be/novox/mesh-sdk/go"
)
@@ -72,7 +72,11 @@ func (m *Module) Puller(steps []StepTool, source steprun.AskSource) *steprun.Pul
if m.ReadPauses.Get != nil {
load = func(key string) ([]byte, error) { return m.ReadPauses.Get(key) }
}
return &steprun.Puller{Source: source, Language: sdkstep.AskNode, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
var say func(string, any, string) error
if m.SayEvent != nil {
say = steprun.SayOn(sdkstep.AskNode, m.Node, m.SayEvent)
}
return &steprun.Puller{Source: source, Language: sdkstep.AskNode, Say: say, Node: m.Node, Put: m.Steps, PausePut: m.Pauses, Load: load, ForgetPause: m.ForgetPause, WatchPauses: m.WatchPauses, PauseKeys: m.ReadPauses.Keys,
Capacity: capacity, SettingsFile: settings, WatchConfig: watch, CoresPerStep: cores, BuildHours: hours, Logf: m.Say,
Run: func(ctx context.Context, a sdkstep.StepAsk) (any, error) {
if err := m.Prepare(ctx); err != nil {
@@ -0,0 +1,30 @@
package main
import (
"testing"
sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
)
// Design 47 G §496, §602 (BG4, BN4, BI4): the module's puller says the seat's events on this node's subjects.
func TestPullerSaysTheSeatsEventsOnItsNodesSubject(t *testing.T) {
var subjects []string
m := &Module{Node: "ace", Capacity: func() int { return 0 },
SayEvent: func(subject string, _ any, _ string) error { subjects = append(subjects, subject); return nil }}
p := m.Puller(nil, steprun.NewFakeAsks())
if p.Say == nil {
t.Fatal("the puller says no event")
}
seat, _ := sdkstep.BuildSeat(sdkstep.AskNode)
for _, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if err := p.Say(event, nil, "id"); err != nil {
t.Fatal(err)
}
}
for i, event := range []string{"ask-taken", "step-progress", "step-ended"} {
if want := "mesh.seat." + seat + ".event." + event + ".ace"; subjects[i] != want {
t.Errorf("%s said on %s, want %s", event, subjects[i], want)
}
}
}
@@ -12,8 +12,8 @@ import (
"os"
"path/filepath"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
sdkstep "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/buildstep"
"git.novox.be/novox/mesh-delivery/modules/mesh-delivery-sdk/steprun"
)
// storedBuild is one member's build, read and checked.
@@ -40,6 +40,7 @@ func main() {
return ReadRegistry(filepath.Join(home, "package-registry.json"))
}
m := &Module{
SayEvent: stdio.SeatPublish,
Node: strings.TrimSpace(os.Getenv("MESH_NODE")),
Reload: func() (Recipe, error) { return ReadRecipe(paths.LockPath()) },
Probe: ProbeNode,
@@ -25,6 +25,10 @@ const CheckRound = 10 * time.Minute
// Module is the Node build module's one running state: the node it runs on, its recipe, the toolchain guard, the
// toolchain directory and the states it writes (toolchains, steps).
type Module struct {
// SayEvent publishes an event of the node build seat on a seat subject (stdio.SeatPublish; nil says none, a test's): the
// puller's ask-taken, step-progress and step-ended (design 47 G §496, §602).
SayEvent func(subject string, body any, id string) error
Node string
// Recipe is the recipe in force. Reload, when set, reads it again at every check (the lock file the mesh
// writes can change under a running module); a failure to read it is a refusal.