port: my falsifier never identified the offset -- the half I called a formality did

Their struct-layout control found that a homogeneous repeated table type-checks at
every field boundary, so an interior test carries no information about phase: 69
of 70 records passed under both shifted alignments. Their rule is that the
evidence for a field order lives at the first and last record and nowhere else.

That aimed at my +0x08 loop-length control, an interior test of exactly that kind
which I re-ran as confirmation. Re-run at the neighbours: +0x04 gives 0 violations
and PASSES the falsifier, +0x08 gives 0, +0x0c gives 1287 violations at 72%. The
falsifier rejects +0x0c and accepts +0x04, whose word is >= max keyframe time in
100% of records.

So the falsifier does not identify +0x08. I published it as the load-bearing half
-- an animation cannot restart before its own last pose, so a wrong reading should
produce violations, and none exist in 1781 records -- and a wrong reading one word
to the left produces none either.

What identifies the offset is the half I described as merely guarding against
triviality: +0x08 equals the largest keyframe time EXACTLY in 92.3% of records and
+0x04 does so in 0%. No unrelated word reproduces that coincidence.

The value is right and my argument for it was wrong. Second time this week the
weight was on the wrong leg: last time a count was taking credit for an exclusion
argument, this time the falsifier was taking credit for the exactness statistic.
Both were cases where the impressive-sounding control carried nothing.

Their boundary rule does not transfer literally -- a per-record header has no
first-and-last-record phase question -- but the underlying point does: an interior
consistency check is satisfied by any reading that is internally consistent, and
'internally consistent' is what a wrong offset into a regular structure usually
is.

Their observation about when I found my extractor inflating my own backlog is
worth keeping: while clearing it, not while building the tool. Clearing put me in
contact with the individual items; building had only put me in contact with the
rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
Sylpheed port agent
2026-08-31 03:49:49 +00:00
parent 6cdffd8f77
commit b0bb57c0e6
2 changed files with 67 additions and 3 deletions

View File

@@ -37,7 +37,17 @@ const SHIPPED: &[&str] = &[
"ptloop01", "ptloop02",
];
/// Which header word to read as the loop length. `0x08` is the decoded one;
/// `--offset=N` re-runs the same falsifier at a neighbour, which is the only way
/// to learn whether the falsifier is evidence for the offset or just for the
/// disc.
static mut OFFSET: usize = 8;
fn main() {
let off: usize = std::env::args().find_map(|a| a.strip_prefix("--offset=")
.and_then(|v| v.parse().ok())).unwrap_or(8);
unsafe { OFFSET = off };
println!(" reading the loop length at header +0x{off:02x}");
let root = std::env::var("SYLPHEED_DISC").unwrap_or_else(|_| "/disc".into());
let mut paks: Vec<_> = std::fs::read_dir(format!("{root}/dat")).expect("dat/")
.flatten().map(|e| e.path())
@@ -55,9 +65,18 @@ fn main() {
if !ratc::is_ratc(&by) { continue }
let Some(b) = ui_layout::parse_build(&by) else { continue };
for (rn, &(o, s)) in &b.records {
if o + 12 > by.len() || o + s > by.len() { continue }
if o + off + 4 > by.len() || o + s > by.len() { continue }
if &by[o..o + 4] != b"RATC" { continue }
let len = u32::from_be_bytes(by[o + 8..o + 12].try_into().unwrap()) as i64;
// 🔴 THE FALSIFIER IS RUN AT NEIGHBOURING OFFSETS TOO. The
// Decoder's struct-layout control showed that a homogeneous
// repeated table type-checks at every field boundary, so an
// interior test carries no information about phase -- 69 of 70
// records passed under BOTH shifted alignments of their dialog
// table. My falsifier (`+0x08 >= max keyframe time`) is an
// interior test of exactly that kind, and I re-ran it as
// "confirmation" without asking whether it discriminates the
// OFFSET or merely the file.
let len = u32::from_be_bytes(by[o + off..o + off + 4].try_into().unwrap()) as i64;
let Some(lb) = ui_layout::parse_build(&by[o..o + s]) else { continue };
let maxt = lb.elements.iter()
.flat_map(|el| el.keyframes.iter().filter_map(|k| k.time))