re: WITHDRAW the (A)-press finding -- three emulators were live at once
While chasing the draw-stream question I found THREE xenia instances running simultaneously (started 15:39, 15:44, 16:12), which violates the "one emulator at a time" hard rule and confounds the finding I recorded last iteration. All three read the same /tmp/xenia_pad.txt and share display :98. A press written to that file is delivered to EVERY instance, while `screenshot` grabs whichever window is topmost -- not necessarily the one that acted on it. So "(A) was delivered and the screen did not change" may simply be two different emulators, and the keystroke-level confirmation proves only that SOME instance received it. The navigation.md entry claiming the boot title's "2 of 2" is no longer 2 of 2 is withdrawn as unsupported, pending a clean re-run. The cause was mine. run-canary's lockfile is the IMPLEMENTATION of the one-at-a- time rule; a kill -9 orphans it, and the obvious unblock -- rm -f the lock -- also disables the guard for every later launch. I did that more than once today. METHOD gains two entries. A lockfile is the rule, not an obstacle to it: clear a stale lock only after confirming zero live instances, and COUNT them rather than trusting a kill landed, because a plain kill is asynchronous and a -9 on a stuck process can take seconds. When a guard blocks you, the question is whether the condition it guards against is present, not how to remove the guard. And a third instance of pgrep -f matching the shell that runs it -- this time it killed a cleanup command halfway through, leaving the emulators alive and the lock in place. Already recorded for wait-loops; promoted to "reach for -C first". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
@@ -321,7 +321,21 @@ Traps that read as bugs but are not, all measured ✅:
|
||||
if you must use `-9`, `rm -f /tmp/xenia-canary.lock` after. **And assert the
|
||||
emulator is alive before entering any wait loop** — `ps -C xenia_canary` — so
|
||||
the loop cannot spend its whole deadline on nothing.
|
||||
* 🔴 **Ⓐ on a settled boot title does NOT reliably reach the menu.** This page's
|
||||
* 🔴🔴 **THE ENTRY BELOW IS WITHDRAWN — the experiment was confounded.** When it
|
||||
ran, **three emulators were live at once** (started 15:39, 15:44 and 16:12 on
|
||||
2026-08-30), all reading the same `/tmp/xenia_pad.txt` and sharing display `:98`.
|
||||
A press written to that file is delivered to **every** instance, and `screenshot`
|
||||
grabs whichever window is topmost — which need not be the one that acted on it.
|
||||
So "Ⓐ was delivered and the screen did not change" may simply be *two different
|
||||
emulators*, and the keystroke-level confirmation proves only that **some**
|
||||
instance received it. ⚠️ The cause was mine: `run-canary`'s lockfile is the
|
||||
implementation of the "one emulator at a time" rule, and I had been clearing it
|
||||
with `rm -f` to get past a stale one — which disables the guard for the next
|
||||
launch too. **Clear a stale lock only after confirming zero live instances**
|
||||
(`ps -C xenia_canary --no-headers | wc -l`). The claim below is unsupported and
|
||||
needs a clean re-run before anyone relies on it.
|
||||
|
||||
* ~~🔴 **Ⓐ on a settled boot title does NOT reliably reach the menu.**~~ This page's
|
||||
§1 and `canary-scripted-input-traps.md` record "the boot title accepts a single
|
||||
Ⓐ (2 of 2 runs)". A run on 2026-08-30 gated on the **plate pulse** (glyph in
|
||||
[500, 2500] held 12 consecutive samples), fired at t=484.5 s with glyph 1723 —
|
||||
|
||||
@@ -355,6 +355,27 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
|
||||
element animates, confirm the element **draws there** — from a leaf sweep, a draw
|
||||
capture, or the rendered quad's own coordinates. A pivot is not a bounding box.
|
||||
|
||||
* **A lockfile IS the rule, not an obstacle to it.** `run-canary` holds
|
||||
`/tmp/xenia-canary.lock` to enforce "one emulator at a time". A `kill -9` orphans
|
||||
it, and the obvious unblock — `rm -f` the lock — **also disables the guard for
|
||||
every later launch**. Doing that repeatedly left **three emulators live at once**
|
||||
on 2026-08-30, all reading the same `/tmp/xenia_pad.txt` and sharing display
|
||||
`:98`. A scripted press then reaches *every* instance while `screenshot` grabs
|
||||
whichever window is topmost, so "the input was delivered and nothing happened"
|
||||
became unfalsifiable — and a finding built on it had to be withdrawn. ⚠️ **Clear
|
||||
a stale lock only after confirming zero live instances**, and count them
|
||||
(`ps -C xenia_canary --no-headers | wc -l`) rather than trusting that a kill
|
||||
landed: a plain `kill` is asynchronous and a `-9` on a stuck process can take
|
||||
seconds. **When a guard blocks you, the question is whether the condition it
|
||||
guards against is present — not how to remove the guard.**
|
||||
|
||||
* ⚠️ **`pgrep -f` / `pkill -f` match the shell that runs them.** Already recorded
|
||||
here for wait-loops; it has now also killed a cleanup command mid-way and, in a
|
||||
third instance, a launcher. Any `-f` pattern that appears in your own command
|
||||
line matches your own process. Kill by process **name** (`ps -o pid= -C name`),
|
||||
or exclude `$$`. Three instances in one session is not a footnote — reach for
|
||||
`-C` first and use `-f` only when the name genuinely is not enough.
|
||||
|
||||
## Runtime / emulator
|
||||
|
||||
* **Look at the PNG** — and check its dimensions.
|
||||
|
||||
35
tools/re-capture/title_draw_capture.sh
Executable file
35
tools/re-capture/title_draw_capture.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Does the game DRAW the sweep leaves (pteff03 / pteff03a) on a SETTLED title?
|
||||
#
|
||||
# ui-resting-pose.md records a tension: two renders one plateau-phase apart differ
|
||||
# by RMSE 11.9 INSIDE the adjudication box, while two captures of that screen from
|
||||
# different sessions differ by 0.32 there, and an --at sweep against a capture is
|
||||
# flat to 1.2. A metric cannot be insensitive to an 11.9 change unless what
|
||||
# changed is largely absent from what it is compared against.
|
||||
#
|
||||
# The leaves are a 400 px-wide strip at scale (100, 600) / (100, 800) -- 1080 and
|
||||
# 1440 px tall, taller than the screen. If the game draws them and they free-run,
|
||||
# the draw stream shows a tall strip whose x translates frame to frame. That is
|
||||
# unmistakable, and the plate's own pulsing is the in-capture control that the
|
||||
# instrument is seeing real variation rather than one frozen frame.
|
||||
set -u
|
||||
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
|
||||
SD="$(cd "$(dirname "$0")" && pwd)"
|
||||
OUT="${1:-/sylph-home/re/titledraw}"; mkdir -p "$OUT"; rm -f "$OUT"/xenia_re_ui_draws_*.log
|
||||
ps -o pid= -C xenia_canary | xargs -r kill; rm -f /tmp/xenia-canary.lock
|
||||
( cd "$OUT" && nohup run-canary --mem_watch=false --log_ui_draws=true \
|
||||
--ui_draw_capture_frames="${FRAMES:-150}" --ui_draw_capture_max=400000 \
|
||||
--logged_profile_slot_0_xuid=B13EBABEBABEBABE \
|
||||
>"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & )
|
||||
sleep 10
|
||||
ps -C xenia_canary >/dev/null 2>&1 || { echo "EMULATOR DID NOT START:"; tail -3 "$OUT/canary.stderr"; exit 4; }
|
||||
until xdotool search --name "Xenia-canary" >/dev/null 2>&1; do sleep 1; done
|
||||
win="$(xdotool search --name "Xenia-canary" | tail -1)"
|
||||
python3 "$SD/wait_plate_pulse.py" 900 || exit 1
|
||||
xdotool windowactivate --sync "$win"; sleep 1
|
||||
xdotool key F10; sleep 0.6
|
||||
xdotool mousemove 900 400 click 1
|
||||
sleep 12
|
||||
grep -i "UI-CAP" "$OUT/canary.stdout" | tail -3
|
||||
ls -l "$OUT"/xenia_re_ui_draws_*.log 2>/dev/null || echo "NO CAPTURE LOG"
|
||||
echo "TITLE DRAW CAPTURE DONE"
|
||||
52
tools/re-capture/wait_plate_pulse.py
Executable file
52
tools/re-capture/wait_plate_pulse.py
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Block until the title's Ⓐ-plate says the screen has SETTLED, then exit 0.
|
||||
|
||||
The same gate `jp_title_capture.py` uses: the green plate glyph count inside a
|
||||
band, HELD for 12 consecutive samples (~3 s at 4 fps). A single `screen_id.py`
|
||||
classification is not enough -- it fires on the ATTRACT loop's title, which
|
||||
accepts no input, and a probe that pressed Ⓐ there concluded nothing for 484 s.
|
||||
|
||||
Exit 0 when settled, 2 on timeout.
|
||||
|
||||
wait_plate_pulse.py [wait_s]
|
||||
"""
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
|
||||
W, H = 1280, 720
|
||||
NEED, CEIL, HOLD = 500, 2500, 12
|
||||
WAIT = float(sys.argv[1]) if len(sys.argv) > 1 else 900
|
||||
|
||||
|
||||
def _open():
|
||||
return subprocess.Popen(
|
||||
["ffmpeg", "-loglevel", "error", "-f", "x11grab", "-draw_mouse", "0",
|
||||
"-video_size", f"{W}x{H}", "-i", ":98", "-r", "4",
|
||||
"-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
|
||||
stdout=subprocess.PIPE, bufsize=W * H * 3 * 2)
|
||||
|
||||
|
||||
def glyph(a):
|
||||
r, g, b = a[:, :, 0], a[:, :, 1], a[:, :, 2]
|
||||
return int(((g > 130) & (g - r > 45) & (g - b > 45)).sum())
|
||||
|
||||
|
||||
T0 = time.time()
|
||||
p, n, seg, streak = _open(), W * H * 3, time.time(), 0
|
||||
while time.time() - T0 < WAIT:
|
||||
if time.time() - seg > 30:
|
||||
p.kill(); p = _open(); seg = time.time()
|
||||
buf = p.stdout.read(n)
|
||||
if len(buf) < n:
|
||||
p.kill(); p = _open(); seg = time.time(); continue
|
||||
c = glyph(np.frombuffer(buf, np.uint8).reshape(H, W, 3).astype(int))
|
||||
streak = streak + 1 if NEED <= c <= CEIL else 0
|
||||
if streak >= HOLD:
|
||||
print(f"[{time.time()-T0:7.1f}s] TITLE SETTLED (plate pulse, glyph {c})", flush=True)
|
||||
p.kill(); raise SystemExit(0)
|
||||
p.kill()
|
||||
print("TIMEOUT — the title never settled", flush=True)
|
||||
raise SystemExit(2)
|
||||
Reference in New Issue
Block a user