# What Is Slideshow Risk Scoring in OpenMontage and How It Prevents Unwanted Output

> Discover Slideshow Risk Scoring in OpenMontage. This system analyzes video plans to detect and block static, repetitive, or low-quality content before rendering.

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

---

**Slideshow Risk Scoring in OpenMontage is a quantitative evaluation system that analyzes video plans across six independent dimensions to detect and block static, repetitive, or low-quality "slideshow-y" content before final rendering.**

OpenMontage implements this gatekeeper mechanism in [`lib/slideshow_risk.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/slideshow_risk.py) to ensure that generated videos maintain cinematic quality and narrative intent. By scoring scene plans before the expensive composition step, the system protects users from receiving generic slideshow output and prevents wasted render resources.

## How Slideshow Risk Scoring Works

The scoring engine evaluates every scene plan through a multi-dimensional analysis before the pipeline commits to final video composition.

### The Entry Point: `score_slideshow_risk`

The primary interface resides in [`lib/slideshow_risk.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/slideshow_risk.py) and accepts a structured scene list along with optional rendering context:

```python
def score_slideshow_risk(
    scenes: list[dict],
    edit_decisions: dict | None = None,
    renderer_family: str | None = None,
    render_runtime: str | None = None,
) -> dict:

```

This function immediately returns a failing verdict if the scene list is empty. For valid inputs, it delegates analysis to six specialized scoring helpers, each returning a normalized `{score, reason}` pair where **0 represents optimal quality** and **5 indicates critical risk**.

### The Six Risk Dimensions

The scorer aggregates signals from six independent quality dimensions:

- **Repetition** (`_score_repetition`): Measures frequency of repeated scene types, descriptions, and shot sizes. High repetition suggests monotonous pacing that mimics static slideshows.

- **Decorative Visuals** (`_score_decorative`): Calculates the proportion of scenes lacking `information_role`, `narrative_role`, or `shot_intent`. Scenes without communicative purpose contribute to "wallpaper" slideshow effects.

- **Weak Motion** (`_score_weak_motion`): Identifies camera movement that lacks explicit `shot_intent`. Movement without purpose creates distracting rather than cinematic motion.

- **Weak Shot Intent** (`_score_weak_intent`): Evaluates overall coverage of `shot_intent` metadata across the scene list. Missing intent signals indicate unplanned, generic shots.

- **Typography Overreliance** (`_score_typography`): Computes the ratio of pure-text cards (such as `text_card` or `stat_card`). Excessive typography without visual variety produces PowerPoint-like output.

- **Unsupported Cinematic Claims** (`_score_cinematic_claims`): Validates whether "cinematic" renderer families are justified by the presence of hero moments, purposeful movement, and deliberate lighting choices.

Each dimension independently analyzes the scene metadata and returns a score between 0 and 5.

### Score Aggregation and Verdict Logic

After calculating individual dimension scores, the system derives the final risk profile:

```python
average = sum(scores) / len(scores)

```

The average maps to categorical verdicts that drive pipeline behavior:

- **Strong** (average < 2.0): Proceed with composition
- **Acceptable** (2.0 ≤ average < 3.0): Proceed with minor warnings
- **Revise** (3.0 ≤ average < 4.0): Prompt user to modify the scene plan
- **Fail** (average ≥ 4.0): Abort composition to prevent unwanted output

The function returns a comprehensive payload containing the rounded average, verdict string, per-dimension breakdown, and `render_runtime` for downstream logging.

## Preventing Unwanted Output Through Pipeline Integration

The risk scoring system functions as a critical checkpoint within the video composition stage. In [`tools/video/video_compose.py`](https://github.com/calesthio/OpenMontage/blob/main/tools/video/video_compose.py), the composer invokes the scorer before initializing expensive rendering operations:

```python
from lib.slideshow_risk import score_slideshow_risk

risk = score_slideshow_risk(scenes, render_runtime="remotion")

if risk["verdict"] == "fail":
    raise RuntimeError("Slideshow risk too high – aborting composition")

```

This integration ensures that any scene plan averaging 4.0 or higher on the risk scale triggers an immediate abort, guaranteeing that OpenMontage never delivers static slideshow content to users. The early exit preserves computational resources while maintaining quality standards.

## Practical Implementation Examples

### Basic Risk Evaluation

Evaluate a scene plan before submission to the composer:

```python
from lib.slideshow_risk import score_slideshow_risk

scenes = [
    {"type": "intro", "description": "Opening shot", "shot_language": {"shot_size": "wide"}},
    {"type": "text_card", "description": "Key metric", "shot_language": {"shot_size": "medium"}},
    {"type": "hero", "description": "Product demo", "shot_language": {"shot_size": "close", "camera_movement": "pan"}},
]

result = score_slideshow_risk(scenes, renderer_family="cinematic-remotion")
print(f"Average risk: {result['average']}")
print(f"Verdict: {result['verdict']}")
print(f"Details: {result['dimensions']}")

```

### Composer Integration Pattern

Implement the risk gate within custom composition workflows:

```python
def compose_video(scenes, renderer_family):
    from lib.slideshow_risk import score_slideshow_risk
    
    risk = score_slideshow_risk(
        scenes, 
        renderer_family=renderer_family,
        render_runtime="remotion"
    )
    
    if risk["verdict"] == "fail":
        raise RuntimeError(f"Aborted: {risk['average']} risk score")
    
    # Proceed with Remotion rendering...

```

### Unit Testing the Scorer

Verify risk thresholds in your test suite (mirroring patterns from [`tests/tools/test_hyperframes_compose.py`](https://github.com/calesthio/OpenMontage/blob/main/tests/tools/test_hyperframes_compose.py)):

```python
def test_slideshow_risk_accepts_balanced_plan():
    from lib.slideshow_risk import score_slideshow_risk
    
    balanced_scenes = [
        {"type": "establishing", "shot_language": {"shot_size": "wide"}},
        {"type": "detail", "shot_language": {"shot_size": "close", "camera_movement": "track"}},
    ]
    
    result = score_slideshow_risk(balanced_scenes, render_runtime="hyperframes")
    assert result["verdict"] in {"strong", "acceptable"}
    assert result["average"] < 3.0

```

## Summary

- **Slideshow Risk Scoring in OpenMontage** operates as a pre-render quality gatekeeper located in [`lib/slideshow_risk.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/slideshow_risk.py).
- The system evaluates scene plans across **six independent dimensions**: repetition, decorative visuals, weak motion, weak shot intent, typography overreliance, and unsupported cinematic claims.
- Scores range from 0 (optimal) to 5 (critical risk), with averages determining verdict categories of **strong**, **acceptable**, **revise**, or **fail**.
- The [`video_compose.py`](https://github.com/calesthio/OpenMontage/blob/main/video_compose.py) pipeline aborts composition immediately when the scorer returns a **fail** verdict (average ≥ 4.0), preventing resource waste and low-quality output.
- Developers can invoke `score_slideshow_risk()` directly to validate scene plans before expensive rendering operations.

## Frequently Asked Questions

### What triggers a "fail" verdict in Slideshow Risk Scoring?

A **fail** verdict occurs when the average score across all six dimensions reaches 4.0 or higher. This typically happens when scene plans exhibit severe repetition, excessive text cards without visual balance, or "cinematic" renderer selections unsupported by actual hero moments and camera movement.

### Can I customize the risk thresholds or dimensions?

The current implementation in [`lib/slideshow_risk.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/slideshow_risk.py) uses fixed thresholds (2.0, 3.0, 4.0) and the six standard dimensions. While the source code exposes the scoring helpers (`_score_repetition`, `_score_decorative`, etc.), modifying the core logic requires editing the library directly. The architecture supports passing custom `edit_decisions` and `renderer_family` parameters to influence how certain dimensions calculate risk.

### Where does OpenMontage call the risk scorer in the production pipeline?

The primary integration point is [`tools/video/video_compose.py`](https://github.com/calesthio/OpenMontage/blob/main/tools/video/video_compose.py) around line 1474, where the composer calls `score_slideshow_risk()` immediately after generating the scene plan but before initializing the Remotion or HyperFrames rendering runtime. This ensures high-risk plans never reach the expensive video generation stage.

### How does the typography dimension distinguish between good and bad text usage?

The **typography overreliance** dimension (`_score_typography`) calculates the ratio of `text_card` and `stat_card` scenes versus total scenes. It penalizes plans where text-heavy scenes dominate without compensating visual variety. A low score indicates balanced use of text elements as accents rather than primary content carriers.