The boxes of an estate find each other.
Until 2026-09-24 the laptop's xtask was the matchmaker of the gunnar.rs estate: three machines booted knowing nothing of each other, and every introduction — bootstrap the primary with the front's console key, enrol the principals, confer the twin's role, sign its certificate — was one ssh command from a laptop, run once, in order. Every one of them was a place the chain broke (a box not listening yet, a killed run, a dropped packet), and a laptop in the middle of an installation is a single point of failure that has nothing to do with the estate.
The owner's order (2026-09-24): the xtask does not pair. It starts the
machines with enough information for them to form a tunnel — WireGuard by
default; Tailscale, Mullvad, or none — and the boxes pair each other inside
it. gunnar and holger share this crate. Design: Skidbladnir/.nornir/pairing-design.md.
The pieces, in the order a box meets them:
- [
seed] — what a MEDIUM is told at compose time, the same for every lay: the estate, the tunnel kind, the join door's fixed address, the installer CA and the bootstrap certificate. Nothing per box, nothing per lay — the medium is constant (2026-09-24 evening). - [
tunnel] — the driver trait and thenonedriver. Only the FRONT needs a known address; the others dial it, and the overlay addresses are ours. - [
join] — the one-time join against the front's door over mutual TLS: the box presents its tunnel public key and its capacity; the door admits it by the address it joins from, and answers with its name and overlay address, the peers (the front's tunnel first), the role, and the FEED. - [
elect] — the weakest gunnar box becomes the twin, decided ONCE on the front from two capacity reports, never re-decided. - [
pair] — the state machine each box runs: tunnel up → joined → role known → paired, every step idempotent and retried by the box itself. - [
signal] — where a box is, as one line and as a value; what the xtask (and an operator) READS instead of doing.
Pure Rust, no shell (LAW). No driver here ever answers "up" for a tunnel it
did not bring up: none and wireguard work, mullvad works as each
box's EXIT beside the WireGuard mesh, and tailscale refuses by name
([tunnel-tailscale-unimplemented]) — see [tunnel].