re: the PRESS A plate PULSES -- measured, and it keeps an authored entry

Answers the port's ask #1, which it had flagged as the only one of its four
that could delete an authored entry rather than confirm one. It confirms one.

Held at the title with no input, the plate oscillates continuously: two windows
in one boot, 58 s and 57 s, ~23 cycles each, no decay. Periods 2.530 and 2.540 s
by upward mid-crossings -- 0.4 % apart.

It never goes off. The plate-absent floor is 159 green pixels, measured on the
committed live-title-build4-no-plate.png; the pulse bottoms at 714, 4.5x that.
So the port's 'flash and nothing after', reasoned from ptbtn00 expiring at
t=244, is wrong on the boot's end state -- ptbtn00f's 120-unit cycle is what
runs.

Instrument controls were run before it was pointed at anything unknown: the
glyph counter reproduces the documented 753 on live-title-press-a.png and 327 on
live-main-menu.png exactly.

Two estimators, and only one replicates. Mid-crossings agree across the two
windows to 0.4 %; a single-sinusoid least-squares fit does not (2.553 vs 2.413),
because the waveform is fast-rise/slow-decay rather than sinusoidal -- its own r2
of 0.468 and 0.228 is the tell. Both were controlled on synthetic sinusoids at
2.24/2.55/3.10 s laid on the ACTUAL timestamps and recovered every one exactly,
so neither is broken; one is misspecified. Recorded as such.

The wall-clock is 13 % longer than the corpus's earlier 2.24 s mean. Same
declared 120 units, different emulator pacing (x1.27 here against x1.12), so
this corroborates 'author the units' rather than disturbing it.

Reach stated: one boot; does not distinguish the boot title from an attract-loop
title; and the glyph count is a thresholded pixel count, so 714/1520 is not an
alpha ratio and no duty cycle can be read off it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
sylph-decoder
2026-08-30 07:37:49 +00:00
parent ec06c50bf6
commit 3c004845fa
4 changed files with 3198 additions and 0 deletions

View File

@@ -180,3 +180,4 @@ files, which is how the same ground got covered twice.
| [`structures/ui-forced-backdrop.md`](structures/ui-forced-backdrop.md) *(colour census + self-refutation)* | What colour a keyless element is, and which forced verdicts the argument actually supports | ✅ **decoded, disc-wide**: every full-screen `*eff00*` **primitive** is **pure black** at its various alphas (`ff000000`, `7f000000`, `40000000`, `b2000000`, `cc000000`, `d4000000`, `00000000`) — exactly an alpha-over dim or fade, and an *additive* black quad would be a no-op nobody would author. The **only** non-black primitive on the disc is `pbafc.prm`, RGB `00e8e0` cyan at alphas to `ff`, and it is **844×600, not full-screen**, so outside the backdrop rule's geometry guard — ❔ it is now the sole additive candidate. 🔴 **Self-refutation: of the 80 forced-first instances only 42 are `.prm`; 38 are `.tbm` carrying fade `ffffffff`.** A *solid* white quad painted first would make the screen white and no screen is white, so a `.tbm` is a white **modulation on a texture** — and element alpha does not establish its coverage. That is the `.t32` error one extension further out: I had fixed the symptom (`el.sprite.is_some()`) not the cause, **an element's alpha is not its texture's opacity, and only an untextured primitive makes the two the same fact**. So 42 verdicts stay **decoded**, 38 drop to 🟡 (still almost certainly right — all named `*base*`, full-screen, and `pfbase.tbm`'s first position is *measured* — but on a name-and-role argument this page elsewhere calls the weaker kind). ⚠️ Code deliberately unchanged: restricting to `.prm` would send eleven screens' backgrounds back to last, the blank-screen bug the rule fixed. Split pinned by a test |
| [`structures/ui-prm-blend-mode.md`](structures/ui-prm-blend-mode.md) | Whether a primitive blends additively or alpha-over | ❔ **undecodable, with reach** — but the consequence is closed. Looked in **the bundle** (no field: the declaration words are constant and a primitive has no RATC child at all), **the colour census** (every full-screen `*eff00*` primitive is **pure black**; the only non-black primitive on the disc is `pbafc.prm`, cyan `00e8e0`), **the occlusion constraint** (inapplicable — `pbafc.prm` strobes 255/124 every 2 units, travels, and is scaled **2 %×3 %**, so it draws ~**17×18 px**, not its declared 844×600), and **the oracle** (`GP_READY_ROOM` is a recorded no-go and gameplay needs the Ⓐ that faults the guest). ✅ **Why it stopped mattering:** for a *black* quad the hypotheses differ only in whether it hides what is beneath — drawn **first** it is correct under **both**, drawn **last** only under additive. So `forced_backdrop`'s verdict is robust to the open question, and the port's original "layerless sorts last" was wrong under alpha-over and merely pointless under additive. ⚠️ This is not evidence *for* alpha-over. 🔴 The investigation found `forced_backdrop` judged coverage from the **pivot alone**, ignoring scale; checked first, **all 80 forced instances are at 100 %**, so no verdict moved and the added guard is defensive |
| [`structures/title-a-press-fault.md`](structures/title-a-press-fault.md) | Why a single Ⓐ on the title faults the guest — the blocker on all menu-side dynamic RE | ✅ **SOLVED 2026-08-30, and it is the emulator, not the game.** Xenia returns `X_ERROR_SUCCESS` with a *zeroed* keystroke on every `XamInputGetKeystrokeEx` while a XAM dialog is up (`xam_input.cc:197`, upstream); the game's pump is an **unbounded** `while (GetKeystrokeEx()==SUCCESS) queue.push_back()`, so it queued **8 388 608** empty keystrokes, grew its vector to 64 MB, asked for 128 MB, got a failed allocation back **unchecked** and copied off the top of the guest thread stack. ✅ **The number is the argument**: the Canary counter reports **8 388 601** swallowed calls at the last report before the crash, the dump's `r29` says the vector held **8 388 608** — two independent instruments, 7 apart, inside the 600-call reporting granularity. No new boot: the failing run's 326 MB log was still on disk. 🔴 **RETRACTED — "`r9` is a wild pointer above 4 GB"**. Xenia prints `si_addr`, a *host* address, and the guest is mapped at `0x100000000`: `0x1701D0000 0x100000000 = 0x701D0000`, which **is** `r9` in the dump — an ordinary guest heap address on an uncommitted page. Subtract `0x100000000` from every `Access Violation … at 0x1________` before reading it. ✅ **Decoded code path**, image-checked with **0 mismatches** over 586 instructions: `sub_824574C0` the input-manager singleton at `0x828F3888`, `sub_82457038` the keystroke pump, `sub_82457780` its `vector<X_INPUT_KEYSTROKE>` insert-with-grow. ✅ **It explains the earlier successes**: whether a XAM dialog is up is *emulator* state, so "reproduced 4/4" and "Q4/Q5 pressed Ⓐ fine" were both always true. 🟡 **Which** dialog is still open — `XamShowDeviceSelectorUI` is ruled out (`storage_selection_dialog = false` takes the headless path), `XamShowSigninUI` / `XamShowMessageBoxUIEx` are not; the settling experiment is one log line per `is_xam_dialog_present_.store(true)` site, not another blind boot. 🟡 Three untried routes out: dismiss the dialog, `--headless`, or return `X_ERROR_EMPTY` from the swallow. ✅ `frame_clock.sh`'s 300 MB guard killed the run as designed — keep it |
| [`structures/plate-pulse-measured.md`](structures/plate-pulse-measured.md) | Does the `PRESS Ⓐ` plate stay up, pulse, or blink once? | ✅ **measured** — it **PULSES**, continuously and without decay, on a title held with **no input**: two windows in one boot, 58 s and 57 s, ~23 cycles each, periods **2.530 / 2.540 s** agreeing to 0.4 %. ⚠️ **It never goes off** — the plate-absent floor is **159** green pixels (the title art's own, from `live-title-build4-no-plate.png`) and the pulse bottoms at **714**, 4.5× that. So the port's "flash and nothing after", reasoned from `ptbtn00` expiring at t=244, is wrong; `ptbtn00f`'s 120-unit cycle is what runs. 🔴 **Two estimators, one misspecified**: mid-crossings replicate to 0.4 %, a single-sinusoid fit does not (2.553 vs 2.413) because the waveform is fast-rise/slow-decay — and its own r² of 0.468/0.228 is the tell. Both were controlled on synthetics at 2.24/2.55/3.10 s laid on the real timestamps and recovered all three exactly. 🟡 wall-clock is **13 % longer** than the corpus's earlier 2.24 s mean — same declared 120 units, different pacing (×1.27 vs ×1.12), so **author the units**. ⚠️ Reach: one boot; does not distinguish the boot title from an attract-loop title; the glyph count is a thresholded pixel count and **not** an alpha, so no duty cycle can be read off it |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
# The `PRESS Ⓐ` plate **pulses**, continuously — it does not blink once
**Classification: measured.** Xenia Canary, 2026-08-30, one no-input boot, two
separate title windows. Answers the port agent's ask #1, and the answer **deletes
nothing** — it says the port is currently wrong on the boot's end state.
## The question, and why it mattered
The port had removed a speculative `looping_focus_records` pulse, leaving a
renderer that *"shows a flash and nothing after"* — reasoning from `ptbtn00`, whose
keyframes make it opaque for 8 units (t=236238, gone by 244). It asked for the
observed shape, saying this was the one ask that could **delete** an authored entry
rather than confirm one.
It confirms one. **Keep the pulse.**
## What the running game does
Held at the title with **no input at all**, the plate oscillates continuously for as
long as the title is up — 58 s in one window and 57 s in another, ~23 cycles each,
with no decay and no settling.
| | window | duration | glyph px | period |
|---|---|---|---|---|
| run 1 | t = 254…312 s | 58 s | **714 … 1520** | **2.530 s** |
| run 2 | t = 83…140 s | 57 s | **714 … 1520** | **2.540 s** |
Two windows of one boot, agreeing to **0.4 %**. Evidence:
[`../data/plate-pulse-timeseries.txt`](../data/plate-pulse-timeseries.txt) ·
[peak frame](../captures/title-builds/live-title-plate-pulse-peak.png) (1520) ·
[trough frame](../captures/title-builds/live-title-plate-pulse-trough.png) (714).
## The instrument, and its controls
`tools/re-capture/plate_timeseries.py` counts the green Ⓐ-glyph pixels — the same
counter as `is_title.py`, byte-identical. **Controls run before it was pointed at
anything unknown**, on committed captures:
| capture | counted | documented |
|---|---|---|
| `live-title-press-a.png` | **753** | 753 ✅ |
| `live-main-menu.png` | **327** | 327 ✅ |
| `live-title-build4-no-plate.png` | **159** | — |
⚠️ That third one is the reason the result is readable at all: **the plate-absent
floor is 159, not 0** — the title art carries green pixels of its own. During the
pulse the count never goes below **714**, four and a half times the floor, so *the
plate is never absent*. It dims and brightens; it does not blink off.
### 🔴 One estimator replicates and one does not — and the failing one says so
| | run 1 | run 2 | agrees? |
|---|---|---|---|
| upward mid-crossings | **2.530 s** | **2.540 s** | ✅ 0.4 % |
| single-sinusoid least squares | 2.553 s | 2.413 s | ❌ 5.8 % |
Both were controlled on synthetic sinusoids at 2.24 / 2.55 / 3.10 s laid on the
**actual sample timestamps**, and both recovered every one exactly — so neither is
broken. The sinusoid fit is **misspecified**: the waveform is a fast rise and slow
decay, not a sinusoid, and its own variance-explained ($r^2$ = 0.468 and 0.228) is
the tell. **Take 2.535 s**, from the estimator that does not assume a shape.
⚠️ Indexing by sample position rather than timestamp is the documented trap here
([`ui-clock-freezes-at-settle.md`](ui-clock-freezes-at-settle.md), where it returned
48 against a true 51); both estimators use the timestamps.
## 🟡 The wall-clock is 13 % longer than the corpus's, and that is expected
[`ui-record-loop-length.md`](ui-record-loop-length.md) decodes the plate's cycle as
**120 units declared**, and earlier runs measured 2.12 / 2.19 / 2.34 / 2.31 s
(mean **2.24**). This run gives **2.535**.
| | implied units→seconds factor |
|---|---|
| declared 120 units at a nominal 60 units/s | 2.000 s |
| corpus's earlier runs | ×1.12 |
| **this run** | **×1.27** |
Same declared number, different emulator pacing — this container was under load.
✅ **This corroborates the existing instruction rather than disturbing it: author
the 120 units, never a second count.** Any wall-clock figure from this container is
pacing-dependent and is not comparable across runs without an independently
measured pacing factor, which this run does not have.
## Reach
⚠️ **Boot title or attract title — this does not say.** The first window opens at
t≈255 s from launch, and Q9's no-input baseline puts the title at ~193 s, so run 1
may already be an attract-loop title rather than the boot's first. Both windows are
"the title, held, with no input", which is what was asked; neither is proof about
the *first* appearance specifically.
⚠️ **The glyph count is a thresholded pixel count, not an alpha.** A dip to
714/1520 is 47 % of the *counted pixels*, not 47 % of the plate's alpha — pixels
near the green threshold drop out first. Do not read a duty cycle or an alpha ramp
off these numbers; the shape (periodic, non-decaying, never absent) is what is
measured.
⚠️ **One boot.** Two windows inside it are not two boots, and the pacing factor is a
property of the run.