From cd1653bfe99b89d24c3fd3d2eafd852e54b39500 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 10 Sep 2026 23:19:17 +0200 Subject: [PATCH] =?UTF-8?q?ADR=200067=20=E2=80=94=20genesis=20is=20a=20piv?= =?UTF-8?q?ot=20through=20a=20temporary=20control=20plane?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The control plane's image is built from source and pushed nowhere, so it has no manifest digest; a registry assigns those. Pinning therefore required a registry before the thing that lets a mesh have a registry could start — a dependency the rule created by accident. The lab hid it by raising a disposable registry no production has. Proposed, not accepted. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF --- 02-DECISIONS/0067-genesis-is-a-pivot.md | 116 ++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 02-DECISIONS/0067-genesis-is-a-pivot.md diff --git a/02-DECISIONS/0067-genesis-is-a-pivot.md b/02-DECISIONS/0067-genesis-is-a-pivot.md new file mode 100644 index 0000000..40f11a9 --- /dev/null +++ b/02-DECISIONS/0067-genesis-is-a-pivot.md @@ -0,0 +1,116 @@ +--- +status: proposed +date: 2026-09-10 +deciders: jochen +reconstructed: false +extends: 0006-the-substrate-and-the-control-plane.md +--- + +# 67. Genesis is a pivot: a temporary control plane installs the registry that makes it permanent + +## Context + +**The mesh builds its own modules into its own registry, and there is no public registry for them +— that is the point, not an omission.** A module is cloned from the forge, built, and published +where the mesh can move, replace and back it up. Nothing about that arrangement wants a copy of the +mesh's code hosted by somebody else. + +**Every image must be pinned by digest** ([ADR 0006](0006-the-substrate-and-the-control-plane.md)), +and the reasoning is exactly right: a bundle is applied where no mesh exists to check anything +against anything, so what it names must be exact. + +Those two sentences are individually correct and together they close a door. The digest a pin means +is a *manifest* digest, and a manifest digest is **assigned by a registry when something is pushed +to it**. The control plane's image is built from source and pushed nowhere, so it has no such +digest, so it cannot be named — and a registry cannot be installed without a control plane to +install it. That is not a pin. It is a dependency the pinning rule created by accident. + +**It went unnoticed because the lab hid it.** The lab raised a disposable registry, stocked it from +a workstation, and rewrote every image reference to point at it — so the lab bootstrapped along a +path no real machine has. A first node in the lab always worked, and a first node anywhere else had +no path at all. Every bootstrap fault found this year was found late for the same reason: **the +install procedure existed only as a test fixture**, and a fixture is free to invent what it needs. + +## Considered Options + +**1. Publish the mesh's own images to a public registry.** Rejected on the premise: there is no +public registry for the mesh's modules and there is not meant to be. It would also make raising a +mesh depend on somebody continuing to host its code, which is the dependency the whole arrangement +exists to remove. + +**2. Build the control plane from source on the first machine.** Rejected. A bare machine would +need a toolchain and a working tree — and worse, the source lives in a forge **that runs on the +mesh**. A total rebuild would then need the mesh it is rebuilding. Acceptable for adding a node to +a healthy mesh; useless for the case that matters. + +**3. Keep a disposable registry as an install step.** Rejected. It exists in no production, and +concealing this problem is precisely what it has been doing. + +**4. Pivot through a temporary control plane.** Chosen. + +## Decision + +**An image may be named by the digest of its own configuration.** A bare `sha256:…` names an image +the machine already holds — content-addressed, immutable, unforgeable, and requiring nothing to +have served it. It satisfies what the pinning rule asks for; the rule simply never contemplated an +image that no registry had ever seen. It is legal exactly where nothing could have served one. + +**Genesis is a pivot**, in this order: + +1. the installer **carries the control-plane image** and loads it onto the machine +2. a **temporary** control plane is raised from it, named by that image's own digest +3. the **registry module is installed** — its image is upstream and it is never built, which + [`04-ISSUES/029`](../04-ISSUES/029-the-artifact-store-cannot-be-delivered-by-the-artifact-store/00-report.md) + already settled: a module that provides the artifact store cannot be delivered through it +4. the control-plane image is **pushed into the mesh's own registry**, which assigns it a manifest + digest — the first one it has ever had +5. the control plane is **reinstalled as an ordinary module** pinned to that digest + +**The host performs the replacement, not the control plane.** Tier 0 outlives tier 2: the control +plane composes a declaration naming the registry-pinned image, and the host applies it and recreates +the container. Nothing is asked to replace itself while running, and the control plane is stateless +— what it knows is in the store. + +**The installer is tier 0, and a separate program from the host.** Bootstrapping is by hand and +changes the machine, which is tier 0's definition. But the host states that it *connects to nothing +and listens on nothing*, and that claim is what makes the one thing running forever on every +machine auditable. An installer connects to plenty. Same tier, same delivery, different program. + +## Consequences + +- **The control plane stops being a special case.** It becomes an ordinary module with an ordinary + image in the mesh's own registry — so the mesh can build and roll out **its own upgrades**, which + is what a mesh that runs itself was always reaching for. +- **The bundle's job shrinks** to raising a temporary control plane exactly once. +- **The source builds the installer; it does not run it.** Cloning moves to a release machine, where + a forge being available is an ordinary working assumption, and leaves the disaster-recovery path + where it very much is not. +- **The lab's disposable registry is deleted.** The lab bootstraps by running the same program a + bare machine runs — the only arrangement in which the installer cannot quietly drift out of truth + again. +- **Two public images remain at genesis** — the store and the broker. An air-gapped install would + embed those too, at a much larger artifact; that is a build variant, not a different design. +- **A control-plane module manifest must exist**, and did not. +- **The handover is the sharp edge.** For one moment the bundle and the module both describe the + same container, and the host tracks what it owns. If a safe handover is not expressible with what + exists, the install **stops before it** and says what is missing. A machine left without a control + plane cannot be fixed remotely, so a partial install that halts cleanly is the better outcome. + +**How each is checked** — an unenforced rule is indistinguishable from a wrong one: + +- **Naming by its own digest:** a machine that can reach no registry at all raises a control plane. +- **The pivot completed:** after installing, the running control plane's image is pinned by a digest + **the mesh's own registry assigned** — not by an image id. If it is still the image id, the pivot + did not happen and the mesh cannot upgrade itself. +- **No fiction left in the lab:** the scenario declares no registry machine, and the bed bootstraps + through the installer rather than around it. +- **The handover:** a machine whose control plane has been replaced still has one, and it answers. + +## References + +- [ADR 0006 — the substrate and the control plane](0006-the-substrate-and-the-control-plane.md), + which pinned images by digest and named what a first node fetches. +- [ADR 0041 — the host depends on nothing that must be installed first](0041-the-host-depends-on-nothing.md), + the tier 0 property this keeps true by not putting the installer inside the host. +- [`04-ISSUES/029`](../04-ISSUES/029-the-artifact-store-cannot-be-delivered-by-the-artifact-store/00-report.md), + the same cycle one layer down, and the rule that a registry module is named and never built.