Files
hq/02-DECISIONS/0161-what-deserves-a-seat.md
T

7.5 KiB

topic, status, date, deciders, reconstructed, extends
topic status date deciders reconstructed extends
the mesh accepted 2026-10-01 jochen false 02-DECISIONS/0126-a-module-declares-its-own-seats.md

161. What deserves a seat: a role of a module is a seat, a singular fact about machines is a placement with a capacity of one, and a holder's software is the machine's

Context

Three issues asked the same question from three sides. The vault provides secret to the whole mesh and claims no seat, so nothing refuses a second vault by name (issue 106). The hub of the private network is a placement, overlay place <node> --hub, and the issue asked whether "there is exactly one hub" is a seat's shape (issue 105). Three modules claim the one uplink seat, one per network manager a machine might run, and nothing checks that the holder names the manager the machine actually runs (issue 138).

Read against the code on the day of deciding:

  • The mesh's own seats are five by design 26's table and four in the controller's seed: mesh-vault is in the table and not in the seed, and the vault's definition claims nothing. The design also says secret is reserved; no parser or resolution rule reserves it. A second provider of secret would be a second candidate, settled by a pin.
  • The store already keeps one hub: a unique index since the overlay's first migration, and the placing command refuses a second hub naming the first. What 105 observed as silent is not. ADR 0121 decided that the private network becomes a mesh-scoped seat held by a server module, with client modules — the overlay is the host's own today, so that seat has nothing to be held by yet.
  • A machine's capabilities are its profile, detected by the host at enrolment and never since, and resolution refuses a module on a machine lacking one it declares, naming the capability. The uplink holders declare package-manager and service-manager, which every machine has.

ADR 0126 gave the reason the mesh's own seats exist: the mesh's own code looks them up by name. mesh-store is an identifier the controller dereferences, not a convention. That reason decides the first question; the other two are decided by what a seat is — a role held by a module assignment — and by what the mesh can check.

Decision

1. A provision the mesh itself dereferences is delivered by a mesh seat its provider claims. The vault's secret is one: the controller seals every minted credential with it. mesh-vault is the fifth seat of the mesh's own, mesh-scoped, delivering secret, under ADR 0079's convention; the vault's definition claims it; a second provider of secret is a second claimant and refused by name. The word reserved leaves design 26: the effect it described is the seat's. Every other mesh-scoped provision — smtp, oidc-client, s3-bucket, route, acme-ca and the rest — may have several providers, and a consumer with several and none local is a person's choice, as the glossary says. The test for "deserves a seat" is the question 0126 asked: does the mesh's own code find it by name?

2. A singular fact about machines is a placement with a capacity of one; a singular role of a module is a seat. A seat is held by a module assignment and points at it; the hub is a machine, and the private network is the host's own until 0121's server and client modules exist. So the hub stays a placement, and what a seat would have given — refusal of a second by name, and the one named when asked — a placement of capacity one gives: the store keeps one (the unique index), the placing command refuses a second naming the one that stands, and the overlay listing names it. 0121's seat for the private network stands, deferred with the split it needs. The rule generalises: a fact of the shape exactly one machine is X is a placement checked by the store and said by name, never a seat with no module to hold it.

3. A holder of a seat whose role is "speak to what this machine runs" must be the dialect the machine runs, and the machine says which. The host's profile gains one capability per network manager found active — uplink-networkmanager, uplink-systemd-networkd, uplink-dhcpcd, each systemctl is-active of the manager's unit — and each uplink holder declares its own. Assignment then refuses the wrong holder with the refusal that already exists, naming the capability; nothing new is judged. The profile is detected again by every apply and travels in the report, and the controller keeps the latest, so a machine that switches managers is, at its next push, a machine whose holder lacks a capability: the plan refuses and names it, which is the one thing the machine is the only one to know. node-uplink stays one seat: its three holders are three dialects of one role, and the capability picks the dialect. One module speaking all three is allowed by this and built by nobody.

Consequences

  • The controller's seed gains mesh-vault; the seat table takes it additively at the next start, as every seed row does. The vault's definition claims it, one release after the controller.
  • The uplink definitions declare their capability one release after the host reports it, or they are refused on every machine in between; the order is controller (the report carries a profile), host, then catalogue.
  • Design 26 loses the word reserved for secret and states rules 2 and 3; the uplink row of the seat table names the capability its holders declare.
  • Issue 106 is resolved by rule 1, 105 by rule 2 with nothing to build, 138 by rule 3.

How this is checked

Rule Checked by
mesh-vault is in the mesh's own set, mesh-scoped, delivering secret, and the vault claims it a catalogue test on the default seats; registration refuses a second claimant by name (CanHold's existing test, with the vault's seat)
A second hub is refused naming the first, and the listing names the hub the overlay command's test; the store's unique index
A machine's profile names the network manager it runs, and is renewed by every report a host detector test per manager; a controller test that a report carrying a profile replaces the stored one
An uplink holder on a machine running another manager is refused, naming the capability the existing capability refusal, exercised by a resolution test with a networkmanager machine and the systemd-networkd holder
Live mesh-controller.seats lists mesh-vault held by the vault on the control node; plan of a machine refuses the wrong uplink holder naming uplink-<manager>

References