ADR 0203: the account's environment is one module's (seat node-environment); every module contributes variables and PATH entries, rendered by the controller as a POSIX file and as environment.d. ADR 0204: shell code is contributed to the login shell in named slots, and login-shell becomes the mesh's node-login-shell. ADR 0205: software the distribution does not package ships as a pinned archive of the module. Issue 225: undeclaring a user stops a node applying; the shell is never given back or checked. To-be 41 carries the work packages; to-be 38 WP5 points to it.
5.9 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
The mechanism changed — 2026-10-04, by ADR 0204. Where this record calls a kept region a marked block in which the operator's own lines are kept, read the inverse, which is what the host built: the mesh's region is the marked block, and every line outside it is the operator's, kept byte for byte and given back when the module goes. The decision stands: a node varies a module by settings and by the operator's own lines, never by 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
- 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
/modelchoice was silently reverted on every node for weeks before anyone found the cause. - 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.
- 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.
- 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
- Research 018 §"One default, varied by settings, never by edits"
- ADR 0011, ADR 0102, issue 168