From 24a51a8e53b78009a1694207d80754cced25e6aa Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 4 Oct 2026 01:41:30 +0200 Subject: [PATCH] ADR 0200: genesis pivots to the controller as a container, and the first push hands it to a process --- ...nd-the-first-push-hands-it-to-a-process.md | 78 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + .../00-report.md | 8 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 02-DECISIONS/0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md diff --git a/02-DECISIONS/0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md b/02-DECISIONS/0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md new file mode 100644 index 0000000..a07de16 --- /dev/null +++ b/02-DECISIONS/0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md @@ -0,0 +1,78 @@ +--- +topic: building it +status: accepted +date: 2026-10-04 +deciders: jochen +reconstructed: false +extends: 02-DECISIONS/0067-genesis-is-a-pivot.md +--- + +# 200. Genesis pivots to the controller as a container, and the first push hands it to a process + +## Context + +The controller is Go, compiled to one static binary, and is the last of the mesh's own programs a +machine runs from an image ([issue 213](../04-ISSUES/213-the-controller-is-a-go-program-run-in-a-container/00-report.md)). +[ADR 0188](0188-a-modules-own-code-is-bundles-in-any-language-and-a-tools-bundle-speaks-mcp-to-the-runtime.md) +§1 says a module's own code is bundles, never an image, and §3 that a service bundle is a `process` the +host runs. The handover exists: a process may name the container it `replaces`, and the host removes +that container only after the process has stayed up across two checks; two controllers are safe +together for that moment, the second standing by on the controller's consumers and every plan held by +one lock. + +What stands in the way is genesis ([ADR 0067](0067-genesis-is-a-pivot.md)), which +[issue 223](../04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md) found +assumes an image and a container at every step from its third: it builds the controller's image, +starts a temporary controller from it, publishes it, finds the controller's container in the pivot +declaration, and from then on talks to the controller through it. A process's bundle is fetched from +the artifact store, and genesis raises the artifact store only after the pivot. + +## Considered Options + +1. **Raise the artifact store before the pivot**, publish the controller's bundle to it, and talk to + the controller from the host's side. Rejected for now: it reorders genesis around a store that is + itself a module the controller deploys, and rewrites the steps that talk to the controller — a + larger change to the one path that is exercised least, to remove a container that exists for + minutes. +2. **Pivot to the controller as a container, as today, and let the first push hand it over to the + process**, through the handover that already exists. Chosen. +3. **Keep the controller a container.** Rejected: it is the exception to ADR 0188 that every other + module's code has now left, and it costs a container runtime on the control machine and a + container recreation in the middle of a plan. + +## Decision + +**Genesis raises the controller as a container, under the resource the controller's process +`replaces`, and the first declaration the controller composes for its own machine hands it over.** +The container is genesis's own shape, built from the controller's repository, and is recorded on the +control machine exactly as the manifest's `replaces` names it, so the first apply after the pivot +finds a replacement for it and removes it once the process is up. The controller's manifest declares +only the process; the image form exists for genesis alone and is not a second way to run the +controller on a live mesh. + +This is the one bounded exception to ADR 0188 §1: a module's own code in an image, for the minutes +between the pivot and the first push, on a mesh being created. + +## Consequences + +- A new mesh ends where a running one is: the controller a process, no controller container. +- Genesis keeps its steps; what changes is that it no longer reads the controller's container from the + manifest, and that it records the container under the name the handover expects. +- The controller's repository keeps its image build for genesis and the lab. +- The handover is now on genesis's path too: a process that fails to stay up leaves the genesis + container serving, and the apply says so — the same rule as on a live mesh. + +## How it is checked + +The installer's test raises a mesh whose controller manifest is the process form, and asserts that the +container genesis recorded is exactly what the process `replaces`, so the first apply hands over and +leaves one controller. Live, on the running mesh: after the manifest change is pushed, the control +machine runs the controller as a process and no controller container, and the controller's seat +answers throughout. + +## References + +- [Issue 213](../04-ISSUES/213-the-controller-is-a-go-program-run-in-a-container/00-report.md), + [issue 223](../04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md) +- mesh-host#86 (the handover), mesh-controller#252 (two controllers safe together), + mesh-controller#253 (the controller's manifest as a process) diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index c645d64..29a22b0 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -320,6 +320,7 @@ python3 00-META/checks/index.py fail if stale - **0111** — [A build source is on the mesh's git seat, or it is an external repository](0111-a-build-source-is-on-the-git-seat-or-external.md) - **0149** — [The live mesh is the test bed](0149-the-live-mesh-is-the-test-bed.md) - **0174** — [A node varies a module through settings and kept regions, never through an edit](0174-a-node-varies-a-module-through-settings-and-kept-regions-never-an-edit.md) +- **0200** — [Genesis pivots to the controller as a container, and the first push hands it to a process](0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md) ### How it is checked diff --git a/04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md b/04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md index 4272aac..1ea570c 100644 --- a/04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md +++ b/04-ISSUES/223-a-new-mesh-installs-its-controller-as-a-container/00-report.md @@ -1,5 +1,5 @@ --- -status: open +status: located opened: 2026-10-04 located-in: - mesh-host @@ -40,3 +40,9 @@ Until it is settled, the change of the controller's manifest (mesh-controller#25 handover itself is built and merged (mesh-host#86); the controller's half (mesh-controller#252) waits on the operator. **How it is checked:** the installer's test raises a mesh whose controller manifest is the process form, and the controller answers its seat's verbs at the end. + +## Decided (2026-10-04) + +Option 2, [ADR 0200](../../02-DECISIONS/0200-genesis-pivots-to-the-controller-as-a-container-and-the-first-push-hands-it-to-a-process.md): +genesis pivots to the controller as a container recorded under the name the process `replaces`, and +the first push hands it over. -- 2.54.0