fix: a failed cold mint must say why; doctor gains DNS diagnosis and --pin-dns #34

Merged
dan-claude-bot merged 1 commit from drill/doctor-dns into main 2026-07-14 01:01:35 +00:00
dan-claude-bot commented 2026-07-14 00:55:40 +00:00 (Migrated from github.com)

Two cold mints in a row died with cloud-init status: error on a host doctor.sh had just certified clean. So the failure is reproducible, not transient, and my earlier "leftover mutations poisoned the network" theory is dead — the doctor disproved it in ten seconds, which is what it is for.

claudebox new now says what went wrong

It printed four hundred dots and the word error. The reason was sitting in the box's own log and nobody was told the log existed — diagnosing it took three commands the user had to be handed. Now, on failure, it prints cloud-init status --long, greps the fetch/resolve errors out of /var/log/cloud-init-output.log, and tells you the box is still up for inspection (a box that failed to build is evidence, not garbage). It also names the usual suspect: the host's resolver, with a pointer to #33.

doctor.sh gains the diagnosis, and the test

  • Host resolver section — what /etc/resolv.conf points at, and whether that is a CGNAT/Tailscale resolver the boxes inherit (#33). Flags it as DIRTY when it is.
  • The question that settles it, asked inside the box: DNS is broken — but can it still reach 1.1.1.1 by address? If yes, egress works and the fault is purely the inherited forwarder. That single probe separates "the network is broken" from "name resolution is broken", which is the distinction three runs have been confused by.
  • --pin-dns applies #33's proposed fix so it can be tested rather than argued:
    incus network set claudenet raw.dnsmasq "no-resolv\nserver=1.1.1.1\nserver=8.8.8.8"
    
    dnsmasq then ignores the host's /etc/resolv.conf entirely.

The run that decides #33

cd claudebox && git pull
bash drill/doctor.sh              # will report the host's resolver + probe the failed 'drill' box
bash drill/doctor.sh --pin-dns    # apply the #33 fix
bash drill/doctor.sh --fix        # clear the dead box
bash drill/drill.sh --yes

If the cold mint now succeeds, #33 is confirmed and the fix belongs in setup-host.sh unconditionally. If it fails the same way, raw.dnsmasq is the wrong lever and #33 needs a different mechanism — and the doctor will have said so rather than leaving us to guess.

🤖 Generated with Claude Code

Two cold mints in a row died with `cloud-init status: error` **on a host `doctor.sh` had just certified clean**. So the failure is **reproducible, not transient**, and my earlier "leftover mutations poisoned the network" theory is dead — the doctor disproved it in ten seconds, which is what it is for. ## `claudebox new` now says what went wrong It printed four hundred dots and the word `error`. The reason was sitting in the box's own log and nobody was told the log existed — diagnosing it took three commands the user had to be handed. Now, on failure, it prints `cloud-init status --long`, greps the fetch/resolve errors out of `/var/log/cloud-init-output.log`, and tells you the box is **still up** for inspection (a box that failed to build is evidence, not garbage). It also names the usual suspect: the host's resolver, with a pointer to #33. ## `doctor.sh` gains the diagnosis, and the test - **Host resolver section** — what `/etc/resolv.conf` points at, and whether that is a **CGNAT/Tailscale resolver the boxes inherit** (#33). Flags it as DIRTY when it is. - **The question that settles it**, asked inside the box: DNS is broken — but can it still reach **`1.1.1.1` by address**? If yes, egress works and the fault is *purely* the inherited forwarder. That single probe separates "the network is broken" from "name resolution is broken", which is the distinction three runs have been confused by. - **`--pin-dns`** applies #33's proposed fix so it can be **tested rather than argued**: ```sh incus network set claudenet raw.dnsmasq "no-resolv\nserver=1.1.1.1\nserver=8.8.8.8" ``` dnsmasq then ignores the host's `/etc/resolv.conf` entirely. ## The run that decides #33 ```sh cd claudebox && git pull bash drill/doctor.sh # will report the host's resolver + probe the failed 'drill' box bash drill/doctor.sh --pin-dns # apply the #33 fix bash drill/doctor.sh --fix # clear the dead box bash drill/drill.sh --yes ``` If the cold mint now succeeds, **#33 is confirmed** and the fix belongs in `setup-host.sh` unconditionally. If it fails the same way, `raw.dnsmasq` is the wrong lever and #33 needs a different mechanism — and the doctor will have said so rather than leaving us to guess. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/box#34
No description provided.