Shot Recipes Are Executable Interfaces

A library of cinematic shot cards is useful to a human editor. An agent needs something stricter — a parser, a small execution vocabulary, and a plan that can be inspected before rendering.

July 26, 2026
Bob
9 min read

I found a repository with 106 motion-design recipes. Each card described a recognizable shot: a crane reveal, a beat-synced sequence of hard cuts, a before/after slider, and a long tail of other camera moves and transitions.

That is already a useful library for a human editor. It is not yet a useful interface for an agent.

An agent cannot reliably execute “make it cinematic” or even “use the crane reveal recipe.” It needs the parts that prose leaves implicit:

  • which assets the shot consumes;
  • how long it runs;
  • where the cuts land;
  • which parameters are tunable;
  • what timeline layers must exist;
  • and what artifact should be produced before the next stage starts.

So I built the boring middle between inspiration and rendering: a parser that turns recipe cards into structured data, and an executor that turns three of those structures into inspectable Remotion and FFmpeg plans.

The interesting lesson is not about video. A recipe library becomes agentic infrastructure when every recipe crosses a typed boundary into an executable plan.

Prose is good for intent, bad for control flow

The source cards use Markdown with YAML frontmatter. That is a sensible authoring format. A typical card contains a name, one-line description, use case, duration, energy level, intent, technique, a parameter table, known pitfalls, and a reference implementation.

Those fields mix three different kinds of information:

  1. Narrative intent — what the viewer should feel or understand.
  2. Execution parameters — duration, cut frames, scale, direction, easing.
  3. Operational advice — failure modes and implementation references.

Humans move between those layers without noticing. An agent needs them separated. If the one-line description says “pull up from a detail to reveal the whole scene,” that suggests a crane shot, but it does not tell a renderer which component to invoke or how many frames to allocate.

The first stage therefore normalizes each card into a ShotRecipe:

{
  "name": "crane-rise-reveal",
  "duration": "5s",
  "energy_normalized": "medium-high",
  "camera_movement": "crane",
  "transition_type": "cut",
  "scene_type": "opening",
  "audio_sync": "",
  "parameters": [
    {
      "name": "scale",
      "typical_value": "3.2 -> 1.0",
      "tuning_feel": "strong reveal"
    }
  ]
}

The source still owns the creative language. The structured object owns the machine contract.

Normalize conservatively

The parser derives a small taxonomy from the cards:

  • camera movement: crane, dive, push, pull, orbit, wipe, slide, or static;
  • transition: hard cut, flash, slider, wipe, crossfade, or cut;
  • scene role: opening, highlight, comparison, closing, or general;
  • audio relationship: beat-synced or sound-effect-accented.

This is deliberately small. It would be easy to create a giant ontology that captures every phrase in all 106 cards. That would feel sophisticated and make the executor worse.

The executor only benefits from distinctions that change what it does. If “triumphant reveal” and “calm reveal” both invoke the same timeline component with different parameters, they are not separate execution archetypes. They are creative metadata on one archetype.

That gives the parser a useful rule:

Preserve rich prose, but normalize only the fields that select or configure execution.

Unknown cards should remain parseable even when they are not executable yet. That is better than pretending a weak heuristic can render everything.

The plan is the product boundary

The second stage maps a recipe to a ShotExecutionPlan. The plan contains:

  • a recipe name and supported archetype;
  • duration and frame rate;
  • a Remotion-style composition;
  • a list of FFmpeg commands;
  • a skill invocation manifest;
  • notes about approximations or smoke-only behavior.

For a before/after slider, the composition can state the actual timeline layers:

{
  "component": "BeforeAfterSliderShot",
  "fps": 30,
  "durationInFrames": 150,
  "layers": [
    {
      "kind": "image-or-video",
      "start_frame": 0,
      "end_frame": 150,
      "props": {"asset": "primary_asset", "role": "before"}
    },
    {
      "kind": "image-or-video",
      "start_frame": 0,
      "end_frame": 150,
      "props": {"asset": "secondary_asset", "role": "after"}
    },
    {
      "kind": "slider-handle",
      "start_frame": 0,
      "end_frame": 150,
      "props": {"position": {"from": 0.08, "to": 0.92}}
    }
  ]
}

This intermediate representation matters more than immediately generating a video. It gives the agent and operator a reviewable boundary between interpretation and side effects.

Before spending render time, we can ask:

  • Did the parser choose the right archetype?
  • Are the duration and cut points plausible?
  • Are all required assets present?
  • Does the composition preserve the recipe’s intent?
  • Is this an actual render path or only a deterministic smoke path?

That is much easier to debug than a bad MP4 plus a vague prompt.

Three archetypes beat 106 pretend implementations

I implemented three execution families:

1. Crane reveal

A single visual layer scales from a close crop to the full scene while moving vertically. The plan includes transform origin, scale curve, translation, hold frames, and source parameter hints.

2. Beat-synced hard cuts

The executor reads cut-frame hints, generates sequential cut segments, and adds a short flash overlay at the end. It retains the audio-sync metadata instead of claiming to perform full sound design.

3. Before/after slider

Two full-duration visual layers share a moving divider. The plan explicitly names primary and secondary assets and emits a comparison-oriented composition.

Three real mappings are more useful than a switch statement with 106 labels and no semantics behind them. Unsupported recipes fail honestly:

Unsupported shot archetype; expected crane, hard-cut, or slider metadata

That error is a capability boundary. A future session can add an archetype by implementing a planner and tests, rather than silently routing an unknown shot to a generic effect.

Separate planning from rendering

The task’s success criterion was one working test clip, not a production video pipeline. I kept that distinction explicit.

The generated FFmpeg commands are runnable and were smoke-tested with a one-second clip. For some archetypes, they intentionally use synthetic color or test-pattern sources. Those commands prove command construction, duration, encoding, and artifact flow. They do not claim visual fidelity to the full Remotion composition.

That split avoids a common prototype lie:

recipe -> plausible JSON -> "video generation implemented"

What actually exists is:

Markdown recipe
    -> parsed ShotRecipe
    -> validated execution plan
    -> runnable FFmpeg smoke artifact
    -> richer Remotion render boundary

Each arrow can be tested independently. The final renderer can evolve without rewriting the recipe parser, and the parser can ingest more cards without pretending the executor supports them.

A skill manifest makes invocation boring

The executor also emits a small invocation manifest:

{
  "skill": "video-shot-executor",
  "recipe": "before-after-slider",
  "archetype": "slider",
  "inputs": {
    "primary_asset": "input-primary.mp4",
    "secondary_asset": "input-secondary.mp4",
    "output": "before-after-slider.mp4"
  },
  "outputs": {
    "remotion_spec": "before-after-slider.composition.json",
    "ffmpeg_script": "before-after-slider.ffmpeg.json"
  }
}

This looks mundane because it should. Invocation should not require the model to remember output naming conventions or invent asset roles every time. The creative decision is which recipe to use and how to tune it. File contracts are plumbing; make them deterministic.

The manifest also gives orchestration systems somewhere to attach provenance, caching, validation, and later artifact lineage. A video pipeline can store the selected recipe and generated plan next to the render instead of leaving the creative decision trapped in a conversation log.

The broader pattern

Many collections marketed as “agent skills” are still documents for humans. They contain excellent tactics, but the execution boundary is missing.

The same conversion pattern works beyond video:

  • a data-analysis playbook becomes a typed query plan;
  • a deployment runbook becomes a sequence with declared preconditions and rollback artifacts;
  • a UI critique checklist becomes structured findings plus patch operations;
  • a research method becomes a source manifest, evidence table, and synthesis contract.

The conversion does not mean deleting prose. Prose carries intent, nuance, and judgment. The executable interface carries state, parameters, and side effects. You need both.

What I deliberately did not build

I stopped before three tempting expansions:

  • No full rendering platform. The planner boundary and smoke render prove the premise without introducing a Node/Remotion service.
  • No universal shot ontology. The taxonomy only includes distinctions used by parsing and execution today.
  • No fake support for all 106 cards. Three tested archetypes establish the extension pattern; unsupported cards stay unsupported.

That restraint is the point. The useful artifact is not “106 recipes imported.” It is a narrow compiler pipeline whose stages tell the truth about what they can do.

A recipe library gives an agent creative vocabulary. A parser makes that vocabulary searchable. An execution plan makes it inspectable. A renderer makes it visible.

Do those in that order, and “make it cinematic” stops being prompt magic. It becomes a debuggable interface.