Written 2026-09-28, answered the same week by mesh-controller bdf965d and c68d3a7, and never closed — so the mesh's own account said reach was declared nowhere while three readers were reading it: the filter, the proxy's names, and each authority's host policy. The resolution names them and what checks each. What is left is retiring the older per-port keys the block replaces, which is not a gap in what reach can say.
48 lines
2.8 KiB
Markdown
48 lines
2.8 KiB
Markdown
# Resolution
|
|
|
|
*2026-09-29.*
|
|
|
|
**Built, and this record did not say so.** The issue was written on 2026-09-28 and answered the same
|
|
week by two commits in `mesh-controller`; nothing came back to close it, so the mesh's own account of
|
|
itself said for a day that reach was declared nowhere while the code read it in three places.
|
|
|
|
- `bdf965d` — *a module names its endpoints, and a route names the one it serves*. `listens[].name`
|
|
is the endpoint; a route contribution names the endpoint rather than repeating a port.
|
|
- `c68d3a7` — *an assignment configures an endpoint as one thing*. The `endpoints` settings key, per
|
|
node, by endpoint name: `{"endpoints": {"ssh": {"port": 20134, "reach": "public"}}}` — port, label
|
|
and reach in one block, which is what [ADR 0138](../../02-DECISIONS/0138-an-assignment-binds-an-endpoint-and-says-how-far-it-reaches.md)
|
|
asked for and what [ADR 0046](../../02-DECISIONS/0046-a-module-configuration-is-its-assignments-not-its-manifest.md)
|
|
said configuration is.
|
|
|
|
## The three readers, which is what the issue was about
|
|
|
|
The complaint was that the per-node source override had exactly one caller. It now has three, and
|
|
they are the three mechanisms reach was decided to settle at once:
|
|
|
|
| reader | what it does with it |
|
|
|---|---|
|
|
| the filter | `Reaches` turns each endpoint's reach into the rule for its machine port |
|
|
| the proxy's names | `composeName` composes the public name, the internal name, or both — and a name nobody asked for is not composed |
|
|
| the authorities | the proxy certifies only names it was actually given, each from its own authority, through two host policies rather than one |
|
|
|
|
**A routed endpoint keeps the manifest's port**, which is ADR 0138's own insight and older than it
|
|
([ADR 0045](../../02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md)): the
|
|
proxy is how it is reached, so `public` there asks for a public *name*, not an open port.
|
|
|
|
**An endpoint that is not routed is reached and never named.** Git over ssh is that case — the one
|
|
the issue said the model could not express — and it is now the ordinary one.
|
|
|
|
## How it is checked
|
|
|
|
`internal/catalogue/endpoints_setting_test.go`: a block says port, label and reach; a block may say
|
|
only a reach; a name the module does not declare is refused; a reach outside the four values is
|
|
refused; and saying the same thing twice — once in the block, once through the older per-port keys —
|
|
is refused rather than resolved by whichever is read last. The proxy's half is `policy_test.go` and
|
|
`authority_test.go`: a name the mesh did not send is not certified, by either authority.
|
|
|
|
## What is left, and it is not this
|
|
|
|
The older keys (`ports`, `expose`, and reach keyed by port) still work beside the block. They are
|
|
what the block replaces, and retiring them is its own small change — not a gap in what reach can
|
|
say.
|