Fixes surfaced by the "How Salt Changed History" run: - Decisions rail showed a stale choice. Contract now requires a superseding decision_log entry when a logged choice changes mid-run; the board collapses by category+subject and renders the latest as current, tagged "revised" (AGENT_GUIDE Decision Communication Contract; board.js renderDecisions). - Assets gate jumped by a draft render. The review surface is the filmstrip: render per-scene stills to snapshots/<scene_id>.png (scripts/atelier_snapshots.py) and STOP; the full/draft render is the compose stage, post-approval (checkpoint-protocol, bespoke-composition). - Broken thumbnails / missing scenes. A .tsx "animation" asset is no longer a renderable visual — resolve snapshots/<scene_id>.* or a shot-spec placeholder; add <img onerror> fallback and a BESPOKE placeholder (state.py, board.js). - Clicking a card video did nothing. .thumb video had no sizing, so the frame and click box drifted; add object-fit:cover. Click-to-play on the render-hero player; narration is clickable -> modal with the full text (board.css/js). - Type too small everywhere. Add one --fs-scale (1.16) knob; every font-size is calc(px * var(--fs-scale)) so text scales proportionally and reversibly, verified for zero overflow at desktop + tablet widths. |
||
|---|---|---|
| .. | ||
| ui | ||
| README.md | ||
| __init__.py | ||
| __main__.py | ||
| server.py | ||
| state.py | ||
README.md
Backlot — the living storyboard
A read-only local board that shows a production happening: pipeline stages
lighting up, the script as a screenplay page, the scene plan as a filmstrip
that fills in as assets generate, decisions, spend, and activity — all
derived from what the pipeline already writes to projects/<id>/.
python -m backlot open <project-id> # start server if needed + open browser
python -m backlot open # library view (all projects)
python -m backlot serve --port 4750 # run the server in the foreground
How it stays live
No agent involvement. A watchfiles watcher on projects/ publishes change
notifications over SSE; the browser refetches board state. State sources:
| Board element | Disk source |
|---|---|
| identity / rail order | project.json + pipeline_defs/<type>.yaml |
| stage states, gates, versions | checkpoint_<stage>.json + history/ |
| script card / modal | artifacts/script.json |
| filmstrip cards | scene_plan × script × asset_manifest join |
| generating shimmer, activity | events.jsonl (written by BaseTool instrumentation) |
| cost meter | checkpoint cost_snapshot |
| renders | renders/*.mp4 (+ root-level mp4 heuristic) |
Projects without checkpoints degrade gracefully to a "what the watcher found" view — media, snapshots, renders.
Replay: a completed run can be scrubbed end-to-end (▶ REPLAY RUN on the board) — reconstructed from checkpoint history and event timestamps.
Try it without a real production:
python scripts/backlot_simulate_run.py # live demo run (~1 min)
python -m backlot open backlot-demo-run
Design doc: internal/design/LIVING_STORYBOARD.md.