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 0c6b034f..af08a4e8 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 @@ -2,7 +2,7 @@ layer: to-be status: in-progress code: [mesh-catalog, mesh-controller, mesh-host] -updated: 2026-10-14 +updated: 2026-10-22 decisions: - "ADR 0369" - "ADR 0303" @@ -26,6 +26,9 @@ decisions: - "ADR 0164" - "ADR 0165" - "ADR 0166" + - "ADR 0507" + - "ADR 0508" + - "ADR 0510" --- # 42. The machines' modules, in order @@ -69,14 +72,14 @@ In order: | 1 | `sudo` | the operator account's escalation, as a drop-in it owns | declares what three modules' tools assume and nothing stated | | 2 | `localization` | locale, time zone, mesh MCP server keymap | one machine on another zone and keymap | | 3 | `time-sync` | timesyncd and its servers | two different daemons across four machines | -| 4 | `pacman` | the package manager's configuration, mirrors and their refresh, cache cleaning | mirrors generated once and never again; caches never cleaned | +| 4 | `pacman` | the package manager's configuration, mirrors and their refresh, cache cleaning; every node's packages on the bus; upgrades one node at a time, each with a package record, a held kernel, an after-upgrade check and a rollback (ADR 0507, ADR 0508) | mirrors generated once and never again; caches never cleaned; no view of which version runs where; every node upgraded at the same moment with no way back | | 5 | `logrotate` | the timer and base configuration | rotation running on one machine of four | | 6 | `avahi` | the daemon | on all four, owned by none | | 7 | `systemd` | the service manager's tools (to-be 41 WP4) | built, assigned nowhere | | 8 | `docker` | the runtime's packages, base configuration, group | four configurations, one owner on one machine | | 9 | `ssh-client` | everything under `~/.ssh` (research 027/03) | a predecessor's entries winning over the mesh's; stale keys | | 10 | scripts | the operator's own scripts, shared and per role (research 027/03) | under no version control, copied by hand | -| 11 | `kernel` | kernel, microcode, boot entries, and the kernel's run-time settings per machine (transparent huge pages first) | two machines without microcode; huge pages left at the distribution's `always` on a machine whose slow disks they flood (issue 746) | +| 11 | `kernel` | kernel, microcode, boot entries, the fallback kernel and its boot entry, and the kernel's run-time settings per machine (transparent huge pages first) | two machines without microcode; huge pages left at the distribution's `always` on a machine whose slow disks they flood (issue 746); only one machine with a fallback kernel | `systemd`, `pacman` and `docker` hold the three seats that apply resources (ADR 0207): @@ -101,6 +104,33 @@ mode in force and the file pages each unit holds in huge pages. `docker` holds t ADR 0164 decides and the capability detected as ADR 0165 decides; what of the three is not built yet is tracked by issue 398. +**Changed 2026-10-22** (ADR 0507, ADR 0508, ADR 0510; milestone issues 1840 and 1841). `pacman` gains a +process of its own on every node, the keeper, under an account of its own and a bus account of its own. It keeps +the node's installed packages and what an upgrade would change in the module's states, written only on change +(at its start, when the package manager's lock is released, when the mirror list is rewritten, and once a day), +and says each change as an event; the controller keeps the packages each node's modules declare, so the view +answers every node, one that is off included, and names the packages no module declares. Upgrades are runs on +the bus. The weekly timer of ADR 0477 §5, which upgraded every node at the same moment, is dropped. Instead the +nodes upgrade one at a time, in the order of the mesh-level key `upgrade-order`, each after the node before it +passed its after-upgrade check. With no order set no round starts, and every node's health says why. Before each +run a package record is taken and read back. A kernel that an installed DKMS module's own bound excludes is held +with its headers, and said. After each run the after-upgrade check names left configuration files, the +distribution's news, newly failed units, a restart needed, processes still mapping a replaced file and DKMS +modules not built for an installed kernel. A rollback returns a node to a record and says first what it would +change. Only the operator passes a node that stopped a round. The keeper never runs as root: the few acts that +need root go through a root-owned helper process with a closed list of verbs, on a socket only the keeper's +account opens (ADR 0510). The module's health is read from the bus, not from a unit's age. + +`kernel` gains the fallback kernel: `linux-lts` and its headers on every machine, with its boot entry on +whichever loader the machine boots with, read from the machine (systemd-boot or GRUB), the default entry left +untouched (ADR 0508 §9-§10, changing ADR 0381 §4). A hook found on a machine that copies every kernel image to +one fixed boot name is taken over: moved into the module's state and named, since it would put the fallback +kernel in the default entry's place. *How it is checked:* the modules' unit tests (the root helper refuses every +verb and argument off its list and every account but the keeper's; the round starts a node only after the one +before it passed; the boot-entry script in stand-in trees of both loaders), an integration test that runs the +keepers of two made-up nodes on a real bus, and, after the delivery, the view answering every node and every +boot menu listing the fallback kernel. + **Added 2026-10-04.** Two more modules for every machine: - `power` holds `node-power` (ADR 0211). Other modules contribute code for its moments (after boot, before sleep, after waking, before shutdown, on mains, on battery), and it