evidence
Skill2 starsChanged 42 days agoMITView on GitHub
Use when a PR, bug fix or UI acceptance criterion needs browser proof: records a captioned MP4, a per-step storyboard PNG, a state trace JSON and a ready-to-paste PR evidence section whose rows match the storyboard tiles 1:1. Good for keyboard/focus flows, multi-step interactions, loading states, bug before/after, or when asked for \"video evidence\", \"record the flow\", \"storyboard\" or \"screenshots for the PR\". Portable: Node + playwright-core + ffmpeg.
- Installs packages
5 other projects use a version of this.
Adopted by
Most recently taken up by
- jacksnxly/keryxtheir own version, first seen Nov 8, 2026
- pahlevikun/levistacktheir own version, first seen Nov 1, 2026
- adiutama/skillstheir own version, first seen Nov 1, 2026
- hoophq/hooptheir own version, first seen Oct 17, 2026
- SoFarSoGoodya/mathmodel-weavetheir own version, first seen Oct 2, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 5
- hoophq/hoop★ 848same name
- SoFarSoGoodya/mathmodel-weave★ 2same name
- adiutama/skills★ 1same name
- jacksnxly/keryx★ 0same name
- pahlevikun/levistack★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 5 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 27
Read back
captions.png: every caption 1..N must appear. - Distinctive: line 51
Verify: before citing anything:
- Distinctive: line 55
Check frames for secrets / personal data before anything leaves the machine.
- Distinctive: line 84
If some rows are trace-only, add one line saying why those frames look identical.
- Very specific: line 93
Motion claims: add mid-transition probes inside act and, if useful, a time-sampled grid (ffmpeg -i <slug>.mp4 -vf …
“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Browser evidence
Three artifacts that must tell the same story, plus the PR text built from them. Default output: docs/qa/evidence/<A-id or slug>/ (the place qa-ui expects; pass outDir to override).
| File | For | Built from |
<slug>.mp4 | Inline video player in the PR | Playwright recordVideo, trimmed to the first step |
<slug>.storyboard.png | Inline image in the PR | One screenshot per step, taken right after that step's probe |
<slug>.trace.json | Proof of claims the eye can't check | probe() after every step |
<slug>.captions.png | Your own check | Caption bar of the MP4 sampled at 4 fps |
<slug>.pr.md | Paste into the PR | Trace diff per step, one row per storyboard tile |
Static end states don't need this; a screenshot is enough.
Rules
A time-sampled storyboard can silently drop a step (a caption with 0 video frames shows tiles 1, 2, 4 while the table says 4 steps). These rules make that impossible:
- Storyboard = per-step screenshots, never evenly time-sampled video frames. (Time-sampled grids only for motion claims: scroll, drag, animation, and then in addition.)
- Hard assert: steps == trace entries == storyboard tiles, numbered 1..N with no gap. The script throws otherwise.
- Hold >= 1000 ms per step so every caption lands in the video.
- Read back
captions.png: every caption1..Nmust appear. Read back the storyboard: each tile shows what its caption claims. - One table row per tile. A claim the screen can't show (native file dialog in headless, a network call) is marked
trace only (<reason>), never implied by a frame. - Captions are user-facing text: proofread. Phrase as the user acts: "Press Tab: focus moves to the button".
Setup (once per machine)
cd <this skill>/scripts && npm i # playwright-core
npx playwright-core install ffmpeg # Playwright's video encoder
which ffmpeg # system ffmpeg for trim/tile (brew install ffmpeg)Uses installed Google Chrome (channel: 'chrome'). Set EVIDENCE_CHANNEL=chromium after npx playwright-core install chromium if Chrome is absent.
Workflow
- Write claims first. One step per user action, each with the claim it proves and the state field(s) that prove it. In the sdlc pipeline, tie the slug to the acceptance id (
a3-keyboard). - Start the app and note its URL (e.g.
http://localhost:3000). - Write a spec in a scratch dir (not the repo), modelled on
examples/keyboard-flow.mjs:ready: selector scoped to the app root, so hidden markup can't match.setup: init-script to instrument what headless can't show (see Gotchas).probe: return only the fields the claims are about.steps:{ caption, claim, act?, traceOnly? }. Real input only (page.keyboard,page.mouse); never set state viaevaluateto fake an interaction.
- Run:
node spec.mjs [outDir]. It throws on any step/trace/tile mismatch. - Verify before citing anything:
- Open
<slug>.storyboard.png: N tiles, captions 1..N, each tile shows its claim. - Open
<slug>.captions.png: every caption present. ffprobe -v error -show_entries format=duration:stream=width,height -of compact <slug>.mp4.- Check frames for secrets / personal data before anything leaves the machine.
- Open
- Host the trace (ask the user before any commit/push): commit
<slug>.trace.jsonto a dedicated branch (never the PR's code branch), push, and use the pinned commit URL as{BASE}, e.g.https://github.com/<org>/<repo>/blob/<sha>/docs/qa/evidence/<slug>. Never host the MP4 this way: GitHub shows a repo-blob.mp4as a download link, not a player. - Fill the PR from the output directory, uploading the media with GitHub CLI >= 2.102 (needs push access to the repo):
gh pr edit <n> --body-file <slug>.pr.md --attach ./<slug>.storyboard.png --attach ./<slug>.mp4--attachuploads each file togithub.com/user-attachments/assets/…(the drag-drop store, the only host GitHub renders as a video player) and swaps the matching./<slug>.*reference for the uploaded URL. If you adapt the section into a repo template, keep eachalone in its own paragraph; inside a sentence or list item it renders as a link. Size cap: 10 MB per video on free plans, 100 MB on paid. Withoutgh --attach, drag-drop the MP4 into the PR editor instead; never fall back to a blob link. Re-read the body (gh pr view <n> --json body): every video line must be a lonehttps://github.com/user-attachments/assets/…URL. - Ledger (sdlc): reference the files from
docs/qa/ledger.tsvevidence column (e.g.docs/qa/evidence/a3-keyboard/a3-keyboard.storyboard.png).
PR evidence section
<slug>.pr.md generates this generic section; paste it where the repo wants evidence, or adapt it to the repo's own PR template (keep the template's sections and order, fill only its screenshots/testing parts):
## PR evidence


- State trace (JSON, read after each step): {BASE}/<slug>.trace.json
| Step | Claim | Trace result | Where to see it |
|---|---|---|---|
| 1 | … | `field: value` | frame 1, ~0.3s |
| 3 | … | `fileInputClickCount: 0 → 1` | trace only (headless has no native file dialog) |If some rows are trace-only, add one line saying why those frames look identical.
Gotchas
- Native file dialog: headless can't show it. In
setup, wrapHTMLInputElement.prototype.clickand count calls wherethis.type === 'file'; mark those rowstraceOnly. - Focus ring: probe
el.matches(':focus-visible'), not a class name. - First load can be slow. The MP4 is trimmed to the first step, so load time doesn't matter; the
readyselector does. - Trace timing comes from the wall clock; video offsets in the table are approximate (
~). Timing claims cite the trace. - Navigation removes the caption bar; the script re-applies it after each
act. - Motion claims: add mid-transition probes inside
actand, if useful, a time-sampled grid (ffmpeg -i <slug>.mp4 -vf "fps=12/<D>,scale=400:-1,tile=4x3" -frames:v 1 motion.png) in addition to the per-step storyboard.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

