re: sweep the disc for the ordinal foot-gun -- GP_TITLE was the mildest case
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
This commit is contained in:
152
docs/re/structures/build-ordinal-vs-entry.md
Normal file
152
docs/re/structures/build-ordinal-vs-entry.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# ✅ `--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:
|
||||
|
||||
```rust
|
||||
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`](../data/ordinal-entry-map.txt) — all 24 archives
|
||||
holding builds:
|
||||
|
||||
* **21 of 24 diverge.** Only `GP_MOVIE_THEATER`, `GP_SYSTEM` and `GP_TUTORIAL`
|
||||
have ordinal == entry throughout.
|
||||
* **18 of the 21 diverge at ordinal 0** — `--build 0` is *not* entry 0. The worst
|
||||
are the six `GP_MAIN_GAME_*2D` paks, where `[0]` is entry **108**, and
|
||||
`GP_HANGAR_ARSENAL` / `GP_READY_ROOM`, where `[0]` is entry **24** / **26**.
|
||||
* `GP_TITLE` is 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`](../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`](../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 under `tools/`, 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_build` moves every ordinal on the disc. This is a property of a
|
||||
predicate, not of the format.
|
||||
Reference in New Issue
Block a user