fix(drill): stop poisoning the host, and add a doctor to prove it #32

Merged
dan-claude-bot merged 1 commit from drill/doctor into main 2026-07-14 00:33:31 +00:00
dan-claude-bot commented 2026-07-14 00:32:05 +00:00 (Migrated from github.com)

Run 8's cold mint died with cloud-init status: error. The box could not resolve deb.debian.org — or claude.ai, or anything:

Err:1 http://deb.debian.org/debian trixie/main amd64 libcares2
  Temporary failure resolving 'deb.debian.org'
curl: (6) Could not resolve host: claude.ai

The cause was not in that run. Run 7's phase D set dns.mode=none on claudenet, the run ended before reverting it, and every box minted afterwards came up with no DNS.

This is the worst failure mode the drill has

A poisoned host does not fail the next run honestly — it produces confident wrong answers. It is how the false L2 filtering BREAKS the box — design veto reached #16, and it cost a cold mint plus an hour of diagnosis aimed at code that was never broken.

Three defences:

  1. The phase-D revert is armed with a trap before the first mutation — it fires on any exit, Ctrl-C included. Previously it only ran if the run reached the end, which is exactly the case that doesn't need it.
  2. The revert is verified, not fired into /dev/null. A failed unset could not be told from a successful one; now the drill checks and says so loudly.
  3. The drill refuses to start on a host still carrying the mutations, reverting them first and aborting if it cannot.

drill/doctor.sh — the question that kept getting answered by hand

bash drill/doctor.sh          # is this host fit to drill?
bash drill/doctor.sh --fix    # revert what an aborted run left behind

Reports: claudenet's dns.mode / IPv4 / IPv6-off contract, the profile NIC's filtering flags, the ACL's rules (including a stray @internal), leftover drill boxes, and — the cheapest real test — whether a box can still resolve DNS and reach the gateway. It also detects a wedged Incus daemon and prints the recovery from #26.

Every diagnostic command I have been pasting into chat all day now lives in the repo, which is where it should have been from the start.

For the current host

cd claudebox && git pull && bash drill/doctor.sh --fix && bash drill/doctor.sh && bash drill/drill.sh --yes

🤖 Generated with Claude Code

Run 8's cold mint died with `cloud-init status: error`. The box could not resolve `deb.debian.org` — or `claude.ai`, or anything: ``` Err:1 http://deb.debian.org/debian trixie/main amd64 libcares2 Temporary failure resolving 'deb.debian.org' curl: (6) Could not resolve host: claude.ai ``` **The cause was not in that run.** Run 7's phase D set `dns.mode=none` on `claudenet`, the run ended before reverting it, and **every box minted afterwards came up with no DNS.** ## This is the worst failure mode the drill has A poisoned host does not fail the next run honestly — it produces **confident wrong answers**. It is how the false `L2 filtering BREAKS the box — design veto` reached #16, and it cost a cold mint plus an hour of diagnosis aimed at code that was never broken. Three defences: 1. **The phase-D revert is armed with a `trap` before the first mutation** — it fires on any exit, `Ctrl-C` included. Previously it only ran if the run reached the end, which is exactly the case that doesn't need it. 2. **The revert is verified, not fired into `/dev/null`.** A failed `unset` could not be told from a successful one; now the drill checks and says so loudly. 3. **The drill refuses to start on a host still carrying the mutations**, reverting them first and aborting if it cannot. ## `drill/doctor.sh` — the question that kept getting answered by hand ```sh bash drill/doctor.sh # is this host fit to drill? bash drill/doctor.sh --fix # revert what an aborted run left behind ``` Reports: `claudenet`'s `dns.mode` / IPv4 / IPv6-off contract, the profile NIC's filtering flags, the ACL's rules (including a stray `@internal`), leftover drill boxes, and — the cheapest real test — **whether a box can still resolve DNS and reach the gateway**. It also detects a wedged Incus daemon and prints the recovery from #26. Every diagnostic command I have been pasting into chat all day now lives in the repo, which is where it should have been from the start. ## For the current host ```sh cd claudebox && git pull && bash drill/doctor.sh --fix && bash drill/doctor.sh && bash drill/drill.sh --yes ``` 🤖 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#32
No description provided.