You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Follow-ups found while fixing the audit's high findings (#469) #470
Found while fixing #469; each was reproduced or is a direct sibling of a fixed defect, and none is fixed there.
A tool that changes the frame rate keeps the source's start timecode at the old rate.proxy.py --fps 50 and denoise.py --fps 50 on a 25 fps file starting 01:00:00:12 write 01:00:00:12 into the 50 fps output (the copied tmcd track's label). fix: the audit's high findings (captions, timing, audio, colour, batch), MCP argument safety, and Scorecard hardening #469 fixed fit (relabel + relabel_timecode= in run_keeping_subtitles) and cut. Not yet checked: background, caption, crop, grid, insert, join, multicam, redact, sequence, sphere, straighten, waveform.
MXF: cut.seek_keyframe reads the wrong keyframe. For -ss 1.5 it reads 0.96 s while FFmpeg lands on 1.44 s, so an MXF stream copy writes no timecode (listed as dropped) and start_snapped is probably wrong for MXF too.
metadata.py fails on a timecoded MOV into .mp4 (kind: ffmpeg, "Could not write header"): its -map 0 -c copy carries the tmcd data track.
FFmpeg 8.0 converts a tagged/untagged mix in other mixing filters.fix: the audit's high findings (captions, timing, audio, colour, batch), MCP argument safety, and Scorecard hardening #469 labels an untagged PiP beside a tagged main in overlay.py --video (8.0.1 moved the main from 80/110/192 to 88/103/192). broll, grid, join and multicam label only beside a converted input; whether 8.0 shifts a BT.709-tagged clip beside an untagged one there needs a run on 8.0 (the decided plans for two untagged inputs stay).
ProRes line, 8-bit source, overlay --image still composites through RGB.
Text-default pictographs above U+1F300 (e.g. 🌡) are still counted as emoji; an emoji placeholder inside an italic cue ends with {\r}, so the text after it loses its italics.
One more follow-up from #469: there is a window between a tool's output check and its final replace.
refuse_existing_outputs() decides whether an existing target may be replaced (with --overwrite, or because batch owns it) before the encode starts. run()'s place step then replaces the target after the encode without checking again. A file someone else puts at that path during the encode is replaced. This applies to every tool, not only batch-owned files.
Fix: record the target's identity at the check, and compare it under _OutputLock immediately before os.replace in run() and place_output(), as batch.deliver() now does. If it no longer matches, refuse with output_exists.
Activity
kajisho5 commentedon Nov 12, 2026
One more follow-up from #469: there is a window between a tool's output check and its final replace.
refuse_existing_outputs()decides whether an existing target may be replaced (with--overwrite, or becausebatchowns it) before the encode starts.run()'s place step then replaces the target after the encode without checking again. A file someone else puts at that path during the encode is replaced. This applies to every tool, not only batch-owned files.Fix: record the target's identity at the check, and compare it under
_OutputLockimmediately beforeos.replaceinrun()andplace_output(), asbatch.deliver()now does. If it no longer matches, refuse withoutput_exists.Generated by Claude Code
fix(runner): recheck an output's identity under the lock before repla…
fix: address review on #480 (framerate per image, fill/key pair, link…