This repository has been archived on 2026-09-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Syplheed-Reborn/docs/re/capture-harness-status.md
Sylpheed RE agent e9924ff9e8 re: build the fast probe -- and it refutes the diagnosis that motivated it
Last iteration I blamed four failed runs on the probe sampling every
~41 s, slower than the title screen lasts, and withdrew three earlier
conclusions on that basis. Building the fix tested the claim and killed
it.

The speedup is real and control-verified. One long-lived ffmpeg x11grab
stream, raw RGB, glyph counted in numpy -- no per-sample process startup,
no PNG encode, no convert -crop:

  wrapper `screenshot`            3.98 s per sample (emulator running)
  import -window root -> PPM      1.20 s
  long-lived x11grab stream       0.29 s          13.7x

The counter is byte-identical to is_title.py: 753 on the committed title
capture, 327 on the main menu.

Pointed at a running game it says the opposite of what I expected:

  332 frames in  85.3 s = 3.89 fps; max glyph 0
  1674 frames in 420.0 s = 3.99 fps; max glyph 0

1674 consecutive samples over seven unbroken minutes, four per second,
zero green-(A) pixels. Sampling rate was a real defect that happened not
to be the cause.

So "neither locale reaches the interactive title without a pad press" --
withdrawn last iteration for want of evidence -- is reinstated, now as a
dense measurement, with its reach stated: a MID-RUN window only, silent
about the boot title.

Leading hypothesis, unconfirmed: the PRESS (A) plate appears only in the
boot title window and the attract loop's title carries none, which is
exactly what title_states_capture.sh was written to test. The experiment
is to start the fast probe from t=0 rather than attach to a run already
in progress.

METHOD: fixing the instrument is how you test the explanation that blamed
it -- a plausible mechanism is a hypothesis, and the fix is its
experiment, not its proof.
2026-08-29 01:34:40 +00:00

121 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🔴 Why the boot harness stopped reaching the title — `screenshot` costs 10.8 s
**Status:** ✅ **diagnosed, with a control.** Four consecutive runs on
2026-08-28/29 failed to reach the interactive title, across two locales, two
launch paths and two display-gamma settings. The cause is none of those.
## The measurement
| condition | one `screenshot` call |
|---|---|
| while Xenia Canary is running | **10.8 s** |
| immediately after killing it | **0.117 s** |
**92×.** The 1-minute load average at the slow measurement was 1.80, so this is
contention with the emulator (both go through the same X server), not general
system load.
## Why that breaks the harness
`skip_intro.sh` takes **two** grabs 0.6 s apart per iteration, plus an
`is_title.py` numpy load. Its actual sample timestamps in the last run:
```
57, 95, 177, 218, 238, 298, 333, 380, 426, 471, 515 → intervals
38, 82, 41, 20, 30, 30, 35, 47, 46, 45, 44, 43, 21, 19 median 41 s
```
A **41-second** sampling interval against a title screen that the corpus already
documents as lasting *"a few seconds"* before auto-returning to the attract loop
(`wait_title.sh`'s own header). The harness is not seeing a stuck game; it is
blinking slower than the thing it is looking for.
That is also why runs at 16:43–18:05 the same day succeeded and later ones did
not — nothing about the game changed.
## 🔴 What this retracts
Three earlier conclusions were built on these runs and are **withdrawn as
causes**, though the observations stand:
* *"the Japanese-locale run never reaches the interactive title"* — it may well
have appeared, unsampled.
* *"neither locale reaches the interactive title without a pad press"* — the
English control shared the same defect, so it controlled for locale but not for
the sampling rate.
* *"the game sat in the attract loop for 604 s"* — what was observed is that
**every one of ~15 samples** landed on movie content, which at a 41 s interval
is a much weaker statement than it reads as.
## ⚠️ A confound I introduced
Setting `kernel_display_gamma_type = 0` makes the frame substantially brighter
(a mid-attract frame measured mean **122.8** against **52.5** and **82.8** on
comparable phases at type 2). `skip_intro.sh` classifies movie-vs-static on an
**absolute** rmse threshold of 1500 between two grabs, so a brighter output
inflates that difference and biases every frame toward "movie". **The capture
harness's tuning is coupled to the display settings** — changing gamma and
capture behaviour in one run confounds both.
## 🔴 The fix works — and it REFUTES the diagnosis above
Built and measured (`tools/re-capture/fast_title_probe.py`): one long-lived
`ffmpeg` x11grab stream, raw RGB frames, glyph counted in numpy. No per-sample
process startup, no PNG encode, no `convert -crop`.
| probe | seconds per sample, emulator running |
|---|---|
| the wrapper `screenshot` | **3.98** |
| `import -window root` → PPM | 1.20 |
| **long-lived x11grab stream** | **0.29** |
**13.7× faster**, and the counter is control-verified against the committed
frames — it returns **753** on `live-title-press-a.png` and **327** on
`live-main-menu.png`, byte-identical to `is_title.py`.
Then it was pointed at a running game:
```
332 frames in 85.3 s = 3.89 fps; max glyph 0
1674 frames in 420.0 s = 3.99 fps; max glyph 0
```
**1 674 consecutive samples over seven unbroken minutes, four per second, and the
interactive title never appeared.** So the sampling rate was a real defect and
*not* the cause. The hypothesis on this page — that the harness was blinking
slower than the event — is **mine, and refuted by my own fix**.
## What that restores
Last iteration I withdrew three conclusions on the strength of that hypothesis.
The withdrawal was right at the time (15 samples at 41 s intervals cannot support
them) and is now **superseded by better evidence**: dense sampling says the
interactive title genuinely does not appear in a mid-run window. Reinstated as a
**measurement**, with its reach:
* ✅ over **420 continuous seconds**, English, `gamma_type = 2`, ~13 minutes into
a run with no pad input, **zero** frames carried the green Ⓐ glyph.
* ⚠️ Reach: this covers a **mid-run** window only. It says nothing about the
first minutes of boot.
## 🟡 The leading hypothesis, not confirmed
The corpus already suspects the answer. `title_states_capture.sh` exists to test
*"whether the interactive one draws `ptbtn00` (the PRESS Ⓐ plate) and the other
does not"* — i.e. the title appears **twice**: once at the end of the boot
sequence, and again from the attract loop, and only the first may carry the
plate. If so, the plate's window is early and one-shot, and no amount of
mid-run sampling will ever find it.
That is consistent with everything measured, and it is **not confirmed**. The
test is to start the fast probe *before* the boot title — from t=0 rather than
attaching to a run already in progress.
## The original fix note, kept
Make the probe cheap enough to sample faster than the title window: grab a small
region rather than the full surface, drop the ImageMagick `convert` round trip,
or keep the glyph test in one long-lived process instead of re-importing numpy
per sample. None of that is done — this page is the diagnosis, and it is what
every remaining emulator-side question is waiting on.