From 17ca9a262b1b2bb0b17e74a2b1a12cb02659c326 Mon Sep 17 00:00:00 2001 From: jochens Date: Fri, 2 Oct 2026 12:23:28 +0200 Subject: [PATCH] 0164: a setting names the file it lands in (issue 198's leak between one module's files); 190 notes the fourth machine now has the resolver --- ...-default-its-meaning-and-what-changing-it-costs.md | 11 +++++++++++ .../00-report.md | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md b/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md index 6673420..f1caeda 100644 --- a/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md +++ b/02-DECISIONS/0164-a-setting-is-declared-with-its-default-its-meaning-and-what-changing-it-costs.md @@ -40,6 +40,12 @@ What was built is narrower than what was decided, measured in the controller on layer sets it — right for a mail domain, where a default is the very literal 0155 removes, and wrong for a tunable like the resolver's upstreams, which the resolver module therefore carries as literals in its file. +- **A setting reaches every mergeable file its module owns.** The layers are one flat map per module, + laid over each such file. Adding a setting to the resolver module for its own configuration put the + key into the container runtime's file as well — the resolver writes into that file too — and the + runtime refuses keys it does not know. The plan showed it before any push; the runtime's file was + then made to take no settings at all ([issue 198](../04-ISSUES/198-the-lans-dns-server-ran-outside-the-mesh-and-its-filter-closed-it/00-report.md)). Issue 173 stopped settings leaking into + contributions and served facts; between one module's own files the leak remains. - **What a change costs is said per file, not per key.** A service names the files it is reloaded or restarted on. The runtime re-reads its trusted registries on a reload and its `dns` key only when it starts; the resolver module declared a reload, so on two machines the key was written, reloaded, @@ -80,6 +86,10 @@ A new default ships with the module's next version and reaches every assignment it; a mesh-wide setting reaches every assignment of the module; a node's reaches one. The plan of a change names each assignment whose effective value moves. +**A declared setting says where it lands.** Each names the file or files of its module that read it, +and reaches no other: a module that owns two mergeable files no longer has one flat map laid over both. +A file that names no setting takes none. + **A declared setting is the only kind accepted.** Setting a key the module does not declare is refused when it is set, naming the declared keys, rather than reported when the machine is planned. The mesh's own words — where a port, a directory or an operator's data is placed, how far an endpoint reaches — @@ -121,6 +131,7 @@ its trusted registries are what the mesh tells it. |---|---| | Every setting a module takes is declared | A parser test refusing a setting declaration without a type or meaning; a catalogue test listing modules with mergeable files or `${setting:}` and no declarations, which must be empty before the implicit form is removed | | A tunable resolves to its default; an operator value without one is refused | Resolution tests: an unset tunable in a JSON file and in a text file both take the default; an unset setting with no default is refused naming it (0155's existing test) | +| A setting reaches only the files it names | A resolution test: a module with two mergeable files and a setting declared for one; the other file's content is unchanged by it (the case of issue 198) | | An undeclared key is refused when set | A controller test: `settings set` with an undeclared key fails naming the declared keys, and nothing is stored | | Every effective value names its source | A test listing a module's configuration on a node with one key from each of default, mesh and node | | A change's reach is shown before it moves | A plan test: changing a mesh-wide setting names every assignment whose effective value moves and no other | diff --git a/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md b/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md index aef74d9..c8769e4 100644 --- a/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md +++ b/04-ISSUES/190-the-runtimes-configuration-is-written-by-modules-that-are-not-the-runtime/00-report.md @@ -33,6 +33,13 @@ The machine without the resolver module shows the other half. Its runtime still resolver and `live-restore` off, because the only module that sets them is a DNS server. A machine gets a correct container runtime only as a side effect of being given a resolver. +> **Later the same day, 2026-10-02.** The resolver module and its sibling for the resolver file were +> assigned to the fourth machine ([issue 198](../198-the-lans-dns-server-ran-outside-the-mesh-and-its-filter-closed-it/00-report.md)), +> so all four now have the resolver writing into the runtime's file, and the predecessor's +> `live-restore: false` there is gone. The same work made the runtime's file, as the resolver declares +> it, take no settings: a setting meant for the resolver's own configuration had reached it. The +> collision and the ownership question above are unchanged. + ## Why this is here The operator ruled it a defect, not a design: **a module does not write another software's