Asked whether merging the three reviewed changes would set a precedent. It would not: five modules already carry a name belonging to this one mesh — a workflow module stating its host, protocol and absolute webhook URL, and two carrying a full clone URL for a repository on the mesh's own forge. That changes what the issue is for. There is no version of this catalogue today that does not name the mesh it was written in, so refusing three changes buys nothing and a mechanism is the only thing that removes any of them. The three were merged on that reading, each PR saying so.
4.8 KiB
status, opened, located-in, fixed-by, amended-design
| status | opened | located-in | fixed-by | amended-design | ||||
|---|---|---|---|---|---|---|---|---|
| located | 2026-09-26 |
|
122 — A module cannot ask for its own public name, so three manifests wrote this mesh's names into the catalogue
What was observed
Reviewing the open module changes on 2026-09-26, three of them independently put a name belonging to one particular mesh into a module definition, each for a different piece of software and each as the only way to make the software work:
- The identity provider's manifest gains
KC_HOSTNAME: https://<label>.<public-domain>as a literal, because the software generates absolute URLs and, behind a proxy, cannot derive them. - The object store's manifest gains
MINIO_BROWSER_REDIRECT_URL: https://<label>.<public-domain>as a literal, for the same reason — its console redirects to an absolute URL. - The file-sync module's S3 bucket is renamed from
nextcloudto a name carrying this mesh's own name, so the module matches a bucket that already exists here.
No reviewer introduced these carelessly: each is the value the software needs, and there is nowhere else to put it.
And they are not the first. Asked whether merging them would set a precedent, the catalogue answered no: five modules already on the main branch carry one. The clearest is the workflow automation module, whose environment file states its host, its protocol and a full absolute webhook URL as literals; two more — the proxy and the builder — carry a complete clone URL for a repository on this mesh's own forge, scheme, host and port included.
So the three under review are the visible edge of a pattern the catalogue already follows, which changes what this issue is for. It is not a matter of refusing three changes; there is no version of this catalogue today that does not name the mesh it was written in, and a mechanism is the only thing that removes any of them.
What the mesh offers instead, and why none of it answers
A manifest may interpolate ${secret:…}, ${seat:…}, ${bound:…}, ${port:…} and
${machine:…}. The machine form resolves at, name and address — the machine's identity on the
private network. None of them yields a public name.
The mesh does compose public names: a route contribution's label is joined to the node's public
domain, <label>.<public-domain>, and the mesh interprets neither half. That happens inside the
controller when a declaration is built, and the result reaches the proxy that serves the route. It
does not reach the module that asked for the route, so a module that must tell its own software
what it will be reached at cannot read what the mesh already worked out.
So the workaround is the only expressible option: write the answer down, in the definition, for the one mesh it is true of.
Why it matters beyond these three
A module definition is meant to hold what is true of the module everywhere, with everything particular to an installation resolved at assignment — the argument ADR 0112 (proposed) makes in full, and what issue 119 found for paths. A hostname is the same kind of fact as a path, and arriving by the same route: not because anyone disagreed with the principle, but because the mechanism that would honour it does not exist yet.
The cost is concrete. A second mesh installing the identity provider from this catalogue gets the first mesh's hostname, and its login flow breaks in a way that looks like a proxy fault. Nothing checks for it: a literal hostname in an env value is a well-formed string, and no rule distinguishes it from a version number.
The bucket case is the same shape with a different subject — an adopted resource's real name is also particular to one installation, and also has nowhere to live but the definition.
Open questions
- Should a module be able to name what it will be reached at — a
route-scoped interpolation resolving to the composed public name of a route it contributes, so the answer the mesh already computes is the one the software is told? That is the smallest fix and it stays within the existing vocabulary. - Does the scheme belong to it? Every instance here wrote
https://, which is true of a route the proxy terminates and not of the module's own port. - For an adopted resource such as an existing bucket: is that a setting on the assignment (where ADR 0112 would put it), and if so what reads it — the provisioner, or the module's own values?
- What check would notice the next one? A definition naming a public domain is detectable in the shape of the value, which is more than nothing, and less than a rule.