Verification
Every render reviews itself before you trust it. Ten deterministic checks run against the delivered pixels — not the plan — and produce a verdict you can gate a pipeline on.
The ten checks
| Check | What it proves |
|---|---|
encode | the MP4 is intact and matches the manifest: codec, resolution, frame rate, duration |
target-in-frame | every target is fully inside the frame around its beat, above the legibility floor, and not hidden behind a caption |
cursor-on-target | the rendered cursor sits on the target at each click beat — and the sprite is proven present in the delivered pixels |
action-effect | every click, type and navigation visibly changed the UI (dead-click detection) |
output-pixels | sampled regions of the delivered MP4 match what the compositor planned |
frozen-blank | no blank or frozen footage — and no frames whose content region is empty because the app was still loading |
captions | captions fit at full size, respect the font floor, and stay inside safe bounds |
pacing | each step gets enough time to read; the whole video is sanely paced |
masks | masked regions are verifiably opaque, and the console log is clean of leaked values |
audio | narration is audible in its windows at target loudness (EBU R128) |
Exit codes are a contract
| Code | Meaning |
|---|---|
0 | publishable |
1 | the app broke the flow — a partial bundle and a watchable failure clip are written |
2 | it rendered, but failed verification |
3 | infrastructure: browser or ffmpeg missing, launch failed |
4 | bad spec or bad arguments |
A test tool that cannot tell “your app is broken” from “the video is ugly” from “the runner is misconfigured” gets || true’d in someone’s pipeline. This is the contract that prevents that.
What you get
out/verify/verdict.json— publishable or not, with a reason per check and provenance (version, spec hash, capture time, host)out/verify/contact-sheet.png— key moments as an annotated grid, so you can judge a video without watching itout/compose-manifest.json— everything the compositor rendered, which is exactly what verification checks against
Anchor your spec to the right page
A spec with no expect steps cannot fail on the wrong page. The pixels are live, the pacing is fine — so a 404, a login wall, or a corporate proxy block page will verify as publishable. Include at least one expect on content that proves the app is your app. playhead validate warns when a spec has none.
Signed verdicts
PLAYHEAD_SIGNING_KEY=… playhead render demo.yaml -o out
playhead attest out/verify --bundle out/captureattest re-hashes the artifacts and checks the signature, proving a verdict describes exactly these files and was never edited after the fact.