sots-re/verify/harness/cb/cbmenu.py
alex 954f3cec63 CB: the turn-command stream, captured and bound to the autosave it produced
Canonical pair turn2->turn3: the complete block set, the three heap payloads no
previous capture could read (route [272], list-10 [1728], the 24-byte Population
body), the three AI client seeds, and both output autosaves -- byte-identical to the
published oracle AND to this lane's own hooks=off control, so the stream and the save
come from the same run and the instrument did not change the turn it recorded.

Creation turn turn1->turn2: three runs. Pinning the AI client seeds to the values an
earlier run observed made a DIFFERENT process reproduce that run's block -- including
the research pick that varies -- and its autosave byte for byte. The workload three
lanes could not reproduce is reproducible given the seeds.

Two corrections to lane L4's list-23 reading (no trailing int; the body is not
turn-dependent) and one to my own list-5 record, the latter found by lane RB while
consuming this capture.

Format: JSON (raw words are ground truth, decoded is a typing) plus lane RB's own .tcb
grammar with the heap payloads filled in, so RB's reader consumes it unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARBgSooAfokKUy6wKUKEyZ
2026-09-08 19:18:57 -04:00

31 lines
1.4 KiB
Python

#!/usr/bin/env python3
"""Poll VM146's framebuffer until the main menu's red buttons are up. Never sleep-and-click:
the >60 s startup has cost this campaign at least five wasted runs, and it is on the board four
times. A run that clicks into the Kerberos intro reads exactly like a run whose clicks did nothing.
"""
import subprocess, sys, time, glob, os
from PIL import Image
DEADLINE = float(sys.argv[1]) if len(sys.argv) > 1 else 240.0
t0 = time.time()
while time.time() - t0 < DEADLINE:
subprocess.run(["uv", "run", "--with", "pillow", "python3", "tools/vmshot.py",
"--ssh", "--one", "146"], capture_output=True, check=False)
shots = sorted(glob.glob("dumps/vmshot/vm146-*.png"), key=os.path.getmtime)
if shots:
im = Image.open(shots[-1]).convert("RGB")
# The button column: Profiles..Exit sit at x 455-570, y 405-695, and are a saturated red
# only when the menu has actually rendered.
red = 0
for y in range(405, 695, 3):
for x in range(455, 570, 3):
r, g, b = im.getpixel((x, y))
if r > 110 and r > g * 2 and r > b * 2:
red += 1
print(f"t+{time.time()-t0:5.0f}s red={red} {os.path.basename(shots[-1])}", flush=True)
if red > 400:
print("MENU UP")
sys.exit(0)
time.sleep(6)
print("MENU NOT SEEN -- do not click")
sys.exit(1)