ADR 0226: the private network is assigned by its own name, and the proxy names its public issuer #128

Merged
mesh-admin merged 2 commits from decision/0226-the-private-network-by-its-own-name into main 2026-10-06 13:04:28 +00:00
Contributor

ADR 0226, from the operator's 2026-10-06 direction ("a private network, some docker stuff, a firewall and a public + internal certificate resolver").

  • networking retires: every machine is assigned mesh-wireguard by its own name; supersedes ADR 0009's domain-module section in part. A module the controller stops shipping is retired at its next start, never while assigned or holding anything (a definition, not ADR 0230's retired consumer).
  • public-acme folds into route-proxy: the proxy states Let's Encrypt in its own acme.env, byte for byte what the binding rendered, so its account directory (named after that spelling and the trust root) and every certificate stay put.
  • dhcpcd, cloudflare-dns leave the catalogue (assigned nowhere; nothing requires public-dns).
  • avahi, netcheck untouched.

Amended: connectivity §1/§2/§5, the installation in full, a module repository; dated pointer notes on ADRs 0009, 0044, 0117. Checks: records, index, cycle pass (rebased onto main with ADRs 0225–0231; 0226 does not collide).

Companion PRs: mesh-host#31 (genesis), mesh-catalog#84, mesh-controller#77.

Rollout

Roles: anchor = the hub and one proxy, home server = the other proxy, laptop and workstation = neither.
Merge order: hq#128 → mesh-host#31 → mesh-catalog#84 → mesh-controller#77.

Step 1 — the private network by its own name: DONE 2026-10-06

mesh-wireguard assigned and networking unassigned on all four machines, pushed; tunnels and DNS verified, plans identical. Re-checked read-only after: no networking.* resource in any plan, mesh-wireguard.* present.

Step 0 for the proxy — baseline: taken 2026-10-06, refreshed before merge

  • Every routed public name on both proxies (51): openssl s_client -connect <name>:443 -servername <name> </dev/null | openssl x509 -noout -serial -enddate. Refreshed after the rebase: all 51 unchanged from the first baseline.
  • Both proxies' rendered route-proxy.acme-env re-read from plan: byte-identical to what mesh-catalog#84 writes literally; trust image digest unchanged.
  • Still to take right before merging #84, on each proxy machine (<node>/node-login-shell.execute): sudo ls -laR --time-style=full-iso /var/lib/route-proxy/acme.

Step 2 — merge hq#128, then mesh-host#31 (genesis only; no live effect)

Step 3 — merge mesh-catalog#84 (the proxy states its issuer; three modules leave)

The merge rebuilds route-proxy and rolls it out one machine first (ADR 0218). On each proxy, once pushed:

  1. mesh-controller.plan → route-proxy.acme-env byte-identical to the baseline; route-proxy.bound-acme-ca gone; route-proxy.trust unchanged.
  2. The proxy container may restart once (a new server image); certificates come from the cache.
  3. Re-run the openssl list → every serial and notAfter unchanged; re-run the acme listing → no new directory, no new or modified file. Any difference: stop, do not continue to the second proxy (pause the plan).
  4. journalctl CONTAINER_NAME=route-proxy --since -30min | grep -i acme → no orders, no errors.
    Then retire what the catalogue no longer has:
  • mesh-controller.unassign {node: <home server>, module: "public-acme"}, same for the anchor; mesh-controller.push each → plan shows no change on either.
  • mesh-controller.unpin {node: <anchor>, provision: "acme-ca"} (a stale pin naming step-ca).
  • mesh-controller.command "module forget public-acme", "module forget dhcpcd", "module forget cloudflare-dns" (none holds settings, secrets or ports; checked 2026-10-06).

Step 4 — merge mesh-controller#77

Its prepare retires networking ("retired networking: the control plane no longer ships it") — step 1 is done, so it should not say "kept". Check mesh-controller.modules (no networking) and mesh-controller.plan per machine unchanged.

ADR 0226, from the operator's 2026-10-06 direction ("a private network, some docker stuff, a firewall and a public + internal certificate resolver"). - **`networking` retires**: every machine is assigned `mesh-wireguard` by its own name; supersedes ADR 0009's domain-module section in part. A module the controller stops shipping is retired at its next start, never while assigned or holding anything (a definition, not ADR 0230's retired consumer). - **`public-acme` folds into `route-proxy`**: the proxy states Let's Encrypt in its own `acme.env`, byte for byte what the binding rendered, so its account directory (named after that spelling and the trust root) and every certificate stay put. - **`dhcpcd`, `cloudflare-dns` leave the catalogue** (assigned nowhere; nothing requires `public-dns`). - `avahi`, `netcheck` untouched. Amended: connectivity §1/§2/§5, the installation in full, a module repository; dated pointer notes on ADRs 0009, 0044, 0117. Checks: records, index, cycle pass (rebased onto main with ADRs 0225–0231; 0226 does not collide). Companion PRs: mesh-host#31 (genesis), mesh-catalog#84, mesh-controller#77. ## Rollout Roles: anchor = the hub and one proxy, home server = the other proxy, laptop and workstation = neither. **Merge order: hq#128 → mesh-host#31 → mesh-catalog#84 → mesh-controller#77.** ### Step 1 — the private network by its own name: **DONE 2026-10-06** `mesh-wireguard` assigned and `networking` unassigned on all four machines, pushed; tunnels and DNS verified, plans identical. Re-checked read-only after: no `networking.*` resource in any plan, `mesh-wireguard.*` present. ### Step 0 for the proxy — baseline: **taken 2026-10-06, refreshed before merge** - Every routed public name on both proxies (51): `openssl s_client -connect <name>:443 -servername <name> </dev/null | openssl x509 -noout -serial -enddate`. Refreshed after the rebase: all 51 unchanged from the first baseline. - Both proxies' rendered `route-proxy.acme-env` re-read from `plan`: byte-identical to what mesh-catalog#84 writes literally; `trust` image digest unchanged. - Still to take right before merging #84, on each proxy machine (`<node>/node-login-shell.execute`): `sudo ls -laR --time-style=full-iso /var/lib/route-proxy/acme`. ### Step 2 — merge hq#128, then mesh-host#31 (genesis only; no live effect) ### Step 3 — merge mesh-catalog#84 (the proxy states its issuer; three modules leave) The merge rebuilds route-proxy and rolls it out one machine first (ADR 0218). On each proxy, once pushed: 1. `mesh-controller.plan` → `route-proxy.acme-env` byte-identical to the baseline; `route-proxy.bound-acme-ca` gone; `route-proxy.trust` unchanged. 2. The proxy container may restart once (a new server image); certificates come from the cache. 3. Re-run the openssl list → **every serial and notAfter unchanged**; re-run the acme listing → no new directory, no new or modified file. Any difference: stop, do not continue to the second proxy (pause the plan). 4. `journalctl CONTAINER_NAME=route-proxy --since -30min | grep -i acme` → no orders, no errors. Then retire what the catalogue no longer has: - `mesh-controller.unassign {node: <home server>, module: "public-acme"}`, same for the anchor; `mesh-controller.push` each → plan shows no change on either. - `mesh-controller.unpin {node: <anchor>, provision: "acme-ca"}` (a stale pin naming step-ca). - `mesh-controller.command "module forget public-acme"`, `"module forget dhcpcd"`, `"module forget cloudflare-dns"` (none holds settings, secrets or ports; checked 2026-10-06). ### Step 4 — merge mesh-controller#77 Its `prepare` retires `networking` ("retired networking: the control plane no longer ships it") — step 1 is done, so it should not say "kept". Check `mesh-controller.modules` (no `networking`) and `mesh-controller.plan` per machine unchanged.
jschoubben added 2 commits 2026-10-06 13:03:06 +00:00
Two modules existed only to say one thing each: networking required mesh-wireguard and nothing else,
and public-acme pointed the one proxy at Let's Encrypt. dhcpcd and cloudflare-dns are assigned
nowhere. Retire all four, keeping every machine's network and every certificate as they are.
The two retirements are easy to confuse; the second deletes nothing a person must approve.
jschoubben force-pushed decision/0226-the-private-network-by-its-own-name from edad6acf49 to 4f981cc2d7 2026-10-06 13:03:06 +00:00 Compare
mesh-admin merged commit cf9eec76c9 into main 2026-10-06 13:04:28 +00:00
mesh-admin deleted branch decision/0226-the-private-network-by-its-own-name 2026-10-06 13:04:28 +00:00
Author
Contributor

Delivery novox/hq@cf9eec76c9b8 — held since 2026-10-06T23:05:28Z

Held for a person: merged without a passing check: only a person decides that it goes on — mesh-delivery.release with why lets it go on.

Delivery plan — builds nothing: the change touches no module of the mesh's graph

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/hq#128 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/hq@cf9eec76c9b8` — **held** since 2026-10-06T23:05:28Z Held for a person: merged without a passing check: only a person decides that it goes on — `mesh-delivery.release` with why lets it go on. **Delivery plan** — builds nothing: the change touches no module of the mesh's graph **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/hq#128 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/hq#128