diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 5c4fcda7..56bdf97f 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.md @@ -331,6 +331,20 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the noticing that what you are about to look at merely *correlates* with what you want to know. +* **Match the noise floor to the quantity — including which noise actually + applies.** A margin needs a floor, but the floor must be the one that moves + *that* margin. Two renders scored against one capture share the capture, so + capture noise largely **cancels**: measured on the JP title, the absolute scores + moved 0.001–0.002 between sessions while the **margin** moved 0.001, against an + in-box capture noise of 0.32. Judging that margin against a whole-frame capture + spread — a number that was simply to hand — made a non-decisive result look + decisive, and this corpus published that for part of a day. + ⚠️ Relatedly, `sylpheed-port` verified a harness "reproducible" from an RMSE + **printed to two decimals** when the residual was 0.0565: **an instrument that + rounds away the thing being verified cannot verify it.** Check the printed + precision against the quantity before quoting the number, and prefer comparing + *frames* to comparing a statistic about them. + ## Runtime / emulator * **Look at the PNG** — and check its dimensions. diff --git a/docs/re/captures/title-builds/live-title-jp-at-rest-run2.png b/docs/re/captures/title-builds/live-title-jp-at-rest-run2.png new file mode 100644 index 00000000..21eff030 Binary files /dev/null and b/docs/re/captures/title-builds/live-title-jp-at-rest-run2.png differ diff --git a/docs/re/data/jp-title-at-rest.txt b/docs/re/data/jp-title-at-rest.txt index 587c3d70..ab8f7a68 100644 --- a/docs/re/data/jp-title-at-rest.txt +++ b/docs/re/data/jp-title-at-rest.txt @@ -43,3 +43,34 @@ # the ptlogo3a/b/c + ptlogo_back2eff* stack, which ui-forced-backdrop and # the tie-break work record as TRANSPARENT at rest on the English title. # That is exactly the region the port's drift is localized to. + +################################################################################ +# SECOND, INDEPENDENT CAPTURE -- 2026-08-30, a fresh boot in a separate session. +# tools/re-capture/jp_title_session.sh (sets ja, captures, ALWAYS restores en). +# +# Why: the five frames above demonstrate the logo stack is at rest WITHIN a run. +# They say nothing about the axis sylpheed-port's drift was on -- BETWEEN runs, +# where a free-running clock lands somewhere else on a fresh boot. Nothing in +# this corpus covered that axis, and the ptlogo_eff3 era adjudication rests on +# a single capture. +# +# Within-run stability REPRODUCES in session 2: +# ROI 350x396 at (405,74): frames 1-4 vs 0, max |d| 0, 0 / 138 600 differing +# whole frame contrast: 47 278 / 51 034 / 58 922 / 72 958 px moving +# +# BETWEEN SESSIONS, inside the 388x423 box the era adjudication uses: +# 645 of 164 124 px differ, max |d| 41, RMSE 0.3215 +# whole frame, for contrast: 116 492 px differ, max |d| 51 +# -- so the two captures are genuinely from different sessions. +# +# THE VERDICT REPRODUCES TO THREE DECIMALS: +# vs session-1 capture vs session-2 capture +# stale era rest (108,72) 58.412 58.413 +# fixed era rest (98,42) 41.690 41.692 +# margin 16.722 16.721 +# +# 📌 And the shape of that is the useful part: capture noise moves BOTH +# candidates together, so it very nearly cancels in a MARGIN. The absolute +# scores moved 0.001-0.002 between sessions and the margin moved 0.001, against +# an in-box capture noise of 0.32. A margin between two renders scored on one +# capture is far more robust than either score is. diff --git a/docs/re/structures/ui-resting-pose.md b/docs/re/structures/ui-resting-pose.md index 8e22e4f5..36f209fa 100644 --- a/docs/re/structures/ui-resting-pose.md +++ b/docs/re/structures/ui-resting-pose.md @@ -93,16 +93,47 @@ the two captures differ by **83 496 pixels** whole-frame (max |d| 174) — they genuinely different grabs — and by **0** inside the box. The screen's free-running element is the plate, which lies outside the logo region the adjudication uses. +### ✅ And a second JP capture, from a fresh session, closes the transfer + +The paragraph above transferred the *EN* title's capture noise to the *JP* box and +flagged that as a limit. A second independent capture was taken — +[`jp_title_session.sh`](../../tools/re-capture/jp_title_session.sh), fresh boot, +separate session, locale set and restored — +[`live-title-jp-at-rest-run2.png`](../captures/title-builds/live-title-jp-at-rest-run2.png). + +Within-run stability **reproduces** (0 of 138 600 in the ROI, 47k–73k px moving +whole-frame as the contrast control). Between sessions, inside the box this +adjudication uses: **645 of 164 124 px differ, RMSE 0.3215**, against 116 492 px +whole-frame — genuinely different sessions. + +**The verdict reproduces to three decimals:** + +| | vs session-1 capture | vs session-2 capture | +|---|---|---| +| stale era rest `(108,72)` | 58.412 | 58.413 | +| fixed era rest `(98,42)` | 41.690 | 41.692 | +| **margin** | **16.722** | **16.721** | + +📌 **Capture noise moves both candidates together, so it nearly cancels in a +margin.** The absolute scores moved 0.001–0.002 between sessions while the margin +moved 0.001, against an in-box capture noise of 0.32. A margin between two renders +scored on one capture is far more robust than either score is — which is why the +render axis, not the capture axis, is the binding constraint here. + **So the margins re-stated against every noise floor now measured:** -| comparison | margin | vs render noise (1.2) | vs capture noise (0.0 in-box, 2.8 whole-frame) | +| comparison | margin | render noise (1.2) | in-box capture noise (0.32) | |---|---|---|---| -| stale vs fixed era | **16.7** | 14× | ≥5.9× | -| settle vs rest | **1.5** | 1.2× | below whole-frame noise | +| stale vs fixed era | **16.72** | **14×** — decisive | 52× — decisive | +| settle vs rest | **1.48** | **1.2×** — NOT decisive | 4.6× | -The era result survives on both axes. The settle-vs-rest negative is **stronger** -than first stated: 1.5 is not merely inside the render plateau's flatness, it is -below the whole-frame capture spread as well. +🔴 **Correction to a claim made earlier the same day.** This page briefly said the +settle-vs-rest negative was *strengthened* because 1.48 sits below the +**whole-frame** capture spread of 2.8. That was the wrong comparison: the +measurement lives in the box, and the in-box between-session noise is **0.32**, so +1.48 is well above it. The negative rests on the **render** axis alone, exactly as +first stated — the "strengthening" was reaching for a number that was to hand +rather than the one that applies. ⚠️ **Reach of the transfer.** This is the *EN* title's capture noise applied to the *JP* title's box. Build 7 carries `ptloop01/02.rat`, which may animate inside that diff --git a/tools/re-capture/jp_title_session.sh b/tools/re-capture/jp_title_session.sh new file mode 100755 index 00000000..273e8e22 --- /dev/null +++ b/tools/re-capture/jp_title_session.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Drive a JAPANESE title capture end to end, and ALWAYS put the locale back. +# +# The first JP capture (2026-08-30) demonstrated the logo stack is at rest +# WITHIN a run: five frames ~1.5 s apart, byte-identical over the port's ROI, +# against a whole-frame contrast control showing 5-8 % of the screen moving. +# That does not test the axis sylpheed-port's drift was on -- BETWEEN runs, where +# a free-running clock lands somewhere else on a fresh boot. This script exists +# to take a second, independent capture so that axis can be measured. +# +# Usage: jp_title_session.sh OUTDIR [wait_s] +set -u +export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98 +SD="$(cd "$(dirname "$0")" && pwd)" +OUT="${1:-/sylph-home/re/jp2}"; WAIT="${2:-700}" +mkdir -p "$OUT" + +restore() { + echo "-- restoring locale --" + python3 "$SD/set_console_language.py" en || echo "RESTORE FAILED -- check by hand" + python3 "$SD/set_console_language.py" --show +} +trap restore EXIT INT TERM + +ps -o pid= -C xenia_canary | xargs -r kill -9 # kill by NAME: `pkill -f` matches this shell +python3 "$SD/set_console_language.py" ja +python3 "$SD/set_console_language.py" --show + +( cd "$OUT" && nohup run-canary --mem_watch=false \ + --logged_profile_slot_0_xuid=B13EBABEBABEBABE \ + >"$OUT/canary.stdout" 2>"$OUT/canary.stderr" & ) +sleep 8 +timeout $((WAIT + 120)) python3 "$SD/jp_title_capture.py" "$OUT" "$WAIT" +echo "CAPTURE STEP DONE" +ls -la "$OUT"/*.png 2>/dev/null | head