diff --git a/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/00-report.md b/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/00-report.md index 92285c4..246fbf4 100644 --- a/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/00-report.md +++ b/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/00-report.md @@ -1,7 +1,7 @@ --- -status: open +status: located opened: 2026-09-24 -located-in: [] +located-in: [mesh-controller internal/inventory, mesh-controller internal/catalogue, mesh-controller cmd/mesh-controller, mesh-catalog modules/dnsmasq] fixed-by: amended-design: --- diff --git a/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/01-diagnosis.md b/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/01-diagnosis.md new file mode 100644 index 0000000..3463dbe --- /dev/null +++ b/04-ISSUES/112-adopting-a-tunnel-gives-the-mesh-addresses-without-names/01-diagnosis.md @@ -0,0 +1,78 @@ +# Diagnosis + +## 2026-09-24 — where the mesh's own record ends, and what stands beside it + +Checked the mechanism first. The resolver module's config (`mesh-catalog modules/dnsmasq`) is +generated whole from `nodes.conf`, the `dnsmasq.fact-node-zones` fact `mesh-controller` computes: +one `address=/./
` wildcard per node the mesh has a name for, plus +`local=//` — which tells dnsmasq it is *authoritative* for the whole suffix, so anything +under it that is not one of those wildcards is refused, not forwarded. That is the exact mechanism +the report describes: **the mesh does not lack an upstream to ask, it has told itself there is +nothing to ask.** + +Checked whether "forward to the resolver it replaced" (the third open question, ADR 0104's shape) +is literal here the way it was for the proxy. It is not, and the difference matters: the proxy's +predecessor kept running throughout its migration, a separate process on ports the mesh's proxy did +not yet hold. DNS has one process on one port. `mesh-catalog`'s dnsmasq module, on assignment, +replaces `/etc/dnsmasq.conf` whole and restarts the one `dnsmasq.service` unit — the same unit the +predecessor's own resolver is running as, right now, on this control-node: + +``` +$ systemctl status dnsmasq +● dnsmasq.service ... Active: active (running) since Fri 2026-09-18 ... +``` + +There is no predecessor process left standing after that assignment for a forward rule to reach. +An adapter in ADR 0104's literal shape — a second thing running, written into by a first — does not +fit; whatever answers this has to be data carried across the cutover, not a live thing forwarded to +across it. + +## What is actually missing, and where it already exists + +The report's first open question — *should a carried peer be nameable, the operator saying which +machine a carried address is, before it enrols* — turns out not to need a guess. The predecessor's +own resolver config, still live on this control-node, already states it: + +``` +# /etc/dnsmasq.d/hal-dns.conf — Generated by HAL dnsmasq-app +address=/novox.internal/10.10.0.1 +address=/ace.internal/10.10.0.2 +address=/g14.internal/10.10.0.4 +address=/shanks.internal/10.10.0.3 +``` + +Checked against what the mesh itself recorded when it took the tunnel over (`overlay show`): + +``` +a peer of the tunnel (zTKYP6Sz…) 10.10.0.2 not yet enrolled +a peer of the tunnel (XT1l25Z0…) 10.10.0.3 not yet enrolled +a peer of the tunnel (mq76YPW0…) 10.10.0.4 not yet enrolled +``` + +`10.10.0.2`/`.3`/`.4` match `ace`/`shanks`/`g14` exactly, one for one. This is not the operator +inventing a fact under time pressure — it is the predecessor's own record, current, and it has been +correctly serving these three names for six days without correction. Recording it is transcription, +not assertion. + +**located-in, tentatively:** `mesh-controller internal/inventory` (where a carried peer's record +lives today — `CarriedPeer`/`TunnelPeer` in `tunnel.go` carry a public key and an address but no +name field) and `cmd/mesh-controller` (a command to set it — nothing today lets an operator attach +a name to a carried-tunnel-peer record; `node add` is for enrolling nodes, not naming peers, and +`node public-domain ` is the closest existing shape to model a new verb on). Separately, +`mesh-controller internal/catalogue` (`facts.go`'s `nodeZones`) would then need to emit an +`address=` wildcard for a *named carried peer* the same way it does for a node — it renders only +from the mesh's `addresses` map today, keyed by node name, and does not distinguish a named carried +peer from an unnamed one. `mesh-catalog modules/dnsmasq` itself needs no change: it already +restarts on the `node-zones` fact and would pick up the new wildcard the moment `internal/catalogue` +emits it. + +## What is still open + +- The mechanism for *recording* the name is not designed — a new field on the carried-peer record, + a new CLI verb, and what happens if the name later disagrees with what the peer states on + enrolling (it should win; nothing says so yet). +- Whether this generalises: the predecessor's static hosts file was the answer *here* because it + happened to be readable and correct. A migration without one still has the report's harder second + option (refuse the resolver until every peer enrols) as its fallback. +- Not implemented. This diagnosis is what the fix would touch and why the ADR 0104 framing in the + report's third option does not transfer directly — not the fix itself.