| name | ui-video-evidence |
| description | Record captioned browser/UI evidence videos, upload to GitHub PR attachments, and link sanitized artifacts in a self-contained gist |
UI Video Evidence for Visual Verification
Purpose
Prove user-visible behavior in a way reviewers and agents can verify quickly from the PR conversation.
When UI Video Is Mandatory
UI/browser video is mandatory whenever work is user-facing, including:
- Visual/UI layout or styling changes
- Click flows, form submit flows, navigation, or modal behavior
- New/changed browser interactions
- Any claim of visual correctness or lack of visual regression
If a PR touches user-facing behavior, missing UI video is an evidence failure.
Required Outputs
Each UI evidence run must provide:
- UI video (
.mp4 preferred)
- UI fallback media (
.gif recommended when player embed is not required)
- Captions (burned-in preferred;
.vtt/.srt acceptable)
- Git linkage (
git rev-parse HEAD visible in recording context)
- GitHub-hosted URL(s) published by automation
- A browser-viewable artifact (
.gif, commit-pinned raw asset, release asset, or native attachment)
- A downloadable high-fidelity artifact (
.mp4, .mp4.zip, or release asset)
- Matching entry in a self-contained gist bundle
Mandatory Frames
| # | Frame | Must show |
|---|
| 1 | URL + Page Load | Full browser URL bar with route under test |
| 2 | Before State | Initial state before action |
| 3 | Action | Click/input/navigation action |
| 4 | After State | Resulting state after action |
| 5 | Git Linkage | Terminal split, devtools log, or on-page SHA marker |
Recording Options
Option 1: Claude-in-Chrome GIF/Video workflow
Use browser automation and record the full flow while keeping URL visible.
Option 2: Kap (manual desktop capture)
brew install --cask kap
Record browser window including address bar.
Option 3: ffmpeg (headless/CI)
ffmpeg -video_size 1280x720 -framerate 10 -f x11grab -i :99 -t 30 /tmp/<work_name>.mp4
Caption Requirements (MANDATORY)
Both tmux and UI videos must always have captions.
Accepted forms:
- Burned-in captions in the video (preferred)
- Sidecar caption file (
.vtt/.srt) linked in PR and included in gist
Use ~/.claude/skills/video-caption/SKILL.md for reliable burned-in captions.
GitHub Hosting (Required, Zero-Touch)
Preferred path for strict /es:
zip -j /tmp/ui_flow.mp4.zip /abs/path/to/ui_flow.mp4
gh release create evidence-pr-<PR_NUMBER> --draft --title "PR #<PR_NUMBER> Evidence" --notes "" 2>/dev/null || true
gh release upload evidence-pr-<PR_NUMBER> /tmp/ui_flow.mp4.zip /abs/path/to/ui_flow.gif /abs/path/to/ui_flow.srt --clobber
gh release view evidence-pr-<PR_NUMBER> --json assets,url
gh pr edit <PR_NUMBER_OR_URL> --body-file /tmp/pr_body.md
Build /tmp/pr_body.md from the asset URLs returned by gh release view --json assets,url. Do not guess the final download URL for draft releases.
Optional path:
$HOME/.claude/scripts/github_pr_media_upload.py may still be used when native user-attachments URLs are specifically desired and a valid GitHub web session cookie is available
Behavior:
- Keeps publication fully zero-touch via
gh
- Produces durable GitHub-hosted URLs that can be pasted into the PR description or comment
- Avoids dependence on a browser session cookie
PR Snippet Template
## UI Evidence
- GIF: `<asset url from gh release view --json assets>`
- MP4 ZIP: `<asset url from gh release view --json assets>`
- Captions: burned-in (or gist: https://gist.github.com/<id>#file-ui-video-vtt)
- Route: `/path/under/test`
- Commit: `<sha>`
- Claim: <what this proves>
Anti-Patterns
Reject these:
- URL bar cropped out
- Success-only clip (no before/action)
- No git SHA linkage
- Missing captions
- Screenshot-only evidence for flow claims
- Manual drag-drop as the only publication path
- Non-GitHub-hosted media when GitHub hosting is available
Reviewer Checklist
- Video is linked in the PR via GitHub-hosted URL
- Automation path uses
gh release upload and PR edit/comment, or the optional native-attachment helper
- Captions are present
- Before/action/after flow is visible
- URL and route match claim
- Git SHA linkage is visible
- Gist contains matching metadata/caption artifacts
First-frame verification (MANDATORY)
Moved here from ~/.claude/CLAUDE.md on 2026-07-25. Applies to AGY CLI and any browser-capture pipeline.
-
Wait for page readiness before capture. Replace fixed-delay sleeps with page.wait_for_load_state("networkidle") AND page.wait_for_selector(<expected-ui-element>, state="visible"). A blank/white first frame is invalid evidence — it means the page had not rendered.
-
Verify the first frame visually before pushing. Extract frame 1 from the MP4 and confirm it shows the expected starting state (dashboard, modal opener, etc.), not a loading screen:
ffmpeg -i video.mp4 -vf "select=eq(n\,0)" -vframes 1 frame1.png
-
Reject evidence with a white/blank first frame. Re-capture with stronger wait conditions. Do NOT push the gist and label it as evidence.
-
Evidence Gate caveat: the evidence-gate CI check validates metadata.json freshness, NOT visual content. Visual verification is the responsibility of the agent pushing the gist — a green evidence-gate says nothing about whether the video shows anything.
Capture script standard (your-project.com-specific)
Every testing_ui/capture_*.py script must use the shared browser_test_helpers.py helpers — wait_for_page_ready() and verify_first_frame_not_blank(). New scripts that re-implement waits inline are a regression.