From 6ecd03694b207cd37c44446b85971508290842ce Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 31 Aug 2026 14:11:34 +0200 Subject: [PATCH] Issue 019: a comment asserting a fact about a machine, which nothing checked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Twice in one file, a statement about a machine that read as reasoned and was wrong — and the module's unit tests all passed while the daemon could not start. That is what a unit test is: it confirms the assertion was made, never that it is true of any machine. 003 in prose rather than in a manifest key. --- .../00-report.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 04-ISSUES/019-a-comment-asserting-a-fact-about-a-machine/00-report.md diff --git a/04-ISSUES/019-a-comment-asserting-a-fact-about-a-machine/00-report.md b/04-ISSUES/019-a-comment-asserting-a-fact-about-a-machine/00-report.md new file mode 100644 index 0000000..5ee6ae4 --- /dev/null +++ b/04-ISSUES/019-a-comment-asserting-a-fact-about-a-machine/00-report.md @@ -0,0 +1,59 @@ +--- +status: resolved +opened: 2026-08-31 +located-in: [mesh-control] +fixed-by: mesh-control — the resolver module's claims about machines are checked on a machine +amended-design: +--- + +# 019 — A comment asserting a fact about a machine, which nothing checked + +## Symptom + +The resolver module carried two statements about the machine it runs on. Both read as reasoned, +both were in prose beside the setting they justified, and **both were wrong**: + +| it said | the machine said | +|---|---| +| `127.0.0.54` is free — "not `.53`, that is systemd-resolved's" | systemd-resolved holds **both**; `.54` is its proxy stub. dnsmasq could not create the socket and never started | +| it takes only `127.0.0.55` | listening on a loopback address takes the rest of loopback with it, `127.0.0.1` included | + +A third statement in the same file was true and incomplete in a way that mattered as much: the +config read `/etc/resolv.conf` for upstreams without saying so, and the module that points a +machine at the mesh writes *this resolver's own address* into that file. So its upstream was +itself. Its receive queue filled with 15KB of queries and every lookup on the machine hung. + +## Why this matters + +**The module had unit tests, and they all passed.** They checked that it names an address, that it +reads what the mesh writes, that it restarts when that changes, and that the two asking modules +point where it answers. Every one of those was true while the daemon could not start at all. + +That is not a gap in those tests. It is what a unit test *is*: it confirms the assertion was made, +never that it is true of any machine. **Only a machine knows which of its addresses are spare, or +what a daemon does with a file when it starts.** + +This is [04-ISSUES/003](../003-firewall-scope-is-read-by-no-code/00-report.md) in prose rather +than in a manifest key. There, five manifests carried a `scope:` that read as a restriction and +restricted nothing. Here, a comment read as a reasoned choice of address and chose a taken one. In +both cases *an unenforced rule is indistinguishable from a wrong one, and costs more, because +people believe it* — and a comment is the least enforced rule there is. + +**It cost three full lab cycles**, at fifteen minutes each, because each one revealed exactly one +of the three faults. + +## What was done + +**The wrong statements are corrected, and the correction says what it now knows rather than +asserting a new comfort.** `.55` is written down as *a convention, not a reservation*: if a future +systemd takes it, one line changes. What the module takes is what its claim already said — the +machine's DNS port — rather than a promise about one address. + +**The unit tests hold what a machine has told us.** They assert the module does not take `.53`, +`.54` or `127.0.0.1`, and that it does not read resolv.conf for upstreams. A unit test cannot +discover those facts; it can refuse to forget them. + +**And the order changed.** A module that asserts something about machines is proven on a machine +*before* its assertions are believed — the lab test written first, not last. Written here because +the cost of the old order is measurable: three cycles, forty-five minutes, for a module whose +mesh-side half was correct from the start.