Review

Code checks first, then a reviewer's marks, in bounded rounds, with your stops; the Mark and Review shapes.

A scene is judged in two passes: code checks every frame, then a reviewer agent reads a contact sheet. It goes round until it passes or reaches you. Checks, reviewers, and people all write the same mark.

1. Code checks

After every render, rapid check holds the scene to its format and style before any agent looks, and writes renders/<id>/r<n>.checks.json: { "pass": boolean, "marks": Mark[] }, each mark authored { "kind": "check", "name": <check> }.

CheckHoldsSeverity
croptype, cards, bubbles, and objects (not data-macro) stay inside the framemajor
bandtype stays inside one of the format's readable bandsmajor
keep-outelements stay clear of the keep-outs that apply to their rolemajor
safeelements stay inside the safe area (textures excepted)minor
min-texttype's line height is at least the format's min_textmajor
fontsevery face the scene asked for loadedblocker
problemsthe scene's code threw nothingblocker
coloura sampled field reads the colour it shouldmajor
deadsomething on screen moves: no span over 0.8 s stands still outside the meta's holdsmajor
cameraa camera move spans its beat: one that finishes early and then stands for over 0.8 s is marked. The quick moves' own frames are let throughmajor
emptyat the key frame, empty field covers at most the meta's room (default 0.4), and neither the top nor the bottom third is baremajor
gridat the key frame, text blocks align with each other and the style's gridminor; major for two or more
scaleat the key frame, the hero type is at least video.hero_ratio (default 3) times the body textminor; major under two thirds of it
beatin a video cut to a track, each landing cue (land, hit, enter, drop, pop, kick) and each ducked cue sits on a beatminor past 2 frames off; major past 5

The placement checks (crop, band, keep-out, safe) hold only elements at rest: an element moving between frames is entering or leaving, so it isn't marked, and one wholly off the frame isn't seen. min-text holds whenever type is on the frame. An edge may cross a guide by half a pixel. Hits of one check on one element on consecutive frames merge into one mark with a span.

Blockers and majors fail the scene; minors and nits go to the reviewer as notes. In a video, a scene with code problems fails its render before any check runs. The checks see only elements with data-el and data-role (tracked elements).

Key frames first

Before a scene moves, its hero is built as a still at meta.key. Code checks the still (rapid check --still, renders/<id>/key-k<try>.checks.json): placement, fonts, problems, empty, grid, scale; in a video every scene but the storyboard's one breath is held to 40% empty field whatever its room. The reviewer reads the frame into the review's frame (each third, how much is bare, hero over body, the visual doing work) and judges it as a poster against the storyboard's key and the style's proof: reviews/<id>-k<try>.json. A major from the checks, or a review that never read the frame, makes a pass a revise. Three tries, then an approval. --keys person has you approve the still instead; --keys off skips key frames.

2. The contact sheet

The reviewer never watches the video. rapid sheet draws frames at chosen moments, each labelled with its time and frame number:

  • Round 1: the poster, then every cue. With no cues, frames spread over the scene.
  • Later rounds: the starts and ends of the changed spans, the cues inside them, then the poster.
  • At most --max (12) frames, no two in one frame.

With agent review, rapid sheet --micro adds a strip 0.3 s either side of the key and of every mark the review must answer. A rapid-reviewer reads the sheet, the strip, the checks, and the previous scene's sheet in a fresh context, against taste.md and the refs; it never edits the scene and doesn't repeat what the checks found. It writes reviews/<id>-r<n>.json.

3. Rounds

VerdictMeansThen
passnothing above minoraccepted
revisea blocker or major a builder can fixthe next round builds from the marks, while rounds remain; then an approval, "accept as it is"
needs_youa person must decidean approval

--rounds (default 4, 1–10). From round 2 the builder reads the last review and checks and changes only what their marks ask, near their times. A review lists every earlier mark it was handed (the last round's, the key frame's, the director's) in answers; a pass that leaves one carried, or leaves one out, counts as a revise. With --review none, passing checks accept the scene and failing ones go straight to an approval.

What a builder reads: the last review and checks; renders/<id>/marks.json, a person's marks (the screening page, add_mark, rapid revise --at), read first and acted on before anything else; and any rapid redo --note, in its prompt.

4. Stops

With --stops all, approvals wait after the storyboard, on a key frame that didn't settle (every key frame with --keys person), and on a scene out of rounds or sent to you. --stops storyboard keeps only the first; --stops none keeps none and takes the best try or round instead. At a stop:

  • approve: rapid approve <node>, /rapid approve <node>, Approve in the pane, or ask Claude;
  • redo the step before it with a direction: rapid redo <node> --note "…";
  • look first: /rapid open <node>, or Open in the pane.

Mark

Mark in contracts/src/marks.ts.

FieldTypeMeans
idstringunique; a reviewer names it for its subject (r2-title-measure)
scene_idstring
versionstringthe scene file's sha256 when the mark was made
tsecondsthe moment, or a span's start
t_endseconds, optionala span's end, after t
elementstring, up to 120, optionalthe data-el; with a span, tracked as it moves
region{ x, y, w, h }, optionalin shares of the frame, 0–1
notestring, 1–4000what to change
severityblocker, major, minor, nita scene can't ship / must be fixed / fix when cheap / a preference
author{ kind, name }kind person, agent, or check; name 1–80
created_atISO time
{
  "id": "r1-card-hold",
  "scene_id": "card",
  "version": "9c1e…",
  "t": 0.8,
  "t_end": 2.3,
  "element": "card",
  "note": "The card holds too long before it leaves; cut the hold to about 0.8 s so it leaves on the settle.",
  "severity": "major",
  "author": { "kind": "agent", "name": "rapid-reviewer" },
  "created_at": "2026-10-28T12:00:00.000Z"
}

POST /api/marks takes a mark without id and created_at, with an optional job_id (HTTP API).

Review

One round's judgment, reviews/<id>-r<round>.json, or a key frame's, reviews/<id>-k<try>.json (round is then the try, and every mark sits at the key time).

FieldTypeMeans
scene_id, versionstringsas in its marks
roundpositive integerfrom 1
verdictpass, revise, needs_you
marksarray of Mark
summarystring, up to 8000the scene's state and what matters most
looked_atarray of [from, to]the spans reviewed; default []
answersarray of { mark, status, note }, optionalevery earlier mark handed over: status answered or carried
frameKeyReading, optionala key frame's reading: top, middle, bottom (what fills each third), empty (0–1), hero_body (ratio or null), visual