Files
hq/02-DECISIONS/0167-a-membership-carries-what-its-module-receives-and-who-the-mesh-is.md
T
jschoubben df667eb710 ADR 0167: a membership carries what its module receives, and who the mesh is
Issue 191's route proxy needs to know who the mesh is to serve an
internal name correctly, and the first fix had it work that out alone.
The membership on the bus now carries it, from the same list the filter
uses. ADR 0138 gains an insight that the proxy is where internal reach
is kept; designs 08 and 25 say how.
2026-10-02 09:49:19 +02:00

6.2 KiB

topic, status, date, deciders, reconstructed, extends
topic status date deciders reconstructed extends
the mesh accepted 2026-10-02 jochen false 02-DECISIONS/0160-the-mesh-issues-an-assignments-subjects-and-a-runtime-serves-what-it-is-issued.md

167. A membership carries what its module receives, and who the mesh is

Context

A provider learns what it is given from a file. The controller composes every consumer's contribution to a requirement, and the node's declaration writes them into the provider's received file. The route proxy reads its routes that way: one JSON file, re-read every two seconds.

Issue 191 showed what that file leaves out. Since ADR 0138, a route whose endpoint reaches only the private network carries an internal name and no public one. The proxy dropped it. Serving it was not enough either: the proxy answers public and internal names on the same listeners, so an internal name served to every request is public under a guessable name. To serve it correctly the proxy needs a second fact, who the mesh is, and nothing gave it one.

The first attempt had the proxy work it out: the mesh's range from an environment variable written by the catalogue, and the machine's container bridges read from its own interfaces. That is a second definition of "the mesh", kept by one module, beside the one the packet filter already uses. The controller resolves "from the mesh" to every machine's address on the private network, and the filter is rendered from that list. Two definitions agree until one changes.

ADR 0160 already gives every assignment one document on the bus, its membership, read once at connect and followed. It says what the assignment serves and reaches. It does not yet say what it is given.

Considered Options

  1. Keep the file, add the mesh to it. The proxy keeps polling a file, and the controller writes the mesh's addresses beside the routes. It fixes the definition, but delivery stays a file re-read on a timer, written by a separate path from the one every other fact a module is told now takes.
  2. Have the proxy work it out from a range in its environment and the machine's interfaces. Rejected: it is the second definition this record exists to remove.
  3. The membership carries it. What each module receives, from the same composition its received file is written from, and the mesh's addresses, from the same list the filter is rendered from. The proxy follows its membership and serves exactly that.

Decision

Option 3.

  • A membership carries what its module receives, by requirement: the contributions every consumer made, exactly as composed for its received file. A requirement nobody contributed to is an empty list, never absent, for the reason the file is written empty: "nothing asked" and "never told" want different responses.
  • A membership carries who the mesh is: every machine's address on the private network, the list a rule saying "from the mesh" resolves to. One list, two readers: the filter and any module that must tell the mesh from the world.
  • The route proxy reads its routes and the mesh from its membership, with the bus account every module that speaks on the bus is given. It serves an internal name only to the machines the mesh names and to the machine itself, and answers anyone else as it answers a name it never routed: in the request, in the handshake, and in the list of names it serves.
  • The file stays until the bus has spoken. While a proxy has read no membership that carries routes, it serves the file, and an internal name only to its own machine: refused, never opened. A membership from a controller that issues no routes changes nothing.

Consequences

  • Every membership grows two fields. A machine joining or leaving republishes every membership, which a push already does.
  • A provider that receives something is told it twice for now, in its file and on the bus. The file goes when every provider reads its membership; that is its own change.
  • The route proxy needs a bus account. It is issued like any module's, so a machine running the proxy cannot be composed between the catalogue declaring the account and the operator issuing it. The machine keeps what it runs meanwhile.
  • The internal name of a route that also has a public one is now served to the mesh only. Outsiders have the public name.
  • A container on the same machine that calls that machine's own internal name arrives from its container network, not from a mesh address, and is refused. Calls between machines are unaffected: they leave by the machine's mesh address. Whether the mesh should also issue each machine's container networks is left open, because the mesh does not record them today.

How this is checked

Rule Checked by
What a provider receives on the bus is what its received file says, same-node port fix included a controller test composing a provider and a consumer on one machine and comparing the two
An internal name is served to the machines the membership names and to loopback, and to nobody else the proxy's tests: served from a named address and from loopback; refused, unlisted and uncertified from any other
A membership that carries no routes, or a mesh that cannot be read, changes nothing the proxy's tests
Until the mesh is issued, an internal name is served to the machine alone the proxy's tests
Live: an internal-only route answers over the mesh and is refused from outside by hand, after the release

References

  • ADR 0160 — the membership this extends
  • ADR 0138 — reach, and the insight of 2026-10-02 that the proxy is where internal reach is kept
  • ADR 0144 — the machine itself is always inside
  • Issue 191 — what found it