# F1 dynamic attempt — harness debugged through four bugs, no measurement yet **Status:** ❔ not answered. Built [`tools/re-capture/f1_hold_capture.py`](../../tools/re-capture/f1_hold_capture.py) to close out issue #1 with an actual draw-log measurement — boot to the settled main menu (the proven glyph-gated route), arm the F10 UI-draw capture, hold a direction, read the cursor's position per frame. Never completed a clean end-to-end run this iteration; four real bugs found along the way, three fixed and confirmed, one fixed but not re-verified. Same shape as [`f1-menu-repeat-harness-built-not-answered.md`](f1-menu-repeat-harness-built-not-answered.md) — the harness is closer, the number still isn't here. ⚠️ **Container reset warning, read this if you are a fresh session:** bug 3 below will hit *any* scripted `run-canary` invocation in a container that has never signed in a profile — which is every container right after a restart, per this project's own "your session is new each time" note. `boot_menu.sh` already handles it; a bare `run-canary` call does not. ## Bug 1 — `tap()` shelled out to `pad.py` with the wrong environment First attempt's "tap A" used `subprocess.run([sys.executable, PAD, ...])` without passing this script's own `env` dict, so the subprocess inherited `os.environ` instead — where `XENIA_PAD_FILE` was never set at the OS level, only in the local dict. `pad.py` wrote its default `/tmp/xenia_pad.txt`; Canary was watching `OUT/pad.txt`. The press never arrived: **an unobserved press that looks identical to a dead pad**, and it cost one full 520 s boot before the mismatch was found (only one `[file-pad]` log line the whole run — the initial clear). **Fixed:** an in-process `tap()` using the same `pad()` function the hold uses, no subprocess. **Confirmed working** the very next run: title reached at 154.5 s, tap delivered, menu reached at 163.0 s. ## Bug 2 — the persisted `ui_draw_capture_frames` was 3, disc-wide default `ui_draw_capture_frames = 3` / `ui_draw_capture_max = 20000` sat in `~/.local/share/Xenia/xenia-canary.config.toml` from a previous session — an old capture's window, kept because `--log_ui_draws=true` (the flag most existing scripts pass) is **now a documented no-op** (`command_processor.cc`: *"OBSOLETE — the UI draw-order capture is armed by F10 unconditionally now"*). Passing `--ui_draw_capture_frames=3000` on the command line did not visibly change the value logged at startup, and this container's saved config wins for these two cvars regardless of the flag. **Fixed:** edited the toml directly, `600` / `400000` — wide enough to cover a multi-second hold at any plausible present rate. Confirmed applied (log dump shows the new values) on the next run, though it wasn't the run that also isolated bug 3, so it hasn't independently produced a capture yet. ## Bug 3 — no signed-in profile, and it reproduces the documented crash The real blocker. This container had **no `content/` directory at all** — a fresh container after a restart, exactly as the loop brief warns, and `f1_hold_capture.py` (unlike `boot_menu.sh`) never checked. Without a profile, the title shows a sign-in dialog, `IsUIActive()` goes true, and — **this is the exact crash `structures/title-a-press-fault.md` already diagnosed** — `XamInputGetKeystrokeEx` returns success with an empty keystroke forever, the game's unbounded pump queues every empty result, and it eventually crashes on a bad allocation. Reproduced, not just matched by description: the crash dump's PC (`0x824578A0`) sits **0x868 past `sub_82457038`** (that doc's "keystroke pump"), registers hold values in the `0x828F3xxx` range (the input-manager singleton at `0x828F3888`), and the access violation address relationship — `0x1701D0000` (host) → `0x701D0000` (guest, `r9`) — matches that doc's own worked arithmetic exactly. Without a profile the crash repeated in a tight loop (one dump roughly every 200 log lines) for the entire run, starting before F10 was ever pressed — this is not an F10 side effect, it is the title's own boot path with no profile to sign into. **Fixed:** `run-canary --create_profile_if_none=F1Probe`, wait ~5 s, kill it — creates `content//`. Script now resolves that XUID and passes `--logged_profile_slot_0_xuid=`, matching `boot_menu.sh`. **Confirmed**: zero crash dumps in the run that used it, against dozens per run before. ## Bug 4 — no root-window blank before launch; found, not re-verified The run after fixing bug 3 detected "TITLE" at **2.6 s** — long before any real window could exist — and never recovered. `skip_intro.sh`'s own header explains why: *"The X root keeps the DEAD session's last frame, so a fresh launch would be detected as already at the title."* The previous run's killed window left stale pixels on the shared `:98` display; my script never blanked it, unlike every proven boot script. **Fixed in the script** (`xsetroot -solid black` before each launch) but **not re-run this iteration** — four bugs and roughly nine minutes of boot time across four attempts is where this stopped rather than chasing a fifth. ## What's left The harness should now be correct: env-safe input, a wide enough capture window, a signed-in profile, a blanked root. The next run is the actual measurement — hold a direction on the settled menu, read `read_draws.py`'s per-frame quad positions, group by `(page, width, height)` shape (the approach `menu_repeat_probe.sh`'s own notes call "track one quad shape's position over time," the one that correctly reports no motion when there is none), and report which shape-group's position changes, at what frame spacing, at the achieved present rate. ## Reach Everything here is ⟨harness⟩ / ⟨environment⟩ — about this container and this tool, not about the game. Bug 3's crash mechanism is not new (already fully diagnosed in `structures/title-a-press-fault.md`); what's new is the trigger (a freshly-reset container with no profile) and that it reproduces byte-for-byte against that page's own addresses. No claim about F1's actual repeat rate is made or changed here.