Files
Sylpheed/docs/re/REFUTED.md
sylph-decoder 95ceb70cb5 re: the refuted register ignored the deaths I just wrote, and two false positives shared a cause
Three refutations written as prose under ### headings never entered the register:
check_refuted.py parses * "claim" lines, so the count stayed at 188. Registered
them properly (188 -> 192). A register that parses one syntax silently ignores
every other, and it is invisible from the author's side -- ask the register what it
holds, do not re-read what you wrote.

Both standing false positives were bullets under a header that retracts the whole
list, with no marker in the +-4-line window: scope marks them, not proximity. The
scan now includes the nearest preceding header and matches markers
case-insensitively ('An earlier version' was missed by the marker 'an earlier
version'). Controlled by planting a real revival and confirming it is still caught;
register now runs clean at 0.

Also records sylpheed-port's diagnosis of the phase-lock fallout: a number can be
inapplicable rather than wrong, and a tension built on one is manufactured. Plus
their point that some claims are not registrable in a substring register at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-30 20:02:21 +00:00

764 lines
49 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.
# Refuted — claims that were tested and died
**Read this before proposing a hypothesis.** Every line below was believed at
some point, measured, and found false. Reviving one costs a whole iteration and
produces nothing.
This file exists because the list had been living in the autonomous agent's
*loop prompt* — the only copy, lost the moment the container was. A refuted
result is a real result; it belongs in the corpus like any other.
**Format:** each entry is the claim as it was believed. Where the true answer is
known it follows after `→`. Grouped by subject so a grep for your noun finds the
neighbourhood, not just the line.
---
## Offsets, structs and the progress singleton
* `position = instance 0x12c` → refuted.
* `+0x29d0` → refuted.
* "an offset intersection can find a struct's consumer" → **only for LARGE or
unusual offsets.** Small ones have no power (`+184`: 301/351/115 hits).
* "a `+1956` store means a progress write" → writes go through the COPY, not
direct stores. 9 direct stores, none of them a progress write.
* "the singleton-global filter can find progress writers" → it fails its own
control.
* "the progress copy destination is an `r1`-relative stack local" → it is a
**frame register**. The `r1` assumption returned 0 for all 21 candidates
*including the known-good* — the filter was killed by its own control.
* "word B's writer also stores the Time/Points record" → it does not.
* "the debriefing records the metric with the clear bit" → 44 calls, exactly two
strings (`DEBRIEFING`, `BASE_INFO`), no `Time`, no `Points`.
* "`0x820AF030` holds live state" → all 384 words constant; it is a
spawned-entity record, not live state.
## Screens, classes and RTTI
* "the rotated draw in the title's capture is the `Z` swoosh
(`ptlogo_back2*`)" → **mine, and refuted.** Its quads span y 209…925 and
292…1012 in screen space; the swoosh is a band at y 126…360.
[`ui-title-build-map.md`](ui-title-build-map.md)
* "the keyframe words at `+4`/`+8`/`+12` are always zero" → they are non-zero in
**4.76 %, 4.62 % and 14.50 % of 83 862** blocks disc-wide, reading as
**degrees** (±180, ±90, 120, 360). The original note was a sample artefact.
(Superseded figures: an earlier count of 72 287 blocks missed every nested
record — see the alignment entry below.)
* ~~"those angle fields are where the title's rotated quads come from" → **no** —
every `GP_TITLE` build 4 element has all three at zero.~~ → **that refutation
was itself wrong, and is withdrawn (2026-08-28).** `+12` *is* exactly where
they come from. Build 4's **top-level** elements do all read zero; the rotated
quads belong to its two **nested** leaf records, `ptloop01.rat` (`+12` = 30)
and `ptloop02.rat` (`+12` = 45), which the census never opened. Measured
off the GPU: **+30.26°** and **45.28°**.
[`ui-keyframe-rotation.md`](structures/ui-keyframe-rotation.md)
* "the rotated draw's element cannot be named from the capture" → refuted; its
quads' **edge lengths** name it. 400 × 1076 and 400 × 1444 match `pteff03`
399×180 at 600 % and `pteff03a` 399×180 at 800 % — two different heights, both
landing. [`ui-keyframe-rotation.md`](structures/ui-keyframe-rotation.md)
* "a keyframe-block scanner may assume 4-byte alignment" → refuted; it found
**0/3** of its own control blocks and under-counted the corpus by 16 341
blocks. Nested `RATC` blobs start at odd offsets (`0xbb5966`).
* "keyframe rotation lives only in **nested** `.rat` leaf records" → **mine, and
refuted within the hour by my own sweep.** It held for the three archives I had
checked (`GP_TITLE`, `GP_BUNK`, `GP_CHALLENGE`) and failed on the next:
`GP_DIALOG` and `GP_DEBRIEFING_PILOTLOG` rotate **top-level** elements, and
those are the clearest examples on the disc.
[`ui-keyframe-rotation.md`](structures/ui-keyframe-rotation.md)
* "the pivot-anchored scale formula `kf.x pivot·(scale100)/100` is our
renderer's reading, not a measurement" → **now measured.** At the `ptloop`
pair's 600 %/800 % scale it predicts both quad centres at y = 360.0 against a
captured 359.1/360.0, where top-left anchoring predicts 810/990.
[`ui-keyframe-rotation.md`](structures/ui-keyframe-rotation.md)
* "the game passes a pink per-vertex colour for the title swoosh" → **refuted by
draw capture.** Every vertex colour in the capture is `<alpha>FFFFFF`, white RGB.
* "the swoosh discrepancy is undecodable" → **solved**: the game submits it as two
**rotated parallelograms**; `ui_layout::blit` only does axis-aligned rectangles.
[`ui-title-build-map.md`](ui-title-build-map.md)
* "the `--log_ui_draws` per-draw capture reads the guest's blend state" →
**mine, and wrong.** It records primitive type, index count, index-buffer
address, VS/PS ucode hashes, texture bindings and vertex attribute 0 — no
`RB_BLENDCONTROL`. It can test vertex colour as-is; blend state needs a Canary
change. [`ui-title-build-map.md`](ui-title-build-map.md)
* "the plate-free title capture (t ≈ 4.0 s) may be too early to be settled" →
**mine, and refuted.** The swoosh band correlates 0.7342 at t = 4.0 s and
0.7353 at t = 21.5 s — identical to 0.001 over 17.5 s.
* "`T8aD +0x04` bit `0x02` selects an additive blend" → **mine, and refuted.**
Blending those sprites additively worsens every measure against the capture.
[`ui-title-build-map.md`](ui-title-build-map.md)
* "the title logo elements' wrong pivots (off by up to 59 px, authored against the
other language's sprite) explain the swoosh rendering too thick" → **mine, and
refuted.** `blit` sizes from the texture and applies the pivot only as
`pivot·(scale100)/100`; all seven swoosh elements are scale `(100,100)` at every
keyframe, so the term is zero. The mismatch is real but inert here — it would
bite `ptlogo1`/`ptlogo2`, which scale to 150 during the build-in.
[`ui-title-build-map.md`](ui-title-build-map.md)
* "the title screen loops at ≈ 2.2 s" → **mine, and doubly wrong.** The title
*art* is near-static (wordmark sd 0.06); the 2.3 s pulse is the
**`PRESS Ⓐ BUTTON` plate**, which is a *different build* (2, not 4). Localised
by a per-tile amplitude map and decoded in `ptbtn00f.rat`.
[`ui-title-build-map.md`](ui-title-build-map.md)
* ~~"a `.rat` leaf record's keyframes use the build's 40-byte layout" → they do
not~~ — **withdrawn.** They do. The scan that "found nothing" required 29
increasing times; the records hold **three**. Decoded in
[`ui-title-build-map.md`](ui-title-build-map.md).
* "the title's measured ≈ 2.2 s oscillation is the `ptloop01`/`ptloop02`
elements" → **mine, and refuted by decoding them.** Their sweeps run 7.5 s and
9.5 s; a 22 s capture showed 8 peaks, not 3. The period's source is unidentified.
* "the developer splash cannot be rendered by `screen render` at all" → it can,
with **`--all`**. It is only invisible to the *default* listing, which filters on
`is_build`. [`ui-title-build-map.md`](ui-title-build-map.md)
* "the four `GP_TITLE` entries that are not screen builds are unidentified" → they
are the **splash**: 10/13 the `SQUARE ENIX` logo, 11/14 the developer logos.
* ~~"the boot title is phase 2 and the attract title is phase 4 state 0, and only
phase 2 handles Ⓐ" → refuted~~ — **the REFUTATION is withdrawn.** The test
assumed Ⓑ lands in phase 4 state 0; the event-0 block actually sets
**phase = 2** and state = 0 together, so it probed phase 2. The hypothesis is
untested, not dead.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "any title after the first one refuses input" → too broad. The **Ⓑ-returned
title accepts Ⓐ**; only the **attract**-returned title is inert.
[`canary-scripted-input-traps.md`](canary-scripted-input-traps.md)
* "`sub_821C6458` is `GamePart_Title`'s state machine" → **mine, imprecise.** It
is the machine for **phase 4** of a five-way outer dispatch at `this+132`;
phase 0 is the splash. The ten states and eighteen edges are phase 4 only.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "`sub_821CC860` is the game's by-name screen factory" → **mine, and wrong.** Its
decoded arguments include `BG`, `BLACK`, `FADE`, `FILE`, `KEY`, `PAD`, `SOUND`,
`GAMMA_RGB` — it is a **generic name-keyed lookup**, mostly config.
* "`DIFFICULTY` and `EXTRA_MENU` are corroborated screen names" → **mine, and
wrong.** Neither appears in `r5` at any of the 48 call sites; they were strings
merely referenced by the same functions. Only `TUTORIAL_MENU` survives.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "the `{func, func, ptr}` triples at `0x820a3b48` are a GamePart state table" →
**static-initialiser records trailing the `RegisterToFactory` strings.** The
bytes before them are the tail of a diagnostic string and the data column is
zero-filled descriptors.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "the boot sequence is driven by a table the game reads" → it is **not
data-driven**; four search spaces closed, transitions are calls with an id
argument. [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "`config.ini` is a GamePart settings table, so the boot order is in it" → its
`[SYSTEM]` section is **empty**; the only populated section is `[LANGUAGE]`.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "the attract loop is `GP_ADVERTISE_DEMO` (GamePart 1)" → 🟡 id 1 has **no
registration site** in the shipped build; the attract is the title replaying
`ADV.wmv`.
* "the 29 id-table names are 29 distinct GameParts" → 24 register, and `3`/`4`
are the **same class** (`GamePart_SaveLoad`).
* "Ⓐ on `NEW GAME` leads to a standing black-screen hang" → it opens
**`DIFFICULTY`**, then **`SELECT DATA`**. What looked like a hang was a menu
waiting for input that nobody pressed; the crash that follows is the already
documented `sub_823070B0` cache throw.
[`menu-navigation-semantics.md`](menu-navigation-semantics.md)
* "tapping Ⓐ during the boot movie breaks the title" → **one** tap skips the
movie cleanly and the title works normally. It is *hammering* (88 presses) that
breaks it. [`movie-binding.md`](movie-binding.md)
* "the attract movie runs ~85 s, so it is not `ADV.wmv` (137 s)" → **mine, and
wrong.** Sampling began 39 s into the movie, so what was timed was its tail.
The attract movie **is** `ADV.wmv`, played in full.
[`movie-binding.md`](movie-binding.md)
* "the boot intro and the attract movie are different videos" → one asset, one
manifest slot (`ADVERTISE_MOVIE`).
* "the new-game intro is unidentified" → `MS00A``S00A.wmv`, decoded from the
movie manifest.
* "`GP_READY_ROOM.pak` holds the Ready Room screen" → its 317 distinct element
names contain **none** of the six visible labels; it is the briefing /
tactical-map content behind the `BRIEFINGS` item.
[`ready-room-probe.md`](ready-room-probe.md)
* "the Ready Room might be 3D with a UI overlay" → it is **2D**; the pak carries
zero 3D containers.
* "element kind `0x3002` is *the* button kind" → title-side only. All 902
`GP_READY_ROOM` bundles have **zero** `0x3002`; that pak uses `0x3000`,
`0x3004`, `0x300c`, `0x3008`. `0x3002` is one member of a `0x3000` family.
* "the transition between menu screens is a cut" → it is a **fade through
black**; a 0.5 Hz screenshot burst simply samples too slowly to see it.
[`screen-transitions.md`](screen-transitions.md)
* "the main menu's initial focus is fixed" → three boots of one script gave
`TUTORIAL`, `TUTORIAL`, `NEW GAME`.
* "the title menus drop d-pad presses shorter than ~0.3 s" → **refuted by my
own data.** The menu **wraps at both ends**; every press registered, and the
"missing" step was the wrap. See [`menu-navigation-semantics.md`](menu-navigation-semantics.md).
* "the main menu opens with `NEW GAME` focused" → it opens on **`TUTORIAL`**,
2/2 boots (🟡 a third recorded run implies `NEW GAME`, so this is reproducible,
not invariant).
* "`GP_TITLE` builds 6/8/9 are three submenus" → **8 is the JAPANESE main
menu**, and 6/9 are the English and Japanese `EXTRAS` submenu. `GP_TITLE`
holds eight screens shipped twice (EN/JP), and exactly one submenu. See
[`ui-title-build-map.md`](ui-title-build-map.md).
* "the `PRESS Ⓐ BUTTON` plate is a state of the title build" → it is **its own
build** (2/3), composited over build 4 and faded in a beat later.
* "the RTTI route can name the anonymous classes" → 1 150 vtables: 1 150
`ANON_`, 0 `rtti_present`, 0 base classes.
* "the sibling vtable methods name the class" → they cannot.
* "`xrefs` can name the callers of a vtable method" → no.
* "the `ind_call` refutation voids existing corpus claims" → damage bounded,
4/4 caller claims verify. But **`xrefs.ind_call` is a CROSS PRODUCT** — always
filter `kind='call'`.
* "`BASE_INFO` marks the 5-slot screen family" → it discriminates
screen-config from table-read, 9/9 vs 10/10.
* "a high key count means a rich screen" → `sub_82297550` / `sub_822A2F00`'s 27
"keys" are coordinate pairs, i.e. a layout table.
* "`EX_` = the CHALLENGE-mission debriefing" → `EX_` is **EXTRA**, mission-kind
3.
* "the `EX_` selection has not been shown" → it has: `[[obj+4]+184] == 3`.
## Stages, missions and the challenge set
* "the disc's stages are numbered 1..28" → S01S16 story, S17 **cut**, S18S23
tutorials, S24S29 challenge.
* "S24S29 are story missions" → they are the challenge missions.
* "the challenge missions have their own maps" → they reuse
`GP_MAIN_GAME_E.pak`'s stage records.
* "the challenge `REQUIREMENT` values are 16,25,26,27,29" → the chain is
16→24→25→26→27→28.
* "the `Extra0n` family shares one leaderboard metric" → `RECORD_TYPE` is
per-stage: 3 Time / 3 Points.
* "stage = filled SHAB count + 1" → refuted.
* "the first TRIGGER is always the point of no return" → refuted.
* "`EnumUnit_S14.tbl` might be missing" / "S14's 13 are a manifest omission" /
"asteroids are exempt from the manifest" → S14's 13 are **dangling
deployments**. NEEDS-HUMAN: fly S14.
* "`StageMessageSet_S02.tbl` is not in the pak" → it is.
* "`S28_p1` has an asteroid volume with no definition" → refuted.
* "`test_s8p1_asteroid.tbl` is test-only" → refuted.
* "the settings family has 28 or 29 objects" → 24.
## ISL / mission scripting
* "the bytecode is in the `.embsec_` sections" → refuted.
* "only 31 built-ins take a unit" → refuted.
* "`sub_8230C398` is the message pump" → refuted.
* "`bus+8216` is the subscriber registry" → refuted.
* "the ScriptPhase vtable is ≥200 slots" → 113.
## IDXD, paks and naming
* "IDXD record keys are `name_hash`" → record keys are **`tag_hash`**
(case-SENSITIVE); `name_hash` is case-INSENSITIVE and used for pak keys.
* "pak TOC order is stage order" / "TOC order is semantic order" → it is not.
* "the executable holds the asset names" → the image names **no data value at
all**; that route is powerless.
* "the image might name a data VALUE" → powerless.
* "the XPR2 manifest names hash to the DefTables tables" → refuted.
* "the `DefTables` model names are unreachable" → reachable via the `Enumerate`
declaration tables (1 413/1 425, 99.2 %).
* "the `GP_MAIN_GAME_*` unnamed block is undiscovered data" → refuted.
* "each `GP_MAIN_GAME_*` `Enumerate` object declares something" → refuted.
* "`GP_HANGAR_ARSENAL` is missing data tables" → refuted.
* "the `Enumeration` self-index can name objects" → a self-index names
**records, not files**.
* "a per-pak prefix might close the 2D blocker" → no.
* "the `+` paths might name the 2D or `GP_READY_ROOM` keys" → the `+`-dictionary
route is exhausted, 0 of 1 817.
* "the `game:\` paths are unresolved" → refuted.
* "a set-difference over file names can see reuse" → it cannot; **join per
USER**. Per-pak copies are ×6.
## Audio
* "which bank the menu plays is not on the disc" → the **cue table** cannot say
(all BGM cues are numeric), but the **code** can: `sub_821C5580` plays cue
**1103 = `BGM_103`**, and its two declared waves match the two streams the XMA
probe saw byte-for-byte.
* "the observed BGM stream sizes match no bank's declared waves, so the game hands
the decoder a window" → **mine, and wrong** — I checked only the `BGM_0xx` rows.
They are `BGM_103`'s two waves exactly; the game hands over the whole wave.
* "an individual SE cue's audio cannot be extracted" → **mine, and wrong.**
`--xma_param_probe=true` logs each stream's head bytes; searching them in
`Static.slb` locates the wave exactly. [`menu-audio-cues.md`](menu-audio-cues.md)
* "`Static.slb` has no wave boundaries, so its layout is unknown" → it is a
**packed run** of whole 2 048-byte XMA packets with no delimiters — the two
located cues are contiguous. There is nothing to scan for, by design.
* "`Pj_Silph.xgs` holds the cue→wave index, so parse XACT" → **no XACT container
exists on this disc**: 0 × `XGSF`/`SDBK`/`WBND` in all 1.08 GB of `sound.pak`,
and no `XACT`/`.xgs` string in the executable. The extensions are the authoring
tool's, not the format's. [`menu-audio-cues.md`](menu-audio-cues.md)
* "every sound cue resolves to its own `.slb` bank" → the 322 `SE_*` cues do not;
**0 of 322** are in `FILES`, and `BANK_SE` puts them all in `Static.slb`.
* "`Static.slb` can be split into waves like any other bank" → it holds **0
`RIFF`, 0 `seek`, 0 `WAVE`** across all 8 353 472 readable bytes.
[`menu-audio-cues.md`](menu-audio-cues.md)
* "`BGM_001.slb` is three sub-waves (10 KB + 4.47 MB + 4.67 MB)" → the 10 KB is
the **bank header**; a bank is **two** waves.
* "a music bank's two waves might be intro + loop, two variations, or two halves"
→ they are **two stems of one performance, played together** — equal duration
in 32/32 banks, and sample-synchronous.
[`structures/bgm-two-stems.md`](structures/bgm-two-stems.md)
* "`BGM_106``BGM_109` break the two-wave rule" → they are the leading-region
straddle; realigned across entry boundaries they obey it.
* "the cue table names which BGM belongs to which screen" → all 32 BGM cues are
numeric (`BGM_001``BGM_109`).
## Units, weapons, effects and assets
* "`Generic` (394) is the unit datasheet" → refuted.
* "a loadout's `Arm1` names an item" → it names a **hardpoint slot**
(`Turret_NNN`), 59/59.
* "`EnumUnit` and the unit datasheet share a vocabulary" → they do not.
* "the roster is the `Generic.Model` set" → roster 40, `Generic.Model` 46,
`GameResourceID` 480 — three vocabularies.
* "every unit ID is `UN_<l>###_<FACTION>_<name>`" → the grammar is
`UN_<letter>###_[<subkind>_]<FACTION>_<name>`.
* "`_EXn` is the `Extra0n` index" → three different `EX` vocabularies exist.
* "the only two `_EX5` names on the disc are the AA gun and the DeltaSaber" →
refuted.
* "running the tutorial will instantiate the `_Ttrl` weapons" → refuted.
* "the disc has exactly three `EnumWeapon` tables" → four.
* "the `wep_NN` package gaps are unshipped weapons" / "`wep_85` is the tip of a
family" → `wep_85` is the **only** declared-but-unshipped asset (59/0/1/26).
* "nothing is deployed without being declared" → refuted.
* "effects are one namespace" → refuted.
* "the 58 undeclared effect names are missing assets" → refuted.
* "all five orphan effects are unshipped" → refuted.
* "`eff_f0002` ships in `Base.xpr`" → refuted.
* "`Base.xpr` holds more bound effects than `ptc_pack`" → refuted.
* "the 34 unlocated are a scatter" → refuted.
* "the 9 unlocated might be under another prefix" → refuted.
* "`ptc_pack` has 532 names" → 727.
* "the `_e`/`_f` law is effect-FIELD-specific" → it is the **faction law**,
564/564.
* "a disc-wide `.xpr` byte search can show an effect is ABSENT" → it cannot.
* "`rot_n001` is on the disc" → refuted.
* "`rou_f004`'s mesh is in `Stage_S28.xpr`" → it is in `DeltaSaber_A.xpr`.
* "`parent` + `_all` + `_child` is the composite-model convention" → refuted.
`_hangar` **is** real (59 of 166, 59/59 with a bare twin); `_all`/`_child` is
not.
* "`Motion_guard_start` has no damage variants" → refuted.
* "`CoverArea` bits 2 and 3 are mutually exclusive" → refuted.
* "the 27 unresolved `NamePlate` values are missing objects" → refuted.
## LOD, background and misc tables
* "`EnumLODSet_*` is a per-stage family" → `EnumLODSet_test.tbl` serves 17
stages; 17+5+1 = 23.
* "there are 8 orphan LOD tables" → 6.
* "the orphans are stale copies of `_test`" → refuted.
* "S25 is absent from the `DefTables` LOD families" → refuted.
* "`BackGroundID` has no referent anywhere" → it is an **identity**.
* "`BackGroundPackage == BG_<id>.xpr`" → refuted.
* "`<X>ID` + `<X>Package` is a convention" → refuted.
* "`Placement_*` / `RouteTest_*` are unattached" → refuted.
* "the `AsteroidDefinition` join does not reproduce by hash" → it does.
* "the 8-value frame is a new finding" → it was already in the corpus.
## Loaders, config and tuning
* "the config reader is XML" → INI.
* "`sub_822F9498` is the unit-definition loader" → it is `PlayerParams`'s.
* "`sub_822AE628` reads the main-game `Tweak`" → refuted.
* "`sub_8230D1F8` is a rank table" → it is the stage-settings loader.
* "`sub_82286BC8`'s key list is new" → refuted.
* "`sub_825F2CF0` / `sub_825F2F88` read a post-processing table" → refuted.
* "`Booster` is a new schema" / "`Booster` is the player craft's flight
envelope" → refuted; nothing selects `Booster`.
* "the `AnalogRevice`/`Tweak` block is unreachable" → reachable
(`sub_821A6CF0`, base `0x820A1630`).
* "a 0-xref string block has no reader" → refuted.
* "the AI table was NEEDS-HUMAN" → refuted.
* "the `PG*` HUD names are undocumented" → they are documented.
* "a base-solver row identifies a FUNCTION" → it does not.
* "a 64K-boundary base is low confidence" → **inverted**; it is high
confidence.
* "the 0x820B0000 cluster is a false positive" → refuted.
* "a pointer to a function in the image implies a registry" → refuted.
`.pdata` is not a registry.
* "the 13 player-facing chatter tables are the WINGMAN tables" → refuted.
* "the 8 undeclared chatter tables are tutorial chatter" → refuted.
* "other datasheets ship a schema too" → refuted.
## Encoding and text
* "every IDXD string value is ASCII" → 6 non-ASCII values of 99 328.
* "`文字列` is a dev placeholder" → they are Shift-JIS **type words**.
* "the splash `_eff` glows hold a constant α ≈ 33, contradicting their declared
255 plateau" → **mine, and refuted within the iteration.** They ramp 34 → 255
in exact steps of 34. I had printed the series' minimum and read it as its
range. [`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)
* "the declared keyframe timeline reproduces the captured splash" → **refuted for
multi-keyframe elements.** `palogo_gamearts` is still at `a=255` nine frames
after its declared `a=32`, and its declared 80-frame fade-in is never drawn.
The `_eff` glows do reproduce, exactly — so this is about the group timeline,
not about the interpolation law. [`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)
* "the `_eff` elements' agreement is the whole case for the keyframe-time shift,
so it stays a shape argument" → superseded. The **hold duration** is
calibration-free and decides it: observed 83 frames of full alpha against a
predicted **2.0** as decoded and **80.0** shifted. The shift is nonetheless
**not adopted** — it moves `GP_TITLE` build 7 by 13 % of pixels, away from its
verified English twin's brightness. [`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)
* "the `GP_TITLE` build 7 render difference is evidence against the keyframe-time
shift" → **mine, and withdrawn.** It is one element, `ptlogo_eff3.t32`, a
transient bloom with no resting pose; `rest()`'s dwell fallback returns a
different endpoint of the same movement under each reading. The brightness
comparison measured our heuristic, not the decode.
[`structures/ui-resting-pose.md`](structures/ui-resting-pose.md)
* "`rest()`'s longest-dwell fallback picks the pose the element rests at" →
**refuted structurally.** A dwell gap is time spent interpolating *between*
poses; an endpoint is only held when the two poses are equal, which is a
plateau, which the earlier path already returned for. Every element that
reaches the fallback has a guessed rest pose.
* "`rest()` for a plateau-less element should be the **last keyframe**" → **mine,
and refuted.** The developer splash's three sibling glows are structurally
identical and differ by one byte (`a=212` vs `a=255` at `t=45`); that rule
makes `palogo_anima_eff` alone invisible while `gamearts_eff` and `seta_eff`
stay lit. Capture box-mean ratios (0.717 / 0.723 / **0.772**) go the other way
too. [`structures/ui-resting-pose.md`](structures/ui-resting-pose.md)
* "a keyframe `scale` of 0 means *unset*, so render at 100 %" → **refuted by a
disc-wide control.** 2 166 elements have a zero-scale keyframe and **not one is
zero on every keyframe**, while 1 762 grow back out of zero (`ptlogo_eff3.t32`
runs 0 % → 200 %). Zero means collapsed; the renderer now draws nothing.
[`structures/ui-rat-layout.md`](structures/ui-rat-layout.md)
* "a Japanese-locale capture is impossible in this container, because canary has
no `user_language` cvar" → **mine, and refuted the next iteration.** The cvar
really is absent, but the language is persisted in
`<storage_root>/xconfig.settings` (`user.language`, BE u32 at file offset
`0x912`, located from three struct landmarks) and that file is writable. The
capture is still not *taken* — a Japanese run never reached the title in 787 s
— but it needs a longer run, not a rebuilt emulator.
[`tools/re-capture/set_console_language.py`](../../tools/re-capture/set_console_language.py)
* "the Japanese-locale run never reached the title in 787 s" → **the measurement
was broken, not the run.** `wait_title.sh` carried the superseded single-pixel
oracle. Re-run with `is_title.py`: the game still did not present the
interactive title, but that is now a measured statement (zero green-glyph
pixels, correlation ≤ 0.22 to either build-7 render) rather than an artefact.
* "the Japanese-locale run fails to reach the interactive title *because of the
locale*" → **refuted by the English control.** 75 samples over 734 s with the
same flags and oracle, every one glyph = 0. Neither locale presents the
interactive title without a pad press.
* "neither locale reaches the interactive title without a pad press" /
"the game sat in the attract loop for 604 s" → **withdrawn as causes.** Both
rest on runs whose polling loop sampled every ~41 s, because `screenshot`
costs 10.8 s while the emulator runs (0.117 s idle, 92×). A title lasting a few
seconds would be missed. The observations stand; the conclusions drawn from
them do not. [`capture-harness-status.md`](capture-harness-status.md)
* "the boot harness fails because its polling loop samples every ~41 s, slower
than the title screen lasts" → **mine, and refuted by my own fix.** The
sampling defect was real (3.98 s → 0.29 s per sample, 13.7×, control-verified
at 753/327), but a probe running at 3.99 fps for **420 continuous seconds —
1 674 samples — still saw zero green-Ⓐ pixels.** Sampling rate was not the
cause. [`capture-harness-status.md`](capture-harness-status.md)
* ~~"neither locale reaches the interactive title without a pad press"~~ →
withdrawn last iteration for want of evidence, now **reinstated as a
measurement**: 1 674 dense samples over 420 s, English, zero glyph frames.
⚠️ Reach: a mid-run window only; it says nothing about the boot title.
* "the PRESS Ⓐ plate appears only in the **boot** title window, which mid-run
sampling could never catch" → **mine, and refuted.** The fast probe was
attached at t=0: **2 391 frames over 600 s at 3.98 fps from launch**, max glyph
0. The plate did not appear at any point in the first ten minutes.
[`capture-harness-status.md`](capture-harness-status.md)
* "2 391 frames over 600 s from t=0, max glyph 0, therefore the title never
appears in the first ten minutes" → **withdrawn: the instrument stalls.** A
single long-lived x11grab stream degrades 3.98 → 1.60 fps and then freezes,
repeating one stale frame; cross-checked, it read surface mean 5.21 where
`import` read 125.65 at the same moment. A dense negative from a frozen stream
is not a negative. [`capture-harness-status.md`](capture-harness-status.md)
* "the `T8aD` layer key fully determines a screen's paint order" → **refuted, and
the remainder is undecodable.** Elements sharing a key are tied; on the title
the game paints the five tied `ptlogo_back2eff` glows `1,2,5,3,4` while the
declaration table, the RATC child order and **every** field in the `T8aD`
header (exhaustive 0x000x7f, u8/u16/u32, both directions — 0 matches against
64 for the declaration-order control) all give `1,2,3,4,5`.
[`ui-paint-order-derived-check.md`](structures/ui-paint-order-derived-check.md)
* "SE audio is undecodable from the disc — no XACT container exists anywhere"
(as it stood on the **handoff page**) → **stale**: `menu-audio-cues.md` had
already retracted it and located three cues in `Static.slb` that decode to PCM.
The retraction never reached the row the port agent reads. Handoff row fixed;
`tools/re-capture/handoff_lint.py` now checks for this class.
* "which of `8AX` and `ptbase` the game draws needs a per-draw capture recording
texture base addresses" → **mine, and refuted — it is settled statically.** The
two carry the same art at two resolutions, so neither compares usefully against
a capture; their *difference* does. Correlating the capture's
departure-from-upscale against the 8AX-only detail gives +0.0475 (main menu)
and +0.0634 (title), both 68 % of ceiling against matched controls of ≤0.0095.
The game draws the full-res `8AX`.
[`ui-8ax-fullres-background.md`](structures/ui-8ax-fullres-background.md)
* "the pixel-pair ratio shows the capture is native, not an upscale" → **mine,
and withdrawn as evidence.** Upscales give 0.000.72, native 0.98, capture 1.01
— but additive noise pushes any such ratio toward 1, and both "native + noise"
and "bilinear upscale + noise" fit the observed values. The conclusion happens
to be right; this test does not establish it.
* "the render-vs-capture gamma may be canary's own BT.709 output transform, since
`kernel_display_gamma_type = 2`" → **mine, and refuted from the source.** That
cvar is the value a `kStub` getter (`VdGetCurrentDisplayGamma`) hands the
**guest**; the game builds its own ramp from it and canary applies the guest's
`DC_LUT` ramp in the swap path. No emulator-side gamma post-process exists to
subtract. 🟡 Whether this game installs a ramp at all is still unestablished.
[`ui-render-tone-curve.md`](structures/ui-render-tone-curve.md)
* "the GPU trace produced nothing because either the CLI flag did not reach the
cvar or `BeginTracing()` failed silently" → **both wrong.** The trace writer is
**compiled out**: `trace_writer.h` gates it on `#ifdef NDEBUG`, so a release
build has no writer at all. Confirmed with a control — the format string
`_stream.xtr` appears **once** in the Debug binary and **zero** times in the
Release binary `run-canary` actually uses.
[`capture-harness-status.md`](capture-harness-status.md)
* "the `T8aD` `+0x04` bit `0x02` means the sprite's name contains `eff`" →
**refuted, now on evidence.** `ptlogo_back2eff` is an `eff` name with the bit
clear; the attribution is confirmed by header-order pairing (18/18 on build 4)
rather than by a size match, which cannot separate it from the same-sized
`ptlogo_back2eff5`. All 10 bit-set sprites *are* `eff` names, so the
implication runs one way only.
* "the bit `0x02` marks a transient element" → **refuted.** `pteff03` and
`pteff03a` carry the bit and run to `t=250`, ramping to `a=255` and holding.
[`ui-paint-order-key.md`](structures/ui-paint-order-key.md)
* "bit `0x02` set ⇒ the sprite's name contains `eff`" (the one-way reading that
survived the biconditional's refutation) → **mine, and refuted disc-wide the
next iteration.** True 10/10 on `GP_TITLE` build 4; over 14 709 sprites it
fails on **2 657 of 4 995** bit-set ones. `P(eff|set) = 0.468` against
`P(eff|clear) = 0.144` — an association, not an implication.
[`ui-paint-order-key.md`](structures/ui-paint-order-key.md)
* "`T8aD +0x04` bit `0x02` selects premultiplied alpha" → **refuted.**
Premultiplied requires `RGB ≤ A` everywhere; over 170 decoded textures the
flagged group violates it on a median **52.5 %** of pixels against **30.2 %**
unflagged — both far from premultiplied, and the flagged group *further*.
[`ui-paint-order-key.md`](structures/ui-paint-order-key.md)
* "`build-reborn test` cannot terminate" → **mine, and too strong; corrected the
next iteration.** It is heavy, not hung: 19 of 166 `.xpr` containers exceed
25 s, `Stage_S02` completes in **144 s** with `rc = 0`, and one full pass is
~4560 minutes. The 3 h 26 m observed was that work at a load average of 914,
inflated by my own two duplicate runs.
[`test-suite-runtime.md`](test-suite-runtime.md)
* "the case for the keyframe-time shift rests on a single element" → **no longer
true.** Three elements across two screens discriminate and all favour it:
`palogo_gamearts` and `palogo_seta` hold full alpha 83 frames, `palogo_sqex`
≥77, against 68 predicted by the current reading and 80102 by the shifted
one. The `_eff` glows fit both and argue against neither.
[`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)
* "an element with no held pose should be drawn as NOTHING rather than at a
guessed endpoint" → **mine, and refuted.** Suppressing every plateau-less
element and re-correlating against the live captures: title +0.9500 → +0.6839,
main menu +0.9460 → +0.9037, `EXTRAS` +0.9440 → +0.9094. Worse on all three.
* "`rest()` guesses for 24.57 % of elements (3 807 of 15 493)" → **mine, and
overstated by 65 %.** The plateau test marks a **single-keyframe** element as
plateau-less because it has no adjacent pair — but its one pose is
unambiguously its rest. 1 502 of the 3 807 are those; the genuinely ambiguous
population is **2 305 (14.88 %)**.
[`ui-resting-pose.md`](structures/ui-resting-pose.md)
* "`rest()` for a plateau-less element should be the last keyframe → refuted by
the sibling argument" → **that refutation is itself refuted, this time by
measurement.** Rendering under the rule and correlating against the live
captures: publisher splash +0.9600 → **+0.9982**, developer splash +0.9643 →
**+0.9758**. Making `palogo_anima_eff` invisible *improves* the match; the
sibling symmetry was my expectation, not evidence.
* "the port's exposure to the rest-guessing defect is 14 elements" → **two.** The
fallback needs an element to be plateau-less **and** multi-keyframe; title,
main menu and `EXTRAS` reach it **zero** times, the two splashes once each.
[`ui-resting-pose.md`](structures/ui-resting-pose.md)
* "the shifted time reading implies rest = the last keyframe, so the plateau rule
can be dropped" → **mine, and refuted by measurement.** Applying it to every
element collapses all five screens (title 0.9500→0.6819, main menu
0.9460→0.6416, `EXTRAS` 0.9440→0.5745) and renders both splashes **blank**. A
group is entry → hold → exit and the exit is the screen's *dismissal*: a
displayed screen sits at the hold, not at its final pose.
[`ui-resting-pose.md`](structures/ui-resting-pose.md)
* "`rest_plateau` renders elements the game has already finished with" (as a
general claim) → **narrowed by its control.** It holds on **transient** screens
only: suppressing the finished glows takes the two splashes from 0.9604/0.9659
to **0.9982/0.9980**, while the same edit costs the title 0.002, the main menu
**0.092** and `EXTRAS` **0.107**. A plateau mid-animation is evidence the
element is held at that point in the timeline, not that it is on screen once the
screen has settled — and where a screen does settle, the rule is right.
[`ui-resting-pose.md`](structures/ui-resting-pose.md)
* "the group header's undecoded lead-in word carries a per-element start offset"
**refuted immediately.** It is `0x00000000` for all seven elements of the
developer splash — glows and logos alike — while those two families are
observed to run sequentially (frames 94115 and 116211) despite declaring
overlapping times. [`ui-group-start-time.md`](structures/ui-group-start-time.md)
* "the splash elements share one clock origin" → **refuted.** Fitting a single
origin needs f₀ ≈ 93.5 for `palogo_gamearts_eff` and f₀ ≈ 103 for
`palogo_gamearts`, ~19 units apart, and aligning one throws the other off by
~9 frames at both ends. Durations match (97.8 %, 98.5 %); starts do not.
* "the glows and logos might overlap and my size-grouping merged them" → **tested
and refuted.** Across all 235 captured frames, **zero** contain both a glow and
a logo; f110115 draw two glows and f116 onward two logos, with no transition
frame. The sequencing is real.
* "a bundle's declared elements are what the screen shows" → **refuted.** Entry 11
declares three logo/glow pairs and only two are ever drawn — `palogo_anima`
gets 0 frames against `palogo_gamearts`'s 95, from byte-identical keyframe
times. (Reach: within the capture's frames 1214.)
[`ui-group-start-time.md`](structures/ui-group-start-time.md)
* "the glow and logo phases are one bundle with elements selectively activated"
**mine, and withdrawn as unestablished.** The alternative — two compositions
shown in sequence — fits equally. The texture-base test fails its control: the
publisher splash is a different bundle and shares the base `0x11C30000`, so
that address is a reused upload slot, not a bundle identity. What survives is
that declared elements ≠ drawn elements.
[`ui-group-start-time.md`](structures/ui-group-start-time.md)
* "two compositions shown in sequence" (as the alternative to selective
activation) → **refuted statically.** It requires a bundle declaring the glows
without the logos; no such bundle exists. Only four `GP_TITLE` entries carry
`palogo` elements, and both developer entries declare **all six** logos and
glows — so whichever was active, a subset of its elements was drawn at a time.
Selective activation is reinstated on evidence.
[`ui-group-start-time.md`](structures/ui-group-start-time.md)
* ~~"the splash's `measured_paint_order` records a front-to-back depth order" →
mis-typed; between its glow and logo halves it records only the temporal order
they were seen in."~~ → **that refutation is itself refuted (same day).** The
vector is a read of the runtime **child array** (`ui-screen-runtime.md`:
"paint order (child slots)"), not of the draw capture, so co-occurrence does
not bear on it; and the halves carry *distinct* T8aD layer keys
(`0xa100` < `0xa110`, `paint_order_audit`: 0 same-key ties), so the file orders
them regardless. The no-overlap measurement was correct; the inference from it
was not. What survives: a capture of this screen can only cross-check the order
*within* each half. [`ui-prm-primitives.md`](structures/ui-prm-primitives.md)
* "`8AX` is the name a `T8aD` is registered under" → **it is not a name at all.**
It is three bytes of the preceding record's payload (`38 41 58`) that happen to
be printable ASCII, which our backwards printable-run scan preferred over the
name the format actually states in its `opt ` block. The claim sat in
`HANDOFF.md` and `ui-8ax-fullres-background.md` as though `8AX` were a real
identifier, and cost every menu screen its full-resolution background.
[`ratc-child-names.md`](structures/ratc-child-names.md)
* "`pmbase.t32` is on the disc nowhere" (the one dangling asset behind
`10 144 of 10 148 references resolve`) → **withdrawn; it is on the disc.** It is
the `GP_STAGE_CLEAR` child the same scan named `8AX`. With the name decoded the
count is **10 148 of 10 148**. [`ratc-child-names.md`](structures/ratc-child-names.md)
## UI timing (2026-08-29)
* "a screen has SETTLED at its `rest.t`" → **refuted.** `rest.t` is the last
*hold* keyframe before the exit, not the end of motion. Build 4's `ptlogo1`
rests at `t=251` and stops moving at **`t=42`**; the title's visible build-in
ends at `t≈118`, where `pteff01`, `pteff02.prm` and `ptlogoall_eff` end their
ramps together. Believing `rest.t` put a port's plate 3.97 s late —
[`title-plate-delay-measured.md`](title-plate-delay-measured.md).
* "the `PRESS Ⓐ` plate is composited a measured 2.13 s after the title settles,
and the port should author that" → **the measurement stands, the instruction
was refuted by the port.** Build 2 has a keyframe group of its own; both builds
run on **one clock started together** and the plate's declared `t=238` supplies
the timing, so nothing is authored. `238 118 = 120 units = 2.000 s`, of which
2.13 s was a wall-clock reading stretched by Canary presenting at ~28.1 fps.
⚠️ General lesson: **a wall-clock duration off this emulator is ~6 % long**, so
a measured interval that lands near a round number of units probably *is* that
number of units.
* "a music bank has three sub-waves" → **refuted; it was our reader.** The third
is the bank header, emitted because `to_xma_riffs` derived a leading packet
stream's start as `first_riff % 2048` — valid only for a header shorter than
one packet. 28/28 disc-wide —
[`structures/slb-bank-header-not-a-wave.md`](structures/slb-bank-header-not-a-wave.md).
## The oracle harness and the container (2026-08-29)
* "the decoder container has no disc" → **refuted the same day.** The container
was replaced and `/disc` is a real 6.2 GB read-only mount. Worse, both
instruments behind the claim were blind to the answer either way:
`find / -xdev` **cannot cross** into a bind mount on another device, and
`sylph-doctor` only checks `/work` and never `$SYLPHEED_DISC`. "sylph-doctor
agrees" was two instruments sharing one blind spot.
→ To test for the disc, ask the variable that names it:
`sylpheed-cli screen list "$SYLPHEED_DISC/dat/GP_TITLE.pak"`.
* "the main menu returns to the title on its own after ~810 s idle" → **refuted.**
The menu sat untouched for **≥ 60 s** without moving (correlation never leaving
0.92450.9249). The ~810 s idle is real but belongs to the **title**. This was
the only reason "Ⓑ leaves the main menu" was classed as authored.
* "whole-image statistics (green / white / mean) can tell the title from the
attract movie" → **refuted.** A frame of `ADV.wmv` with a bright green laser
reads green 0.0018 / white 0.086 / mean (53,67,76) — the title's numbers. A
probe built on it tapped Ⓐ into the movie and waited 120 s for a menu that was
never coming. → Correlate against a committed capture instead, and keep movie
frames as the negative controls.
* "a 360-bin angular cross-correlation can measure the focus ring's rotation
angle" → **refuted by its own control**: a synthetic **30°** rotation of a live
frame came back as **0°** (peak 0.596), while 90/180/270° came back exactly
(peak 1.000) — it only resolves exact pixel permutations. No angle was quoted;
the spin was established from brightness conservation instead.
* "a latency read off a classified `x11grab` stream is a duration" → **refuted.**
At 1503 ms per classification against an 8 fps stream the consumer ran at
0.64 fps, so frames were stale and increasingly so. Four "durations" died with
it. The tell was that a screen transition, a button press and a plate fade all
came out at ~2025 s. → A backlog **preserves ordering and destroys
durations**; check consumed-fps against requested-fps before quoting a time.
## UI timing and transitions (2026-08-30)
Seven claims died this session. Each was recorded in its own page at the time,
and **none of them reached this file** — which is the one the brief says to grep
before proposing anything. A refutation that lives only where it was made is not
reachable by the person about to repeat it.
* "the fade-OUT duration is not in the file — the port must author it" → **mine,
and wrong in every sentence.** The [record-layout
fix](ui-keyframe-record-layout.md) times a group's final pose, so block 4
carries `t = 80` / `74` / `269`: the ramp is **decoded** at 10 / 10 / 8 units.
The section asserting this stood 78 lines above its own correction, in a
heading, telling the port to author a decoded value.
[`screen-transitions.md`](screen-transitions.md)
* "the ~14 units the fade-out does not account for are a black HOLD" → **mine,
arithmetic that fit.** Measured: the content elements' own fade-outs, starting
six frames before the quad's ramp. [`screen-transitions.md`](screen-transitions.md)
* "the black interval between screens is a LOAD" → **mine, refuted three ways.**
Bundle size runs backwards (the 12.3 MB screen gaps 0, the 7.0 MB one gaps 3);
the gap is 3 frames in three independent runs; and press-to-change latency moved
~12 frames between those runs while the gap did not move at all.
[`screen-transitions.md`](screen-transitions.md)
* "Ⓑ has no black interval" → **mine, one screen pair generalised.** `EXTRAS → menu`
via Ⓑ gives **two completely empty frames**. [`screen-transitions.md`](screen-transitions.md)
* "`ptloop01`/`ptloop02` do not free-run on the settled title" → **mine, measured
over the wrong rectangle.** The parent's `(441,270)` 200×90 is a **pivot anchor**;
the leaf sweeps a 400 px quad whose left edge travels 639…1521. The zero was
measured in a dead zone. [`structures/ui-resting-pose.md`](structures/ui-resting-pose.md)
* "the game runs the splash dwells ~8.5 % long" → **mine, and it was one element's
visible span read as the screen's.** The `_eff` glow is lit from t≈0 while the
logo is still transparent, so the screen's visible span is the full group. Six
ratios recomputed to a mean of 1.0146 with one below unity.
[`boot-order-and-splash-dwell.md`](boot-order-and-splash-dwell.md)
* "`EXTRAS` can supply only one transition measurement — a **structural** limit"
**mine, and refuted by one `screen info`.** Build 6 declares three buttons
(`ptbtn11/12/13`, kind `0x3002`). ⚠️ `sylpheed-port` had copied this sentence out
of a message into their own record as an established fact **while holding the
file that refuted it**. [`data/fade-four-transitions.txt`](data/fade-four-transitions.txt)
* "the black gap is determined by the OUTGOING screen" → **mine, superseded
twice.** The same origin gives 0 and 1 to different destinations; every repeated
*pair* is identical across five replicates. The pair determines; the origin only
constrains. [`data/fade-four-transitions.txt`](data/fade-four-transitions.txt)
### The JP title might not draw the sweep leaves at rest — ❌ REFUTED (2026-08-30, mine)
* ~~"the JP title does not draw the sweep leaves at rest"~~ — refuted, see below.
* ~~"build 7's denser logo stack occludes the sweep leaves"~~ — refuted, see below.
I hypothesised that build 7's denser logo stack (katakana + crystalline burst)
**occludes** the two sweep leaves, to explain why two JP title captures differ by
RMSE 0.32 inside the adjudication box while two EN captures a plateau-phase apart
differ by 11.9. A draw capture in `ja` (control: the same extraction on the EN
title log) shows the **same three tall ROT strips, same dimensions, at HIGHER
alpha than English** — 180/188/194 vs 160/168/166. There is no absence to
explain. [data](data/title-sweep-jp-draw-capture.txt)
The 0.32 had a different cause: **my own gate**. See below.
### "Two sessions sample a free-running clock" — ❌ REFUTED (2026-08-30, mine)
* ~~"a free-running clock lands somewhere else on a fresh boot"~~ — refuted, the gate phase-locks it.
* ~~"the in-box capture noise of 0.32 between sessions"~~ — refuted as a noise floor; it measures the trigger.
`jp-title-at-rest.txt` justified a second capture as probing the between-run axis
"where a free-running clock lands somewhere else on a fresh boot", and reported
its in-box **0.32 as capture noise**. Measured at the shutter instant, the sweep
strips sit **2526 px apart across two runs in different locales and different
sessions** — 1.6 % of a ~1600 px traverse. The plate pulse *is* part of the
animation, so gating on it phase-locks the shutter. **0.32 is a lower bound
produced by the instrument, not a property of the game**; the honest figure at an
arbitrary phase is 11.9. The era adjudication is unaffected — its margin, 16.72,
clears even 11.9. [details](structures/plate-pulse-phase-lock.md)
### Refutation attempt on `sylpheed-port` — ✅ THE CLAIM SURVIVED (2026-08-30)
**Target:** the port's rejection of a positional mechanism, resting on 98 % of
off-edge area matching exactly with a residual of ±12 levels *inside lit logos*.
**My attempt:** if the sweep leaves' ink crosses the logos, that residual could
be sweep ink our renderer omits — and phase-locking would have made it look
stable across sessions rather than exposing it.
**Result: refuted, the claim stands.** `jp-title-at-rest.txt` has five frames
~1.5 s apart *within* a run — not gated individually, so genuinely different
sweep phases — and the 350×396 logo ROI is **byte-identical across all of them
(0 / 138 600 px differing, max |d| 0), reproduced in two independent sessions**,
while 58 % of the whole frame moves as a contrast control. The sweep ink does
not land on the logos. The ±12 residual is not sweep.