re: the port was still being told SE audio is undecodable -- it is not

A resolve-check on HANDOFF's own rows. Q8 read "SE audio is undecodable
from the disc -- no XACT container exists anywhere". menu-audio-cues.md
retracted exactly that ("### Retracting 'cannot be extracted'") and
locates three cues in Static.slb that decode to PCM: d-pad move 0x1ec0
(4 packets), (B) back 0x0ec0 (2), (A) confirm 0x5d6c0 (6), all mono
48 kHz. The retraction landed in docs/re/ and the page the port reads
kept the superseded text -- the fourth time in this corpus.

Writing the rule down has not worked, so there is a tool now.
handoff_lint.py flags every HANDOFF line making a strong negative claim
that links a doc containing retraction language. First run: found the Q8
row, plus one benign false positive (Q3 links a doc whose retraction is
about a sprite count, not about the tie-break -- checked, and HANDOFF
repeats none of the retracted figures). The lint also caught its own bug
first: it reported existing docs as missing because it joined a guessed
repo root, so it now resolves links relative to the file as markdown does.

Separately, EXTRAS's paint-order risk narrows twice more. Of its 15 tied
pairs only 2 overlap, and of those, ptloop01 x ptloop02 are loop*
animations compose skips by default -- so exactly ONE tie can be drawn:
ptframe3 x ptframe4, overlapping 102x132 px. Against live-extras.png that
contested region correlates +0.9622, better than the whole frame (+0.9440)
and inside the range of regions where order cannot matter (+0.8502 /
+0.9903). Consistent with our order, not proof: correlation cannot see a
swap between locally similar art.

15 -> 2 -> 1 -> consistent is now the whole paint-order risk on the five
screens, and HANDOFF says so.
This commit is contained in:
Sylpheed RE agent
2026-08-29 02:31:37 +00:00
parent 9ff9e8e633
commit 3eba09aae0
6 changed files with 138 additions and 5 deletions

View File

@@ -83,6 +83,20 @@ fn main() {
let Some((label, want)) = measured(&names) else {
println!("entry {i:2} (no measured order) {} elements, {tie_pairs} tied pairs, \
{tie_overlap} of them OVERLAPPING", build.elements.len());
// Name them: these are the only pairs whose order can show.
for a in 0..keys_all.len() {
for b in (a + 1)..keys_all.len() {
if keys_all[a] != keys_all[b] || keys_all[a] == u32::MAX { continue; }
let (Some(ra), Some(rb)) = (rect(&build.elements[a]), rect(&build.elements[b]))
else { continue };
let ox = (ra.0 + ra.2).min(rb.0 + rb.2) - ra.0.max(rb.0);
let oy = (ra.1 + ra.3).min(rb.1 + rb.3) - ra.1.max(rb.1);
if ox > 0 && oy > 0 {
println!(" overlapping tie: [{a}] {} x [{b}] {} key {} rect {:?} / {:?} overlap {}x{}",
build.elements[a].name, build.elements[b].name, keys_all[a], ra, rb, ox, oy);
}
}
}
continue;
};
checked += 1;