Files
hq/01-RESEARCH/018-the-operators-machine-as-modules/01-the-intended-behaviour.md
T
jochen 7fb59bde98 Research 018: the operator's machine as modules
The predecessor is retired on every node and what it still owned on the two
workstations — some thirty modules of dotfiles, user units and /etc files — is
owned by nothing. To-be 29 covers one directory under the home; the operator
wants the whole machine, system folders and home alike, as modules: one
default configuration each, varied per node by settings or a kept region,
never an edit; roles the machine has once as node-scoped seats with tool
contracts; the graphical stack gated by a capability so the same catalogue
serves the servers.

Four documents: the intended behaviour in the mesh's words; the predecessor's
desktop measured (34 modules, one with 88 files, 4 flavors and ~90 theme
variables) against what the records already give and what is missing (the
account is empty on every node, no user-scoped units, settings leak, tools run
in a container per module per node); the direction the operator set for where
tools run — one executor per node, host-side, module-agnostic, the console
renamed and moved out of its container, superseding 0047/0150 for tools; and
the candidate seats of the environment with first verbs, the shell first.
2026-10-02 15:19:25 +02:00

6.8 KiB
Raw Blame History

01 — The intended behaviour

Written 2026-10-02 from the operator's words, in the mesh's words. What is wanted, before what exists. Where a sentence restates a record, the record is named; where it goes further, that is said.

The machine is the mesh's

Everything configurable on a node is declared by a module. Not only the services the mesh runs: the login manager, the display server, the window manager, the bar, the launcher, the notifier, the compositor, the lock screen, the terminal emulator, the clipboard, the shell and its prompt, the editor, the audio setup, the boot images, the package manager's configuration, the agent a person runs at a terminal, and the folders a person works in — a downloads folder that is tidied, backed up, distributed to other nodes and asked questions of. System folders and the operator's home alike. The operator is the only person on every node, so the mesh manages the person's machine, not a machine with a person on it.

This is ADR 0040's definition applied without the service bias its examples carry. A module is one managed thing, named once, described completely by its manifest. It may have a package, files, a container, a unit, a binary, a seat it holds, and tools it serves — any one of these, or all, or two. There is no kind of module: zsh has a package, files, a seat claim and the tools that claim obliges it to serve; downloads has a folder, a process and tools; nftables has a package, files, a service, a seat and tools. The difference is what each declares, not what each is.

The home has no boundary. To-be 29 owns one directory under the home and draws a line inside it between the mesh's and the person's. Here the line is drawn only by what the modules declare: every file some module places is the mesh's; what no module declares is found and left alone, exactly as the adoption rules already say for a machine. The reach is bounded by sense, not by a rule — the mesh configures what can be configured, and a person's documents, projects and history are data under ADR 0051, not configuration.

A module names no node and no path. The operator account is a node fact and the home is derived from it (to-be 29 §1–2, shipped in the controller; its record is proposed in an open change). A module places a file under the home, owned by the account, and the same manifest lands on a server and a laptop.

One default, varied by settings, never by edits

One module, one default configuration. The window manager module ships the configuration that is right for every node. There are no flavors: the predecessor's one desktop module carried four, one per class of machine, and what differed between them is what settings are for.

A node varies a module in exactly two ways. A setting, declared by the module with its type, meaning and default (proposed alongside the container-runtime records), set for the mesh or for one node, and rendered into the file at composition — the value is in the file, not in an environment variable the file reads. Or a kept region: a block in a file the mesh writes into, where the operator's own lines survive every push (ADR 0102). An edit to a managed file outside such a region is not a third way; it is overwritten, as ADR 0011 says, and the predecessor's habit of adopting disk drift back into its database is not carried over.

The predecessor's theming — some ninety environment variables substituted into templates at sync time, with tools to list and set them — is the same idea with the wrong rendering. The knobs become declared settings; the file carries the value.

Roles a machine has once are seats, and seats carry tools

A role a machine fills at most once is a node-scoped seat, declared by a module (ADR 0121, ADR 0126): the login shell, the display session, the display server, the terminal emulator, the launcher, the notifier, the compositor, the lock screen, the service manager, the boot loader. Several modules may be able to hold one — zsh, fish and bash can all hold the login shell — and the assignment on each node says which does. Installing a shell is installing software; holding the seat is being the shell.

A seat's contract is its tools (ADR 0132). Every holder of the login-shell seat serves execute, which takes one string, the command, and runs it on the node the seat is scoped to. Every holder of the boot seat serves "rebuild the boot images", so "rebuild your boot images" is a verb addressed to a machine, not a one-off step in a hook. Every holder of the service-manager seat answers for the units on the machine, system and user scope. A module may serve its own tools beside the seat's (ADR 0170 §2): show the rendered configuration, set a theme value, report status.

Any tool may be called from any node. The operator's statement, and the grant model it implies: the executor on each node may call everything, as the console already may. A verb that needs root on the machine is the module's concern — the tool escalates, the executor and the caller do not know.

Servers and workstations differ by capability, not by catalogue

The same catalogue serves every node. A module declares what it needs — a graphical session, a display server, a container runtime — and the machine reports what it has, as the profile already reports eight capabilities today (issue 160). Assignment refuses the wrong placement by name (ADR 0161 §3). So every node takes the shell, the prompt, git and the agent; only a node with a graphical session can take the display server, and only a node holding the display server can take a window manager. Nothing in a module says "workstation".

What the operator would say to the mesh

Set the login shell on the build node to fish. Rebuild the laptop's boot images. Show me the window manager's effective configuration on the desktop and where each value comes from. Give the downloads folder on the laptop to the home server. Run uptime on every node. Each of these is a seat verb or a module tool, addressed to a node, answered by whatever holds the role there.