- F-01: cost bar crit (red) state past 90% of budget
- F-02: normalize() hardens fetched board state against sparse payloads
- F-03: /thumb 404s for videos with no extractable poster frame instead
of serving raw video bytes
- F-04: checkpoint artifact path refs only resolve inside the project dir
- F-05 (board half): stall detection — in_progress stage with no disk
activity >10min renders red 'stalled?' + header badge flips to STALLED?;
verified against the real wedged why-cities-glow project
- eval harness from dogfood session committed (visual regression +
interaction smoke, capture watcher, server/gate test suites) +
regression tests for each finding; 46 backlot tests green, visual eval
green (restage-before-capture note logged)
- README 'Watch It Happen' section with four staged screenshots (fictional
demo productions, generated placeholder art — no private project content)
+ governance section notes enforced approval gates
- scripts/backlot_screenshot_stage.py: stages 4 demo projects in 4 pipeline
states against OPENMONTAGE_PROJECTS_DIR and captures the shots with
Playwright — reproducible README imagery
- lib/paths.py: OPENMONTAGE_PROJECTS_DIR env override (checkpoints, events,
and the board all follow one root); backlot/state.py now imports it
(was still defining its own copy — the exact drift the review warned of)
- undeclared-stage checkpoints (e.g. a legacy 'idea' run under a cinematic
manifest) now slot into their canonical rail position instead of dangling
after publish, drawn dashed + italic with an 'unlisted' note
- ChangeHub subscriptions filtered per project: unrelated-project bursts
can no longer flood a board's queue and starve its own change signal
- thumbnail temp files unique per request (concurrent-miss race on the
shared .tmp path corrupted the cache)
- watcher change-mapping is pure string work (no per-path resolve() in
thousand-file change batches); 'C:'-style project ids rejected
- replay: tz-naive timestamps treated as UTC; final render/script no
longer leak at t0 on storyboard-less projects; single tick chain on
rapid pause/play; drag-safe scrubber (label tracks input, board renders
on release); render-video playback survives SSE re-renders
- state: scene id 0 joins correctly, nested depth>0 events don't corrupt
generating state, out-of-project asset paths honestly unserveable,
negative durations clamped, tolerant manifest stage parse
- UI: decisions alt filter precedence fixed, activity counts parallel
same-tool runs, el() html sink removed, NaN-safe formatters
- replay mode: scrub a completed run from checkpoint history + event
timestamps — stage rail rewinds, script/storyboard/renders appear at
their real moments, generating shimmer replays; ~20s full-run playback
- stage history_entries exposed in BoardState (powers replay + versions)
- entrance choreography plays on first paint only (not on SSE refreshes)
- live-run fixes found by driving a simulated production against the
board: null rendered by native append, activity ticker showing closed
starts as running, scene-id label handling for 'scene-N' ids
- scripts/backlot_simulate_run.py: drives a fake production through the
REAL contract (init_project, in_progress heartbeats, gated
awaiting_human -> approved, per-scene events, growing manifest) —
live-board verification + demo driver
- backlot/README.md
- backlot/state.py: BoardState from disk — stage rail with gate audit
(gate_skipped detection from history/), scene_plan x script x
asset_manifest storyboard join, takes, generating-state from events,
media discovery incl. atelier root-render heuristic, degradation ladder,
library summaries
- backlot/server.py: FastAPI on 4750 — /api/projects, /api/project/{id}/state,
SSE change feeds (project + library) fed by a watchfiles watcher,
/media with range support and traversal protection, UI mounts
- backlot/__main__.py: 'python -m backlot open [project]' idempotent
launcher (spawns detached server, opens browser); 'serve' foreground
- verified against real projects: 73 listed, full state for
signal-from-tomorrow, 206 range responses, SSE change push on
filesystem write