0066 was proven on a four-node bed before it was ratified: one node setting moved an entire domain, a routed name resolved inside the mesh and was issued a certificate by the internal authority, and TLS verified against that authority with no override. 08-connectivity rests on it and could not while it was proposed. 0067 records what deleting the lab's registry exposed — that pinning quietly required a registry before the thing that lets a mesh have a registry could start — and the pivot that resolves it. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
130 lines
8.1 KiB
Markdown
130 lines
8.1 KiB
Markdown
---
|
|
topic: the tiers
|
|
status: accepted
|
|
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 registry may require nothing.**
|
|
[`04-ISSUES/029`](../04-ISSUES/029-the-artifact-store-cannot-be-delivered-by-the-artifact-store/00-report.md)
|
|
states that a module providing the artifact store may not *build* artifacts, because there is
|
|
nowhere to put them until it runs. The pivot shows that is the narrow case of a wider rule: **it
|
|
may not require anything the store is needed to deliver.** Found the hard way — an unrelated
|
|
change gave the registry a public name and, with it, a route requirement. At genesis nothing
|
|
provides a route, and nothing can, because the routing stack needs images and images need the
|
|
store. The same cycle, re-entered through a door the existing wording did not cover.
|
|
- **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.
|
|
- **The registry requires nothing:** its manifest is resolvable on a mesh that has no other module
|
|
in it. A requirement added to it later is caught where it is written, rather than by a genesis
|
|
that cannot complete — which is how this one was found.
|
|
|
|
## 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 0005 — the node host](0005-the-node-host.md), which makes tier 0 the one thing installed by
|
|
hand and the only thing that changes a machine — the property this keeps true by shipping the
|
|
installer beside the host rather than inside it.
|
|
- [`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.
|