# How the Backlot Live Storyboard Determines State from Project Files in OpenMontage

> Discover how the Backlot live storyboard determines its state from project files in OpenMontage by dynamically assembling board state objects from JSON marker files, checkpoint histories, artifacts, and live events. Learn more ...

- Repository: [Calesthio/OpenMontage](https://github.com/calesthio/OpenMontage)
- Tags: internals
- Published: 2026-08-30

---

**The Backlot live storyboard determines its state by dynamically assembling a `BoardState` object from JSON marker files, checkpoint histories, artifacts, and live events stored in the project directory, eliminating the need for a separate database.**

The OpenMontage Backlot system renders a real-time production filmstrip by treating the filesystem as the single source of truth. Rather than maintaining state in a database, the live storyboard reconstructs the entire production context—including scene cards, generation status, and media assets—by parsing specific on-disk files every time the state is requested.

## State Assembly Pipeline Overview

The state derivation process is implemented in [`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py) and orchestrated by the `load_board_state` function. This function executes a deterministic eight-step pipeline that reads project metadata, aggregates checkpoint histories, resolves pipeline configurations, and merges live event streams into a cohesive storyboard representation.

## Loading Project Metadata and Checkpoints

The assembly process begins by reading the project marker and metadata files. At lines 88–95 in [`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py), the system reads [`project.json`](https://github.com/calesthio/OpenMontage/blob/main/project.json) (the marker file) and [`meta.json`](https://github.com/calesthio/OpenMontage/blob/main/meta.json) to extract the project title, pipeline type, and style playbook.

```python
marker = _read_json(project_dir / "project.json")
meta_json = _read_json(project_dir / "meta.json")

```

Simultaneously, the `_collect_checkpoints` and `_collect_history` functions (lines 18–34) scan the directory for all `checkpoint_*.json` files. These files contain stage status information, timestamps, artifact references, and archived historical snapshots that represent the project's progression through the production pipeline.

## Resolving Pipeline Definitions and Artifacts

Once basic metadata is loaded, the system resolves the pipeline definition via `_load_pipeline_meta` (lines 63–92). The pipeline type is inferred from the marker file or the first available checkpoint. If a manifest exists, it is loaded to determine stage ordering and identify human-gated stages; otherwise, the system falls back to a default stage list.

Artifact collection occurs through `_collect_artifacts` (lines 46–66), which reads JSON files from the `artifacts/` directory, including [`scene_plan.json`](https://github.com/calesthio/OpenMontage/blob/main/scene_plan.json), [`script.json`](https://github.com/calesthio/OpenMontage/blob/main/script.json), and [`asset_manifest.json`](https://github.com/calesthio/OpenMontage/blob/main/asset_manifest.json). The system also resolves any artifact references embedded directly within checkpoint files, ensuring that generated assets remain linked to their corresponding pipeline stages.

## Streaming Live Events and Media Discovery

To capture in-progress generation steps, the system streams the most recent events from `events.jsonl`. At lines 108–110, the `read_events` function ingests up to 250 entries from the events log, providing real-time visibility into active generation tools and background processes.

Media discovery is handled by `_scan_media` (lines 1002–1015), which traverses the `renders/`, `snapshots/`, and `assets/music/` directories to locate rendered videos, preview thumbnails, and audio files. This scan ensures that the storyboard displays the most current visual assets available on disk.

## Building the Scene Cards

The core storyboard construction logic resides in `_build_storyboard` (lines 403–496). This function merges the scene plan, script sections, asset manifest, and live events to produce an array of scene cards. Each card contains:

- **Scene metadata** (ID, timing, description)
- **Visual assets** (images, videos, snapshots)
- **Audio assets** (music tracks, SFX)
- **Generation status flags** (`generating`, `generating_tool`)

The function applies a resolution algorithm to determine which visual to display for each scene, selecting the newest renderable asset, a missing-file placeholder, or a per-scene snapshot based on availability.

## Final State Assembly and Error Handling

At lines 40–57, the final `BoardState` dictionary is assembled by combining all collected components. The architecture enforces a strict error-resilience policy: the state dictionary **never raises exceptions**. If any file read fails or data is corrupted, that specific piece is simply omitted from the final state, allowing the UI to render partial information rather than crashing.

The resulting `state["storyboard"]` object is what the front-end consumes to render the live filmstrip, generation progress indicators, and thumbnail previews.

## Code Examples

### Generating Board State from a Project Directory

```python
from pathlib import Path
from backlot.state import load_board_state

project_path = Path("/path/to/projects/1234abcd")
board_state = load_board_state(project_path)

# Access the live storyboard

storyboard = board_state["storyboard"]
print(f"Loaded {len(storyboard['scenes'])} scenes")

```

This invokes the complete pipeline, parsing all JSON files and media folders to produce the current production state.

### Accessing Individual Scene Cards

```python
scene_id = "scene_02"
scene_card = next(
    card for card in storyboard["scenes"] 
    if card["id"] == scene_id
)

print("Visual path:", scene_card["visual"]["path"])
print("Generating:", scene_card["generating"])

```

Each card exposes `visual`, `takes`, `audio`, and generation flags that drive the UI rendering logic.

### Consuming State in the Front-End

```javascript
// From backlot/ui/board.js
import { loadBoardState } from '../../backlot/state';

loadBoardState(projectDir).then(state => {
  const storyboard = state.storyboard;
  if (!storyboard) return;
  
  const filmstrip = document.getElementById('filmstrip');
  storyboard.scenes.forEach(card => {
    const img = document.createElement('img');
    img.src = `/media/${card.visual.path}`;
    filmstrip.appendChild(img);
  });
});

```

The UI iterates over `state.storyboard.scenes` and binds the `visual.path` property to DOM image elements.

## Key Source Files

- **[`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py)** – Core orchestration logic containing `load_board_state`, `_build_storyboard`, and media scanning functions.
- **[`backlot/ui/board.js`](https://github.com/calesthio/OpenMontage/blob/main/backlot/ui/board.js)** – Front-end component that consumes `state["storyboard"]` and renders the live filmstrip interface.
- **[`backlot/ui/lib.js`](https://github.com/calesthio/OpenMontage/blob/main/backlot/ui/lib.js)** – Utility library providing DOM helpers and event handlers for the board interface.
- **[`scripts/backlot_watch_captures.py`](https://github.com/calesthio/OpenMontage/blob/main/scripts/backlot_watch_captures.py)** – Diagnostic tool that walks storyboard structures and outputs capture metadata.
- **[`tests/backlot/test_state.py`](https://github.com/calesthio/OpenMontage/blob/main/tests/backlot/test_state.py)** – Test suite verifying scene plan integration and artifact resolution correctness.

## Summary

- The Backlot live storyboard reconstructs state entirely from filesystem artifacts rather than a database.
- The `load_board_state` function in [`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py) drives an eight-step pipeline to parse JSON markers, checkpoints, artifacts, and live events.
- `_build_storyboard` (lines 403–496) merges scene plans, scripts, and assets into consumable scene cards.
- Media discovery scans `renders/`, `snapshots/`, and `assets/music/` directories to locate visual content.
- The system reads up to 250 recent entries from `events.jsonl` to reflect real-time generation progress.
- Error handling is fail-safe: corrupted or missing files are omitted rather than causing state assembly to fail.

## Frequently Asked Questions

### What files does the Backlot live storyboard read to determine state?

The storyboard reads [`project.json`](https://github.com/calesthio/OpenMontage/blob/main/project.json) and [`meta.json`](https://github.com/calesthio/OpenMontage/blob/main/meta.json) for metadata, `checkpoint_*.json` files for stage history, artifacts like [`scene_plan.json`](https://github.com/calesthio/OpenMontage/blob/main/scene_plan.json) and [`script.json`](https://github.com/calesthio/OpenMontage/blob/main/script.json) for content structure, and `events.jsonl` for live generation events. It also scans media directories including `renders/`, `snapshots/`, and `assets/music/` to locate visual and audio assets.

### How does the system handle missing or corrupted project files?

According to the implementation in [`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py) (lines 40–57), the state assembly never raises exceptions. If a file read fails or returns invalid data, that specific component is omitted from the final `BoardState` dictionary. This ensures the UI can render partial storyboards even when some assets or checkpoints are unavailable.

### What determines which visual asset appears on a storyboard scene card?

The `_build_storyboard` function implements a resolution hierarchy at lines 403–496. It selects the newest renderable asset available for each scene; if no render exists, it falls back to a per-scene snapshot or displays a missing-file placeholder. This logic ensures the storyboard always shows the most current visual representation of production progress.

### How recent are the live events reflected in the storyboard state?

The system reads up to 250 entries from `events.jsonl` as implemented at lines 108–110 of [`backlot/state.py`](https://github.com/calesthio/OpenMontage/blob/main/backlot/state.py). This limit provides a balance between capturing recent generation activity and maintaining fast state assembly performance, ensuring the UI reflects in-progress tool executions without overwhelming the browser with historical data.