Genesis clones from a mesh, and checks what it got #35
@@ -0,0 +1,80 @@
|
|||||||
|
---
|
||||||
|
topic: the tiers
|
||||||
|
status: accepted
|
||||||
|
date: 2026-09-12
|
||||||
|
deciders: jochen
|
||||||
|
reconstructed: false
|
||||||
|
extends: 0070-the-catalogue-owns-the-module-graph.md
|
||||||
|
---
|
||||||
|
|
||||||
|
# 71. Genesis clones from a mesh, and checks what it got
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
**[ADR 0070](0070-the-catalogue-owns-the-module-graph.md) has the init builder clone the source,
|
||||||
|
and does not say from where.** [ADR 0067](0067-genesis-is-a-pivot.md) had already rejected building
|
||||||
|
at genesis partly for that reason: the forge holding the source runs *on* the mesh, so a total
|
||||||
|
rebuild would need the mesh it is rebuilding.
|
||||||
|
|
||||||
|
That objection is real but narrower than it reads. It only binds when the mesh being raised and the
|
||||||
|
mesh holding the source are the same one, which is true exactly once.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
**Genesis clones from a mesh's forge, reached by name.** Any mesh that holds the source can serve
|
||||||
|
it. The first mesh is not structurally special — it is simply the only one that existed when there
|
||||||
|
was nothing else to clone from.
|
||||||
|
|
||||||
|
**If the mesh serving the source is lost, the name moves to another mesh that holds a copy.**
|
||||||
|
Recovery is a name pointing somewhere else, not a backup being restored. This is what makes the
|
||||||
|
source's survival a property of there being more than one mesh, rather than a property of somebody
|
||||||
|
having remembered to take a copy. A mesh that has installed from that name holds the source
|
||||||
|
afterwards, so every installation adds a place the name could point.
|
||||||
|
|
||||||
|
**Genesis names a commit and checks what it got.** It does not clone whatever a branch happens to
|
||||||
|
point at. The forge a mesh installs from is the trust anchor for everything that mesh will ever
|
||||||
|
run, and a branch is a moving target that somebody else controls.
|
||||||
|
|
||||||
|
*This is not hypothetical.* On 2026-09-11 the forge that would serve this role was running a
|
||||||
|
cryptominer, and its git operations were being tampered with in flight — output injected into the
|
||||||
|
protocol stream by a hook that fired on every fetch. Nothing was altered: the repositories were
|
||||||
|
verified against local copies and found byte-identical. But a mesh installing from that name during
|
||||||
|
those hours had no way to establish that for itself, and would have had none.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
The init builder needs a name it can resolve and a commit it can verify, and nothing else. It does
|
||||||
|
not need to know which mesh answers.
|
||||||
|
|
||||||
|
Whoever operates the mesh that name points at carries a responsibility to everyone installing from
|
||||||
|
it, and should know that. It is not merely a convenience host.
|
||||||
|
|
||||||
|
A mesh that cannot reach any forge cannot be raised. That is a real limit and it is accepted: the
|
||||||
|
alternative is carrying the whole source in the installer, which makes the installer a release
|
||||||
|
artifact that goes stale rather than a program that fetches what it was told to.
|
||||||
|
|
||||||
|
## Open — what relationship a mesh keeps afterwards
|
||||||
|
|
||||||
|
**Not decided, and named here so it is not decided by accident** by whoever writes the init
|
||||||
|
builder. Two shapes, and they are meaningfully different:
|
||||||
|
|
||||||
|
**A snapshot, and then independence.** A mesh installs once, mirrors the source into its own forge,
|
||||||
|
and has no upstream afterwards. It is fully self-hosted, in the sense that nothing it needs lives
|
||||||
|
anywhere else. Updates are then something an operator does deliberately, by pulling changes in —
|
||||||
|
tooling for which is possible and is not a priority.
|
||||||
|
|
||||||
|
**A continuing upstream for core modules**, the way a distribution serves packages and a separate
|
||||||
|
collection serves everything else. A mesh keeps looking at the origin for the modules that make a
|
||||||
|
mesh a mesh, and holds its own for the rest.
|
||||||
|
|
||||||
|
The first is more obviously aligned with the rest of this design, which is arranged so nothing a
|
||||||
|
mesh needs depends on somebody else continuing to host it. The second is more convenient and makes
|
||||||
|
a security problem in one forge everybody's problem. Neither is chosen here.
|
||||||
|
|
||||||
|
## How this is checked
|
||||||
|
|
||||||
|
| Rule | Checked by |
|
||||||
|
|---|---|
|
||||||
|
| Genesis needs only a name and a commit | A mesh is raised with the name pointed at a different mesh than the last time, and the result is identical. |
|
||||||
|
| What was cloned is what was asked for | Genesis is pointed at a commit and refuses a forge serving different content under it, rather than building what it received. |
|
||||||
|
| Losing the serving mesh is survivable | The name is repointed at a mesh that installed from it earlier, and a raise succeeds. |
|
||||||
@@ -103,6 +103,7 @@ python3 00-META/checks/index.py fail if stale
|
|||||||
- **0068** — [The lab takes requests, one at a time, and runs each from its own copy](0068-the-lab-takes-requests.md) *(proposed)*
|
- **0068** — [The lab takes requests, one at a time, and runs each from its own copy](0068-the-lab-takes-requests.md) *(proposed)*
|
||||||
- **0069** — [A module is a repository and a path within it](0069-a-module-is-a-repository-and-a-path.md)
|
- **0069** — [A module is a repository and a path within it](0069-a-module-is-a-repository-and-a-path.md)
|
||||||
- **0070** — [The catalogue owns the module graph, and genesis builds rather than carries](0070-the-catalogue-owns-the-module-graph.md)
|
- **0070** — [The catalogue owns the module graph, and genesis builds rather than carries](0070-the-catalogue-owns-the-module-graph.md)
|
||||||
|
- **0071** — [Genesis clones from a mesh, and checks what it got](0071-where-genesis-gets-its-source.md)
|
||||||
|
|
||||||
### What runs on them, and how it gets there
|
### What runs on them, and how it gets there
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user