Brief to Scenes
An 8-stage, deterministic pipeline that reads a creative brief — intent, assets, key messages — and outputs validated scene JSON files without LLM calls.
Overview
The scene generator (generate_scenes) bridges the gap between brief authoring and the sizzle pipeline. You describe what you want — intent, assets, key messages — and the system translates it into scene compositions that feed directly into the sequence planner.
The core generation is rule-based and deterministic. No LLM calls are required. When enhance: true is passed with an ANTHROPIC_API_KEY, two optional LLM stages layer on top for scene plan text improvement and camera move suggestions — but all LLM output is validated and falls back to rule-based output on failure.
The creative brief
A brief answers three questions:
- What are you making? — type, tone, duration
- What do you have? — assets, text content
- What matters most? — hero moments, key messages
Everything else — scene count, layout selection, camera moves, transitions — is the system's job.
Brief schema
{
"brief_id": "string",
"template": "product-launch | brand-story | tutorial | investor-pitch | photo-essay | custom",
"project": {
"title": "string",
"description": "string (1-3 sentences)",
"duration_target_s": "number (optional)",
"style": "string (optional — style pack name)"
},
"tone": {
"mood": "string (e.g., confident, warm, urgent)",
"energy": "low | medium | high",
"audience": "string (optional)"
},
"content": {
"headline": "string (optional)",
"sections": [
{
"label": "string (e.g., 'Hero', 'Features', 'CTA')",
"text": "string",
"emphasis": "normal | strong",
"assets": ["asset_id references"]
}
]
},
"assets": [
{
"id": "string",
"path": "string (relative file path)",
"type": "image | video | svg | text-file",
"hint": "string (optional — what this asset shows)",
"role": "hero | supporting | background | logo (optional)"
}
],
"constraints": {
"must_include": ["asset IDs that must appear"],
"scene_count": { "min": "number", "max": "number" },
"brand_colors": ["hex values"],
"font_family": "string"
}
}
Section labels and intent mapping
The label on each content section guides how the system assigns intent tags:
| Label pattern | Intent tag | Typical treatment |
|---|---|---|
| Hero, Intro, Opening | opening, hero | First scene, strong visual weight |
| Features, Details, How It Works | detail, informational | Middle scenes, varied layouts |
| Testimonial, Social Proof, Quote | emotional | Crossfade transition, push_in camera |
| CTA, Closing, Contact | closing | Final scene, brand mark |
| Team, About | detail | Portrait layouts |
Style inference
When no style is specified in the brief, the system resolves it in priority order:
- Explicit —
project.stylefield - Template default — each template has a default style
- Tone inference —
tone.energymaps to style families - Fallback —
prestige
| Tone energy | Inferred styles |
|---|---|
| low | fade, minimal |
| medium | prestige, corporate |
| high | energy, kinetic |
Brief templates
Five pre-built templates provide structure and recommended defaults. Use template: "custom" for freeform briefs.
| Template | Default style | Duration | Scenes | Description |
|---|---|---|---|---|
brand-story | intimate | 45s | 6–12 | Narrative arc with emotional moments. Slow build, hero reveal, emotional close. |
investor-pitch | corporate | 30s | 5–8 | Metrics-forward, polished enterprise feel. Product + traction + team + ask. |
photo-essay | fade | 35s | 6–15 | Visual-first, minimal text, atmospheric. Images do the talking. |
product-launch | prestige | 30s | 4–8 | Hero product + features + social proof + CTA. Confident, forward energy. |
tutorial | minimal | 40s | 5–10 | Step-by-step, UI-focused, educational. Clean cuts, content-forward. |
Each template defines a section structure with suggested layouts, content types, and intent tags. Sections can be marked optional or allow repeat ranges — the generator expands or contracts sections based on available assets and constraints.
Templates live in the catalog at catalog/brief-templates.json. The list_brief_templates MCP tool returns all available templates with their full structure.
The 8-stage pipeline
Scene generation runs through 8 sequential stages. Each is a pure function.
| Stage | Function | Purpose |
|---|---|---|
| 1 | validateBrief() | Schema validation — required fields, template ID, asset uniqueness, referential integrity |
| 2 | classifyAssets() | 3-tier asset classification: hint, filename, extension fallback |
| 3 | resolveTemplate() | Load named template or infer virtual structure for custom briefs |
| 4 | resolveStyle() | Priority: explicit > template default > tone inference > fallback |
| 5 | allocateDurationsWeighted() | Weighted division with emphasis (strong = 1.5x), clamped to 0.5–30s |
| 6 | buildScenePlan() | Expand sections, handle repeats/optionals, assign assets, enforce must_include |
| 7 | generateScene() | Build layers, slots, and assets per content type |
| 8 | generateScenes() | Orchestrator — composes stages 1-7, self-validates every scene via validateScene() |
Every generated scene passes through validateScene() before returning. Invalid output throws — there is no silent failure.
Asset classification
Assets are classified through a 3-tier priority system:
| Tier | Source | Confidence | Example |
|---|---|---|---|
| 1 | Explicit hint field | 1.0 | hint: "product" maps to product_shot |
| 2 | Filename convention | 0.8 | hero-dashboard.png maps to product_shot |
| 3 | Extension fallback | 0.3 | .svg maps to brand_mark |
| 4 | Default | 0.1 | Unknown maps to product_shot |
Filename conventions the classifier recognizes:
hero-*,product-*— role: hero, type:product_shotteam-*,headshot-*,portrait-*— type:portraitui-*,screen-*,dashboard-*— type:ui_screenshotlogo-*,brand-*,mark-*— type:brand_markbg-*,background-*— role: background
Asset assignment (two-pass)
- Explicit refs — honor
content.sections[].assets[]references first - Affinity distribution — unassigned assets matched to scenes by content type, then role (hero to opening, logo to closing, background to heavy scenes)
- Force must_include — remaining
constraints.must_includeassets forced into best-matching scene
Content type mapping
Each content type maps to a specific layout and layer structure:
| Content type | Layout | Key layers |
|---|---|---|
typography | hero-center | bg (HTML) + fg text (word-reveal or scale-cascade) |
ui_screenshot | device-mockup | bg + device (image) + content (text) |
product_shot | device-mockup | bg + device (image) + content (text) |
portrait | split-panel | bg + left (image) + right (text) |
brand_mark | hero-center | bg + center (image) + optional text |
collage | masonry-grid | cell-N (images) |
data_visualization | hero-center | bg + center (image) + text |
Camera is always set to static in generated scenes. Camera moves are the sequence planner's job — this avoids conflicts with style pack camera overrides.
Example brief
A minimal product launch brief:
{
"brief_id": "brief_product_v1",
"template": "product-launch",
"project": {
"title": "Acme Dashboard",
"description": "30-second product launch sizzle for our new analytics dashboard. Show the UI, highlight key features, end with brand."
},
"tone": {
"mood": "confident",
"energy": "medium"
},
"content": {
"headline": "Analytics, Reimagined",
"sections": [
{
"label": "Hero",
"text": "Introducing Acme Dashboard",
"assets": ["product-hero"],
"emphasis": "strong"
},
{
"label": "Features",
"text": "Real-time metrics. Custom reports. Team sharing.",
"assets": ["ui-metrics", "ui-reports"]
},
{
"label": "CTA",
"text": "Start free today",
"assets": ["logo"]
}
]
},
"assets": [
{ "id": "product-hero", "path": "assets/hero-dashboard.png", "type": "image", "hint": "product UI hero shot" },
{ "id": "ui-metrics", "path": "assets/screen-metrics.png", "type": "image" },
{ "id": "ui-reports", "path": "assets/screen-reports.png", "type": "image" },
{ "id": "logo", "path": "assets/logo-acme.svg", "type": "svg", "hint": "company logo" }
]
}
This brief generates approximately 4-5 scenes: opening typography, hero product shot in a device-mockup layout, feature split-panels, and a closing brand mark.
Try it
Try asking your AI:
List the available brief templates and show me what the brand-story template looks like.
Generate scenes from this brief: I need a 30-second product launch video for a design tool called Canvas. I have a hero screenshot, two feature screenshots, and a logo.
I have 8 photos from a studio visit. Generate a photo-essay with soft transitions and minimal text.