A setting overrides a key a contribution or served fact declares and adds none; a provider that must
tell its consumers an operator's value declares it as ${setting:…} (173). The mesh's own files for a
module are a placed directory, `place: "mesh"`, and forty-eight definitions name no host path for
them (174). Registration refuses a definition naming an installation, the day the list emptied
rather than a release later (0155, progressive insight; 134). Designs 27 and 18 carry the rules.
4.6 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | |||
|---|---|---|---|---|---|---|---|
| resolved | 2026-09-30 |
|
mesh-controller PR 175 (a setting overrides a declared key and adds none; `${setting:…}` in a served or contributed value); mesh-catalog PR 196 (mail declares its domain, the identity provider its issuer) | 03-DESIGN/01-to-be/27-a-module-requires-the-mesh-resolves.md |
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),
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,endpointandport; - in the database it contributes to the store's provider, beside the database's
name; - in the
smtpfacts 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 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:<key>}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.
Resolved, 2026-09-30
A setting overrides a key a contribution or a served fact declares, and adds none. A file keeps
taking any key, because a configuration file is where an operator adds things; a contribution and a
served fact are a contract the other side reads, and a setting made for one of the module's files is
no part of it. A key that lands nowhere — no mergeable file, no ${setting:…} asking for it, no
contribution or served fact declaring it — is named as stray when the node is planned, rather than
dropped.
The first open question is answered the smaller way, and it turned out to be the right one: the two
keys consumers actually read through the leak — the mail provider's domain, the identity provider's
issuer — are now declared by the provider in what it serves, as the operator's value
(${setting:domain}, ${setting:issuer}), filled from the same setting that used to leak and refused
by name when nothing sets it. So the contract says what travels, which is the shape design 27 draws,
without a second key for overrides. The second question stands: a consumer still checks nothing
against a contract, because there is none yet; what it is told is now only what the provider
declared.
How it was checked: the plans of all four nodes, under the running controller and the one with the
rule, compared resource by resource — every key that disappears from a contribution is a leaked file
setting or one of the mesh's own words (expose, endpoints), and nothing a provider reads goes
away; the two served keys were declared before the controller rolled. Unit tests: a setting a route
never declared does not reach the proxy; a served value nothing sets is refused by name; the setting
a served fact asks for is not stray.