port: take formats-pin-2026-08-30b and stop owning the +0x08 read

The tag was cut within the iteration, so screen.rs now calls
ui_layout::loop_length_units and its local RATC guard and byte read are deleted.
One line, as predicted -- and the doc comment promising that deletion is the only
reason a temporary reading did not quietly become permanent.

A pin bump moves the whole crate, not one function, and this pin is recorded
load-bearing, so both commits between the tags were read before taking it:
b5df02a adds the public function, d020845 is comment-only -- two 'fixed code
under an unfixed description' corrections. No behavioural change in either, and
the oracle RMSEs confirm it: main_menu 13.21, extras 13.38, title 14.16, all
identical across the bump.

d020845 is worth noting for what it is. The rest override's comment still claimed
it tested the shifted time reading that the record-layout fix had refuted, and a
continue branch was documented with the pre-fix rule. Both are the same failure
this port hit in spin_period_units: a doc comment describing the rule the body no
longer implements. Three instances now, across two agents and two languages.

examples/record_loop_control.rs deliberately did NOT follow the API. The moment a
control calls the thing it exists to check it stops being a control and becomes
the API tested against itself; the falsifier means something only because the
reading is independent. Re-run at the new pin, unchanged. So the port holds one
copy of this reading instead of two, and it is the copy whose job is to disagree.

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-30 21:27:54 +00:00
parent f7fee7a77f
commit edd5af5be5
5 changed files with 57 additions and 27 deletions

View File

@@ -108,18 +108,6 @@ pub struct FocusElement {
pub keyframes: Vec<Keyframe>,
}
/// A nested record's declared cycle length, or `None` if the span is not one.
///
/// Guarded rather than trusted: the magic is checked and the header must fit,
/// because an offset that has drifted returns a plausible number otherwise.
fn record_loop_units(bundle: &[u8], off: usize, size: usize) -> Option<u32> {
let span = bundle.get(off..off.checked_add(size)?)?;
if span.len() < 12 || &span[..4] != b"RATC" {
return None;
}
Some(u32::from_be_bytes(span[8..12].try_into().ok()?))
}
#[derive(Serialize)]
pub struct Focus {
/// The `.rat` leaf this came from, e.g. `ptbtn01f.rat`.
@@ -140,11 +128,12 @@ pub struct Focus {
/// their own last pose**; on the eight records this port animates, seven
/// exact and `ptbtn00f` the one hold.
///
/// ⚠️ Read here rather than through `sylpheed_formats` because the field is
/// exposed in **no public API on any ref** — it lives in an example and a
/// test. `parse_build` publishes each record's `(offset, size)`, so this is
/// four big-endian bytes at a documented offset inside a span whose magic is
/// checked, not a second decoder. **Delete it the day the crate exposes it.**
/// ✅ **The port no longer owns this reading.** For one iteration `screen.rs`
/// held its own guard and byte read, because the field was decoded in an
/// example and a test and exposed in no public API on any ref. It is now
/// `ui_layout::loop_length_units`, taken at `formats-pin-2026-08-30b`, and
/// the local copy is deleted — the doc comment that promised that deletion
/// is the only reason it did not quietly become permanent.
pub loop_length_units: Option<u32>,
/// Back-to-front, in the leaf's own declaration order.
pub elements: Vec<FocusElement>,
@@ -489,7 +478,7 @@ pub fn export_build(
} else {
Some(Focus {
record: rec.to_string(),
loop_length_units: record_loop_units(bundle, off, size),
loop_length_units: ui_layout::loop_length_units(&bundle[off..off + size]),
elements: fes,
})
})
@@ -550,7 +539,7 @@ pub fn export_build(
if !fes.is_empty() {
focus = Some(Focus {
record: rec,
loop_length_units: record_loop_units(bundle, off, size),
loop_length_units: ui_layout::loop_length_units(&bundle[off..off + size]),
elements: fes,
});
}