diff --git a/crates/sylpheed-export/examples/record_population.rs b/crates/sylpheed-export/examples/record_population.rs index 920570d9..e186b7db 100644 --- a/crates/sylpheed-export/examples/record_population.rs +++ b/crates/sylpheed-export/examples/record_population.rs @@ -17,6 +17,7 @@ fn main() { .filter(|p| p.extension().and_then(|s| s.to_str()) == Some("pak")).collect(); paks.sort(); let (mut records, mut in_bounds, mut magic, mut parsed, mut timed) = (0, 0, 0, 0, 0); + let (mut untimed, mut all_at_zero) = (0usize, 0usize); for p in &paks { let Ok(ar) = pak::PakArchive::open(p) else { continue }; for e in ar.entries() { @@ -34,7 +35,20 @@ fn main() { let maxt = lb.elements.iter() .flat_map(|el| el.keyframes.iter().filter_map(|k| k.time)) .max().unwrap_or(0); - if maxt == 0 { continue } + // 🔴 `maxt == 0` merges two different populations, and the + // Decoder's cause -- `.max()` returning `Some(0)` -- is only one + // of them. A record with NO timed keyframe has no largest + // keyframe time; a record whose keyframes all sit at t=0 has + // one, and it is 0. Only the first is a question without + // content. Both of us called all 1 530 "the question has no + // meaning"; that is true of one group and an assumption about + // the other. + let any_timed = lb.elements.iter() + .any(|el| el.keyframes.iter().any(|k| k.time.is_some())); + if maxt == 0 { + if any_timed { all_at_zero += 1 } else { untimed += 1 } + continue; + } timed += 1; } } @@ -44,5 +58,8 @@ fn main() { println!(" carrying the RATC magic : {magic} <- {} dropped here", in_bounds - magic); println!(" parsing as a nested build : {parsed}"); - println!(" with at least one timed keyframe: {timed}"); + println!(" with a largest keyframe time > 0: {timed}"); + println!(" of the {} excluded:", untimed + all_at_zero); + println!(" NO timed keyframe at all : {untimed} <- the question has no content"); + println!(" timed, but every pose at t=0 : {all_at_zero} <- a largest time EXISTS, and it is 0"); } diff --git a/docs/port/DECISIONS.md b/docs/port/DECISIONS.md index 4250631b..ecd3ae72 100644 --- a/docs/port/DECISIONS.md +++ b/docs/port/DECISIONS.md @@ -9,7 +9,7 @@ dies, which is what this file is for. -309 sections. Search this before re-deriving anything. +310 sections. Search this before re-deriving anything. * [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28) * [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28) @@ -320,6 +320,7 @@ dies, which is what this file is for. * [🔴 Their record layout was wrong and I had copied it — fourth relayed aside](#their-record-layout-was-wrong-and-i-had-copied-it--fourth-relayed-aside) * [🔴 My falsifier never identified the offset — the half I called a formality did](#my-falsifier-never-identified-the-offset--the-half-i-called-a-formality-did) * [The 92.3 %-versus-49.6 % gap: same numerator, and their filter is not applied](#the-923--versus-496--gap-same-numerator-and-their-filter-is-not-applied) +* [🔴 Correcting my own correction: none of the 1 530 is a question without content](#correcting-my-own-correction-none-of-the-1-530-is-a-question-without-content) ## P0 — the exporter, 2026-08-28 @@ -15258,3 +15259,46 @@ is the same shape as a negative reported without its reach. — neither of us was wrong about the disc. That is a cheaper failure than the offset one and a more common one: **the numerator agreed to the unit, which is exactly what makes a denominator mismatch invisible.** + +## 🔴 Correcting my own correction: none of the 1 530 is a question without content + +I told them their denominator held *"1 530 questions that were never asked"* — +records with no timed keyframe, where *"does `+0x08` equal the largest keyframe +time?"* has no meaning. **I did not check that, and it is wrong.** + +| of the 1 530 excluded | | +|---|---| +| **no timed keyframe at all** | **0** | +| **timed, every pose at t = 0** | **1 530** | + +**Every one of them has a largest keyframe time. It is 0.** So the question is +well-formed there, and the answer is *"not exact"* — because a **static record +still declares a cycle length**, and a nonzero `+0x08` against a largest time of 0 +is a real disagreement, not an absent one. + +📌 **Which makes their 49.6 % defensible rather than mistaken.** Two statistics +over two populations: + +* **92.3 %** — of records whose largest keyframe time is **> 0**. +* **49.6 %** — of **all** nested records, static ones included. + +**Neither is the corrected version of the other.** I framed mine as the correct +one and theirs as an artefact; the truthful statement is that they answer +different questions and **both need their population attached** — which was my own +point one message earlier, applied to their number and not to my reading of it. + +⚠️ Their cause diagnosis is still right about the **mechanism** — `.max()` returns +`Some(0)` rather than `None` — but *"records with no timed keyframe"* describes +**zero records on this disc**. The mechanism they found is real and the population +they attributed it to does not exist. + +📌 **Third-order, and worth naming as such:** they corrected an argument, I +corrected their denominator, and this corrects my characterisation of what was in +it. Each step was checkable in one scan, and each of us stated the *interpretation* +confidently while only the *number* had been measured. **The numbers have agreed +throughout; every disagreement has been about what they were counting.** + +✅ What survives untouched, and is the only part the port depends on: `+0x08` +equals the largest keyframe time exactly where that time is nonzero, `+0x04` does +so **0 %** of the time under either denominator, and the offset identification +stands on both scans.