Merge pull request 'Phase 5 (4/4): replay issues 263 and 273 (hq ADR 0237)' (#98) from feat/replays into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on

This commit was merged in pull request #98.
This commit is contained in:
2026-10-06 19:19:49 +00:00
+113
View File
@@ -0,0 +1,113 @@
package main
import (
"testing"
"github.com/novox/mesh-controller/internal/catalogue"
)
// The replays of the controller's incidents (novox/hq to-be 45 §9, M9): each a scripted replay of what
// happened, asserting the rule's outcome rather than the fix's mechanism, so it can be run against the
// commit before the fix and fail there, and against the fix and pass. **Written only with what the
// controller had before each fix** — the stores, register, assign, planFor, declarationFor — so the
// prover (mesh-lab replays/cmd/prove) can lay this file over the older commit and run it there.
//
// Registered in mesh-lab's replays/register.go with the fix each one proves; run by this repository's
// merge check on every pull request with the rest of the suite.
// **R263 — a consumer's identity never refuses its provider's machine.** On 2026-10-06 the network
// manager came to require the mesh's resolver; on a machine whose name made its identity 23 to 26
// characters against the one global bound of 20, the anchor — the resolver's holder, carrying every
// consumer's grant — could not compose, and no push to it could go through. The outcome asserted: the
// provider's machine composes whatever its consumers are called, and a provision that mints no
// credential holds no consumer to a key's length.
func TestReplay263AnIdentityTooLongNeverRefusesItsProvidersMachine(t *testing.T) {
open := aMesh(t)
ctx := t.Context()
register(t, open, catalogue.Manifest{Module: "resolver", Version: "1",
Provides: []catalogue.Offer{{Name: "wildcard-resolution", Scope: catalogue.ScopeMesh}}})
register(t, open, catalogue.Manifest{Module: "networkmanager", Version: "1",
Requires: []string{"wildcard-resolution"}})
for _, a := range [][2]string{{"anchor", "resolver"}, {"laptop", "networkmanager"}} {
if _, err := assign(ctx, open, a[0], a[1]); err != nil {
t.Fatalf("assign %s %s: %v", a[0], a[1], err)
}
}
// The consumer's machine composes first, as a push does: what it is sent is what its provider grants.
for _, node := range []string{"laptop", "anchor"} {
plan, settings, err := planFor(ctx, open, node)
if err != nil {
t.Fatalf("%s does not resolve: %v", node, err)
}
if _, err := declarationFor(ctx, open, node, plan, settings); err != nil {
t.Fatalf("%s cannot be sent anything — the consumer networkmanager on laptop, identified "+
"mesh_laptop_networkmanager (26 characters), refused it: %v", node, err)
}
}
}
// **R273 — a binding to a consumer's data does not move by itself.** On 2026-10-05 a rule written for
// the resolver re-bound every database consumer on the home server — which runs its own store, beside
// its applications' data — to the store seat's holder on the control node, which made each a new empty
// database; five applications ran on empty data for twenty hours. The outcome asserted: a consumer on a
// machine running its own store stays bound to it while another machine holds the store's seat; the
// resolver, which every holder answers alike, follows its seat.
func TestReplay273AConsumerBesideItsStoreStaysBoundToIt(t *testing.T) {
open := aMesh(t)
ctx := t.Context()
inv := open.inventory
if _, err := inv.SeedSeats(ctx, catalogue.DefaultSeats()); err != nil {
t.Fatal(err)
}
for _, m := range []catalogue.Manifest{
{Module: "store", Version: "1",
Provides: []catalogue.Offer{{Name: "postgres-database", Scope: catalogue.ScopeMesh}},
Claims: []catalogue.Claim{{Name: "mesh-store", Scope: catalogue.ScopeMesh}},
Serves: map[string]map[string]any{"postgres-database": {"port": 5432}},
Grants: map[string]string{"postgres-database": "/var/lib/mesh/store/grants"}},
{Module: "resolver", Version: "1",
Provides: []catalogue.Offer{{Name: "wildcard-resolution", Scope: catalogue.ScopeMesh}},
Claims: []catalogue.Claim{{Name: "mesh-dns-resolver", Scope: catalogue.ScopeMesh}}},
{Module: "network", Version: "1", Requires: []string{"wildcard-resolution"}},
{Module: "board", Version: "1", Requires: []string{"postgres-database"}},
} {
register(t, open, m)
}
assignAll := func(pairs ...[2]string) {
for _, a := range pairs {
if _, err := assign(ctx, open, a[0], a[1]); err != nil {
t.Fatalf("assign %s %s: %v", a[0], a[1], err)
}
}
}
// The control node holds the mesh's store and resolver seats; the home server runs its own of each.
assignAll([2]string{"anchor", "store"}, [2]string{"anchor", "resolver"})
for _, seat := range [][2]string{{"mesh-store", "store"}, {"mesh-dns-resolver", "resolver"}} {
if err := inv.HoldSeat(ctx, seat[0], catalogue.ScopeMesh, "anchor", seat[1]); err != nil {
t.Fatal(err)
}
}
assignAll([2]string{"laptop", "store"}, [2]string{"laptop", "resolver"}, [2]string{"laptop", "network"},
[2]string{"laptop", "board"})
plan, _, err := planFor(ctx, open, "laptop")
if err != nil {
t.Fatal(err)
}
var board, network string
for _, n := range plan.Needs {
switch {
case n.For == "board" && n.Name == "postgres-database":
board = n.From
case n.For == "network" && n.Name == "wildcard-resolution":
network = n.From
}
}
if board != "laptop" {
t.Fatalf("the consumer beside its store was bound to the store on %q, which would make it a new, empty "+
"database there (issue 273)", board)
}
if network != "anchor" {
t.Fatalf("the resolver was bound to %q; its seat is held on anchor (issue 258)", network)
}
}