agentleFS
ltlongtmaltlongtma/solo-sdlc/skills/evidence/SKILL.md

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

  • Other versions5 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 5

    1. hoophq/hoop★ 848same name
    2. SoFarSoGoodya/mathmodel-weave★ 2same name
    3. adiutama/skills★ 1same name
    4. jacksnxly/keryx★ 0same name
    5. 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.

  • In this repository2 other files it gives its agents.

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
  1. Very specific:

    Read back captions.png: every caption 1..N must appear.

    line 27
  2. Distinctive:

    Verify: before citing anything:

    line 51
  3. Distinctive:

    Check frames for secrets / personal data before anything leaves the machine.

    line 55
  4. Distinctive:

    If some rows are trace-only, add one line saying why those frames look identical.

    line 84
  5. Very specific:

    Motion claims: add mid-transition probes inside act and, if useful, a time-sampled grid (ffmpeg -i <slug>.mp4 -vf …

    line 93

“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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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).

FileForBuilt from
<slug>.mp4Inline video player in the PRPlaywright recordVideo, trimmed to the first step
<slug>.storyboard.pngInline image in the PROne screenshot per step, taken right after that step's probe
<slug>.trace.jsonProof of claims the eye can't checkprobe() after every step
<slug>.captions.pngYour own checkCaption bar of the MP4 sampled at 4 fps
<slug>.pr.mdPaste into the PRTrace 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:

  1. Storyboard = per-step screenshots, never evenly time-sampled video frames. (Time-sampled grids only for motion claims: scroll, drag, animation, and then in addition.)
  2. Hard assert: steps == trace entries == storyboard tiles, numbered 1..N with no gap. The script throws otherwise.
  3. Hold >= 1000 ms per step so every caption lands in the video.
  4. Read back captions.png: every caption 1..N must appear. Read back the storyboard: each tile shows what its caption claims.
  5. 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.
  6. 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

  1. 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).
  2. Start the app and note its URL (e.g. http://localhost:3000).
  3. 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 via evaluate to fake an interaction.
  4. Run: node spec.mjs [outDir]. It throws on any step/trace/tile mismatch.
  5. 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.
  6. Host the trace (ask the user before any commit/push): commit <slug>.trace.json to 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 .mp4 as a download link, not a player.
  7. 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
    --attach uploads each file to github.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 each ![](./<slug>.mp4) alone 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. Without gh --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 lone https://github.com/user-attachments/assets/… URL.
  8. Ledger (sdlc): reference the files from docs/qa/ledger.tsv evidence 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

![Storyboard: …](./<slug>.storyboard.png)

![](./<slug>.mp4)

- 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, wrap HTMLInputElement.prototype.click and count calls where this.type === 'file'; mark those rows traceOnly.
  • 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 ready selector 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 act and, 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.