test: add an end-to-end drill against a real Incus #18

Merged
dan-claude-bot merged 3 commits from drill/rehearsal into main 2026-07-13 21:34:44 +00:00

3 commits

Author SHA1 Message Date
aba7015e53 test: fold the #15 audit into the drill — sibling probes and a hardening rehearsal
The drill covered the CLI surface and basic egress but never probed the
one claim everything hinges on: it only ever had one box running, so
sibling isolation — #12's central, never-reproduced finding — went
untested. Phase C now clones a peer and probes box-to-box reachability
(with a listener, so "refused" cannot masquerade as "dropped"), DNS
enumeration, IPv6-off, and host-to-box inbound. A new phase D applies
the exact changes #16 proposes (dns.mode=none, NIC filtering, @internal)
and watches what breaks — a FAIL there is a design veto caught before
the code is written. The run ends with an answers block to paste into
issue #15.

Also: defaults now install heavy-duty/claudebox@main (the old default
pointed at a fork branch that stopped moving when #13 merged), the
version check compares against the installed VERSION file instead of a
hardcoded 0.3.0, and the blind sleep after start became an agent poll.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:30:47 +00:00
69eff180d4 fix: setup-host installs nftables when neither nft nor UFW exists
A stock Debian 13 cloud image ships neither, so the no-UFW firewall path
died on its first nft call — on exactly the kind of fresh cloud host the
tool targets. Found by the drill; the drill's manual workaround becomes a
regression tripwire.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 21:30:47 +00:00
c1ca981f46 test: add an end-to-end drill against a real Incus
The repo has no tests and no CI, and everything in #9/#10/#13 was verified
against a stubbed incus. The interesting failures aren't in the bash — they're
in what Incus actually does, which is exactly what a stub gets wrong. So the
drill runs the real thing on a host you can format.

  A. Incus semantics — the assumptions claudebox is built on, probed directly:
     the user.claudebox=1 tag read (now on the path of every box command in
     #13), the list filter, the CSV shape, the state string, whether rename
     really refuses a running instance, the snapshot-list field order.
  B. The claudebox surface — mint, list, info, snapshot, clone-from-snapshot-of-
     a-renamed-box, rename, the escape hatch, the rm guard, the CLI contract —
     and the boundary: an instance claudebox did NOT mint has down/rm/hatch
     aimed at it, must refuse all three, and must still be standing after.
  C. Isolation — from inside a real box: public egress works, box → host is
     blocked, box → RFC1918 is dropped.

Destructive by design, and it says so before it starts: it asks for consent
(--yes to skip), and refuses outright with no TTY. Without /dev/kvm it reports
that the VM trust boundary was NOT validated rather than passing on a container.
2026-07-13 21:15:56 +00:00