ADR 0215: the machine's message bus is a node seat, and it is never restarted live

This commit is contained in:
jochen
2026-10-05 11:33:20 +02:00
parent e51d6f1d86
commit d088f8ec2f
3 changed files with 77 additions and 1 deletions
@@ -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 |
+1
View File
@@ -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
@@ -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.