Finding video
The product is the finding, not the website. The video shows the real material that proves it, large and clear, holds one thing constant so the viewer sees what changed, and ends on a question that people answer in the comments. The site appears only at the end, as the source.
It grew out of the Cluj satellite clip (same place, 1968 → 2025, full-frame imagery, a year label, two lines, no website), which worked much better than walking around the site.
What you deliver
- Two cuts, 1080×1920, 30 fps, H.264 + AAC, 15–25 s: A opens on the question or the first image and loops; B opens cold on the payoff. Covers for both.
post.txt: files and specs, posting notes, the claims table (every number and line on screen → its source file or URL), image credits, sound sources. No post text unless the user asks for it (agents don't draft posts).- The videos in a folder outside the repo (
~/Videos/<project>-finding-<date>/); the storyboard, scripts and material crops in the project'sreports/finding-<date>/, with a README: what's there, where the media lives, what the scripts need. - Posting is the user's job: never post for them.
Workflow: three cheap approvals before the long render
- The finding. List 2–4 candidate findings from the project's own data, each with the tension it carries and its denominator. Pick the one with pull (money, the city, a shared annoyance). Verify every number against the data, not against the page that summarises it.
- The material. For the finding, find the most vivid real thing that shows it: a saved
menu capture, a satellite frame, a document, a photo, the data itself as a chart. Note
the rights for each piece (see
references/craft.md, Material). Crops stay exactly as captured: no retouching, no added prices. - Story check (approval 1). A beat table: time, what fills the frame, the caption, the sound, and the claim each beat makes with its source. Name the constant (what stays the same while the rest changes) and the device (the one idea you could say in a sentence). Wait for the user's yes or changes.
- Look check (approval 2). Use the page's current design: read its colours, type and chart style from the site's source each time, since pages get redesigned (2026-11-06). Render 2–3 full-size frames (
frames.py --stills, orseek_capture.mjs ... stills) and show them. Wait for a thumbs up per frame. - Storyboard (approval 3). Draw it with
scripts/storyboard.py: one key frame per beat at real size proportions, with the time, the sound and the transition into the next beat. Show it and wait for a yes. The user asked for this check: no video render before it (2026-11-06). - Build. Render, then run the checks below and look at every sheet yourself.
- Deliver.
post.txt, board, and tell the user what you couldn't check (sound by ear at least) and that the 2-second hold, watch time and comments are the real verdict.
Skip an approval only when the user says so for this video.
Renderers
Pick by material; all write 1080×1920 PNG frames and encode with tv-range BT.709 yuv420p.
| Material | Renderer | How |
|---|---|---|
| Photos, scans, satellite frames, document crops | scripts/frames.py (from the satellite clip) | a Python frame_fn(t) that composites full-frame images, shade_top behind captions, overlay/text for captions; synth for sound events; render() encodes |
| A chart or a number that moves | an HTML page with window.seek(t) (the chart method below) + scripts/seek_capture.mjs | node seek_capture.mjs <page.html> <out> stills for check frames, then frames for the video; encode with ffmpeg as in frames.encode |
| An illustrated scene (atmosphere, a metaphor) | optional: cth9191/animate (MIT), a third-party skill | ask before installing it |
The chart method (from charlie947/motion-graphics-skills animated-chart, MIT): four
states — start, one change (nothing fades out and gets replaced), hold with the headline
value labelled, return so the loop has no jump. Every frame is computed from t alone. The
title, labels and axis never move. Never round, reformat or add a number. After building,
capture frames at 0, 1, 2, 4 and 7 s and look for overlapping or cut-off text before the
video.
Needs numpy and Pillow for frames.py, Playwright for seek_capture.mjs (set PLAYWRIGHT= to
its node_modules/playwright if it isn't resolvable), and ffmpeg.
Checks
python3 ../demo-video/scripts/check.py <out dir> --name <name>(from this skill's folder) (name the cuts<name>-A.mp4/<name>-B.mp4): size, frame rate, colour, loudness, loop SSIM, safe-zone and contact sheets. It reports and doesn't fail: read every line, and check each number against its target yourself.- Look at the safe-zone sheet: no caption, number or source line under red.
- Read every caption at phone size (360 px wide) on the contact sheet.
- Name the hero of each main beat and check it takes at least 40% of the frame's height, and
name the turn (
references/craft.md). Say which beats miss. - Claims table: every on-screen number traced to a file; every comparison says its basis (which pizzas, which date, how many).
- Measure the sound beat by beat, both full range and above 250 Hz (what a phone speaker plays). The payoff must be the loudest in both, and the near-silence must be quiet. Then listen once if you can; otherwise say you didn't. Use
frames.mixto give the payoff its own level, thenframes.level; on the pizza pilot the old compressor left the hum louder than the hit.
Gotchas
-
A caption next to a number inherits its unit. "the biggest gap" under "4 lei" reads as lei; say "în procente" or drop it. (Treponti was the biggest in percent, La Crosta in lei.)
-
Don't reuse the apps' product photos or UI (Wolt and Glovo terms reserve image rights). Transcribe a listing into your own neutral card, dated, or crop only text you need as evidence and say where it's from.
-
AI-generated footage stays out of videos about real places or real prices; it reads as staged. Atmosphere comes from the user's own footage, public-domain archives (check each item's rights) or a clearly illustrated style.
-
ElevenLabs "Chris" gets Romanian numbers wrong, even as digits (49 and 67 on the pizza video, 88 on the permits video, 2026-11-06). Transcription doesn't catch it. Audition every spoken number and have the user listen before mixing.
-
Before posting, the page must be live and the numbers re-checked if the data changed.
-
Synthetic voices misread numbers, and transcription won't catch it. Spelled-out „optzeci” came out as „opt zece”, the transcript still said „Optzeci”, and a take with digits was right. The next take of the same number came out wrong again, so generation varies: once the user approves a take, splice that audio in and don't regenerate it. Only a human ear can check pronunciation (2026-11-06).
Where the rules come from
references/craft.md holds the craft: the finding beat sheet, the story rules, captions,
material and rights, sound. Sources: a satellite-imagery clip of Cluj-Napoca (2026-11-03), demo-video's
craft notes, cth9191/animate's story grammar (MIT), charlie947's animated-chart and
vox-explainer rules (MIT), StewdioAI/blank-page's frame and turn rules (MIT), and a Codex
consult (2026-11-04).