Two jobs, deliberately ordered. First: run real linux_configuration work through the sandbox (the 8 Arch-only CI tests, night-lockdown, boot_recovery, the hosts guard) and fix vmbox wherever it breaks -- it has only ever been driven by one session against a handful of scripts, so the ~1090-file surface will find things. Second, and only if the first says vmbox is trustworthy: the CLAUDE.md rule that routes script testing here by default. A rule pointing at a flaky tool is worse than no rule, so that ordering is the point. Four questions have to be settled before writing it -- what triggers it, whether it replaces or precedes the host run (see feedback-verify-real-deployment-path), the hardware escape hatch, and keeping it short since CLAUDE.md is always-on context. Carries forward the traps that cost real time this session: diagnose an unreachable guest with `systemctl list-jobs`, never grep a bash -x trace for the failure, and fix the image live over the serial console rather than rebuilding once per hypothesis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdyMBGCrGVGDWtJ9xe48f3
6.0 KiB
Next session: make vmbox the default place scripts get tested
Paste everything below into a fresh Claude session.
~/utils/vmbox is a working disposable-Arch-VM sandbox (built and verified
2026-08-22, pushed to github.com/kuhyx/utils). Read ~/utils/vmbox/README.md
first — it documents the design and the traps.
Two jobs this session, in order.
Job 1: harden it by using it for real
vmbox has only ever been driven by one session, against a handful of scripts.
testsAndMisc/linux_configuration is ~1090 files, ~170 of which need root.
Expect it to break. That is the point of this job: find the breakages by
running real work through it, and fix them.
Work through this list, fixing vmbox whenever it gets in the way:
- The 8 Arch-only tests the repo's CI already names in
.github/workflows/shell-tests.yml(arch-testsjob) —test_hosts_*,test_makepkg_*,test_pacman_wrapper_security.sh,test_security_hardening.sh,test_shutdown_timer_monitor.sh. These are the ones its comments say "cannot run on an Ubuntu runner". Run them in a sandbox and report which pass. test_security_hardening.shspecifically: on a bare guest it reports its host checks as skipped. Install the real system first (install_core_system.sh), then re-run it, so those checks become real.setup_night_lockdown.sh— writes/etc/systemd/systemunits and an i2c module config. The i2c RGB part is hardware and will not work; confirm everything else does.boot_recovery/install.sh— pacman hooks + mkinitcpio. Highest blast radius of anything in the repo, and the best argument for the sandbox.- The hosts guard (
periodic_background/hosts/install.sh) — rewrites/etc/hostsand makes it immutable withchattr +i. Verify the immutable flag really lands in the guest, then thatvm resetclears it.
For each: vm share what it needs, clone into the guest, run it, report what
happened. When vmbox itself is the thing that broke, fix vmbox and commit.
Known-good invocation shape
vm share ~/testsAndMisc # bind mount, NOT a symlink (9p won't follow one)
vm share ~/utils # guard-lib lives here; several scripts need guardctl
vm new t1 --rtc 2026-08-22T20:55:00 # pin the clock: shutdown scripts gate on 21:00-05:00
vm run t1 'git clone --no-hardlinks -q /mnt/hostrepo/testsAndMisc ~/tam'
vm run t1 'echo y | sudo bash ~/tam/path/to/script.sh enable' # many prompt; stdin is closed
vm reset t1 # ~2s back to pristine
Traps already paid for — do not rediscover these
- A guest that boots but refuses ssh is almost never a network problem.
Run
systemctl list-jobson the guest viavm sshor the serial console. A unit that is enabled, has satisfied dependencies, and neither starts nor fails is QUEUED behind something. That cost most of a session. - Never grep a
bash -xtrace for the failure — you find where your pattern matched, not where execution stopped. Read the tail. pkill -f <pattern>kills the Bash-tool shell when the pattern appears in the command running it (exit 144). Usepgrep -f | xargs -r kill.- Full list:
~/.claude/projects/-home-kuhy/memory/reference-vmbox-guest-image-traps.mdandreference-qemu-shutdown-verification.md.
Rebuilding the image
vm build --force takes ~10 min. It ends with a smoke test that boots a real
sandbox and refuses to ship an unreachable image. Do not debug the image by
rebuilding per hypothesis — boot an overlay off the current base, fix it live
over the serial console (root autologin is on ttyS0 and ttyS1), confirm the
fix, and only then bake it into guest/provision.sh and rebuild once.
Job 2: make it the default, once Job 1 says it is trustworthy
kuhy's ask: "claude should ALWAYS defer to using this sandbox when testing stuff, ESPECIALLY when testing scripts."
Do Job 2 only after Job 1. A rule that routes work into a tool that breaks is worse than no rule. If Job 1 leaves vmbox flaky, say so and stop.
The rule belongs in ~/.claude/CLAUDE.md. Points to settle with kuhy before
writing it — these are real forks, not rhetorical:
- What triggers it. "Any script" is too broad: it would send a one-line
python_pkgunit test through a VM boot. A sharper line is anything that needs root, writes outside$HOME, touches systemd/pacman//etc, or could power the machine off. - What it replaces. Today's
CLAUDE.mddevelopment workflow says "run the actual script to verify it does what it is supposed to do". Does the sandbox become the first run, or an extra step before the host run? Note the standingfeedback-verify-real-deployment-pathmemory: testing somewhere that is not the real deploy target has burned kuhy before, so a sandbox pass must NOT be presented as proof the host is fine. - The escape hatch. Anything hardware-bound (adb/phone, GPU, i2c, the Huion tablet) cannot run in a VM. The rule needs a stated exception, or it will be violated on the first phone task and quietly stop being followed.
- Where it lives.
CLAUDE.mdis always-on context, so keep it to a few lines and link out. Pertoken-spend.instructions.md, a long rule there is a permanent per-turn tax.
Draft it, get kuhy's sign-off on those four points, then write it.
Definition of done
- The 5 items in Job 1 have been run in a sandbox, with results reported per item (pass / fail / not-applicable-in-a-VM, with reasons).
- Every vmbox bug found is fixed, committed, and pushed.
bats ~/utils/vmbox/tests/test_vmbox.bats, shellcheck and ruff all clean.- Either the CLAUDE.md rule is written and agreed, or there is a clear statement of what still makes vmbox untrustworthy.
State as of handoff
Verified working: the shutdown verdict (5 outcomes, all measured against real guests), destructive demo 7/7, reset ~2s, VM-to-VM ping (0% loss), screenshots, pinned clock, repo share + clone, base-corruption guard, build smoke gate.
Unverified / not attempted: everything in Job 1 above; anything hardware-bound; concurrent sandboxes beyond two.