Rename mesh-control -> mesh-controller, substrate -> foundation

One name per thing, per the HQ glossary: the module/container/image/binary/repo
becomes mesh-controller, the seat the-controller, and the store+broker pair the
foundation (embedded base bundles, default template and example lock renamed with
their go:embed directives). No behaviour change — a pure vocabulary rename.

Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
2026-09-16 18:40:40 +02:00
parent 01c7730fb3
commit 121367319d
48 changed files with 317 additions and 317 deletions
+27 -27
View File
@@ -15,16 +15,16 @@ const (
otherHeld = "sha256:2222222222222222222222222222222222222222222222222222222222222222"
)
// theRealBundle is this repository's own substrate example, used rather than a fixture.
// theRealBundle is this repository's own foundation example, used rather than a fixture.
//
// A fixture would agree with whatever this code does. The example is what an installer is actually
// pointed at, it names the control plane twice, and it is the file that changes when the substrate
// pointed at, it names the control plane twice, and it is the file that changes when the foundation
// changes — so a rewrite that stops working on it is a rewrite that has stopped working.
func theRealBundle(t *testing.T) []byte {
t.Helper()
raw, err := os.ReadFile("../../examples/substrate-first-node.lock")
raw, err := os.ReadFile("../../examples/foundation-first-node.lock")
if err != nil {
t.Fatalf("reading the substrate example: %v", err)
t.Fatalf("reading the foundation example: %v", err)
}
return raw
}
@@ -48,7 +48,7 @@ func TestTheControlPlaneIsNamedByTheImageThisMachineHolds(t *testing.T) {
// **Every place the bundle names that image, not only the container.**
//
// The substrate names the control plane's image twice: the container that runs `serve`, and the
// The foundation names the control plane's image twice: the container that runs `serve`, and the
// action that runs `migrate` to create the contexts' schemas. Rewriting only the container leaves
// the migration pointing at an image no registry serves, and the apply dies in the middle — after
// the store is up and before the broker. This is the test that would have caught that.
@@ -60,7 +60,7 @@ func TestEveryPlaceTheBundleNamesTheControlPlaneIsRewritten(t *testing.T) {
t.Fatal(err)
}
if out.Places < 2 {
t.Fatalf("the control plane's image was found in %d place(s); the substrate names it in "+
t.Fatalf("the control plane's image was found in %d place(s); the foundation names it in "+
"the container AND in the migration action", out.Places)
}
if remaining := strings.Count(string(out.Bundle), out.Was); remaining != 0 {
@@ -86,7 +86,7 @@ func TestPostgresAndTheBrokerAreLeftExactlyAsTheyWere(t *testing.T) {
for _, id := range []string{"store", "broker"} {
image, named := produced[id]
if !named {
t.Fatalf("the substrate example no longer declares a %q container", id)
t.Fatalf("the foundation example no longer declares a %q container", id)
}
// Compared against the template's own text rather than against an expectation written
// here: what is being defended is "unchanged", and the template is the only thing that
@@ -126,7 +126,7 @@ func TestABundleThatNamesNoControlPlaneIsRefused(t *testing.T) {
func TestAControlPlaneThatIsNotAContainerIsRefused(t *testing.T) {
template := []byte(`{"declaration":1,"resources":[
{"id":"control-plane","type":"package","package":"mesh-control"}
{"id":"control-plane","type":"package","package":"mesh-controller"}
]}`)
if _, err := Rewrite(template, held); err == nil {
t.Fatal("a control plane declared as a package was accepted, and a package has no image")
@@ -175,7 +175,7 @@ func TestANewImageReplacesAnOlderHeldOne(t *testing.T) {
}
// The produced bundle is meant to be READ. Re-serialising a parsed declaration would drop every
// comment in the template, and the substrate example is mostly comments — each one recording why a
// comment in the template, and the foundation example is mostly comments — each one recording why a
// resource is the way it is, several of them paid for in the lab.
func TestTheProducedBundleKeepsTheTemplatesComments(t *testing.T) {
template := theRealBundle(t)
@@ -194,11 +194,11 @@ func TestTheProducedBundleKeepsTheTemplatesComments(t *testing.T) {
func TestSomethingThatIsNotAnImageIdIsRefused(t *testing.T) {
for _, bad := range []string{
"",
"mesh-control:latest",
"mesh-controller:latest",
"sha256:abc",
"sha256:" + strings.Repeat("1", 63),
"sha256:" + strings.Repeat("g", 64),
"mesh-control@sha256:" + strings.Repeat("1", 64),
"mesh-controller@sha256:" + strings.Repeat("1", 64),
} {
if _, err := Rewrite(theRealBundle(t), bad); err == nil {
t.Errorf("image id %q was accepted", bad)
@@ -216,7 +216,7 @@ func TestTheAddressNodesWillDialIsReportedAndNotRewritten(t *testing.T) {
t.Fatal(err)
}
if out.BrokerAddress == "" {
t.Fatal("the substrate example no longer says what address enrolling nodes will dial")
t.Fatal("the foundation example no longer says what address enrolling nodes will dial")
}
if !strings.Contains(string(out.Bundle), out.BrokerAddress) {
t.Errorf("the produced bundle no longer carries %q — it was rewritten, and nothing here "+
@@ -228,21 +228,21 @@ func TestTheAddressNodesWillDialIsReportedAndNotRewritten(t *testing.T) {
// The rename, which is what makes genesis a pivot rather than a handover (novox/hq ADR 0067).
// ---------------------------------------------------------------------------------------------
// **This is the test that dissolves the blocker.** The substrate raises a control plane and a
// module later declares one; if both are called `mesh-control` then for one moment two owners hold
// **This is the test that dissolves the blocker.** The foundation raises a control plane and a
// module later declares one; if both are called `mesh-controller` then for one moment two owners hold
// one container, and the host — which tracks what it owns — has no way to stop owning something
// without destroying it. Nothing here invents such a mechanism. The substrate's container is
// called `temp-mesh-control` instead, and there are simply two containers.
func TestTheSubstratesControlPlaneMovesOutOfTheModulesWay(t *testing.T) {
// without destroying it. Nothing here invents such a mechanism. The foundation's container is
// called `temp-mesh-controller` instead, and there are simply two containers.
func TestTheFoundationsControlPlaneMovesOutOfTheModulesWay(t *testing.T) {
out, err := Rewrite(theRealBundle(t), held)
if err != nil {
t.Fatal(err)
}
if !out.Renamed {
t.Error("the rewrite reported nothing renamed, and the template named it mesh-control")
t.Error("the rewrite reported nothing renamed, and the template named it mesh-controller")
}
if out.TempName != "temp-mesh-control" {
t.Errorf("the substrate's control plane is called %q", out.TempName)
if out.TempName != "temp-mesh-controller" {
t.Errorf("the foundation's control plane is called %q", out.TempName)
}
control, err := controlPlaneIn(out.Declaration)
if err != nil {
@@ -260,22 +260,22 @@ func TestTheSubstratesControlPlaneMovesOutOfTheModulesWay(t *testing.T) {
}
}
// The image reference contains the string `mesh-control` too, and it is not a container name. A
// substitution that caught it would produce `…/temp-mesh-control@sha256:…`, which no registry
// The image reference contains the string `mesh-controller` too, and it is not a container name. A
// substitution that caught it would produce `…/temp-mesh-controller@sha256:…`, which no registry
// serves — and it would be found inside a pull rather than here.
func TestTheImageReferenceIsNotMistakenForTheContainerName(t *testing.T) {
out, err := Rewrite(theRealBundle(t), held)
if err != nil {
t.Fatal(err)
}
if strings.Contains(string(out.Bundle), TempPrefix+"mesh-control@") ||
strings.Contains(string(out.Bundle), "/"+TempPrefix+"mesh-control") {
if strings.Contains(string(out.Bundle), TempPrefix+"mesh-controller@") ||
strings.Contains(string(out.Bundle), "/"+TempPrefix+"mesh-controller") {
t.Error("the rename reached inside an image reference")
}
}
// Everything else keeps the name the substrate gave it. The store and the broker are containers
// too, and a rename that moved them would leave a machine whose substrate the host cannot find.
// Everything else keeps the name the foundation gave it. The store and the broker are containers
// too, and a rename that moved them would leave a machine whose foundation the host cannot find.
func TestRenamingTheControlPlaneLeavesEveryOtherContainerAlone(t *testing.T) {
before, err := declaration.ParseFileTrusted(theRealBundle(t))
if err != nil {
@@ -309,7 +309,7 @@ func TestRewritingABundleThisAlreadyProducedRenamesNothing(t *testing.T) {
t.Fatal(err)
}
if second.Renamed {
t.Error("a bundle already naming temp-mesh-control was renamed again")
t.Error("a bundle already naming temp-mesh-controller was renamed again")
}
if second.TempName != first.TempName {
t.Errorf("the second pass calls it %q and the first called it %q",