motion-choreographer · git:20260610.b85bc8a · 2026-06-10 · sha256 77f1645526a6ce8a
motion-choreographer git:20260610.b85bc8aA
Immutable. This exact content is served forever at /api/v1/blob/77f1645526a6ce8a.
--- model_tier: inherit name: motion-choreographer description: "Use when turning a locked still + blueprint into a provider-tuned motion prompt — camera, primary + secondary motion, physics, native-audio sync. Triggers 'motion prompt for Veo/Kling/Sora'." personas: - ai-video-technical-director domain: product workspaces: - small-business packs: - ai-video lifecycle: experimental trust: level: experimental install: default: false removable: true --- # motion-choreographer > Turn an approved still + the 12-block scene blueprint into a > provider-tuned **motion prompt** that the target video adapter > consumes. Camera choreography, primary subject motion, secondary > environment motion, physics constraints, and — when the adapter > declares `audio: native` — a synchronized audio direction block. > Reads adapter capabilities from > [`adapter-contract.md`](../../../scripts/ai-video/lib/adapter-contract.md); > never speaks to a network API. ## When to use - An image is locked (operator picked one candidate via `operator-pick.sh`) and the next step is motion + audio direction for the video adapter. - The blueprint exists in `scenes/<id>/blueprint.json` but the motion prompt has not been emitted yet. - A provider switch (Veo → Kling, Sora → Higgsfield) requires the same scene retuned for the new adapter's capability profile. Do NOT use when: - The blueprint is still prose only — run [`scene-expander`](../scene-expander/SKILL.md) → `parse-blueprint.sh` first. - No still has been locked — the operator-selection checkpoint must complete first. - The output is a still graphic — `canvas-design`. ## Procedure ### Step 0: Inspect 1. Read `scenes/<id>/blueprint.json` — fail loud if missing. 2. Read `scenes/<id>/selection.json` — fail loud if missing; the locked image path is required as the motion anchor. 3. Read the target adapter's capability via `scripts/ai-video/adapters/<id>.sh capability`. Cache `audio=*` for Step 3. 4. If a `character.json` lock exists, load it verbatim — identity tokens are immutable. ### Step 1: Camera choreography Emit a `CAMERA MOTION` block with the move type, distance, speed in seconds, and start-end framing. - Move types: lock-off, pan, tilt, dolly-in, dolly-out, truck, pedestal, push, pull, handheld, gimbal-glide, crane, whip. - Speed in seconds per beat (`0.4s push, hold 1.6s, 0.4s pull`). - Start and end framing named (`MS → CU`, `WS → MS`). Blueprint intent-class decoding — the blueprint CAMERA block names one of six provider-agnostic intent classes; map it to the move types above before encoding: | Intent class | Move-type mapping | |---|---| | static hold | lock-off | | push-in | push / dolly-in | | pull-back | pull / dolly-out | | lateral track | truck / pan | | handheld drift | handheld / gimbal-glide | | orbit | crane / arc via truck+pan | Adapter quirks (per-provider encoding of the mapped move): - **Veo** — accepts named moves; prefers ≤ 8s clips. - **Kling** — motion intensity 0–1 token; map our speed to that. - **Sora** — natural-language move + duration; no token. - **Higgsfield** — preset-driven; pick the preset that matches the move; record the preset id in the motion prompt. - **LENS handling** — blueprint mm + aperture translate to the provider's nearest lens / FOV idiom; never forward raw mm to a provider that lacks lens grammar. - **DURATION handling** — the blueprint value is free; clamp to the provider ceiling here and record the clamp in `review.md` (a silent clamp is a drift bug). ### Step 2: Primary + secondary motion Two blocks: 1. **PRIMARY MOTION** — what the subject does, beat-counted, with physics anchors (mass, contact points, momentum). Reuse `ACTION` from the blueprint; refine for the adapter's preferred verb density. 2. **SECONDARY MOTION** — what the world does (hair, fabric, foliage, water, dust, particles, breath). One layer per line. ### Step 3: Audio direction (conditional) If adapter capability is `audio: native` AND the blueprint's `audio.enable_native_audio` is `true`: Emit an `AUDIO DIRECTION` block with: - `DIALOGUE TIMING` — `speaker @ 0.4s: "line"` per dialogue entry. - `AMBIENT LAYERS` — copy from blueprint; one layer per line. - `SYNC CUES` — which action beat maps to which audio cue (`footstep @ 1.2s`, `door close @ 2.1s`). If adapter capability is `audio: none`: - Emit a `# AUDIO: ffmpeg-mux fallback` comment with the blueprint's audio paths queued for stitch-time mux. - Set `enable_native_audio: false` in the motion-prompt JSON. - Blueprint carries DIALOGUE → the mux fallback cannot speak text lines. Emit a mandatory `AUDIO DOWNGRADE` warning block in `motion-prompt.txt` AND `adapter-notes.md` listing every dialogue line that will not render. The decision whether that is acceptable belongs to the orchestrator gate (adapter-contract § Audio ownership) — this skill translates, it never validates, and it NEVER silently strips dialogue. ### Step 4: Physics constraints Emit `PHYSICS` — a short list of what the model must respect: gravity direction, contact friction, fluid behavior, hair / cloth inertia, lens parallax. Single line per constraint. ### Step 5: Emit motion-prompt JSON Write `scenes/<id>/motion-prompt.json` with the adapter-contract stdin shape. The orchestrator pipes this into the video adapter's `submit` subcommand. ### Step 6: Validate 1. JSON parses (`jq .`). 2. `requires.audio_native` is consistent with the chosen adapter's capability. 3. Duration in the motion prompt matches blueprint duration ±0. 4. Identity tokens (if `character.json` exists) are verbatim. ## Output format 1. **`scenes/<id>/motion-prompt.json`** — adapter-contract stdin. 2. **`scenes/<id>/motion-prompt.txt`** — labeled prose blocks (CAMERA MOTION · PRIMARY MOTION · SECONDARY MOTION · AUDIO DIRECTION · PHYSICS) for operator review. 3. **`scenes/<id>/adapter-notes.md`** — which adapter, which capability, which preset / model, with rationale. ## Gotcha - The model wants to "improve" the blueprint's `SUBJECT` block — identity tokens are immutable; refuse the temptation. - Picking `audio: native` on an adapter that returns `audio: none` produces silent video — always read capability first, never guess from the adapter name. - Higgsfield preset id must be recorded; otherwise the rerun drifts to whichever preset the model picks on the next call. - Sora durations > 8s often degrade — clamp at the adapter table limit; surface the clamp to the operator. ## Do NOT - Do NOT emit motion prompts for an adapter whose capability you did not query this turn. - Do NOT skip the still-locked check — motion direction without an anchored image diverges on every call. - Do NOT paraphrase identity tokens from `character.json`. - Do NOT call any network API — this skill is provider-tuning prose only. ## Policies Motion prompts inherit every constraint the upstream blueprint carries. Before emitting provider-tuned prose: - [`agents/settings/policies/media/disclosure.md`](../../../agents/settings/policies/media/disclosure.md) — every distributed clip carries the non-removable AI-generation disclosure; refuse adapter flags that would suppress it. - [`agents/settings/policies/media/transparency.md`](../../../agents/settings/policies/media/transparency.md) — provider provenance (C2PA / SynthID) is preserved; refuse re-encode flags whose effect is to strip provenance. - [`agents/settings/policies/media/voice-cloning.md`](../../../agents/settings/policies/media/voice-cloning.md) — when the motion prompt requests `audio: native` narration in a named voice. - [`agents/settings/policies/media/brand-impersonation.md`](../../../agents/settings/policies/media/brand-impersonation.md) — when the motion prompt copies a recognised brand's chyron / mascot / signature transition. Refuse-and-surface; the motion prompt cannot launder a policy gap upstream skills should have caught.