port: the runtime now says what the voice export is missing, at the moment it plays it

The manifest has carried the gap for weeks and the runtime printed '+ voice ADV'
and nothing else. A reader of manifest.json gets a paragraph; a person LISTENING
gets clean dialogue and no way to learn a stream is absent. NEW GAME already
announces the screens it jumps over; audio had no equivalent.

ManifestAudio gains  -- one line naming what is KNOWN missing, absent
meaning nothing is known rather than nothing is wrong -- and MenuAudio carries it
so _play_video can print it. Verified on the boot's ADV and P7's S00A.

The first version of the message was FALSE for one of the two assets: it said
'one is a start-truncated stream', which is ADV's story, where S00A's dropped
chunks are digitally silent. Caught by reading the output for both, which I
nearly skipped because the ADV line was obviously right. Now states the counts
and points at the entry's why.

A message generated once from a template but true only for the case it was
written against is harder to see than a wrong number -- the sentence is
well-formed and confident in both places.

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 08:49:25 +00:00
parent 507155422b
commit 64b76b0892
4 changed files with 90 additions and 1 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 -->
128 sections. Search this before re-deriving anything.
129 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)
@@ -139,6 +139,7 @@ dies, which is what this file is for.
* [The voice export now carries every qualifying stream — and a unity sum was refused by our own check](#the-voice-export-now-carries-every-qualifying-stream--and-a-unity-sum-was-refused-by-our-own-check)
* [Their stream assignment does not fit my region — weights NOT applied](#their-stream-assignment-does-not-fit-my-region--weights-not-applied)
* [The resolver starts late, and my "duplicate tail" was a real stream all along](#the-resolver-starts-late-and-my-duplicate-tail-was-a-real-stream-all-along)
* [The export knew the voice was incomplete; the runtime did not say so](#the-export-knew-the-voice-was-incomplete-the-runtime-did-not-say-so)
<!-- /INDEX -->
## P0 — the exporter, 2026-08-28
@@ -7498,3 +7499,46 @@ not have:
✅ The assignment itself still stands — their ratio test was chosen to be immune to
the clipping — but ⚠️ chunk 0's absolute level was measured over 62 % of its
stream, so its 0.05 dB agreement is luckier than it reads.
## The export knew the voice was incomplete; the runtime did not say so
The manifest has carried a full account of the voice export's gap for weeks, and
the runtime printed `+ voice ADV` and nothing else. That asymmetry is the
dangerous one for audio specifically: a reader of `manifest.json` gets a
paragraph, and a person **listening** gets clean dialogue with no way to learn
that a stream is absent from it.
This port already governs the same situation elsewhere — NEW GAME announces the
two measured screens it jumps over rather than skipping them silently. Audio had
no equivalent, so:
* `ManifestAudio` gains **`incomplete`**, one line naming what an asset is *known*
to be missing. Absent means nothing is known to be missing — **never** that the
asset was checked and found complete.
* `MenuAudio` carries it alongside the stream, and `_play_video` prints it at the
moment the voice starts.
```
+ voice ADV
🔴 KNOWN INCOMPLETE: 2 of 3 streams. The running game decodes all 3 …
```
Verified on both paths — the boot's `ADV` and P7's `S00A`.
### 🔴 And the first version of the message was false for one of the two assets
It read *"one is a start-truncated stream this export drops"*. That is `ADV`'s
story: its dropped chunk is the start-clipped remainder of ctx0. **`S00A`'s
dropped chunks are digitally silent** — a different reason entirely — and the
message would have told anyone running the new-game intro something untrue about
their own asset.
Caught by reading the output for both, which took one command and which I nearly
skipped because the `ADV` line was obviously correct. The wording now states the
counts and points at the entry's `why`, because **which streams are dropped and
why is not the same story twice** and a single sentence cannot carry both.
⚠️ Worth naming as its own shape: a message generated *once* from a template but
*true* only for the case it was written against. It is the failure mode of every
generic warning, and it is harder to see than a wrong number because the sentence
is well-formed and confident in both places.