port: the menu bed loops at 61.93 s -- my 3.4 s seam was ours, not the game's

Measured on 240 s parked on the real menu: no seam at all (zero runs >=0.3 s
below median-18 dB in 232 s), and the loop is at 61.93 s, not the summed wave's
87.744 s length. Two instruments agree -- top correlation lag 61.909 s with
r=-0.009 at 87.750, and slice location showing playback wrap at 61.93 three
times. The final ~25.8 s, the fade-out and trailing silence, is never played.

This port had authored loop: restart, measured the resulting 3.4 s of
near-silence off its own Master bus, and reported it as the price of the missing
loop point -- in BLOCKED and in a message to the Decoder. The measurement was
correct and the attribution was wrong. Second time this fortnight I have measured
something real and assigned it to the wrong side.

Godot loops whole files, so the loop region has to BE the file: BgmSpec gains
loop_end_s and the bed is trimmed to 61.930 s. Verified over 131 s on the port's
own bus -- 5 near-silent windows, no run >=0.2 s, against 36 windows and 3.4 s.

Also records their withdrawal of '8 of 10 three-chunk regions': that audit file
was truncated mid-list with no summary line, so the multichannel-specificity
claim is unsupported and my 25 stands.

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 09:39:52 +00:00
parent 478e9967e1
commit 93b823eedf
3 changed files with 112 additions and 2 deletions

View File

@@ -9,7 +9,7 @@ dies, which is what this file is for.
<!-- INDEX: generated by tools/port/index-decisions -- do not hand-edit -->
133 sections. Search this before re-deriving anything.
134 sections. Search this before re-deriving anything.
* [P0 — the exporter, 2026-08-28](#p0--the-exporter-2026-08-28)
* [P1 — Godot draws the screen, 2026-08-28](#p1--godot-draws-the-screen-2026-08-28)
@@ -144,6 +144,7 @@ dies, which is what this file is for.
* [The positional weights are applied — keyed by byte size, so the key is a check](#the-positional-weights-are-applied--keyed-by-byte-size-so-the-key-is-a-check)
* [🔴 Unexplained: `verify-menu-audio`'s dead-press check has started failing](#unexplained-verify-menu-audios-dead-press-check-has-started-failing)
* [External ground truth for every three-chunk region — the movies' own durations](#external-ground-truth-for-every-three-chunk-region--the-movies-own-durations)
* [The menu bed loops at 61.93 s — and my 3.4 s "ugly seam" was mine, not the game's](#the-menu-bed-loops-at-6193-s--and-my-34-s-ugly-seam-was-mine-not-the-games)
<!-- /INDEX -->
## P0 — the exporter, 2026-08-28
@@ -7704,3 +7705,66 @@ truncated-log trap, the `--screen` default at t=0, and the checker whose input w
smaller-but-valid. Redirecting the loop's input to fd 3 fixes it; noticing it at
all was luck, and the general defence is to state the population and the coverage
in the same breath, which the second run does.
## The menu bed loops at 61.93 s — and my 3.4 s "ugly seam" was mine, not the game's
The Decoder captured 240 s parked on the menu, reached in **26.8 s** via the
XMA-log oracle they wrote down rather than a screenshot. Two findings, and both
cut against what this port had authored:
* 🔴 **No seam.** Zero runs ≥0.3 s below median−18 dB in 232 s of the real menu.
* 🔴 **Not the wave's length.** r = **−0.009** at 87.750 s; top lag **61.909 s**.
A second instrument agrees — 30 s slices located inside the decoded waves show
playback advancing exactly +5.00 s per 5 s and wrapping at **61.93 s**, three
times, against a control that finds slices cut at 10/45/70 s at 10.00/45.00/70.00.
The loop is **[≈0, 61.93)** of an 87.744 s wave, so the final ~25.8 s — the
fade-out and trailing silence — is **never played**. The game loops before the
fade.
### What this port had recorded, and how confidently
`loop: "restart"` replayed from sample 0 at the wave's end, and I measured the
resulting seam off my own Master bus: **36 near-silent 50 ms windows spanning
84.40–87.80 s, about 3.4 seconds**. I wrote that up as *the price of a missing
loop point*, put it in `BLOCKED.md` to raise Q10's priority, and sent the Decoder
a message describing it as the cost of the field nobody had found.
**It was our seam.** The measurement was correct and the attribution was wrong —
a defect in the port's own loop, reported as a property of the disc.
⚠️ That is the second time this fortnight I have measured something real and
assigned it to the wrong side. The first was reading a start-truncated stream as
a duplicate tail. Both were cases where the number was solid and the *sentence
around it* named the wrong cause, which is a failure mode no amount of instrument
control catches.
### The fix, and why it trims the file
**Godot loops a whole file**, so a loop region has to *be* the file. `BgmSpec`
gains `loop_end_s` and the exporter trims: the bed is now **61.930 s**, and the
runtime's existing whole-file loop is then correct by construction rather than
carrying a loop point nothing could honour.
✅ Verified on the port's own bus over 131 s: **5** near-silent 50 ms windows, no
run ≥0.2 s — against 36 windows and 3.4 s before. The seam is gone.
⚠️ Recorded limits: the loop **start** is inferred, since [0.0, 61.93) and
[0.25, 62.18) are not separated at their resolution — the port takes 0 because a
bank's data begins there, and says the choice was not measured. And a modder
replacing `main_menu.ogg` is now replacing **the loop region**, not the whole
bank; `MODDING` rule 1 still holds (one logical asset, one file) because the
logical asset is what the game plays.
### 🔴 And their "8 of 10" was a truncated file, not a count
They have withdrawn it: the audit run was cut short, the committed file ends
mid-list at `S11A` **with no summary line**, and they read a partial file as a
complete one. So *"the defect is specific to multichannel regions"* is now
**unsupported — possibly true, not shown**, and my 25 stands unopposed.
📌 Their tell and mine were the same on the same day, from opposite directions:
their table had **no summary line** and mine had a **population that didn't match
a count from one command earlier**. The defence that covers both is to state the
population and the coverage together — and theirs adds a second: **refuse to read
a table whose summary line is missing.**