re: not ONE of the 80 forced instances has a file-read key

The port agent pointed out that forced_backdrop_necessity.rs collapsed
sprite_layer_key (a u16 read from the T8aD header, decoded) with
implied_layer_key (this crate's table of positions MEASURED in the running
game), and that 'has its own key' therefore reads as file-backed when it is
not. Splitting them is stronger than either of us stated:

    read from the T8aD header:   0
    implied (measured):         14   10x pfbase.tbm, 4x palogo_eff0.prm
    nothing at all:             66   62 decided, 4 inert

Zero. There is no instance on the disc where a forced element also carries a
file-read layer key, so this rule has never been checked against a decoded
field -- there is no case where both can speak. That is what a keyless-element
fallback necessarily looks like, but it removes a check a reader would assume
exists.

Also corrects something I said to the port and had wrong. 'None of the 18 is
evidence for the rule in any direction' conflated two questions. Whether the
rule changes the composite: no, the sort already had the key. Whether the rule
gets the RIGHT answer: yes, and the 14 implied keys are measured positions, so
this is the rule agreeing with the oracle -- its only external corroboration,
and there are 14 instances of it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
sylph-decoder
2026-08-30 07:11:12 +00:00
parent 215943e873
commit b8cb695053
3 changed files with 209 additions and 6 deletions

View File

@@ -0,0 +1,100 @@
# What kind of key does each of the 80 forced instances have?
#
# Produced by: cargo run -p sylpheed-formats --example forced_backdrop_key_source
# 2026-08-30, SYLPHEED_DISC=/disc, every dat/*.pak.
#
# forced_backdrop_necessity.rs collapsed sprite_layer_key (a u16 READ from the
# T8aD header -- decoded) with implied_layer_key (this crate's per-name table of
# positions MEASURED in the running game). Raised by the port agent; splitting
# them gives a stronger result than either of us stated.
#
# read from the T8aD header: 0 <-- NOT ONE, anywhere on the disc
# implied (measured): 14 10x pfbase.tbm, 4x palogo_eff0.prm
# nothing at all: 66 62 the rule decides, 4 inert
#
# archive entry element key_source key
GP_BUNK.pak 0 px_bunk_base.tbm none -
GP_BUNK.pak 2 px_bunk_base.tbm none -
GP_BUNK.pak 4 pvbase.tbm none -
GP_BUNK.pak 6 pvbase.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 118 px_deb_base.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 130 px_deb_base.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 131 pjbgbase2.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 134 px_deb_base.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 150 pjbgbase2.tbm none -
GP_DEBRIEFING_PILOTLOG.pak 165 px_deb_base.tbm none -
GP_DIALOG.pak 2 pcbase.tbm none -
GP_DIALOG.pak 3 pcbase.tbm none -
GP_DIALOG.pak 9 pzeff00.prm none -
GP_DIALOG.pak 10 pzeff00.prm none -
GP_DIALOG.pak 11 pzeff00.prm none -
GP_DIALOG.pak 12 pzeff00.prm none -
GP_DIALOG.pak 13 pzeff00.prm none -
GP_DIALOG.pak 14 pzeff00.prm none -
GP_DIALOG.pak 15 pzeff00.prm none -
GP_DIALOG.pak 16 pzeff00.prm none -
GP_DIALOG.pak 17 pzeff00.prm none -
GP_DIALOG.pak 18 pzeff00.prm none -
GP_DIALOG.pak 19 pzeff00.prm none -
GP_DIALOG.pak 20 pzeff00.prm none -
GP_DIALOG.pak 21 pzeff00.prm none -
GP_DIALOG.pak 22 pzeff00.prm none -
GP_DIALOG.pak 23 pzeff00.prm none -
GP_DIALOG.pak 24 pzeff00.prm none -
GP_DIALOG.pak 25 pzeff00.prm none -
GP_DIALOG.pak 26 pzeff00.prm none -
GP_DIALOG.pak 28 pzeff00.prm none -
GP_DIALOG.pak 29 pzeff00.prm none -
GP_DIALOG.pak 30 pzeff00.prm none -
GP_DIALOG.pak 31 pzeff00.prm none -
GP_DIALOG.pak 32 pzeff00.prm none -
GP_DIALOG.pak 33 pzeff00.prm none -
GP_DIALOG.pak 34 pzeff00.prm none -
GP_DIALOG.pak 35 pzeff00.prm none -
GP_DIALOG.pak 36 pzeff00.prm none -
GP_DIALOG.pak 37 pzeff00.prm none -
GP_DIALOG.pak 38 pzeff00.prm none -
GP_DIALOG.pak 39 pzeff00.prm none -
GP_DIALOG.pak 40 pzeff00.prm none -
GP_DIALOG.pak 41 pzeff00.prm none -
GP_DIALOG.pak 86 esrb_base.prm none -
GP_DIALOG.pak 130 esrb_base.prm none -
GP_GAMEOVER.pak 4 pnbase.tbm none -
GP_GAMEOVER.pak 7 pnbase.tbm none -
GP_MISSION_SELECT.pak 3 px_mission_base.tbm none -
GP_MISSION_SELECT.pak 5 px_mission_base.tbm none -
GP_MOVIE_THEATER.pak 0 px_movie_base.tbm none -
GP_MOVIE_THEATER.pak 1 px_movie_base.tbm none -
GP_OPTIONS.pak 0 po_menu_base.tbm none -
GP_OPTIONS.pak 0 po_menu_base.tbm none -
GP_OPTIONS.pak 2 po_menu_base.tbm none -
GP_OPTIONS.pak 2 po_menu_base.tbm none -
GP_SAVE_LOAD.pak 37 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 37 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 40 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 40 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 46 pgloading_eff00.prm none -
GP_SAVE_LOAD.pak 58 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 69 pgloading_eff00.prm none -
GP_SAVE_LOAD.pak 78 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 89 px_replay_base.tbm none -
GP_SAVE_LOAD.pak 93 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 93 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 98 px_replay_base.tbm none -
GP_SAVE_LOAD.pak 99 pfbase.tbm implied_MEASURED 0x00000000
GP_SAVE_LOAD.pak 99 pfbase.tbm implied_MEASURED 0x00000000
GP_SYSTEM.pak 0 pqbase.tbm none -
GP_SYSTEM.pak 1 pqbase.tbm none -
GP_TITLE.pak 10 palogo_eff0.prm implied_MEASURED 0x00000000
GP_TITLE.pak 11 palogo_eff0.prm implied_MEASURED 0x00000000
GP_TITLE.pak 12 pgloading_eff00.prm none -
GP_TITLE.pak 13 palogo_eff0.prm implied_MEASURED 0x00000000
GP_TITLE.pak 14 palogo_eff0.prm implied_MEASURED 0x00000000
GP_TITLE.pak 15 pgloading_eff00.prm none -
GP_TUTORIAL.pak 0 pubase.tbm none -
GP_TUTORIAL.pak 1 pubase.tbm none -
# forced instances by key source:
# read from the T8aD header (decoded): 0
# implied — this crate's MEASURED name table: 14
# none — only forced_backdrop can speak: 66

View File

@@ -218,14 +218,46 @@ instrument: `crates/sylpheed-formats/examples/forced_backdrop_necessity.rs`.
is the rule behaving as designed: it is a fallback, and it only ever fires where
nothing else can speak.
### 🔴 Not one of the 80 has a key read from the file
The necessity probe asked whether an element had *a* key, collapsing
`sprite_layer_key` — a `u16` read out of the `T8aD` header, **decoded** — with
`implied_layer_key` — this crate's per-name table, whose doc comment says outright
*"only names whose position has actually been measured"*. The port agent pointed out
that for describing what a *confirmation is made of* those are different claims, and
splitting them gives a sharper answer than either of us had
([`../data/forced-backdrop-key-source.txt`](../data/forced-backdrop-key-source.txt)):
| key source | instances |
|---|---|
| read from the `T8aD` header (decoded) | **0** |
| `implied_layer_key` (measured in the running game) | 14 |
| nothing at all | 66 |
**Zero.** There is no instance anywhere on the disc where a forced element also
carries a file-read layer key — which means **this rule has never been checked
against a decoded field, because there is no case in which both can speak.** That is
not a defect of the rule; it is what a fallback for keyless elements necessarily
looks like. But it removes a check a reader would reasonably assume exists, and the
page should not have let "own key" stand for it.
The 14 are two names: `pfbase.tbm` ×10 (`GP_SAVE_LOAD`) and `palogo_eff0.prm` ×4
(`GP_TITLE`), both implied `0x00000000`.
The 18 that merely agree split two ways, and the distinction matters:
* **14 have a key of their own** — `pfbase.tbm` (10) and `palogo_eff0.prm` (4). Here
the sort already had the answer and the rule reproduces it. ⚠️ **This is the part
that is not independent support.** `palogo_eff0.prm` being forced first agrees
with its measured order, but its `implied_layer_key` is `0x00000000` and would
have put it first anyway — so that agreement is the rule reproducing the crate,
not the game confirming the rule.
* **14 have a key of their own, and it is an IMPLIED one** — `pfbase.tbm` (10) and
`palogo_eff0.prm` (4). ⚠️ Two questions come apart here and an earlier version of
this page ran them together:
* *Does the rule change the composite?* **No** — the sort already had the key, so
these contribute nothing to the necessity count. That much was right.
* *Does the rule get the right answer?* **Yes, and this is the only place that can
be asked.** `implied_layer_key` is a position measured in the running game, so
the rule forcing these 14 first is the rule agreeing with the **oracle**.
🔴 So "none of the 18 is evidence for the rule in any direction" — said to the port
agent on 2026-08-30 and corrected here — **was wrong about the 14**. They are not
a file-side check, and they are not independent of the sort, but they are the
rule's *only* external corroboration and there are 14 of them.
* **4 are keyless but inert** — `po_menu_base.tbm`, twice in each of two 2-element
builds. *Every* element on those screens is forced, so all keys collapse to the
same value and the declaration-index tie-break gives the identical order either