D3 (contracts): the fixtures and contract tests G adds name roles, not nodes and the operator

Nodes read anchor, home-server, laptop, workstation (in the order the node names sorted) and a person reads alice.

Builds: design 47 G A-296 (review round 2 D3)

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 22:18:30 +01:00
parent b056f32c13
commit 4ba52d9ab7
36 changed files with 220 additions and 220 deletions
@@ -312,8 +312,8 @@ func TestSeatHoldersFollowsTheClaimantOfTheAssignerSeat(t *testing.T) {
seats := &fakeSeats{source: []string{"main"}, regs: map[string][]string{}, version: 1}
w := &fakeWiring{adopted: map[string]*views.Follower{}, hears: map[string]func(context.Context, []byte) error{},
values: map[string]map[string]json.RawMessage{
"asg-a": {"node-tool-runner.ace": json.RawMessage(`{"holders":[{"module":"node-tools","node":"ace"}]}`)},
"asg-b": {"node-tool-runner.ace": json.RawMessage(`{"holders":[{"module":"tool-runner-2","node":"ace"}]}`)}},
"asg-a": {"node-tool-runner.anchor": json.RawMessage(`{"holders":[{"module":"node-tools","node":"anchor"}]}`)},
"asg-b": {"node-tool-runner.anchor": json.RawMessage(`{"holders":[{"module":"tool-runner-2","node":"anchor"}]}`)}},
followed: make(chan string, 4)}
b, err := NewBranches(w, seats.call)
if err != nil {
@@ -64,7 +64,7 @@ func TestAVerdictIsRefusedForWhatAReaderCouldNotPlace(t *testing.T) {
t.Errorf("a pass judged by a checking program is refused: %v", err)
}
failed := passing()
failed.State, failed.Failed = VerdictFail, &checker.VerdictsByGroupHeadsValueFailed{Machine: "ace"}
failed.State, failed.Failed = VerdictFail, &checker.VerdictsByGroupHeadsValueFailed{Machine: "anchor"}
if err := CheckVerdict(failed); err != nil {
t.Errorf("a fail naming a machine is refused: %v", err)
}
@@ -42,7 +42,7 @@ func TestSubjectsAndBodies(t *testing.T) {
if _, err := GroupEnded([]byte(`{"v":1,"group":"g","branch":"main","outcome":"passed","pipelines":[{"module":"nats"}]}`)); err == nil {
t.Error("a group-ended with a pipeline naming nothing was taken")
}
if e, err := StepEnded([]byte(`{"v":1,"pipeline":"p","module":"nats","branch":"main","commit":"c1","result":{"step":"unit","status":"required","outcome":"passed","rerun":true,"by":"operator@shanks"}}`)); err != nil || !e.Result.Rerun {
if e, err := StepEnded([]byte(`{"v":1,"pipeline":"p","module":"nats","branch":"main","commit":"c1","result":{"step":"unit","status":"required","outcome":"passed","rerun":true,"by":"operator@workstation"}}`)); err != nil || !e.Result.Rerun {
t.Errorf("step-ended: %+v, %v", e, err)
}
}
@@ -110,12 +110,12 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
if _, err := DecodeNodeWant([]byte(`{"v":1,"composed":"` + c + `","fp":"` + a + `"}`)); err == nil {
t.Error("a fingerprint in a node's own want is read")
}
raw, err = EncodeHeld(Held{Node: "ace", Words: "unhealthy"})
raw, err = EncodeHeld(Held{Node: "anchor", Words: "unhealthy"})
if err != nil {
t.Fatal(err)
}
sameJSON(t, raw, `{"v":1,"node":"ace","words":"unhealthy"}`)
if h, err := DecodeHeld(raw); err != nil || !SameHeld(h, Held{V: 1, Node: "ace", Words: "unhealthy"}) {
sameJSON(t, raw, `{"v":1,"node":"anchor","words":"unhealthy"}`)
if h, err := DecodeHeld(raw); err != nil || !SameHeld(h, Held{V: 1, Node: "anchor", Words: "unhealthy"}) {
t.Fatalf("%+v %v", h, err)
}
if _, err := EncodeHeld(Held{Node: "a.b"}); err == nil {
@@ -124,14 +124,14 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
})
t.Run("keys", func(t *testing.T) {
for _, row := range []struct{ module, want string }{
{"mesh-delivery-assigner", "want.ace.mesh-delivery-assigner"},
{"novox.be", "want.ace.novox=2ebe"},
{"mesh-delivery-assigner", "want.anchor.mesh-delivery-assigner"},
{"novox.be", "want.anchor.novox=2ebe"},
} {
k, err := WantKey("ace", row.module)
k, err := WantKey("anchor", row.module)
if err != nil || k != row.want {
t.Fatalf("WantKey %s = %q, %v", row.module, k, err)
}
if n, m, err := ParseWantKey(k); err != nil || n != "ace" || m != row.module {
if n, m, err := ParseWantKey(k); err != nil || n != "anchor" || m != row.module {
t.Fatalf("ParseWantKey %q = %q %q %v", k, n, m, err)
}
}
@@ -141,27 +141,27 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
if m, fp, err := ParseHeldKey("held.mesh-delivery-assigner." + rep("a")); err != nil || m != "mesh-delivery-assigner" || fp != a {
t.Fatalf("ParseHeldKey = %q %q %v", m, fp, err)
}
if k, err := WantNodeKey("ace"); err != nil || k != "want.ace.node" {
if k, err := WantNodeKey("anchor"); err != nil || k != "want.anchor.node" {
t.Fatalf("WantNodeKey = %q %v", k, err)
}
if n, err := ParseWantNodeKey("want.ace.node"); err != nil || n != "ace" {
if n, err := ParseWantNodeKey("want.anchor.node"); err != nil || n != "anchor" {
t.Fatalf("ParseWantNodeKey = %q %v", n, err)
}
if _, err := WantKey("ace", "node"); err == nil {
if _, err := WantKey("anchor", "node"); err == nil {
t.Error("a module named node has a want key")
}
if _, err := HeldKey("novox.be", a); err == nil {
t.Error("a module with a dot has a held key")
}
for _, key := range []string{"want.ace.node", "held.m." + rep("a"), "ace.m", "want.ace", "want..m"} {
for _, key := range []string{"want.anchor.node", "held.m." + rep("a"), "anchor.m", "want.anchor", "want..m"} {
if _, _, err := ParseWantKey(key); err == nil {
t.Errorf("%q is a want key", key)
}
}
if _, err := ParseWantNodeKey("want.ace.m"); err == nil {
if _, err := ParseWantNodeKey("want.anchor.m"); err == nil {
t.Error("a module's want is a node's own")
}
if _, _, err := ParseHeldKey("want.ace.m"); err == nil {
if _, _, err := ParseHeldKey("want.anchor.m"); err == nil {
t.Error("a want key is a held key")
}
})
@@ -184,30 +184,30 @@ func TestWantsAreWhatTheEarlierCodecWrote(t *testing.T) {
t.Fatal("no revision taken, yet seeded")
}
first := later.Add(-time.Hour)
if got := p.Take(rev(3, &first, "ace/mesh-build-go", "g14/mesh-build-go", "g14/mesh-build-node")); !reflect.DeepEqual(got,
map[string][]string{"ace": {"mesh-build-go"}, "g14": {"mesh-build-go", "mesh-build-node"}}) {
if got := p.Take(rev(3, &first, "anchor/mesh-build-go", "home-server/mesh-build-go", "home-server/mesh-build-node")); !reflect.DeepEqual(got,
map[string][]string{"anchor": {"mesh-build-go"}, "home-server": {"mesh-build-go", "mesh-build-node"}}) {
t.Fatalf("first revision changed %v", got)
}
if s, ok := p.Since("ace", "mesh-build-go"); !ok || !s.IsZero() {
if s, ok := p.Since("anchor", "mesh-build-go"); !ok || !s.IsZero() {
t.Fatalf("a pair of the first revision stands since %v (%v), want the zero time", s, ok)
}
if got := p.Take(rev(4, &later, "ace/mesh-build-go", "ace/mesh-build-node", "g14/mesh-build-go")); !reflect.DeepEqual(got,
map[string][]string{"ace": {"mesh-build-node"}, "g14": {"mesh-build-node"}}) {
t.Fatalf("revision 4 changed %v, want mesh-build-node placed on ace and taken off g14", got)
if got := p.Take(rev(4, &later, "anchor/mesh-build-go", "anchor/mesh-build-node", "home-server/mesh-build-go")); !reflect.DeepEqual(got,
map[string][]string{"anchor": {"mesh-build-node"}, "home-server": {"mesh-build-node"}}) {
t.Fatalf("revision 4 changed %v, want mesh-build-node placed on anchor and taken off home-server", got)
}
if s, ok := p.Since("ace", "mesh-build-node"); !ok || !s.Equal(later) {
if s, ok := p.Since("anchor", "mesh-build-node"); !ok || !s.Equal(later) {
t.Fatalf("a pair new in revision 4 stands since %v (%v), want its time %v", s, ok, later)
}
if s, _ := p.Since("ace", "mesh-build-go"); !s.IsZero() {
if s, _ := p.Since("anchor", "mesh-build-go"); !s.IsZero() {
t.Fatalf("a pair named again keeps its time, got %v", s)
}
if _, ok := p.Since("g14", "mesh-build-node"); ok {
if _, ok := p.Since("home-server", "mesh-build-node"); ok {
t.Fatal("a pair revision 4 does not name still stands")
}
if got := p.Take(rev(4, &later)); got != nil || !p.Seeded() || p.Revision() != 4 {
t.Fatalf("the same revision again moved %v", got)
}
if got := p.ByNode(); !reflect.DeepEqual(got, map[string][]string{"ace": {"mesh-build-go", "mesh-build-node"}, "g14": {"mesh-build-go"}}) {
if got := p.ByNode(); !reflect.DeepEqual(got, map[string][]string{"anchor": {"mesh-build-go", "mesh-build-node"}, "home-server": {"mesh-build-go"}}) {
t.Fatalf("by node %v", got)
}
})
@@ -29,13 +29,13 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v HeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.container-image-registry\\.event\\.held$")},
{name: "released on the seat's subject", subject: "mesh.seat.container-image-registry.event.released", given: "{\"at\":\"2026-11-04T12:00:00Z\",\"by\":\"mesh-artifact-sweep\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"holder\":\"distribution\",\"name\":\"mesh-sdk\",\"reason\":\"kept by the sweep's rule\"}", wire: "{\"at\":\"2026-11-04T12:00:00Z\",\"by\":\"mesh-artifact-sweep\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"holder\":\"distribution\",\"name\":\"mesh-sdk\",\"reason\":\"kept by the sweep's rule\"}",
decode: func(b []byte) (any, error) { var v ReleasedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.container-image-registry\\.event\\.released$")},
{name: "a hold", subject: "", given: "{\"by\":\"operator@shanks\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"container-image-registry\",\"since\":\"2026-11-05T10:00:00Z\"}", wire: "{\"by\":\"operator@shanks\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"container-image-registry\",\"since\":\"2026-11-05T10:00:00Z\"}",
{name: "a hold", subject: "", given: "{\"by\":\"operator@workstation\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"container-image-registry\",\"since\":\"2026-11-05T10:00:00Z\"}", wire: "{\"by\":\"operator@workstation\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"container-image-registry\",\"since\":\"2026-11-05T10:00:00Z\"}",
decode: func(b []byte) (any, error) {
var v HoldsBySeatNameDigestValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "an open window", subject: "", given: "{\"holding\":[\"ace\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"ace\":\"2026-11-05T10:00:00Z\"}}", wire: "{\"holding\":[\"ace\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"ace\":\"2026-11-05T10:00:00Z\"}}",
{name: "an open window", subject: "", given: "{\"holding\":[\"anchor\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"anchor\":\"2026-11-05T10:00:00Z\"}}", wire: "{\"holding\":[\"anchor\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"anchor\":\"2026-11-05T10:00:00Z\"}}",
decode: func(b []byte) (any, error) { var v WindowsByCallerValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "publish opens a transfer", subject: "", given: "{\"commit\":\"cccccccccccccccccccccccccccccccccccccccc\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"fingerprint\":\"f1\",\"kind\":\"image\",\"name\":\"mesh-sdk\",\"parts\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"size\":1048576}],\"transfer\":\"t1\",\"version\":\"0.1.19\"}", wire: "{\"commit\":\"cccccccccccccccccccccccccccccccccccccccc\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"fingerprint\":\"f1\",\"kind\":\"image\",\"name\":\"mesh-sdk\",\"parts\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"size\":1048576}],\"transfer\":\"t1\",\"version\":\"0.1.19\"}",
decode: func(b []byte) (any, error) { var v PublishInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -17,17 +17,17 @@ func TestFixtures(t *testing.T) {
decode func([]byte) (any, error)
subjectIs *regexp.Regexp
}{
{name: "pull.updated is said", subject: "mesh.seat.git.event.pull-updated", given: "{\"author\":\"jochen\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}", wire: "{\"author\":\"jochen\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}",
{name: "pull.updated is said", subject: "mesh.seat.git.event.pull-updated", given: "{\"author\":\"alice\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}", wire: "{\"author\":\"alice\",\"base\":\"main\",\"base-head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"title\":\"One wiring\",\"url\":\"https://forge.test/p/178\"}",
decode: func(b []byte) (any, error) { var v PullUpdatedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-updated$")},
{name: "pull.merged is said", subject: "mesh.seat.git.event.pull-merged", given: "{\"base\":\"main\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"head-checks\":{\"mesh/check\":\"success\"},\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"base\":\"main\",\"branch\":\"feat/47-G\",\"change\":{\"module-dirs\":[\"go\"],\"paths\":[\"go/seatlist/seatlist.go\"]},\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"head-checks\":{\"mesh/check\":\"success\"},\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v PullMergedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-merged$")},
{name: "pull.closed is said", subject: "mesh.seat.git.event.pull-closed", given: "{\"base\":\"main\",\"branch\":\"fix/x\",\"head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"number\":179,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"base\":\"main\",\"branch\":\"fix/x\",\"head\":\"cccccccccccccccccccccccccccccccccccccccc\",\"number\":179,\"repository\":\"novox/mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v PullClosedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.pull-closed$")},
{name: "forge.pull is said", subject: "mesh.seat.git.event.forge-pull", given: "{\"action\":\"synchronized\",\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}", wire: "{\"action\":\"synchronized\",\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}",
{name: "forge.pull is said", subject: "mesh.seat.git.event.forge-pull", given: "{\"action\":\"synchronized\",\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"alice\"}", wire: "{\"action\":\"synchronized\",\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"sender\":\"alice\"}",
decode: func(b []byte) (any, error) { var v ForgePullEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-pull$")},
{name: "forge.status is said", subject: "mesh.seat.git.event.forge-status", given: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"failed\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"mesh-delivery-checker\",\"state\":\"failure\"}", wire: "{\"commit\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"context\":\"mesh/check\",\"description\":\"failed\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"mesh-delivery-checker\",\"state\":\"failure\"}",
decode: func(b []byte) (any, error) { var v ForgeStatusEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-status$")},
{name: "forge.delete is said", subject: "mesh.seat.git.event.forge-delete", given: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}", wire: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"jochen\"}",
{name: "forge.delete is said", subject: "mesh.seat.git.event.forge-delete", given: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"alice\"}", wire: "{\"ref\":\"feat/47-G\",\"ref-type\":\"branch\",\"repository\":\"novox/mesh-sdk\",\"sender\":\"alice\"}",
decode: func(b []byte) (any, error) { var v ForgeDeleteEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.forge-delete$")},
{name: "repo.writable is said", subject: "mesh.seat.git.event.repo-writable", given: "{\"account\":\"mesh-delivery\",\"repository\":\"jochen/notes\"}", wire: "{\"account\":\"mesh-delivery\",\"repository\":\"jochen/notes\"}",
decode: func(b []byte) (any, error) { var v RepoWritableEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.git\\.event\\.repo-writable$")},
@@ -41,15 +41,15 @@ func TestFixtures(t *testing.T) {
}, subjectIs: nil},
{name: "pull asks", subject: "", given: "{\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"repository\":\"novox/mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v PullInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "pull answers", subject: "", given: "{\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}", wire: "{\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}",
{name: "pull answers", subject: "", given: "{\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}", wire: "{\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"merge-commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"merged-at\":\"2026-11-09T19:40:00Z\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"merged\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"}}",
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "pull answers an open one with what the forge would merge now", subject: "", given: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}", wire: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}",
{name: "pull answers an open one with what the forge would merge now", subject: "", given: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}", wire: "{\"merging\":{\"mergeable\":false,\"protected\":true,\"required\":[\"mesh/check\"],\"writes\":true},\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":179,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/179\"}}",
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "pull answers an error, never none", subject: "", given: "{\"error\":\"the forge holds no pull request novox/mesh-sdk#999\",\"error-kind\":\"refused\"}", wire: "{\"error\":\"the forge holds no pull request novox/mesh-sdk#999\",\"error-kind\":\"refused\"}",
decode: func(b []byte) (any, error) { var v PullAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "open-pulls asks", subject: "", given: "{}", wire: "{}",
decode: func(b []byte) (any, error) { var v OpenPullsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "open-pulls answers", subject: "", given: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}", wire: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"jochen\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}",
{name: "open-pulls answers", subject: "", given: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}", wire: "{\"pulls\":[{\"checks\":{\"mesh/check\":{\"at\":\"2026-11-09T19:00:00Z\",\"by\":\"mesh-delivery-checker\",\"context\":\"mesh/check\",\"description\":\"passed\",\"state\":\"success\",\"target\":\"https://forge.test/x\"}},\"pull\":{\"author\":\"alice\",\"base\":\"main\",\"branch\":\"feat/47-G\",\"head\":\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"number\":178,\"repository\":\"novox/mesh-sdk\",\"state\":\"open\",\"title\":\"One wiring of the seat list\",\"url\":\"https://forge.test/novox/mesh-sdk/pulls/178\"},\"required\":[\"mesh/check\"]}]}",
decode: func(b []byte) (any, error) { var v OpenPullsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "open-pulls answers none open as an empty list", subject: "", given: "{\"pulls\":[]}", wire: "{\"pulls\":[]}",
decode: func(b []byte) (any, error) { var v OpenPullsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -107,7 +107,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v ViewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "view answers an error, never none", subject: "", given: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}", wire: "{\"error\":\"the forge answered 502\",\"error-kind\":\"failed\"}",
decode: func(b []byte) (any, error) { var v ViewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "note asks", subject: "", given: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to ace\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to ace\",\"repository\":\"novox/mesh-sdk\"}",
{name: "note asks", subject: "", given: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to anchor\",\"repository\":\"novox/mesh-sdk\"}", wire: "{\"commit\":\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"id\":\"owed-4\",\"line\":\"owed-4 delivered to anchor\",\"repository\":\"novox/mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v NoteInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "note answers", subject: "", given: "{\"id\":\"owed-4\",\"performed\":true}", wire: "{\"id\":\"owed-4\",\"performed\":true}",
decode: func(b []byte) (any, error) { var v NoteAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -19,11 +19,11 @@ func TestFixtures(t *testing.T) {
}{
{name: "a package published with the dependencies the build resolved", subject: "mesh.seat.mesh-builds.event.package-published", given: "{\"artifact\":\"mesh-sdk:go\",\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"dependencies\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":1,\"part\":\"mesh-contracts:go-nodeengine\",\"version\":\"0.1.4\"},{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":3,\"part\":\"mesh-build-go:toolchain\",\"version\":\"1.26.0\"}],\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"module\":\"mesh-sdk\",\"source\":3589,\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"artifact\":\"mesh-sdk:go\",\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"dependencies\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":1,\"part\":\"mesh-contracts:go-nodeengine\",\"version\":\"0.1.4\"},{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"kind\":3,\"part\":\"mesh-build-go:toolchain\",\"version\":\"1.26.0\"}],\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"module\":\"mesh-sdk\",\"source\":3589,\"v\":1,\"version\":\"0.1.15\"}",
decode: func(b []byte) (any, error) { var v PackagePublishedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.package-published$")},
{name: "a toolchain agreed", subject: "mesh.seat.mesh-builds.event.toolchain-agreed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"ace\",\"g14\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"novox\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"ace\",\"g14\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"novox\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}",
{name: "a toolchain agreed", subject: "mesh.seat.mesh-builds.event.toolchain-agreed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"anchor\",\"home-server\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"laptop\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"digests\":[{\"digest\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"nodes\":[\"anchor\",\"home-server\"]},{\"digest\":\"sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210\",\"nodes\":[\"laptop\"]}],\"language\":\"go\",\"v\":1,\"version\":\"1.26.0\"}",
decode: func(b []byte) (any, error) { var v ToolchainAgreedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.toolchain-agreed$")},
{name: "the build step ended passed on the builder's node, each entry named by its fingerprint (A-97)", subject: "mesh.seat.mesh-builds.event.step-ended.novox", given: "{\"ended\":\"2026-11-10T10:01:00Z\",\"entries\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"novox\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-10T10:01:00Z\",\"entries\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"novox\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"build\",\"v\":1}",
{name: "the build step ended passed on the builder's node, each entry named by its fingerprint (A-97)", subject: "mesh.seat.mesh-builds.event.step-ended.laptop", given: "{\"ended\":\"2026-11-10T10:01:00Z\",\"entries\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"laptop\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-10T10:01:00Z\",\"entries\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"laptop\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "the build step failed on its entry", subject: "mesh.seat.mesh-builds.event.step-ended.novox", given: "{\"entries\":[{\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6b\",\"node\":\"novox\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats:program did not build\",\"step\":\"build\",\"v\":1}", wire: "{\"entries\":[{\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6b\",\"node\":\"novox\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats:program did not build\",\"step\":\"build\",\"v\":1}",
{name: "the build step failed on its entry", subject: "mesh.seat.mesh-builds.event.step-ended.laptop", given: "{\"entries\":[{\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6b\",\"node\":\"laptop\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats:program did not build\",\"step\":\"build\",\"v\":1}", wire: "{\"entries\":[{\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}],\"id\":\"m2kx9a1b3c4d6b\",\"node\":\"laptop\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats:program did not build\",\"step\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-builds\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "reserved asks a module", subject: "", given: "{\"module\":\"mesh-sdk\"}", wire: "{\"module\":\"mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v ReservedInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -27,7 +27,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v FullEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-catalog\\.event\\.full$")},
{name: "the store back below its cap", subject: "mesh.seat.mesh-catalog.event.room", given: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":300000000,\"cap\":536870912,\"store\":\"catalog-revisions\"}", wire: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":300000000,\"cap\":536870912,\"store\":\"catalog-revisions\"}",
decode: func(b []byte) (any, error) { var v RoomEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-catalog\\.event\\.room$")},
{name: "a registration changed on its warrant", subject: "mesh.seat.mesh-catalog.event.registration-changed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"operator@shanks\",\"module\":\"nats\",\"moved\":[\"nats:program unit: required -\\u003e bypass\"],\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"operator@shanks\",\"module\":\"nats\",\"moved\":[\"nats:program unit: required -\\u003e bypass\"],\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
{name: "a registration changed on its warrant", subject: "mesh.seat.mesh-catalog.event.registration-changed", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"operator@workstation\",\"module\":\"nats\",\"moved\":[\"nats:program unit: required -\\u003e bypass\"],\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"operator@workstation\",\"module\":\"nats\",\"moved\":[\"nats:program unit: required -\\u003e bypass\"],\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
decode: func(b []byte) (any, error) {
var v RegistrationChangedEvent
err := json.Unmarshal(b, &v)
@@ -97,13 +97,13 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a module's registration", subject: "", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
{name: "a module's registration", subject: "", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
decode: func(b []byte) (any, error) {
var v RegistrationsByModuleValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "one version kept in the history", subject: "", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
{name: "one version kept in the history", subject: "", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}",
decode: func(b []byte) (any, error) {
var v RegistrationHistoryByModuleVersionValue
err := json.Unmarshal(b, &v)
@@ -145,7 +145,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v RevisionAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "registrations of one module with its history", subject: "", given: "{\"history\":true,\"module\":\"nats\"}", wire: "{\"history\":true,\"module\":\"nats\"}",
decode: func(b []byte) (any, error) { var v RegistrationsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "registrations answers one with its versions", subject: "", given: "{\"history\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":1,\"warrant\":\"ask-m2kx9a1b3c4d5e\"},{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}],\"registrations\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}]}", wire: "{\"history\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":1,\"warrant\":\"ask-m2kx9a1b3c4d5e\"},{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}],\"registrations\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@shanks\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}]}",
{name: "registrations answers one with its versions", subject: "", given: "{\"history\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":1,\"warrant\":\"ask-m2kx9a1b3c4d5e\"},{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}],\"registrations\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}]}", wire: "{\"history\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":1,\"warrant\":\"ask-m2kx9a1b3c4d5e\"},{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}],\"registrations\":[{\"at\":\"2026-11-10T10:00:00Z\",\"branches\":[\"main\"],\"by\":\"operator@workstation\",\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1,\"version\":2,\"warrant\":\"ask-m2kx9a1b3c4d5e\"}]}",
decode: func(b []byte) (any, error) { var v RegistrationsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "register a module whole", subject: "", given: "{\"registration\":{\"branches\":[\"main\"],\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1},\"why\":\"the first registration\"}", wire: "{\"registration\":{\"branches\":[\"main\"],\"module\":\"nats\",\"origin\":\"novox/mesh-catalog\",\"path\":\"modules/nats/module.json\",\"policy\":{\"artifacts\":{\"program\":{\"unit\":\"bypass\"}},\"steps\":{\"approval\":\"bypass\",\"composition\":\"required\",\"integration\":\"required\",\"lint\":\"required\",\"review\":\"optional\",\"unit\":\"required\"}},\"v\":1},\"why\":\"the first registration\"}",
decode: func(b []byte) (any, error) { var v RegisterInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -43,7 +43,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v RoomEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-delivery\\.event\\.room$")},
{name: "main moved to its next source revision", subject: "mesh.seat.mesh-delivery.event.source-moved.main", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"revision\":3590,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"revision\":3590,\"v\":1}",
decode: func(b []byte) (any, error) { var v SourceMovedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-delivery\\.event\\.source-moved\\.[^.*> ]+$")},
{name: "a recovery merged", subject: "mesh.seat.mesh-delivery.event.recovery-merged", given: "{\"at\":\"2026-11-11T10:00:00Z\",\"branch\":\"main\",\"by\":\"jochen\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"mesh-sdk\",\"repository\":\"novox/mesh-sdk\",\"v\":1,\"why\":\"the live delivery was broken\"}", wire: "{\"at\":\"2026-11-11T10:00:00Z\",\"branch\":\"main\",\"by\":\"jochen\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"mesh-sdk\",\"repository\":\"novox/mesh-sdk\",\"v\":1,\"why\":\"the live delivery was broken\"}",
{name: "a recovery merged", subject: "mesh.seat.mesh-delivery.event.recovery-merged", given: "{\"at\":\"2026-11-11T10:00:00Z\",\"branch\":\"main\",\"by\":\"alice\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"mesh-sdk\",\"repository\":\"novox/mesh-sdk\",\"v\":1,\"why\":\"the live delivery was broken\"}", wire: "{\"at\":\"2026-11-11T10:00:00Z\",\"branch\":\"main\",\"by\":\"alice\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"mesh-sdk\",\"repository\":\"novox/mesh-sdk\",\"v\":1,\"why\":\"the live delivery was broken\"}",
decode: func(b []byte) (any, error) { var v RecoveryMergedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-delivery\\.event\\.recovery-merged$")},
{name: "approval-carried is said for a pull request approved before G", subject: "mesh.seat.mesh-delivery.event.approval-carried.mesh-tools.35", given: "{\"approver\":\"operator\",\"at\":\"2026-11-11T10:00:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"pull\":35,\"repository\":\"mesh-tools\"}", wire: "{\"approver\":\"operator\",\"at\":\"2026-11-11T10:00:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"pull\":35,\"repository\":\"mesh-tools\"}",
decode: func(b []byte) (any, error) { var v ApprovalCarriedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-delivery\\.event\\.approval-carried\\.[^.*> ]+\\.[^.*> ]+$")},
@@ -85,7 +85,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v SourceAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "recovery names a merge and why", subject: "", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\",\"why\":\"the live delivery was broken\"}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\",\"why\":\"the live delivery was broken\"}",
decode: func(b []byte) (any, error) { var v RecoveryInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "recovery answers the caller the runtime proved", subject: "", given: "{\"by\":\"jochen\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"recovery\":true,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"by\":\"jochen\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"recovery\":true,\"repository\":\"novox/mesh-sdk\"}",
{name: "recovery answers the caller the runtime proved", subject: "", given: "{\"by\":\"alice\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"recovery\":true,\"repository\":\"novox/mesh-sdk\"}", wire: "{\"by\":\"alice\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"recovery\":true,\"repository\":\"novox/mesh-sdk\"}",
decode: func(b []byte) (any, error) { var v RecoveryAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
}
for _, c := range cases {
@@ -19,17 +19,17 @@ func TestFixtures(t *testing.T) {
}{
{name: "a pipeline started with the steps its policy gives", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"status\":\"required\",\"step\":\"lint\"},{\"status\":\"bypass\",\"step\":\"review\"}],\"v\":1}",
decode: func(b []byte) (any, error) { var v PipelineStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a pipeline ended passed, an optional step failed, over budget and widening named", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}",
{name: "a pipeline ended passed, an optional step failed, over budget and widening named", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"tests\":{\"integration\":3,\"unit\":42},\"v\":1,\"widens\":[{\"name\":\"mesh-build-go:program\",\"said\":\"its test runner\",\"what\":\"serving part\"}]}",
decode: func(b []byte) (any, error) { var v PipelineEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a pipeline ended failed, naming the step that held it, its approval not asked", subject: "mesh.seat.mesh-pipeline-runner.event.pipeline-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"failed\",\"over-budget\":true,\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"outcome\":\"failed\",\"status\":\"required\",\"step\":\"unit\"},{\"outcome\":\"not asked\",\"status\":\"required\",\"step\":\"approval\",\"why\":\"unit of nats:program failed\"}],\"v\":1,\"why\":\"unit of nats:program failed\"}",
decode: func(b []byte) (any, error) { var v PipelineEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.pipeline-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a group's one pipeline ended on a watched branch", subject: "mesh.seat.mesh-pipeline-runner.event.group-ended.main.registry-1966", given: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}",
{name: "a group's one pipeline ended on a watched branch", subject: "mesh.seat.mesh-pipeline-runner.event.group-ended.main.registry-1966", given: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"ended\":\"2026-11-10T10:20:00Z\",\"group\":\"registry-1966\",\"outcome\":\"passed\",\"pipelines\":[{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"group\":\"registry-1966\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}],\"revision\":12,\"source\":3589,\"v\":1}",
decode: func(b []byte) (any, error) { var v GroupEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.group-ended\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a run on request started", subject: "mesh.seat.mesh-pipeline-runner.event.run-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@shanks\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@shanks\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}",
{name: "a run on request started", subject: "mesh.seat.mesh-pipeline-runner.event.run-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@workstation\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"by\":\"fix-1965@workstation\",\"members\":[{\"branch\":\"feature/1966-x\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"module\":\"nats\"}],\"run\":\"run-m2kx9a\",\"v\":1}",
decode: func(b []byte) (any, error) { var v RunStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.run-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a step started", subject: "mesh.seat.mesh-pipeline-runner.event.step-started.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"outcome\":\"running\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},\"revision\":12,\"source\":3589,\"v\":1}",
decode: func(b []byte) (any, error) { var v StepStartedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-started\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a rerun step ended passed, with its proved caller", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@shanks\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}",
{name: "a rerun step ended passed, with its proved caller", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@workstation\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"at\":\"2026-11-10T10:05:00Z\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"artifact\":\"nats:program\",\"by\":\"operator@workstation\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"rerun\":true,\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},\"revision\":12,\"source\":3589,\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a bypassed step said", subject: "mesh.seat.mesh-pipeline-runner.event.step-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},\"revision\":12,\"source\":3589,\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.step-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
@@ -37,13 +37,13 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.wait-held\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "the wait ended answered", subject: "mesh.seat.mesh-pipeline-runner.event.wait-ended.nats.main.0123456789abcdef0123456789abcdef01234567", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"how\":\"answered\",\"module\":\"nats\",\"on\":\"person\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"since\":\"2026-11-10T10:10:00Z\",\"source\":3589,\"step\":\"approval\",\"v\":1,\"who\":\"the operator\"}",
decode: func(b []byte) (any, error) { var v WaitEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-pipeline-runner\\.event\\.wait-ended\\.[^.*> ]+\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a pipeline kept", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}",
{name: "a pipeline kept", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1}",
decode: func(b []byte) (any, error) {
var v PipelinesByBranchRevisionModuleValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a pipeline a publication started, with the version it names (design 47 G 550)", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"g14\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}",
{name: "a pipeline a publication started, with the version it names (design 47 G 550)", subject: "", given: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"end-count\":1,\"ended\":\"2026-11-10T10:20:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"started\":\"2026-11-10T10:00:00Z\",\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"},{\"artifact\":\"nats:program\",\"carried-from\":\"main.11.nats\",\"fingerprint\":\"fp-0123\",\"outcome\":\"carried\",\"status\":\"required\",\"step\":\"unit\",\"tests\":{\"unit\":42}},{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"node\":\"home-server\",\"outcome\":\"failed\",\"seat\":\"node-build-go\",\"status\":\"optional\",\"step\":\"integration\",\"tests\":{\"integration\":3},\"why\":\"TestTheBusWhole failed\"},{\"outcome\":\"passed\",\"seat\":\"mesh-wants\",\"status\":\"required\",\"step\":\"composition\"},{\"outcome\":\"bypassed\",\"status\":\"bypass\",\"step\":\"review\"},{\"outcome\":\"passed\",\"status\":\"required\",\"step\":\"approval\"}],\"v\":1,\"version\":\"0.1.15\"}",
decode: func(b []byte) (any, error) {
var v PipelinesByBranchRevisionModuleValue
err := json.Unmarshal(b, &v)
@@ -59,7 +59,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v ReviewInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "review answers its step", subject: "", given: "{\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"passed\",\"status\":\"optional\",\"step\":\"review\"}}", wire: "{\"pipeline\":\"main.12.nats\",\"result\":{\"outcome\":\"passed\",\"status\":\"optional\",\"step\":\"review\"}}",
decode: func(b []byte) (any, error) { var v ReviewAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "show answers a pipeline with its log and fill", subject: "", given: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", wire: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"ace\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}",
{name: "show answers a pipeline with its log and fill", subject: "", given: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}", wire: "{\"fill\":[{\"bytes\":4096,\"cap\":268435456,\"store\":\"pipelines\"}],\"log\":[{\"artifact\":\"nats:program\",\"at\":\"2026-11-10T10:00:00Z\",\"pipeline\":\"main.12.nats\",\"step\":\"lint\",\"what\":\"started\"}],\"outputs\":[\"main.12.nats.lint.nats:program\"],\"pipeline\":{\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"outcome\":\"running\",\"pipeline\":\"main.12.nats\",\"revision\":12,\"source\":3589,\"steps\":[{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"fingerprint\":\"fp-0123\",\"node\":\"anchor\",\"outcome\":\"passed\",\"seat\":\"node-build-go\",\"status\":\"required\",\"step\":\"lint\"}],\"v\":1}}",
decode: func(b []byte) (any, error) { var v ShowAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "accept asks with why", subject: "", given: "{\"artifact\":\"nats:program\",\"pipeline\":\"main.12.nats\",\"step\":\"integration\",\"why\":\"flaky upstream, issue 1966\"}", wire: "{\"artifact\":\"nats:program\",\"pipeline\":\"main.12.nats\",\"step\":\"integration\",\"why\":\"flaky upstream, issue 1966\"}",
decode: func(b []byte) (any, error) { var v AcceptInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -31,7 +31,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v WantedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wanted\\.[^.*> ]+\\.[^.*> ]+$")},
{name: "a composing wait held with its bound", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}", wire: "{\"bound\":\"30m\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}",
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-held$")},
{name: "a wait ended, released by hand", subject: "mesh.seat.mesh-wants.event.wait-ended", given: "{\"bound\":\"30m\",\"by\":\"lead@shanks: the node is away\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"how\":\"released\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}", wire: "{\"bound\":\"30m\",\"by\":\"lead@shanks: the node is away\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"how\":\"released\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}",
{name: "a wait ended, released by hand", subject: "mesh.seat.mesh-wants.event.wait-ended", given: "{\"bound\":\"30m\",\"by\":\"lead@workstation: the node is away\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"how\":\"released\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}", wire: "{\"bound\":\"30m\",\"by\":\"lead@workstation: the node is away\",\"fp\":\"src2:b427bdde1f100e2f52490cfa9df0c5112dd3700226b4892349f0c14a15a4af56\",\"how\":\"released\",\"module\":\"xclip\",\"node\":\"n1\",\"part\":\"node-engine\",\"since\":\"2026-11-09T19:00:00Z\",\"step\":\"compose\",\"version\":\"src2:7dd0db8e98224f46121a5ae05c0b9c5a430eff531a5120aa40b1a59237853a3f\"}",
decode: func(b []byte) (any, error) { var v WaitEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-ended$")},
{name: "the store past 80 % of its cap", subject: "mesh.seat.mesh-wants.event.filling", given: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":450000000,\"cap\":536870912,\"store\":\"assignment-revisions\"}", wire: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":450000000,\"cap\":536870912,\"store\":\"assignment-revisions\"}",
decode: func(b []byte) (any, error) { var v FillingEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.filling$")},
@@ -39,25 +39,25 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v FullEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.full$")},
{name: "the store back below its cap", subject: "mesh.seat.mesh-wants.event.room", given: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":300000000,\"cap\":536870912,\"store\":\"assignment-revisions\"}", wire: "{\"at\":\"2026-11-09T19:00:00Z\",\"bytes\":300000000,\"cap\":536870912,\"store\":\"assignment-revisions\"}",
decode: func(b []byte) (any, error) { var v RoomEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.room$")},
{name: "the composition step ended passed on the assigner's node, a node asleep warned", subject: "mesh.seat.mesh-wants.event.step-ended.novox", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:01:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6a\",\"module\":\"nats\",\"node\":\"novox\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"composition\",\"v\":1,\"warnings\":[\"g14 asleep: composed from its last capabilities\"]}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:01:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6a\",\"module\":\"nats\",\"node\":\"novox\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"composition\",\"v\":1,\"warnings\":[\"g14 asleep: composed from its last capabilities\"]}",
{name: "the composition step ended passed on the assigner's node, a node asleep warned", subject: "mesh.seat.mesh-wants.event.step-ended.laptop", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:01:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6a\",\"module\":\"nats\",\"node\":\"laptop\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"composition\",\"v\":1,\"warnings\":[\"home-server asleep: composed from its last capabilities\"]}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:01:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6a\",\"module\":\"nats\",\"node\":\"laptop\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"composition\",\"v\":1,\"warnings\":[\"home-server asleep: composed from its last capabilities\"]}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "the composition step failed, two modules owning one path", subject: "mesh.seat.mesh-wants.event.step-ended.novox", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6b\",\"module\":\"nats\",\"node\":\"novox\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats and xclip both own /etc/nats.conf on ace\",\"step\":\"composition\",\"v\":1}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6b\",\"module\":\"nats\",\"node\":\"novox\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats and xclip both own /etc/nats.conf on ace\",\"step\":\"composition\",\"v\":1}",
{name: "the composition step failed, two modules owning one path", subject: "mesh.seat.mesh-wants.event.step-ended.laptop", given: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6b\",\"module\":\"nats\",\"node\":\"laptop\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats and xclip both own /etc/nats.conf on anchor\",\"step\":\"composition\",\"v\":1}", wire: "{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d6b\",\"module\":\"nats\",\"node\":\"laptop\",\"outcome\":\"failed\",\"pipeline\":\"main.12.nats\",\"said\":\"nats and xclip both own /etc/nats.conf on anchor\",\"step\":\"composition\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "a version delivered with the machines away", subject: "mesh.seat.mesh-wants.event.version-delivered", given: "{\"away\":[\"laptop\"],\"module\":\"mesh-sdk\",\"parts\":{\"mesh-sdk:go\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"},\"v\":1,\"version\":\"0.1.15\"}", wire: "{\"away\":[\"laptop\"],\"module\":\"mesh-sdk\",\"parts\":{\"mesh-sdk:go\":\"sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"},\"v\":1,\"version\":\"0.1.15\"}",
decode: func(b []byte) (any, error) { var v VersionDeliveredEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.version-delivered$")},
{name: "a composition step's progress", subject: "mesh.seat.mesh-wants.event.step-progress.ace", given: "{\"ask\":\"a1b2\",\"asker\":\"assigner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"build\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"assigner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"build\"}",
{name: "a composition step's progress", subject: "mesh.seat.mesh-wants.event.step-progress.anchor", given: "{\"ask\":\"a1b2\",\"asker\":\"assigner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"build\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"assigner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"build\"}",
decode: func(b []byte) (any, error) { var v StepProgressEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.step-progress\\.[^.*> ]+$")},
{name: "a put without hold waits, counted from its start", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"node\":\"ace\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"put\"}", wire: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"node\":\"ace\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"put\"}",
{name: "a put without hold waits, counted from its start", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"node\":\"anchor\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"put\"}", wire: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"node\":\"anchor\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"put\"}",
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-held$")},
{name: "a dependent's delivery waits for a dependency's version", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"60m\",\"clock-from\":\"2026-11-11T09:58:00Z\",\"machines\":[\"ace\",\"g14\"],\"module\":\"nats\",\"part\":\"mesh-sdk\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"delivery\",\"version\":\"0.1.4\"}", wire: "{\"bound\":\"60m\",\"clock-from\":\"2026-11-11T09:58:00Z\",\"machines\":[\"ace\",\"g14\"],\"module\":\"nats\",\"part\":\"mesh-sdk\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"delivery\",\"version\":\"0.1.4\"}",
{name: "a dependent's delivery waits for a dependency's version", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"60m\",\"clock-from\":\"2026-11-11T09:58:00Z\",\"machines\":[\"anchor\",\"home-server\"],\"module\":\"nats\",\"part\":\"mesh-sdk\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"delivery\",\"version\":\"0.1.4\"}", wire: "{\"bound\":\"60m\",\"clock-from\":\"2026-11-11T09:58:00Z\",\"machines\":[\"anchor\",\"home-server\"],\"module\":\"nats\",\"part\":\"mesh-sdk\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"delivery\",\"version\":\"0.1.4\"}",
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-held$")},
{name: "the builder's toolchain wait held, in the contract's words", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"mesh-sdk\",\"on\":\"toolchain\",\"owner\":\"mesh-delivery-builder\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"build\",\"words\":\"waits for the Go build seat to report its toolchain\"}", wire: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"mesh-sdk\",\"on\":\"toolchain\",\"owner\":\"mesh-delivery-builder\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"build\",\"words\":\"waits for the Go build seat to report its toolchain\"}",
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-held$")},
{name: "the builder's toolchain wait ended by a newer fingerprint", subject: "mesh.seat.mesh-wants.event.wait-ended", given: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"superseded\",\"module\":\"mesh-sdk\",\"on\":\"toolchain\",\"owner\":\"mesh-delivery-builder\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"build\"}", wire: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"superseded\",\"module\":\"mesh-sdk\",\"on\":\"toolchain\",\"owner\":\"mesh-delivery-builder\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"build\"}",
decode: func(b []byte) (any, error) { var v WaitEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-ended$")},
{name: "an outside wait held on a hub's silence, counted from its first start", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"nats\",\"node\":\"ace\",\"on\":\"silent:g14\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}", wire: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"nats\",\"node\":\"ace\",\"on\":\"silent:g14\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}",
{name: "an outside wait held on a hub's silence, counted from its first start", subject: "mesh.seat.mesh-wants.event.wait-held", given: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"nats\",\"node\":\"anchor\",\"on\":\"silent:home-server\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}", wire: "{\"bound\":\"30m\",\"clock-from\":\"2026-11-11T10:00:00Z\",\"fingerprint\":\"src2:aaaa\",\"module\":\"nats\",\"node\":\"anchor\",\"on\":\"silent:home-server\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}",
decode: func(b []byte) (any, error) { var v WaitHeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-held$")},
{name: "an outside wait ended by the operator's Go on", subject: "mesh.seat.mesh-wants.event.wait-ended", given: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"go-on\",\"module\":\"nats\",\"node\":\"ace\",\"on\":\"silent:g14\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}", wire: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"go-on\",\"module\":\"nats\",\"node\":\"ace\",\"on\":\"silent:g14\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}",
{name: "an outside wait ended by the operator's Go on", subject: "mesh.seat.mesh-wants.event.wait-ended", given: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"go-on\",\"module\":\"nats\",\"node\":\"anchor\",\"on\":\"silent:home-server\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}", wire: "{\"fingerprint\":\"src2:aaaa\",\"how\":\"go-on\",\"module\":\"nats\",\"node\":\"anchor\",\"on\":\"silent:home-server\",\"owner\":\"mesh-delivery-assigner\",\"since\":\"2026-11-11T10:00:00Z\",\"step\":\"outside\"}",
decode: func(b []byte) (any, error) { var v WaitEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.mesh-wants\\.event\\.wait-ended$")},
{name: "a want", subject: "", given: "{\"fp\":\"ab12\",\"rule\":3,\"v\":1}", wire: "{\"fp\":\"ab12\",\"rule\":3,\"v\":1}",
decode: func(b []byte) (any, error) {
@@ -77,7 +77,7 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a held fingerprint", subject: "", given: "{\"node\":\"ace\",\"v\":1}", wire: "{\"node\":\"ace\",\"v\":1}",
{name: "a held fingerprint", subject: "", given: "{\"node\":\"anchor\",\"v\":1}", wire: "{\"node\":\"anchor\",\"v\":1}",
decode: func(b []byte) (any, error) {
var v WantsByHeldModuleFingerprintValue
err := json.Unmarshal(b, &v)
@@ -17,21 +17,21 @@ func TestFixtures(t *testing.T) {
decode func([]byte) (any, error)
subjectIs *regexp.Regexp
}{
{name: "a unit step ended passed on its node, with its counts and what it carried", subject: "mesh.seat.node-build-go.event.step-ended.ace", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}",
{name: "a unit step ended passed on its node, with its counts and what it carried", subject: "mesh.seat.node-build-go.event.step-ended.anchor", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "an integration step that could not run, naming the part not heard", subject: "mesh.seat.node-build-go.event.step-ended.g14", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}",
{name: "an integration step that could not run, naming the part not heard", subject: "mesh.seat.node-build-go.event.step-ended.home-server", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-go.event.toolchain-reported.ace", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-go.event.toolchain-reported.anchor", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
decode: func(b []byte) (any, error) { var v ToolchainReportedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.toolchain-reported\\.[^.*> ]+$")},
{name: "a running ask says its progress", subject: "mesh.seat.node-build-go.event.step-progress.ace", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
{name: "a running ask says its progress", subject: "mesh.seat.node-build-go.event.step-progress.anchor", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
decode: func(b []byte) (any, error) { var v StepProgressEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.step-progress\\.[^.*> ]+$")},
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-go.event.step-ended.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-go.event.step-ended.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-go.event.ask-taken.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}",
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-go.event.ask-taken.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}",
decode: func(b []byte) (any, error) { var v AskTakenEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.event\\.ask-taken\\.[^.*> ]+$")},
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}",
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}",
decode: func(b []byte) (any, error) {
var v PausesByPausedNodeValue
err := json.Unmarshal(b, &v)
@@ -59,23 +59,23 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.delivery$")},
{name: "a build ask with the version the builder reserved (G 573)", subject: "mesh.seat.node-build-go.accept.delivery", given: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}", wire: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}",
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.delivery$")},
{name: "a check ask with its fetch, siblings and levels", subject: "mesh.seat.node-build-go.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"beside\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"repository\":\"novox/mesh-sdk\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"packages\":{\"git.novox.be/novox/mesh-sdk/go\":\"fedcba9876543210fedcba9876543210fedcba98\"},\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"ace\",\"g14\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"2\",\"version\":\"1.26.0\"}},\"id\":\"c3d4\",\"kind\":\"check\",\"language\":\"go\",\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"beside\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"repository\":\"novox/mesh-sdk\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"packages\":{\"git.novox.be/novox/mesh-sdk/go\":\"fedcba9876543210fedcba9876543210fedcba98\"},\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"ace\",\"g14\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"2\",\"version\":\"1.26.0\"}},\"id\":\"c3d4\",\"kind\":\"check\",\"language\":\"go\",\"v\":1}",
{name: "a check ask with its fetch, siblings and levels", subject: "mesh.seat.node-build-go.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"beside\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"repository\":\"novox/mesh-sdk\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"packages\":{\"git.novox.be/novox/mesh-sdk/go\":\"fedcba9876543210fedcba9876543210fedcba98\"},\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"anchor\",\"home-server\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"2\",\"version\":\"1.26.0\"}},\"id\":\"c3d4\",\"kind\":\"check\",\"language\":\"go\",\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"beside\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"repository\":\"novox/mesh-sdk\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"packages\":{\"git.novox.be/novox/mesh-sdk/go\":\"fedcba9876543210fedcba9876543210fedcba98\"},\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"anchor\",\"home-server\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"2\",\"version\":\"1.26.0\"}},\"id\":\"c3d4\",\"kind\":\"check\",\"language\":\"go\",\"v\":1}",
decode: func(b []byte) (any, error) { var v CheckAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.check$")},
{name: "a finished build step with its artifacts", subject: "", given: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}",
{name: "a finished build step with its artifacts", subject: "", given: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a finished build step that kept its artifact on its node", subject: "", given: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b3\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"kept\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b3\",\"node\":\"ace\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"kept\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}",
{name: "a finished build step that kept its artifact on its node", subject: "", given: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b3\",\"node\":\"anchor\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"kept\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:03:00Z\",\"id\":\"a1b3\",\"node\":\"anchor\",\"result\":{\"artifacts\":[{\"artifact\":\"go\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"reference\":\"container-image-registry/nats/go@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"}],\"imports\":[\"git.novox.be/novox/mesh-sdk/go\"],\"kept\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"toolchain\":{\"language\":\"go\",\"recipe\":\"1\",\"version\":\"1.26.0\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a finished check step with its levels", subject: "", given: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a finished check step with its levels", subject: "", given: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:06:00Z\",\"id\":\"c3d4\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"a.go\",\"modules/m/main.go\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"fedcba9876543210fedcba9876543210fedcba98\",\"modules\":[\".\"],\"trees\":{\"modules/m\":{\"locks\":{\"go.sum\":\"c5fc83c01e92404452b986527d239140ccf9a48b88e0c268fbf38c2e1429e9c9\"},\"manifest\":\"ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356\",\"tree\":\"1111111111111111111111111111111111111111\"}},\"workspace\":\"mvii1iwu5414e4\"},\"levels\":[{\"digest\":{\"level\":\"unit\",\"packages\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\"}]},\"kept\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"package\":\"./modules/a\",\"tests\":12}],\"level\":\"unit\",\"tests\":[{\"package\":\"./modules/b\",\"pass\":true}],\"unmet\":[{\"needs\":[\"docker\"],\"package\":\"./modules/c\"}]}]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a declined step", subject: "", given: "{\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}", wire: "{\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}",
{name: "a declined step", subject: "", given: "{\"id\":\"c3d5\",\"node\":\"anchor\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}", wire: "{\"id\":\"c3d5\",\"node\":\"anchor\",\"result\":{\"declined\":true,\"lacks\":[\"docker\"],\"needs\":[\"docker\"]},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"refused\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a finished check step whose head does not merge", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a finished check step whose head does not merge", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a run ask of the checking program over two heads", subject: "mesh.seat.node-build-go.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"id\":\"r5e6\",\"kind\":\"check\",\"language\":\"go\",\"run\":{\"args\":[\"-verdict\"],\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"},{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\"}],\"input\":{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"size\":7,\"verb\":\"seat:mesh-delivery-checker.input\"},\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"},\"reader\":\"checking program of mesh-delivery head\"},\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"id\":\"r5e6\",\"kind\":\"check\",\"language\":\"go\",\"run\":{\"args\":[\"-verdict\"],\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"},{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\"}],\"input\":{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"size\":7,\"verb\":\"seat:mesh-delivery-checker.input\"},\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"},\"reader\":\"checking program of mesh-delivery head\"},\"v\":1}",
decode: func(b []byte) (any, error) { var v CheckAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.check$")},
{name: "a finished run step whose program exited non-zero", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"ace\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"ace\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}",
{name: "a finished run step whose program exited non-zero", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"anchor\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"anchor\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "an ask dropped by the caller that no longer waits", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v PausesByDroppedIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -91,13 +91,13 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) {
var v StepsByAskerNodeIDValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "drop names the ask and why", subject: "", given: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v DropInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -17,21 +17,21 @@ func TestFixtures(t *testing.T) {
decode func([]byte) (any, error)
subjectIs *regexp.Regexp
}{
{name: "a lint step ended passed on its node", subject: "mesh.seat.node-build-image.event.step-ended.ace", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}",
{name: "a lint step ended passed on its node", subject: "mesh.seat.node-build-image.event.step-ended.anchor", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "a lint step that could not run, naming the part not heard", subject: "mesh.seat.node-build-image.event.step-ended.g14", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}",
{name: "a lint step that could not run, naming the part not heard", subject: "mesh.seat.node-build-image.event.step-ended.home-server", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-image.event.toolchain-reported.ace", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-image.event.toolchain-reported.anchor", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
decode: func(b []byte) (any, error) { var v ToolchainReportedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.toolchain-reported\\.[^.*> ]+$")},
{name: "a running ask says its progress", subject: "mesh.seat.node-build-image.event.step-progress.ace", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
{name: "a running ask says its progress", subject: "mesh.seat.node-build-image.event.step-progress.anchor", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
decode: func(b []byte) (any, error) { var v StepProgressEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-progress\\.[^.*> ]+$")},
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-image.event.step-ended.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-image.event.step-ended.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-image.event.ask-taken.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}",
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-image.event.ask-taken.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}",
decode: func(b []byte) (any, error) { var v AskTakenEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.ask-taken\\.[^.*> ]+$")},
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}",
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}",
decode: func(b []byte) (any, error) {
var v PausesByPausedNodeValue
err := json.Unmarshal(b, &v)
@@ -59,7 +59,7 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.accept\\.delivery$")},
{name: "a build ask with the version the builder reserved (G 573)", subject: "mesh.seat.node-build-image.accept.delivery", given: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}", wire: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}",
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.accept\\.delivery$")},
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "an ask dropped by the caller that no longer waits", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v PausesByDroppedIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -73,13 +73,13 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) {
var v StepsByAskerNodeIDValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "drop names the ask and why", subject: "", given: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v DropInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -17,21 +17,21 @@ func TestFixtures(t *testing.T) {
decode func([]byte) (any, error)
subjectIs *regexp.Regexp
}{
{name: "a unit step ended passed on its node, with its counts and what it carried", subject: "mesh.seat.node-build-node.event.step-ended.ace", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}",
{name: "a unit step ended passed on its node, with its counts and what it carried", subject: "mesh.seat.node-build-node.event.step-ended.anchor", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5e\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"carried\":[{\"digest\":\"sha256:bbbb\",\"level\":\"unit\",\"package\":\"./modules/nats/a\"}],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"kept\":[{\"digest\":\"sha256:cccc\",\"level\":\"unit\",\"package\":\"./modules/nats/b\"}],\"module\":\"nats\",\"node\":\"anchor\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"unit\",\"tests\":{\"unit\":14},\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "an integration step that could not run, naming the part not heard", subject: "mesh.seat.node-build-node.event.step-ended.g14", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}",
{name: "an integration step that could not run, naming the part not heard", subject: "mesh.seat.node-build-node.event.step-ended.home-server", given: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"ask\":\"m2kx9a1b3c4d5f\",\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:02:00Z\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"home-server\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"integration\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-node.event.toolchain-reported.ace", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-node.event.toolchain-reported.anchor", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"anchor\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
decode: func(b []byte) (any, error) { var v ToolchainReportedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.toolchain-reported\\.[^.*> ]+$")},
{name: "a running ask says its progress", subject: "mesh.seat.node-build-node.event.step-progress.ace", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
{name: "a running ask says its progress", subject: "mesh.seat.node-build-node.event.step-progress.anchor", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
decode: func(b []byte) (any, error) { var v StepProgressEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.step-progress\\.[^.*> ]+$")},
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-node.event.step-ended.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"ace\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
{name: "a builder's build ended, naming its asker and no commit or fingerprint (G 548)", subject: "mesh.seat.node-build-node.event.step-ended.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:03:00Z\",\"id\":\"m2kx9a1b3c4d6a\",\"node\":\"anchor\",\"outcome\":\"failed\",\"said\":\"the build failed\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.step-ended\\.[^.*> ]+$")},
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-node.event.ask-taken.ace", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"ace\"}",
{name: "an ask taken, whatever its asker (G 602)", subject: "mesh.seat.node-build-node.event.ask-taken.anchor", given: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}", wire: "{\"ask\":\"m2kx9a1b3c4d6a\",\"asker\":\"mesh-delivery-builder\",\"at\":\"2026-11-11T10:00:00Z\",\"node\":\"anchor\"}",
decode: func(b []byte) (any, error) { var v AskTakenEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.event\\.ask-taken\\.[^.*> ]+$")},
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}",
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@workstation\",\"paused\":true,\"v\":1}",
decode: func(b []byte) (any, error) {
var v PausesByPausedNodeValue
err := json.Unmarshal(b, &v)
@@ -59,11 +59,11 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.accept\\.delivery$")},
{name: "a build ask with the version the builder reserved (G 573)", subject: "mesh.seat.node-build-node.accept.delivery", given: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}", wire: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b3\",\"kind\":\"build\",\"language\":\"go\",\"version\":\"1.4.2\"}",
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.accept\\.delivery$")},
{name: "a check ask with the group's packages", subject: "mesh.seat.node-build-node.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"group-packages\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"ref\":\"refs/pull/12/head\",\"repository\":\"novox/mesh-sdk\"},{\"commit\":\"76543210fedcba9876543210fedcba9876543210\",\"path\":\"modules/mesh-delivery-contracts/ts/seats/git\",\"ref\":\"refs/pull/9/head\",\"repository\":\"novox/mesh-delivery\"}],\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"ace\",\"g14\"],\"toolchain\":{\"language\":\"typescript\",\"recipe\":\"1\",\"version\":\"26.12.0\"}},\"id\":\"c3d5\",\"kind\":\"check\",\"language\":\"typescript\",\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"group-packages\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"ref\":\"refs/pull/12/head\",\"repository\":\"novox/mesh-sdk\"},{\"commit\":\"76543210fedcba9876543210fedcba9876543210\",\"path\":\"modules/mesh-delivery-contracts/ts/seats/git\",\"ref\":\"refs/pull/9/head\",\"repository\":\"novox/mesh-delivery\"}],\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"ace\",\"g14\"],\"toolchain\":{\"language\":\"typescript\",\"recipe\":\"1\",\"version\":\"26.12.0\"}},\"id\":\"c3d5\",\"kind\":\"check\",\"language\":\"typescript\",\"v\":1}",
{name: "a check ask with the group's packages", subject: "mesh.seat.node-build-node.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"group-packages\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"ref\":\"refs/pull/12/head\",\"repository\":\"novox/mesh-sdk\"},{\"commit\":\"76543210fedcba9876543210fedcba9876543210\",\"path\":\"modules/mesh-delivery-contracts/ts/seats/git\",\"ref\":\"refs/pull/9/head\",\"repository\":\"novox/mesh-delivery\"}],\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"anchor\",\"home-server\"],\"toolchain\":{\"language\":\"typescript\",\"recipe\":\"1\",\"version\":\"26.12.0\"}},\"id\":\"c3d5\",\"kind\":\"check\",\"language\":\"typescript\",\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"check\":{\"fetch\":{\"base\":\"89abcdef0123456789abcdef0123456789abcdef\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"group-packages\":[{\"commit\":\"fedcba9876543210fedcba9876543210fedcba98\",\"ref\":\"refs/pull/12/head\",\"repository\":\"novox/mesh-sdk\"},{\"commit\":\"76543210fedcba9876543210fedcba9876543210\",\"path\":\"modules/mesh-delivery-contracts/ts/seats/git\",\"ref\":\"refs/pull/9/head\",\"repository\":\"novox/mesh-delivery\"}],\"ref\":\"refs/pull/7/head\",\"repository\":\"novox/mesh-catalog\"},\"kept\":true,\"levels\":[\"unit\",\"integration\"],\"node-names\":[\"anchor\",\"home-server\"],\"toolchain\":{\"language\":\"typescript\",\"recipe\":\"1\",\"version\":\"26.12.0\"}},\"id\":\"c3d5\",\"kind\":\"check\",\"language\":\"typescript\",\"v\":1}",
decode: func(b []byte) (any, error) { var v CheckAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-node\\.accept\\.check$")},
{name: "a finished check step of a TypeScript merge preview", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a finished check step of a TypeScript merge preview", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d6\",\"node\":\"anchor\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"changed\":[\"modules/m/package.json\"],\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"merge\":\"0123456789abcdef0123456789abcdef01234567\",\"modules\":[\"modules/m\"],\"trees\":{\"modules/m\":{\"manifest\":\"0581b699d9d05517e69b21f5cedbeb2eee8aba2b205280b561be731594d7feef\",\"tree\":\"0123456789abcdef0123456789abcdef01234567\"}},\"workspace\":\"mvii1sxt979f67\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"anchor\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "an ask dropped by the caller that no longer waits", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v PausesByDroppedIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -77,13 +77,13 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"anchor\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
decode: func(b []byte) (any, error) {
var v StepsByAskerNodeIDValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"ace\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
{name: "a check's step whose answer is kept as an object (G A-290)", subject: "", given: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:05:00Z\",\"id\":\"c3d4e5f6a7b8c9\",\"node\":\"anchor\",\"output-object\":\"output.c3d4e5f6a7b8c9\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "drop names the ask and why", subject: "", given: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}",
decode: func(b []byte) (any, error) { var v DropInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -29,13 +29,13 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v HeldEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.oci-artifact-registry\\.event\\.held$")},
{name: "released on the seat's subject", subject: "mesh.seat.oci-artifact-registry.event.released", given: "{\"at\":\"2026-11-04T12:00:00Z\",\"by\":\"mesh-artifact-sweep\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"holder\":\"distribution\",\"name\":\"mesh-sdk\",\"reason\":\"kept by the sweep's rule\"}", wire: "{\"at\":\"2026-11-04T12:00:00Z\",\"by\":\"mesh-artifact-sweep\",\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"holder\":\"distribution\",\"name\":\"mesh-sdk\",\"reason\":\"kept by the sweep's rule\"}",
decode: func(b []byte) (any, error) { var v ReleasedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.oci-artifact-registry\\.event\\.released$")},
{name: "a hold", subject: "", given: "{\"by\":\"operator@shanks\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"oci-artifact-registry\",\"since\":\"2026-11-05T10:00:00Z\"}", wire: "{\"by\":\"operator@shanks\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"oci-artifact-registry\",\"since\":\"2026-11-05T10:00:00Z\"}",
{name: "a hold", subject: "", given: "{\"by\":\"operator@workstation\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"oci-artifact-registry\",\"since\":\"2026-11-05T10:00:00Z\"}", wire: "{\"by\":\"operator@workstation\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"kind\":\"base\",\"name\":\"base\",\"seat\":\"oci-artifact-registry\",\"since\":\"2026-11-05T10:00:00Z\"}",
decode: func(b []byte) (any, error) {
var v HoldsBySeatNameDigestValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "an open window", subject: "", given: "{\"holding\":[\"ace\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"ace\":\"2026-11-05T10:00:00Z\"}}", wire: "{\"holding\":[\"ace\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"ace\":\"2026-11-05T10:00:00Z\"}}",
{name: "an open window", subject: "", given: "{\"holding\":[\"anchor\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"anchor\":\"2026-11-05T10:00:00Z\"}}", wire: "{\"holding\":[\"anchor\"],\"name\":\"mesh-delivery-builder\",\"open\":true,\"since\":{\"anchor\":\"2026-11-05T10:00:00Z\"}}",
decode: func(b []byte) (any, error) { var v WindowsByCallerValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "publish opens a transfer", subject: "", given: "{\"commit\":\"cccccccccccccccccccccccccccccccccccccccc\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"fingerprint\":\"f1\",\"kind\":\"bundle\",\"name\":\"mesh-sdk\",\"parts\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"size\":1048576}],\"transfer\":\"t1\",\"version\":\"0.1.19\"}", wire: "{\"commit\":\"cccccccccccccccccccccccccccccccccccccccc\",\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"fingerprint\":\"f1\",\"kind\":\"bundle\",\"name\":\"mesh-sdk\",\"parts\":[{\"digest\":\"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\"size\":1048576}],\"transfer\":\"t1\",\"version\":\"0.1.19\"}",
decode: func(b []byte) (any, error) { var v PublishInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -7,7 +7,7 @@
"name": "base",
"kind": "base",
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"by": "operator@shanks",
"by": "operator@workstation",
"since": "2026-11-05T10:00:00Z"
}
},
@@ -18,10 +18,10 @@
"name": "mesh-delivery-builder",
"open": true,
"holding": [
"ace"
"anchor"
],
"since": {
"ace": "2026-11-05T10:00:00Z"
"anchor": "2026-11-05T10:00:00Z"
}
}
}
@@ -10,7 +10,7 @@
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"base": "main",
"title": "One wiring",
"author": "jochen",
"author": "alice",
"url": "https://forge.test/p/178",
"base-head": "cccccccccccccccccccccccccccccccccccccccc",
"change": {
@@ -71,8 +71,8 @@
"branch": "feat/47-G",
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"base": "main",
"author": "jochen",
"sender": "jochen"
"author": "alice",
"sender": "alice"
}
},
{
@@ -96,7 +96,7 @@
"repository": "novox/mesh-sdk",
"ref": "feat/47-G",
"ref-type": "branch",
"sender": "jochen"
"sender": "alice"
}
},
{
@@ -15,7 +15,7 @@
"repository": "novox/mesh-sdk",
"number": 178,
"title": "One wiring of the seat list",
"author": "jochen",
"author": "alice",
"branch": "feat/47-G",
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"base": "main",
@@ -34,7 +34,7 @@
"repository": "novox/mesh-sdk",
"number": 179,
"title": "One wiring of the seat list",
"author": "jochen",
"author": "alice",
"branch": "feat/47-G",
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"base": "main",
@@ -75,7 +75,7 @@
"repository": "novox/mesh-sdk",
"number": 178,
"title": "One wiring of the seat list",
"author": "jochen",
"author": "alice",
"branch": "feat/47-G",
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"base": "main",
@@ -396,7 +396,7 @@
"id": "owed-4",
"repository": "novox/mesh-sdk",
"commit": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"line": "owed-4 delivered to ace"
"line": "owed-4 delivered to anchor"
}
},
{
@@ -40,14 +40,14 @@
{
"digest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"nodes": [
"ace",
"g14"
"anchor",
"home-server"
]
},
{
"digest": "sha256:fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
"nodes": [
"novox"
"laptop"
]
}
],
@@ -57,13 +57,13 @@
{
"name": "the build step ended passed on the builder's node, each entry named by its fingerprint (A-97)",
"of": "event:step-ended",
"subject": "mesh.seat.mesh-builds.event.step-ended.novox",
"subject": "mesh.seat.mesh-builds.event.step-ended.laptop",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6a",
"pipeline": "main.12.nats",
"step": "build",
"node": "novox",
"node": "laptop",
"outcome": "passed",
"entries": [
{
@@ -79,13 +79,13 @@
{
"name": "the build step failed on its entry",
"of": "event:step-ended",
"subject": "mesh.seat.mesh-builds.event.step-ended.novox",
"subject": "mesh.seat.mesh-builds.event.step-ended.laptop",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6b",
"pipeline": "main.12.nats",
"step": "build",
"node": "novox",
"node": "laptop",
"outcome": "failed",
"entries": [
{
@@ -76,7 +76,7 @@
"moved": [
"nats:program unit: required -> bypass"
],
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
}
@@ -412,7 +412,7 @@
}
},
"version": 2,
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
}
@@ -444,7 +444,7 @@
}
},
"version": 2,
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
}
@@ -196,7 +196,7 @@
}
},
"version": 2,
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
}
@@ -221,7 +221,7 @@
}
},
"version": 1,
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
},
@@ -249,7 +249,7 @@
}
},
"version": 2,
"by": "operator@shanks",
"by": "operator@workstation",
"warrant": "ask-m2kx9a1b3c4d5e",
"at": "2026-11-10T10:00:00Z"
}
@@ -186,7 +186,7 @@
"branch": "main",
"commit": "0123456789abcdef0123456789abcdef01234567",
"why": "the live delivery was broken",
"by": "jochen",
"by": "alice",
"at": "2026-11-11T10:00:00Z"
}
},
@@ -126,7 +126,7 @@
"repository": "novox/mesh-sdk",
"commit": "0123456789abcdef0123456789abcdef01234567",
"recovery": true,
"by": "jochen"
"by": "alice"
}
}
]
@@ -48,7 +48,7 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"ask": "m2kx9a1b3c4d5e"
},
{
@@ -70,7 +70,7 @@
"why": "TestTheBusWhole failed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "g14",
"node": "home-server",
"tests": {
"integration": 3
}
@@ -173,7 +173,7 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"ask": "m2kx9a1b3c4d5e"
}
],
@@ -197,7 +197,7 @@
"branch": "feature/1966-x"
}
],
"by": "fix-1965@shanks",
"by": "fix-1965@workstation",
"at": "2026-11-10T10:00:00Z"
}
},
@@ -244,12 +244,12 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"tests": {
"unit": 42
},
"rerun": true,
"by": "operator@shanks"
"by": "operator@workstation"
},
"at": "2026-11-10T10:05:00Z",
"fingerprint": "fp-0123"
@@ -20,7 +20,7 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"ask": "m2kx9a1b3c4d5e"
},
{
@@ -42,7 +42,7 @@
"why": "TestTheBusWhole failed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "g14",
"node": "home-server",
"tests": {
"integration": 3
}
@@ -90,7 +90,7 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"ask": "m2kx9a1b3c4d5e"
},
{
@@ -112,7 +112,7 @@
"why": "TestTheBusWhole failed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "g14",
"node": "home-server",
"tests": {
"integration": 3
}
@@ -66,7 +66,7 @@
"outcome": "passed",
"fingerprint": "fp-0123",
"seat": "node-build-go",
"node": "ace",
"node": "anchor",
"ask": "m2kx9a1b3c4d5e"
}
],
@@ -90,7 +90,7 @@
"since": "2026-11-09T19:00:00Z",
"bound": "30m",
"how": "released",
"by": "lead@shanks: the node is away"
"by": "lead@workstation: the node is away"
}
},
{
@@ -130,7 +130,7 @@
{
"name": "the composition step ended passed on the assigner's node, a node asleep warned",
"of": "event:step-ended",
"subject": "mesh.seat.mesh-wants.event.step-ended.novox",
"subject": "mesh.seat.mesh-wants.event.step-ended.laptop",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6a",
@@ -139,10 +139,10 @@
"module": "nats",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "novox",
"node": "laptop",
"outcome": "passed",
"warnings": [
"g14 asleep: composed from its last capabilities"
"home-server asleep: composed from its last capabilities"
],
"started": "2026-11-10T10:00:00Z",
"ended": "2026-11-10T10:01:00Z"
@@ -151,7 +151,7 @@
{
"name": "the composition step failed, two modules owning one path",
"of": "event:step-ended",
"subject": "mesh.seat.mesh-wants.event.step-ended.novox",
"subject": "mesh.seat.mesh-wants.event.step-ended.laptop",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6b",
@@ -160,9 +160,9 @@
"module": "nats",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "novox",
"node": "laptop",
"outcome": "failed",
"said": "nats and xclip both own /etc/nats.conf on ace"
"said": "nats and xclip both own /etc/nats.conf on anchor"
}
},
{
@@ -184,7 +184,7 @@
{
"name": "a composition step's progress",
"of": "event:step-progress",
"subject": "mesh.seat.mesh-wants.event.step-progress.ace",
"subject": "mesh.seat.mesh-wants.event.step-progress.anchor",
"given": {
"asker": "assigner",
"ask": "a1b2",
@@ -198,7 +198,7 @@
"subject": "mesh.seat.mesh-wants.event.wait-held",
"given": {
"step": "put",
"node": "ace",
"node": "anchor",
"module": "nats",
"fingerprint": "fp-0123",
"since": "2026-11-11T10:00:00Z",
@@ -215,8 +215,8 @@
"part": "mesh-sdk",
"version": "0.1.4",
"machines": [
"ace",
"g14"
"anchor",
"home-server"
],
"module": "nats",
"since": "2026-11-11T10:00:00Z",
@@ -261,10 +261,10 @@
"given": {
"step": "outside",
"owner": "mesh-delivery-assigner",
"node": "ace",
"node": "anchor",
"module": "nats",
"fingerprint": "src2:aaaa",
"on": "silent:g14",
"on": "silent:home-server",
"since": "2026-11-11T10:00:00Z",
"clock-from": "2026-11-11T10:00:00Z",
"bound": "30m"
@@ -277,10 +277,10 @@
"given": {
"step": "outside",
"owner": "mesh-delivery-assigner",
"node": "ace",
"node": "anchor",
"module": "nats",
"fingerprint": "src2:aaaa",
"on": "silent:g14",
"on": "silent:home-server",
"since": "2026-11-11T10:00:00Z",
"how": "go-on"
}
@@ -35,7 +35,7 @@
"of": "state:wants/held.<module>.<fingerprint>",
"given": {
"v": 1,
"node": "ace"
"node": "anchor"
}
},
{
@@ -2,7 +2,7 @@
{
"name": "a unit step ended passed on its node, with its counts and what it carried",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-go.event.step-ended.ace",
"subject": "mesh.seat.node-build-go.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5e",
@@ -14,7 +14,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "ace",
"node": "anchor",
"outcome": "passed",
"tests": {
"unit": 14
@@ -41,7 +41,7 @@
{
"name": "an integration step that could not run, naming the part not heard",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-go.event.step-ended.g14",
"subject": "mesh.seat.node-build-go.event.step-ended.home-server",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5f",
@@ -53,7 +53,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "g14",
"node": "home-server",
"outcome": "could not run",
"said": "the sandbox could not fetch novox/mesh-sdk",
"output-object": "mesh-build-go_sent-objects/m2kx9a1b3c4d5f",
@@ -63,9 +63,9 @@
{
"name": "a node's toolchain reported",
"of": "event:toolchain-reported",
"subject": "mesh.seat.node-build-go.event.toolchain-reported.ace",
"subject": "mesh.seat.node-build-go.event.toolchain-reported.anchor",
"given": {
"node": "ace",
"node": "anchor",
"language": "go",
"version": "1.26.0",
"recipe": "1",
@@ -75,7 +75,7 @@
{
"name": "a running ask says its progress",
"of": "event:step-progress",
"subject": "mesh.seat.node-build-go.event.step-progress.ace",
"subject": "mesh.seat.node-build-go.event.step-progress.anchor",
"given": {
"asker": "runner",
"ask": "a1b2",
@@ -86,13 +86,13 @@
{
"name": "a builder's build ended, naming its asker and no commit or fingerprint (G 548)",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-go.event.step-ended.ace",
"subject": "mesh.seat.node-build-go.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6a",
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"outcome": "failed",
"said": "the build failed",
"at": "2026-11-11T10:03:00Z"
@@ -101,11 +101,11 @@
{
"name": "an ask taken, whatever its asker (G 602)",
"of": "event:ask-taken",
"subject": "mesh.seat.node-build-go.event.ask-taken.ace",
"subject": "mesh.seat.node-build-go.event.ask-taken.anchor",
"given": {
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"at": "2026-11-11T10:00:00Z"
}
}
@@ -6,7 +6,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -17,7 +17,7 @@
"given": {
"v": 1,
"paused": true,
"by": "operator@shanks",
"by": "operator@workstation",
"at": "2026-11-05T10:00:00Z"
}
},
@@ -129,8 +129,8 @@
"recipe": "2"
},
"node-names": [
"ace",
"g14"
"anchor",
"home-server"
]
}
}
@@ -142,7 +142,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:03:00Z",
@@ -172,7 +172,7 @@
"v": 1,
"id": "a1b3",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:03:00Z",
@@ -203,7 +203,7 @@
"v": 1,
"id": "c3d4",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:06:00Z",
@@ -275,7 +275,7 @@
"v": 1,
"id": "c3d5",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "refused",
"started": "2026-11-05T10:00:00Z",
"result": {
@@ -296,7 +296,7 @@
"v": 1,
"id": "c3d5",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:01:00Z",
@@ -363,7 +363,7 @@
"v": 1,
"id": "r5e6",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "failed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:01:00Z",
@@ -382,7 +382,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "again",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:00:30Z",
@@ -539,7 +539,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -551,7 +551,7 @@
"v": 1,
"id": "c3d4e5f6a7b8c9",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:05:00Z",
@@ -2,7 +2,7 @@
{
"name": "a lint step ended passed on its node",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-image.event.step-ended.ace",
"subject": "mesh.seat.node-build-image.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5e",
@@ -14,7 +14,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "ace",
"node": "anchor",
"outcome": "passed",
"started": "2026-11-10T10:00:00Z",
"ended": "2026-11-10T10:02:00Z",
@@ -24,7 +24,7 @@
{
"name": "a lint step that could not run, naming the part not heard",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-image.event.step-ended.g14",
"subject": "mesh.seat.node-build-image.event.step-ended.home-server",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5f",
@@ -36,7 +36,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "g14",
"node": "home-server",
"outcome": "could not run",
"said": "the sandbox could not fetch novox/mesh-sdk",
"output-object": "mesh-build-go_sent-objects/m2kx9a1b3c4d5f",
@@ -46,9 +46,9 @@
{
"name": "a node's toolchain reported",
"of": "event:toolchain-reported",
"subject": "mesh.seat.node-build-image.event.toolchain-reported.ace",
"subject": "mesh.seat.node-build-image.event.toolchain-reported.anchor",
"given": {
"node": "ace",
"node": "anchor",
"language": "go",
"version": "1.26.0",
"recipe": "1",
@@ -58,7 +58,7 @@
{
"name": "a running ask says its progress",
"of": "event:step-progress",
"subject": "mesh.seat.node-build-image.event.step-progress.ace",
"subject": "mesh.seat.node-build-image.event.step-progress.anchor",
"given": {
"asker": "runner",
"ask": "a1b2",
@@ -69,13 +69,13 @@
{
"name": "a builder's build ended, naming its asker and no commit or fingerprint (G 548)",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-image.event.step-ended.ace",
"subject": "mesh.seat.node-build-image.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6a",
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"outcome": "failed",
"said": "the build failed",
"at": "2026-11-11T10:03:00Z"
@@ -84,11 +84,11 @@
{
"name": "an ask taken, whatever its asker (G 602)",
"of": "event:ask-taken",
"subject": "mesh.seat.node-build-image.event.ask-taken.ace",
"subject": "mesh.seat.node-build-image.event.ask-taken.anchor",
"given": {
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"at": "2026-11-11T10:00:00Z"
}
}
@@ -6,7 +6,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -17,7 +17,7 @@
"given": {
"v": 1,
"paused": true,
"by": "operator@shanks",
"by": "operator@workstation",
"at": "2026-11-05T10:00:00Z"
}
},
@@ -98,7 +98,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "again",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:00:30Z",
@@ -199,7 +199,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -211,7 +211,7 @@
"v": 1,
"id": "c3d4e5f6a7b8c9",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:05:00Z",
@@ -2,7 +2,7 @@
{
"name": "a unit step ended passed on its node, with its counts and what it carried",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-node.event.step-ended.ace",
"subject": "mesh.seat.node-build-node.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5e",
@@ -14,7 +14,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "ace",
"node": "anchor",
"outcome": "passed",
"tests": {
"unit": 14
@@ -41,7 +41,7 @@
{
"name": "an integration step that could not run, naming the part not heard",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-node.event.step-ended.g14",
"subject": "mesh.seat.node-build-node.event.step-ended.home-server",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d5f",
@@ -53,7 +53,7 @@
"artifact": "nats:program",
"commit": "0123456789abcdef0123456789abcdef01234567",
"fingerprint": "fp-0123",
"node": "g14",
"node": "home-server",
"outcome": "could not run",
"said": "the sandbox could not fetch novox/mesh-sdk",
"output-object": "mesh-build-go_sent-objects/m2kx9a1b3c4d5f",
@@ -63,9 +63,9 @@
{
"name": "a node's toolchain reported",
"of": "event:toolchain-reported",
"subject": "mesh.seat.node-build-node.event.toolchain-reported.ace",
"subject": "mesh.seat.node-build-node.event.toolchain-reported.anchor",
"given": {
"node": "ace",
"node": "anchor",
"language": "go",
"version": "1.26.0",
"recipe": "1",
@@ -75,7 +75,7 @@
{
"name": "a running ask says its progress",
"of": "event:step-progress",
"subject": "mesh.seat.node-build-node.event.step-progress.ace",
"subject": "mesh.seat.node-build-node.event.step-progress.anchor",
"given": {
"asker": "runner",
"ask": "a1b2",
@@ -86,13 +86,13 @@
{
"name": "a builder's build ended, naming its asker and no commit or fingerprint (G 548)",
"of": "event:step-ended",
"subject": "mesh.seat.node-build-node.event.step-ended.ace",
"subject": "mesh.seat.node-build-node.event.step-ended.anchor",
"given": {
"v": 1,
"id": "m2kx9a1b3c4d6a",
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"outcome": "failed",
"said": "the build failed",
"at": "2026-11-11T10:03:00Z"
@@ -101,11 +101,11 @@
{
"name": "an ask taken, whatever its asker (G 602)",
"of": "event:ask-taken",
"subject": "mesh.seat.node-build-node.event.ask-taken.ace",
"subject": "mesh.seat.node-build-node.event.ask-taken.anchor",
"given": {
"asker": "mesh-delivery-builder",
"ask": "m2kx9a1b3c4d6a",
"node": "ace",
"node": "anchor",
"at": "2026-11-11T10:00:00Z"
}
}
@@ -6,7 +6,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -17,7 +17,7 @@
"given": {
"v": 1,
"paused": true,
"by": "operator@shanks",
"by": "operator@workstation",
"at": "2026-11-05T10:00:00Z"
}
},
@@ -133,8 +133,8 @@
"recipe": "1"
},
"node-names": [
"ace",
"g14"
"anchor",
"home-server"
]
}
}
@@ -146,7 +146,7 @@
"v": 1,
"id": "c3d6",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:01:00Z",
@@ -179,7 +179,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "again",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:00:30Z",
@@ -296,7 +296,7 @@
"v": 1,
"id": "a1b2",
"tool": "build",
"node": "ace",
"node": "anchor",
"state": "running",
"started": "2026-11-05T10:00:00Z"
}
@@ -308,7 +308,7 @@
"v": 1,
"id": "c3d4e5f6a7b8c9",
"tool": "check",
"node": "ace",
"node": "anchor",
"state": "passed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:05:00Z",
@@ -7,7 +7,7 @@
"name": "base",
"kind": "base",
"digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"by": "operator@shanks",
"by": "operator@workstation",
"since": "2026-11-05T10:00:00Z"
}
},
@@ -18,10 +18,10 @@
"name": "mesh-delivery-builder",
"open": true,
"holding": [
"ace"
"anchor"
],
"since": {
"ace": "2026-11-05T10:00:00Z"
"anchor": "2026-11-05T10:00:00Z"
}
}
}