# Output spec ## Deliverables | File | Format | Size | Notes | | ------------------------- | ------ | ---------------------------------------------- | ----------------------------------------------------------------------------------------------- | | `board.json` | JSON | | The shot list: locks, captions, prompts, seconds, frame paths. Film-Skill shot fields. | | `frames/-1.jpg` | JPEG | 1280 × 720 (16:9) or 720 × 1280 (9:16) | One approved draft keyframe per shot, GPT Image 2 at medium (low for a rough pass), e.g. `01-establishing-frame-medium-1.jpg`. | | `board.png` | PNG | 2560 × 1440 (16:9 board) or 1440 × 2560 (9:16) | Title, idea, frames with number, slot, seconds, caption and camera note, price footer. All text local. | | `board.png.json` | JSON | | Layout record: grid, frames used, font, price snapshot. Read by check-board.mjs. | | `board-preview.webp` | WebP | 2048 px wide (1152 for a 9:16 board) | Optional, for a message or a web page; aim for 150 to 400 KB. | | `prices.md` | Markdown | | Every route, with and without audio, billed seconds, cost, source pages, whole-film estimate. | | `film.json` / `teaser.json` | JSON | | The handoff file for the Cinematic brand film or Destination teaser Skill. | Default settings: `openai/gpt-image-2` for the first frame without photos, `openai/gpt-image-2/edit` for frames with references (the approved establishing frame, the user's place photos, the product photo; at most 3), `quality` "medium", `image_size` 1280 × 720 or 720 × 1280, `output_format` "jpeg"; board 2560 × 1440, Helvetica, prices from `assets/video-prices.json`. ## Approximate cost (GPT Image 2 on fal, token-billed; prices read 2026-10-18) | Step | 6 shots | 5 shots | 4 shots | | ------------------------------------------------------------- | ---------------- | ---------------- | ---------------- | | Clean board at medium (about $0.044 a frame plus about $0.01 per reference) | about $0.31-0.34 | about $0.26-0.29 | about $0.21-0.24 | | Rough pass at low (optional; about $0.005 a frame plus references) | about $0.08-0.11 | about $0.07-0.10 | about $0.05-0.08 | | Clean board after a rough pass (each frame carries its rough frame) | about $0.37-0.40 | about $0.31-0.34 | about $0.25-0.28 | | One re-roll at medium | about $0.05-0.07 | about $0.05-0.07 | about $0.05-0.07 | | Price table, board layout, checks, handoff | free | free | free | `build-requests.mjs --stage estimate` prints the total for the real shot list (it counts the references each frame will carry); quote it and get one yes before the first paid call. The 6-shot OSTRA plan with a product photo and fictional people estimates at $0.34 for the clean board, $0.11 for a rough pass and $0.40 for the clean board after it. The sample run cost $0.53 by the lab's estimates (rough pass $0.14 at the figures then in use, clean board $0.39), with no re-rolls. GPT Image 2 is billed by tokens and fal returns no token count with the image, so check the fal dashboard after the run; fal's published per-image prices put the real charge at or a little under the estimate. ## Checklist Technical (`scripts/check-board.mjs`, exit code 0): 1. board.json has no `FILL:` left; shots numbered 1 to N; captions at most 60 characters, labels at most 18; durations whole seconds. 2. Every shot has a `frame` that exists, in the film's shape (16:9 or 9:16), at the planned size. 3. board.png is a PNG of the right size, composed from exactly those frames (the manifest matches), with no placeholder panels. 4. The prices on the board come from the current price file, and that file was checked within 90 days (a warning after 30). 5. With `--prices-md`: prices.md is from the current price file and the current shot lengths. With `--preview`: a WebP, at most 2048 px, ideally 150 to 400 KB. With `--handoff`: a film Skill schema, no FILL, no `{{TOKENS}}`, the same number of shots. By eye (open the board at full size, then each frame): 6. One place: the building, materials and landscape match from frame to frame (and match the user's photos for a real place). 7. One product: shape, colours and label match the product photo in every frame; read the label letter by letter. 8. People, if any, are fictional adults seen from behind, in silhouette or small; no visible face unless the shot is marked `face_visible` and planned for Kling or Veo; no extra or duplicated people; hands natural. 9. No text, signs, menus, logos or watermarks in any frame, other than the product's own label. 10. Every cut changes size or angle; no two neighbouring frames look alike. 11. Something in every frame can move (steam, water, fabric, light). 12. One look across the six frames, with only slot 5 changing the light. 13. Every label, caption, camera note, number and price on the board is spelled and numbered exactly as in board.json and prices.md. 14. 9:16 frames: nothing essential in the top 12% or bottom 20% (check with `--guides`). 15. Tasteful (`references/prompt-patterns.md`): people dressed, garments in place, nothing centred on hips. 16. For a real place or product: nothing shown that it does not have. If a check fails: at most 3 attempts per frame, change one thing per attempt and say which, compare each attempt with shot 1 and the user's photos, then deliver the best and say plainly what still differs. Text and layout problems are free to fix: edit board.json and recompose. ## Known imperfections in the sample The OSTRA sample (2026-10-18; a rough pass at low, then the clean board at medium with each shot's rough frame as a reference, no re-rolls) passed every check above. What is still not perfect: - Wardrobe drifts a little: the hand in shot 3 wears a chunky cream knit, the roaster in shot 4 a cream cotton shirt. Both are cream, so it reads as one person on a board; the film Skill's cast sheet locks the wardrobe for the real film. - The light change is mild. Shots 3 and 4 already have low warm sun, so slot 5 reads as a brighter moment of the same morning rather than a new light. For a clearer change, keep shots 2 to 4 in flat early light and give slot 5 its own time of day. - The hall in shot 5 looks larger than the boathouse in shot 1 (windows on both long sides, a door onto the water at the end). Fine for a plan; compare the film's high-quality keyframes with shot 1. - Shot 2 asked for the pouch soft at the edge of the frame; the model kept it sharp. Not a fault, as the label reads correctly. - Shot 4 shows the roaster's ear and cheek with the eyes hidden. Hidden enough for the board; the frame has not been sent to Seedance, as the board makes no video. - At first the aerial place reference put the boathouse into its own window in shot 4 (the rough pass). The place line in build-requests.mjs and a prompt that says what the window shows fixed it.