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.
129 lines
9.4 KiB
Markdown
129 lines
9.4 KiB
Markdown
---
|
|
topic: what runs on it
|
|
status: accepted
|
|
date: 2026-09-30
|
|
deciders: jochen
|
|
reconstructed: false
|
|
extends: 02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md
|
|
---
|
|
|
|
# 155. A definition names no installation: how that is checked, and the three ways a value that did gets out
|
|
|
|
## Context
|
|
|
|
[ADR 0112](0112-a-module-definition-names-no-node-mesh-or-path.md) decided that a module definition
|
|
names no node, no mesh and no host path, and said how the name half is checked: *a catalogue test
|
|
finds no domain name in any definition value*. No such test existed
|
|
([issue 134](../04-ISSUES/134-a-definition-may-still-name-the-mesh/00-report.md)). Written and run
|
|
over the 77 definitions on 2026-09-30, the check it describes finds **42 values**, in 15 definitions,
|
|
and they are of four kinds that want four different answers:
|
|
|
|
| kind | count | example |
|
|
|---|---|---|
|
|
| a service told its own public name as a literal | 5 | an identity provider's `KC_HOSTNAME`, an object store's console redirect, an automation tool's webhook URL |
|
|
| an operator's value written into the definition | 10 | a mail server's domain, site name, website, and the address it trusts a real-IP header from |
|
|
| this mesh's forge, by URL, as a recipe's build context | 2 | the builder and the proxy, which package the controller's source |
|
|
| an application built outside the mesh, pulled from this mesh's registry | 7 | four sites and tools whose repositories are the operator's own |
|
|
| the world's servers, named by upstream defaults | 10 | a Matrix homeserver's trusted key server, Element's integration manager |
|
|
| a module named after the domain it serves | 8 | one site module, with its paths and network named after it |
|
|
|
|
Not one was careless. Each was the value the software needs, and until today there was nowhere else
|
|
to put it ([issue 122](../04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md)).
|
|
Two of the answers were built before this record: a module is told the name its route composes
|
|
(`${bound:<route>:name}`, controller PR 149, 2026-09-30), and a source may be a path on the git seat
|
|
([ADR 0111](0111-a-build-source-is-on-the-git-seat-or-external.md)). What was missing: an operator's
|
|
value in a file the software reads, the same for a build *context*, a way to say a name is meant, and
|
|
the check.
|
|
|
|
## Considered Options
|
|
|
|
**1. A string search for the installation's own names.** Rejected. The controller is as
|
|
mesh-agnostic as the definitions; it does not know which names are "this mesh's", and a check that had
|
|
to be told would be configured per installation and pass everywhere else. What it can know is the
|
|
*shape*: a name under a public top-level domain, a public address.
|
|
|
|
**2. Report every such shape.** Rejected. Eight of the 42 were `why` strings — prose the mesh never
|
|
reads, explaining what a port is for — and a check that reports those beside `KC_HOSTNAME` teaches
|
|
people to ignore the report. And a Matrix homeserver *must* name the federation's public key server;
|
|
a check with no way to say so would be a check people argue with rather than obey.
|
|
|
|
**3. Judge what the mesh acts on; let a definition say which names it means, one by one, with a
|
|
reason; exempt the world's services that a definition may name as a policy default.** Chosen.
|
|
|
|
**For an operator's value**, one option was to wait for design 27's requirement form in full. Rejected
|
|
for the reason 0112 gave against a slow operator provider: if asking a person for a value takes more
|
|
than a setting, module authors route around it and the literals come back. `${setting:<key>}` is the
|
|
operator provider in its first form, on the settings a module already has.
|
|
|
|
## Decision
|
|
|
|
**The check.** Every string value of a definition that the mesh acts on is judged for a hostname under
|
|
a public top-level domain and for a public address. Not judged: `why` and `description`, which are
|
|
prose. Allowed where they can only mean the world: the public registries an `image` may be pulled
|
|
from, the public resolvers a machine may forward to, and the public certificate authorities' ACME
|
|
directories. The container runtime's alias for its own host is the runtime's. A module's own name is a
|
|
value too. The check runs in `module check` and as a catalogue-wide test; **it does not yet refuse at
|
|
registration**, because the list it prints is the list that shrinks, and a registration that refused a
|
|
manifest whose only remedy is a merge elsewhere would refuse the mesh's own catalogue on the day the
|
|
check landed. It moves to registration when the list has been empty for a release.
|
|
|
|
> **Progressive insight — 2026-09-30.** The list was empty the day the check landed — every remaining name declared with its reason — and the operator asked for registration to refuse at once rather than after a release. It does, since mesh-controller PR 175: `module add` and a build's result are refused in the check's words, naming the way out, and the build stays recorded. The decision stands; only the day moved.
|
|
|
|
**A name a definition means is declared with its reason.** `names-on-purpose` on a resource maps each
|
|
such name to why: *the federation's public key server, the world's*; *built outside the mesh, from the
|
|
application's own repository, until that repository is a build source on the git seat*. A name the map
|
|
does not cover is still reported. The host never sees the word.
|
|
|
|
**An operator's value reaches a file as `${setting:<key>}`**, filled from the module's settings
|
|
layers — the mesh's, then the node's — the same layers a mergeable file and a contribution take, so
|
|
`settings set <module>` stays the one place a person's values go. Refused, naming the key and the
|
|
command, when nothing set it: a default for a mail domain would be the literal this removes, and a
|
|
blank written silently would be a service that comes up wrong somewhere that names nothing.
|
|
|
|
**A build context may live on the git seat.** `context: {"seat": "git", "repository": "<owner>/<name>"}`
|
|
is composed by the mesh that builds it: the request carries each seat's clone base, and a builder told
|
|
no base for a seat a context names refuses the build by the seat's name rather than guessing a forge.
|
|
|
|
**A module is named for what it is.** The site module named after its domain is `website`.
|
|
|
|
## Consequences
|
|
|
|
- **The catalogue names no installation, and a test says so.** The forty-two became zero the same day,
|
|
by the four answers above; seven of them are declared on purpose and stay visible as the list to
|
|
shrink — four applications the mesh does not build yet.
|
|
- **An operator's values are the assignment's.** The mail module takes its domain, its site name, its
|
|
website and the address it trusts a real-IP header from as settings; a mesh that installs it without
|
|
them is refused at composition, by name, which is the right moment. The module's own README says
|
|
which.
|
|
- **What got harder:** a manifest reviewer has one more word to read, and `names-on-purpose` on an
|
|
application's image is a debt visible in the definition until the application is built here. A
|
|
reader of `settings set` output sees more keys than files, because a key a file asks for is a
|
|
destination too.
|
|
- **Not decided here:** ADR 0112's requirement form (design 27) still replaces `${setting:…}` and the
|
|
other placeholders when it lands; this is its first case, the way [ADR 0038](0038-the-mesh-assigns-the-port.md)
|
|
was for ports. Host paths ([issue 119](../04-ISSUES/119-a-module-definition-decides-where-its-files-live/00-report.md))
|
|
are the next step of the same group, and the registry's name ([issue 123](../04-ISSUES/123-the-image-registry-is-named-after-a-role/00-report.md))
|
|
the one after.
|
|
|
|
## How this is checked
|
|
|
|
| Rule | Checked by |
|
|
|---|---|
|
|
| A value naming an installation is reported at its path, in the definition's words | a catalogue unit test over a definition with a hostname in an env value and a public address in a file |
|
|
| Prose, the world's registries in an image, public resolvers, ACME directories and the runtime's own alias are not reported | the same tests |
|
|
| A name declared on purpose is not reported; a name beside it that is not declared is | a test with a homeserver's config |
|
|
| An image from an installation's registry needs a reason | a test without and with the word |
|
|
| A module named after a domain is reported | a test |
|
|
| No definition in the catalogue names an installation | `TestNoCatalogueManifestNamesAnInstallation` over the checkout, and `module check modules/` |
|
|
| A definition naming an installation is refused at registration, and one declaring its names passes | `TestRegistrationRefusesADefinitionNamingAnInstallation` (2026-09-30) |
|
|
| `${setting:key}` fills from the layers, node over mesh; refused by name when unset; not stray when set | three tests |
|
|
| A context on a seat is cloned from the base the mesh sent; a seat with no base is refused by name | the builder's test |
|
|
|
|
## References
|
|
|
|
- [ADR 0112](0112-a-module-definition-names-no-node-mesh-or-path.md) — extended: the check it promised, and the operator provider's first form
|
|
- [ADR 0111](0111-a-build-source-is-on-the-git-seat-or-external.md) — a source on the seat; now a context too
|
|
- [issue 122](../04-ISSUES/122-a-module-cannot-ask-for-its-own-public-name/00-report.md), [issue 134](../04-ISSUES/134-a-definition-may-still-name-the-mesh/00-report.md) — what this closes
|
|
- [27 — A module requires, the mesh resolves](../03-DESIGN/01-to-be/27-a-module-requires-the-mesh-resolves.md) — where this sits in the larger design
|
|
- mesh-controller PR 169, mesh-catalog PR 188 — the check, the words, and the catalogue that passes it
|