38 — the mesh assigns the port, and a module does not care

Jochen's call, and the right one: a module cannot choose a port well,
because it is written once and assigned anywhere. Any number it picks is
a guess about a machine it has never seen, and two modules guessing the
same number is not a mistake either of them made.

Writing it up turned up something the issue had missed. The same number
appears three times in every module — the rule set, what a consumer is
told, and what the runtime publishes — and nothing checks that they
agree. They agree today because one person wrote all three. A module
whose `serves` said one thing and whose container published another
would resolve, compose, apply, and hand every consumer a port that
answers nothing.

So the decision is one source with the other two derived, and an
assignment made once and kept, as a credential is.

The part that needed thought is ports that cannot move — mail on 25,
submission on 587. Those become claims, which is what the mesh already
has for what is singular on a machine. Two modules wanting 25 is the
same shape as two wanting the seat, and gets refused by name at
assignment rather than by a container runtime at apply. That makes this
mostly a matter of pointing an existing mechanism at ports.

Left open: whether a module should publish to the machine at all.
Assignment makes publishing safe without making it necessary.
This commit is contained in:
2026-09-01 17:42:27 +02:00
parent 6330abce5f
commit c2a37ab7f8
2 changed files with 99 additions and 1 deletions
@@ -3,7 +3,7 @@ status: located
opened: 2026-09-01
located-in: [mesh-control]
fixed-by:
amended-design:
amended-design: 02-DECISIONS/0038-the-mesh-assigns-the-port.md
---
# 028 — Two things want one port, and nothing says so until the machine
@@ -55,3 +55,19 @@ folklore.
`listens` already says which ports a module accepts on, and filtering is computed from it. That is
about what may reach a port from elsewhere. This is about two things on one machine wanting to own
the same one, which `listens` does not model and could not answer.
## Answered in principle
[ADR 0038](../../02-DECISIONS/0038-the-mesh-assigns-the-port.md), proposed the same day: **the mesh
assigns the machine-side port and a module does not care.** A module cannot choose well, because it
is written once and assigned anywhere — any number it picks is a guess about a machine it has never
seen.
A port fixed by its protocol — mail on 25, submission on 587 — becomes a **claim**, which is the
mechanism the mesh already has for what is singular on a machine. Two modules wanting 25 is the
same shape as two wanting the seat, and earns the same refusal at assignment rather than at apply.
The record also names what this issue missed: the same number is written **three times** in every
module — once for the rule set, once for what a consumer is told, once for what the runtime
publishes — and nothing checks that they agree. A module whose `serves` and whose container
disagreed would hand every consumer a port that answers nothing.