From 0ea2b8e00d86745bb81fb0bb81cc36a18ec6e342 Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Sun, 30 Aug 2026 23:44:01 +0000 Subject: [PATCH] re: first audit of INDEX against the pages it links -- 3 of 8 rows were stale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit INDEX is read every iteration and is the first thing a new reader meets, and I had admitted three times to never auditing it. Found by accident: I was about to spend a boot measuring whether A skips a movie because INDEX said 🟡, when movie-binding.md had it settled since 2026-08-28 with a three-boot baseline and a delivery counter, and HANDOFF carried it correctly. The staleness was in the index alone. Three stale rows fixed: movie skippability, SE audio extractability, and B leaving the main menu. Five other hits read and left alone -- index and page were talking about different clauses. One of the three should have been caught by check_refuted.py: REFUTED holds the same dead claim with a different second clause, and the register matches exact wording. Its docstring documents that weakness; this is the first live instance. Also flags a within-page contradiction not fixed here: menu-audio-cues.md line 81 still heads a section saying SE audio is not extractable, which its own line 189 refutes. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v --- docs/re/INDEX.md | 6 +-- docs/re/data/index-vs-pages-audit.txt | 58 ++++++++++++++++++++++++++ tools/re-capture/index_vs_pages.py | 60 +++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 docs/re/data/index-vs-pages-audit.txt create mode 100644 tools/re-capture/index_vs_pages.py diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index bebc3f8e..afd98968 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -153,11 +153,11 @@ files, which is how the same ground got covered twice. | [`title-crash-stl-tree.md`](title-crash-stl-tree.md) | The title-screen crash is an STL `map`/`set` erase on a bad iterator | ✅ CONFIRMED — the guest throws std::out_of_range from an STL | | [`ui-paint-order-third-permutation.md`](ui-paint-order-third-permutation.md) | A third measured paint order — tool built and validated, screen not reached | ✅ the reader works and is CONFIRMED against both previously | | [`ui-quad-class-foothold.md`](ui-quad-class-foothold.md) | The guest's UI quad class — a foothold found from the capture's vertex layout | 🟡 PROBABLE for the identification below (it is a static read, but | -| [`menu-navigation-semantics.md`](menu-navigation-semantics.md) | The title menu — how it moves, and where each button goes | ✅ measured: wraps both ends, Ⓑ restores focus, ⬅➡ inert; all 5 destinations driven. 🟡 GamePart id is a name match. 🟡 **Ⓑ leaving the MAIN menu downgraded 2026-08-29** — uncited, and the main menu is the only screen whose footer omits Ⓑ (0 glyph px in frame vs 514/518 elsewhere). ✅ **MISSION SELECT's stuck cursor was a LOCKED stage list** — labels have three brightnesses, locked 104 / unfocused 183 / focused 254 | +| [`menu-navigation-semantics.md`](menu-navigation-semantics.md) | The title menu — how it moves, and where each button goes | ✅ measured: wraps both ends, Ⓑ restores focus, ⬅➡ inert; all 5 destinations driven. 🟡 GamePart id is a name match. ✅ **Ⓑ leaving the MAIN menu re-measured 2026-08-30** — goes to the title, delivery-confirmed, ≤ 0.4 s, no loading screen, and the plate is re-drawn ~7 s later; ~~downgraded 2026-08-29 as uncited~~, and the main menu is the only screen whose footer omits Ⓑ (0 glyph px in frame vs 514/518 elsewhere). ✅ **MISSION SELECT's stuck cursor was a LOCKED stage list** — labels have three brightnesses, locked 104 / unfocused 183 / focused 254 | | [`screen-transitions.md`](screen-transitions.md) | Between two screens — a fade through black, and where its timing lives | ✅ the fade quad's keyframe group is decoded (disc-wide: per-pak all-or-nothing; `GP_TITLE` = the 6 screens, not the 6 overlays); the ~0.4 s fade-OUT is measured, not on the disc | -| [`menu-audio-cues.md`](menu-audio-cues.md) | Menu audio — the event vocabulary is on the disc, the binding is not | ✅ `SE_UI_*` cue names/ids decoded and `BANK_SE`→`Static.slb` (0/322 in FILES); 🟡 event binding is a name match; ❔ `Static.slb` has no wave boundaries, so SE audio is not extractable | +| [`menu-audio-cues.md`](menu-audio-cues.md) | Menu audio — the event vocabulary is on the disc, the binding is not | ✅ `SE_UI_*` cue names/ids decoded and `BANK_SE`→`Static.slb` (0/322 in FILES); 🟡 event binding is a name match; ✅ **SE audio IS extractable** — the waves are located in `Static.slb` by playing them (move `0x1ec0`, confirm `0x5d6c0`, back `0x0ec0`); ~~❔ `Static.slb` has no wave boundaries, so SE audio is not extractable~~ is **refuted** and was still asserted here | | [`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md) | What the game reads at boot — `config.ini`, and which GameParts exist | ✅ `config.ini` selects the language (the disc's only config); ❔ its `[SYSTEM]` is empty so the boot order is not in config; 🟡 24/29 ids bind to a class, `GP_ADVERTISE_DEMO` is never registered | -| [`movie-binding.md`](movie-binding.md) | Which movie plays where — boot intro, attract loop, new-game intro | ✅ decoded from the movie manifest (`ADVERTISE_MOVIE`→`ADV.wmv`, `MS00A`→`S00A.wmv`); attract identity confirmed independently by frame matching; 🟡 skippability unsettled | +| [`movie-binding.md`](movie-binding.md) | Which movie plays where — boot intro, attract loop, new-game intro | ✅ decoded from the movie manifest (`ADVERTISE_MOVIE`→`ADV.wmv`, `MS00A`→`S00A.wmv`); attract identity confirmed independently by frame matching; ✅ **skippability settled 2026-08-28: one Ⓐ skips a movie** — title at 57 s against a 193/196/193 s three-boot baseline, the press proved singular by Canary's own delivery counter (3→4), and the skipped-to title fully functional. ~~🟡 skippability unsettled~~ was stale here while the page and `HANDOFF.md` both had it answered | | [`ready-room-probe.md`](ready-room-probe.md) | S1 — the Ready Room probe: no-go, and not for the reason expected | ✅ it is 2D and enumerates (60 builds), but the pak is briefing/tactical-map content; and `kind == 0x3002` finds 0 buttons there | | [`ui-title-build-map.md`](ui-title-build-map.md) | Which `GP_TITLE` build is which screen state | ✅ CONFIRMED for title / `PRESS Ⓐ` / main menu / `EXTRAS` against live captures; the archive is 8 screens × EN/JP, and "6/8/9 are submenus" is withdrawn ✅ **2026-08-29: the two "unidentified `DELTASABER` plates" are the LOADING screen** — builds 0/1 the plain variant, 10/11 the dressed one, decoded from their `pgloading_*` element names, and the executable (`sub_821C4EB0`, bytes checked in the image) names exactly five title-side screens: `TITLE_SCREEN`, `BUTTON`, `TITLE_MENU`, `LOADING`, `LOADING2`. 🟡 which loading bundle takes which of the two names is undecided. 🟡 the English member of a pair is the one in the first half of `GP_TITLE.p00` — 8/8 structurally, 3/3 where a capture can check it. | | [`ui-title-paint-order-capture.md`](ui-title-paint-order-capture.md) | The title screen's paint order, measured from the guest's draw submissions | ✅ CONFIRMED — the order in which the running game paints the title | diff --git a/docs/re/data/index-vs-pages-audit.txt b/docs/re/data/index-vs-pages-audit.txt new file mode 100644 index 00000000..1cbe5d94 --- /dev/null +++ b/docs/re/data/index-vs-pages-audit.txt @@ -0,0 +1,58 @@ +# Does INDEX.md agree with the pages it links? -- 2026-08-30. FIRST AUDIT. +# +# INDEX.md is read every iteration by both agents and is the first thing a new +# reader meets. sylpheed-port's phrase is the right one: an index is an +# AMPLIFIER -- a status wrong there is wrong everywhere it is quoted from. It is +# also a file I have admitted three times I had never audited. +# +# FOUND BY ACCIDENT, which is why the audit happened: I was about to spend a boot +# measuring whether Ⓐ skips a movie, because the port's BLOCKED.md lists it 🟡 and +# so did INDEX. `movie-binding.md` has had it ✅ SETTLED since 2026-08-28 -- with a +# three-boot baseline and a delivery counter -- and HANDOFF carries it correctly. +# The staleness was in the index alone, and it nearly cost a run. +# +# TOOL: tools/re-capture/index_vs_pages.py. It prints a LISTING, NOT A VERDICT: +# 8 rows where the index is 🟡/❔ while the linked page has a "✅ settled/decoded" +# heading. A row can legitimately be unsure about one clause while its page is +# sure about another, so every hit is a prompt to read. I read all 8. +# +# ✅ 5 ARE LEGITIMATE -- index and page are talking about different clauses: +# 77 flight-speed-law "🟡 for the unit scale" -- still true +# 127 isl-builtins "🟡 28 ..." -- still true +# 132 mcol-collision "🟡 OPENED ..." -- a status word +# 159 boot-config-registry "❔ [SYSTEM] is empty ..." -- still true +# 162 ui-title-build-map "🟡 which loading bundle takes which name" -- open +# +# 🔴 3 WERE STALE, all three contradicted by the page they link: +# +# 160 movie-binding "🟡 skippability unsettled" +# -> page: ✅ settled 2026-08-28. One Ⓐ skips: title at 57 s against a +# 193/196/193 s three-boot baseline, press proved singular by Canary's +# own delivery counter going 3→4, skipped-to title fully functional. +# +# 158 menu-audio-cues "❔ Static.slb has no wave boundaries, so SE audio is +# not extractable" +# -> page line 189: "both waves are located in Static.slb. The port can +# have the audio." The waves are at move 0x1ec0, confirm 0x5d6c0, +# back 0x0ec0. +# ⚠️ AND THE PAGE CONTRADICTS ITSELF: its line 81 still heads a section +# "❔ And a new negative: an individual SE's audio is not extractable +# yet", which its own line 189 refutes. Not fixed here -- flagged. +# +# 156 menu-navigation "🟡 Ⓑ leaving the MAIN menu downgraded 2026-08-29 -- +# uncited" +# -> page line 27: ✅ measured 2026-08-30, delivery-confirmed, ≤0.4 s, no +# loading screen, plate re-drawn ~7 s later, three captures cited. +# +# 🔴 AND ONE OF THE THREE SHOULD HAVE BEEN CAUGHT BY MY OWN REGISTER. +# REFUTED.md holds "`Static.slb` has no wave boundaries, so its layout is +# unknown". INDEX said "...so SE audio is not extractable". Same dead claim, +# different second clause -- and check_refuted.py matches EXACT wording, so it +# saw nothing. That weakness is documented in the tool's own docstring ("a clean +# run means no VERBATIM revival"); this is the first LIVE instance of it, and it +# survived in the index for days. +# +# ⚠️ REACH: this compares an index row's emoji against the presence of a ✅ +# heading on the linked page. It cannot see a row that is confidently WRONG +# (no 🟡 to trip on), a row whose page has no status heading, or anything in +# HANDOFF.md or BLOCKED.md. 3 of 8 hits were real; the other 5 cost one read each. diff --git a/tools/re-capture/index_vs_pages.py b/tools/re-capture/index_vs_pages.py new file mode 100644 index 00000000..d2adbb60 --- /dev/null +++ b/tools/re-capture/index_vs_pages.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Does an INDEX.md row's status agree with the page it links? + +`INDEX.md` is read every iteration by both agents and is the first thing a new +reader meets. sylpheed-port's phrase for it is "an index is an amplifier": a +status that is wrong there is wrong everywhere it is quoted from. + +Found by accident: INDEX called movie skippability 🟡 unsettled while +`movie-binding.md` had it ✅ settled since 2026-08-28, with a three-boot baseline +and delivery confirmation -- and HANDOFF carried the answer correctly. The stale +row is in the index alone. + +⚠️ THIS PRINTS A LISTING, NOT A VERDICT. An audit that invents defects is worse +than no audit, because its false positives are indistinguishable from its true +ones until each is opened by hand (sylpheed-port paid for that, and so did I with +a 7-candidate/0-real sweep). A row can legitimately say 🟡 about one clause while +its page says ✅ about another. Every hit here is a PROMPT TO READ. + + index_vs_pages.py [--all] +""" +import re +import sys +from pathlib import Path + +ROOT = Path("docs/re") +idx = (ROOT / "INDEX.md").read_text().splitlines() +LINK = re.compile(r"\[`([^`]+\.md)`\]\(([^)]+)\)") + +rows = [] +for n, line in enumerate(idx, 1): + if not line.startswith("|"): + continue + m = LINK.search(line) + if not m: + continue + target = (ROOT / m.group(2)).resolve() + if not target.exists(): + rows.append((n, m.group(1), "MISSING PAGE", "")) + continue + page = target.read_text() + # the page's own headline status, if it declares one + st = "" + ms = re.search(r"\*\*Status:\*\*\s*(.+)", page) + if ms: + st = ms.group(1).strip() + idx_unsure = ("🟡" in line) or ("❔" in line) + page_sure = bool(re.search(r"^##+ ✅[^\n]*(settled|SETTLED|decoded|DECODED|measured)", + page, re.M)) + if idx_unsure and page_sure: + rows.append((n, m.group(1), st[:70], "index unsure / page has a ✅ settled heading")) + elif "--all" in sys.argv: + rows.append((n, m.group(1), st[:70], "")) + +print(f"{len(rows)} row(s) to READ (not defects):\n") +for n, name, st, why in rows: + print(f" INDEX.md:{n} {name}") + if why: + print(f" {why}") + if st: + print(f" page Status: {st}")