{"id":30714,"plugin_id":"plugin_asdk_app_6a18d4c190a0819186e6b129a09e931e","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-09T18:02:36.642Z","digest":"388a13d1adcaef26dc84d5f3bc7ec8782e3b087ab8344820abd6663b1396c7e7","against":null,"payload":{"description":"Generate the film's shots — the shooting period. Final per-scene shotlists, preset-driven shot design (camera moves, optics, two-source lighting, acting), every scene's pictures on one board (scene picture, wide, a room map when needed), the handbook's two-part prompt — one prompt per RUN of shots (as much of the film as fits a single generation, scenes included), the model making the cuts inside it — drafts, surgical iterations with a full log, the delivered run split back into its shots, and take selection into selects. Use for stage 6 of the film pipeline, only after the scenes' asset sheets are approved. Routed from the film skill.","included_files":[{"relative_path":"references/PRESETS-ACTING.md","size_in_bytes":6345},{"relative_path":"references/PRESETS-CAMERA.md","size_in_bytes":43244},{"relative_path":"references/PRESETS-LIGHTING.md","size_in_bytes":13134},{"relative_path":"references/PROMPT-BLOCKS.md","size_in_bytes":47816},{"relative_path":"references/PROMPT-VERIFY.md","size_in_bytes":14821},{"relative_path":"references/SEAMS.md","size_in_bytes":19633}],"name":"film-scenes","skill_md_contents":"---\nname: film-scenes\ndescription: \"Generate the film's shots — the shooting period. Final per-scene shotlists, preset-driven shot design (camera moves, optics, two-source lighting, acting), every scene's pictures on one board (scene picture, wide, a room map when needed), the handbook's two-part prompt — one prompt per RUN of shots (as much of the film as fits a single generation, scenes included), the model making the cuts inside it — drafts, surgical iterations with a full log, the delivered run split back into its shots, and take selection into selects. Use for stage 6 of the film pipeline, only after the scenes' asset sheets are approved. Routed from the film skill.\"\n---\n\n# ChatGPT and Codex integration\n\nApply these host conventions throughout this skill and its references.\n\n- Discover the connected Picsart tools and use their actual names and schemas.\n  The `picsart_*` names in the workflow identify tools, not a fixed host namespace.\n  If the connection is missing, explain that Picsart must be connected; continue\n  script and shot planning when possible. Never invent tool results or renders.\n- Read board decisions from the current user message and attached widget context.\n  Use `read_widget_context` only if the host actually exposes that tool. Do not\n  assume ChatGPT has Claude's context reader. Treat a board's initial tool result\n  and unsent widget state as previews, never as user approval. If a submitted\n  decision has no accessible payload, explain briefly and use the text fallback\n  to collect the missing decision; do not guess or repeat charged operations.\n- Use the host's available question interface or one concise conversational\n  question for preset choices.\n- UI rendering and delivery of feedback are the remote MCP server's responsibility.\n  If a board is unavailable, present its relevant options in text and record the\n  user's selection using the same documented feedback fields. Do not claim that\n  a plugin manifest makes Claude-specific widgets compatible with ChatGPT.\n- Save `film.json` and artifacts in the user's writable project workspace, not\n  the installed plugin directory. If persistent file tools are unavailable,\n  keep a structured project checkpoint in the conversation and provide it for\n  download when the host supports files. Never claim a file was saved without\n  confirmation from a file tool.\n- Honor the user's current instructions and already authorized scope. Preserve\n  quoted spend limits and production locks; do not infer authorization from a\n  preview, a timeout, or a connection being installed. A timed-out charged call\n  needs a status check before considering a retry.\n- This package holds six film skills (`film`, `film-development`, `film-assets`, `film-scenes`, `film-edit`, `film-finishing`) and three motion skills (`motion`, `motion-import`, `motion-design`). Route between them directly.\n- `motion-import` reads a design's layers through the Figma app's tools. If Figma is not connected in this host, use its flat-frame fallback and say so once.\n\n\n# Scenes — the shooting period\n\nThis is where the money goes, so it runs as a seven-step conveyor per scene, in\norder, because each step is more expensive than the one before it. The gate behind\nyou is real: **no run generates until the assets of every scene it spans are\nlocked** (the matrix in `film`) — a run that crosses a production-block boundary\nwaits for both blocks, so where the film works block by block, the run pass cuts\nruns at block boundaries. The gate ahead: every shot `final`, in selects, logged.\n\n**Nothing charged in video goes out on a number the user has not seen and said\nyes to (2026-09-07).** Reported from real sessions: runs dispatched with no\ncredit figure in front of the user at all. Video is the film's largest spend, so\nevery charged video call — the pilot run, the batch, a re-roll, an edit, an\nextend, the final-resolution pass — happens in three steps in this order:\n`picsart_preflight` (free) returns a number, the number goes to the user in one\nline, and the dispatch **waits for their yes**. One quote per dispatch, never per\nshot: a run of five shots is one number and one yes.\n\nWhat does NOT count as that yes — the forecast below (a plan, not a purchase),\nthe shot list's approval (that is the list's yes, and its board figure prices\nper-card generations, which a run is not), the sheets' lock, the yes that opened\nthis stage, and the yes that covered an earlier dispatch. **Express pace changes nothing here.** When\npreflight cannot price the call, say so in the same line — the rate arithmetic,\nnamed an estimate — and still wait; an unpriced call never reads as free. Record\nthe figure in `film.json`'s `credits.nextActionQuote` before the call, so the\nyes has a number on record.\n\n**Before the money phase, state the film's forecast once.** Convert the\nshotlist into numbers before anything renders: runs × expected takes × each\nrun's `genSec` × the model's per-second rate, plus a regeneration buffer\n(~20%), the edit passes you can foresee (one per risky stretch, at the edit\nmodel's rate — quote it once), and the charged QC\nframes (take QC, cut-point checks). **The\n~25% keep rate practitioners quote is per-shot data and does not transfer**: a\nrun passes only when every cut in it passes, and nobody has measured that rate\non this pipeline yet — so plan two takes per run, say the number is a guess,\nand correct it out loud after the first run lands. One honest range — \"this\nfilm will cost roughly X–Y credits\" — before the first dispatch; track\nactual-vs-forecast in `film.json`'s `credits` and say so when the pace will\nblow it.\n\n## The unit of generation is the run, not the shot (2026-09-03)\n\n**Repair exception:** this section governs initial production, not permission\nto replace accepted footage. A user-approved connecting insert between existing\nclips may generate alone under `../film-edit/references/JOIN-REPAIR.md`. Preserve\nboth originals and verify both joins; do not merge the insert into their run and\nre-roll it merely to satisfy the packing rule.\n\n**Shots are authored one at a time and bought together.** Measured on this\npipeline's own material: a film generated shot by shot — one `picsart_generate`\nper card, the takes cut together at the edit — loses to the same shots\ngenerated as ONE multi-shot take with the cards written in as its cut list. The\nloss is not subtle and it is not one thing: identity holds across the cuts\nbecause the model never re-reads the descriptor from cold, the light and grade\nare less likely to step at every join, voices face fewer independent generation\ndecisions, and the cuts *land* — a match on action that one generation authored\ninto both halves actually matches, where two independent renders only ever\napproximated it. *(Owed beside this date when the experiment's notes are typed\nup: the model, the shot count, the run length, and the axes it won on. The\nfinding stands; the numbers are still to be recorded.)*\n\nSo the **run** is the unit: **as much of the film as fits inside a single\ngeneration at the model's live ceiling** (`picsart_model_params` — Seedance 2.5\ngoes to 30s), scenes included. A short that fits is ONE generation — garage\nscene and street scene together; a film that does not is the fewest runs that\ncover it, split where the last paragraph of this section says. A scene change\ninside a run is a cut like any other: a shot block whose first frame is the new\nplace, with the new scene's geography line stated where its first shot is\n(`references/PROMPT-BLOCKS.md`).\n\n**“Fewest runs” is a quality rule, not merely a cost preference.** The measured\ncontinuity advantage above increases with the amount of consecutive film the\nmodel authors together. Therefore a payoff, climax, close-up, long hold,\ndifferent emotional beat, scene boundary, or a belief that a shot will “hold up\nbetter alone” is **never** a reason to start another generation. Those facts\nshape the shot header and its seconds; they do not shape the run boundary. A\npartition is invalid if the same ordered shots can fit in fewer runs at the live\nceiling while keeping every necessary run edge valid. Before dispatch, merge\nevery adjacent pair of planned runs that fits as one generation; scene changes\ninside the merged run remain ordinary internal cuts.\n\nNothing about *authoring* changes. The shot cards, the cut-by-cut pass,\nsizes, who is in frame, the geography line, the silence after every line — all\nof it is still written per shot; the user still sees short cards on\n`picsart_shotlist_board` and still sets each one with the presets. What\nchanges is where it lands: one prompt per run in the handbook's two-part shape\n— a setup once (the tagging header, the tone, the camera line, the cut list),\nthen one short block per shot that opens with its shot type and camera move\n(`references/PROMPT-BLOCKS.md`, 2026-09-09).\n\n**Everything travels as a reference image; the prompt says what each one is\nfor.** The `startFrame` *field* and reference media are exclusive (step 2), and\nthat field anchors exactly one frame — the first — while a run has many shots\nthat each need identity pixels. The way round it is solved (user-verified\n2026-09-03): the run's call carries `imageUrls` only — the **views** of every\ncharacter and location the run uses *and* every approved still — in a fixed\norder, and\n**the tagging header gives each image its role in words**: a face and an\noutfit (*\"100% matched based exactly on IMAGE n\"*), `START FRAME` (the run\nopens on exactly this image), `FRAME REFERENCE for shot N` (that shot opens on\nthis framing), `SPACE` (the wide, the map). The model honours the role it is\ntold; after the header, names only. That is the anchoring a run gets — identity\npixels for every character in every shot, *and* a photographed first frame for\nany cut that has one. A character the user supplied as a **photograph** goes\nfirst and untouched — *\"Cal face 100% matched based exactly on IMAGE 1 — a\nphotograph of the real person\"* — with one view of its generated angle sheet, when one\nexists, second as *wardrobe and angles, face from IMAGE 1* (`film-assets`, *When\nthe user brings the asset*).\n\n**One image, one thing — never a multi-panel sheet (2026-09-07).** Every entry\nin `imageUrls` shows exactly one view of exactly one asset. An asset's sheet is\ncut into single-view files at lock, and those are what a run carries; the sheet\nitself stays in the library as the approved archive. This is not tidiness: a\nfour-panel reference of one woman at four ages, with the references header correctly naming\n*\"the adult-formalwear panel\"*, gave sc04a the wrong Alina — and the identical\nprompt gave sc04b a *different* wrong Alina, plus one frame that blended two\npanels into a face not in the cast. Each generation is an independent draw\nagainst the same ambiguity, so it fails differently every time, never appears in\na prompt diff, and holds *within* a run while moving *between* runs. Panel\nlabels rendered into the sheet's own pixels did not fix it either. **There is no\nfallback pointer**: a prompt naming a panel or a position is a dispatch error\n(the lint in step 2). And every run that needs a state passes the **same view\nfile**, so identity rests on byte-identical input rather than on a guess\nrepeating. The method and the crop recipe are in\n`../film-assets/references/ASSET-SHEETS.md`, *How an asset reaches the run*.\n\n**What you are accepting, stated once so nobody rediscovers it mid-film:**\n\n- **A repair is an edit or an extend before it is ever a re-roll (2026-09-04).**\n  The model ships two siblings for exactly this, recorded at the pick as\n  `shoot.editModel` and `shoot.extendModel` (never a version named here —\n  2026-09-10): the **edit** sibling\n  changes something *inside* a clip (the clip + the change in words + the same\n  numbered references → the same clip, changed), and the **extend** sibling\n  makes a clip *longer* (the clip + what happens next → the clip continued).\n  The note's *meaning*, read against what was selected on the board, routes\n  the call (step 5): a note about how the marked stretch plays → the edit\n  model; a note asking for something that has not happened yet in the clip →\n  the extend model; only \"regenerate / redo\", or a note about the whole run →\n  a fresh roll. A clip selected with the note \"expand\" is an extend call, never\n  a regeneration — that mistake was made and reported. Both siblings are\n  candidates, not measured methods: the first of each is a test, judged in the\n  cut in the scene editor, and a clip that will not take an edit in two tries\n  is re-rolled.\n- **Handles exist only at the run's two ends.** Inside the run the model's cut\n  is the cut; the trim room at an internal boundary is the silence after a line, and\n  nothing else.\n- **The declared cut times are a request.** The model cuts near them, not on\n  them, and will occasionally fold two declared cuts into one or add one nobody\n  asked for. The delivered take is split where it *actually* cut (step 6), never\n  at the planned times, and a wrong cut count is a failed take.\n- **Length can cost resolution on some models.** A model whose long takes cap\n  below the finish format makes every run a resolution decision — which is why\n  native multi-shot *at the finish resolution* is a hard filter at the model\n  pick (`film`, model policy), not a trade-off discussed per scene.\n\n**What you are not losing — and say so when it comes up:** per-shot *editing*.\nThe run comes back as one file and is split at its delivered cuts into\nshot-shaped clips before anyone sees it — compositor bookkeeping, free — so\ntrims, reorders, drops, the scene editor's clips, Final Cut and the join QC all\nstay per shot exactly as before. \"We lose shot editing\" is imprecise: a shot\nis edited in place with the edit model, lengthened with the extend model, and\nonly re-rolled — with its run — when the user says so.\n\n**There are no exceptions at planning.** No shot shoots alone, no film shoots\nshot by shot: a risky stretch is a risk the run carries, a shot whose\ncomposition matters gets a longer header and a labelled composition reference.\n*Repair* is the edit model, the extend model, or a re-roll of the run (step 5).\nThe planning decision was made once (2026-09-03) so it is not re-made per\nscene.\n\n**One primary action per CUT is still the rule** — it moved from the\ngeneration to the cut header. A header with five unrelated beats smears exactly\nas a five-beat shot did; a scene of eleven cards is eleven headers of one action\neach, with beats inside a header legitimate at roughly one per 2–3 seconds when\nthey are one continuous movement (a hand reaching, a head turning, a line\nlanding). What the run retires is the *other* half of the old rule — \"use the\nedit, not a generation, to build sequence structure\" — because the measured\nresult says the generation builds it better.\n\n**The ceiling is a packing limit, not a shot-length recommendation.** Author\ncoverage first, then pack those cards into a run. Default dramatic cuts are\n3–8s and action may be shorter. A card over 8s needs\n`design.durationReason`; over 12s is a deliberate long take. A scene longer\nthan 12s with one card must not pass silently: recommend a 2–4-shot coverage\nversion, warn that the long take\nrisks stretched motion and gives the edit no reaction/insert coverage, and keep\nthe one-card version only after the user explicitly chooses it. Model choice,\nrun grouping, visual rhyme, \"restrained\" tone, or spare seconds under the ceiling\ndo not constitute that choice. Several short shots still cost one generation\nwhen they share a run — never merge their actions onto one card to save calls.\n\n**Run length is arithmetic, not habit.** A run's `genSec` is the sum of its\nshots' `sec` plus one handle at each end of the run, snapped **up** to a length\nthe model offers; the 3–8 seconds AI motion tolerates before it reads uncanny\n(`film-edit`) is authored into each shot's `sec` rather than trimmed out of a\nlong take afterwards. Going to the ceiling is not an exception any more — it is\nwhat a film costs — and the one trade-off that survives is the re-roll: a broken\nsecond 22 of 30 re-rolls all 30, and the film has chosen to pay it.\n\nWhere the film outruns the ceiling, **the edge between two videos is joined the\nhandbook's way** (`references/SEAMS.md`, *The video edge*, 2026-09-09): video A's\nlast shot ends in the middle of a movement, video B's first shot picks that\nmovement up from a clearly different angle and size — a close-up, a detail, an\nover-the-shoulder, never the same framing twice — and both videos carry the\nsame pictures in the same order, so every video dispatches together. The edge\nfalls where the ceiling falls, moved to the nearest moment where something is\nmoving; the story decides where scenes change, and an edge is never dragged to\na scene change to make it \"clean\" — that rule (2026-09-04 to 2026-09-08) made\nfilms jump between places for no story reason. The one exception is a video\nthat changed its place or its people: the videos after it there take their\npictures of that place from its frames and wait for it (step 6).\n(The extend sibling stitches several clips into one continuous video — ten on\nthe catalog's Seedance on 2026-09-10 — and may turn out to be a join between\ntwo runs; nobody has measured it here — a candidate, not a method.)\n\n**Inside a video the cuts are the model's, and the pair rules are written into\nthe shot blocks** — match on action, eyeline, screen direction, motivation\n(`references/SEAMS.md`, *Internal cuts*). Three habits carry: the scene picture\nopens the video — **the FIRST video of the scene only; a second video of the\nsame scene carries no `START FRAME` at all: it opens on its block's words plus\nthe identity views, the wide and the map** (`references/SEAMS.md`, *No two\nadjacent cuts open on the same still*, and the reason it is a pixel contract);\none geography line,\nidentical in every prompt of the scene;\nsilence after every spoken line. Two uses of a frame image are opposites: an\n**authored, approved still** labelled `START FRAME` in `imageUrls` is the\nanchor (step 3); a **frame exported from an earlier video** is used only when\nthat video changed the place (step 6) or the scene is written as one unbroken\nshot — it inherits the earlier video's drift and makes the next video wait.\n\n## Which surface owns which decision\n\nEvery board answers about the artifact in front of it. Asking a question on a\nsurface that has nothing to show is what makes a console feel like a form.\n\n| What exists | Surface | What the user decides there |\n|---|---|---|\n| nothing — a list | `picsart_shotlist_board` | story, coverage, shot **size**, **duration**, order, cuts |\n| one run's take, split into its shots | `picsart_scene_editor` | is this the run, which cut (if any) failed, and what exactly is wrong |\n| an assembled cut | `picsart_scene_editor` | watch it, trim, split, delete a stretch, and say in comments what to regenerate |\n| a retake of a shot they already watched | `picsart_scene_editor` | the new take in the cut — keep it, or go back to the one in the log |\n\nThe shotlist board has **no modes**. It had a `plan` and a `conveyor` pass once;\nthe conveyor was take triage, and that moved off the board when it was rebuilt\n(2026-08-21). The board plans — one call, every scene of the pass, one approval.\nA take is judged in the scene editor, always.\n\n**The board still thinks in shots; generation thinks in runs.** Its rows,\n`genSec` and \"commit to video\" are per shot, and it has no way to show which\nrows share a generation — so the run grouping is said in chat when the list is\napproved, and the board's per-shot `genSec` is read as \"what this shot would\ncost alone\", never summed into the forecast. A run marker on the board is a\nserver-repo ask (`../../docs/PLATFORM-ASKS.md`), not something to fake with\nrow labels.\n\n**Camera has one author.** The shot's card on the shotlist board is where it is\nchosen — the move pill, previewed by the board's own clip for that move — and\nafter a video exists it is re-asked exactly once, as the step-4 severity\nrouting. There is no separate design screen (retired 2026-08-21); a second\nsurface asking the same questions is the duplication this flow removed. Pass\ntakes with `kind` (`video` | `image`) so a still is never shown as a broken\nplayer.\n\n**The model is chosen BEFORE the durations.** A shot's length is only real if the\nmodel accepts it — and what the model accepts is read off `picsart_model_params`\n(`duration`: min, max, step), never from a note here: on 2026-09-10 the schema\nsaid any whole second from 4 to 30, and a 7-second call was accepted and\ndelivered at 7.0 s — the older note in this file that listed a ladder with no 7\nwas wrong. The run's `genSec` is still\npreflighted before the board opens. A card planned\nmodel-blind gets snapped afterwards, which is an approved\nplan being quietly changed. Pass `model` on the `picsart_shotlist_board` call and\nthe board offers exactly that model's lengths; a length nobody was offered cannot\nbe snapped. Switching models later re-opens every duration, which is why the\npick sits in Stage 1 — after the look console, before the shot list ever opens\n(`film-development`) — and not at the bible lock. **And the model is chosen\nbefore the runs**, for the same reason one level up: its ceiling is what decides\nhow many generations the film is, so a film grouped model-blind is a grouping\nthat will be redone.\n\n## Step 1 — final scene shotlist\n\nSharpen the preliminary cards from `film-development` into the generation\nshotlist. Per shot: id (`12A`), size, movement, FOV anchor, action (one),\nline/sound, light/time of day, palette world, duration, and **the tags of every\nasset in frame** — that last column is the prompt's checklist. The board's return replaces\nthe fields the board owns and leaves `design`, `refs`, `run` and `trim` on the\ncard by id (`../film/references/WIDGET-FEEDBACK.md`); an action that no longer\ntells the story's paragraph is a story note back to `film-development`: the\nparagraph is rewritten and shown first, never answered with a board.\nCoverage logic as\non a set: scene master → sizes → details; mind eye-lines, the action axis,\ncutaways. Present via `picsart_shotlist_board`, feedback per\n`../film/references/WIDGET-FEEDBACK.md`. The markdown-table fallback is for a\nconnection that does not expose the tool — never a shortcut when it does, and\nnever the answer to \"show me the shot list\". **Asked to see the shot list, open\nthe board again**, whatever stage the film is at: the board is where a shot list\nis read and changed, and printing the rows instead hands back data the user then\nhas no way to edit.\n\n### The cut-by-cut pass — write every cut as a pair, then read three checks\n\nShots are drafted one at a time, as a director drafts them. Then walk the scene\nin adjacent pairs, **before any prompt is assembled**, and write each cut into\nthe two shot blocks as a pair — the end of A's action and the start of B's —\nwith one of the four pair rules in `references/SEAMS.md` (match on action,\neyeline, screen direction, motivation). Nothing is recorded per boundary; the\npair lives in the prompt. A cut rule is a claim about two shots' *content*, and\ncontent is decided in the prompt: an editor handed two shots that never shared\na movement cannot invent one.\n\n**Three checks, free, read off the cards:**\n\n- **No two adjacent shots of the same subject share a size.** Two sizes apart or\n  the cut stutters. This is the checkable half of the 30° rule.\n- **Eyelines agree.** Where a look answers a thing, A's gaze direction and B's\n  subject placement are on opposite sides of frame. Same side reads as the\n  thing being behind them.\n- **Screen direction holds inside the scene**, shot to shot. A reversal is legal\n  with a toward-or-away shot between it, and illegal silently.\n\nShot length is a habit, not a gate: dramatic shots run 3–8 seconds, action\nshorter, a reaction shorter still (the handbook: *\"Use the duration based on\nwhat the shot needs.\"*). A shot over 8 seconds carries its reason in one line\non the card and nothing else — no approval, no alternative shown.\n\nA failure here costs a keystroke. The same failure found after generation costs\na take.\n\n### The run pass — the videos the plan named, filled to the ceiling\n\n**The videos were decided in Stage 1, with the user's yes** — the video plan\n(`../film-development/SKILL.md`, step 5) already says how many videos the film\nis, which scenes each covers, its `genSec`, and one sentence for every join,\nseeded into `film.json.runs[]`. The run pass does not plan videos; it fills\nthem. With the cuts written, walk the FILM in cut order and assign each card to\nits planned video, **filling each one up to the model's live ceiling** (30 s on\nSeedance 2.5; `picsart_model_params`). The edge falls where the plan put it —\non a movement, never a rest, never a scene change for its own sake\n(`references/SEAMS.md`, *The video edge*). At that edge the last shot block says\n*ends in the middle of the movement* and the next video's first shot block\nsays *picks that movement up from this new angle*, and is a clearly different\nsize and angle — a detail or an extreme close-up by preference.\n\n**A moved edge is shown, never re-cut in silence (2026-09-09).** When the\ncards' seconds do not sum to a video's `genSec`, or the plan's edge lands on a\nrest, say so in one line with the fix — *\"video 1 runs 33 s; the edge moves\nfrom 1G to 1F, where Rasa's hand closes on the flask\"* — and get the yes, the\nway a story note gets one. Two adjacent planned videos that fit as one are one,\nand that too is said, not done. On 2026-09-08 the videos were decided at this\nstage, after the pictures and unseen, and the user asked four times how scene 1\nconnected to scene 2.\n\nRecord only what the dispatch needs: each shot carries `run` (`\"r1\"`), and\n`film.json.runs[]` holds each video's shot ids in order (across scenes), its\nplanned `cutTimes` (the running sum of `sec`, in run seconds from the prompt's\n0.0), its `genSec`, its `join` sentence from the plan, and its `refs` — the\nordered list of reference images every shot block numbers against.\n\nSay the grouping in one line when the shot list is approved — *\"the film is\nthree videos of 30 s as planned, the edges at 1F/2A and 2G/3A\"* — because it is\nthe first thing that changes the invoice, and the one thing the board cannot\nshow.\n\n### OTS is not a shot size — it is a two-body claim\n\nShot size is **one dial, and it means distance**: WS, MS, MCU, CU, ECU. Any of\nthem can be shot with one person alone in an empty room; none of them says who\nelse is present.\n\n**Over-the-shoulder is a different kind of thing wearing the same label.** It\ndescribes an arrangement: two people facing each other, the camera tucked behind\none of them, looking past their shoulder at the other. Recorded in the `size`\ncolumn it reads downstream as \"how close is the camera\", and three facts travel\nnowhere:\n\n- **whose shoulder** is in the foreground,\n- **which side of frame** it sits on, and\n- that a **second body must persist** — a close-up needs one person for six\n  seconds; an OTS needs two people holding fixed positions for six seconds, one\n  of whom is barely visible.\n\nThe third is what fails. A start frame where the near shoulder is an ambiguous\ndark mass gives the model nothing to hold, and it stops treating that mass as a\nperson partway through the shot. Observed twice on one shot; it held only once\nthe near figure's ear, jaw, shoulder line and garment texture were all legible.\n\nSo the rules, and none of them costs a render:\n\n1. **The card names the near body.** `values.nearCharacter` (whose shoulder) and\n   `values.nearSide` (left/right). `picsart_shotlist_board` refuses an OTS card\n   that names neither, and refuses one that lists fewer than two assets in frame.\n2. **Check the side against the location map** before generating. The map already\n   says who sits where; if it says Maro sits right, an OTS over her shoulder puts\n   her on the right. Put her left and the audience reads it as her having got up\n   and moved.\n3. **The prompt claims the near body as a person, not a silhouette** — named\n   features, and holding position for the whole shot. See the foreground-body\n   clause in `references/PROMPT-BLOCKS.md`.\n\nThe board carries this as its own decision now — **Who's in it**, separate from\nsize: `single` · `two-shot` · `dirty single` · `OTS` · `POV` · `insert` · `group`.\nThree of them (two-shot, dirty single, OTS) are two-body claims and take the\n`nearCharacter` + `nearSide` treatment above. Two more were being mis-recorded as\nsizes: a **POV** is about whose eyes the camera is — and the other actor must look\n*into the lens*, which no size can say — and an **insert** is a thing rather than\na person, which is what an \"ECU of the instrument on the table\" actually is.\n`group` is worth naming because three or more bodies is where models start\ncloning people.\n\n**Camera height is a decision too, and the board had none.** `eye level` ·\n`low` · `high` · `top-down` · `dutch`. It is the second instruction a director\ngives after size — low looks up and grants stature, high looks down and takes it\naway — so a shot that never says it is a shot nobody framed. Set it per shot like\nany other value.\n\nAn OTS also rarely travels alone: a conversation is covered as **two reverse\nangles**, and the pair must match in everything except who is near — same lens,\nsame height, same distance, eyelines reversed. Nothing checks that pairing yet;\nuntil it does, set the two shots' values identically by hand and look at them\nside by side.\n\n## Step 2 — design the shot on its card, then assemble the prompt\n\n**The card is the design surface, and it arrives filled in.** Every shot's six\ndecisions — size, camera move, lens, light, colour, length — plus its\narrangement and camera height are pills on its card on `picsart_shotlist_board`,\neach opening a picture rather than a list. **A pill the user changes is written\ninto that shot's block; a light left as seeded writes nothing, but lens and\naperture reach every shot, seeded or changed, and so does a palette other than\n`auto`** (`references/PROMPT-BLOCKS.md`, Part 2, *The card's own picks*).\nA choice made on the board is never a choice the model did not hear. **Seed them before the board opens**,\nfrom what is already decided (the story's action, the scene location's light,\nthe world defaults' register, the run's model), so the user touches only what they\ndisagree with; nothing forces a stop, in either pace. There is no console behind\na row — the inline design panel and its \"compose the first frame\" button were\nretired with the board's 2026-08-21 rebuild, and the requirement to open one\nper scene went with them (2026-09-04). Without boards, the same rule: state the\nseeded design in one line and the host's question interface only what the card leaves open,\nfrom `references/PRESETS-CAMERA.md`, `PRESETS-LIGHTING.md`,\n`PRESETS-ACTING.md`. Both paths return preset names plus their compiled text\nfragments. World defaults come from the bible's setup; the shot stores only its\ndeviations (`design` on the shot in `film.json`).\n\n**The scene's pictures are step 3, always (2026-09-08).** A shot's frame is no\nlonger composed here on request: every scene gets the handbook's set of\npictures before its run — the scene picture the run opens on, the wide, the\nroom map — on one board for all scenes (step 3).\nA user who asks \"show me how the opening looks\" is shown that board.\n\n**A fragment is the start of the Camera block, not the whole of it.** Nineteen\nof the moves have been generated and measured (`genre-previews/_camera/` in the\nplugin repo), and the finding that matters at prompt time is that a model\nrenders a described *picture* and ignores a stated *quantity*. So paste the\nfragment, then make sure the block ends on the arrival as an image, name the set\nas rigid if the camera travels through it, and — for any move that ends on a\nchanged aspect — say that the camera does the turning. `PRESETS-CAMERA.md`'s\n\"Getting a model to actually do the move\" carries the rules and what each one\ncost to learn.\n\n**The board holds choices; the numbers behind them are yours.** Several blocks\nwant a quantity where the card holds a word — the Kelvin behind `warm`, the\nkm/h behind a moving car, the fog density behind a foggy street, the ratio\nbetween two things of different size. **None of them becomes a pill.** The\nconsole's job is a decision with a picture behind it, and nobody can judge 5200\nagainst 5600 from a chip; a board that asks would be the form this pipeline\nkeeps trying not to be. Resolve each from what the user already chose plus the\nscene's location and time of day, write it into its block, and do not raise it\nin chat either unless it is genuinely in question. `PROMPT-BLOCKS.md` blocks 8,\n9 and 10 carry the rules and the tables.\n\n**A slow shot names which kind of slow it is.** There is no tempo setting\nanywhere (retired 2026-09-04 — `PRESETS-LOOKS.md` has the why). Models render\ndescribed pictures and ignore stated qualities, so rhythm is written, never\nstated: the shot block's action and the card's `sec` carry it, and tempo\nwords (slow, calm, measured, brisk, urgent) do not appear in a header. A shot\nthat should feel slow has less happening in more seconds, and it records\n`design.slowReason`, from four:\n\n| `slowReason` | What it is | How it reaches the shot |\n|---|---|---|\n| `anti-tempo` | slow *against* the scene around it, for contrast | real time; the neighbours carry the contrast, so it is a cut decision as much as a shot one |\n| `hero reveal` | the thing itself deserves the seconds | **not generated slow** — generated at normal speed and ramped at the edit, because a model asked for slow motion smears instead of slowing |\n| `breath` | the film needs air after a heavy beat | real time, minimal action, usually paired with a `tailHold` |\n| `emotional pause` | a face working, nothing else happening | real time; the seconds go to the acting, not to the action lines |\n\nThe value is not decoration: three of the four are real-time shots whose slowness\ncomes from *having less happen*, and one is a post effect that should never be\nasked of the generator. A card that just says \"slow\" gets whichever the model\nguesses.\n\n**Generate one size wide when the shot can afford it.** A take framed one\nshot-size wider than the card's intent gives the edit spatial trim room —\nvirtual reframes, subtle push-ins, and composition fixes are then free crop\nmoves instead of retakes. Skip this on faces at CU and tighter (resolution is\nthe budget; a crop spends it).\n\n**Generate one beat long, for the same reason.** Two numbers, not one:\n\n- `sec` is the **cut length** — how long the shot runs in the film. It is what\n  the ±10% runtime gate measures and what the dialogue rule computes.\n  Unchanged.\n- `genSec` is the **generation length**. For a run it is the sum of its shots'\n  `sec` plus a handle at each end *of the run*, snapped **up** to a duration the\n  model actually offers; for a solo shot it is `sec` plus a handle at each end.\n  It is what you pass to `picsart_generate`, and you trim back to the shots'\n  `sec` in the assembly.\n\nThis is the temporal twin of shooting one size wide, and the same logic: a\ngenerated take has no second take, so the cheapest repair is material you\nalready paid for. A tail that drifts, an action that lands half a beat late, an\nend state the next shot cannot cut to — with handles those are trims; without\nthem they are re-renders.\n\n**Handles are a per-film policy**, stored independently of setup feedback\n(the MCP setup no longer sends `handles`), because\nthey are a real and permanent cost: duration is what video models bill. On a run\nthey are exactly two — one at each end of the run — and they are cheap in\nproportion: two seconds on a 28s run, not two on every 5s shot. Skip them\n(`handles: \"off\"`) only when the run is already at the model's ceiling and there\nis no room to add. **Inside the run no shot has a handle**, by construction: an\ninternal boundary is the model's cut, and its only trim room is `tailHold` and\nthe audio line's silence. That is why the silence is not optional, and why a run whose\nline runs into its cut is a failed take rather than a trim — there is no handle\nbehind the last word.\n\n### Audio: the takes keep the voice they were born with (2026-08-27)\n\n**Shoot dialogue with `generateAudio: true` and each speaker's saved voice\ndescription.** Read the character's `voice` field and copy it verbatim into every\nspeaking block, including inserts, retakes, edits and extensions; see\n`references/PROMPT-BLOCKS.md`. Fill a missing field once using\n`../film-assets/references/ASSET-SHEETS.md`, without an extra user question.\nDescribe the shot's emotion and volume separately. Native audio is the default;\nno separate TTS, cloning or saved audio sample is required for this text rule.\n\nThe description improves consistency but does not guarantee identical timbre.\nCompare new dialogue with accepted takes before declaring the voice consistent.\nOptional reference audio is conditioning, not a deterministic voice lock or a\npromise that the supplied waveform will be reproduced. A separate voice workflow\nis a distinct production choice; do not silently substitute it or remove dialogue.\n\nFive rules make native audio survivable. They are not optional:\n\n1. **Fewer, longer takes.** Keeping a dialogue scene in one generation reduces\n   independent voice decisions. Still check the delivered performances; neither\n   a shared run nor the copied description guarantees perfect consistency.\n2. **Transcribe every dialogue take and read it against the story's lines.** The model\n   paraphrases, drops words, adds filler, and mispronounces names. Cheap to\n   check, impossible to fix later without a retake.\n3. **Demand silence handles** — a beat before and after each line — and reject a\n   take that runs its line into the last frame. Native audio is welded to the\n   picture, so the only cut points the edit gets are the silences the model left.\n4. **Carry a bed across every scene.** Each take is mastered on its own, so\n   levels, EQ and room tone step at every join; a continuous ambience or music\n   bed is what hides it. Audiences forgive picture mismatch, not level jumps.\n5. **Preserve the scripted dialogue.** Voice drift is a review issue, not a reason\n   to replace a requested line with silence or narration. Judge accent, register\n   and timbre against the accepted character performance, separately from emotion.\n\nA bed can smooth changes in room tone and level; it cannot repair a changed\nspeaker identity. Do not automatically accept voice drift under the native policy.\n\n### Frames or references — one way: `imageUrls` only\n\n**Every video call carries `imageUrls` only, and the `startFrame` field stays\nempty** — on a run, a bridge, an insert, a one-shot reshoot, whatever the clip\nis called (rule 7, `../film/SKILL.md`). The frame the video must open on is\npicture 1, labelled `START FRAME` in the tagging header; the identity and\nwardrobe views of everyone in the video ride beside it, in the order `runs[].refs`\nfixes, and the header says which is `FRAME REFERENCE for shot N`, which a face\nor an outfit, which `SPACE`; after the header, names only. User-verified\n2026-09-03: the model honours the role stated in words, so one call gets both\nthings the two fields used to force a choice between.\n\nWhy the field is never filled — measured facts, kept here as reasons, not as\na second recipe:\n\n- **A start frame and reference media cannot travel in the same request**, and\n  \"reference media\" means images, video **and audio** alike: the video model\n  routes on which fields you set. Verified by running it (2026-08-26) — a call\n  carrying both `startFrame` and `audioUrls` came back\n\n  > `bytedance_invalid_parameter` — *\"The parameter `content` specified in the\n  > request is not valid: first/last frame content cannot be mixed with reference\n  > media content\"*\n\n  while the same audio alongside `imageUrls` rendered fine. Seedance 2.5's\n  schema pairs `image_urls` (up to 30 references) against `image_with_roles`\n  (≤ 2 entries: `first_frame`, `last_frame`, `reference_image`) as\n  alternatives. Sending both is a rejection **after** the wait.\n- **A frame shows only the people in it.** The 2026-09-08 bridge went out with\n  scene 1's last frame in the `startFrame` field — one woman's face — and no\n  picture of the other woman, who was in the shot but not in the frame. She\n  came back in a long coat with two flasks, and the bridge put a wardrobe jump\n  on both of its joins.\n- **Native audio is NOT reference media.** Tested end to end (2026-08-26):\n  `generateAudio: true` with the line in its shot block was accepted, rendered,\n  and the character spoke the line — so a call carries its lines and its\n  images together. Until 2026-09-09 this test was also written up here as a\n  second way to build an anchored shot (*\"approved start frame + generateAudio\n  + the line\"*). It is not a way: it is the proof about audio, and the call is\n  still `imageUrls` only.\n\n- **Keep the reference set tight, and every entry a single view.** The\n  identity view and the wardrobe view of every character in the video — both,\n  always (rule 7, `../film/SKILL.md`) — and per scene the run plays its pictures — the scene\n  picture, the map and the wide (step 3). A tagged\n  state a cut names — `@cal_wet` — is its\n  own view, numbered like any other image, never a panel pointer into a sheet.\n  For a photo-sourced character the photograph is the identity view and, when\n  it shows the outfit the story dresses them in, the wardrobe view too; when it\n  does not, the user is asked for one more photograph that does (rule 7,\n  2026-09-10) — a view of its angle sheet comes along only when a cut in this\n  run needs that angle. Every prop the film gave a plate to rides as `IMAGE n —\n  PROP: <name>` (rule 7): the descriptor is not in the prompt, so a picture is\n  the only carrier an object has. Every image is inlined and the total has a\n  ceiling.\n  - **The ceiling is real and it is measured before every dispatch**\n    (2026-09-04). The 22MB that died on `inline_media_too_large` was three\n    *lossless PNG* references; a view is a JPEG crop of a max-resolution sheet\n    scaled to a **2048 px delivery cap** (the model renders 1080p and declares\n    no input pixel limit, so the cap is ours to hold), which puts each one at a\n    few hundred KB — **what binds is the image count, not the bytes**. Still: `picsart_media_probe_media` every\n    URL (free — `bytes`, `width`, `height`), sum, and stay **under 15 MB** —\n    the count follows the scenes the run plays (two characters and one scene\n    are seven images; Seedance 2.5 takes 30) and the old 6–8 cap is gone\n    (2026-09-08).\n\n    **The probe returns `width` and `height` for a reason: read the short side\n    of every picture, not only the bytes.** `min(width, height)` under 300 px is\n    refused by the provider after the wait, so nothing under **320 px on its\n    short side** is dispatched — width counts as much as height. On 2026-09-09 a\n    252×508 wardrobe view was probed, its bytes were summed, and it was\n    dispatched anyway: only the total was being read, and the floor everyone\n    remembered was *\"300 px tall\"*. The cut that made it is fixed in\n    `../film-assets/references/ASSET-SHEETS.md`, *The crop*; this is the gate\n    that should have caught it regardless.\n\n    Over budget, in order: **drop the wide — but only when the map is in the set\n    and no cut in the run opens the setting up** (a pull-back, a reframe wider\n    than the shot it came from, a move that reveals a skyline or a street: those\n    cuts need the wide, and dropping it there is what let a location drift on\n    2026-09-10); **the map never leaves, and neither do the identity\n    and wardrobe views** (rules 7 and 10 — no descriptor is in\n    the prompt any more, so neither the costume nor the geography has another\n    carrier); re-encode any PNG as\n    JPEG; downscale a view only as far as keeps\n    the identity view ≥ 600 px on its short side — and **a view downscaled once\n    becomes that state's file from then on**, recorded in `views[]` and passed\n    by every later run, never a one-run copy (one state, one file). The old last step — splitting\n    the face panel out of a sheet — is gone, because that split now happens at\n    lock for every asset. The method and the export calls are in\n    `../film-assets/references/ASSET-SHEETS.md`, *How an asset reaches the\n    run*. Never discover the ceiling after the render.\n  - **The panel-pointer lint, run at the same moment (2026-09-07).** Read the\n    image labels before the prompt goes out — the references header and every cut header's\n    image reference. A pointer **into a reference image** — *panel 2*, *the\n    leftmost panel*, *the top-right of IMAGE 1*, *the bottom row of the sheet* —\n    is a **dispatch error**, not a wording preference: it means one image in\n    this set has more than one thing in it, and the fix is a crop (free, at\n    boxes `film.json` already holds), never a reworded label. Two runs of one\n    correct pointer returned two different women; the wording was never the\n    variable. **Scope: reference labels only.** Position words describing the\n    *frame being made* — the location map, the blocking block, where a\n    character stands, where the camera is — are the film's staging and are\n    required; the lint never touches them.\n\n**The anchor is compositional, not pixel-exact.** Measured on that test: the\ndelivered first frame scored SSIM 0.73 / PSNR 20dB against the approved still —\nsame woman, wardrobe, room, pose and props, framed slightly wider with the\nsubject shifted. Excellent anchoring, and *not* a guarantee of identical pixels,\nwhatever the vendor doc's \"exactly match\" says. That measurement went through\nthe `startFrame` field; a run's frames travel in `imageUrls` with their role in\nwords, and the same expectation applies — compositional, not pixel-identical.\n\n**Reference audio is a conditioning input, never the film's voice.** Also\nmeasured: feeding a 5.3s scratch line as `audioUrls` produced audio whose\nenvelope correlated with it at 0.249 — the model performed its own line in its\nown timing, not the supplied track. So a scratch mix earns its keep for\n**timing** (see step 3), and the final voice comes from native audio or from the\ndub at finishing. It is never delivered by attaching a wav.\n\n**Duration = the spoken line + one second, snapped UP the model's list.** Block\n11 already requires a second of silence after each line as the editor's cut\npoint; the duration has to leave room for it. A 5.3s line needs 6.3s, and a\nsolo clip snaps that **up** to the next length the model's `duration` schema\nallows (read off `picsart_model_params` — never a ladder remembered from a\nnote; on Seedance 2.5's step-1 schema 6.3s is a 7s clip, and 7 s was accepted\nand delivered on 2026-09-10). The same test\nasked for 6s and the dialogue ran to the final frame with no cut point — exactly\nthe failure the audio line exists to prevent. **Inside a run the snap moves to the\ntotal.** Cut times are prompt text, so a shot inside a run keeps its exact\n`sec` — 6.3s is 6.3s, no ladder — and only the run's `genSec` snaps up to what\nthe model offers; the slack that snapping adds goes to the run's tail handle,\nnever to a shot.\n\nEither error — the mixed pair, or `inline_media_too_large` — is permanent.\n**Change the payload; never re-run the same one**, and say in one line what you\nchanged.\n\nEvery run's prompt is the handbook's two-part shape — see\n`references/PROMPT-BLOCKS.md` for the template, the shape per model, a worked\nexample and the pre-dispatch checklist. The assembly is mechanical by design:\nthe handbook's lines verbatim, the style prefix verbatim from the bible, the\ngeography line verbatim from the scene; no descriptor is pasted — the pictures\ncarry identity. There is no negative prompt: every ban is written as what IS in\nthe frame.\n\n**Before every video dispatch, including edits, extensions and inserts, run the\nprompt-verify step — `references/PROMPT-VERIFY.md` — not just the format lint.**\nIt opens the files that govern a run (the blocks reference, the camera, lighting\nand acting presets, the seams, the look), derives what they require for this\ncall, and checks the **literal tool arguments** against them; its verdict is\nwritten before preflight and a fail blocks the dispatch. Use\n`picsart_prompt_verify` for the objective half and read the rest yourself. A valid schema and a credit approval do not excuse missing dialogue,\nchanged story content, or a house line paraphrased on its way into the prompt.\n\n**Price the model before believing the draft rule.** The rule below exists for\nONE reason — keep the iterations cheap so only the keeper is paid for at full\nsize — and it only works on a model whose price moves with resolution. Prices\nchange and no number is recorded here: quote both resolutions with\n`picsart_preflight` before the first dispatch. If the price moves with\nresolution, draft at 480p; if it is the same, draft at the finish resolution and\nthere is no second pass to pay for. Say which of the two the film is doing, once,\nin the forecast.\n\n### Native draft to final\n\nRead `picsart_model_params` for the chosen model before quoting. On Seedance\n2.5, when the schema lists `draft`, use `picsart_generate` with\n`extra: { \"draft\": true }` for a native draft, keeping the approved prompt,\nreferences, duration and format. Preflight the same payload including `extra`.\nRecord the returned result URL exactly in `film.json`.\n\nIf the live schema also exposes `fromDraft`, preflight a final request with\n`extra: { \"fromDraft\": \"<exact draft result URL>\" }`; use the schema's\nrequired envelope only. The tool requires a `prompt` string: use an empty\nstring for a from-draft request only if preflight accepts it. Re-quote and\nobtain approval before the paid final. Do not add the original references,\nduration or draft flag unless the live contract requires them.\n\nIf `fromDraft` is absent or rejected, it is not available on this connection.\nExplain that the final requires a separately quoted rerender and may change\ncontent; follow the normal finishing approval and re-review. Choose a regular\nresolution-priced draft instead when that better fits the approved budget.\n\nFor models without the native draft path, dispatch drafts at **480p** — where resolution actually changes the price —\nwith the run's images in `imageUrls`, in exactly the order the prompt numbers\nthem, and **the `startFrame` field empty** — the start frame is the image the references header\nlabels `START FRAME`. `generateAudio: true` on any run with a\nline in it — the line, its lip-sync, and\nthe voice block are part of what is being judged; a run with no speech drafts\nwith audio off. Audio follows the film's **voice policy** (always `native`,\nrecorded in `film.json.voicePolicy` — nothing to decide) — and *how the approved voice\nreaches the picture* is settled before the first dialogue take, not at finishing:\nsee the next section. **Every video generation is submit-and-poll**:\n`async: true` + `picsart_job_status` (the server defaults every media mode to\nasync now, so this holds even if you forget) — a synchronous video call dies at\nthe host's ~60s tool window while the render keeps running and charging, with\nno handle left to recover the result. A host \"isn't responding\" error is therefore never a failed\ngeneration: poll the job, never re-submit on that signal.\n`picsart_preflight` the batch, **give the user the quoted total, and dispatch\nonly on their yes** (the law at the top of this skill) — surprise spend is the\none unrecoverable mistake.\n\nAfter dispatching, put the batch's job handles on `picsart_render_monitor`\n(when the server has it): it polls the jobs itself, shows live per-shot\nprogress, and **reports the finished takes back into the conversation\nautomatically**. Never ask the user to wait, check back, or \"ping me in five\nminutes\" — that is the monitor's job. Without the monitor, poll\n`picsart_job_status` yourself; if a render outlives the turn, say plainly\nwhat's running and check it first thing next turn.\n\n## Step 3 — the scene's pictures: one board for all scenes (2026-09-08)\n\nRead `../film-assets/references/ASSET-EFFICIENCY.md` for scheduling and changes:\nindependent ready scene chains advance without waiting for unrelated retries;\nan upstream correction triggers a content-impact check, not a blanket rebuild.\nScene pictures still use the full scene style prefix, unlike neutral asset plates.\n\n**Every scene gets its pictures before its run, and nothing else is generated\nbetween the shot list and the run.** Until 2026-09-08 stills were on request\nand the run's only picture of a place was a clean, empty location panel. The\nhandbook does it the other way round, with a reason that stands: *the model is\ntrained on films with actors in them — an empty location renders unreal, so\nmake the scene first and take the location from it.* A scene's pictures are one\ndependency graph: wide first, opening crop and optional map derived from it. They\nare what the run's `imageUrls` carries for that scene — the scene picture as\n`START FRAME`, the wide and the map as `SPACE` — so the model never has to\nguess the room. A `FRAME REFERENCE for cut N` rides along only when a frame\nexported from an already-approved run supplies it (step 6); none is authored\nahead of time. Character views ride beside them (step 2).\n\n**Wide first, then cut the scene picture out of it, then the map — one approved batch (2026-09-23).** Two generations and one free crop:\n\n1. **The wide is generated first**, at 4K, with the cast in it from their\n   identity and wardrobe views; the scene-picture craft below (whose cast\n   opens the scene, the prompt lines, the three planes) applies to it.\n2. **The scene picture is cut out of the wide** with `picsart_media_export` (the crop\n   recipe, `../film-assets/references/ASSET-SHEETS.md`, *The crop*): a box\n   around the opening shot at the film's ratio, no credits, the run's `START\n   FRAME`. Its short side must clear the video's resolution (1080 px for\n   1080p), else the wide itself is the start frame. In a vertical film a\n   two-shot barely zooms, so a scene opening on two usually starts on the wide.\n3. **The room map is generated from the wide**, when needed (item 3 below).\n\nQuote the wide and the map as one intended batch. Preflight each concrete\npayload, obtain approval for its cost, and use `picsart_generate` asynchronously.\nThe map waits for the actual wide URL and its visual check; if its exact quote\ncould not be obtained in advance, show that quote before dispatch. The opening\ncrop is free to render. Present wide, crop and map together for one scene review.\nA scene starts as soon as its own cast is approved. A request to shoot now can\nauthorize the prerequisite pictures and run together only when their scope and\ncost are explicit; preserve all dependency and asset checks.\n\n**The chain, per scene** (a scene = one place at one time of day; a scene that\nmoves rooms is two chains). **Model (2026-09-23): the wide on a model that\nrenders 4K (`gemini-3.1-flash-image` today, `resolution: \"4K\"`; check the enum\nwith `picsart_model_params`); the room map, square and empty, on the GPT Image\nfamily — ids as recorded in `film.json` (`model.pictures` — `people`,\n`map`), read off `picsart_model_catalog` once at Stage 4\n(`../film/references/PIPELINE.md`, *Image models are families*).**\nOn *The Last Drop* (2026-09-08) Nano Banana lost faces in two-shots made from\nwhole sheets and Seedream held them; with cut views (2026-09-23) Nano Banana\nheld both. If a two-shot fails on faces again, try Seedream for that wide,\naccept the smaller cut, and write the finding here. The\norder below is the order things are attached, because the handbook's prompts\nsay *the 2nd photo*. Every prompt opens with the two film lines\n(`../film-assets/references/ASSET-SHEETS.md`, *Every image prompt carries the\nfilm*).\n\n**Before either generation dispatches, run the prompt-verify step\n(`references/PROMPT-VERIFY.md`, 2026-09-13) — it is mandatory for a still\nexactly as it is for a run, and the still row of its governing-files table\nnames what to open.** A scene picture, a wide or a\nmap is still a generation with subjects tagged\nin it, and the same failure the gate exists to catch on video happens on\nstills just as easily: a character named in the shot but written into the\nprompt only as the target of someone else's reaction, with no pose or emotion\nof their own. Check the literal text about to be sent, not a recollection that\nthe rule is known.\n\n1. **The scene picture** — the handbook's *base image*, the scene as its first\n   frame. **CUT from the wide since 2026-09-23** (above): what follows is the\n   craft of the wide's prompt and of where the cut falls. Every head in the cut\n   at least a tenth of its frame tall.\n\n   **\"The scene as its first frame\" means the cast of `shots[0].assets` —\n   read it, never the scene's dramatic centre (2026-09-13).** A scene whose\n   cast changes as it plays (someone arrives on a footsteps cue, a knock, a\n   door) is *about* the pairing that arrives, but its FIRST shot is whoever\n   is already in the room — and the scene picture is the first shot, not the\n   scene's throughline. Built from the throughline instead, a three-person\n   confrontation scene got its base image as the two-shot of the arriving\n   character and the one already there, when the shot list's own `1A` named\n   only the two who open it — the run would have opened on someone who has\n   not entered yet. Before writing `Subject #1`/`#2`, open the approved shot\n   list and copy `shots[0].assets` verbatim; if that list disagrees with\n   whichever pairing feels like the scene's centre, the shot list wins.\n\n   Prompt: the handbook's\n   thirteen lines, in its order, each filled from the film — *describe only\n   what the camera sees*:\n\n   ```\n   Visual tone: <bible.stylePrefix, verbatim>. Skin matte and textured with visible pores, no gloss or shine. A frame of live-action film — real people, real fabric, real light; not an illustration, not animation, not a 3D render.\n   Subject description: <one distinguisher per present character — \"Subject #1 — @cal, worn dark-blue work jacket\"; the face comes from the attached view, not from words>\n   Shot size: <the card's size fragment>\n   Camera angle: <the card's angle fragment; \"Eye-level.\" when the card is neutral>\n   Composition: <the card's arrangement or composition fragment, or N/A>\n   Pose & action: <the card's action — what each subject is physically doing in frame one>\n   Emotion: <the card's feels line, per visible face>\n   Gaze: <each visible face's gaze target — in the scene, never at camera>\n   Positioning in the frame: <each subject's placement from the location map — left third, right third, centered>\n   Visible / Not visible: <what must stay in frame, what may crop>\n   Foreground, Midground, Background elements: <all three, named — what sits closest to the lens, the plane the subject is on, what falls away behind them>\n   Setting: <the location descriptor's setting line — place, condition, time of day>\n   Aspect ratio: <the film's ratio>\n   ```\n\n   **The skin clause rides on `Visual tone`, and is ours (2026-09-11).** The\n   prefix compiles the camera (grain rides in its stock) and the lens family,\n   and a camera fragment says how its stock renders skin *colour* — none of them ask\n   for skin *texture*, which is the one instruction that most reliably fights\n   the render look on faces (2026-09-07). It was in the video prompt's quality\n   line and nowhere in the still that sets the film's look. It is appended to\n   line one rather than added as a fourteenth line, because the thirteen are\n   the handbook's, in its order, and the only deliberate departure from them is\n   the aspect-ratio substitution below. **Where the light comes from is not\n   asked for here, and that is now a decision, not an omission (decided\n   against 2026-09-11).** Lighting is per-shot by decision (2026-09-07), so it\n   cannot ride the prefix, and the handbook's thirteen have no lighting slot;\n   a scene picture takes its light from the time of day on `Setting` and from\n   the plate it was derived from. The course argues a named light source is\n   the largest single realism lever there is, and it may well be right — the\n   case is kept in `research/ai-video-bootcamp/ANALYSIS.md` §4.12. It was put\n   to the user on 2026-09-11 and declined. Do not re-raise it unopened.\n\n   **The still says what medium it is, and bans the others (2026-09-11).**\n   Appended to `Visual tone` after the skin clause, and taken word for word\n   from what the character sheets already carry, so the two describe the same\n   film: *\"A frame of live-action film — real people, real fabric, real light;\n   not an illustration, not animation, not a 3D render.\"* A film set up as\n   animated says its own medium instead — the line is whatever the film is,\n   never a fixed string. Until now this guard existed only on the character\n   sheets: the sheets refused the render look while the picture that sets the\n   whole scene's look asked for nothing, and every frame of the scene is\n   derived from that picture.\n\n   **They go to the compiler as `space` (`foreground`, `midground`,\n   `background`), the same in every prompt of the scene; it refuses a run or\n   a scene picture without all three (2026-09-23).**\n\n   **All three planes are named, and `N/A` is an argued exception (2026-09-12).**\n   The line used to end *\"or N/A\"*, and an escape offered in a template is the\n   value that gets written. The course's sharpest demonstration is a matched\n   pair — same model, same subject, same place — where the only difference is\n   whether a foreground, a midground and a background were written down, and the\n   version without them renders the person pasted onto the backdrop like a\n   sticker. The claim is that the flat look **is** the missing layers, not a\n   model weakness, and it is the same reason the handbook's own location plate\n   carries the three slots. So the default inverts: a frame nearly always has\n   something close to the lens — a shoulder, a doorframe, a railing, steam, the\n   edge of a table — and writing `N/A` means claiming it does not, which is\n   rare enough to be worth a sentence in the card's notes.\n\n   **This is the near plane only; it is not an instruction to fill the frame.**\n   A foreground object sits close to the lens and slightly soft, and it frames\n   rather than competes: one already in the location, never a prop invented for\n   the shot, and never something that crosses a face. Where the camera travels,\n   check it against the measured warning that a single large near object sweeps\n   the whole frame on a lateral or orbital move and drags the subject with it\n   (`references/PRESETS-CAMERA.md`, *If you are generating a start frame too*) —\n   many small cues beat one big one. The `Atmosphere` presets in that same file\n   are the other half of this: the planes give the eye somewhere to travel,\n   atmosphere is what physically separates them.\n\n   **Adapted from the Skool course's framing lesson, and not measured here**\n   (`research/ai-video-bootcamp/ANALYSIS.md` §10.3). It is free — it changes no\n   field and costs no call — which is why it is adopted on his demonstration\n   rather than held for a probe of ours.\n\n   **`negativePrompt`, where the image model's schema declares one.** These are\n   all image-model work, so the guardrail the sheets already use applies here\n   unchanged (`../film-assets/references/ASSET-SHEETS.md`): for live action, the\n   medium ban — the words that rule out drawing, animation, rendering and\n   plastic-looking skin. `picsart_film_compile_asset_prompt` returns it in\n   `negativePrompt`; take it from there rather than writing it. Never as prose,\n   never in a video block. The lettering ban below is scoped more narrowly than\n   this one.\n\n   **The lettering ban goes on the scene picture and the wide — NEVER on the\n   room map.** The map's prompt asks in as many words for a label\n   on each side, *A on the north side, B on the east side*, and those labels are\n   the only reason the map exists: they are read off it to write the geography\n   line that every prompt of the scene then carries. Banning lettering there\n   destroys the artifact. On the three that do take it, the compiler adds the\n   lettering ban — every form of on-image text, from signage to watermarks — to\n   the medium ban above.\n\n   **A film that needs a sign does NOT ask the model for it (corrected\n   2026-09-11).** A story with a readable shop name, a door number, a headline\n   on a screen or a figure on a phone still gets the ban — because the model\n   cannot hold clean typographic text, which is the same reason\n   `film-finishing` already refuses to generate the film's titles and makes\n   them as overlay tracks instead. In-world text is the twin that rule went\n   silent on. Keep the words out of the generation and **lay them in as a\n   compositor layer over the finished clip** (`../film-edit/SKILL.md`),\n   positioned so they read as part of the frame. The ban and the wanted text\n   are not in conflict: the ban stops the model inventing lettering, and the\n   layer supplies the lettering the film actually wants, clean.\n\n   An earlier version of this note said to name the exact string on the\n   *Visible* line and let the model render it. That was wrong, and the\n   practitioner evidence is explicit — numbers rendered into a generated shot\n   come back glitched, so they are typed out separately and laid over the clip\n   afterwards, where nobody can tell they were not always there\n   (`research/ai-video-bootcamp/ANALYSIS.md` §9).\n\n   **Why the lettering ban is worth its own words.** The video prompt has\n   carried the handbook's no-subtitles line on every generation for some time\n   (`references/PROMPT-BLOCKS.md`, item 7). The still that every one of those\n   videos is\n   built from carried no equivalent, so a model was free to invent signage,\n   labels and shopfront text in the picture, and the video then faithfully\n   reproduced whatever it invented. This is the same shape as the medium guard\n   above: a rule that held one end of the pipeline and went silent at the\n   other. What it is aimed at is **invented** lettering — the garbled pseudo-text\n   a model reaches for when it has to fill a sign it was never told about — and\n   not at text the film actually wants, which is why it has the two exceptions\n   above. That failure is not hypothetical: **the run QC below already rejects\n   \"random pseudo-text\" as an artifact**, beside hands and teeth. We were\n   catching it after a video had been paid for and rejecting the take; this\n   catches it one step earlier, in the picture the take is built from.\n\n   **The wide is the authored source picture.** Its compiler input carries\n   the locked medium, skin treatment, lettering constraints and all three\n   `space` planes. Its opening crop inherits those pixels. The map uses the\n   checked wide as its reference and the compiler's map template. Preserve\n   each compiler result's `negativePrompt` and matching `promptToken`.\n\n   Attached: the identity view **and** the wardrobe view of every present\n   character — both, always (rule 7, `../film/SKILL.md`) — and, for a real\n   place, the user's photographs of it. **Nothing else**: no room map, no prop\n   plate, no extra still. On 2026-09-08 five references went into a two-shot\n   and the faces were outvoted; the roll that passed carried the faces only. A\n   prop is named in words with its count on the *Visible* line (*\"one flask,\n   on a cross-body strap\"*). The handbook writes 16:9 or 9:16 here; ours is\n   the film's ratio — the one substitution. Recorded on the scene as\n   `pictures.scene`. **Looked at as soon as the plan lands**: each face\n   against its identity view on the preview URL (`film` rule 4);\n   a wide with one wrong face is regenerated, and its cut and map with it —\n   on 2026-09-08 three derived frames inherited one wrong face. **Two failures on faces in a row change\n   the reference set or the model, never a third roll of the same call.**\n2. **The wide — generated FIRST since 2026-09-23**, from the cast's views and\n   item 1's craft, at the film's ratio and 4K.\n   `pictures.wide`.\n3. **The room map — only when the scene needs one (2026-09-09)**: an\n   interior, or any scene whose cards cut between two or more walls behind the\n   people; a single outdoor place with one background gets no map, its wide is\n   the geography (two of three maps came back wrong on 2026-09-08 for a square\n   that needed none). When needed, from the wide — the handbook's *location\n   sheet*. Its prompt asks for a top-down view of the place in the photo with\n   every corner and side visible, no people in it, each side lettered A to D\n   clockwise from north, the colour and realism of the source kept, 1:1.\n   `picsart_film_compile_prompt` pastes it (a typo in the handbook's own\n   wording, \"one\" for \"on\", is corrected there, once). Attached: the wide. **One map per place and time of day**,\n   made from the first scene played there and reused by every later scene at\n   that place — the handbook makes one per scene; one per place is what keeps\n   the walls the same across scenes, and it is ours, deliberately. When the map\n   lands, read it and write its four sides into the location map (the geography line):\n   *\"Side A — the shelving wall; Side B — the roller door; …\"*. Recorded on the\n   location as its `map` view.\n\n   **Left and right are read off the scene picture, not off the map\n   (2026-09-09).** Who is frame-left and who is frame-right in the scene\n   picture goes into the geography line, and the sides never change inside a\n   scene (`references/SEAMS.md`, screen direction). The map says which wall is\n   behind each face — **the background side is the wall behind the face of the\n   person facing the camera**, read off the map, never copied from an example.\n   On 2026-09-08 a reverse was written with Nen's shoulder frame-right while\n   the master had her frame-left, and cost a round. **What a reverse changes**:\n   whose back is in the foreground, the background wall, and the pointing hand\n   becomes the other hand — say it in the shot block (*\"Subject #2 hand\n   pointing should be the other hand\"*), because the model confuses hands\n   across a reverse.\n\n**Check each picture against the one before it as results land** — with\n`picsart_view_image` on the preview URL (`film` rule 4), beside\nshowing it (`film-assets`, *Show it the moment it lands*) — the same faces as the\nidentity views, the same grain and colour, the same room — and re-dispatch on\ndrift. No picture becomes a start frame or a reference until its check is\nback. On the\nwide, the handbook's questions: did the room stay the same room; did the\ncharacters keep their left and right; is anyone looking at the camera.\n\n**When a picture comes back wrong, read it back to the line that made it\n(2026-09-13).** The rule above says how many times to try — two failures on\nfaces in a row change the reference set or the model, never a third roll of the\nsame call. It does not say *what to change*, so a picture that came back plastic\nand a picture that came back generic have been getting the same treatment: the\nsame prompt, rolled again. Every roll is a charged generation. Read the defect\nback to the line of the thirteen that owns it, change that line, and only then\nre-dispatch.\n\n| What came back | The line that owns it | What to change |\n|---|---|---|\n| the person could be anyone; the face is not theirs | `Subject description`, and the attachments | the exclusive tell is missing or is not exclusive; or the identity and wardrobe views were not both attached (rule 7) |\n| the whole frame reads as a render; skin is plastic | `Visual tone`, and `negativePrompt` | check the skin clause and the medium line are on line one **verbatim**, and that the ban field was actually filled. If both were there, this is not a wording problem — it is the reference set or the model |\n| the place is a stock backdrop; it is nowhere in particular | `Setting` | thin setting line, or the location's anchor object was never named — a place without its anchor is \"somewhere\", and somewhere drifts |\n| the people look pasted onto the background | `Foreground, Midground, Background elements` | a plane was left unnamed — most often the near one. This is the defect that line exists to prevent |\n| the frame is inert; everyone is centred | `Positioning in the frame`, `Composition` | no placement was given, or the frame needed organising and the composition slot was left empty |\n| invented lettering, garbled signs and labels | `negativePrompt` | the lettering ban was not added — and check it was not added to a room map, where it destroys the artifact |\n| something the shot needs is simply absent | the whole prompt | it is overloaded. **Cut, do not add** — the model drops what it cannot fit, and another clause makes it worse |\n| a prop is missing or there are two of it | `Visible / Not visible` | props are named there with their count, and every prop needs its plate |\n\n**Two things this table deliberately does not do.**\n\n- **It does not authorise more rolls.** It sits *inside* the two-failure cap, not\n  beside it: it is how you spend the second attempt well. A third roll of a\n  changed prompt is still a change of the reference set or the model.\n- **It says nothing about where in the prompt a line sits.** The course argues\n  both sides — one lesson says move an ignored detail closer to the *beginning*,\n  its colour cheat-sheet says the model weights the *end* — and demonstrates\n  neither. The thirteen lines stay in the handbook's order.\n\n**One row the course would add, and we do not have.** Its own answer to the\nplastic-render row is that the light has no named source, and its fix is a\nlighting instruction in the picture prompt. We have no lighting line here by\ndecision (2026-09-11), so the row above names the levers we actually own\ninstead. Do not re-raise it unopened\n(`research/ai-video-bootcamp/ANALYSIS.md` §4.12).\n\n**Adapted from the Skool course's prompt-diagnosis checklist and mapped onto our\nthirteen lines; not measured here** (`research/ai-video-bootcamp/ANALYSIS.md`\n§10.4). It changes no field and costs no call.\n\n**One board for every scene's pictures at once** (user's choice, 2026-09-08,\nas the cast board): `picsart_asset_review`, split past 12 tiles, one tile per\npicture — `tag` the scene and the picture (`sc03 · scene picture`, `sc03 · OTS\nover @cal`, `@garage · map`), `prompt` the picture's prompt, `info` the cuts it\nserves, one `judge` line: scene picture *\"the scene as the card designs it —\nthese faces, this room, real.\"*; wide *\"the same room, the people small and\nfar.\"*; map *\"the room from above, four sides labelled, nobody in it.\"*. Feedback per\n`../film/references/WIDGET-FEEDBACK.md`: `approved[]` and `changes[]`, nothing\ndecided by silence. **A change repairs that picture and triggers an impact check\nof its dependents** (`../film-assets/references/ASSET-EFFICIENCY.md`). Rebuild\nonly images whose required content became invalid: a facial-expression correction\ndoes not remake an unchanged room map.\nGeometry or lighting changes can affect many views; inspect rather than assume\nreuse. Record the reuse/repair decision and source versions. Approved pictures are saved with the scene\n(`film.json.scenes[].pictures`, the URLs the save hands back) and are what the\nrun carries; the map and the wide are the location's views\n(`../film-assets/references/ASSET-SHEETS.md`, *The location*), saved through\n`picsart_save_asset` as its row. Two adjacent cuts never open on the same\npicture (`references/SEAMS.md`).\n\n**The animatic stays on request** — *\"let me see it as stills first\"*: the\nscene pictures cut in order at each shot's `sec` — a montage bootstrapped\nwith each picture as a clip (`content.asset.type: \"image\"`, `duration` = the\nshot's `sec`) and opened as `scene` in `picsart_scene_editor` — played at the\nfilm's real length, so the ±10% runtime gate is checked against the reply's\n`duration` before anything renders; ask them to watch it once without stopping — playing finds pacing,\nscrubbing finds frames. Rendering it to a file is charged and almost never\nneeded.\n\n**Dialogue durations come from the words, not from a pre-generated line.** A\nline's `sec` is its word count at ~2.5 words per second plus the audio line's one\nsecond of silence, snapped to nothing — no line is generated to be measured\n(retired 2026-09-04: the model treats a cut time as a share of running time, not\na frame-accurate mark, so the precision was never real). The run's total snaps\nto what the model offers; the shots inside it keep their estimates.\n\n**An `END FRAME` stays an editorial tool, on request, per run** — a second\ncomposed image the run arrives on, for a designed transformation or a match cut\ninto the next run; generated FROM the scene picture (image-to-image), never rolled\nfresh, and never on a held look or a line delivered in stillness, where you want\nlife rather than interpolation.\n\n**Scene-level changes propagate by content.** A weather, light, or time-of-day\nchange updates the SCENE entity once and recompiles affected headers. Check its\npicture dependencies under `ASSET-EFFICIENCY.md`; remake views whose required\nillumination/state changed, not every file solely because it shares a scene ID.\nDo not retain a reference whose pixels contradict the new state.\n\n## Step 4 — one run before the rest\n\n**With the shot list approved, the sheets locked and the scenes' pictures\napproved, buy ONE run before dispatching the rest.** Not a sample of the batch — a test of the path. It answers, for the\nprice of a single generation, what a whole-film dispatch would answer\nexpensively and all at once: does the video path work end to end on this\ndeployment, does the chosen model hold the locked identity across its own cuts,\ndoes it make the cuts it was told to (count and approximate times), does\nlip-sync land on a spoken line, and is the recipe (model, resolution, run\nlength, the reference order, block order, how the cut list is phrased)\nworth saving and reusing.\n\n- **On a film that fits one run, the test run IS the film.** There is nothing\n  to hold back; buy it with care, judge it on the board, and the \"recipe\" you\n  save is the film's own prompt. On a longer film, pick the riskiest run — the\n  one with a *line* in it and the most cuts, since lip-sync and the cut count\n  are the two variables with the most ways to be wrong — never a throwaway.\n- **Say the arithmetic once, in credits, not in theory**: \"the film is one run\n  at ~120; a re-roll costs the same again\" — or, on a longer film, \"one run at\n  ~100 instead of the whole film at ~400 — if it holds, the rest go out in one\n  batch.\" Then ask, and wait for the yes — the plan is yours, the purchase is\n  theirs. *(Amended 2026-09-07: this line used to end \"that is a plan, not a\n  permission question; run it\", which is how runs went out unquoted.)*\n- **Then the conveyor.** A pass unblocks the whole batch — which is quoted and\n  confirmed like any other dispatch; a fail has cost one\n  run, and what it teaches (wrong model, a cut the model will not make, a\n  header it ignores, a descriptor too loose in motion) applies to every run\n  before any of them are bought.\n- **This is not the \"quick test shot\" in *Traps*.** That one is a test *before\n  the assets lock*, which is the gate itself. This is after the lock — the last\n  cheap question before the expensive pass.\n\nSave the winning recipe in `film.json`, per the handbook's own step for\nthis (\"Generation tests: choose model/method per shot; save recipes\"), and reuse\nit for the batch rather than re-deciding per shot.\n\n## Step 5 — iterations: edit, extend, or re-roll\n\nFor a note about the join between clips, route first to\n`../film-edit/references/JOIN-REPAIR.md`. Its diagnosis may select a deterministic\nedit or a separate connecting insert; the model-routing table below is not a\nreason to regenerate accepted footage. Run the prompt-verify step before\ndispatching the selected generative repair.\n\n**The note's meaning is the route, and the route is a model call — never a\nregeneration by reflex.** A note arrives with a selection — a stretch marked\non the scene editor's timeline (`scene_editor_feedback.timelineComments`, with\nits seconds), a pin on a clip (`comments`, with its `layerId`), or a sentence in\nchat about a shot — and the two together say\nwhich of three things is being asked. Derive it; do not wait for the word\n\"edit\" or \"extend\":\n\n| What was selected + what the note asks | It means | The call |\n|---|---|---|\n| a **stretch** or a clip, and the note is about **how what is there plays** — *\"make this more dynamic\"*, *\"he should look angrier here\"*, *\"slower\"*, *\"the mug should be white\"*, *\"the last 10 seconds are wrong\"* | change what exists, inside its seconds | **edit** |\n| a clip, and the note asks for **something that has not happened yet** and needs seconds the clip does not have — *\"in this scene the copter must land\"* when the clip ends with it still in the air, *\"let him finish the sentence\"*, *\"hold on her a beat longer\"* | continue the clip | **extend** |\n| a clip, and the note asks for the event **instead of** what is there in the same seconds — *\"the copter should land here, not hover\"* | change what exists | **edit** |\n| a note about the **whole run** — light, cast, the cut count — or the words *regenerate / redo / new take* | a different take | **re-roll** |\n\nThe test between the first two rows: **does the note ask for something after\nthe clip's last frame, or in place of what the frames show?** After → extend;\nin place → edit. A range selection is almost always an edit (they marked *this*\nstretch); a clicked clip with a new event is almost always an extend.\n\n**When the intent is clear, go — no confirmation.** Asking \"did you mean edit\nor extend?\" on a note that already says which is the ceremony this pipeline\nkeeps removing. **Ask only when the note genuinely reads both ways** — *\"make\nthe ending better\"* on a whole clip could be either — and then one short\nquestion naming the two readings in the user's own terms (*\"change how the\nlanding plays, or add the landing after what's there?\"*), then the call. Never\ntwo questions, never a menu of models.\n\nThe three calls:\n\n| The user says | The call | What goes in |\n|---|---|---|\n| **edit · change · fix · replace · remove · \"the last 10 seconds are wrong\"** — anything about what is *in* the clip | **the edit sibling (`shoot.editModel`)** | `videoUrl` = the clip (the run's file, or the piece the shot lives in); `prompt` = the change and *only* the change, naming the shot and its seconds; `imageUrls` = the same numbered views and frames the run had, so identity does not move; `generateAudio` as the run had it |\n| **extend · expand · longer · continue · \"add a beat at the end\"** — anything about *more* clip | **the extend sibling (`shoot.extendModel`)** | `videoUrls` = [the clip]; `prompt` = what happens in the added seconds, written as one more cut header (positions restated, the same references named by number); `duration` per the model's own definition — read `picsart_model_params` and preflight before the first use, and record which it is |\n| **regenerate · redo · new take · \"roll it again\"** — or a note about the whole run: light, cast, the cut count | **a fresh roll of the run** | one header or block changed, the rest byte-identical; it costs the run, said in credits before it goes, and every other shot comes back different — a fresh roll is a fresh roll |\n\n### Extend input gate — probe before preflight (measured 2026-09-12)\n\nThe live Seedance 2.5 extend path exposed provider checks that\n`picsart_preflight` did not catch. Before dispatching that sibling, probe every\ndistinct input video and enforce both limits yourself:\n\n- every input video is at least **1.8 seconds** long;\n- the **sum of all input-video durations is at most 30.2 seconds**.\n\nThese are observations from the current `dreamina-seedance-2-5` r2v worker, not\ntimeless catalog doctrine: read `picsart_model_params` first and treat a newer\nlive schema or provider diagnostic as authoritative. Preflight still runs after\nthis gate for payload validity and price, but a green preflight alone is not\nevidence that these two duration checks pass.\n\nFor a two-sided seam repair, never send the whole following run merely to show\nthe target pose. Make a deterministic excerpt of its opening, normally **2.0\nseconds**: `picsart_media_apply_scene_template` with `mpscene://montage`, one\nclip and the required trim → `picsart_media_validate_scene` →\n`picsart_media_export` as mp4 → probe the exported excerpt again. If the source\nside plus that excerpt still exceeds the total ceiling, trim the source input to\nthe shortest motion-bearing tail that the model accepts; keep the original\ntakes untouched.\n\nThe measured extend schema accepts `videoUrls` and no `imageUrls`. Do not attach\nreference pictures when the live schema omits them. On hosts whose generic\n`picsart_generate` surface exposes only singular `videoUrl`, put the model's\nmulti-video field in `extra: { videoUrls: [...] }`; the generate tool flattens\n`extra` before model validation. Pass `videoUrls` directly to\n`picsart_preflight`. `duration` is the requested generated continuation, not\nthe sum or trim length of the source videos.\n\nEvery retry gets a fresh returned job handle. Put that exact handle on the new\nrender monitor row; never reopen a failed handle or let an old monitor stand in\nfor the retry.\n\n**Regenerating a clip the user wanted kept is the failure this section exists\nfor.** A selected clip with the note \"expand\" was answered with a new prompt\nand a fresh roll (reported 2026-09-04): the footage they liked was gone and a\nrun's price was paid for a beat's worth of new seconds. The note said what to\ndo; the selection said where; nothing in it asked for a new take.\n\n**What each call must carry so nothing breaks:**\n\n- **The same references, the same numbers.** `imageUrls` for an edit is the\n  run's list verbatim — same sheets, same order, same roles in the prompt — so\n  the edited clip's faces are anchored by the same pixels the run was. Never a\n  fresh selection, never a re-ordering.\n- **Verbatim is the floor, not the ceiling: an edit that opens the frame up\n  needs the place's pictures ADDED (2026-09-10).** The run's list anchors what\n  the clip already showed. The moment the edit changes what is *visible* — a\n  pull-back, a wider reframe, a camera move that reveals a skyline, a street, a\n  far wall — the newly revealed area is anchored by nothing, and the model\n  invents it. So before an edit like that goes out, ask what the new framing\n  will show that the old one did not, and put the **map and the wide** of that\n  place in `imageUrls` (appended, so the existing numbers do not move) with the\n  geography line in the prompt. **The failure this is written from\n  (2026-09-10):** clip 3 carried only a tight frame of its setting; the map and\n  the wide were not in the run and so were not in the edit either; the edit\n  pulled back, and the skyline it revealed was a new place. Rule 10.\n- **The change alone, named to the second.** An edit prompt is *\"cut 3\n  (13.0–19.0s): the mug on the bench is white ceramic, not steel; everything\n  else unchanged\"* — not a re-description of the shot. A re-described shot is a\n  re-rolled shot wearing an edit's price.\n- **An extension is a header.** The added seconds are written like any cut\n  header of the run — positions restated, the action in beats, the line in\n  quotes with its silence, the references by number — because the model reads\n  the continuation the same way it read the run.\n- **Frames as references are exported at full size** (step 6, *Frames the model\n  reads*); a thumbnail is rejected or anchors a soft frame.\n- **Preflight, quote, then wait.** Each sibling has its own rate; the number\n  goes to the user before the call and the call waits for the yes. A repair is\n  a purchase like any other.\n\n**After the call:** a focused join candidate stays separate from the accepted\ncut and follows `../film-edit/references/JOIN-REPAIR.md`'s comparison workflow.\nOtherwise, the result goes into the cut and the whole cut goes back into\n`picsart_scene_editor`, with one line naming the stretch that changed; an edit\nreplaces the clip's\nurl in `runs[].pieces` (the shots re-point to it, trims re-derived by the user\nonly), an extension appends a piece. Split the result at its actual cuts before\nanyone judges it — an edit that changed the cut count is a failed take like any\nother. Log which call it was, with its prompt and rate.\n\n**Rules that hold across all three:**\n\n- One change per call: one thing edited, one beat extended, one header\n  re-rolled. Two changes at once and you will not know which one worked.\n- **Log every generation**: run or piece, which call, prompt version, what\n  changed, result URL, verdict per cut. `film.json` runs carry `promptVersion`,\n  `takes`, `editPasses`, `extends` and `pieces`; the prose log lives in\n  `docs/log.md` when there is a disk.\n- A clip that will not take an edit in **two** tries, or a run that will not\n  land in **four or five** rolls, has a wording problem exactly never. Simplify\n  the header that keeps failing: drop an action, change the angle, lengthen\n  the beat.\n\n## Step 6 — select and accept takes\n\n**The board opens on the run as delivered — split at its cuts, untrimmed.**\nWhen the batch lands, **split every run's take at its delivered cuts**: look at\nthe frames either side of each declared time (`picsart_media_contact_sheet`, or\nthe scene editor's own playhead), place a compositor split where the picture\nactually changed, write the result to `runs[].cutTimesActual`, and treat a cut\ncount that disagrees with the cut list as a failed take before anything else is\njudged. The split is bookkeeping over one source file and costs nothing; it is\nwhat makes every shot of the run a clip again. Then open the board on exactly\nthat: every shot a cell bounded by the model's cut, no trims derived, nothing\nshaved. **The automatic rough cut is off (2026-09-04)** — the model already made\nthe cuts, and a video edge is joined by the handbook's angle change\n(`references/SEAMS.md`), so there is nothing to align;\n`film-edit` keeps what the pass did and why it is parked. Trims are the user's,\nmade in the scene editor, and land as `trim` with `trimSource: \"user\"`. With\nseveral takes competing for a run, you pick the stronger, splice it in and name\nthe other in a clause (below): the scene is one timeline and cannot hold two\nversions of the same shot. Say nothing about cutting\nbefore the board opens — there was no cut; say what came back, and open it.\n\n### A batch that lands opens a board. Every time, without being asked.\n\n**Generations coming back IS the trigger** — not the user asking to see them,\nnot the takes being good, not the batch being small. First pass, retake, single\nshot, a re-roll after a model swap: material arrived, so a board opens in that\nsame turn. There is no state of the world in which the right response to a\nfinished generation is a paragraph about it.\n\nThis is a reported failure, not a hypothetical. Four takes came back; the reply\nread *\"1A, 2A, and 3A all check out clean on Seedance — matching their beats, no\nissues. Only 4A still needs work\"*, then offered a choice between a stronger\nprompt and splitting the shot. No board was opened. The user's next message was\n*\"Why don't you open view review widget?\"* — and by then they had been told\nthree of their four shots were fine without having seen a single frame of any of\nthem. Three separate rules broke at once:\n\n- **The board never opened**, so nothing was reviewable.\n- **The verdict was self-certified in prose.** \"Matching their beats, no issues\"\n  is a taste verdict on material the user has not watched. It is the same class\n  as the asset-sheet failure in `film-assets` (\"never self-certify identity in\n  prose while the user has seen none of the frames\"), and it is worse here,\n  because a take is what they are paying for. **You may say what you observed;\n  you may not say it passed.** \"4A drifts the same way on a third model\" is an\n  observation and belongs in the message. \"1A, 2A and 3A check out clean\" is an\n  approval, and approval is theirs.\n- **The turn ended on a menu.** Two craft options were offered as a question\n  when the pipeline already answers it: a third take drifting the same way on a\n  second model is not a model problem and not a wording problem — step 5's rule\n  is that a shot which will not land is *simplified*, split in two or reduced to\n  one action. Do that, say you did it, and put it on the board. A question is\n  for a decision that is genuinely the user's; \"which of these two repairs\n  should I try\" is your job.\n\nSo the shape of that turn should have been: open the board with all four takes,\nsay in one line that 4A drifts toward calm on a third model and is being split\nrather than re-worded, and let them verdict the other three themselves.\n\nReview takes in **one `picsart_scene_editor` that carries the whole film,\nby default** (rule 8, `../film/SKILL.md`). Focused join comparisons follow\n`../film-edit/references/JOIN-REPAIR.md` instead, without promoting their preview\nto the accepted cut. For ordinary review, not the batch that was just\ndispatched — the film: every accepted take plus the new one, in playback order,\nbootstrapped into one montage scene (`../film-edit/references/ASSEMBLY.md`) and\npassed as `scene`. Two accepted videos and a third just delivered is a scene of\nthree, the new one in its story position. `videoUrl` is for a film that has\nexactly one video and nothing else to play beside it.\nOn a run the scene's clips are the run's cuts, so a comment maps straight back\nto the header that produced it — by the pin's `layerId`, or by its time\n(`../film/references/REVIEW-FEEDBACK.md`, *Mapping a comment back to a shot*).\nThe editor carries no prompt or model, so keep that link in `film.json`. The\nscene is **one** timeline, and that timeline is the film.\n**Never one view per take**: three takes on three boards means three separate sends, and the\nfirst send moves the conversation forward while the other two boards die\nunanswered — the documented flunky-confirmation failure. One board, one send,\nverdicts for the whole batch. The same rule covers the editor's own edits: when\nthe user trims or splits in it, that cut is theirs and already seen — record it\nfrom the returned `document` and say so, never an editor per piece\n(`film-edit`). If several boards are ever genuinely open at\nonce, one board's feedback is one item of the queue: act on it, return to the\nqueue, and advance nothing until the queue is empty or the user says move on.\n\n**Every retake is seen before it becomes the cut — and the surface it goes on is\nthe scene editor (2026-09-07).** `picsart_video_compare` is out of this\nflow: one surface judges picture. What survives from the old compare rule is the\npart that mattered — the user sees **every** retake, not just the first, and\nnothing becomes the cut behind their back. The failure above ran a shot through\ntwo models and a third generation without the user seeing any of them, which is\nhow \"still needs work\" became something only I knew.\n\n- **A retake goes INTO the cut, and the cut goes up.** Swap the new take in,\n  rebuild the scene, open the editor on the whole thing, and say in one line\n  what changed. Two versions of one shot are never both in the scene: it is the\n  timeline, so they would lay out end to end as two different shots of twice the\n  real length, with no way to say which wins.\n  This ordinary-review rule does not forbid explicitly labelled join comparison\n  previews under `JOIN-REPAIR.md`; those are not the accepted movie timeline.\n- **With two takes of one shot in hand, you pick — and say so.** Which of two\n  candidates is stronger is a craft call, like which repair to try; make it,\n  splice it in, and name the other in a clause: it is in the log, one word away.\n  Asking the user to choose blind between two files is the old compare board's\n  job, and it is gone.\n- **An edit or extend return is the same path** — into the cut, the whole cut\n  back on the board, one line naming the seconds that changed. That is where an\n  edit which fixed the hand and lost the light actually shows.\n- **Going back stays free.** Every superseded url stays in the log, so \"use the\n  first one\" is one call and no credits. That is the honest replacement for a\n  lockstep A/B: the comparison happens in sequence, inside the cut, and the old\n  take is a word away.\n- **A re-rolled run** replaces the run's take the same way: the new take split\n  at its own cuts, its shots as the scene's clips, and one line on what you\n  changed between the takes.\n- If a shot is on its third attempt, say the attempts are converging on nothing\n  and that the shot needs splitting. The board is where that gets said.\n\nContract in `../film/references/REVIEW-FEEDBACK.md`.\n\n**Frames the model reads are exported at full size, never thumbnailed\n(2026-09-04).** `picsart_media_contact_sheet` renders thumbnails — 480 px wide\nby default — for *looking*; fed to the model as a frame, one came back 480×270\nand Seedance rejected it (it refuses a picture with **either side** under 300 px\n— width counts as much as height — and a small frame that is accepted anchors a\nsmall, soft composition). A frame that will\ntravel in `imageUrls` is extracted with `picsart_media_export`: a one-layer\nscene of the run, `mediaType: \"png\"`, `startTime` at the wanted second, at the\nrun's native size (`picsart_media_probe_media` the run first for width, height\nand fps). Then **probe the exported frame**: if its width or its height is below the\nrun's, you have a thumbnail — stop and re-extract; **and neither side may be\nunder 300 px**, which is the check a 252-px-wide crop got past on 2026-09-09. It is an export (a render wait, a\nDrive file, and it counts against the reference byte budget), and it is the\nonly way a frame from a take becomes a `START FRAME`, `END FRAME` or `FRAME\nREFERENCE`.\n\n**Kept frames are anchors, not notes.** The scene editor has no keep-frame\nbutton: a pin whose `instruction` asks to keep what is on screen (*\"keep this\nface\"*, *\"this frame is right\"*) is a kept frame at its `time` — a second on\nthe scene's timeline, so map it to the take's own second first\n(`../film/references/REVIEW-FEEDBACK.md`). Each one survives pixel-for-pixel:\nexport that frame\nfrom the take at native size (above — never a re-render, never a thumbnail) and\nfeed it back. On a run it\ngoes into the re-roll's `imageUrls` labelled as that cut's frame (*\"IMAGE 9 —\nFRAME REFERENCE for cut 3: shot 3 as approved, hold this face and this\nframing\"*), named in the references header and in that cut's header, or as the identity\nreference for an edit pass on that stretch; two kept frames in one cut label as\nits opening and closing frames. A user who wants a clean rebuild says so, or\nremoves the pin before sending: if a keep pin is there, honour it. Kept frames\ncan also ride on an approved cut, where they are simply on the record for\nwhatever gets regenerated later.\n\n**When the face is right but the shot is wrong, keep the frame.** Do not throw\naway an identity the model just got right: save the best frame of that take and\ncarry it into the re-roll as that cut's labelled `FRAME REFERENCE`, with the\nheader's motion rewritten and nothing else — the action, the camera, the\nprogression, and nothing that re-describes what the frame already shows. This\nis the handbook's own frame-reuse technique, and it is also how a good frame\nfrom one shot becomes the `FRAME REFERENCE` of a later one.\n\n**When a run changes a place, its frames become the next run's pictures of\nthat place — automatically (2026-09-08, the handbook's continuity rule).** The\nwritten prompt cannot carry state: a room wrecked in run A, a character covered\nin dust, exists only in run A's frames, and the approved scene pictures now\nshow a clean room that *fights* them. So: the story says where the\nstory changes a place (the fire, the fight, the flood); every later run at that\nplace is **dependent** and waits for run A's accepted take, and every other run\ndispatches together as now. When run A's take is accepted, pull the frames\nwithout a stop: list every angle the dependent run will see; for each,\n`picsart_media_contact_sheet` at the times of run A's last beat on that angle\n(up to eight thumbnails, free) and pick the frame that is sharp, mid-action\nwhere the next run continues the movement, and shows the place in its new\nstate; export each pick at native size (`picsart_media_export`, above) and\nprobe it. **One frame per angle** — a frame is one camera angle and carries the\nstate of the scene, not the geography of the room; an angle with no usable\nframe means run A holds that angle for a beat (an extend) or the dependent run\nis not ready. The exported frames **replace** that place's pictures for the\ndependent run — scene picture, and the map when the room's shape\nchanged (a new map from the widest frame with the handbook's map prompt) —\nnever attached beside them: two versions of one room is exactly the\ncontradiction the rule removes. **The same for a person the earlier run\nchanged**: the frame that shows the state becomes that person's state view and\nreplaces their wardrobe view in the dependent run (rule 7, 2026-09-10) — a\nclean coat beside a torn one is the same contradiction. Record them as `pictures.<state>` on the scene,\nname them in the `notes` line when run A's scene opens in the scene editor so\nthe user sees which were chosen and can swap one, and dispatch the dependent run — its charge was quoted\nwith run A's in one batch and approved once, so nothing waits on a second yes.\n\nA take is accepted against the checklist, not vibes:\n\n- Characters and location match their references — face, costume, space.\n- No artifacts: hands, teeth, extra fingers, drifting objects, random pseudo-text.\n- **Every declared cut landed as a cut** — the right count, each near its\n  time, a hard cut and not a whip pan, a morph or a dissolve. A run that made\n  the wrong cuts is rejected whole, whatever else it got right: its shot\n  boundaries are not where the plan says, so nothing downstream lines up.\n- Camera movement is what the shotlist ordered. **When the camera is wrong, it\n  is a camera-change retake — and an ANCHORED one.** Swap exactly the move\n  preset (one block-7 recompile of that shot's header) and never re-prompt the\n  whole shot over a camera verdict. On a run this is a re-roll with one header\n  changed — a camera move is motion, which an edit pass does not change — and\n  the anchoring is the same numbered references, so nothing else in the call\n  moves.\n  - The order arrives as a comment that asks for a different camera move and\n    nothing else. The editor has no preset panel, so read the words; a move\n    named in them is the shotlist board's own vocabulary, so it recompiles to\n    exactly one block.\n  - **Anchor it.** Take a frame from the start of that shot's source (the\n    commented clip's source url) and\n    send it as a *reference image* beside the shot's locked asset references —\n    all of them as references together — then name the opening frame in the\n    prompt. Cast, wardrobe, set and light survive as pixels; only the camera\n    changes. Not a first-frame role (a frame role and reference images are\n    alternatives, and the pair is rejected after the wait), and never the old\n    take as a reference video (a reference video supplies camera motion, so it\n    reinstates the move being changed).\n  - A note that moves the camera **and** something else is an ordinary\n    regeneration — an opening-frame anchor would fight a new lighting note.\n  - **For a user-requested join repair, distinguish a crop from a new camera\n    move.** Existing-pixel reframing follows `film-edit`'s compositor guidance\n    after checking the live operation; it is not a generative camera change.\n    The old crop-path implementation was removed (2026-08-31). This\n    routed a dead-but-usable framing note to a crop-path push-in in the export,\n    free instead of a retake; the export half of crop-path was never wired up,\n    the code is deleted. Do not infer that all compositor crops are unavailable;\n    genuine new camera motion still needs a generative repair.\n- The performance fits the task; the line reads; lip-sync holds. **\"The line\n  reads\" has a method** when the classic Picsart API plugin is installed:\n  `video-transcribe-audio` the take and diff against the scripted line — it\n  catches lip-sync saying the wrong words and verifies the one-second silence\n  tail. Without that plugin, judge by ear and say so.\n- **Look INSIDE accept candidates before promoting**: a take's first frame\n  hides mid-clip morphs. On the takes you intend to accept (only those —\n  contact sheets cost render time, not generation credits), render 3–4 frames across the take\n  (~25/50/75%), view them in one batched `picsart_view_image` call, and check\n  identity and artifacts at each.\n- It will cut with its neighbours: a movement written to carry across a cut\n  ends mid-move and is picked up; a look that answers a thing leaves frame on\n  the right side; the cause is shown before the answer. At a video edge, the\n  last shot ends in the middle of its movement and the next video's first shot\n  is a clearly different angle (`references/SEAMS.md`). If a join fails, inspect\n  whether existing footage can be recut before deciding it needs new material\n  (`../film-edit/references/JOIN-REPAIR.md`).\n- Palette and light match the world.\n\nAccepted: the run's URL and its `cutTimesActual` into `selects/scNN/` (and\n`picsart_drive` — CDN links expire), its prompt saved as the final version,\nevery shot in it status `final`.\n\n## Step 7 — run it as a conveyor\n\nWork in scene batches, never scattered shots — a scene keeps light and continuity\nin one head. A run at a place an earlier run changed is dependent and waits for\nthat run's frames (step 6); every other run goes out together. While scene N iterates, shotlist N+1 and hand scene N−1 to\n`film-edit` for parallel assembly (that is where reshoot orders come from). Track\ndaily output in shots-final-per-day against the target and say so when the pace\nwill not make it.\n\nGate out (per scene block): every run's take accepted and split at its delivered\ncuts · all shots `final` in selects · final prompts versioned · log complete ·\nthe run watched on the board at its cuts and its run edges (the ten-second\nversion of the edit's join QC, before problems compound).\n\n## Costs\n\n| Free | Charged |\n|---|---|\n| shotlist, shot design on the cards, run grouping, prompt assembly, preflight, splitting a delivered run at its cuts, splicing a repaired piece back, animatic review on the board when requested, the handoff frames of a changed place (contact-sheet thumbnails to choose, full-size exports to use — render time, not credits), the 1280 px check copies of every picture (`picsart_media_export`), frame exports for anchors (`picsart_media_export` — render time and a Drive file, not credits, 2026-09-07), `picsart_shotlist_board` / `picsart_scene_editor` (renders nothing) | every scene's pictures — scene picture, wide, coverage, a room map when needed (image rates, one board for all scenes), cut-point and take-QC contact-sheet frames (per frame), every draft and re-roll (`picsart_generate`, video rates — billed at the generated length, which is the reason everything upstream of this skill exists), every edit or extend call (each sibling's own rate — preflight first) |\n\n## Traps\n\n- Dispatching on a number the user never saw, or on a yes that covered an\n  earlier call. Every charged video call carries its own quote and its own yes;\n  the forecast is not a purchase.\n- Generating a \"quick test shot\" for an unlocked scene. That is the gate, and it\n  exists because half of early material gets redone.\n- Pasting a descriptor into the prompt, whole or shortened. Since 2026-09-09\n  the pictures carry identity and the prompt names them by number\n  (`references/PROMPT-BLOCKS.md`); a paragraph beside the pictures makes the\n  model average words and pixels.\n- Dropping the geography line or the map to save tokens — characters swap\n  sides between shots and the scene stops cutting.\n- Dispatching a prompt that points at a panel of a bigger picture. That is a\n  lint error, not a phrasing choice: the reference is wrong, and the crop that\n  fixes it is free.\n- A run without its scene's pictures, or a place generated empty from its\n  descriptor. The handbook's order is scene first, place from it — an empty\n  location renders unreal, and a run without the pictures asks the model to\n  invent the room (2026-09-08).\n- Attaching the approved scene pictures beside frames from a run that changed\n  the place. Two versions of one room; the frames replace the pictures.\n- Cropping, mapping or using a wide before its visual check has passed.\n\n- A third roll of the same two-shot after two failures on faces. Change the\n  reference set or the model.\n- Iterating two variables at once. When it improves you will not know why.\n- Re-submitting a generation because the call \"timed out\". The render survived\n  the severed call and already charged — poll `picsart_job_status` first,\n  always.\n- Letting accepted takes sit in the raw pile — the editor must only ever see\n  selects.\n- Generating a scene shot by shot out of habit. Measured worse (2026-09-03):\n  the run is the initial-production unit; a scoped connecting insert between\n  accepted clips is the repair exception, not a new production default.\n- Treating the run ceiling as a reason to make one long shot. A 30s run should\n  usually contain several 3–8s shots; one 30s shot is a long take with its\n  reason on the card, not the default meaning of \"one run.\"\n- Filling the `startFrame` field on any video — a run, a five-second bridge, a\n  one-shot reshoot. It locks out `imageUrls`, and a frame shows only the people\n  in it (the 2026-09-08 bridge: one face in the frame, no picture of the other\n  woman, a long coat and two flasks). The start frame goes in *with* the\n  references, labelled `START FRAME` in the tagging header — every image\n  numbered with its role.\n- A person in a shot block without their identity and wardrobe views in `imageUrls`, or\n  an object named in two places (\"on her strap\" and \"in her hand\" is two\n  flasks).\n- A shot block that opens without its shot type and camera move. The model\n  guesses both (the handbook: *\"Tell it clearly.\"*).\n- A prompt that refers to the video before it — \"continuing from the previous\n  scene\", \"as before\", \"again\". The model never sees that video; write what is\n  in the frame now (`references/PROMPT-BLOCKS.md`, first language law).\n- A contact-sheet thumbnail used as a reference, a descriptor's picture or a\n  start frame. Thumbnails are 480 px previews for choosing; the frame is\n  exported at full size first (the 2026-09-08 reshoot failed on two of them).\n- Splitting a delivered run at its PLANNED cut times. The model cut near them,\n  not on them — split where it actually cut, or every trim downstream is off by\n  the drift.\n- Regenerating when the note asked for a change or a continuation. \"Make this\n  more dynamic\" on a marked stretch is an edit; \"the copter must land\" on a\n  clip that ends mid-air is an extend — with or without the words *edit* and\n  *expand*. A regeneration in their place throws away the clip they wanted to\n  keep (reported 2026-09-04).\n- Re-describing the whole shot in an edit prompt. An edit names the change and\n  the seconds, nothing else; a re-described shot is a re-roll at an edit's\n  price.\n- Feeding the model a contact-sheet thumbnail as a frame. A frame the model\n  reads is exported at the run's native size and probed before it goes.\n- Polishing re-roll 8 of a run whose failing header should have been simplified\n  at re-roll 4.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}