Last iteration I retracted three claims because `--build 10/11` on GP_TITLE are entries 12/15, and named the untested remainder in my own report: how much else in the corpus used a build ordinal as an entry index. This is that sweep. `screen --build N` indexes a predicate-filtered list, so every rejected entry shifts every later ordinal. Disc-wide: 21 of 24 build-bearing archives diverge, 18 of them at ordinal 0 -- `--build 0` is entry 108 in each GP_MAIN_GAME_*2D, 24/26 in GP_HANGAR_ARSENAL/GP_READY_ROOM. GP_TITLE is the ONLY archive whose first ten ordinals are the identity, which is the sole reason 207 of the corpus's 226 build citations are safe. Second foot-gun: `--all` swaps the predicate and renumbers 18 archives, so `--build N` and `--build N --all` are not the same object. The instrument failed its control first. A version using parse_build as the predicate reported GP_TITLE as 16 builds, ordinal == entry throughout -- it would have certified the exact bug it was built to find. The shipped version uses the same predicates screen_builds() uses and reproduces `screen list` on GP_TITLE exactly. Audited all 226 citations. One real defect: a five-row table in ui-keyframe-time-unit.md headed "declared element (build 11)" spans builds 10 and 11 -- palogo_sqex is in 10. All five placements re-verified and correct, so the linear-ramp measurement is untouched; only the label was wrong. Fixed with a per-row bundle column. GP_DIALOG --build 0 and GP_DEBRIEFING_PILOTLOG --build 10 re-run and reproduce. Refutation attempted: sylpheed-port's corrected mid-ramp test rests on ptlogo_all_eff holding a=127 from t=112 to t=246. Their quote is exact and it is a plateau. The refutation fails; their correction stands. METHOD already carried the rule I broke, and ui-splash-addressing already said the splashes need --all. The failure was not missing knowledge -- it was addressing a bundle by index without grepping for the index first. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
7.2 KiB
✅ --build N is an ordinal into a filtered list — and on 21 of 24 archives it is not the entry
Status: ✅ decoded, disc-wide, instrument controlled against the CLI's own
output. The object decoded is the addressing, not a file field: how
sylpheed-cli screen --build N resolves, and where that number stops agreeing
with the pak entry index a reader will assume it means.
Why this was swept
Last iteration I rendered --build 10 and --build 11 of GP_TITLE believing
they were the two splash screens, wrote three claims on the output, and every
downstream number validated. They are entries 12 and 15 — the loading
screens. I retracted it, and named the untested remainder in my own report:
"how much else in the corpus used --build as an entry index — not swept."
This is that sweep.
The mechanism
crates/sylpheed-cli/src/main.rs:394 builds the list:
fn screen_builds(pak: &Path, all: bool) -> Result<Vec<(usize, Vec<u8>)>> {
for (i, e) in ar.entries().iter().enumerate() {
let keep = if all { ui_layout::is_composable(&bytes) }
else { ui_layout::is_build(&bytes) };
if keep { out.push((i, bytes)); } // (entry, bytes)
}
}
--build N indexes out, so N counts only entries that passed a predicate.
Every entry the predicate rejects shifts every later ordinal down by one.
🔴 The result: GP_TITLE is the mildest case on the disc
data/ordinal-entry-map.txt — all 24 archives
holding builds:
- 21 of 24 diverge. Only
GP_MOVIE_THEATER,GP_SYSTEMandGP_TUTORIALhave ordinal == entry throughout. - 18 of the 21 diverge at ordinal 0 —
--build 0is not entry 0. The worst are the sixGP_MAIN_GAME_*2Dpaks, where[0]is entry 108, andGP_HANGAR_ARSENAL/GP_READY_ROOM, where[0]is entry 24 / 26. GP_TITLEis the only archive whose first ten ordinals happen to be the identity. It diverges at ordinal 10 and nowhere earlier.
So the corpus was not lucky in general — it was lucky in the one archive almost all of it is about, and unlucky in exactly the two indices I used.
⚠️ Second foot-gun: --all renumbers, on 18 archives
--all swaps the predicate, which changes the list, which changes the ordinals.
--build N and --build N --all are not the same object on 18 of 24
archives — including GP_TITLE, where --build 10 is entry 12 but
--build 10 --all is entry 10. Any citation of a build index that does not also
record whether --all was passed is under-specified.
✅ Audit of every build citation in docs/
226 citations of a build index across docs/ (this file excluded). The 207 that
name an ordinal 0–9 of GP_TITLE are safe by the accident above. The 19 that
name an ordinal ≥10, or a non-GP_TITLE archive, are the ones that can be wrong,
so each was opened and checked rather than counted:
| # | citations | verdict |
|---|---|---|
| 6 | carry --all, where ordinals 10/11 are entries 10/11 |
✅ correct |
| 4 | inside last iteration's retraction, already marked void | ✅ n/a |
| 2 | GP_TITLE --build 10 bare — ui-title-build-map.md:85 |
✅ correct: it names what comes back, the loading screen pgloading_str.t32 |
| 2 | GP_DIALOG --build 0 ([0] is entry 2) |
✅ re-run, reproduces |
| 2 | GP_DEBRIEFING_PILOTLOG build 10 ([10] is entry 131) |
✅ re-run, reproduces |
| 2 | prose about an unfinished sweep / the renumbering warning itself | ✅ n/a |
| 1 | ui-keyframe-time-unit.md:59 |
🔴 wrong, and fixed |
The two re-runs
Neither claim asserted an entry number — both cite the output of a command, so a reader running it gets the same object the author had. Confirmed by running them, not by arguing it:
$ sylpheed-cli screen info --build 0 --geometry /disc/dat/GP_DIALOG.pak
4 pceff03.t32 0: a=0 r=90 8: a=128 r=30 12: a=192 r=10 14: a=224 r=3 16: a=255
5 pceff04.t32 0: a=0 r=90 8: a=128 r=30 12: a=192 r=10 14: a=224 r=3 16: a=255
$ sylpheed-cli screen info --build 10 --geometry /disc/dat/GP_DEBRIEFING_PILOTLOG.pak
5 pjeff24a.t32 382x140 0: 335,49 210%,210% a=53 r=90 (one keyframe)
Both stand unchanged.
🔴 The one real defect the sweep found
ui-keyframe-time-unit.md headed a five-row table
"declared element (build 11)". Its first row is palogo_sqex.t32 — and
--all --build 11 does not contain it:
--all --build 10 palogo_sqex, palogo_sqex_eff
--all --build 11 palogo_gamearts{,_eff}, palogo_seta{,_eff}, palogo_anima{,_eff}
The rows span two bundles. All five placements re-verified and are correct —
palogo_sqex.t32 666×68 @ (309,330) in build 10, palogo_gamearts_eff.t32
521×91 @ (379,154) in build 11 — so the measurement the table supports (the ramp
is linear) is untouched. Only the label was wrong. Fixed: the table now carries a
per-row bundle column.
That is the shape worth remembering: the index error did not corrupt the numbers, it corrupted the sentence around them, and the numbers kept validating.
⚠️ For the port: this is an addressing hazard, not a decoding one
If you address bundles by pak entry index — which
ui-splash-addressing.md recommends for the
splashes — and cross-reference a doc that says "build 6", those are different
objects on 21 archives. When quoting an index, say which kind it is. Our docs
now say ordinal or entry.
Refutation attempted — sylpheed-port's corrected mid-ramp test — survives
The port withdrew their own title_jp "separating case" this iteration, on the
grounds that ptlogo_all_eff holds a=127 from t=112 to t=246 rather than
ramping through it, so their old 0 < alpha < 255 test had counted a steady
semi-transparent glow as a transition. Their whole correction — and the 5/5
result they say survives it — rests on the keyframes of that one element, which
is disc data and therefore mine to check. Quoted against the disc:
$ sylpheed-cli screen info --build 7 --geometry /disc/dat/GP_TITLE.pak
29 ptlogo_all_eff.t32 538x255 0: a=0 76: a=0 112: a=127 246: a=127 258: a=0
(kind 0x3000, 200%,200%, position constant)
Their quote [0:a0 76:a0 112:a127 246:a127 258:a0] is exact, and a=127 is
held flat across 134 units with nothing else moving. It is a plateau. The
refutation fails and their correction stands — including the part that costs
them, since it removes the one case that would have separated their hypothesis
from mine.
⚠️ Note what this does not establish: that a=127 is a glow. That reading is
theirs and rests on kind 0x3000 and the 200 % scale, neither of which I have
tested against the running game. What I checked is the keyframes.
What this does not settle
- Whether anything outside
docs/— scripts undertools/, committed test fixtures — hard-codes a build ordinal for a diverging archive. I swept the prose, not the code. - The three identity archives are identity today. Nothing enforces it; a change
to
is_buildmoves every ordinal on the disc. This is a property of a predicate, not of the format.