From 27c1db8a863edcf76456fbe140a0e47e98ac2be5 Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 2 Oct 2026 00:48:06 +0200 Subject: [PATCH] Review of 0164-0166 and 190: the mesh's own setting words stay settable; changing runtime verbs are not the console's wildcard; migration steps 1-2 are one push; dnsmasq's dns key dates from 09-23 --- ...-its-meaning-and-what-changing-it-costs.md | 8 ++++-- ...t-creates-containers-through-its-holder.md | 26 +++++++++++++------ .../00-report.md | 6 +++-- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md b/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md index 44a096e..6673420 100644 --- a/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md +++ b/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md @@ -81,14 +81,18 @@ it; a mesh-wide setting reaches every assignment of the module; a node's reaches change names each assignment whose effective value moves. **A declared setting is the only kind accepted.** Setting a key the module does not declare is refused -when it is set, naming the declared keys, rather than reported when the machine is planned. A module +when it is set, naming the declared keys, rather than reported when the machine is planned. The mesh's +own words — where a port, a directory or an operator's data is placed, how far an endpoint reaches — +are the mesh's to validate as they are today, and no module declares them. A module that declares no settings keeps today's behaviour until it does; a catalogue test lists those modules, and the list shrinks to empty before the implicit form is removed — design 27's rule for every retired mechanism. **A setting says what it costs: nothing, a reload, or a restart.** When a file changes, the host applies the strongest cost among the settings whose values moved in it, so a key the software reads -only at start can no longer be written and never read. A service's `reload-on` and `restart-on` keep +only at start can no longer be written and never read. A setting that reaches a container's environment +costs that container being recreated, which the host already does when a container's specification +changes; it needs no declaration. A service's `reload-on` and `restart-on` keep naming the files that are not settings — a generated roster, a credential. **The container runtime is the first module to declare its settings** and the model for the rest: diff --git a/02-DECISIONS/0166-the-container-runtime-is-a-node-seat-and-the-host-creates-containers-through-its-holder.md b/02-DECISIONS/0166-the-container-runtime-is-a-node-seat-and-the-host-creates-containers-through-its-holder.md index 396c27b..891962b 100644 --- a/02-DECISIONS/0166-the-container-runtime-is-a-node-seat-and-the-host-creates-containers-through-its-holder.md +++ b/02-DECISIONS/0166-the-container-runtime-is-a-node-seat-and-the-host-creates-containers-through-its-holder.md @@ -66,7 +66,12 @@ it and is assigned to every machine. A podman module may claim it later; one mac **The seat's verbs cover every container on the machine:** list, inspect, logs, stats, start, stop, restart, create and remove. A mesh-held container is marked by the host's label and says which -assignment holds it. **Creating or removing a mesh-held container is the host's alone.** Any other +assignment holds it. **A container the runtime runs can be root on the machine** — privileged, a host +path mounted, the host's network or process namespace, the runtime's own socket — so a caller other +than the host may not create one that is any of these; only a declaration the mesh composed may ask +for them. And the verbs that change anything are granted by name, never by a wildcard: a grant of +every tool (the console's today) reaches the reading verbs only. Issue 193 is what a verb that trusts +its caller costs. **Creating or removing a mesh-held container is the host's alone.** Any other caller is refused naming the assignment, because the host would undo it at its next apply. Starting, stopping or restarting one is allowed, and the answer says the host will restore what its declaration says. A container the mesh does not hold is the caller's to do anything with. @@ -105,13 +110,13 @@ adopt theirs ([ADR 0078](0078-the-store-and-broker-are-modules.md)). ## Consequences - **The migration on the running mesh has a fixed order:** - 1. The resolver module and the private network stop writing the runtime's file - ([issue 190](../04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md)). - The runtime module takes the same file in the same push. Otherwise the controller refuses two - modules declaring one path. - 2. The runtime module is assigned to every machine and adopts the runtime there. Each machine's - hand-written configuration is read before the first push, because the module's defaults - replace what differs. + 1. Each machine's hand-written configuration is read, because the module's defaults replace what + differs. + 2. In one push per machine: the resolver module and the private network stop writing the + runtime's file ([issue 190](../04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md)), + and the runtime module is assigned and adopts the runtime, its file and its service. Split in + two, either the controller refuses two modules declaring one path, or a machine is left with + nothing setting `dns` and `live-restore`. 3. The controller seeds the seat and enforces the container requirement. 4. The host releases the version that uses the holder. 5. The host's command-line path is removed in the release after every machine's holder answers. @@ -124,6 +129,10 @@ adopt theirs ([ADR 0078](0078-the-store-and-broker-are-modules.md)). tools cannot fall back to a container. - A user interface subscribing to events directly does not exist. Today a reader of events is a module that consumes them. The mesh's container view is a module, or waits for that path. +- [ADR 0005](0005-the-node-host.md) ("a container runtime is detected, not chosen") and + [ADR 0006](0006-the-substrate-and-the-control-plane.md)'s matching line describe the mechanism this replaces: on + acceptance, each gets a dated note saying the runtime is now a seat's holder, as the decision + records' rule for a moved mechanism requires. Design 05 and design 26 are amended after acceptance. - The operator's decision to remove the third-party interface by hand needs no mechanism. No module-retires-module rule is introduced. - **What got harder:** the host gains a dependency it did not have, and a first machine's bundle gains @@ -136,6 +145,7 @@ adopt theirs ([ADR 0078](0078-the-store-and-broker-are-modules.md)). |---|---| | The seat is the mesh's own, node-scoped, with its verbs and events | A catalogue test on the default seats; registration refuses a claimant that does not serve every verb (design 33's existing check) | | Creating or removing a mesh-held container is the host's alone | A test of the runtime module's verbs: create or remove of a container carrying the host's label, from any caller but the host's socket, is refused naming the assignment; the same verbs on an unlabelled container succeed | +| No caller but the host creates a container that is root on the machine | A test of `create` from the bus: privileged, a host path, the host's namespaces and the runtime's socket are each refused; the same request on the host's socket is accepted. A broker test: a grant of every tool does not reach a changing verb | | The host uses the holder and never the command line | A host test with a fake holder on the local socket: every container operation goes to it, and with the holder absent the apply creates nothing and reports the seat; after step 5, the host carries no command-line runtime code (checked by build: the package is gone) | | A container needs the seat held | A resolution test refusing a containerised assignment on a machine with the seat unheld, naming the seat | | Socket mounts are granted by the seat | A catalogue test: a module mounting the runtime's socket on a machine whose holder states a different path is refused | diff --git a/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md b/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md index aafa3c4..aef74d9 100644 --- a/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md +++ b/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md @@ -16,8 +16,10 @@ the runtime: - **The resolver module** writes the runtime's `dns` key (the machine's private address) and `live-restore` into the runtime's file, written into rather than over ([ADR 0102](../../02-DECISIONS/0102-the-mesh-writes-into-a-shared-file-never-over-it.md)). It also - declares the runtime's service, reloaded when that file changes. It was added on 2026-09-30 to - fix [issue 110](../110-a-container-on-the-runtimes-own-network-cannot-reach-the-resolver/00-report.md), + declares the runtime's service, reloaded when that file changes. The `dns` key has been written + since the resolver module was converted from its predecessor on 2026-09-23; `live-restore` and the + service were added on 2026-09-30 while fixing + [issue 110](../110-a-container-on-the-runtimes-own-network-cannot-reach-the-resolver/00-report.md), where containers silently resolved through a public resolver. - **The private network** writes the runtime's `insecure-registries` into the same file, and declares the same service reloaded on it, as [ADR 0082](../../02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md)