From 72b0810c530edee014b543229db24b8fe6894086 Mon Sep 17 00:00:00 2001 From: jochen Date: Sat, 12 Sep 2026 22:19:41 +0200 Subject: [PATCH] Genesis clones from a mesh, and checks what it got MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR 0070 has the init builder clone the source and does not say from where, and ADR 0067 had rejected building at genesis partly because the forge runs on the mesh being rebuilt. That objection binds only when those are the same mesh, which is true exactly once. So genesis clones from a mesh by name, and if that mesh is lost the name moves to another that holds a copy — recovery is a name pointing elsewhere rather than a backup being restored, and every installation adds somewhere it could point. It names a commit and checks what it got, because the forge a mesh installs from is the trust anchor for everything that mesh will run. On 2026-09-11 that forge was running a cryptominer and tampering with git operations in flight; nothing was altered, but a mesh installing during those hours could not have known that. What relationship a mesh keeps afterwards is left open and named, so that whoever writes the init builder does not settle it by accident: a snapshot and then independence, or a continuing upstream for core modules. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx --- .../0071-where-genesis-gets-its-source.md | 80 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + 2 files changed, 81 insertions(+) create mode 100644 02-DECISIONS/0071-where-genesis-gets-its-source.md diff --git a/02-DECISIONS/0071-where-genesis-gets-its-source.md b/02-DECISIONS/0071-where-genesis-gets-its-source.md new file mode 100644 index 0000000..6ebb201 --- /dev/null +++ b/02-DECISIONS/0071-where-genesis-gets-its-source.md @@ -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. | diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index fc67ee1..499fddd 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -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)* - **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) +- **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 -- 2.54.0