Repository navigation
music-video's final mix comes back at +3.26 dBFS with no peak warning: Music 3 is already over and pairing adds ~2 dB more #158
Description
tool: run_workflow (templates/minimax/music-video, its music_video / pair_audio stage), observed via get_gallery_metadata
What happens
The music-video deliverable comes back with a positive peak_dbfs — i.e. over full scale — and nothing in job.warnings mentions it. The job warns about a 6.4 dB level jump between the two shots, which is the lesser problem, while the louder one goes unreported.
Repro (workspace qa-verify, job 85b1ff7fe7e8, run 20260914-151609-bb8ca560)
templates/minimax/music-video with a two-entry shots list, audio_duration: 30, a supplied singer_reference, custom song_prompt/song_lyrics. Then get_gallery_metadata on each stage's output:
| stage | file | peak_dbfs |
mean_dbfs |
|---|---|---|---|
write_song (Music 3) |
...write_song.0-0.0.mp3 |
+1.34 | -19.82 |
shot@accusation (H3) |
...shot@accusation.3-0.0.mp4 |
-0.44 | -23.17 |
shot@verdict (H3) |
...shot@verdict.4-0.0.mp4 |
+0.34 | -16.93 |
music_video (final) |
...music_video.6-0.0.mp4 |
+3.26 | -21.82 |
job.warnings for the run:
"edit: concat_videos: the tracks being joined span 6.4 dB (rms -23.1 to -16.7 dBFS) - the cut
will be audible as a level jump. Pass match_levels to even them out"
That is the only level-related warning. Nothing about the peak.
Expected
A deliverable at or below 0 dBFS, or — if the mix legitimately can't be guaranteed — a warning naming the peak, in the same channel and with the same specificity as the existing match_levels one.
Actual
+3.26 dBFS on the final, reported as a clean succeeded.
Reading of it
Two things seem to be stacking, and I can only see the numbers, not the mixer:
- Music 3's own output is already over at +1.34 dBFS before anything is combined. So the source isn't leaving headroom to begin with.
- The pairing stage adds roughly 2 dB more on top of the shots' own audio, landing at +3.26. The shots themselves are fine (-0.44 and +0.34, i.e. essentially at the ceiling but not beyond it).
A caveat I want to be honest about: I'm reading peak_dbfs out of the metadata block, not the samples. Decoded lossy audio can legitimately overshoot 0 dBFS on intersample peaks without the encode having clipped, so a small positive figure isn't automatically distortion. +3.26 dB is a lot more than codec overshoot usually accounts for, and the monotonic climb across the stages points at summing without headroom rather than a measurement artefact — but I can't listen to the file, so I can't confirm audible distortion. If the mixer already normalises and this is purely an intersample reading, that is a fine answer and the issue becomes "the metadata is misleading" instead.
Why it's worth raising either way
This failure is invisible to exactly the consumer this server is built for. get_gallery_metadata's own next hint teaches the checks an agent that cannot listen should make — it names mean_dbfs below -40 as the near-silent case, but says nothing about the other end of the range. A clipped deliverable is the symmetric failure and there's currently no guidance and no warning for it, so an agent following the documented advice passes it.
The existing concat_videos warning shows the machinery and the judgement are already there — it computes RMS across tracks and tells the caller which argument fixes it. A peak check would be the same shape.
Suggestions, in order of how much I'd argue for them
- Warn when a final deliverable's peak is >= 0 dBFS, naming the figure and the stage. Cheapest, and it makes the failure visible without changing any behaviour.
- Add the ceiling to
get_gallery_metadata'snexthint, so the check is documented for agents that only read metadata — symmetric with the-40advice already there. - Leave headroom when summing in
pair_audio, or expose anormalize_audio/target-peak knob onmusic-videothe waymatch_levelsis exposed. This is a behaviour change and the biggest ask of the three; I'd rather have (1) than guess at the right mix policy.
Note
Not a regression — I have no evidence this ever behaved differently, and the two-shot music-video runs in the suite (M-F006) assert duration and frame count, never level. Found while running TESTER_TASK.md (episode 14). Reported by model opus via the anthropic provider, consumer-only session.
Activity
fix: #154 #155 #157 #158 - the plan quotes this box's history, an H3 …
Merge fixes for #154 #155 #157 #158 - observed cost in the plan, the …
dkackman commentedon Sep 14, 2026
Fixed in c0435d2 (branch
fixes/2026-09-14c, merged todevelop), deployed tolem. I did your (1) and (2) and deliberately left (3).First, one correction to the reading.
pair_audiodoes not sum - it replaces the video's soundtrack with the track it is given (dw/tasks/pair_audio.py), so the final file's audio is Music 3's song and nothing else. The +1.34 -> +3.26 climb is not 2 dB of mixing; it is the same over-full-scale waveform decoded through two different lossy codecs (mp3 forwrite_song, AAC in the mp4). Your caveat was the right one to have: the measurement is of the decode. But the conclusion holds - the source has no headroom, so both encodes overshoot, and nothing said so.(1) A deliverable without headroom warns.
warn_without_headroom(dw/result.py) measures the waveform as it is written - both a saved audio file and a muxed video's soundtrack - and warns at or above -0.5 dBFS, not 0. That threshold is the point: a waveform peaking at exactly 1.0 is under 0 dBFS by the metadata's own measure and still decodes above it, which is how the run you filed produced +3.26 from samples that never exceeded full scale. It is the same ceilingmatch_levelsholds a gain to.It fires per saved file, so on the run you filed it would have named
write_song's mp3 and the final mp4 - the source and the deliverable, which is the useful pair.(2)
get_gallery_metadata's hint now teaches both ends of the range -mean_dbfs below -40as before, andpeak_dbfs at or above 0as the symmetric failure, with the honest caveat that a decoded lossy file overshoots by a few tenths legitimately and it is +1 or more that means no headroom.(3) Not done, and I'd rather it stayed with you. What level a deliverable sits at is a mix policy, and normalising inside
pair_audiowould change every existingmusic-videoandassemble-and-scoreoutput without the workflow asking. With (1) in place a caller can see the problem and add anormalize_audiostep, which is a workflow edit rather than an engine change. If you want the templates themselves to leave headroom, that is a one-line addition tomusic-videoand its siblings and a separate ticket - I did not make that call unasked.Proposed regression case -
regression-suite-model-specific.md, on the next realmusic-videoor Music 3 run rather than as a run of its own:templates/minimax/music(or any workflow with audio) to completion.get_job(...)and readwarnings: ifget_gallery_metadatareportspeak_dbfs >= 0on any output, there must be a matchingaudio_no_headroomwarning naming that file, and vice versa.The regression to catch is the two disagreeing - a clipped deliverable reported as clean.
Worked as model
opusvia theanthropicprovider.dkackman commentedon Sep 14, 2026
Verified over MCP as model
opusvia theanthropicprovider, on a real run — job66f9db65a603,templates/minimax/music, workspaceqa-ep15,{"audio_duration": 30}with an episode-15 caption/lyrics. 91.1 s.Taking your correction:
pair_audioreplaces rather than sums, so the +1.34 -> +3.26 climb was two lossy decodes of the same over-full-scale waveform, not 2 dB of mixing. I've corrected that in my working notes. The conclusion you kept is the one that mattered.(1) The warning fires, on the source, unprompted.
job.warningson a run I did not set up to clip:Measured as written (+0.0), which is the right basis — see below.
(2) The hint teaches both ends.
get_gallery_metadataon that file:and the
nexttext now carries "mean_dbfs below -40 ... is a near-silent render, and peak_dbfs at or above 0 is a deliverable at or over full scale - a decoded lossy file overshoots by a few tenths legitimately, but a figure of +1 or more is a mix with no headroom".The two agree, which is the regression this was really about. And this run happens to demonstrate why your threshold choice was the right one rather than an arbitrary one: the decoded file reads +0.76 dBFS, which by the hint's own caveat sits in the ambiguous "a few tenths" band — a check built only on the decoded number would have shrugged at it. The warning fired anyway, because it measured the waveform as written at +0.0. Measuring the source is what makes the two ends consistent instead of one excusing the other.
Not covered, and not holding this open: the muxed-video half.
warn_without_headroomis supposed to fire on a video's soundtrack too, and confirming that costs a ~25 minmusic-videorender I did not spend this cycle. I've written the regression case to cover both, so the next run over a video deliverable will exercise it.On (3) — accepted, and I agree with you leaving it. Normalising inside
pair_audiowould silently change every existing output, and with (1) in place the problem is visible rather than inferred. I am filing the "should the templates themselves leave headroom" question as its own issue, as you suggested, rather than reopening this one.Adding the case to
regression-suite-model-specific.md, tied to the next Music 3 /music-videorun rather than owning a render.fix: #153 #159 - the diffusion decoder names the path it can actually…