diff --git a/cmd/mesh-controller/replay292_test.go b/cmd/mesh-controller/replay292_test.go new file mode 100644 index 0000000..853d12e --- /dev/null +++ b/cmd/mesh-controller/replay292_test.go @@ -0,0 +1,33 @@ +package main + +import ( + "testing" + "time" + + "github.com/novox/mesh-controller/internal/link" +) + +// **R292 — a drill is never counted as a repair** (novox/hq issue 292). On 2026-10-07 two deliberate +// drills of ADR 0240's health check — a module stopped on purpose, then one made to crash, each with the +// operator's word — were recorded through `hand-act record --cause drill`, there being no verb for a drill, +// and S15 raised `mesh.hand-acts.drill.healer-wanted`: "drill" repaired by hand twice, a healer wanted. The +// outcome asserted: those two acts, as the log holds them, want no healer. +// +// In a file of its own, written only with what the controller had before the fix (watchHandActs, calm, the +// hand-act log's row), so the prover can lay it over that commit; replays_test.go holds replays of later +// commits that do not build there. +func TestReplay292TwoDrillsRecordedByHandWantNoHealer(t *testing.T) { + now := time.Date(2026, 10, 7, 12, 0, 0, 0, time.UTC) + drill := func(at time.Time, what, why string) link.HandAct { + return link.HandAct{ID: "act-" + at.Format("150405"), At: at, By: "the operator at a shell on the laptop", + Verb: "hand-act record", Args: []string{what}, Why: why, Cause: "drill"} + } + f := calm(now) + f.handActs = []link.HandAct{ + drill(now.Add(-11*time.Hour), "stopped a module on purpose", "ADR 0240: an exited container is said"), + drill(now.Add(-30*time.Minute), "made a module crash on purpose", "ADR 0240: a crash loop is said"), + } + if got := watchHandActs(f); len(got) != 0 { + t.Fatalf("two drills the operator approved were counted as repairs: %s", got[0].Summary) + } +} diff --git a/internal/catalogue/replays_test.go b/internal/catalogue/replays_test.go new file mode 100644 index 0000000..3439da3 --- /dev/null +++ b/internal/catalogue/replays_test.go @@ -0,0 +1,36 @@ +package catalogue + +import ( + "slices" + "testing" +) + +// **R298 — a seat's new verb lands in either repository first** (novox/hq issue 298). On 2026-10-07 the +// delivery seat gained `checks`: the seat is defined here and held by a module in the catalogue, and +// neither could merge first — a controller promising the verb refused the holder that did not serve it +// yet, and a holder serving it was refused by the controller that did not promise it. The outcome +// asserted: the holder as it was, and the holder serving `checks` too, both hold the delivery seat. +// +// Written only with what the catalogue package had before the fix (SeatNamed, VerbNames, CanHold), so the +// prover can lay it over that commit. +func TestReplay298ADeliverySeatHolderHoldsBeforeAndAfterItServesChecks(t *testing.T) { + seat, ok := SeatNamed(DeliverySeat) + if !ok { + t.Fatal("the delivery seat is not in the set") + } + var before []string + for _, v := range VerbNames(seat.Serves) { + if v != "checks" { + before = append(before, v) + } + } + holder := func(serves []string) Manifest { + return Manifest{Module: "mesh-delivery", Claims: []Claim{{Name: DeliverySeat, Scope: ScopeMesh, Serves: serves}}} + } + if err := CanHold(holder(before), seat); err != nil { + t.Fatalf("the holder as the catalogue had it, before it serves checks, is refused: %v", err) + } + if err := CanHold(holder(append(slices.Clone(before), "checks")), seat); err != nil { + t.Fatalf("the holder serving checks is refused — the catalogue cannot merge first: %v", err) + } +}