Fix two ways the vmbox harness went green while broken

Trimming the harness to the three surviving cases took `pacman -S tk` with it,
and that step was doing two jobs nobody had written down.

It was the guest's BOOT. `vm new`/`vm reset` leave a sandbox stopped and there
is no `vm up`, so the first `vm run` is what starts it; `vm repo` then failed
with "sandbox is not running". The pacman step is restored with that spelled
out, so the next person to prune it knows what else they are removing.

And tk is still genuinely required, despite the Tk alarm window being gone:
`_state` imports `gatelock.log_integrity` for the HMAC, and gatelock's
`__init__` imports tkinter at module scope, so `import gatelock` dies with
"libtk8.6.so: cannot open shared object file". Measured in the guest.

The second fix is the one that matters. `run_install` trusted `vm run`'s exit
code, but `vm run` reports the VM's verdict rather than the guest command's
status -- the same fail-open `guest_cases.sh` already guards against with its
ALL-CASES-PASSED sentinel. So install.sh died on that ImportError, the step
reported success, and the three cases downstream failed with no hint that the
install was the cause. It now confirms an INSTALL-OK marker in the output.

Harness passes: imports-from-system-python, trigger-timer-enabled,
trigger-dry-run. That run exercised the new install.sh end to end, including
its call into uninstall.sh --retired-only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PcdngP688mW6rJye3LRkSN
This commit is contained in:
Krzysztof Rudnicki 2026-08-30 15:33:35 +02:00
parent e67cef0c54
commit a573b1b9d6

View File

@ -28,6 +28,14 @@ readonly REPO_DIR
SCRIPT_NAME="$(basename "$0")"
readonly SCRIPT_NAME
# The guest image lacks tk, and it is NOT optional even though the alarm's Tk
# window is gone: `_state` imports `gatelock.log_integrity` for the HMAC, and
# `gatelock/__init__.py` imports tkinter at module scope, so `import gatelock`
# dies with "libtk8.6.so: cannot open shared object file" without it. Measured
# in the guest, not guessed -- dropping this package is what broke the harness
# when the alarm window was deleted.
readonly GUEST_PACKAGES="tk"
# Printed by guest_cases.sh only when every case passed. See run_cases().
readonly GUEST_OK_SENTINEL="ALL-CASES-PASSED"
@ -83,6 +91,13 @@ provision_sandbox() {
step "Sharing the repo with the guest"
vm share "$REPO_DIR" >/dev/null
# `vm new`/`vm reset` leave the sandbox STOPPED, and there is no `vm up`;
# `vm run` is what boots it, and `vm repo` needs it running.
step "Installing guest packages ($GUEST_PACKAGES)"
vm run "$VM_NAME" \
"sudo pacman -S --noconfirm --needed $GUEST_PACKAGES" >/dev/null ||
die "could not install guest packages"
# --worktree, not a clone: the point of the gate is to test the edits in
# front of you, including the ones not committed yet.
step "Copying the working tree into the guest"
@ -94,7 +109,14 @@ provision_sandbox() {
# the same install.sh a machine runs, so a break in it fails the gate.
run_install() {
step "Running install.sh in the guest"
if ! vm run "$VM_NAME" 'cd ~/wake-alarm && bash install.sh' >/tmp/wa-install.log 2>&1; then
# `vm run` reports the VM's verdict, not the guest command's exit status,
# so this must confirm success from the OUTPUT. Trusting the exit code let
# a guest ImportError through as a pass, and the three cases downstream
# then failed with no hint that the install was the cause.
vm run "$VM_NAME" \
'cd ~/wake-alarm && bash install.sh && echo INSTALL-OK' \
>/tmp/wa-install.log 2>&1 || true
if ! grep -q 'INSTALL-OK' /tmp/wa-install.log; then
tail -20 /tmp/wa-install.log >&2
die "install.sh failed in the guest (full log: /tmp/wa-install.log)"
fi