re: the PRESS-A plate arrives 2.13 s after the title settles, measured twice

The one number the port said decides a structural question on its side: whether
`ScreenView` has to draw two builds at once. It does. The boot title shows
build 4 alone, and 2.13 s after build 4 stops animating it composites build 2
over it. Two independent boots agree to 6 ms (2.138 / 2.132), which is under one
sample interval.

Measure from SETTLED, not from first pixels. "First drawn -> plate" is 3.78 s in
one run and 4.26 s in the other, because the build-in animation itself ran 1.64 s
and 2.13 s -- that spread is the emulator's frame pacing, and it is exactly the
kind of number that looks like a measurement.

Ruled out before believing it: that the plate was pulsing all along, too dim for
a thresholded glyph counter. The counter reads EXACTLY 154 -- the committed
no-plate title's own value -- for every frame of a plateau nearly one full pulse
period long, with zero variation, and the surface mean is flat to +/-0.03 across
it. A cycling overlay moves both.

Also settled, and also not:

  * the black hold between two screens is 0.14-0.30 s, which brackets the port's
    authored 0.17-0.23 s and the file's declared 12 units. Their constant stands.
  * the (A)->menu latency is STILL not available, and now the reason is known.
    Both runs freeze one frame for ~1.4 s at surface mean 26.626 -- agreeing
    between runs to six decimals, and reproduced in run 2 with stream restarts
    disabled, so it is not the capture path. It is a guest load stall: the (B)
    path, which loads nothing, has no freeze at all. Any figure from it would be
    an emulator load time.

Refutation attempt, recorded whether or not it survived: navigation.md's "the
title is not input-ready for about ten seconds, and even then (A) registers
roughly half the time". At 7.29 s and 7.28 s after the title settled, (A) was
accepted first press in both runs, as was (B) on the menu. n=2 only makes "half
the time" unlikely (p ~ 0.25); it contradicts the ten seconds outright.

And the standing red banner is withdrawn: the interactive title IS reachable in
this container, twice, with no pad input, in ~3.5 minutes. Why it changed is NOT
established -- this container came up with no Xenia storage root at all, so run 1
created a profile -- and that is written as a correlation for the next session to
test rather than as a cause.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014voBspJ6kFncNErZJuZcLw
This commit is contained in:
sylph-decoder
2026-08-29 12:15:22 +00:00
parent 3ee1a25f47
commit 5fcc89be55
7 changed files with 3992 additions and 2 deletions

View File

@@ -32,7 +32,7 @@ Confidence: ✅ seen in a capture · 🟡 inferred · ❔ unknown.
| 1 | **SQUARE ENIX** in white on black, the two dots in red, `™` after it ✅ | nothing | fades on to the next logo |
| 2 | **GAME ARTS**, **SETA** and **studio anima** stacked on black ✅ | nothing | fades on into the cinematic |
| 3 | The opening cinematic | **Ⓐ** skips it ✅ | ends into the title |
| 4 | **Title screen** — the wordmark appears **first, with no prompt**; `PRESS Ⓐ BUTTON` fades in a beat later, above the 2006/2007 Square Enix copyright line ✅ | press **Ⓐ** | goes to the main menu ✅ |
| 4 | **Title screen** — the wordmark appears **first, with no prompt**; `PRESS Ⓐ BUTTON` fades in **2.13 s** later, above the 2006/2007 Square Enix copyright line, and then pulses about every 2.2 s ✅ | press **Ⓐ** | goes to the main menu ✅ |
| 5 | **Main menu** | — | see §2 |
Both logo screens are **still pictures the game draws**, not video — neither is a
@@ -54,6 +54,21 @@ boot.
⚠️ **The title is not input-ready for about ten seconds** after it appears ✅.
And even then Ⓐ registers roughly half the time, with nothing yet found that
predicts which ✅ — budget retries.
🔴 **Refutation attempt, 2026-08-29 — both halves of that came out wrong on the
runs I could test.** Two boots, Ⓐ pressed **7.29 s** and **7.28 s** after the
title art settled (5.15 s and 5.15 s after the prompt appeared): **accepted both
times, first press, no retry**, and each went straight on to the main menu. Ⓑ on
the menu was then also accepted first press, both runs.
⚠️ Reach: **n = 2**, so "half the time" is only made unlikely (2/2 has p ≈ 0.25
under it), not excluded — but *"not input-ready for about ten seconds"* is
contradicted outright, because 7.3 s worked twice. Keep the retry budget; drop
the ten-second wait. Evidence:
[run 1](../re/data/plate-timing-run1.tsv) · [run 2](../re/data/plate-timing-run2.tsv) ·
[`title-plate-delay-measured.md`](../re/title-plate-delay-measured.md).
⚠️ **The prompt takes 2.13 s to arrive, measured twice (2.138 s / 2.132 s).**
Timed from the moment the wordmark stops animating, not from the moment it first
appears — the build-in itself varies by half a second between runs.
---

View File

@@ -49,6 +49,24 @@ a bind mount on another device, and which is what the withdrawn banner ran.
`sylpheed-cli` against a pak, run the disc-gated tests and read the executable
again. New measurements are available; ask for them.
## ✅ 2026-08-29 — the interactive title is reachable again, and the "emulator-blocked" banner in MISSION is withdrawn
Two consecutive boots reached the interactive title **with no pad input at all**,
passed through the attract loop in ~3.5 minutes, took Ⓐ to the main menu and Ⓑ
back. The standing negative ("three runs, two locales, two launch paths, ~35
minutes of emulator time, no interactive title") does not hold in this container.
**Why it changed is not established.** The container came up with **no Xenia
storage root at all** — no profile, no `xconfig.settings`, no shader cache — so
run 1 created one with canary's `--create_profile_if_none`. That is a correlation
across two runs, not a cause, and it is written down so the next session can test
it rather than re-derive the reachability.
[`capture-harness-status.md`](../re/capture-harness-status.md)
**What it means for you:** the oracle is live. Anything you need timed or
observed on the five screens can now be asked for and taken, including the two
items MISSION parks as emulator-blocked.
## ✅ 2026-08-29 — three answers from one oracle session (the port's asks 1, 2 and 3)
* **1 — the focus ring SPINS CONTINUOUSLY. Period 2.18 s wall-clock; author it
@@ -84,7 +102,39 @@ again. New measurements are available; ask for them.
after.** It is your third option, not the first two. Green-Ⓐ glyph count on the
boot title went **154 → 781**, and 154 is the same reading the committed
`live-title-build4-no-plate.png` gives (159) while plate titles give
753/977/1493. 🔴 **The delay is NOT measured** — see the next bullet.
753/977/1493.
**AND THE DELAY IS NOW MEASURED — 2.13 s, replicated to 6 ms.** Two
independent boots: the plate arrives **2.138 s** and **2.132 s** after build 4
settles (the frame where the glyph counter first reads its no-plate 154 and
motion goes to zero). **So `ScreenView` does have to draw two builds at once,
and your `--boot` end state is NOT plate-free** — that is the structural answer
you said this question decides.
⚠️ Measure from **settled**, not from first pixels: "first drawn → plate" is
3.78 s in one run and 4.26 s in the other, because the build-in animation
itself ran 1.64 s and 2.13 s. That spread is the emulator's frame pacing, not
the game's clock.
Then pulse the plate at ≈ **2.24 s** (four intervals: 2.12 / 2.19 / 2.34 /
2.31), which replicates the corpus's ≈2.3 s rather than replacing it.
[`title-plate-delay-measured.md`](../re/title-plate-delay-measured.md) ·
[figure](../re/captures/ui-timing/plate-onset-two-runs.png) ·
[run 1](../re/data/plate-timing-run1.tsv) · [run 2](../re/data/plate-timing-run2.tsv)
* 🟡 **Your black hold survives a real clock — keep 0.170.23 s.** Measured on
the Ⓐ path in both runs, the frame is pure black (surface mean 0.070) for
**0.140.30 s** and **0.140.27 s**. At an 0.125 s sample interval that is as
tight as this instrument goes, and it brackets both your authored value and
the file's declared 12 units (0.20 s). It is the one authored constant you
ship that a measurement now agrees with.
* 🔴 **The Ⓐ→menu latency is STILL not a number you may have, and now I know
why.** Both runs contain a **frozen frame** on the Ⓐ path — 14 frames (1.53 s)
and 12 frames (1.39 s) held at surface mean **26.626**, agreeing between two
independent runs to six decimals. Run 2 had stream restarts disabled for the
whole window, so it is **not** the capture path: the guest starts the fade,
re-presents one frame for ~1.4 s, then shows the full title again and fades
properly. That is a **load stall**, and the Ⓑ path — nothing to load — has none.
So any Ⓐ→menu figure from this harness is an emulator load time. Your
zero-dwell sequencer is the right call; do not add one.
* 🔴 **Four durations I took the same day are WITHDRAWN, including the plate
delay.** `screen_match.classify_array` costs **1503 ms/frame**; a probe running
@@ -96,6 +146,10 @@ again. New measurements are available; ask for them.
the sequence results above stand and the timings do not. Fixed (`fast=True`,
3875 ms, re-controlled 8/8 on both paths, agreeing to ±0.005); the ring's
numbers are unaffected and that was checked, not assumed.
**One of the four is now re-taken properly** — the plate delay, above. The
probe that took it costs **8.7 ms/frame** (173× cheaper) and both runs sampled
at **7.97 / 7.98 fps against a requested 8**, so there was no backlog to
destroy them.
## Status

View File

@@ -163,4 +163,5 @@ files, which is how the same ground got covered twice.
| [`weapon-datasheet-runtime.md`](weapon-datasheet-runtime.md) | Weapon DATA SHEET — runtime capture (Route B) | 🟡 first dynamic capture, 2026-07-28. The Arsenal's Gallery Mode panel is a |
| [`xpr2-colour-check.md`](xpr2-colour-check.md) | XPR2 colours: channel order ✅ confirmed against the running game | — |
| [`focus-ring-spin-measured.md`](focus-ring-spin-measured.md) | The main menu's focus ring spins continuously — and how fast | ✅ **measured**: period **2.177 s** over 9 revolutions (8 evenly spaced autocorrelation peaks) = 120 units = 60 frames = 2.00 s at 30 Hz. A pulse is excluded — annulus total conserved to 0.4 % while per-bin brightness swings by 24. ✅ the ring is the **only** moving thing on the settled main menu (std exactly 0.000 elsewhere). 🔴 no angle is quoted: the angular estimator FAILED its own control (30° → 0°) |
| [`title-plate-delay-measured.md`](title-plate-delay-measured.md) | How long the boot title shows build 4 before the `PRESS Ⓐ` plate | ✅ **measured**, two independent boots: **2.138 s** and **2.132 s** from the frame build 4 settles (glyph = its no-plate 154, motion → 0). Agreeing to **6 ms**. So the boot title's end state is **not** plate-free and a compositor must draw **two builds at once**. ⚠️ Measure from *settled*, not from first pixels — "first drawn → plate" is 3.78 s vs 4.26 s across the same two runs, because the build-in animation's own duration varies with emulator frame pacing. Plate pulse re-measured at 2.12/2.19/2.34/2.31 s (mean 2.24), replicating the corpus's ≈2.3 s. ✅ black hold between screens bracketed at **0.140.30 s**, consistent with the declared 12 units. 🔴 the Ⓐ→menu latency is still **not** available: both runs freeze one frame for ~1.4 s at surface mean **26.626** — agreeing between runs to 1e-6, and reproduced with stream restarts disabled — which is a guest **load stall**, not the capture path. Probe: 8.7 ms/frame, 7.97/7.98 fps against a requested 8, controls 9/9 + 4/4 |
| [`menu-idle-and-b-2026-08-29.md`](menu-idle-and-b-2026-08-29.md) | The main menu does not idle back to the title — and four durations that were a pipeline | ✅ **refuted**: no self-return in **≥ 60 s** untouched; the ~810 s idle belongs to the **title**. 🟡 Ⓑ→title ordering measured, latency not. 🔴 `classify_array` at **1503 ms/frame** drained an 8 fps stream at 0.64 fps and manufactured four latencies (24.66 s / 15.58 s / 25.60 s / 20.26 s) — all withdrawn; a backlog preserves ordering and destroys durations |

View File

@@ -1,3 +1,62 @@
# ✅ WITHDRAWN 2026-08-29 (later the same day) — the interactive title IS reachable here, twice, with no pad input
**This banner supersedes everything below it about the title being unreachable,
and it supersedes the 🔴 "Emulator-side questions are blocked" section of
[MISSION](../port/MISSION.md).** Everything below is kept because the harness
defects it diagnoses were real and the fixes are in use; what it concluded about
the *game* is now refuted by measurement.
**Two consecutive boots reached the interactive title, with the `PRESS Ⓐ BUTTON`
plate, without a single pad press before it:**
| | run 1 | run 2 |
|---|---|---|
| plate on screen at | **205.4 s** into the probe | **218.4 s** |
| pad input before that | **none** | **none** |
| Ⓐ then reached the main menu | ✅ | ✅ |
| Ⓑ then returned to the title | ✅ | ✅ |
Full per-frame traces, 8 fps, 1783 and 1886 frames:
[`data/plate-timing-run1.tsv`](data/plate-timing-run1.tsv) ·
[`data/plate-timing-run2.tsv`](data/plate-timing-run2.tsv). The measurement they
were taken for is [`title-plate-delay-measured.md`](title-plate-delay-measured.md).
So the standing negative — "three runs, two locales, two launch paths, ~35
minutes of emulator time, no interactive title" — does not hold in this
container today. **The attract loop is simply passed through in ~3.5 minutes and
the title follows.**
## ❔ What changed is NOT established, and I am not going to guess it
What is different about this container, stated as facts rather than as a cause:
* it came up with **no Xenia storage root at all** — no
`~/.local/share/Xenia`, so no profile, no `xconfig.settings`, and no shader
cache. The earlier runs signed in a profile that already existed.
* run 1 therefore had to create one, with canary's own
`--create_profile_if_none=Decoder`. Run 2 signed in the profile run 1 made
(`B13EBABEBABEBABE`).
* the launch was otherwise `boot_menu.sh`'s, minus `skip_intro.sh` — this
measurement had to leave the title untouched, so nothing tapped Ⓐ at all.
⚠️ **A cold profile is a correlation across two runs, not a cause.** It is
written down so the next session can test it directly (delete the storage root,
boot, compare) instead of re-deriving that the title is reachable.
## 🔵 What this unblocks
* the **Japanese-locale capture** that MISSION parks as "🟡 needs one more run":
the mechanism (`set_console_language.py ja`, `user.language` at file offset
`0x912`) is in place, and the reason it was parked — *the title never
appears* — is gone. ⚠️ Note the storage root is new, so `xconfig.settings` has
been recreated and the byte offset should be re-located by its three landmarks
rather than assumed.
* the two items MISSION lists as emulator-blocked: the gamma control behind
[tone curve](structures/ui-render-tone-curve.md), and separating `8AX` from
`ptbase` in [8AX](structures/ui-8ax-fullres-background.md).
---
# 🔴 Why the boot harness stopped reaching the title — `screenshot` costs 10.8 s
**Status:****diagnosed, with a control.** Four consecutive runs on

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,140 @@
# ✅ The boot title shows build 4 alone for **2.13 s**, then composites the plate
**Status:****measured** — two independent boots of the real game in Xenia
Canary, 2026-08-29. Not on the disc as a delay: build 2 (the `PRESS Ⓐ BUTTON`
plate) is an overlay with no fade quad of its own, and nothing in either
bundle's keyframe group carries the gap between them.
**Question this closes:** the port asked which of three things the boot title is
— build 4 alone, build 4 with the plate composited from the start, or build 4
**then** the plate after a delay — because the third case is the only one where
`ScreenView` has to draw **two builds at once**, which it has never done. The
sequence was already answered (it is the third,
[`menu-idle-and-b-2026-08-29.md`](menu-idle-and-b-2026-08-29.md)); **the delay
was withdrawn the same day** and is what this page supplies.
## The number
| | run 1 | run 2 |
|---|---|---|
| title art first drawn (surface leaves black) | 201.617 s | 214.130 s |
| **title settled** — glyph counter first reads its no-plate value **154** | 203.260 s | 216.261 s |
| **plate first counted** — glyph leaves 154 | 205.398 s | 218.393 s |
| **settled → plate** | **2.138 s** | **2.132 s** |
| first drawn → plate | 3.781 s | 4.263 s |
**Take 2.13 s, measured from the moment build 4's own build-in animation
finishes.** The two runs agree to **6 ms**, which is under one sample interval.
⚠️ **Do not take "first drawn → plate".** It differs by 0.48 s between the two
runs because the build-in itself ran 1.64 s and 2.13 s — the emulator's frame
pacing during an animation is not the game's clock, and this is exactly the sort
of number that looks like a measurement and is really the harness.
![plate onset, both runs](captures/ui-timing/plate-onset-two-runs.png)
Raw per-frame data, 8 fps, every frame of both runs:
[`data/plate-timing-run1.tsv`](data/plate-timing-run1.tsv) ·
[`data/plate-timing-run2.tsv`](data/plate-timing-run2.tsv).
## Why "then the plate", and not "the plate was pulsing all along too dim to see"
The plate's declared alpha never exceeds `0x50` (80/255,
[HANDOFF](../port/HANDOFF.md)), so a glyph counter with a hard threshold could in
principle miss its dim phase and produce a fake delay. It does not, on two
independent observables:
* the glyph count is **exactly 154** — the committed no-plate title's own value,
159 on `live-title-build4-no-plate.png` — for every frame of the plateau, with
**zero** variation, for 1.99 s (run 1) and 2.13 s (run 2). After onset the
same counter swings 714 ↔ 1520 continuously. A cycling plate cannot produce a
flat exact-154 plateau nearly one full period long;
* the **surface mean** is flat to ±0.03 across the plateau (61.09 → 61.15) and
then rises. A pulsing overlay moves the frame mean; the frame mean does not
move until onset.
## What the port should author
1. draw build 4, play its own keyframes;
2. when build 4 has settled, wait **2.13 s**;
3. composite build **2** over it and start its pulse — period measured here at
**2.12 / 2.19 / 2.34 / 2.31 s** across four peak- and trough-to-peak
intervals in the two runs, mean **2.24 s**, which replicates the corpus's
≈ 2.3 s rather than replacing it.
So yes: `ScreenView` needs two builds at once, and the boot's end state is
**not** plate-free.
## What is NOT measured here — the press latencies, again
Both runs pressed Ⓐ on the plate and Ⓑ on the menu, and both runs contain a
**frozen frame** on the Ⓐ path that makes the Ⓐ→menu duration meaningless:
| | run 1 | run 2 |
|---|---|---|
| frames held at surface mean **26.626**, motion exactly 0 | 14 (1.53 s) | 12 (1.39 s) |
🔴 **This is not the instrument.** Run 1's freeze straddled an x11grab restart,
so it looked exactly like the documented stale-stream failure; run 2 was run with
restarts **disabled** for the whole measuring window and reproduced the same
freeze, at the **same** surface mean to six decimals, in the same place relative
to the press. Two independent runs cannot agree to 1e-6 on a stalled buffer.
It is the guest: after Ⓐ, the fade-out starts (mean 64.4 → 51.0 → 26.6), the
frame is then **re-presented unchanged for ~1.4 s**, the full title reappears at
mean 64.28, and only then does the fade run to completion. That is the shape of
a **load stall**, and the Ⓑ path — menu → title, nothing to load — has no freeze
at all.
**So the Ⓐ→menu latency is an emulator load time, not a game beat, and the port
must not bake it in.** The parts of the transition that are stall-free:
| | run 1 | run 2 |
|---|---|---|
| press → first visible change (Ⓐ) | — | 0.290.37 s |
| press → first visible change (Ⓑ) | — | 0.280.33 s |
| **pure black between the two screens** (Ⓐ path) | 0.140.30 s | 0.140.27 s |
| black → menu settled | ≈ 1.0 s | ≈ 1.0 s |
| Ⓑ path: menu fade-out to black | — | 0.50 s |
| Ⓑ path: black → title art | — | ≤ 0.27 s, and it is a **cut**, not a fade |
⚠️ The two "first visible change" figures are **upper bounds that include this
harness**: the press is a file the emulator polls (`--hid=file`), so an unknown
poll interval sits inside them. They are quoted only because they bracket the
black hold, and they do **not** refute
[`screen-transitions.md`](screen-transitions.md)'s 0.07 s, which was taken a
different way.
**The black hold does check the port's authored constant.** The port ships
0.170.23 s; both runs put it in **0.140.30 s**. Consistent, at a sampling
resolution (0.125 s) that cannot do better — so the authored value stands and is
now bracketed by a measurement rather than only by the declared 12 units
(0.20 s).
## The instrument, and its controls
[`tools/re-capture/title_timing_probe.py`](../../tools/re-capture/title_timing_probe.py),
built because the four durations withdrawn on 2026-08-29 came from a classifier
costing **1503 ms per frame** draining an 8 fps stream at 0.64 fps.
* **8.7 ms of compute per frame** — measured, 173× cheaper. The saving is the
±8 px offset search: every committed capture aligns at exactly `dy=0 dx=0`
([`five-screens-acceptance.md`](five-screens-acceptance.md)), so the live path
decimates 4× and does one ZNCC per reference instead of 25 at full res.
* **Both runs sampled at 7.97 and 7.98 fps against a requested 8.** A backlog
preserves ordering and destroys durations; there was no backlog.
* `--control` **passed 9/9 content controls and 4/4 plate-detector controls**,
including the two committed movie frames that are the class this oracle exists
to reject.
* an **independent one-shot grab** every 20 s, through a separate process, is
logged beside the stream's own frame. On the static screens the two agree to
**0.000 / 0.001**; the large disagreements are all inside movies, where a
0.3 s difference in grab time is a different picture.
* and the plateau itself carries an internal clock check: the plate's ~2.2 s
pulse is visible in the same trace. A stalled stream cannot produce a periodic
signal.
## Reach
Two runs, English locale, one machine, Xenia Canary. It says nothing about the
**attract loop's** title (which the corpus records as accepting no input at all),
and nothing about the Japanese build 7.