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 49b80d8516
commit 5d6e8fbe7a
89 changed files with 785 additions and 785 deletions
+2 -2
View File
@@ -103,7 +103,7 @@ export interface Machine {
* and a handful of containers.
*
* Declared, because it is a fact about the machine the scenario describes — the node that runs
* the whole substrate is bigger than the laptop that joins it, and a test that starves its
* the whole foundation is bigger than the laptop that joins it, and a test that starves its
* anchor at the default answers questions about memory pressure, not about the mesh. The forge
* test failed three times as "status hangs" before anyone counted the containers in 1GiB
* (novox/hq 04-ISSUES/024 is the same lesson about a different resource).
@@ -158,7 +158,7 @@ export interface Scenario {
* **The mesh's own images** — the ones that exist in no registry and are put onto a machine by
* whoever built them.
*
* mesh-control, mesh-builder, mesh-route-proxy, the per-module runtimes and the provisioners are
* mesh-controller, mesh-builder, mesh-route-proxy, the per-module runtimes and the provisioners are
* built from source and published nowhere. A machine gets them the way an operator's machine
* does: they are built on the workstation, loaded onto the machine, and named by the digest of
* their own image configuration. Written as tags, because a tag is what `docker save` can
+1 -1
View File
@@ -7,7 +7,7 @@
* from the internet, and that is now the thing worth proving before a raise says it is finished.
*
* The failure it exists to stop is the same one, in the same shape: `raise` returns, the caller
* applies a substrate, the first pull fails, no node enrols, and the instance is left a bare
* applies a foundation, the first pull fails, no node enrols, and the instance is left a bare
* shell — with the cause several steps back and looking like a mesh fault rather than a lab one.
*
* Two things are checked, in this order, because they fail differently and the difference is the
+2 -2
View File
@@ -5,7 +5,7 @@
* the thing it exists to test did not exist (novox/hq 03-DESIGN/00-as-is/11-the-lab.md). Tier
* 0 now does, so this is the seam where the lab acquires a consumer.
*
* Only `host` is placeable. Everything else in the placement vocabulary — the substrate, a
* Only `host` is placeable. Everything else in the placement vocabulary — the foundation, a
* control plane, a forge — is still refused by name rather than ignored, because a scenario
* that declares something and raises without it is the fault this lab was built to catch
* (novox/hq 04-ISSUES/003).
@@ -515,7 +515,7 @@ export async function loadHeldImages(
throw new Error(
`${requested} is not on this workstation, so there is nothing to hand the machines.\n` +
` It is one of the mesh's own images and exists in no registry — nothing can pull it.\n` +
` Build it first (mesh-control's \`make image …\`, or scripts/build-module-runtime.sh).`,
` Build it first (mesh-controller's \`make image …\`, or scripts/build-module-runtime.sh).`,
);
}
}
+1 -1
View File
@@ -338,7 +338,7 @@ export async function raise(
// **Only now is "this machine can reach the outside" a true statement.** The route, the
// gateway and the machine's own filtering are all in place, so this is the path a pull takes.
// A raise that returned without checking would hand the next step a fact it depends on and
// has no way to test — which is how a substrate apply used to die on its first pull.
// has no way to test — which is how a foundation apply used to die on its first pull.
enter("confirming egress reaches the internet");
await confirmEgress(scenario, byMachine, log);
+1 -1
View File
@@ -36,7 +36,7 @@ export function assertSupported(scenario: Scenario): void {
// `host`, `runtime` and `image:<reference>` work. Everything else in the vocabulary is named
// individually rather than refused as a whole, so a scenario that places a host and a
// substrate is told exactly which half the lab cannot do.
// foundation is told exactly which half the lab cannot do.
const unplaceable = new Set<string>();
for (const { artifacts } of planPlacements(scenario)) {
for (const artifact of artifacts) {
+2 -2
View File
@@ -3,7 +3,7 @@
*
* **A digest is not knowable until something is built** (novox/hq 04-ISSUES/025). A manifest in a
* repository can pin a third-party image, because somebody can ask a registry what a tag points
* at. It cannot pin an image the mesh builds itself: mesh-control, mesh-builder, mesh-route-proxy,
* at. It cannot pin an image the mesh builds itself: mesh-controller, mesh-builder, mesh-route-proxy,
* the per-module runtimes and the provisioners exist in no registry, so there is no manifest
* digest to write down. The catalogue ships sixty-four zeros for them, which parses, resolves,
* composes — and stops on the machine.
@@ -54,7 +54,7 @@ export function repositoryOf(reference: string): string {
*
* **Derived from the shape the build produces, not from a list of names.** `make image
* builder-image provisioner-image objectstore-image redis-provisioner-image proxy-image` in
* mesh-control and `scripts/build-module-runtime.sh` here both tag their output `mesh-<something>`
* mesh-controller and `scripts/build-module-runtime.sh` here both tag their output `mesh-<something>`
* with no registry host and no upstream organisation — that is what "built here, published
* nowhere" looks like, and a hardcoded list would go stale the first time a module is added.
*
+3 -3
View File
@@ -45,7 +45,7 @@ export function planned(env: NodeJS.ProcessEnv = process.env): Build[] {
env: { CGO_ENABLED: "0" },
});
}
const control = where["mesh-control"];
const control = where["mesh-controller"];
if (control) {
// **Every image the lab runs, not only the control plane's.**
//
@@ -84,7 +84,7 @@ export function planned(env: NodeJS.ProcessEnv = process.env): Build[] {
//
// It is built here at all because the bed now bootstraps THROUGH it (novox/hq ADR 0067): the
// anchor is brought into existence by running the same program a bare machine runs, rather than
// by the bed applying a substrate bundle by hand and calling that an install. An installer that
// by the bed applying a foundation bundle by hand and calling that an install. An installer that
// was stale would be a bed proving something about last week's procedure.
const installer = env["MESH_LAB_BOOTSTRAP_BINARY"];
if (installer && where["mesh-host"]) {
@@ -104,7 +104,7 @@ export function planned(env: NodeJS.ProcessEnv = process.env): Build[] {
* thing it was going to run and now carries the thing that makes it, so a raised mesh holds a
* control plane it built from a repository and a commit rather than one it was handed.
*
* `mesh-builder:development` is what mesh-control's `make builder-image` tags — one tag, said in
* `mesh-builder:development` is what mesh-controller's `make builder-image` tags — one tag, said in
* one place. Overridable because a release installer carries a release image, and nothing about
* that is the lab's business.
*/
+1 -1
View File
@@ -23,6 +23,6 @@ export function repositories(env: NodeJS.ProcessEnv = process.env): Repositories
const host = env["MESH_LAB_HOST_BINARY"];
if (host) found["mesh-host"] = dirname(host);
const modules = env["MESH_LAB_MODULES"];
if (modules) found["mesh-control"] = dirname(dirname(modules));
if (modules) found["mesh-controller"] = dirname(dirname(modules));
return found;
}