Issue 110's cause was not the filter: the runtime had never been told, and the resolver dropped a query arriving on a bridge. ADR 0148 step 3 landed once it did (109, 151 resolved). ADR 0151 composes a route's internal name under the serving node and drops the suffixed alias (139, 157 resolved). Design 08 amended; a fact in 0148 corrected.
5.9 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| the tiers | accepted | 2026-09-30 | jochen | false | 02-DECISIONS/0066-public-routing-is-name-agnostic.md |
151. A route's internal name is composed under the node that serves it
Context
A module that requires a route is given two names from one label: a public one, <label>.<public domain>, and an internal one, <label>.<node>.internal
(ADR 0138). Both were composed
from the node the module runs on.
The two are answered differently. The public name is published into every machine's roster at the
address of the node whose proxy serves it (ADR 0066), so
it reaches the proxy from anywhere in the mesh. The internal name is answered by every machine's
resolver as anything under a node's name goes to that node
(design 08 §2) — the node it was composed from, which is
the consumer's. Where the proxy runs on another machine, that name sends a client to a machine with
nothing listening, while the public name works
(issue 139).
Every route on this mesh today is served beside its module, so it has not been seen; route is
provided mesh-wide precisely so that stops being true.
Beside it, the roster gave every routed name a second entry with the mesh's suffix appended —
<name>.<public domain>.internal — because it composed a full name for every entry as it does for a
machine. That name resolved on every machine, was served by nothing, and was refused by the proxy at
the handshake; the first three names tried while reproducing an unrelated issue were those, and the
evidence pointed at a regression that had not happened
(issue 157).
Considered Options
1. Keep the consumer's name and publish it at the serving node's address, as the public name is.
The name stays <label>.<consumer>.internal and an exact roster entry overrides the wildcard.
Rejected: it makes <x>.<node>.internal mean goes to that node except when it does not, which is
the one rule the resolver design states; it needs an entry per route where the wildcard needed none;
and which of an exact entry and a wildcard a resolver answers first is the resolver's business, which
the mesh deliberately does not know.
2. A proxy on every machine, so the serving node is always the consumer's. Rejected for this
question: it is a different decision about what route is — a node-scoped seat with a mesh-wide
fallback — and this mesh runs one proxy on the hub today. Whatever is decided there, a route served
from another machine must have a name that reaches it.
3. Compose the internal name under the node that serves the route. Chosen.
Decision
A route's internal name is <label>.<serving node>.internal — composed under the node whose proxy
answers the route, which is the machine the request arrives at. The public name is unchanged:
<label>.<public domain> of the node the module runs on, which is where the operator put it.
Where the proxy runs beside the module — every route on this mesh today — the two nodes are one and nothing changes. Where it does not, the name says where the request goes, which is what a name under a node's name has always meant.
A routed name has no mesh form. The roster publishes it as itself, once, at the serving node's address. Only a machine has a bare name beside its full one.
What certifies the internal name is unchanged by this: the proxy that terminates it obtains a certificate from the mesh's authority for the names it is given, and it is given this one.
Taken on the operator's standing instruction to answer the open design questions in the work order.
How this is checked
- Composition. A controller test contributes a route from a module on one node to a proxy offered from another, gathered the way the controller gathers a consumer's contribution for a provider on another machine, and asserts the internal name carries the serving node.
- Publication. A controller test renders a roster with a machine and a routed name and asserts the routed name appears as itself, once, and never with the suffix appended.
- On the mesh. After the change no machine's roster carries a
<domain>.internalentry, and a route's internal name still answers from a container with a certificate from the mesh's authority.
Consequences
- A route served from another machine now has a usable internal name. The first module assigned that way will resolve, where before it would have resolved to the wrong machine with no error.
- The internal name of a route can change when its proxy moves. A route re-homed from one proxy to another gets a new internal name, as the design's rule implies; clients that dialled the old one reach the old machine. The public name does not move with the proxy and is the stable one.
- The roster is one line shorter per routed name, and a person reading a hosts file no longer finds names that resolve to a refusal.
- Issue 139's second question — a per-node route holder — is left open, and is a decision about what a seat is rather than about a name.
References
- issue 139 — the question
- issue 157 — the alias
- ADR 0066 — routed names propagate mesh-wide; extended here
- ADR 0138 — how the two names are composed and how far each reaches
- design 08 §2 — anything under a node's name goes to that node