From ee5ed2cfd2a45263b5df2259191e0bcff24075da Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Sun, 30 Aug 2026 15:15:42 +0000 Subject: [PATCH] re: count the in-range fallbacks -- and the control that failed is the answer sylpheed-port pointed out that classifying defaults "by inspection" is exactly the method that cannot see an in-range fallback, and that correction applies to my own sweep from an hour ago: I waved 64 sites through by reading them. Counted instead, disc-wide over 965 builds and 24 811 keyframes: ui_layout.rs:1681 untimed poses (would fabricate t=0): 0 ui_layout.rs:1010 pose_at queries 168 264, None (reads a=0): 0 Two zeroes, which is the result this corpus now distrusts most, so the detector was made to prove it can see a hit: ask pose_at for a time no build declares. The control FAILED -- 10 906 out-of-range queries, 0 None -- so the detector was blind and the :1010 zero measured nothing. The failure is the finding. pose_at is TOTAL: reading the source, its only None path is an `if ks.is_empty() { return None }` guard, and disc-wide there are 0 elements with zero keyframes out of 5 453. So :1010's unwrap_or(0) is unreachable BY CONSTRUCTION, which is stronger than "0 in this corpus" -- and it was established by the control failing rather than by the count passing. Without the control this corpus would have recorded a true conclusion resting on a meaningless number. :1681 stands differently: 0 of 24 811, and time really is Option with the stale reader demonstrably producing None (its screen info prints a trailing -), so the state is representable and a detector would see it. :973 is not a hazard -- guarded two lines later by `if tmax == 0 { return false; }`, where reading is sufficient because the guard is the proof. METHOD gains both: a zero is worth nothing until the detector is shown able to report non-zero; and the habit under several of this week's errors, which is reading a PROXY for the thing when the thing itself is one command away -- a line count for an era, a type name's spelling for its default, an ordinal for an entry, a fallback's text for its firing rate. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v --- .../examples/inrange_fallback_count.rs | 86 +++++++++++++++++++ docs/re/METHOD.md | 22 +++++ docs/re/data/fallback-fabrication-sweep.txt | 32 +++++++ 3 files changed, 140 insertions(+) create mode 100644 crates/sylpheed-formats/examples/inrange_fallback_count.rs diff --git a/crates/sylpheed-formats/examples/inrange_fallback_count.rs b/crates/sylpheed-formats/examples/inrange_fallback_count.rs new file mode 100644 index 00000000..73e902af --- /dev/null +++ b/crates/sylpheed-formats/examples/inrange_fallback_count.rs @@ -0,0 +1,86 @@ +//! Do `ui_layout`'s two IN-RANGE fallbacks ever fire? Counted, disc-wide. +//! +//! An in-range fallback supplies a value that is legitimate, so no output can +//! distinguish it from the real thing and inspection cannot settle it. The only +//! question that has an answer is *how often does it fire*. +//! +//! ui_layout.rs:1681 kf.time.unwrap_or(0) -- 0 is a real keyframe time +//! (pose 0's time IS 0), so a fabricated one is invisible. +//! ui_layout.rs:1010 pose_at(t).map(|k| k.fade >> 24).unwrap_or(0) > 0 +//! -- alpha 0 is legitimate, and it makes "no pose here" +//! read as "fully transparent", biasing an occlusion test +//! toward NOT occluded. +//! +//! (ui_layout.rs:973's `unwrap_or(0)` is NOT counted: it is guarded two lines +//! later by `if tmax == 0 { return false; }`, so 0 is handled, not assumed.) +//! +//! cargo run -p sylpheed-formats --example inrange_fallback_count +use sylpheed_formats::{pak::PakArchive, ui_layout}; +use std::io::Write; +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().is_some_and(|x| x == "pak")).collect(); + paks.sort(); + let (mut kf, mut untimed, mut builds) = (0u64, 0u64, 0u64); + let (mut queries, mut none_at) = (0u64, 0u64); + for pak in &paks { + let Ok(ar) = PakArchive::open(pak) else { continue }; + for e in ar.entries() { + let Ok(by) = ar.read(e) else { continue }; + if !ui_layout::is_build(&by) { continue } + let Some(b) = ui_layout::parse_build(&by) else { continue }; + builds += 1; + // (a) :1681 -- how many poses carry no time? + for el in &b.elements { + for k in &el.keyframes { + kf += 1; + if k.time.is_none() { untimed += 1 } + } + } + // (b) :1010 -- ask every element for a pose at every time that any + // element declares, which is the set the occlusion test draws from. + let mut times: Vec = b.elements.iter() + .flat_map(|e| e.keyframes.iter().filter_map(|k| k.time)).collect(); + times.sort_unstable(); times.dedup(); + for el in &b.elements { + for &t in × { + queries += 1; + if el.pose_at(t).is_none() { none_at += 1 } + } + } + } + print!("."); std::io::stdout().flush().ok(); + } + println!(); + println!("{builds} builds, {kf} keyframes"); + println!(":1681 untimed poses (the fallback would fabricate t=0): {untimed}"); + println!(":1010 pose_at queries {queries}, of which None (fallback reads a=0): {none_at}"); + // NEGATIVE CONTROL. Both counters above report 0, and a zero is the result + // this corpus has learned to distrust most -- it reads clean rather than + // suspicious. So prove the detector CAN see a hit: ask every element for a + // pose at a time no build declares. If pose_at is total, `none_out` is 0 too + // and the 0 above means nothing. + let mut out_queries = 0u64; + let mut none_out = 0u64; + for pak in &paks { + let Ok(ar) = PakArchive::open(pak) else { continue }; + for e in ar.entries() { + let Ok(by) = ar.read(e) else { continue }; + if !ui_layout::is_build(&by) { continue } + let Some(b) = ui_layout::parse_build(&by) else { continue }; + for el in &b.elements { + for &t in &[u32::MAX, 1_000_000u32] { + out_queries += 1; + if el.pose_at(t).is_none() { none_out += 1 } + } + } + } + } + println!("CONTROL pose_at at an undeclared time: {out_queries} queries, {none_out} None"); + println!(" (if this is 0 the detector is blind and the 0 above is meaningless)"); + println!("--- END ---"); +} diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 1145f8d5..5c4fcda7 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.md @@ -309,6 +309,28 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the a literal that could pass for a measurement is the hazard. Build the sweep so it finds a **known** case as its positive control. +* **A zero from a detector is worth nothing until the detector is shown able to + report non-zero — and when that control fails, the failure is often the + answer.** Counting `ui_layout`'s two in-range fallbacks gave 0 and 0. The + negative control — ask `pose_at` for a time no build declares — returned **0 + None across 10 906 queries**, so the detector was blind and one of those zeroes + measured nothing. That failure produced the real result: `pose_at` is **total**, + its only `None` path is an `is_empty()` guard, and disc-wide **0 of 5 453** + elements have zero keyframes — so the fallback is unreachable *by construction*, + which is a stronger statement than "it never fired here". ⚠️ Had the control not + run, this corpus would have recorded a true conclusion supported by a + meaningless number, which is the same defect as + [agreeing by luck](#) and just as invisible. + +* 📌 **The habit under several of these: reading a PROXY for the thing when the + thing itself is one command away.** Inferring a decoder era from a **line + count**; classifying a fallback as harmless by the **spelling** of its type + name; calling a default a sentinel by **reading** it rather than counting how + often it fires; taking a build's identity from an **ordinal** rather than the + entry column. Each time the direct check existed and cost seconds. The tell is + noticing that what you are about to look at merely *correlates* with what you + want to know. + ## Runtime / emulator * **Look at the PNG** — and check its dimensions. diff --git a/docs/re/data/fallback-fabrication-sweep.txt b/docs/re/data/fallback-fabrication-sweep.txt index 68167a68..e2661476 100644 --- a/docs/re/data/fallback-fabrication-sweep.txt +++ b/docs/re/data/fallback-fabrication-sweep.txt @@ -66,3 +66,35 @@ GP_TUTORIAL.pak 2 read 0 FABRICATED # number. Mine is 0, which is a LEGITIMATE keyframe time -- pose 0's time really # is 0 -- so a fabricated one would be indistinguishable from a real one in any # output. An in-range fallback cannot be caught downstream. + +################################################################################ +# COUNTED, not inspected -- 2026-08-30, after sylpheed-port pointed out that +# classifying defaults "by inspection" is exactly the method that cannot see an +# in-range fallback. That correction applies to this file's own first pass: 64 +# sites were waved through as sentinels by reading them. +# instrument: examples/inrange_fallback_count.rs +# +# 965 builds, 24 811 keyframes +# :1681 untimed poses (fallback would fabricate t=0): 0 +# :1010 pose_at queries 168 264, of which None (reads a=0): 0 +# +# ⚠️ Two zeroes, which is the result this corpus distrusts most. So the detector +# was made to prove it can see a hit -- ask pose_at for a time no build declares: +# +# CONTROL 10 906 out-of-range queries, 0 None <-- THE CONTROL FAILED +# +# The detector was BLIND, and the :1010 zero meant nothing. The failure is the +# finding: pose_at is TOTAL. Reading the source, its only None path is an +# `if ks.is_empty() { return None }` guard at line 217 -- and disc-wide there are +# 0 elements with zero keyframes out of 5 453. So :1010's unwrap_or(0) is +# unreachable by CONSTRUCTION, which is stronger than "0 in this corpus", and it +# was established by the control failing rather than by the count passing. +# +# :1681 stands on a different footing: 0 of 24 811, and `time` really is +# Option, with the STALE reader demonstrably producing None (its `screen +# info` prints a trailing `-`). So the state is representable and a detector +# would see it; the corrected reader simply never produces one. +# +# :973's unwrap_or(0) is NOT a hazard: it is guarded two lines later by +# `if tmax == 0 { return false; }`. Read, not counted, and that is sufficient +# because the guard is the proof.