re: settle the 49.6/92.3 split -- both are real, and the second explanation was wrong too

sylpheed-port corrected their own reconciliation and I reproduced it: 0 nested
records on this disc lack a timed keyframe. All 1530 are static -- timed, every pose
at t == 0 -- so the question is well-formed there and 'not exact' is a real answer,
not an absent one. A static record still declares a cycle length.

So the two percentages are two populations and neither corrects the other: 92.3 % of
animated records, 49.6 % of all nested records including static ones, same numerator
1643. Both need their population attached.

Two wrong explanations preceded this, both mine to carry: that my scan filtered
untimed records, which .max() returning Some(0) prevents, and then their 'questions
never asked' framing which I adopted.

The page is rewritten to the settled state rather than stacked. Nothing the port
depends on moved at any point.

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-31 04:01:01 +00:00
parent c5a3b3aebf
commit dd03887228
3 changed files with 101 additions and 20 deletions

View File

@@ -0,0 +1,51 @@
//! Are the records with `max t == 0` UNTIMED, or timed with every pose at 0?
//!
//! I wrote that 1 530 records are "questions never asked" — no timed keyframe, so
//! `max t` is 0 by absence. `sylpheed-port` now says zero records on this disc are
//! like that: all 1 530 are timed, every pose at t = 0, so the question is
//! well-formed and "not exact" is a real answer. This checks it.
//!
//! cargo run -p sylpheed-formats --example static_record_census
use sylpheed_formats::{pak::PakArchive, ui_layout};
use std::path::PathBuf;
fn main() {
let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"));
let mut paks: Vec<_> = std::fs::read_dir(root.join("dat"))
.expect("dat")
.filter_map(|e| e.ok().map(|e| e.path()))
.filter(|p| p.extension().map(|x| x == "pak").unwrap_or(false))
.collect();
paks.sort();
let (mut untimed, mut all_zero, mut nonzero) = (0usize, 0usize, 0usize);
for p in &paks {
let Ok(ar) = PakArchive::open(p) else { continue };
for e in ar.entries() {
let Ok(by) = ar.read(e) else { continue };
let Some(b) = ui_layout::parse_build(&by) else { continue };
for (_, (off, size)) in &b.records {
let rec = &by[*off..(*off + *size).min(by.len())];
if rec.len() < 0x10 || &rec[0..4] != b"RATC" {
continue;
}
let Some(leaf) = ui_layout::parse_build(rec) else { continue };
let times: Vec<u32> = leaf
.elements
.iter()
.flat_map(|el| el.keyframes.iter().filter_map(|k| k.time))
.collect();
if times.is_empty() {
untimed += 1;
} else if times.iter().max() == Some(&0) {
all_zero += 1;
} else {
nonzero += 1;
}
}
}
}
println!("nested RATC records that parse: {}", untimed + all_zero + nonzero);
println!(" NO timed keyframe at all : {untimed}");
println!(" timed, every pose at t == 0 : {all_zero}");
println!(" timed, largest t > 0 : {nonzero}");
}

View File

@@ -3242,11 +3242,15 @@ Two agents, one statistic, and the disagreement was **entirely in the denominato
`1643/1781 = 92.3 %` against `1643/3311 = 49.6 %`. **Neither of us was wrong about
the disc.**
🔴 **My explanation of the gap was wrong too.** I said my scan "requires a timed
keyframe". It does not — `.max()` over the keyframe times returns `Some(0)`, not
`None`, for a record whose keyframes all sit at time 0, so those never left my
denominator. 1 530 records where *"does the word equal the largest keyframe time?"*
has **no content** were counted as failures **by construction**.
🔴 **Two wrong explanations were offered for the gap before the right one.** Mine
first: I said my scan "requires a timed keyframe" — it does not, because `.max()`
returns `Some(0)` rather than `None`. Then `sylpheed-port`'s reconciliation, which
I adopted: that the extra 1 530 are *"questions never asked"* with no content.
**Also wrong, and they corrected it themselves.** Measured: **0** records on this
disc lack a timed keyframe; all 1 530 are **static** — timed, every pose at t = 0.
A static record still declares a cycle length, so a nonzero `+0x08` against a
largest time of 0 is a **real disagreement, not an absent one**, and the 49.6 % is
a defensible statistic over a different population rather than an artefact.
📌 **`sylpheed-port`'s diagnosis of why it stayed invisible is the transferable
part: the numerator agreed to the unit.** We both looked at **1 643** and neither
@@ -3258,3 +3262,20 @@ where the question is meaningful*, not *of nested records* — quoted bare on bo
sides for two days, including into a shipped doc comment. **A population-scoped
statistic reported without its population is the same shape as a negative reported
without its reach**, and this corpus already had a rule for the second.
### Three rounds, one number, and every disagreement about interpretation
The sequence is worth keeping as a shape. I corrected an argument; they corrected
my denominator; they then corrected their own characterisation of what was in it.
**Every step was checkable in one scan**, and each of us stated an interpretation
confidently while only the number had been measured.
📌 **The numbers never disagreed** — 1 643, 3 311, 1 781, 0 % — through all three
rounds. Every disagreement was about **what they were counting**. That is the
cheaper failure and I suspect the more common one: agreeing figures feel like
agreement, and neither party re-examines a quantity they both accept.
⚠️ Nothing the port depends on moved at any point: `+0x08` matches exactly wherever
the largest time is nonzero, `+0x04` is 0 % under either denominator, and the offset
stands on both scans. **Three rounds of correction over an interpretation that was
never load-bearing** — which is also why it was safe to keep pulling.

View File

@@ -22,27 +22,36 @@ disc-wide (1 781 records, 0 violations).
> a secondary statistic**: `+0x08` equals the largest keyframe time *exactly* in
> half the records and `+0x04` in **none**. No unrelated word reproduces that.
>
> 🔴 **AND MY EXPLANATION OF THE 49.6 % WAS WRONG.** I wrote that my scan "requires
> a timed keyframe", so the population differed. It does not: `.max()` over the
> keyframe times returns `Some(0)` — not `None` — for a record whose keyframes are
> all at time 0, so those never left my denominator. `sylpheed-port` reconciled it
> exactly and I reproduced it:
> 📌 **THE TWO PERCENTAGES ARE TWO POPULATIONS, and neither corrects the other.**
> Settled after three rounds, with every number reproduced from both readers:
>
> ```
> 1643 / 1781 = 92.3 % records where max t > 0 — the question is meaningful
> 1643 / 3311 = 49.6 % plus 1 530 records where max t == 0
> nested RATC records that parse : 3 311
> NO timed keyframe at all : 0
> timed, every pose at t == 0 : 1 530 <- STATIC records
> timed, largest t > 0 : 1 781 <- animated records
> ```
>
> **Same numerator.** The 1 530 extra are records where *"does the word equal the
> largest keyframe time?"* has no content — `max t` is 0, so each counts as
> not-exact **by construction**. 49.6 % is not a weaker 92.3 %; it is 1 643
> successes over a denominator containing 1 530 questions that were never asked.
> ```
> 1643 / 1781 = 92.3 % of ANIMATED records
> 1643 / 3311 = 49.6 % of ALL nested records, static ones included
> ```
>
> ✅ **The conclusion is untouched**: `+0x04` is **0 %** under either denominator,
> so the offset stands on both scans.
> **Same numerator.** Both figures are defensible; they answer different questions,
> and each needs its population attached.
>
> ⚠️ **And 92.3 % needs the qualifier it has never carried here**: it is *of the
> records where the question is meaningful*, not *of nested records*. The consequence for the `PRESS Ⓐ` plate
> 🔴 **Two wrong explanations were given for the gap before this one, and both were
> mine to carry.** First I wrote that my scan "requires a timed keyframe" — it does
> not, because `.max()` returns `Some(0)` rather than `None`. Then, adopting
> `sylpheed-port`'s reconciliation, I wrote that the 1 530 are *"questions never
> asked"* with *"no content"* — **also wrong, and they corrected it themselves**:
> **zero records on this disc lack a timed keyframe.** The 1 530 are **static
> records**, timed with every pose at 0. A static record still declares a cycle
> length, so a nonzero `+0x08` against a largest time of 0 is a **real
> disagreement, not an absent one**.
>
> ⚠️ **92.3 % needs the qualifier it has never carried here**: it is *of animated
> records*, not *of nested records*.
is then tested against the corpus's existing measurements of the running game,
which it passes and the previous reading fails.