From c89e4da723f1148b447426e03a73625e5763a249 Mon Sep 17 00:00:00 2001 From: sylph-decoder Date: Sun, 30 Aug 2026 12:13:46 +0000 Subject: [PATCH] re: my own 1697 audited -- and the first correction failed its control Applying the port's physical-story rule to my own number. '1 697 fallback fires return a visible pose' was published as if it were a defect count; it is not, since an element that genuinely ends visible should rest visible. The first correction split the 1 697 by whether the element's LAST keyframe is visible: 347 correct, 1 350 transient peaks. Plausible, arithmetic fine, and WRONG -- 12 278 of 13 991 elements (87.8 %) end at alpha 0 because a screen's exit ramp drives everything to zero, so the split carries almost no information. The 1 350 is not published. What survives needs no such split: the fallback runs only when no two adjacent poses are equal, i.e. only when no pose is held, so every pose it can return is un-held by construction -- and 1 457 of the 2 305 times it returns the element's MAXIMUM alpha, the brightest un-held pose. I ran that control only because the port had just been bitten by the same exit ramp, its census calling ptmsg -- the main menu's permanent footer -- 'a 2-unit flash'. Without its message the 1 350 would have shipped. METHOD gains the sharpened form: the physical-story test catches confident FALSE claims, not just nulls. A wrong number usually still has a story, just an absurd one. Plus the tell that its fix was right -- re-keyed on the screen's span, the false positives fell out on their own, and a definition that stops needing hand-maintained exceptions is usually the correct one. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v --- .../examples/rest_fallback_audit.rs | 68 +++++++++++++++++++ docs/re/METHOD.md | 27 ++++++++ docs/re/data/rest-fallback-audit.txt | 46 +++++++++++++ docs/re/structures/ui-resting-pose.md | 19 +++++- 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 crates/sylpheed-formats/examples/rest_fallback_audit.rs create mode 100644 docs/re/data/rest-fallback-audit.txt diff --git a/crates/sylpheed-formats/examples/rest_fallback_audit.rs b/crates/sylpheed-formats/examples/rest_fallback_audit.rs new file mode 100644 index 00000000..0ad06138 --- /dev/null +++ b/crates/sylpheed-formats/examples/rest_fallback_audit.rs @@ -0,0 +1,68 @@ +//! Does "1 697 fallback fires return a visible pose" survive being said out loud? +//! +//! `rest-fallback-census.txt` reports that of 2 305 elements where the dwell +//! fallback decides, 1 697 rest at `alpha > 0`. It was written as if that number +//! were the defect. **It is only a defect where the element is a transient.** An +//! element that genuinely ends visible and stays visible SHOULD rest visible, and +//! the fallback happening to be the path that got there is not an error. +//! +//! The port agent hit the mirror image of this: it counted a screen's own exit +//! ramp as the end of an element's visibility, so `ptmsg` — the main menu's +//! permanent footer — came out as "a 2-unit flash". The story collapsed when +//! said aloud. This asks the same question of my number. +//! +//! Split the 1 697 by what the element's LAST keyframe does: +//! * last alpha > 0 -> the element ends visible; resting visible is right +//! * last alpha == 0 -> it fades out; a visible rest is a transient's peak +//! +//! cargo run -p sylpheed-formats --example rest_fallback_audit +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().is_some_and(|x| x == "pak")).collect(); + paks.sort(); + let (mut fires, mut vis, mut ends_visible, mut ends_zero, mut at_peak) = (0, 0, 0, 0, 0); + // ⚠️ The port agent's exit-ramp finding applies to THIS split too: if a + // screen's exit ramp drives every element to a=0, then "last keyframe a=0" + // says nothing about the element being a transient. Measure it on ALL + // elements before using it on the 1 697. + let (mut all_el, mut all_end_zero) = (0usize, 0usize); + 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 }; + let Some(b) = ui_layout::parse_build(&by) else { continue }; + for el in &b.elements { + if el.keyframes.len() < 2 { continue } + all_el += 1; + if (el.keyframes.last().unwrap().fade >> 24) & 0xff == 0 { all_end_zero += 1 } + if el.keyframes.windows(2).any(|w| w[0].x == w[1].x && w[0].y == w[1].y + && w[0].scale_x == w[1].scale_x && w[0].scale_y == w[1].scale_y + && w[0].fade == w[1].fade) { continue } + fires += 1; + let Some(r) = el.rest() else { continue }; + let a = (r.fade >> 24) & 0xff; + if a == 0 { continue } + vis += 1; + let last = (el.keyframes.last().unwrap().fade >> 24) & 0xff; + if last > 0 { ends_visible += 1 } else { ends_zero += 1 } + let peak = el.keyframes.iter().map(|k| (k.fade >> 24) & 0xff).max().unwrap_or(0); + if a == peak { at_peak += 1 } + } + } + } + println!("fallback fires {fires}"); + println!(" of those, rest alpha > 0 {vis}"); + println!(" element's LAST keyframe alpha > 0 {ends_visible} <- ends visible; resting visible is CORRECT"); + println!(" element's LAST keyframe alpha = 0 {ends_zero} <- fades out; a visible rest is a transient's peak"); + println!(" rest alpha == the element's MAX {at_peak}"); + println!("\nCONTROL on the split itself — is 'ends at a=0' near-universal?"); + println!(" all elements with >= 2 keyframes {all_el}"); + println!(" of those, last keyframe alpha = 0 {all_end_zero} ({:.1} %)", + 100.0 * all_end_zero as f64 / all_el as f64); + println!("\n--- END (if this line is missing, the run did not finish) ---"); +} diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 3f7d8a10..225611af 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.md @@ -1584,3 +1584,30 @@ stories collapse the moment they are told out loud. **And a control does not test this.** A control proves the **instrument**; it says nothing about the **sample**. Neither of us has a habit that catches a well-measured number taken from the wrong thing — this is the closest either has got. + +### The physical-story test catches confident FALSE claims, not just nulls + +Sharpened by the port agent after the rule's first *prospective* catch. Its census +returned "28 elements across 12 screens", arithmetic correct, no control it would +have failed — and the list contained `ptmsg`, the main menu's own +`⊙ Select Ⓐ OK` footer, as **"visible 2 of 64 units"**, plus `ptbtn00`, the plate. +Both sit on screen the whole time the game does. + +**Nothing else pointed at it.** The story collapsed the moment it was said aloud. +The cause was that a screen's **exit ramp** drives every element to `a = 0`, so +counting the exit as the end of visibility made every normal element look like a +flash. + +⚠️ So the net is wider than *null-as-result*: **a wrong number usually still has a +story, just an absurd one.** "The footer is a 2-unit flash" is not a null — it is a +confident false claim, and the same test catches it as catches *"no element ends on +an alpha ramp"*. + +📌 And the fix has the tell of a right definition: re-keyed on the **screen's** span +rather than the element's, `ptmsg` and `ptbtn00` fell out **on their own**. A +definition that stops needing hand-maintained exceptions is usually the correct one. + +**It caught one of mine within the hour.** I split a census by whether an element's +last keyframe is visible; 87.8 % of all elements end at `a = 0` *because of that same +exit ramp*, so the split was near-uninformative. I ran that control only because the +port had just been bitten by it. diff --git a/docs/re/data/rest-fallback-audit.txt b/docs/re/data/rest-fallback-audit.txt new file mode 100644 index 00000000..b24fb698 --- /dev/null +++ b/docs/re/data/rest-fallback-audit.txt @@ -0,0 +1,46 @@ +# Auditing my OWN 1 697 with the port's rule -- and the first correction failed +# its own control. 2026-08-30. +# +fallback fires 2305 + of those, rest alpha > 0 1697 + element's LAST keyframe alpha > 0 347 <- ends visible; resting visible is CORRECT + element's LAST keyframe alpha = 0 1350 <- fades out; a visible rest is a transient's peak + rest alpha == the element's MAX 1457 + +CONTROL on the split itself — is 'ends at a=0' near-universal? + all elements with >= 2 keyframes 13991 + of those, last keyframe alpha = 0 12278 (87.8 %) + +--- END (if this line is missing, the run did not finish) --- +# +# THE STORY, SAID OUT LOUD: +# +# 1. '1 697 fallback fires return a visible pose' was published as if the +# number were a defect count. It is not. An element that genuinely ends +# visible and stays visible SHOULD rest visible; the fallback being the +# path that got there is not an error. +# +# 2. FIRST CORRECTION, and it looked clean: split by whether the element's +# LAST keyframe is visible. 347 end visible (correct), 1 350 fade out +# (a transient's peak). Plausible, arithmetic fine. +# +# 3. 🔴 IT FAILED ITS CONTROL. The port agent had just found that a SCREEN's +# exit ramp drives every element to a=0 at the end -- which is why its own +# census called ptmsg, the permanent footer, 'a 2-unit flash'. Measured +# here: 12 278 of 13 991 elements (87.8 %) end at alpha 0. So 'ends at +# a=0' is near-universal and says almost nothing about being a transient. +# The 1 350 is not a transient count and is NOT published as one. +# +# 4. ✅ WHAT SURVIVES, and it needs no such split: +# +# 2 305 elements where the dwell fallback decides +# 1 457 of those rest at the element's MAXIMUM alpha +# +# The fallback runs only when NO two adjacent poses are equal -- i.e. +# only when no pose is held. So every pose it can return is un-held by +# construction, and 1 457 times it returns the BRIGHTEST un-held pose. +# That is the defect shape, stated without needing to know where the +# element's visibility ends. +# +# I ran the control only because the port had just been bitten by the exit +# ramp. Without that message the 1 350 would have shipped. diff --git a/docs/re/structures/ui-resting-pose.md b/docs/re/structures/ui-resting-pose.md index b103a570..5aee44a2 100644 --- a/docs/re/structures/ui-resting-pose.md +++ b/docs/re/structures/ui-resting-pose.md @@ -328,7 +328,24 @@ Disc-wide ([`../data/rest-fallback-census.txt`](../data/rest-fallback-census.txt | elements with ≥ 2 keyframes | 13 991 | | have a plateau — the fallback never runs | 11 686 | | **have none — the fallback decides** | **2 305** | -| **of those, it returns a VISIBLE pose** | **1 697 (74 %)** | +| of those, it returns a visible pose | 1 697 (74 %) | +| **of those, it returns the element's MAXIMUM alpha** | **1 457** | + +⚠️ **"1 697" is not a defect count and this page briefly implied it was.** An element +that genuinely ends visible *should* rest visible. **The number that survives is +1 457**: the fallback runs only when no two adjacent poses are equal — i.e. only when +**no pose is held** — so every pose it can return is un-held by construction, and +1 457 times it hands back the *brightest* one. + +🔴 **A first attempt to correct this failed its own control**, and is recorded +because the failure is instructive +([`../data/rest-fallback-audit.txt`](../data/rest-fallback-audit.txt)). Splitting the +1 697 by whether the element's **last** keyframe is visible gave 347 / 1 350 — plausible, +arithmetic sound. But **12 278 of 13 991 elements (87.8 %) end at alpha 0**, because a +screen's *exit ramp* drives everything to zero. The split carries almost no +information. The port agent had been bitten by exactly this an hour earlier — its +census called `ptmsg`, the main menu's permanent footer, "a 2-unit flash" — and I ran +the control only because it said so. **`GP_TITLE`: 5 fires, 4 visible** — and all four are on the **splash screens**, `palogo_sqex_eff.t32` / `palogo_anima_eff.t32` on entries 10/11/13/14. Each reads