From 58c6d86b6677bb0762fe18fa8b1b9876fbd0d512 Mon Sep 17 00:00:00 2001 From: Hermes Date: Wed, 4 Nov 2026 13:05:23 +0000 Subject: [PATCH] fix(release): re-record a demo take whose capture stalls instead of shipping the dead stretch --- scripts/build_release.py | 90 +++++++++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 34 deletions(-) diff --git a/scripts/build_release.py b/scripts/build_release.py index e65459c..8e14910 100755 --- a/scripts/build_release.py +++ b/scripts/build_release.py @@ -303,28 +303,62 @@ def main() -> int: run(["npm", "run", "test:photo-lifecycle"], tree) run(["npm", "run", "test:training-contribution"], tree) run(["npm", "run", "test:portability"], tree) - demo_raw = release_dir / f"timmy-talking-turd-{version}-demo.raw.webm" + demo = release_dir / f"timmy-talking-turd-{version}-demo.mp4" caption_receipt = release_dir / f"timmy-talking-turd-{version}-demo-captions.json" - demo_env = dict(server_env) - demo_env["TIMMY_RELEASE_VERSION"] = version - demo_env["TIMMY_RELEASE_DEMO_DELTA"] = release_delta - demo_env["TIMMY_DEMO_CAPTIONS_OUT"] = str(caption_receipt) - run(["node", "scripts/record_release_demo.mjs", str(demo_raw)], tree, env=demo_env) - if not caption_receipt.exists(): - raise SystemExit("Release demo produced no on-camera caption receipt") - recorded = json.loads(caption_receipt.read_text(encoding="utf-8")) - onscreen = [str(line) for line in (recorded.get("captions") or [])] - # A pushed string is not proof of pixels. Only captions the demo measured as a painted, - # on-top, in-frame bar (style + elementFromPoint + band pixel change) count as on camera. - verified = [str(item.get("text")) for item in (recorded.get("captionsVerified") or []) - if item.get("visible") is True and item.get("bandChanged") is True] - if recorded.get("releaseDelta") != release_delta or not any(release_delta in line for line in verified): - raise SystemExit("Release demo did not state the declared release delta on camera") - for required in DEMO_REQUIRED_CAPTIONS: - if not any(required in line for line in onscreen): - raise SystemExit(f"Release demo is missing a required on-camera caption: {required}") - if not any(required in line for line in verified): - raise SystemExit(f"Release demo caption never painted on screen: {required}") + # A contended host starves the headless compositor and the screencast fills the gap with a + # uniform grey screen, caption bar included. That is not a code failure, but it is not + # reviewable either, so take a fresh recording until one is readable. Bounded, and how many + # takes it took is published in the manifest rather than hidden. + attempts = int(os.environ.get("TIMMY_DEMO_ATTEMPTS", "3")) + dead_capture = None + demo_takes = 0 + for attempt in range(1, attempts + 1): + demo_takes = attempt + demo_raw = release_dir / f"timmy-talking-turd-{version}-demo.raw.webm" + demo_env = dict(server_env) + demo_env["TIMMY_RELEASE_VERSION"] = version + demo_env["TIMMY_RELEASE_DEMO_DELTA"] = release_delta + demo_env["TIMMY_DEMO_CAPTIONS_OUT"] = str(caption_receipt) + run(["node", "scripts/record_release_demo.mjs", str(demo_raw)], tree, env=demo_env) + if not caption_receipt.exists(): + raise SystemExit("Release demo produced no on-camera caption receipt") + recorded = json.loads(caption_receipt.read_text(encoding="utf-8")) + onscreen = [str(line) for line in (recorded.get("captions") or [])] + # A pushed string is not proof of pixels. Only captions the demo measured as a painted, + # on-top, in-frame bar (style + elementFromPoint + band pixel change) count as on camera. + verified = [str(item.get("text")) for item in (recorded.get("captionsVerified") or []) + if item.get("visible") is True and item.get("bandChanged") is True] + if recorded.get("releaseDelta") != release_delta or not any(release_delta in line for line in verified): + raise SystemExit("Release demo did not state the declared release delta on camera") + for required in DEMO_REQUIRED_CAPTIONS: + if not any(required in line for line in onscreen): + raise SystemExit(f"Release demo is missing a required on-camera caption: {required}") + if not any(required in line for line in verified): + raise SystemExit(f"Release demo caption never painted on screen: {required}") + run(["ffmpeg", "-y", "-v", "error", "-i", str(demo_raw), "-vf", "scale=720:1280:flags=lanczos", "-an", "-c:v", "libx264", "-preset", "fast", "-crf", "20", "-pix_fmt", "yuv420p", "-movflags", "+faststart", str(demo)], tree) + demo_raw.unlink() + for debris in release_dir.glob("page@*.webm"): + debris.unlink() + run(["ffmpeg", "-v", "error", "-i", str(demo), "-f", "null", "-"], tree) + probe = json.loads(run(["ffprobe", "-v", "error", "-print_format", "json", "-show_streams", "-show_format", str(demo)], tree, capture=True)) + video_streams = [stream for stream in probe.get("streams", []) if stream.get("codec_type") == "video"] + if len(video_streams) != 1 or video_streams[0].get("codec_name") != "h264" or video_streams[0].get("pix_fmt") != "yuv420p" or video_streams[0].get("width") != 720 or video_streams[0].get("height") != 1280: + raise SystemExit("Release demo media probe failed") + # A stalled compositor paints uniform grey over the whole screen, caption bar included, so + # the take reads as a dead channel for as long as the stall lasts. Measure it, do not + # eyeball it, and re-record rather than shipping the dead stretch. + measurement = measure_dead_capture(demo) + try: + assert_readable_demo(measurement) + except SystemExit: + print(json.dumps({"take": attempt, "dead_capture": measurement}), flush=True) + if attempt == attempts: + raise + demo.unlink(missing_ok=True) + continue + dead_capture = measurement + print(json.dumps({"take": attempt, "dead_capture": measurement}), flush=True) + break finally: server.terminate() try: @@ -333,19 +367,6 @@ def main() -> int: server.kill() server.wait(timeout=5) server_log.close() - demo = release_dir / f"timmy-talking-turd-{version}-demo.mp4" - run(["ffmpeg", "-y", "-v", "error", "-i", str(demo_raw), "-vf", "scale=720:1280:flags=lanczos", "-an", "-c:v", "libx264", "-preset", "fast", "-crf", "20", "-pix_fmt", "yuv420p", "-movflags", "+faststart", str(demo)], tree) - demo_raw.unlink() - run(["ffmpeg", "-v", "error", "-i", str(demo), "-f", "null", "-"], tree) - probe = json.loads(run(["ffprobe", "-v", "error", "-print_format", "json", "-show_streams", "-show_format", str(demo)], tree, capture=True)) - video_streams = [stream for stream in probe.get("streams", []) if stream.get("codec_type") == "video"] - if len(video_streams) != 1 or video_streams[0].get("codec_name") != "h264" or video_streams[0].get("pix_fmt") != "yuv420p" or video_streams[0].get("width") != 720 or video_streams[0].get("height") != 1280: - raise SystemExit("Release demo media probe failed") - # A stalled compositor paints uniform grey over the whole screen, caption bar included, so the - # take reads as a dead channel for as long as the stall lasts. Measure it; do not eyeball it. - dead_capture = measure_dead_capture(demo) - assert_readable_demo(dead_capture) - print(json.dumps({"dead_capture": dead_capture}), flush=True) contact_sheet = release_dir / f"timmy-talking-turd-{version}-demo-contact-sheet.jpg" # Span the whole recording: a fixed 1/2 fps sheet only covered the first 24s of a longer demo. demo_duration = float(run(["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", str(demo)], tree, capture=True)) @@ -484,6 +505,7 @@ def main() -> int: "feature_demo_no_dead_capture": "passed", }, "demo_dead_capture": dead_capture, + "demo_takes": demo_takes, } manifest_path = release_dir / "manifest.json" manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")