Files
hq/02-DECISIONS/0174-a-node-varies-a-module-through-settings-and-kept-regions-never-an-edit.md
T
jochen bf39baf104 Research 018 graduates: ADRs 0173–0177 and to-be 37, the operator's machine
Every configurable thing on a node is a module, the home included, and a
module is whatever it declares (0173, extending 0040). A node varies a module
only through a setting rendered into the file or a kept region, never an edit
(0174, extending 0011; issue 168 first). One tool runtime per node serves every
module's tools on the host side, never in a container; the console is its
serving mode, renamed node-tools (0175, extending 0150; 0047/0150/0152 carry
dated notes). The login shell is a node seat held by one shell module with
`execute` as its contract (0176). A unit may be user-scoped and the service
manager is a node seat held by systemd (0177).

To-be 37 is handed off in-progress to mesh-host, mesh-controller, mesh-tools
and mesh-catalog, with the build in order: the account on every node, the
runtime, zsh, systemd, then the graphical stack. To-be 29 keeps ~/.ssh and
points at 37; 33 §6 and 34 are amended; the glossary gains node tools, bundle,
kept region, installed/holding, and retires flavor.
2026-10-02 16:34:57 +02:00

5.3 KiB

topic, status, date, deciders, reconstructed, extends
topic status date deciders reconstructed extends
building it accepted 2026-10-02 jochen false 02-DECISIONS/0011-managed-files-are-generated-never-edited.md

174. A node varies a module through settings and kept regions, never through an edit

Context

ADR 0011 says a managed file is derived and an edit to it is overwritten without warning. The predecessor said the same and then undid it twice: a merge strategy that adopted disk drift back into its database, so a local edit became the record; and a theming layer of about 90 environment variables substituted into templates at sync time, with tools to list and set them, so that nearly every value was a variable — a second configuration language laid over the first.

The operator wants both the variation and the rule. One window-manager module with one default configuration, and each node tweaking it; and the file carrying the wanted value rather than a variable the file reads. Two mechanisms already exist for exactly this: a setting, declared by the module and set per mesh or per node, rendered at composition (${setting:…} is live in the resolver's manifest); and a kept region, a block in a file the mesh writes into where the operator's own lines survive every push (ADR 0102, used by the ssh-client module for the operator's own Host blocks).

What stands in the way is issue 168: a setting today reaches every mergeable file and every contribution of its module. Ninety theme knobs on that mechanism would reach ninety files. The record that fixes it — a setting declared with its type, meaning, default and the file it lands in — is proposed in an open change alongside the container-runtime records.

Considered Options

  1. Carry the predecessor's merge strategy. A local edit is adopted into the node's layer. Rejected: two writers and no arbiter, which is the option 0011 removed, and the reason a /model choice was silently reverted on every node for weeks before anyone found the cause.
  2. Carry the environment-variable theming. Rejected by the operator: the value belongs in the file; a variable the file reads is a second place for the same fact.
  3. A per-node file override — a whole file replaced for one node. Rejected: it is a flavor under another name, and a module update then misses that node entirely.
  4. Settings rendered into the file, and kept regions, and nothing else. Chosen.

Decision

A node varies a module in exactly two ways.

  • A setting. Declared by the module with a default, set for the mesh or for one node, rendered into the file at composition. The value is in the file. Asked, the mesh lists every setting with its effective value and where it came from.
  • A kept region. A marked block in a file the mesh writes into, in which the operator's own lines are kept across every push and given back when the module goes (ADR 0102).

An edit outside a kept region is overwritten, as ADR 0011 says, and never adopted. Nothing reads a managed file back into the record.

The predecessor's theme knobs become settings of the modules whose files they render — the window manager's colours are the window manager's settings, the bar's are the bar's — each landing in the file that reads it and no other.

Issue 168 is fixed before any environment module declares a setting. A setting must name the file it lands in; until that ships, the environment modules carry their defaults in their files and no settings.

Consequences

  • No flavors, no per-node file copies, no environment layer. A module's definition is one set of files; a node's difference is data in its layer, visible by asking.
  • The settings record proposed alongside the container-runtime records is on the critical path of every module with a knob, and this record depends on it shipping as proposed.
  • A kept region is the only place a person edits a managed file, and the file says where it is. The operator's own prompt customisations, aliases and window rules live there.
  • What got harder: a change that is neither a setting the module declared nor the operator's own lines has no home, and is refused by the mechanism rather than silently kept. That is the point.

How it is checked

Rule Checked by
A setting reaches only the file its declaration names the controller's settings tests, once the proposed record ships; issue 168 closes on it
A kept region survives a push with its content and is given back on undeclare the host's write-into tests (ADR 0102), with a region declared by an environment module
An edit outside a region does not survive a push the same tests, asserting the file equals the composed content outside the region
Every effective value names its source mesh-controller.settings and the module's own show-config tool

References