Drive 4 worked. With focus detected and the detector validated live against a known transition (NEW GAME, down, LOAD GAME -- CONTROL PASSED), the drive navigated and pressed through, and every step confirms against a committed capture: main menu +0.999, newgame-difficulty +0.999, newgame-selectdata-crash +0.997. Then the guest throws, PC 0x82307128 times 349, and no S00A voice stream ever decodes. It is on the new-game path rather than the boot: the log order is ADV attract, then BGM_103 menu music, then the throw. So it is not the ~100 s boot throw that title-crash-stl-tree.md documents. That page attributes the throw to an incomplete on-disc cache and Q4 s note cites it for this crash. The attribution survives, but not through the container the page names. aab216c3 is complete here at 7 files. The line immediately before the exception resolves \1b556564\9\00c8dcd, and 1b556564 holds exactly one file plus a stray 1b556564900c8dcd.tmp -- precisely the page s run C, partially rebuilt, which throws. So the new-game path builds a different cache container from the title path and that one is incomplete. The page s remedy does not transfer. It restores a previously complete cache, and no complete 1b556564 has ever existed here: the game crashes while building it, leaving the .tmp, so the cache cannot complete and re-running does not escape it. Its own run B shows a fully cold cache throws as well, so deleting does not help. Consequence recorded: the centre-channel voice result stays resting on ADV alone, because the corroborating asset is behind a crash that is outside menu-port scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
159 lines
7.8 KiB
Markdown
159 lines
7.8 KiB
Markdown
# 🔴 `S00A` is unreachable here — the new-game path crashes on an on-disc cache it cannot finish building
|
||
|
||
**Four drives.** The first three failed on tooling and are recorded below because
|
||
each defect is live in shared scripts. The fourth drove perfectly and hit a
|
||
**guest crash**, which is the real answer.
|
||
|
||
**Classification: measured.** Two drives, 2026-08-29. Reported as a **route
|
||
finding** rather than retried silently, because the cause is a defect in shared
|
||
harness tooling that will bite the next drive too.
|
||
|
||
## What was wanted
|
||
|
||
`S00A` is the new-game intro and the second asset for the centre-channel voice
|
||
result ([`voice-three-streams-are-concurrent.md`](structures/voice-three-streams-are-concurrent.md)):
|
||
its second full-length stream is **digital silence** where `ADV`'s is a 0.60 ×
|
||
copy, so agreement there would stop the finding resting on one movie. It starts
|
||
~4.5 s after Ⓐ on the save slot, so it needs a **driven, rendered** run.
|
||
|
||
## 🔴 Drive 1 — `screen_id.py` cannot see the title it was waiting for
|
||
|
||
396 s of `other`, two spurious `menu` hits, abort. The guest was healthy
|
||
throughout — its audio was decoding the whole time.
|
||
|
||
`screen_id.py` thresholds on **green** and only returns `title` once the
|
||
`PRESS Ⓐ` plate has faded in. This corpus's own finding is that the boot title
|
||
shows **build 4 first, plate-less**. Both defects reproduce on committed frames
|
||
(see [`METHOD.md`](METHOD.md)):
|
||
|
||
| frame | `screen_id.py` | should be |
|
||
|---|---|---|
|
||
| `live-title-build4-no-plate.png` | **`other`** | title |
|
||
| `difficulty-screen.png` | **`menu`** | not the main menu |
|
||
|
||
⚠️ `newgame_path.sh`, `nav_probe.sh` and `boot_menu.sh` all gate on it.
|
||
|
||
## 🔴 Drive 2 — reached the title, then pressed Ⓐ on the wrong button
|
||
|
||
With a replacement classifier controlled **6/6** (three oracle frames at 1.000;
|
||
`difficulty-screen` and both movie frames correctly `other`, at a 0.85 threshold —
|
||
at 0.60 it repeated `screen_id.py`'s own difficulty/menu confusion), the drive
|
||
reached `title_plate` at **t = 398 s**, took Ⓐ to the menu, and drove on.
|
||
|
||
**It ended up in a tutorial mission.** The screen 60 s after the last Ⓐ
|
||
correlates **+0.960** with the committed
|
||
`tutorial-mission-reached-then-crash.png`. No `S00A` voice stream ever decoded —
|
||
the probe logged `ADV`'s three, `BGM_102`'s two, `BGM_103`'s two and two SE cues,
|
||
and **none of S00A's** (1 810 432 / 1 263 616 / 98 304).
|
||
|
||
**Why:** `newgame_path.sh`'s header says *"NEW GAME is the menu's FIRST item, so
|
||
this presses (A) with no d-pad movement"*. 🔴 **That assumption contradicts this
|
||
corpus's own Q5 result** — initial focus varies boot to boot, four boots giving
|
||
`TUTORIAL, TUTORIAL, NEW GAME, NEW GAME`
|
||
([`menu-navigation-semantics.md`](menu-navigation-semantics.md)). This boot
|
||
started on TUTORIAL, so the first Ⓐ opened the lesson list.
|
||
|
||
✅ **Incidental corroboration:** `BGM_103`'s two waves (3 876 864 / 3 930 112)
|
||
decoded on reaching the menu — an independent confirmation of HANDOFF's
|
||
"the menu's music is `BGM_103`", from the runtime rather than from the cue table.
|
||
|
||
## ❔ What is needed, and why it is not just "press up four times"
|
||
|
||
Focus must be **detected**, not assumed — and wrap-around makes it
|
||
unreachable by counting: ⬆ from the first item goes to the *last*, so no fixed
|
||
number of presses lands on a known item from an unknown start.
|
||
|
||
🔴 **And I do not currently have a focus detector.** A per-row brightness
|
||
statistic **failed its control**: on `live-main-menu-options-focused.png` — whose
|
||
answer is in its own filename — it picked NEW GAME. Brightness across a button
|
||
row is dominated by something other than the focus highlight. Until a controlled
|
||
detector exists, a driven run cannot reliably choose a menu item on this boot
|
||
path.
|
||
|
||
## 🟢 A refutation attempt on the port's focus identification — it FAILED
|
||
|
||
The port identified `live-main-menu.png` as **NEW GAME focused**, by minimum
|
||
render difference, with the `-options-focused` capture as a control it picked
|
||
correctly by 4.7×.
|
||
|
||
Differencing the two captures directly and binning by button row, I got NEW GAME
|
||
and **EXTRAS** changing while OPTIONS stayed still — an apparent refutation.
|
||
**It was my error.** I placed the row bands as `rest_y ± 24`, treating the
|
||
resting position as a band *centre*; the changed bands then mis-assigned.
|
||
|
||
The offset-independent check settles it without needing that geometry at all:
|
||
|
||
| | |
|
||
|---|---|
|
||
| changed band centres (design y) | 195.2 and 450.1 |
|
||
| separation | **254.9** |
|
||
| 3 button pitches (3 × 80) | 240 — off by **14.9** |
|
||
| 4 button pitches | 320 — off by 65.1 |
|
||
|
||
**The two focused buttons are 3 apart, not 4** — NEW GAME → OPTIONS, not
|
||
NEW GAME → EXTRAS. ✅ **The port's identification stands.** ⚠️ And as they
|
||
themselves noted, it identifies *one frame*, not a rule: Q5's instability is
|
||
untouched.
|
||
|
||
---
|
||
|
||
## ✅ Drive 4 — the drive worked; the GAME crashes at `SELECT DATA`
|
||
|
||
With focus detected and the detector validated **live against a known
|
||
transition** (`NEW GAME` → ⬇ → `LOAD GAME`, expected `LOAD GAME`, **CONTROL
|
||
PASSED**), the drive navigated to `NEW GAME` and pressed through. Every step is
|
||
confirmed against a committed capture:
|
||
|
||
| step | correlates with | r |
|
||
|---|---|---|
|
||
| after navigation | `main-menu-items.png` | **+0.999** |
|
||
| after Ⓐ | `newgame-difficulty.png` | **+0.999** |
|
||
| after Ⓐ (NORMAL) | `newgame-selectdata-crash.png` | **+0.997** |
|
||
|
||
Then the guest throws: **`PC: 0x82307128` ×349**, one
|
||
`Guest attempted to throw a C++ exception!`. No `S00A` voice stream ever decodes.
|
||
|
||
✅ **It is on the new-game path, not the boot.** Ordering in the log is
|
||
`ADV` (attract) → **`BGM_103`** (menu music, i.e. the menu was reached) → throw →
|
||
crash dumps. So this is *not* the ~100 s boot throw that
|
||
[`title-crash-stl-tree.md`](title-crash-stl-tree.md) documents.
|
||
|
||
## 🟡 Refining that page — the mechanism holds, the container does not
|
||
|
||
That page attributes the throw to an **incomplete on-disc cache**, and Q4's note
|
||
says the `SELECT DATA` crash "is already in the corpus", citing it. **Checked,
|
||
and the attribution survives — but not via the container the page names.**
|
||
|
||
| cache container | state here | |
|
||
|---|---|---|
|
||
| **`aab216c3`** — the one the page names | **7 files, complete** | not the trigger |
|
||
| **`1b556564`** — resolved immediately before the throw | **1 file + `1b556564900c8dcd.tmp`** | ⚠️ exactly the page's **run C**, "partially rebuilt (1 file + a `.tmp`) → 1 GUEST-THROW" |
|
||
|
||
The log line before the exception is
|
||
`HostPathDevice::ResolvePath(\1b556564\9\00c8dcd)`. So the **new-game path
|
||
builds a different cache container from the title path**, and it is that one
|
||
which is incomplete.
|
||
|
||
🔴 **And the page's remedy does not transfer.** Its fix is to restore a
|
||
*previously complete* cache (run D). **No complete `1b556564` has ever existed in
|
||
this container** — the game crashes while building it, leaving the `.tmp`, so the
|
||
cache cannot complete and the crash cannot be escaped by re-running. The page's
|
||
own run B shows a fully cold cache throws too, so deleting it does not help
|
||
either.
|
||
|
||
## The answer
|
||
|
||
❔ **`S00A` is not obtainable in this container**, and the reach is:
|
||
|
||
* the drive is **not** the obstacle — four screens confirmed against committed
|
||
captures at r ≥ 0.997, and the focus detector passed a live transition control;
|
||
* the obstacle is a **guest crash** with a known site and a known class of
|
||
trigger;
|
||
* the documented remedy needs an artefact — a complete `1b556564` — that has
|
||
never existed here and that the game cannot produce because it crashes
|
||
mid-build.
|
||
|
||
⚠️ **Consequence for the voice finding:** the centre-channel result stays resting
|
||
on `ADV` alone. `S00A` was wanted because its second stream is digital silence
|
||
where `ADV`'s is a 0.60 × copy; that corroboration is **not available from this
|
||
container** without first solving a crash that is outside the menu-port scope. |