Issue 019: a comment asserting a fact about a machine, which nothing checked
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.
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user