package main import ( "reflect" "strings" "testing" "time" "github.com/novox/mesh-controller/internal/catalogue" "github.com/novox/mesh-controller/internal/inventory" ) // **A new SDK plans the toolchain, and then every bundle compiled in it** (novox/hq issue 614), reasoned // as `mesh-controller.delivery-plan` reasons it: the modules registered as a build registers them — // resolved, so carrying no `build` — their builds recorded with what they stood on and what they made, // the graph read by theGraph and the change scoped by pullScope. On 2026-10-13 mesh-sdk 0.1.14 planned // "builds mesh-sdk, sent nowhere": mesh-tools' `build.on` naming the SDK's package and the providers' // TypeScript bundles were edges only while their manifests were unbuilt. // // **The replay of issue 614** (mesh-lab R614): written only with what the controller had before its fix — a // store, modules registered and builds recorded, theGraph and pullScope — so it is laid over the commit before // and fails there with the plan of that day, [[mesh-sdk]]. Needs a store: MESH_TEST_POSTGRES. func TestReplay614ANewSDKPlansTheToolchainAndThenItsBundles(t *testing.T) { inv := inventory.ForTest(t) ctx := t.Context() asked := time.Now().Add(-time.Hour) digest := func(c string) string { return "@sha256:" + strings.Repeat(c, 64) } register := func(m catalogue.Manifest, repository, path string, against []string, made []inventory.Artifact) { t.Helper() if err := inv.RegisterModule(ctx, m, inventory.Source{Repository: repository, Seat: "git", Path: path, Ref: "main", BuiltFrom: "old", Asked: asked}); err != nil { t.Fatal(err) } if err := inv.RecordBuild(ctx, inventory.Build{ID: "build-" + m.Module, Repository: repository, Ref: "main", Module: m.Module, Commit: "old", On: "builder", Path: path, Against: against, Made: made, Asked: asked}); err != nil { t.Fatal(err) } } bundle := func(module, language string) catalogue.Manifest { return catalogue.Manifest{Module: module, Version: "1", Bundles: []catalogue.Bundle{{ Name: "code", Language: language, Source: catalogue.ArtifactStoreScheme + module + "/code" + digest("2"), Entrypoints: []string{"tools/index.js"}}}} } register(catalogue.Manifest{Module: "build-agent", Version: "1", Claims: []catalogue.Claim{{Name: "node-build-agent", Scope: catalogue.ScopeNode}}}, "novox/mesh-catalog", "modules/build-agent", nil, nil) register(catalogue.Manifest{Module: "mesh-sdk", Version: "1"}, "novox/mesh-sdk", "", nil, []inventory.Artifact{{Name: "lib", Kind: "package", Reference: "@novox/mesh-sdk@0.1.13"}}) register(catalogue.Manifest{Module: "mesh-tools", Version: "1"}, "novox/mesh-tools", "", []string{"@novox/mesh-sdk@0.1.13", catalogue.ArtifactStoreScheme + "upstream/docker.io/library/node" + digest("0")}, []inventory.Artifact{{Name: "build", Kind: "image", Reference: catalogue.ArtifactStoreScheme + "mesh-tools/build" + digest("1")}}) register(catalogue.Manifest{Module: "mesh-tools-go", Version: "1"}, "novox/mesh-tools", "go", nil, nil) register(bundle("minio", "typescript"), "novox/mesh-catalog", "modules/minio", nil, nil) register(bundle("umami", "typescript"), "novox/mesh-catalog", "modules/umami", nil, nil) register(bundle("dnsmasq", "go"), "novox/mesh-catalog", "modules/dnsmasq", nil, nil) entries, read, edges, err := theGraph(ctx, inv) if err != nil { t.Fatal(err) } m := orderMember{ID: "novox/mesh-sdk@new", Repository: "novox/mesh-sdk", Head: "new", Paths: []string{"src/provisioner/index.ts", "package.json"}} s := pullScope(m.pull(), entries, read, edges) want := [][]string{{"mesh-sdk"}, {"mesh-tools"}, {"minio", "umami"}} if !reflect.DeepEqual(s.Reach.Plan.Tiers, want) { t.Fatalf("a new SDK plans %v, want %v (edges %v)", s.Reach.Plan.Tiers, want, edges) } if !reflect.DeepEqual(s.Dependents, []string{"mesh-tools", "minio", "umami"}) { t.Errorf("dependents %v", s.Dependents) } }