hyperframes: add HTML/CSS/GSAP as a parallel composition runtime

Separates creative grammar (renderer_family) from technical engine
(render_runtime) so HyperFrames can stand alongside Remotion as a
first-class runtime instead of masquerading as a Remotion sub-case.
Locks runtime choice at proposal stage and enforces it end-to-end: the
schemas require it, video_compose routes by it, the reviewer fails
closed on silent swaps, and a parametrized contract test walks every
pipeline manifest to ensure each planning-stage skill explains the
conversation to the user. Adds hyperframes_compose (scaffold/lint/
validate/render/doctor/add_block), a playbook -> CSS style bridge, and
vendored HyperFrames Layer 3 skills from commit d291358, pinned via
PROVENANCE.md for future re-sync. Final_review now records
render_runtime_used and runtime_swap_detected so compose lies are
catchable after the fact.
This commit is contained in:
calesthio
2026-04-18 18:37:00 -07:00
parent 9e17263aa5
commit b4f7ec4eee
118 changed files with 10128 additions and 126 deletions
@@ -4,6 +4,22 @@
Render the animation with an emphasis on text sharpness, timing integrity, and consistent output cadence. For `image_animation` approach, this stage also includes building the composition JSON, sourcing music, running pre-render validation, and performing post-render self-review.
## Runtime Routing (MANDATORY first step)
Before any other work, read `edit_decisions.render_runtime`. It was locked at proposal and MUST NOT be changed silently. The rest of this skill assumes `render_runtime="remotion"` (the default for this pipeline). If the proposal locked a different runtime:
- **`render_runtime="hyperframes"`** — HTML/CSS/GSAP render. Do NOT follow the Remotion-specific sections below (public/ staging, Remotion composition JSON). Instead:
1. Read `skills/core/hyperframes.md` for the full routing model.
2. Read `.agents/skills/hyperframes/SKILL.md` and `.agents/skills/hyperframes-cli/SKILL.md` for authoring contract and CLI usage.
3. Call `video_compose` with `edit_decisions.render_runtime="hyperframes"` — it delegates to `hyperframes_compose`, which owns workspace materialization under `projects/<name>/hyperframes/`, runs `hyperframes lint → validate → render`, and returns the MP4 path.
4. `hyperframes lint` and `hyperframes validate` MUST both pass before render. Never skip validate; contrast can be deferred with `skip_contrast=true` during iteration but not for final delivery.
- **`render_runtime="ffmpeg"`** — simple concat/trim with no composition. Call `video_compose` directly; it will not auto-upgrade to Remotion.
- **Runtime unavailable** — do NOT silently swap to a different engine. Surface the blocker to the user per AGENT_GUIDE.md > "Escalate Blockers Explicitly" and wait for approval (recorded as a `render_runtime_selection` decision in decision_log) before switching.
The post-render self-review (final_review) is identical across runtimes — same ffprobe probe, frame sampling, audio spotcheck, and promise preservation checks. `final_review.checks.promise_preservation.render_runtime_used` must equal the runtime that actually ran.
**Pass `proposal_packet` to `video_compose.execute()`** when you invoke it. That lets the tool directly compare the proposal-locked runtime against the runtime recorded in `edit_decisions` and flip `runtime_swap_detected=true` if they diverge. Without it, the check is `skipped` and the reviewer skill has to catch swaps via cross-artifact comparison instead.
## Prerequisites
| Layer | Resource | Purpose |
+78 -42
View File
@@ -8,6 +8,34 @@ You are the **Proposal Director** for a generated animation video. You sit betwe
Animation proposals have a unique dimension: **animation mode selection**. Unlike explainer videos where the visual approach is secondary to the narrative, animation videos ARE their visual approach. The mode choice (Manim vs Remotion vs AI video vs motion graphics) fundamentally shapes the entire production.
## Runtime Selection (required field — `render_runtime`)
Animation proposals must lock **both** a `renderer_family` (creative grammar) and a `render_runtime` (technical engine). These are separate concepts now that HyperFrames is a first-class runtime. Read `skills/meta/animation-runtime-selector.md` and `skills/core/hyperframes.md` for the decision matrix, and `AGENT_GUIDE.md` → "Present Both Composition Runtimes (HARD RULE)" for the governance contract.
**MANDATORY workflow — present both runtimes, don't silently default:**
1. Query `video_compose.get_info()["render_engines"]`. If both `remotion` and `hyperframes` are `True`, proceed to step 2. If only one is available, go to step 4 with just that one.
2. Present both runtimes to the user with brief-specific analysis:
- **Remotion** — one line on fit (e.g. "your brief uses data-chart and stat_card heavily, both already exist as React components"), one line on tradeoff (e.g. "React component authoring is more rigid than HTML/CSS for custom typographic motion").
- **HyperFrames** — one line on fit (e.g. "the kinetic-typography opener fits HTML + GSAP better than Remotion interpolation"), one line on tradeoff (e.g. "no word-level caption burn parity yet; no access to existing Remotion chart library").
3. Recommend one with rationale tied to the brief's `delivery_promise`, the selected animation mode, and the reuse strategy from research.
4. Wait for explicit user approval. Do NOT write `render_runtime` into `proposal_packet.production_plan` before approval.
5. Log a `render_runtime_selection` decision in `decision_log` with BOTH runtimes in `options_considered`, the user's pick as `selected`, and the rationale as `reason`. If a runtime was unavailable, record it as rejected with `rejected_because: "runtime not available on this machine"`.
Fit cheat-sheet for the recommendation (NOT an auto-decision):
| Brief characteristic | Lean toward |
|----------------------|-------------|
| Data-chart-heavy, text_card/stat_card/kpi_grid dominant | Remotion |
| MathAnimate / Manim scene in the animatic | Remotion (Manim renders to a video, composed in Remotion) |
| Kinetic typography, product promo, launch reel, HTML/GSAP-native motion | HyperFrames |
| Website-to-video or UI-driven composition | HyperFrames |
| Registry blocks needed (data-chart, grain-overlay, shader transitions) | HyperFrames |
| Word-level/karaoke caption burn required | Remotion (HyperFrames caption parity deferred) |
| Simple source-footage concat, no composition | ffmpeg |
A `render_runtime_selection` decision with only one option considered when both were available is a CRITICAL reviewer finding. That's how the moat collapses into "everything looks like our chart stack."
## Prerequisites
| Layer | Resource | Purpose |
@@ -95,50 +123,51 @@ This is the key differentiator from the explainer proposal. **Present the user w
#### Step 3a: Tool Availability Scan
Before designing concepts, scan what's available and present it honestly:
Before designing concepts, scan what's available and present it honestly. **Do NOT hardcode provider names, costs, or key names in this output** — they drift. Read them live from the registry:
```python
from tools.tool_registry import registry
registry.discover()
summary = registry.provider_menu_summary() # see AGENT_GUIDE.md > Mandatory Preflight
```
Then render the scan from `summary`, grouping by capability. Example shape you should **generate from the registry**, not copy:
```
TOOL AVAILABILITY SCAN
──────────────────────
Image generation:
FLUX (fal.ai) — FAL_KEY detected — $0.03-0.05/image
gpt-image-1 — OPENAI_API_KEY missing — $0.13/image
❌ Stable Diffusion — Not installed locally — Free
❌ FLUX (local) — Not installed locally — Free
Video generation:
❌ Runway Gen-3 — No API key — $0.50/clip
❌ Kling — No API key — $0.10-0.30/clip
❌ CogVideoX (local) — Not installed — Free
Composition:
✅ Remotion — Installed — Free (local CPU)
✅ FFmpeg — Installed — Free
Audio:
✅ Pixabay Music — No key needed — Free
❌ OpenAI TTS — OPENAI_API_KEY missing — $0.015/min
✅ Local TTS (piper) — Not checked — Free
Math/Diagram:
❌ ManimCE — Not installed — Free
✅ diagram_gen — Available — Free
Image generation: {configured}/{total}
{tool_name} ({provider}) — available
{tool_name} ({provider}) — {install_instructions trimmed to one line}
Video generation: {configured}/{total}
...
Composition runtimes: {ffmpeg} / {remotion} / {hyperframes}
See AGENT_GUIDE.md > "Present Both Composition Runtimes (HARD RULE)".
Audio: {configured}/{total}
Math/Diagram: {configured}/{total}
```
**Rules for this output:**
- Every name, provider, cost, and install instruction comes from `provider_menu_summary()` or `provider_menu()`. Don't type them from memory — provider surfaces change between releases.
- Never cite a cost that isn't live in the tool's `estimate_cost` or install metadata.
- Composition runtimes are a separate section because the "Present Both" HARD RULE needs all three engines visible.
**Present this scan to the user.** Say: "Here's what I can see right now. Based on this, here are your animation approach options."
#### Step 3b: Animation Approach Decision Matrix
Present the approaches as clear options:
| Approach | What It Looks Like | Tools Required | Cost Range | Proven? |
|----------|-------------------|----------------|------------|---------|
| **A: Image-Based Animation (Remotion)** | AI-generated keyframes with crossfade, camera motion, particles. Looks like moving anime/illustration. | `image_selector` (any provider) + Remotion | $0.03-0.13/image × 2-3/scene | ✅ Proven (mori-no-seishin) |
| **B: Clip-Based Video** | AI-generated video clips assembled as a story. Most cinematic but least consistent. | `video_selector` (Runway/Kling/etc.) | $0.10-0.50/clip × scenes | ❌ Not yet proven |
| Approach | What It Looks Like | Tools Required | Cost | Proven? |
|----------|-------------------|----------------|------|---------|
| **A: Image-Based Animation (Remotion)** | AI-generated keyframes with crossfade, camera motion, particles. Looks like moving anime/illustration. | `image_selector` (any provider) + Remotion | Pull per-image cost from the chosen provider's `estimate_cost`; 2-3 images per scene is typical | ✅ Proven (mori-no-seishin) |
| **B: Clip-Based Video** | AI-generated video clips assembled as a story. Most cinematic but least consistent. | `video_selector` routing to whichever provider is available | Pull per-clip cost from the chosen provider's `estimate_cost`; varies widely between providers | ❌ Not yet proven |
| **C: Programmatic Animation (Manim)** | Code-driven math/geometry animation. Precise, clean, 3Blue1Brown style. | `math_animate` (ManimCE) | Free (local) | ❌ Not yet proven |
| **D: Data Visualization (Remotion)** | Animated charts, KPIs, kinetic typography. Data-driven storytelling. | Remotion (built-in components) | Free (local) | ✅ Proven (zero-key formula) |
| **E: Diagram + Image Stills** | Process flows and architecture diagrams with Ken Burns. | `diagram_gen` + `image_selector` | $0-0.05/image | ✅ Proven |
| **F: Mixed Mode** | Combine any of the above per-scene. Most flexible. | Multiple tools | Varies | Partial |
| **E: Diagram + Image Stills** | Process flows and architecture diagrams with Ken Burns. | `diagram_gen` + `image_selector` | `diagram_gen` is free; per-image cost from `image_selector`'s routed provider | ✅ Proven |
| **F: Mixed Mode** | Combine any of the above per-scene. Most flexible. | Multiple tools | Sum per-scene from each tool's `estimate_cost` | Partial |
**Rule:** do NOT fill in a dollar figure in the Cost column from memory. Read every cost live via `estimate_cost()` or `provider_menu_summary()` at proposal time. Provider pricing changes between releases.
**For each viable approach, present to the user:**
@@ -150,15 +179,15 @@ camera motion (zoom, pan, ken-burns) and particle overlays (fireflies, mist,
sparkles). Creates the illusion of movement from still frames.
You need: An image generation API key.
→ You already have: FAL_KEY (FLUX at $0.05/image)
→ Alternative: Install Stable Diffusion locally (free, slower)
→ Alternative: Add OPENAI_API_KEY for gpt-image-1 ($0.13/image)
→ You already have: {from provider_menu_summary: available image_generation providers}
→ Alternative: {from setup_offers: 1-env-var image_generation tools}
→ Alternative: local Stable Diffusion (see local_diffusion tool install_instructions)
Estimated cost for 30s video: ~$0.65 (13 images)
Estimated cost for 5min video: ~$6.00 (120 images)
Estimated cost for 30s video: pull per-image costs from each provider's
`estimate_cost` (do NOT hardcode — they drift between releases).
Style options: anime-ghibli, painterly, photorealistic, watercolor
Reference: remotion-composer/public/demo-props/mori-no-seishin.json
Style options: depend on the picked provider; read from playbook and
provider-specific Layer 3 skill (e.g. `.agents/skills/flux-best-practices`).
APPROACH B: Clip-Based Video
─────────────────────────────
@@ -166,11 +195,13 @@ What it looks like: AI-generated 3-5 second video clips assembled as a story.
Most cinematic output but hardest to maintain visual consistency across clips.
You need: A video generation API key.
→ Currently available: None detected
→ To enable: Add RUNWAY_API_KEY, KLING_API_KEY, or install CogVideoX locally
→ Currently available: {from provider_menu_summary: available video_generation providers}
→ To enable: {from setup_offers: 1-env-var video_generation tools}, or
install a local video model (see video_selector fallback_tools).
Estimated cost for 30s video: $3-15 depending on provider
Estimated cost for 5min video: $30-150
Estimated cost for 30s video: pull from each provider's `estimate_cost` on the
actual clip plan — per-clip costs range widely between providers and change
often. Do NOT hardcode.
Note: This approach is not yet proven in the OpenMontage pipeline.
Consistency across clips is the #1 challenge.
@@ -178,6 +209,11 @@ Note: This approach is not yet proven in the OpenMontage pipeline.
**Critical principle: Surface capabilities, don't hide limitations.** The user should know exactly what's possible right now vs. what needs setup.
**Rules for this section — same as Step 3a:**
- Every provider name, env var, and cost comes from `provider_menu_summary()` or a tool's live `install_instructions` / `estimate_cost`.
- The `{placeholder}` tokens above are for the agent to fill from the registry, not paste literally.
- If you find yourself typing a specific API-key env-var name or a per-unit dollar cost into this section, stop. Those drift between releases; hardcoding them in a director skill is a governance regression (see AGENT_GUIDE.md on hardcoded provider names). Pull the same data from the registry instead.
#### Step 3c: Mode Selection Rules
- If the topic is visual/artistic (anime, illustration, fantasy) → **Approach A** (image-based)
@@ -403,7 +439,7 @@ Validate the `proposal_packet` artifact against `schemas/artifacts/proposal_pack
## Common Pitfalls
- **Not showing the Tool Availability Scan**: The user must know what's available BEFORE seeing concepts. Don't hide missing keys or tools.
- **Ignoring animation approach feasibility**: If FLUX isn't available, don't propose image_animation without saying "you need to add FAL_KEY first." Design around constraints OR explicitly state what's needed.
- **Ignoring animation approach feasibility**: If the routed image/video provider isn't available, don't propose that approach without explicitly telling the user what's needed. Read each missing tool's `install_instructions` from the registry (do NOT hardcode specific env var names here — they drift). Design around constraints OR explicitly state what's needed.
- **Three versions of the same concept with different titles**: Structural diversity means different animation approaches, different narrative structures, different hooks.
- **Not leveraging free tools**: Animation has a huge cost advantage — Manim, Remotion data-viz, and diagram_gen are free. If proposing expensive AI video, justify why free alternatives won't work.
- **Over-promising visual complexity**: 20 unique hand-crafted scenes is not realistic. Design reuse strategies that look varied but share underlying templates.
@@ -4,6 +4,14 @@
Render the final spokesperson outputs. The bar is simple: the presenter must look stable, speech must be clear, and subtitles or support cards must not crowd the frame.
## Runtime Routing (HARD CONSTRAINT — Remotion only)
Phase 1 deferred from HyperFrames. `edit_decisions.render_runtime` must be `"remotion"`. This pipeline depends on the Remotion `TalkingHead` composition and `remotion_caption_burn` — both have no HyperFrames parity in Phase 1.
- If `edit_decisions.render_runtime == "hyperframes"`, stop. Re-open the idea stage and surface the constraint. Silent rewrite is a governance violation.
- Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": the lock to remotion is NOT an excuse to skip the conversation. The user deserves to know that HyperFrames exists as a runtime and why it isn't viable for avatar-spokesperson. Log a `render_runtime_selection` decision with hyperframes `rejected_because: "TalkingHead + caption parity deferred on avatar-spokesperson"`.
- Pass `proposal_packet`/`brief` to `video_compose.execute()` for in-tool runtime-swap detection.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,12 @@ Use this pipeline when the deliverable is a presenter-led avatar video: a spokes
Your first job is to classify the avatar path honestly before anyone writes polished copy for an impossible production setup.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"`. **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — avatar-spokesperson depends on the Remotion `TalkingHead` composition and `remotion_caption_burn`, and neither has HyperFrames parity yet.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": do NOT silently default. Tell the user: "HyperFrames is available on your machine, but avatar-spokesperson depends on the Remotion TalkingHead composition and caption burn, so remotion is the only viable runtime here — OK to proceed?" Record a `render_runtime_selection` decision with hyperframes `rejected_because: "TalkingHead + caption parity deferred on avatar-spokesperson"`.
## Reference Inputs
- `docs/avatar-spokesperson-best-practices.md`
@@ -4,6 +4,18 @@
Render the cinematic piece with careful attention to grade, audio dynamics, and frame treatment. This is not a generic export step.
## Runtime Routing (MANDATORY first step)
Read `edit_decisions.render_runtime`. Cinematic work routes to:
- **`render_runtime="remotion"`** — default for video-led trailers using `CinematicRenderer`. Keeps video clips, transitions, and ambient overlays in one React-based pass.
- **`render_runtime="hyperframes"`** — for kinetic title cards, HTML/GSAP-driven trailers, or launch-reel-style compositions where the visual grammar is HTML/CSS. See `skills/core/hyperframes.md`. `hyperframes lint` and `hyperframes validate` must both pass before render.
- **`render_runtime="ffmpeg"`** — simple source-footage concat with no composition.
`delivery_promise.motion_required=true` means the locked runtime is a commitment. Silent swap to another runtime (including FFmpeg Ken Burns) is a CRITICAL governance violation. If the locked runtime fails, escalate per AGENT_GUIDE.md > "Escalate Blockers Explicitly."
**Pass `proposal_packet` to `video_compose.execute()`** so the tool's `runtime_swap_detected` check compares directly against `proposal_packet.production_plan.render_runtime`. Without it the swap check is skipped in-tool and only the reviewer skill catches the drift.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,31 @@ You are the **Proposal Director** for a cinematic video (trailers, brand films,
**This is the approval gate.** Nothing downstream runs until the user says "go."
## Runtime Selection (required field — `render_runtime`)
Cinematic proposals must lock **both** a `renderer_family` (creative grammar: `cinematic-trailer`, `documentary-montage`, etc.) and a `render_runtime` (technical engine). Read `skills/meta/animation-runtime-selector.md` and `skills/core/hyperframes.md` for the decision matrix, and `AGENT_GUIDE.md` → "Present Both Composition Runtimes (HARD RULE)" for the governance contract.
**MANDATORY workflow — present both runtimes, don't silently default:**
1. Query `video_compose.get_info()["render_engines"]`. If both `remotion` and `hyperframes` are `True`, proceed to step 2.
2. Present both runtimes to the user with brief-specific analysis:
- **Remotion** — one line on fit (mention `CinematicRenderer`, `<OffthreadVideo>`, existing transition stack if applicable), one line on tradeoff.
- **HyperFrames** — one line on fit (mention kinetic title sequences, registry shader transitions, or HTML-native typographic motion if applicable), one line on tradeoff.
3. Recommend one with rationale tied to the brief's `delivery_promise` (especially `motion_required`), `renderer_family`, and approved tone.
4. Wait for explicit user approval. Do NOT write `render_runtime` into `proposal_packet.production_plan` before approval.
5. Log a `render_runtime_selection` decision in `decision_log` with BOTH runtimes in `options_considered` plus `ffmpeg` if it was a realistic option.
Fit cheat-sheet for the recommendation (NOT an auto-decision):
- Video-led trailer with motion clips via `<OffthreadVideo>` + color-graded overlays → lean **Remotion**.
- HTML/GSAP-driven trailer: kinetic title sequence, launch reel, brand film where the visual grammar is typographic → lean **HyperFrames**.
- Shader transitions or registry grain overlays → lean **HyperFrames**.
- Simplest source-footage concat with no composition → **ffmpeg**.
**Motion-required deliverables**: if `delivery_promise.motion_required=true`, the chosen runtime is a commitment. Silent downgrade to FFmpeg Ken Burns or still-led animatic is forbidden. If the chosen runtime becomes unavailable at render time, compose must escalate, not substitute.
A `render_runtime_selection` decision with only one option considered when both were available is a CRITICAL reviewer finding.
## Prerequisites
| Layer | Resource | Purpose |
@@ -4,6 +4,14 @@
Render each clip and platform variant independently. The important behaviors here are consistency, batch resilience, and clear reporting of partial failures.
## Runtime Routing (HARD CONSTRAINT — Remotion or FFmpeg only)
This pipeline is Phase 1 deferred from the HyperFrames adoption schedule. `edit_decisions.render_runtime` must be `"remotion"` (default) or `"ffmpeg"` (pure-concat clip jobs with no composition). HyperFrames is NOT a valid runtime here — clip-factory depends on Remotion word-level caption burn, and HyperFrames caption parity is deferred work.
- If `edit_decisions.render_runtime == "hyperframes"`, stop. Re-open the idea stage so the user can be presented the real constraint and lock `remotion` with a `render_runtime_selection` decision that records `hyperframes` as `rejected_because: "caption-burn parity deferred on clip-factory"`.
- Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": the constraint is NOT an excuse to skip the conversation. The user still gets to see that HyperFrames exists and why it isn't viable here.
- Pass `proposal_packet`/`brief` to `video_compose.execute()` so the in-tool runtime-swap check runs end-to-end.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,12 @@ Use this pipeline when the source is long-form footage and the goal is multiple
You are not planning one video. You are planning a ranked portfolio of clips.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"` (for composed clips with word-level captions) or `"ffmpeg"` (for pure concat/trim with no composition). **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — clip-factory depends on Remotion's word-level caption burn, which has no HyperFrames parity yet.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": do NOT silently lock remotion. Surface the constraint to the user: "HyperFrames is an available runtime on your machine, but clip-factory depends on Remotion caption burn that doesn't have HyperFrames parity yet, so remotion is the only viable choice here — OK to proceed?" Record the decision in `decision_log` with category `render_runtime_selection`, including hyperframes as a rejected option (`rejected_because: "caption-burn parity deferred on clip-factory"`).
## Reference Inputs
- `docs/clip-factory-best-practices.md`
@@ -9,6 +9,14 @@ mix) that makes a mixed-era corpus feel like one film.
The output is a single mp4 plus a `render_report` artifact.
## Runtime Routing (HARD CONSTRAINT)
This pipeline currently REQUIRES `render_runtime="remotion"`. The end-tag stack (ProRes 4444 overlay composited on final scenes, or concat fallback) depends on Remotion's `CinematicRenderer` composition and its alpha-preserving render path. HyperFrames end-tag parity is explicitly Wave 3 / deferred work (see `skills/core/hyperframes.md` → "What stays Remotion-only in Phase 1").
- If `edit_decisions.render_runtime` is anything other than `remotion`, stop. This is a CRITICAL governance violation. Surface the conflict to the user, route the decision back to proposal to re-lock `render_runtime="remotion"`, log a `render_runtime_selection` correction in decision_log, and resume.
- Never silently proceed by rewriting render_runtime in edit_decisions. The documentary promise (motion-led, mood-driven, uniform grade) is preserved by the Remotion stack, and that promise is what the user approved.
- Pass `proposal_packet` to `video_compose.execute()` so the in-tool `runtime_swap_detected` check actively confirms the runtime stayed `remotion` end-to-end. A `skipped` check on this pipeline means you forgot to pass the proposal artifact.
## Prerequisites
| Layer | Resource | Purpose |
@@ -7,6 +7,12 @@ downstream stage will read. For this pipeline, the brief is the
thematic core: what the montage is ABOUT, what it should feel like,
and how long it should run.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"`. **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — documentary-montage depends on the Remotion `CinematicRenderer` composition and its ProRes-4444 alpha end-tag overlay stack, neither of which has HyperFrames parity.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": do NOT silently default. Tell the user: "HyperFrames is available on your machine as an alternative runtime, but documentary-montage depends on the Remotion CinematicRenderer + end-tag overlay stack, so remotion is the only viable choice here — OK to proceed?" Record a `render_runtime_selection` decision in `decision_log` listing both runtimes in `options_considered`, with hyperframes `rejected_because: "CinematicRenderer + end-tag overlay parity deferred on documentary-montage"`.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,18 @@ You are the Compositor for a generated explainer video. You have `edit_decisions
This is the last technical stage before the video exists as a playable file. Everything converges here.
## Runtime Routing (MANDATORY first step)
Read `edit_decisions.render_runtime` before anything else. It was locked at proposal and must not be changed silently. The rest of this skill's process steps (Remotion public/ staging, word-level caption burn, etc.) assume `render_runtime="remotion"` — the default for data-driven explainers.
- **`render_runtime="hyperframes"`** — HTML/CSS/GSAP render. Do NOT follow the Remotion-specific steps below. Instead: read `skills/core/hyperframes.md`, `.agents/skills/hyperframes/SKILL.md`, and `.agents/skills/hyperframes-cli/SKILL.md`. Call `video_compose` with the edit_decisions unchanged — it will delegate to `hyperframes_compose`, which materializes a workspace under `projects/<name>/hyperframes/`, runs `lint → validate → render`, and returns the MP4. Both lint AND validate must pass before render; contrast can be deferred during iteration but not for final delivery.
- **`render_runtime="ffmpeg"`** — simple concat/trim. Call `video_compose` directly; it will NOT auto-upgrade to Remotion when this runtime is explicitly locked.
- **Runtime unavailable** — surface the blocker per AGENT_GUIDE.md > "Escalate Blockers Explicitly" and get user approval (recorded as a `render_runtime_selection` decision in decision_log) before switching.
`final_review.checks.promise_preservation.render_runtime_used` must equal the runtime that actually ran; `runtime_swap_detected` must be `false` unless an approved decision authorizes the swap.
**Pass `proposal_packet` to `video_compose.execute()`** so in-tool swap detection can actually fire. Without it the `runtime_swap_check` is reported as `skipped` and you have to rely on the reviewer skill's cross-artifact comparison instead.
## Prerequisites
| Layer | Resource | Purpose |
@@ -8,6 +8,28 @@ You are the **Proposal Director** for a generated explainer video. You sit betwe
Think of yourself as a creative agency pitching to a client: you present concepts backed by research, show what it'll cost, explain the tradeoffs, and let the client choose.
## Runtime Selection (required field — `render_runtime`)
Explainer proposals must lock **both** a `renderer_family` (creative grammar) and a `render_runtime` (technical engine). Read `skills/meta/animation-runtime-selector.md` for the decision matrix and `AGENT_GUIDE.md` → "Present Both Composition Runtimes (HARD RULE)" for the governance contract.
**MANDATORY workflow — present both runtimes, don't silently default:**
1. Query `video_compose.get_info()["render_engines"]`. If both `remotion` and `hyperframes` are `True`, proceed to step 2. If only one is available, go to step 4 with just that one.
2. Present both runtimes to the user with brief-specific analysis. For THIS concept:
- **Remotion** — one line on fit (mention the React scene stack components that apply), one line on tradeoff.
- **HyperFrames** — one line on fit (mention HTML/GSAP motion, registry blocks, kinetic typography if applicable), one line on tradeoff.
3. Recommend one with rationale tied to the brief's `delivery_promise`, `visual_approach`, and whether word-level caption burn is required (that one forces Remotion).
4. Wait for explicit user approval. Do NOT write `render_runtime` into `proposal_packet.production_plan` before approval.
5. Log a `render_runtime_selection` decision in `decision_log` with BOTH runtimes (plus `ffmpeg` if it was a realistic option) in `options_considered`, the user's pick as `selected`, and the rationale as `reason`. If a runtime was unavailable, record it as rejected with `rejected_because: "runtime not available on this machine"`.
Fit cheat-sheet for recommendation (input for the conversation, not an auto-decision):
- Existing React scene stack (text_card, stat_card, bar_chart, line_chart, pie_chart, kpi_grid, callout, comparison, hero_title, caption overlay, anime_scene) fits → recommend **Remotion**.
- Kinetic typography, custom HTML motion graphics, registry-block-driven scenes, or website-to-video → recommend **HyperFrames**.
- Word-level/karaoke captions required → **Remotion only** in Phase 1 (caption parity is deferred).
A `render_runtime_selection` decision with only one option considered when both were available is a CRITICAL reviewer finding.
## Prerequisites
| Layer | Resource | Purpose |
@@ -4,6 +4,18 @@
Render the hybrid project so source media, support graphics, and audio all remain coherent across outputs.
## Runtime Routing (MANDATORY first step)
Read `edit_decisions.render_runtime`. Hybrid work typically sticks with Remotion because source footage + React support overlays compose cleanly in one pass:
- **`render_runtime="remotion"`** — default. Source footage via `<OffthreadVideo>`, support graphics as React components, one render.
- **`render_runtime="hyperframes"`** — pick only when the support layer is HTML/GSAP-native (e.g., animated text callouts, registry blocks). Source footage is still possible via `<video class="clip">` but lose some of the Remotion component stack. See `skills/core/hyperframes.md`.
- **`render_runtime="ffmpeg"`** — rare on this pipeline; implies no generated support layer.
Silent runtime swap is a CRITICAL governance violation. Escalate blockers per AGENT_GUIDE.md before substituting.
**Pass `proposal_packet` to `video_compose.execute()`** so the tool's in-tool swap-detection check runs against the proposal directly instead of being `skipped`.
## Prerequisites
| Layer | Resource | Purpose |
+13
View File
@@ -6,6 +6,19 @@ Use this pipeline when the project combines real source media with support visua
Hybrid is not a catch-all. Your first job is to define what stays primary.
## Runtime Selection (MANDATORY — present both runtimes)
Before locking the production plan, decide `render_runtime` with the user. Hybrid supports BOTH Remotion and HyperFrames; neither is an auto-default. Follow the contract in AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)":
1. Query `video_compose.get_info()["render_engines"]`. If both `remotion` and `hyperframes` are `True`, present both to the user with brief-specific analysis:
- **Remotion** — fits when source footage dominates and support layers are React scene components (chart, callout, text card). Remotion composes video clips + React overlays in one pass via `<OffthreadVideo>`.
- **HyperFrames** — fits when support layers are HTML/GSAP-native (kinetic callouts, registry blocks, typographic overlays) and source footage is embedded as `<video class="clip">`.
2. Recommend one with rationale tied to the anchor medium and the shape of the support layer.
3. Wait for explicit user approval.
4. Log the choice in `decision_log` as a `render_runtime_selection` decision with BOTH runtimes in `options_considered`.
A `render_runtime_selection` decision with only one runtime in `options_considered` when both were available is a CRITICAL reviewer finding.
## Reference Inputs
- `docs/hybrid-video-best-practices.md`
@@ -4,6 +4,14 @@
Render the localized outputs. The quality bar is intelligibility, timing coherence, and clear version labeling across every language package.
## Runtime Routing (HARD CONSTRAINT — Remotion or FFmpeg only)
Phase 1 deferred from HyperFrames. `edit_decisions.render_runtime` must be `"remotion"` or `"ffmpeg"`. Localization depends on Remotion's caption stack (per-locale subtitle burn) and, when dubbing with lip-sync, on the Remotion TalkingHead pipeline. HyperFrames has no parity for either in Phase 1.
- If `edit_decisions.render_runtime == "hyperframes"`, stop. Re-open the idea stage and surface the constraint — don't silently rewrite the runtime.
- Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": the pipeline's constraint does NOT skip the conversation. Present the constraint to the user so they know HyperFrames exists but isn't viable here. Log a `render_runtime_selection` decision with hyperframes `rejected_because: "caption + lip-sync parity deferred on localization-dub"`.
- Pass `proposal_packet`/`brief` to `video_compose.execute()` for end-to-end runtime-swap detection.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,12 @@ Use this pipeline when the user has a source video and wants translated delivera
Your first responsibility is to define what kind of localization is actually required, because subtitle-only, dubbed-audio, and lip-synced translation are different jobs.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"` (composed deliverables with per-locale caption burn / lip-sync) or `"ffmpeg"` (pure subtitle-burn over source with no composition). **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — localization depends on Remotion's caption stack and, for dubbed-with-lip-sync, on the Remotion TalkingHead pipeline.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": do NOT silently default to remotion. Tell the user: "HyperFrames is available, but localization-dub depends on Remotion caption + TalkingHead parity that isn't there yet in Phase 1 — remotion is the only viable choice". Record a `render_runtime_selection` decision with hyperframes `rejected_because: "caption + lip-sync parity deferred on localization-dub"`.
## Reference Inputs
- `docs/localization-dubbing-best-practices.md`
@@ -4,6 +4,14 @@
Render the podcast-derived outputs with audio fidelity as the top priority. The visuals need to support the speech, not compete with it.
## Runtime Routing (HARD CONSTRAINT — Remotion or FFmpeg only)
Phase 1 deferred from HyperFrames. `edit_decisions.render_runtime` must be `"remotion"` (audiograms, composed outputs) or `"ffmpeg"` (pure-audio-led clip exports). HyperFrames caption-burn parity is deferred, and podcast outputs lean on Remotion's word-level caption stack.
- If `edit_decisions.render_runtime == "hyperframes"`, stop. Re-open the idea stage and surface the constraint to the user. Never silently rewrite the runtime.
- Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": tell the user HyperFrames exists and why it isn't viable on this pipeline, rather than silently locking remotion. Record a `render_runtime_selection` decision with hyperframes `rejected_because: "caption-burn parity deferred on podcast-repurpose"`.
- Pass `proposal_packet`/`brief` to `video_compose.execute()` for end-to-end runtime-swap detection.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,12 @@ Use this pipeline when the source is a podcast episode, either audio-only or vid
Your first responsibility is to decide what is feasible from the source that actually exists.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"` (audiograms and composed outputs) or `"ffmpeg"` (pure-audio-led clip exports). **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — podcast outputs lean on Remotion's word-level caption stack, which has no HyperFrames parity yet.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": surface the constraint to the user — "HyperFrames is available on your machine, but podcast-repurpose depends on Remotion caption burn, so remotion is the only viable choice here". Record a `render_runtime_selection` decision with hyperframes `rejected_because: "caption-burn parity deferred on podcast-repurpose"`.
## Reference Inputs
- `docs/podcast-repurposing-best-practices.md`
@@ -4,6 +4,19 @@
Render the final screen-demo outputs. The quality bar is simple: the UI must be readable, the pacing must feel intentional, and the result must match the planned platform shapes.
## Runtime Routing (MANDATORY first step)
Read `edit_decisions.render_runtime` first. Screen-demo compositions use three distinct runtimes depending on the demo shape:
- **`render_runtime="remotion"` with `TerminalScene`** — the preferred path for synthetic terminal/CLI/install flows. See `.agents/skills/synthetic-screen-recording/`.
- **`render_runtime="remotion"`** (other scenes) — for mixed screen-capture + animated overlays.
- **`render_runtime="hyperframes"`** — for custom synthetic HTML UI demos where CSS + GSAP express the UI naturally. Read `skills/core/hyperframes.md`. `hyperframes lint` and `hyperframes validate` must both pass before render.
- **`render_runtime="ffmpeg"`** — for simple cut/concat of real screen recordings without composition.
Silent swaps between runtimes are CRITICAL governance violations. If the locked runtime is unavailable, escalate per AGENT_GUIDE.md before substituting.
**Pass `proposal_packet` to `video_compose.execute()`** so the tool can directly confirm the runtime locked at proposal matches what edit_decisions says. Without it the in-tool swap check is skipped and you rely entirely on the reviewer skill to catch drift.
## Prerequisites
| Layer | Resource | Purpose |
@@ -1,5 +1,17 @@
# Idea Director - Screen Demo Pipeline
## Runtime Selection (MANDATORY — present all viable runtimes)
Lock `render_runtime` at the idea stage alongside the production mode. Which runtimes are viable depends on the mode:
| Production mode | Viable runtimes |
|-----------------|-----------------|
| `real_capture` (actual screen recording) | `remotion` (preferred — mix capture with overlays), `ffmpeg` (pure concat/trim) |
| `synthetic_terminal` (Remotion `TerminalScene`) | `remotion` only |
| `synthetic_ui` (custom HTML UI demo) | `remotion` OR `hyperframes` — real choice, present both |
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": when the mode allows multiple runtimes AND both are available on the machine (check `video_compose.get_info()["render_engines"]`), present both to the user with brief-specific analysis, recommend one, wait for approval. Do NOT silently default. When the mode constrains the choice (e.g. `synthetic_terminal` is Remotion-only), tell the user the constraint explicitly rather than silently locking remotion. Record every choice in `decision_log` under `render_runtime_selection` with all considered options.
## When To Use
Use this pipeline whenever the deliverable is a screen-recording-style demo. There are **two production modes** — pick one in the brief:
@@ -4,6 +4,14 @@
You have edit decisions and an asset manifest. Your job is to render the final talking-head video: apply the enhancement chain, burn subtitles, mix audio, and encode to the target profile.
## Runtime Routing (HARD CONSTRAINT — Remotion or FFmpeg only)
Phase 1 deferred from HyperFrames. `edit_decisions.render_runtime` must be `"remotion"` (preferred — uses the `TalkingHead` composition + `remotion_caption_burn`) or `"ffmpeg"` (for source-footage concat with no composition).
- If `edit_decisions.render_runtime == "hyperframes"`, stop. Re-open the idea stage and surface the constraint. Silent rewrite is a governance violation.
- Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": the pipeline's constraint doesn't skip the conversation. Present the constraint to the user so they know HyperFrames exists but isn't viable here. Record a `render_runtime_selection` decision with hyperframes `rejected_because: "TalkingHead + caption parity deferred on talking-head"`.
- Pass `proposal_packet`/`brief` to `video_compose.execute()` for runtime-swap detection.
## Prerequisites
| Layer | Resource | Purpose |
@@ -6,6 +6,12 @@ You are starting a talking-head video project. You have raw footage of a person
Unlike the explainer pipeline (which starts from a topic), you start from existing footage. The brief documents what you're working with and what the final video should look like.
## Runtime Selection (MANDATORY — present the constraint, don't silently pick)
Lock `render_runtime = "remotion"` (preferred — uses `TalkingHead` + `remotion_caption_burn`) or `"ffmpeg"` (for source-footage concat with no composition). **HyperFrames is NOT a valid runtime on this pipeline in Phase 1** — the TalkingHead composition and word-level caption burn have no HyperFrames parity yet.
Per AGENT_GUIDE.md → "Present Both Composition Runtimes (HARD RULE)": do NOT silently default to remotion. Tell the user: "HyperFrames is available, but talking-head depends on the Remotion TalkingHead composition, so remotion is the only viable composition choice (or ffmpeg for a raw cut) — OK to proceed?" Record a `render_runtime_selection` decision with hyperframes as a rejected option (`rejected_because: "TalkingHead + caption parity deferred on talking-head"`).
## Prerequisites
| Layer | Resource | Purpose |