From de1ff6ed76d1fb3617276e52ad1b975542fd08a2 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Wed, 26 Aug 2026 10:29:15 +0000 Subject: [PATCH] docs: define the status markers, and fix six mislabelled or superseded entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An audit of BACKLOG.md turned up a class of error with a single root cause: the README defines only the CONFIRMED/PROBABLE/HYPOTHESIS confidence scale, while the pages actually use a second vocabulary -- and πŸ”΄ appears 98 times without ever being defined. It gets used for two different things, "refuted" and "blocked", and three entries slid from one into the other. README now defines βœ…/🟑/❔/πŸ”΄/❌/🚧 and states the rule the corpus was missing: πŸ”΄ never means "we have not run it yet". That is ❔ or 🚧. Its blocked sense is only for a real limit of the box -- no push credentials, no hardware Vulkan, a decision only the user can make -- and since the box can run the emulator, script input, screenshot and read guest memory, "needs a run" is never blocked. I made exactly this mistake on the world-unit item earlier today, which is what prompted looking for others. Fixed in BACKLOG.md: * the elimination test, marked πŸ”΄ UNRUN and in fact run and refuted nine lines further down; * the frozen capture, marked πŸ”΄ STILL UNRUN and in fact taken eleven lines down -- πŸ”΄ wrong twice, since "the freeze did not happen this run" is a scheduling outcome and not a refutation; * a 🚧 STILL UNRUN item whose stated blocker (the boot-nav bug) is fixed; * the objective-counter heading, which asserts 0xbdb59668 as the answer while its own first body line refutes that address -- retitled to say what is actually solved, the method; * the paint-order "third measured permutation" question, answered inside its own entry by a third, fourth and fifth screen; * the UTF-16 endianness question -- resolved, and it is not a stale comment: localization.rs both documents LE and decodes with u16::from_le_bytes, so it is a code bug worth filing. Also fixes the corpus's only dangling link (INDEX.md pointed at structures/idxd-unnamed-keys.md, never written). --- docs/re/BACKLOG.md | 19 ++++++++++++------- docs/re/INDEX.md | 2 +- docs/re/README.md | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 97fe6105..dfb01539 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -157,7 +157,7 @@ where translucent sprites overlap. A separate earlier slip on the same page counted the six *language* copies of `GP_MAIN_GAME_2D` as six paks. Same shape each time: a statistic computed over an unverified sampling frame. -* ❔ A third measured permutation, to promote "holds on two" to a rule. The +* ~~❔ A third measured permutation, to promote "holds on two" to a rule.~~ **Answered inside this same entry** β€” a third, fourth and fifth screen were measured, the last from `GP_SAVE_LOAD`, i.e. outside `GP_TITLE.pak`. The cheapest is a screen whose object is resident at the same time as the title's. * ❔ 341 builds now composite in an order no capture has checked. @@ -600,7 +600,7 @@ search cannot find a *schedule*. longer covers those (it still covers t=170/210/240; the run was cut at 240 s by the turn timeout, not the planned 330 s). 🟑 **Sharper hypothesis:** the squadron ended at **2, never 0** β€” no squadron has ever been eliminated in any - run, so the trigger may be *elimination*, not damage. πŸ”΄ **Elimination test UNRUN (2026-08-24)**: the hunting + run, so the trigger may be *elimination*, not damage. ❔ **Elimination test unrun (2026-08-24)** β€” *superseded below by the `SYLPH_KEEPOUT=1400` run that refuted it; and πŸ”΄ was the wrong marker, an unfinished run is ❔, not blocked*: the hunting pilot died at t=83 s with the squadron at 14. βœ… But the player's own record hit `2β†’0` β€” first `nβ†’0` ever seen, so the signal does register elimination (no arrival followed; weak, it was the player not an enemy squadron). βœ… **KEY: @@ -799,8 +799,11 @@ search cannot find a *schedule*. `0xbdb59668` is phase-1 progress** and is the right signal to watch, not `deployed`. Closes a loop to the first session. πŸ”΄ **Method lesson: the crate already knew this** β€” several iterations reconstructed it the hard way; - `grep -rl TextIndex crates/` would have saved the detour. ❔ Minor: `ixud.rs` - says UTF-16BE, `localization.rs` says LE β€” one comment is wrong. + `grep -rl TextIndex crates/` would have saved the detour. βœ… Minor, resolved 2026-08-26: + strings are **UTF-16BE** ([`idxd-container`](structures/idxd-container.md), + 1 104/1 104 objects), so `ixud.rs` is right and **`localization.rs` is the wrong + one** β€” its header says UTF-16LE *and* it decodes with `u16::from_le_bytes`, so + it is a code bug, not a stale comment. * βœ…πŸ”΄ **(2026-08-24) REMAINING OB hunt: method works, run unfinished** ([`remaining-ob-hunt.md`](remaining-ob-hunt.md)). Correlate heap words against *named* kill events instead of scanning for a value: **one `e010` event cut ~8 M @@ -987,7 +990,7 @@ search cannot find a *schedule*. groups sharing a handle. 🟑 `%ebp` is **not** a usable count β€” `WaitMultiple` reuses it at `8fc158` β€” so the array is bounded by reading until an entry stops resolving. What survives: the object types and the self-validating read. -* πŸ”΄ **(2026-08-25) The frozen capture is STILL unrun β€” the freeze did not happen.** +* ❔ **(2026-08-25) The frozen capture was unrun β€” the freeze did not happen that run.** *Superseded: it was taken (see `FROZEN CAPTURE TAKEN` below). πŸ”΄ was wrong twice β€” the capture was not blocked, and "it did not happen this run" is a scheduling outcome, not a refutation.* Two captures in one run (200 s and 367 s of mission), and `screen_id` reads **`flight`** at both, plus at ~470 s with a drifting frame mean. So the labelled `healthy -> frozen` diff is **two healthy captures**, and its `20 -> 18` is three @@ -1382,7 +1385,7 @@ premise was wrong.** long-lived Python process computing both signals β€” then re-run. Second: check whether the fast 2026-08-25 run had a warm shader cache that this one, started after `rm -f /dev/shm/xenia_*`, did not. -* 🚧 **(2026-08-25) STILL UNRUN β€” the live test of the `reset_phase_threads` +* 🚧 **(2026-08-25) Still unrun β€” the live test of the `reset_phase_threads` rename.** Built-in 100 clears the trigger container and frees every thread but the caller, so at a phase terminator **both** `[phase+272+20]` (triggers queued) and `[phase+216+8]` (coroutines alive) should collapse; if they climb @@ -1509,7 +1512,9 @@ shared checkout (202 files, no submodule churn), profile bootstrapped with the meant to, the profile + save + `bin/` copies want a home inside a repo or a named volume; that is a call for the user, not for an agent. -## βœ… SOLVED (2026-08-23) β€” the mission objective counter is at `0xbdb59668`, and the hunt is automated +## βœ…πŸ”΄ SOLVED (2026-08-23) β€” the *method* for finding the mission objective counter is automated; the **address is run-dependent** + +*(Retitled 2026-08-26: the old heading asserted `0xbdb59668` as the answer while its own first line refutes that address. The method is the result.)* πŸ”΄ **`0xbdb59668` is refuted as a durable address** (2026-08-23): 0 in two independent Stage 02 runs while the HUD read `004`/`008`/`012`, on an allocated diff --git a/docs/re/INDEX.md b/docs/re/INDEX.md index d1a0f0d4..f730b82e 100644 --- a/docs/re/INDEX.md +++ b/docs/re/INDEX.md @@ -12,7 +12,7 @@ Promote to a prose `structures/…md` file when a format needs behavioural notes |--------|-------|-----------------------|-------| | IPFB `.pak` archive | βœ… | `sylpheed-formats/src/pak.rs` + `tests/pak_idxd_disc.rs` | header + 12-byte TOC, Z1/zlib payloads | | name-hash (TOC keys) | βœ… | `sylpheed-formats/src/hash.rs` | Barrett-reduction hash; recovers original paths | -| IDXD object/table | βœ… | `sylpheed-formats/src/idxd.rs` + `tests/idxd_records_disc.rs` ([container](structures/idxd-container.md)) | **The binary record/index region in front of the string pool is DECODED** (2026-08-25), closing the parser's long-standing "not yet decoded" note. Uniform 16-byte records `{name_hash, name_off, field_begin, field_end}` sorted by hash and binary-searched, then a field count, 12-byte fields `{key, name_off, value_off}` sorted by key, a pool size, and the string pool; the trailing `pool_size == file_len - pool_base` identity makes the layout self-checking. Verified over the **whole disc** with **zero** failures: 7 750/7 750 objects, 190 782/190 782 records reproducing their stored `tag_hash`, 1 271 462/1 271 462 named fields reproducing their key β€” and `IXUD` is the same container with `ixud_hash`, UTF-16BE and all offsets in **chars** (1 104/1 104 objects, 628 165/628 165 fields). **Field names are stored on disc** β€” a field's middle word points at its own name β€” so nothing needs preimage search except the **504** field entries disc-wide that are hash-keyed with no name β€” which are only **42 distinct keys**, each in 12 places (see [idxd-unnamed-keys.md](structures/idxd-unnamed-keys.md)), and are provably unrecoverable from the hash alone; the other 1 485 073 nameless fields are *positional*, keyed by a literal integer (line slots, movie ids). ⚠️ **Two long-held beliefs WITHDRAWN**: the word at `0x08` is **not a schema hash**, it is record 0's `name_hash` (7 750/7 750) β€” the header has no type field at all, so an object's kind is known only from the caller that loads it; and the field's middle word is **not** an always-`0xFFFFFFFF` flags word. The first was caught by a test asserting that every movie id names a real record: `1005 -> STAGE10_PHASE01` failed because `tag_hash("STAGE10_PHASE01")` **is** `0x067025B9`, that table's supposed schema id. 🟑 the legacy value-before-key string-pool reader is now known to be an *approximation* of the real table, and every number derived from it is re-checkable but not yet re-checked | +| IDXD object/table | βœ… | `sylpheed-formats/src/idxd.rs` + `tests/idxd_records_disc.rs` ([container](structures/idxd-container.md)) | **The binary record/index region in front of the string pool is DECODED** (2026-08-25), closing the parser's long-standing "not yet decoded" note. Uniform 16-byte records `{name_hash, name_off, field_begin, field_end}` sorted by hash and binary-searched, then a field count, 12-byte fields `{key, name_off, value_off}` sorted by key, a pool size, and the string pool; the trailing `pool_size == file_len - pool_base` identity makes the layout self-checking. Verified over the **whole disc** with **zero** failures: 7 750/7 750 objects, 190 782/190 782 records reproducing their stored `tag_hash`, 1 271 462/1 271 462 named fields reproducing their key β€” and `IXUD` is the same container with `ixud_hash`, UTF-16BE and all offsets in **chars** (1 104/1 104 objects, 628 165/628 165 fields). **Field names are stored on disc** β€” a field's middle word points at its own name β€” so nothing needs preimage search except the **504** field entries disc-wide that are hash-keyed with no name β€” which are only **42 distinct keys**, each in 12 places (the page for these was never written β€” the finding is in this row), and are provably unrecoverable from the hash alone; the other 1 485 073 nameless fields are *positional*, keyed by a literal integer (line slots, movie ids). ⚠️ **Two long-held beliefs WITHDRAWN**: the word at `0x08` is **not a schema hash**, it is record 0's `name_hash` (7 750/7 750) β€” the header has no type field at all, so an object's kind is known only from the caller that loads it; and the field's middle word is **not** an always-`0xFFFFFFFF` flags word. The first was caught by a test asserting that every movie id names a real record: `1005 -> STAGE10_PHASE01` failed because `tag_hash("STAGE10_PHASE01")` **is** `0x067025B9`, that table's supposed schema id. 🟑 the legacy value-before-key string-pool reader is now known to be an *approximation* of the real table, and every number derived from it is re-checkable but not yet re-checked | | XPR2 texture + cubemap | 🟑/βœ… | `sylpheed-formats/src/texture.rs` + [colour check](xpr2-colour-check.md) | de-tile + A8R8G8B8 and DXT1. **Channel order βœ… confirmed against the running game**: the Delta Saber's decoded atlas is orange-dominant (median saturated hue 23.3Β°, *zero* cool pixels) and the game renders the same hull at 9.3Β° β€” a red↔blue swap would sit at β‰ˆ200Β°. Exact fidelity (gamma/sRGB curve, premultiplied alpha, per-channel scale) is 🟑 untested, since a hue comparison cannot see it; cubemap face ordering ❔ | | T8aD 2D texture | βœ… | `sylpheed-formats/src/t8ad.rs` | **100 % of the disc decodes** (19 216/19 216, measured). The "~15 % deferred variants" were a wrong model, not a variant: a surface is a list of **arbitrary sub-rectangles**, each with a 16-byte header of `dst X, dst Y, width, height`, not a 256Γ—256 grid β€” `0x1c` is the **rectangle count**. Uncovered area stays transparent. **Colours βœ… CONFIRMED** ([k8888](structures/texture-color-k8888.md)) | | RATC bundle | βœ… | `sylpheed-formats/src/ratc.rs` | child listing confirmed. **"One level deep" is not a limitation β€” there is nothing deeper**: 2 859 bundles hold 18 002 children at depth 1 and **0 at depth 2**, with no parse failures. Nested RATC blobs are **leaf records that reference siblings by name** (`opt `, the sprite name): 3 311 leaves, all embedding sibling names, **10 144 of 10 148 references resolve**. The 4 that do not are one dangling asset β€” `pmbase.rat` β†’ `pmbase.t32` in `GP_STAGE_CLEAR.pak`'s four language builds, and `pmbase.t32` is **on the disc nowhere** | diff --git a/docs/re/README.md b/docs/re/README.md index ff981389..26a6efca 100644 --- a/docs/re/README.md +++ b/docs/re/README.md @@ -37,6 +37,28 @@ This mirrors the project method β€” *measure the oracle, never infer; refute bef | `PROBABLE` | Strong single-source inference. | One clean observation, or an unambiguous static read of the disassembly. | | `HYPOTHESIS` | Educated guess, not yet tested. | Anything else. Must say what would confirm/refute it. | +### The status markers + +The table above is the *confidence* scale. The markers that appear in +`BACKLOG.md` and the `structures/` pages are a separate, and until now undefined, +vocabulary. They mean: + +| Marker | Meaning | +|---|---| +| βœ… | Confirmed β€” verified against ground truth. | +| 🟑 | Partial: true as far as it goes, or true under a stated assumption. | +| ❔ | Open question. Nobody has answered it yet. | +| πŸ”΄ | **Refuted** β€” shown false β€” **or blocked by something the container cannot do.** | +| ❌ | A specific claim that was tried and failed. Prefer πŸ”΄. | +| 🚧 | Work started and not finished. | + +**πŸ”΄ never means "we have not run it yet."** That is ❔ or 🚧. Reserve πŸ”΄'s +"blocked" sense for a real limit of the box β€” no push credentials, no hardware +Vulkan (lavapipe only), or a decision only the user can make. The box *can* run +the emulator, script input, screenshot, read guest memory, and build and test +Rust, so "needs a run" is never a blocker. This paragraph exists because the +marker was undefined for 98 uses and three of them were mislabelled that way. + **Promotion requires new evidence, not re-reading the old evidence.** A `HYPOTHESIS` that "looks right again" is still a `HYPOTHESIS`. Only an *independent* check promotes it. If evidence later contradicts an entry, **demote it and record the contradiction** β€” do