From d088f8ec2fab23c90e4776714500dada2f26ec2f Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 5 Oct 2026 11:33:20 +0200 Subject: [PATCH] ADR 0215: the machine's message bus is a node seat, and it is never restarted live --- ...a-node-seat-and-is-never-restarted-live.md | 74 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + .../42-the-machines-modules-in-order.md | 3 +- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md diff --git a/02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md b/02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md new file mode 100644 index 0000000..ecc36cb --- /dev/null +++ b/02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md @@ -0,0 +1,74 @@ +--- +topic: what runs on it +status: accepted +date: 2026-10-05 +deciders: jochen +reconstructed: false +extends: 02-DECISIONS/0212-a-seat-says-what-it-receives-and-the-machines-hotkeys-are-a-seat.md +--- + +# 215. The machine's message bus is a node seat, and it is never restarted live + +## Context + +Every machine runs a D-Bus system bus, and the workstations a session bus per login. The service +manager, logind, the network manager, the Bluetooth stack, the GPU switcher, the keyring, the +desktop portal and the power module's sleep lock all speak on it. Nothing in the mesh owned it. + +On 2026-10-04 a full upgrade on a workstation restarted the system bus in the middle of the upgrade. +From then on logins hung, sshd answered nothing, and the machine's host stopped reporting, until a +person rebooted it at its keyboard. The mesh had no record of what the bus is, no view of it, and no +rule about when it may restart. + +## Considered Options + +1. **Leave the bus to the distribution.** Rejected: the outage above is what that gives, and nothing + would ever say the bus is unwell. +2. **Make it part of the service manager's holder.** Rejected: the bus is a separate program with its + own policy, its own clients and its own failure. A machine can have a healthy service manager and + a wedged bus, which is exactly what happened. +3. **A node seat held by a `dbus` module.** Chosen. + +## Decision + +**1. `node-message-bus` is a node seat in the mesh's own set.** Every machine has one. The first +holder is a module named `dbus`, which owns the bus implementation's package and its system +service, and serves tools to look at both buses. + +**2. The bus is never restarted live.** The holder declares the bus running and enabled, and never +restarts or reloads it on any change. A new version of the bus takes effect at the machine's next +boot. A module's change that needs the bus to pick up a policy uses the bus's own reload of policy +files, which keeps every connection, never a restart. + +**3. Curated events, never traffic.** The holder publishes on the mesh's bus only what matters about +the machine's bus: +- the bus's health (up, stalled, restarted); +- a well-known system service appearing on the bus or leaving it; +- a policy denial. + +The bus's traffic, which carries secrets, notification text and the clipboard, never leaves the +machine. The holder's tools let a person watch it, bounded in time, on request. + +**4. The seat receives nothing yet.** Packages ship their own D-Bus policy and service files, and no +module writes one of its own today. When one does, it is a contribution to this seat (ADR 0210, ADR +0212), and the seat lists the kind then. + +## Consequences + +- Phase 1 of [to-be 42](../03-DESIGN/01-to-be/42-the-machines-modules-in-order.md) gains `dbus` on + every machine. +- A full upgrade that brings a new bus no longer breaks a running machine through the mesh. The + distribution's own upgrade still restarts it, so the rule is enforced only for what the mesh + does. The holder's check says whether the running bus is older than the installed package, which + is the sign that a reboot is due. +- **What got harder:** a fix to the bus itself waits for a reboot. That is the price of never taking + every login on the machine down with it. + +## How it is checked + +| Rule | Checked by | +|---|---| +| `node-message-bus` is a node seat of the mesh's own set | the seat table's tests | +| The bus's service is declared running and enabled, with no restart or reload trigger | the dbus module's manifest test | +| No traffic is published, only the curated events | the dbus module's tests over its event code | +| A bus older than its installed package is said | the dbus module's check, over a recorded answer | diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index 39eb267..4e6ea34 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -314,6 +314,7 @@ python3 00-META/checks/index.py fail if stale - **0211** — [A machine's power is a node seat, its moments take contributions, and its states are events](0211-a-machines-power-is-a-node-seat-its-moments-take-contributions-and-its-states-are-events.md) - **0213** — [The operator sets the agent's managed settings through the agent module, under the mesh's own keys](0213-the-operator-sets-the-agents-managed-settings-through-the-agent-module.md) - **0214** — [Backups guard against mistakes, stay on the machine, and are declared by the module that owns the data](0214-backups-guard-against-mistakes-and-stay-on-the-machine.md) +- **0215** — [The machine's message bus is a node seat, and it is never restarted live](0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md) ### How it is built diff --git a/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md b/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md index c9c9627..c798be9 100644 --- a/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md +++ b/03-DESIGN/01-to-be/42-the-machines-modules-in-order.md @@ -4,6 +4,7 @@ status: in-progress code: [mesh-catalog, mesh-controller, mesh-host] updated: 2026-10-04 decisions: + - 02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md - 02-DECISIONS/0173-the-operators-machine-is-the-meshs-and-a-module-is-what-it-declares.md - 02-DECISIONS/0040-what-a-module-is.md - 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md @@ -83,7 +84,7 @@ until ADRs 0165 and 0166 are accepted. - `power` holds `node-power` ([ADR 0211](../../02-DECISIONS/0211-a-machines-power-is-a-node-seat-its-moments-take-contributions-and-its-states-are-events.md)). Other modules contribute code for its moments (after boot, before sleep, after waking, before shutdown, on mains, on battery), and it publishes the machine's power states on the bus. -- `dbus` holds the message bus. Modules shipping D-Bus policies or services contribute them to it. +- `dbus` holds `node-message-bus` ([ADR 0215](../../02-DECISIONS/0215-the-machines-message-bus-is-a-node-seat-and-is-never-restarted-live.md)). Modules shipping D-Bus policies or services contribute them to it. It shares curated events, never raw traffic. An upgrade never restarts the bus live: its package waits for a reboot. A live restart in the middle of a full upgrade took down a workstation's logins on the day this was written.