ADR 0067's own acceptance check said the lab must raise its anchor by running the program a bare machine runs. It did not: whole-mesh-full applied the substrate bundle by hand and then looped enrolment over all four machines as one continuous operation. That gets the order right by accident and models the wrong shape — and an install procedure that exists only as a test fixture is exercised by whoever writes tests and never by whoever installs, which is why every bootstrap fault this year was found late. Two acts now, and the first gates the second. GENESIS is novox running mesh-bootstrap: the installer is built from source before the raise (make bootstrap, carrying the control-plane image built in the same run), placed beside the host binary, given the two manifests it reads, and run. The bed then asserts a WORKING MESH OF ONE — the control plane answers, the registry replies on /v2/, the container called mesh-control is running from a registry-pinned digest rather than an image id, the registry agrees it serves it, temp-mesh-control is gone, and the mesh has heard from its node. The image-id check is ADR 0067's "the pivot completed" verbatim: if it is still an id, nothing was published and this mesh can never roll out its own upgrades. JOINING is ace, shanks and g14: host binary, token, enrol, run. novox is NOT enrolled again — the installer already did it, and a second identity is one the mesh does not know. If genesis stops, the bed prints which of the installer's ten steps it stopped at and goes no further. A second machine joining a mesh that is not ready is a different failure, and running it would bury this one underneath it. The anchor is no longer handed mesh-control:development. Its absence is the point: the installer carries that image inside itself, and handing it over as well would make the load say "already held" and leave the carrying untested — the same class of fiction the lab's own registry used to hide. A unit test asserts the scenario keeps it out. The registry is reached at 127.0.0.1:5000, which is a finding rather than a shortcut: a runtime refuses a plain-HTTP registry at any address but a loopback one, so the digest the control-plane module is pinned to is one only the anchor can pull. Enough here, because only the anchor runs a control plane. Written down in the bed. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
116 lines
5.7 KiB
TypeScript
116 lines
5.7 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { planned, controlPlaneImage } from "../src/rebuild.ts";
|
|
import { repositories } from "../src/repos.ts";
|
|
import { loadScenario } from "../src/declaration/parse.ts";
|
|
|
|
// The control plane's image and the builder are one step, not two.
|
|
//
|
|
// Both parse manifests. On 2026-08-30 a rename was built into the image and not the binary, and
|
|
// the run that found out was a full lab raise. novox/hq 04-ISSUES/005.
|
|
test("the control plane's image and builder are always built together", () => {
|
|
const builds = planned({
|
|
MESH_LAB_MODULES: "/repo/control/examples/modules",
|
|
MESH_LAB_BUILDER: "/repo/control/build/mesh-builder",
|
|
});
|
|
const what = builds.map((b) => b.what);
|
|
assert.ok(what.includes("images"), "the images were not built");
|
|
assert.ok(what.includes("builder"), "the builder was not built");
|
|
for (const build of builds) assert.equal(build.in, "/repo/control");
|
|
});
|
|
|
|
// Every image the lab runs, not only the control plane's.
|
|
//
|
|
// On 2026-09-01 a run had a control-plane image built that minute and a provisioner image built
|
|
// the day before. A test against a real database failed, and it looked exactly like the change
|
|
// under test being wrong: the provisioner was creating logins by a naming rule that had been
|
|
// replaced hours earlier. novox/hq 04-ISSUES/005 again, one target along.
|
|
//
|
|
// Named individually rather than by counting, because the failure this guards is a target that
|
|
// exists and is not run — which a count would not notice.
|
|
test("every image the lab runs is rebuilt, not only the control plane's", () => {
|
|
const builds = planned({ MESH_LAB_MODULES: "/repo/control/examples/modules" });
|
|
const images = builds.find((b) => b.what === "images");
|
|
assert.ok(images, "no image build at all");
|
|
for (const target of [
|
|
"image", "builder-image", "provisioner-image", "objectstore-image",
|
|
"redis-provisioner-image", "proxy-image",
|
|
]) {
|
|
assert.ok(images.argv.includes(target), `${target} is never built, so the lab runs a stale one`);
|
|
}
|
|
});
|
|
|
|
// The installer is built, and it is built AFTER the image it carries.
|
|
//
|
|
// `make bootstrap` embeds the output of `docker save <image>`, so an installer built before the
|
|
// control plane's image is one carrying whatever was lying around — 04-ISSUES/005 again, this time
|
|
// sealed inside a binary where nothing would ever notice. The bed raises its anchor by running this
|
|
// program (novox/hq ADR 0067), so a stale one is a bed proving something about last week.
|
|
test("the installer is built, carrying the image built in the same run", () => {
|
|
const builds = planned({
|
|
MESH_LAB_HOST_BINARY: "/repo/host/mesh-host",
|
|
MESH_LAB_MODULES: "/repo/control/examples/modules",
|
|
MESH_LAB_BOOTSTRAP_BINARY: "/repo/host/mesh-bootstrap",
|
|
});
|
|
const what = builds.map((b) => b.what);
|
|
assert.ok(what.includes("installer"), "the installer is never built, so the bed carries a stale one");
|
|
assert.ok(
|
|
what.indexOf("images") < what.indexOf("installer"),
|
|
`the installer is built before the image it embeds: ${what.join(", ")}`,
|
|
);
|
|
|
|
const installer = builds.find((b) => b.what === "installer")!;
|
|
assert.equal(installer.in, "/repo/host");
|
|
assert.ok(installer.argv.includes(`IMAGE=${controlPlaneImage({})}`), installer.argv.join(" "));
|
|
assert.ok(installer.argv.includes("BOOTSTRAP_OUT=/repo/host/mesh-bootstrap"), installer.argv.join(" "));
|
|
});
|
|
|
|
// The anchor must NOT be handed the control plane's image.
|
|
//
|
|
// The installer carries it, which is the whole reason a machine that can reach no registry can
|
|
// raise a mesh (novox/hq ADR 0067). Hand it over from the workstation as well and the installer's
|
|
// load says "already held", the carrying is never exercised, and the bed goes green on a fiction —
|
|
// the same class of thing the lab's own registry used to hide. Asserted on the file rather than
|
|
// remembered, because a list of images is exactly the kind of thing somebody tops up.
|
|
test("the whole-mesh bed hands its anchor no control-plane image", () => {
|
|
const scenario = loadScenario("scenarios/whole-mesh-full.yml");
|
|
const named = [
|
|
...(scenario.images ?? []),
|
|
...Object.values(scenario.machines).flatMap((m) => m.images ?? []),
|
|
];
|
|
assert.deepEqual(
|
|
named.filter((i) => i.startsWith("mesh-control")),
|
|
[],
|
|
"the anchor is handed mesh-control, so genesis would never find out whether the installer " +
|
|
"really carries it",
|
|
);
|
|
});
|
|
|
|
// A repository this run was not pointed at is not built, and not claimed.
|
|
test("only what this run was pointed at is built", () => {
|
|
assert.deepEqual(planned({}), []);
|
|
const hostOnly = planned({ MESH_LAB_HOST_BINARY: "/repo/host/mesh-host" });
|
|
assert.deepEqual(hostOnly.map((b) => b.what), ["host"]);
|
|
assert.equal(hostOnly[0]!.in, "/repo/host");
|
|
});
|
|
|
|
// What the receipt claims and what the run built come from one derivation.
|
|
//
|
|
// They are separate concerns that must agree: a receipt naming a repository the run did not build
|
|
// is false coverage arriving by nobody's decision — just two derivations drifting apart.
|
|
// novox/hq 04-ISSUES/005.
|
|
test("every repository the receipt claims was built by the run", () => {
|
|
const env = {
|
|
MESH_LAB_HOST_BINARY: "/repo/host/mesh-host",
|
|
MESH_LAB_MODULES: "/repo/control/examples/modules",
|
|
MESH_LAB_BUILDER: "/repo/control/build/mesh-builder",
|
|
};
|
|
const built = new Set(planned(env).map((b) => b.in));
|
|
for (const [name, directory] of Object.entries(repositories(env))) {
|
|
// mesh-lab is the exception, and it is not an omission: it is TypeScript run from source, so
|
|
// the code under test *is* the code running. There is nothing to build and nothing to go stale.
|
|
if (name === "mesh-lab") continue;
|
|
assert.ok(built.has(directory), `${name} (${directory}) is claimed but never built`);
|
|
}
|
|
});
|