Amend design 42 for the package view, one-at-a-time upgrades and the fallback kernel (ADR 0507, ADR 0508, ADR 0510; issues 1840, 1841)
mesh/repo-check head 333e73830c31 merged into trunk 93963aeb5189 beside mesh-catalog#450@86ba54b0 +1 more — pass: its merge-check.sh passed
mesh/merge-gate head 333e73830c31 merged into trunk 93963aeb5189 — pass: group feat/upgrade-safety composed: every machine composes with the change as it d…
mesh/delivery delivered
mesh/delivery-group group feat/upgrade-safety delivered: every member is delivered

This commit is contained in:
2026-10-22 17:41:15 +02:00
parent 58555ec330
commit 333e73830c
@@ -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