Files
Sylpheed/docs/re/REFUTED.md
sylph-decoder 1bf619460a re: menu focus does not survive a reboot -- six fresh boots, three following a session that ended elsewhere
No new boot was spent: six runs had already captured the first menu entry of a
fresh boot, and all six read NEW GAME. Three of them follow a session that ended
with the cursor on EXTRAS or OPTIONS, which is what makes it a test of persistence
rather than a repeated observation.

Reach stated rather than implied: every session ends with the emulator KILLED, so a
game that writes menu state on a clean shutdown would never get the chance. This
measures 'does not survive a killed session'.

Refutation attempt on the port's extras/initial_focus: ptbtn11 -- it SURVIVES.
ptbtn11 is the top button on the EXTRAS build, with the main menu as a control
where ptbtn01 is top and is known to be NEW GAME.

Incidentally corrects ring_row.py's stated calibration. It cited capture_y = 49.5 +
1.060*design_y, fitted against menu_focus.py's row centres, which are NOT the
disc's button rows -- the disc says 162/242/322/401/482, spacing 80, and
menu_focus.py drifts up to 17 px against them. Re-fitted: 64.82 + 0.9919*design_y,
residuals under 0.7 px. No item assignment changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-31 01:51:03 +00:00

53 KiB
Raw Blame History

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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "a .rat leaf record's keyframes use the build's 40-byte layout" → they do notwithdrawn. They do. The scan that "found nothing" required 29 increasing times; the records hold three. Decoded in 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
  • "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 Ⓐ" → refutedthe 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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "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
  • "the boot intro and the attract movie are different videos" → one asset, one manifest slot (ADVERTISE_MOVIE).
  • "the new-game intro is unidentified" → MS00AS00A.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
  • "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
  • "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.
  • "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.
  • "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

  • "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

  • "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

  • "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

  • "BGM_106BGM_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_001BGM_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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

  • "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

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.
  • "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.

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 (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 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
  • "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
  • "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
  • "Ⓑ has no black interval" → mine, one screen pair generalised. EXTRAS → menu via Ⓑ gives two completely empty frames. 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
  • "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
  • "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
  • "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

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

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

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.

Music-bank stems (2026-08-30)

  • "wave 1 is wave 0 put through a filter" refuted on BGM_103 by magnitude-squared coherence. A real linear filter of wave 0 reads 0.930.94 in every band (positive control); the measurement reads 0.027 at 14 kHz. No linear filter does that in a band where both waves carry energy. data
  • "the rear-pair reading can be tested by coherence" refuted, and it was my own test's premise. The control that matters — L vs R within one wave, genuinely one performance in two channels — reads only 0.2210.497, so in this material "same performance" does not imply high coherence. A 4-channel mix's rear pair is not a linear filter of its front pair, so the discriminator never had the power to separate the two readings. The 🟡 stands.

Refutation attempt on the corpus's "two stems of ONE PERFORMANCE" — 🟡 SURVIVED, WEAKENED (2026-08-30)

Target: structures/bgm-two-stems.md (the BGM_103 section is another agent's), which reads the two waves as two stems of one performance.

My attempt: if they are one performance, they should share signal structure; coherence should be well above the independent floor across the bands carrying the music.

Result: the claim survives, but one of its supporting readings is dead and the bands carrying 96 % of the energy read 0.169 and 0.184 — far above the 0.001 independent floor, so not independent, and far below a filtered copy. "One performance" stands; "rear pair, i.e. a filtered view of the same mix" does not.

Refutation attempt on sylpheed-port's band-energy check — SURVIVES, with a measured caveat (2026-08-31)

Target: their replacement for a disqualified difference-signal path — "band energies need no alignment", with transcodes matching their sources to 0.66 dB worst-case and an unrelated movie landing at 1920 dB.

My attempt: if band energies are genuinely alignment-free, a signal against a misaligned copy of itself must match as closely as against itself.

worst band
w0 vs itself 0.00 dB
vs itself shifted 1 s (misaligned, same content) 0.16 dB
vs itself shifted 10 s 1.00 dB
vs a different bank (BGM_104) 5.28 dB

The claim survives. A 1 s misalignment costs 0.16 dB, well inside their 0.66 dB pass band — alignment-insensitive as advertised, which is exactly what makes it the right instrument where a lag search failed.

⚠️ Two caveats it is worth them having. It is not literally alignment-free: at 10 s the figure reaches 1.00 dB, because a fixed analysis window covers different material once the shift is large relative to it. And the separation margin is material-dependent — two unrelated music banks separate by only 5.28 dB here, against the 1920 dB an unrelated movie gave them. A 0.66 dB threshold has an 8× margin against that floor rather than a 30× one, so the safety of the threshold depends on how different the chosen known-negative is, not on the method. data

Refutation attempt on sylpheed-port's extras/initial_focus: ptbtn11 SURVIVES (2026-08-31)

Target: their statement that EXTRAS keeps ptbtn11 and is "correct under the surviving reading" — i.e. that a submenu resets to the item it opens on, and that ptbtn11 is that item.

My attempt: the oracle shows EXTRAS opening on MISSION SELECT, the first of three. So their value is right only if ptbtn11 is the top button on that screen. Checked against the disc, with the main menu as a control (examples/extras_button_order.rs):

buttons top to bottom
control — main menu (entry 5) ptbtn01 y162, ptbtn02 y242, ptbtn03 y322, ptbtn04 y401, ptbtn05 y482 → top is ptbtn01 = NEW GAME
EXTRAS (entry 6) ptbtn11 y282, ptbtn12 y362, ptbtn13 y442 → top is ptbtn11

The claim survives, and the control confirms the ordering rule reproduces a screen whose answer is independently known.