From 0d9208dbbff9c1971b41443eb58a1a139d045214 Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 2 Oct 2026 14:15:44 +0200 Subject: [PATCH] ADR 0172: the lab is a module, and runs a bed when the mesh asks --- ...odule-and-runs-a-bed-when-the-mesh-asks.md | 59 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + 03-DESIGN/01-to-be/04-lab-installation.md | 25 +++++++- 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md diff --git a/02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md b/02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md new file mode 100644 index 0000000..6649261 --- /dev/null +++ b/02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md @@ -0,0 +1,59 @@ +--- +topic: the mesh +status: accepted +date: 2026-10-02 +deciders: jochen +reconstructed: false +extends: 02-DECISIONS/0016-the-lab.md +--- + +# 172. The lab is a module, and runs a bed when the mesh asks + +## Context + +The lab raises virtual machines and runs the mesh on them, end to end, before a change reaches a real +machine ([ADR 0016](0016-the-lab.md)). It runs on one machine of the mesh, the one with the +virtualisation it needs. Until now the only way to start a bed there was to sign in to that machine and +run the lab's command line by hand, with a dozen environment variables pointing at sibling checkouts. + +Nothing in the mesh could ask for it. An agent working through the mesh's own tools could build, +merge and push a change, and could not prove it in the lab first. The operator's direction on +2026-10-02: work on another machine goes through a mesh tool, not a shell on it. + +## Considered Options + +1. **Keep the lab a command line on one machine.** Every run is a person, or an agent with a shell on + that machine, outside the mesh. +2. **The lab is a module.** Assigned to the machine that can run it, serving tools that run a bed + against named branches and say how it went. + +## Decision + +**Option 2.** + +- **A `lab` module, assigned where the lab can run**, serves five tools: whether this machine can run + beds, run beds against a branch per repository, a run's state, its log, and stopping it. +- **A run is the lab's own suite**, against fresh checkouts of the named branches from the mesh's forge, + side by side as the lab expects them. It builds what the beds place from those checkouts, as the suite + already does. It answers at once with an id, like a build: a bed takes minutes, and a call does not. +- **Only branches on the forge are run**, never code handed to the tool. What a run tested is what the + forge holds at the commit it names. +- **The lab is reached over the mesh only.** Its tools travel the bus, and the module opens no port. +- **No grant beyond the mesh's own.** Running a bed is root on the lab's machine, but anyone who can call + the mesh's tools can already do worse. The operator's judgement on 2026-10-02. + +## Consequences + +- An agent proves a change in the lab through the mesh, the same way it builds and pushes one. +- The lab's machine carries a module whose runtime holds the virtualisation's and the container + runtime's sockets, and a toolchain to build the mesh with. +- A run's checkouts are its own, so two runs never build from each other's tree. Old ones are removed + when their run ends. + +## How this is checked + +| Rule | Checked by | +|---|---| +| A run checks out exactly the named branches, and reports the commits it tested | the module's tests over a forge fixture, and each run's answer | +| A run answers at once, and its state and log follow it to the end | by hand, the first run | +| The module opens no port | the composed filter of the lab's machine | diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index 6da6144..847dac9 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -181,6 +181,7 @@ python3 00-META/checks/index.py fail if stale - **0168** — [A converged machine is filtered by the mesh alone, and the host says what else refuses](0168-a-converged-machine-is-filtered-by-the-mesh-alone.md) - **0169** — [A machine joins through the tunnel, and the bus is never public](0169-a-machine-joins-through-the-tunnel-and-the-bus-is-never-public.md) - **0169** — [The firewall seat serves its verbs, and a foreign rule set is removed through one of them](0169-the-firewall-seat-serves-its-verbs.md) +- **0172** — [The lab is a module, and runs a bed when the mesh asks](0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md) ### Its tiers, from the bottom up diff --git a/03-DESIGN/01-to-be/04-lab-installation.md b/03-DESIGN/01-to-be/04-lab-installation.md index 85c4f34..1bbd5c8 100644 --- a/03-DESIGN/01-to-be/04-lab-installation.md +++ b/03-DESIGN/01-to-be/04-lab-installation.md @@ -1,9 +1,10 @@ --- layer: to-be status: in-progress -code: [mesh-lab] -updated: 2026-09-11 +code: [mesh-lab, mesh-catalog modules/lab] +updated: 2026-10-02 decisions: + - 02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md - 02-DECISIONS/0016-the-lab.md - 02-DECISIONS/0010-delivery.md --- @@ -119,7 +120,25 @@ In order, on a machine with nothing: 6. **Verification**, as above, before anything is raised. -## Open +## The lab answers the mesh + +*2026-10-02* ([ADR 0172](../../02-DECISIONS/0172-the-lab-is-a-module-and-runs-a-bed-when-the-mesh-asks.md)). +Once installed, the lab is also a module: `lab`, assigned to the machine that passed `check`. Its +tools run there and nowhere else: + +| tool | does | +|---|---| +| `lab_check` | the lab's `check`, on this machine | +| `lab_run` | fresh checkouts of the named branches from the forge, side by side, then the suite on the named beds; answers with an id | +| `lab_status` | where a run is, and how it ended: the commits it tested, passed and failed | +| `lab_log` | the run's output so far | +| `lab_stop` | ends a run | + +The runtime is a container holding the toolchain the suite builds with. It reaches the +virtualisation daemon and the container runtime through their sockets on the machine, so what it +raises is what a hand run raises. The prerequisites above stay installed by hand. The module uses +them, and never installs them. + - **Whether the lab's bootstrap may install packages at all**, given that the mesh's rules forbid installing by hand. The resolution is probably that the lab's bootstrap *is* the