diff --git a/04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md b/04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md index 2e7eec4..ba0525a 100644 --- a/04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md +++ b/04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md @@ -129,3 +129,12 @@ as `${setting:}` in the file the software reads **The check that notices the next one** is the shape of the value, as this record guessed it would be, and it is more than nothing: it found forty-two, and the catalogue passes it now ([issue 134](../134-a-definition-may-still-name-the-mesh/00-report.md)). + +**What the rollout cost, 2026-09-30 evening.** The site module's rename from its domain to `website` +was a new module to the mesh, and two things the old assignment carried by name were lost: the +container still named the old network, and a port setting on the old assignment had hidden that +`listens` said one port while the container published another. The site answered 502 for about +twenty minutes across two one-line fixes (mesh-catalog PRs 190, 191). A module's rename is an +unassign and an assign, and everything the assignment held — settings, ports, its directory — is the +new module's to get again; the mesh says nothing about that today. The mail module's settings turned +out to reach every fact it contributes, which is [issue 173](../173-a-modules-settings-reach-every-fact-it-contributes/00-report.md). diff --git a/04-ISSUES/173-a-modules-settings-reach-every-fact-it-contributes/00-report.md b/04-ISSUES/173-a-modules-settings-reach-every-fact-it-contributes/00-report.md new file mode 100644 index 0000000..da113f7 --- /dev/null +++ b/04-ISSUES/173-a-modules-settings-reach-every-fact-it-contributes/00-report.md @@ -0,0 +1,47 @@ +--- +status: located +opened: 2026-09-30 +located-in: [mesh-controller internal/catalogue/settings.go (settle), mesh-controller internal/catalogue/declaration.go (composed, ownNames)] +fixed-by: +amended-design: +--- + +# 173 — A module's settings reach every fact it contributes, not only the file that asked + +## What was observed + +Setting the mail module's operator values — `domain`, `sitename`, `website`, `proxy-address` — so that +its environment file could read them as `${setting:…}` +([ADR 0155](../../02-DECISIONS/0155-a-definition-names-no-installation-and-how-that-is-checked.md)), +and then planning the control node, showed the four keys in places nothing asked for them: + +- in every **route** the module contributes to the proxy, beside `label`, `endpoint` and `port`; +- in the **database** it contributes to the store's provider, beside the database's `name`; +- in the `smtp` facts every **consumer** of its mail provision is bound to. + +Nothing broke: a provider ignores a key it does not read. But a proxy now receives a mail server's +`proxy-address` and `website` as if they were route facts, a consumer of mail is told the site's name, +and a reader of `plan` cannot tell which of a contribution's keys the module meant and which leaked in. + +## Why this is here + +Settings are one flat map per module, laid over every mergeable file, every contribution and every +served fact alike (`settle`). That was the right generality when a setting *was* a contribution's +override — a route's label is the example the code gives. It stops being right the day a setting is +an operator's value for one file, which ADR 0155 made ordinary. The design permits a value to travel +where nobody sent it, silently, and every consumer of a provision reads a map that grows with the +provider's unrelated settings. + +[ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md) and design 27 +already say where this ends: a requirement has a contract, and a value goes to the requirement that +asked for it. Until that form exists, this is the cost of the placeholder being the first case of it. + +## Open questions + +- Should a key a file asks for with `${setting:}` be withheld from contributions and served + facts, or should a contribution's overrides live under their own key (`contributes`, `serves`)? + The second is the shape design 27 draws; the first is the smaller change and keeps the leak from + widening while it is drawn. +- What does a consumer do with a served key it did not expect? Today: nothing, silently. A served + map is not checked against what the provision's contract says it carries, because there is no such + contract yet.