cueframe 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,442 @@
1
+ ---
2
+ name: composing-video
3
+ description: Use when an agent is asked to make ANY video with CueFrame — a product launch, announcement, promo, teaser, social clip, reel, short, explainer, animated explainer, concept video, product/dev-tool demo, walkthrough, or founder/talking-head piece. Triggers on "make a video", "launch video", "promo", "teaser", "reel", "short", "explainer", "animated explainer", "demo video", "talking-head", or turning long-form footage into clips.
4
+ ---
5
+
6
+ # Composing Video: craft for CueFrame
7
+
8
+ ## The one idea
9
+
10
+ CueFrame composes **real footage** into finished video, and that is its edge: it detects faces and the active speaker and reframes/punches in on them; it renders titles behind the speaker's head; it times captions to the real transcript; it grades color and renders 4K. Real footage is the strongest grounding you can give a video and CueFrame's home turf — so it is the thing to reach for FIRST and usually your highest-leverage move. But the skill's job is **any good video**, footage or not: an animated explainer, a Manim concept video, a data piece. These are first-class, not a lower tier.
11
+
12
+ What separates good from slop is not "footage vs. no footage" — it is **grounded specificity vs. the generic default**. The enemy is the interchangeable filler that could belong to any video: gradient/aurora backgrounds under kinetic text, stock "AI b-roll," faked UI, unmotivated motion. The antidote is a **controlling idea** plus **grounded, specific content** — real footage, OR real UI/screen captures, OR real data, OR a *purposeful* graphic/animation that DEPICTS THIS content specifically (a Manim diagram of the actual mechanism, a data animation of the real numbers) — a data/mechanism visual, NOT animated copy. Animated/kinetic TEXT by itself is not grounding. A well-crafted animated explainer built on diagrams of the real mechanism is grounded and good; it is not slop.
13
+
14
+ **Generic default ⇒ slop. Grounded specificity ⇒ good.** Real footage is the strongest grounding and CueFrame's home turf — reach for it first — but purposeful, specific graphics count too. This is a mechanical prediction, not a taste call (see *Craft principles*). Your single most expensive mistake is walking past real footage that exists to build generic gradient slides instead — which is precisely what happened in the SIA case below.
15
+
16
+ **The loophole to nail shut:** "purposeful graphics" means *specific to this content* — the real mechanism, the real data, a diagram of the actual thing. Animated/kinetic TEXT by itself is not that, no matter how deliberate — it is not grounding. A generic gradient or aurora is NEVER "purposeful"; it is always the slop default. The reframe broadens what counts as good; it does not wave decorative filler through.
17
+
18
+ **The boundary.** This is craft guidance you can override, not a gate. You own the **vision** (the one idea for this specific video) and you own **data correctness** (if you supply a wrong number, CueFrame renders it faithfully and the mistake is yours). CueFrame owns being faithful, legible, and teaching you the craft below. Reason from these principles; break a rule knowingly when your vision demands it. (Skip this whole flow only for a pure re-render of an already-approved composition, or a single trivial still — don't ceremony a one-liner.) Planning a new video from scratch? Do **`cueframe-storyboard`** first to get the beat flow, then apply this craft to each beat.
19
+
20
+ ---
21
+
22
+ ## Related skills & positioning
23
+
24
+ This skill is the **craft / quality layer** for an agent driving CueFrame over the **MCP tool surface** (`preview_frame` / `apply_composition` / `score_composition` / `create_render`) — *not* the `cueframe` CLI binary. It owns the decision layer: vision → rubric → grounding → iterate → verify. When a mechanic below is owned by a sibling skill, defer to that skill for the deep how-to:
25
+
26
+ - **`cueframe-storyboard`** — the intake/structure step BEFORE craft: interview the user for the brief and lay out the hook→body→cta beat flow. Start here for a new video from scratch; this skill then makes each beat grounded and good.
27
+ - **`cueframe-cli`** — the `cueframe` binary + wire mechanics (auth, projects, raw request/response shapes).
28
+ - **`cueframe-compose-loop`** — the full author→render→verify→fix **convergence loop**; it owns the loop budget and ship bar (this skill's step 6 mirrors it: 3–5 passes, ship at composite ≥ 7.5).
29
+ - **`cueframe-product-video`** — the click-points → reframe-segment **auto-zoom tiling** + picture-in-picture recipe for screen demos.
30
+ - **`cueframe-brand-demo`** — brand-token vocabulary + auto intro/outro/logo for branded launches.
31
+ - **`cueframe-component-authoring`** — the full fork → preview → push loop for custom components.
32
+
33
+ Loading this skill and a sibling together: this one governs *what makes the video good*; the sibling governs *how that mechanic works*.
34
+
35
+ ---
36
+
37
+ ## If you read nothing else
38
+
39
+ Six non-negotiables. Everything below is the reasoning behind them.
40
+
41
+ 1. **HUNT for real footage FIRST** — it's the strongest grounding and CueFrame's edge — before building without it; the SIA failure was never looking.
42
+ 2. **Write a harsh, specific rubric BEFORE you render a single frame** — including the three mandatory kill criteria (K1–K3), meaning preserved.
43
+ 3. **Grounded, specific content must DOMINATE the runtime** — real footage, real UI/data, or purposeful content-specific graphics — never generic/decorative filler. (For footage-based formats, target real footage ≥60%.)
44
+ 4. **Describe every rendered still in words before you score it** — if you can't say what's in the frame, you didn't look.
45
+ 5. **Get an independent grade you can't game:** `score_composition` samples its own frames — you cannot cherry-pick flattering timestamps past it.
46
+ 6. **Budget 3–5 verify passes, never set your ship bar below 7.5/10, then stop.**
47
+
48
+ ---
49
+
50
+ ## The method — run these steps in order, every time
51
+
52
+ The order is the forcing function. Steps 2, 3, and 5 are where agents cut corners and ship slop, so they are not optional.
53
+
54
+ ### 1 — Decide the VISION, then the FORMAT
55
+ Write the controlling idea as one sentence with a value and a cause — "X wins *because* Y" (McKee, *Story*: a story is a charged value-shift, not a topic). Not "SIA launch" — a claim: "Two founders tell you, to your face, why SIA kills the pipeline step you dread — and you watch it be faster." Then pick the format floor: product-launch / social-clip / explainer / demo / talking-head (playbooks below). The vision is the filter for what belongs; anything that doesn't express it gets cut.
56
+
57
+ ### 2 — Write a HARSH, SPECIFIC rubric — BEFORE you render anything
58
+ Authored against the vision, before pixels exist, so it can't be rationalized after the fact. Use the template below: must-haves anchored to named frame timestamps, measurable thresholds, and kill criteria that fail the render outright.
59
+
60
+ **Hard gate:** do not call `preview_frame` until the rubric text exists in your context. No rubric → no pixels.
61
+
62
+ **These three kill criteria are MANDATORY — preserve the MEANING of K1–K3 in every rubric, adapting the phrasing to your video. You may add more; you may not remove or weaken these:**
63
+ - **K1.** Any sampled frame is a gradient/solid background with only text and NO grounded subject — no real footage, no real UI/data, no purposeful content-specific graphic, just decorative filler. Animated/kinetic TEXT over any background does NOT count as a grounded subject — only a visual of the real mechanism or real data does.
64
+ - **K2.** Any on-screen number you cannot trace to a written source, or any faked/mocked UI standing in for a real capture.
65
+ - **K3.** Generic/decorative filler dominates the runtime — grounded, specific content (real footage, real UI/data, or purposeful content-specific graphics) does not.
66
+
67
+ ### 3 — Ground the video (hunt for footage first, then a grounding ladder — never straight to generic filler)
68
+
69
+ Real footage is the strongest grounding and CueFrame's edge, so hunt for it FIRST — but grounding is the goal, and purposeful, specific graphics are a legitimate way to reach it.
70
+
71
+ **3a. Hunt for footage FIRST, before building without it.** Before you build without footage, actively look, in order:
72
+ 1. Did the user attach or name footage?
73
+ 2. Does the subject (company/person/product) already have a launch video, founder clips, demo recordings, or a conference talk you can `import_media` from a public https URL?
74
+ 3. Ask the user directly: *"Do you have a founder clip, screen capture, or event recording? CueFrame is built to compose real footage — it's the difference between a launch film and a slideshow."*
75
+
76
+ In the SIA case, step 2 alone would have surfaced the founders-to-camera launch video and changed everything. Footage is the highest-leverage grounding; don't walk past it.
77
+
78
+ **3b. The stop fires only when the plan is GENERIC filler.** If your plan has no grounded content — no footage, no real UI/data, no purposeful content-specific graphic, just a gradient with kinetic text — STOP and say so, verbatim, before rendering anything:
79
+ > *"This has no grounded content — it's a gradient-and-text motion piece, the generic default, not a video composed from the real thing. I recommend we ground it in [a 30-second founder to-camera clip / a real screen capture / a Manim diagram of the actual mechanism]. Want to proceed as generic motion-graphics, or ground it first?"*
80
+
81
+ Proceed only on an explicit "proceed." A *purposeful, specific* animation — a Manim diagram of the real mechanism, a data animation of the real numbers — does NOT trip this stop; it is a legitimate grounded choice, not a consolation prize. The stop exists only for decorative, could-be-any-video filler. Silent generic slop is the failure; a stated, chosen tradeoff is fine.
82
+
83
+ **3c. The grounding ladder** (strongest first; every rung is legitimate except the last — degrade the *promise*, never the craft):
84
+ 1. **Real footage** — `import_media` a founder clip, event recording, or demo. The strongest grounding and CueFrame's home turf.
85
+ 2. **Real screen capture** — `import_media` (CueFrame cannot screen-record; that's the external Kishu client, or the user's own recording).
86
+ 3. **Real product screenshots / photos** as held stills with **motivated** motion.
87
+ 4. **Purposeful Manim / crafted graphics OF THE ACTUAL THING** — `generate_media → manim` for a diagram of the real mechanism (process/algorithm/data viz), or a data animation of the real numbers specific to this content. A **first-class grounded path**, not a fallback — a good animated explainer lives here. The grounding is that it depicts THIS thing — the real mechanism, the real data — not a decorative loop; animated/kinetic TEXT by itself does not qualify.
88
+ 5. **Generic `generate_media` texture** as a *supporting* backdrop only (a stage, a texture) — never a fake-cinematic hero, never a re-created product UI (it hallucinates specifics).
89
+ 6. **Generic gradient-with-text** is the **last** resort and is exactly what triggers the 3b stop.
90
+
91
+ Do not fake the missing footage, and do not dress up generic filler as grounding.
92
+
93
+ ### 4 — Author against `get_media_context`
94
+ When you have imported media, pull the detected **faces** (subject boxes per frame, with `faceId`s) and **transcript** before composing. Align reframe/punch-in to the faces, caption words to the transcript timing, and cut points to the speech. Discover primitives with `list_catalog` before hand-placing hex and coordinates — a built-in almost always exists.
95
+
96
+ ### 5 — Iterate on REAL PIXELS (and prove you looked)
97
+ `preview_frame` PNG stills at your rubric's named timestamps — **always including t=0 and hook-end** — and **look at them**. (Sessionless: a cold first call returns 409 box_warming — retry in a few seconds; subsequent calls are fast.)
98
+
99
+ For every still, before you score it, write one literal line of what is visible: *Is there a grounded subject (real footage, real UI/data, or a purposeful content-specific graphic)? Real UI, or a styled div? Is the background mostly empty decoration? Is the text legible over what's behind it? Does any on-screen number match its written source?* If you can't describe the pixels, you did not look — render again. Score only from these descriptions, never from what you intended to author. Grade the first frame hardest: if t=0 is a bare gradient with the product name, K1 trips and you're done.
100
+
101
+ `validate_composition` only checks shape (membership, params, track-family, reframe coverage) — a pass there means nothing about quality. Judge the pixels, not the JSON.
102
+
103
+ ### 6 — Get an independent second opinion, then stop
104
+ You grading your own render is the weak link. Call `score_composition` (sessionless — the warm box is a server detail) with your VISION line as `editorialIntent` and brand facts as `brandContext`. It renders and grades **four fixed server-side criteria** — editorial, spatial, brand, caption (0–10 each) — plus a weighted composite and a worst-first critique, **on frames it samples itself.** Your `editorialIntent` steers *what "good" means for this video*; it does **not** replace the criteria, and you cannot feed it your own rubric or pick its frames — that un-gameable sampling *is* the independence. Treat a low score on a frame you didn't choose as ground truth, not noise.
105
+
106
+ Fix the worst thing via `apply_composition`, re-render the affected frames, re-score. **Budget 3–5 verify passes** (two no-improvement passes = diminishing returns — `cueframe-compose-loop` owns the full convergence loop). Ship only when your own rubric passes with zero kill criteria tripped AND the `score_composition` composite ≥ 7.5 — not when you get bored. (No session to close — the warm box is a server detail that reaps itself.)
107
+
108
+ ---
109
+
110
+ ## Recognizing slop (the mechanism — so you can predict it, not just avoid it)
111
+
112
+ Slop is the model's most common answer to an under-specified prompt: what the path of least resistance produces once the human decision layers are removed. It has a recognizable signature *because* each missing decision compounds:
113
+
114
+ - **No juxtaposition, no meaning.** Meaning in video is manufactured by adjacency — the same neutral shot reads as grief or desire depending only on the shot next to it (Kuleshov effect; Eisenstein's montage of collision). A gradient next to a gradient creates nothing. Grounded, specific shots in sequence (problem-shot → product-shot → relief-shot) make a claim the individual shots never state. Compose in **pairs and triads**, ordered so adjacency does the arguing.
115
+ - **No specificity, no belief.** Images are encoded more deeply than abstract words (picture-superiority effect, Paivio), and — a separate, stronger mechanism — a real human face is among the most attention-binding things a screen can show. "14x faster" on a card is an abstraction the viewer can't feel; two real founders in a real office, or a diagram of the *actual* mechanism, is embodied and credible — it *shows*.
116
+ - **No subject, no eye-trace, no peak.** With nothing specific on screen there's no focus of interest to cut on (Murch's eye-trace) and no candidate for the one emotional peak the viewer remembers (Kahneman's Peak-End Rule). A flat decorated slideshow has no peak and a whimper ending.
117
+
118
+ So grounding the video (step 3) is load-bearing, not a preference. Missing it guarantees the rest.
119
+
120
+ ### Slop tells — you are making slop if a frame has any of these
121
+ 1. **Gradient/aurora background under centered kinetic text**, no grounded subject. The literal default of every text-to-video toy. Zero information per frame — animating the text, or calling it "purposeful kinetic typography," does NOT ground it; only a visual of the real mechanism or real data does.
122
+ 2. **Generic AI b-roll** — glowing brains, blue circuit boards, particle networks, rotating server racks, holographic dashboards. "Technology" as a vibe; interchangeable across a thousand companies.
123
+ 3. **Faked or mocked UI/terminals** — a styled `<div>` pretending to be the product. The cursor doesn't blink, nothing scrolls, the output is too clean. A real 4-second capture beats it every time.
124
+ 4. **On-screen numbers with no real source** — "14x", "10x", "99.9%" over a gradient. Unsourced is the content-farm tell; *wrong* is a credibility bomb.
125
+ 5. **All generic filler, nothing grounded** — 100% decorative generated backgrounds and kinetic text, with no real footage, no real UI/data, and no purposeful content-specific graphic. The master failure that produces all the others. (A *purposeful* animated explainer — one built on diagrams of the real mechanism or animations of the real data, NOT animated copy — is grounded and does NOT count as this tell.)
126
+ 6. **Unmotivated motion** — everything drifts, floats, Ken-Burns-pans, swoosh-transitions for no reason. The screensaver aesthetic: soft, well-oiled, no harsh edges, regardless of content.
127
+ 7. **Template rhythm** — title card → 3 bullet slides → CTA, every beat the same length and entrance. The eye recognizes the mold.
128
+ 8. **Metronomic pacing** — every clip the same length, every caption the same duration, no held beat before the payoff. The tell of an algorithm chunking on a timer.
129
+ 9. **Off-brand default type / over-captioning** — Inter/Arial where a brand typeface exists; karaoke captions on a slideshow with no speech to caption.
130
+ 10. **Dead-center symmetry, one z-plane** — subject and text fighting for the same pixels, throwing away the depth CueFrame gives you (an overlay title at `zPlane:"behind-subject"`).
131
+
132
+ ### The positive inverse — author toward these
133
+ One controlling idea every clip serves · grounded content of the real thing (real footage, real UI/data, or a purposeful diagram of the actual mechanism) · motivated motion (the frame moves because the subject moved or the idea turned) · restraint (fewer elements, held longer) · typographic discipline (brand type, ≤2 weights, one hierarchy) · honest data with visible provenance ("12.4% (Table 3)" beats "14x") · varied pace that builds to one memorable beat · real depth (a title behind the head, layered z-planes).
134
+
135
+ ### The SIA case — the exact contrast to burn in
136
+ **Brief:** a product-launch video for Hexo Labs' product "SIA."
137
+ **What the agent shipped (slop):** ~37s of purple-gradient slides with centered kinetic text; a static mocked terminal card pretending to be SIA running; a fabricated "14x faster" (the paper said **12.4%**); zero grounded content. A clean sweep of tells #1, #3, #4, #5, #7, #10.
138
+ **What was sitting right there, ignored:** Hexo's own launch footage — two founders talking to camera in a nice office. *Precisely* CueFrame's home turf: `all-faces` on the two-shot / `active-speaker` on the singles, transcript-timed captions, a lower-third per founder, a color grade, a 4K render.
139
+ **Craft looks like (same tool, same 37s):** `import_media` the founder footage → `get_media_context` for faces + transcript → reframe to whoever is speaking → transcript-tracked captions with a legibility plate → a title behind the head → a `lower-third` naming each founder → SIA's real brand type → if a benchmark appears, the real **12.4%** with source visible, ideally over a real capture of SIA running. One idea, grounded content, motivated cuts, honest data, a payoff. (Even the no-footage version was fixable: a Manim diagram of SIA's *actual* pipeline step beats a gradient — that's grounded too.)
140
+
141
+ ---
142
+
143
+ ## Operating floors (fold into every format)
144
+
145
+ Directional, not laws — reason above them:
146
+
147
+ - **Hook = first 3 seconds.** Viewers decide to stay or scroll almost immediately; the first frame is the highest-leverage frame in the piece. Budget craft disproportionately to 0–3s. Put a real face or real motion there — never a logo fade.
148
+ - **Caption speech, always.** Most social video is watched sound-off, and captions lift retention and completion — treat them as mandatory, not decoration. Attach `captions` with word-level timing from `get_media_context`; set legibility via `setCaptionStyle` (`position` + `emphasisPlate`). Caption **speech** — do not karaoke a slideshow.
149
+ - **Length: earn it.** Engagement decays with length; short pieces complete far better than long. A sub-1-min teaser is watched to the end at rates a 5-min film never sees; instructional pieces are the exception *only* when they genuinely teach. Never pad — every second must carry the idea forward.
150
+ - **Cut cadence (motivated, never for its own sake):** a visual change every ~1.5–2s for sub-60s pieces; B-roll shots ~1.5–3s (>3s stalls); cinematic ~4–6s. For talking-head/demo the two operations differ: **reframe/punch-in every ~3–4s *within* a held speaker shot**, and insert a B-roll **cutaway every ~5–8s** of continuous talking. Drive with clip `trim`/`duration` and overlay entrance timing — but every change of state must be *motivated* (a reframe to the speaker, a lower-third entrance, a caption emphasis).
151
+ - **Word budget:** ~130–150 wpm; 60s ≈ ~130 words; a 12–15-word hook ≈ 5–6s of speech. Past ~160 wpm reads rushed.
152
+ - **Sound sets perceived pace.** CueFrame composes to an existing audio bed — use it: land caption entrances and cut points on stressed words / beats via the transcript's word timing (a cut on the beat reads as craft, off it reads as accident — synchresis, Chion); duck music under speech; hold one beat of silence before the payoff line. Silence before the peak is a tool, not an absence.
153
+ - **The saturated default.** Gradient-text-over-music synced to a beat is the *standard* software-launch look, not a differentiator. When you reach for that generic default instead of grounding the piece, you land in exactly that interchangeable tier — which is the whole reason step 3 exists.
154
+
155
+ ---
156
+
157
+ ## Format playbooks
158
+
159
+ Each playbook is a **floor**, not a template — reason above it. Every beat maps to a real CueFrame capability. Default to **16:9 landscape** for product/demo/explainer/founder-web; **9:16 vertical** only for social cutdowns (a wide source crammed vertical crops the subject wrong and wastes the frame).
160
+
161
+ ### 1 — Product launch / announcement
162
+ **When:** launching or announcing a product; teaser or full launch film.
163
+ **Beat sheet (45s, 16:9):**
164
+ | Beat | Time | Content | Words |
165
+ |---|---|---|---|
166
+ | Cold-open hook | 0–3s | One wow frame or the single pain moment. No logo. | ≤10 |
167
+ | Problem | 3–12s | The specific status-quo pain, shown not told. | ~20 |
168
+ | Reveal | 12–30s | The product doing the thing on REAL footage/screen. | ~35 |
169
+ | Proof | 30–40s | One concrete result or credible demo moment. | ~20 |
170
+ | CTA + date | 40–45s | Exact action + launch date. Logo last. | ≤12 |
171
+
172
+ **Frameworks:** 3-act teaser (Tease → Reveal → CTA) or StoryBrand SB7 (customer is hero, you are guide). One pain or one wow — not five diluted features.
173
+ **Reach for:** `import_media` a real demo capture or founder clip · `list_catalog` → the `product-launch-trailer` and `cinematic-title` scenes (use `cinematic-title` for the *closing* wordmark, never the open) · `color-grade` for the hero look · date + CTA on the final held frame.
174
+ **Anti-patterns:** opening on a logo animation; stacking five features; narrating specs; a fabricated/rounded stat; a mocked terminal standing in for a real screen.
175
+ **Quality bar:** the first frame survives with zero text on it. If your open is a gradient with the product name, you've already lost.
176
+
177
+ ### 2 — Short-form social clip (TikTok / Reels / Shorts)
178
+ **When:** a vertical clip for social, usually cut from existing long-form.
179
+ **Beat sheet (22s, 9:16):**
180
+ | Beat | Time | Content |
181
+ |---|---|---|
182
+ | Visual + verbal hook | 0–3s | Bold claim / question / pattern-interrupt, on screen AND spoken. Answer teased, not given. |
183
+ | Setup | 3–8s | Frame the stakes; open loop #1. |
184
+ | Escalation | 8–16s | Value in ≤2 beats, each opening the next loop. Cut every ~1.5–2s. |
185
+ | Payoff | 16–20s | Close the main loop; put the payoff word on screen. |
186
+ | CTA / loop-back | 20–22s | Soft CTA or a re-hook that rewards replay. |
187
+
188
+ **Frameworks:** Hook → Retention → Payoff with curiosity stacking. Keep cutdowns ≤30s — shorter clips complete far more often.
189
+ **Reach for:** `suggest_briefs` on the long-form media (the AI clip-finder authors trim + speaker framing + captions from the transcript for you), then `compose({ suggestionId })` (Director ensemble) or author yourself via `apply_composition` · reframe `focus: {mode:"active-speaker"}` to keep the speaker centered in the vertical crop · word-level captions with `emphasis` on the payoff word and `entrance:"word-pop"` · `derive_composition` to auto-reframe a 16:9 master to 9:16 content-aware (not letterboxed).
190
+ **Anti-patterns:** a wide source letterboxed into 9:16 with black bars instead of subject-tracked reframe; no captions (dies on mute); a hook that describes instead of provokes ("In this video I'll…").
191
+ **Quality bar:** the hook sentence starts at t ≤ 1.5s; the face box is a real fraction of the frame with the top of the head in-frame on every sampled still.
192
+
193
+ ### 3 — Explainer
194
+ **When:** explaining a concept, mechanism, or product so a viewer *gets* it.
195
+ **Beat sheet (75s, 16:9, ~160 words @ ~130 wpm):**
196
+ | Beat | Time | Words | Content |
197
+ |---|---|---|---|
198
+ | Hook | 0–5s | ~12–15 | The "why watch" — land inside 3s. |
199
+ | Problem | 5–20s | ~30 | Name the exact pain; they must feel understood. |
200
+ | Solution | 20–45s | ~55 | Your answer and how it differs. Show it working. |
201
+ | Proof | 45–62s | ~35 | One result / mechanism / credible demo. |
202
+ | CTA | 62–75s | ~20 | One clear next step. |
203
+
204
+ **Frameworks:** Hook → Problem → Solution → Proof → CTA. Decide the CTA first, script it last; write for the ear.
205
+ **A fully animated explainer is a FIRST-CLASS grounded format**, not a fallback for missing footage. A Manim explainer built on diagrams of the *actual* mechanism (its real pipeline, the real data) is grounded — the grounding is that each visual depicts THIS thing specifically, not a decorative loop. Reach for it deliberately, not as a consolation for "no footage."
206
+ **Reach for:** `generate_media` (prompt → `manim`) to anchor an abstract mechanism with a real diagram — *this is Manim's actual lane* (process/algorithm/data viz), not cinematic footage · `lower-third` for term labels · one idea per beat · when using real footage, narrate to the detected transcript timing.
207
+ **Anti-patterns:** a wall of narration over stock gradient loops with no visual keyed to the words (the generic-filler tell — a purposeful diagram of the real mechanism is the opposite); explaining features before establishing the problem; using `generate_media` text-to-video to fake a "product" that doesn't match the real UI (it hallucinates specifics).
208
+ **Quality bar:** every beat has a visual keyed to what's being said — grounded and specific to this content, not decoration; the hook lands in 3s.
209
+
210
+ ### 4 — SaaS / dev-tool demo
211
+ **When:** showing a product/CLI/app actually doing a real task.
212
+ **Beat sheet (~2 min, 16:9, real screen capture):**
213
+ | Beat | Time | Content |
214
+ |---|---|---|
215
+ | Hook + problem | 0–15s | The workflow that hurts today. Real UI or founder to-camera. |
216
+ | Setup | 15–30s | The task we'll accomplish; the promised outcome. |
217
+ | Walkthrough | 30–95s | Do the real thing on the real screen. Punch-in on the exact UI region per step; ~3–4s cadence; caption each action. |
218
+ | Outcome | 95–110s | Result achieved; the payoff vs the opening pain. |
219
+ | CTA | 110–120s | One action: start free / book / docs. |
220
+
221
+ **Frameworks:** Problem → Product-in-action → Outcome, wrapped in one completed task, not a feature tour. ~2 min is a good ceiling; chapter beyond that.
222
+ **Reach for:** `import_media` a REAL screen recording (captured by the user or Kishu — CueFrame does not screen-record) · reframe punch-in to the active UI element each step (`focus:{mode:"point",x,y}` on the click target, or a `face` focus for a founder inset) — the single biggest amateur→pro delta in demos, because the click target is ~30px in a 3840px 4K frame and nobody sees it unzoomed (**see `cueframe-product-video`** for the full click-point→reframe-segment auto-zoom tiling + PiP recipe) · a `lower-third` label per step.
223
+ **Anti-patterns:** the cardinal demo sin — a mocked/fake terminal or static UI card instead of the real app; showing the full 4K screen unzoomed; narrating every menu.
224
+ **Quality bar:** every UI/terminal on screen is a real capture; the actual action is visibly punched-in, not lost in a wide frame.
225
+
226
+ ### 5 — Founder / talking-head (CueFrame's home turf)
227
+ **When:** a real person speaking to camera — founder update, announcement, testimonial. The format CueFrame composes best, and the one the SIA agent walked past.
228
+ **Beat sheet (75s, 16:9 for web; 9:16 cutdown for social):**
229
+ | Beat | Time | Content |
230
+ |---|---|---|
231
+ | Attention / Problem | 0–5s | Founder states the pain or bold claim to camera. Eyes to lens. |
232
+ | Interest / Agitate | 5–25s | Why it matters now; personal stakes. B-roll cutaway. |
233
+ | Desire / Solution | 25–55s | What they built and the shift it creates. Product B-roll. |
234
+ | Proof | 55–68s | One credible result. Lower-third for name/title/metric. |
235
+ | Action | 68–75s | One CTA. |
236
+
237
+ **Frameworks:** PAS (Problem → Agitate → Solution) or AIDA. Framing: eyes on the upper-third line, small headroom, subject looks into the lens; break every ~5–8s of pure talking head with a cutaway.
238
+ **Reach for:** THE canonical CueFrame job. `get_media_context` for faces + transcript → reframe `focus:{mode:"active-speaker"}` for a solo speaker, `{mode:"all-faces"}` to hold a two-shot, or `{mode:"face",faceId,shotScale:"close"}` to punch in on emphasis → transcript-timed `captions` with a legibility plate (`setCaptionStyle` `emphasisPlate`, `position:"bottom"`) → a text overlay at `zPlane:"behind-subject"` when you want a title/word to sit *behind* the head (the signature look; render bakes the person matte) → a `lower-third` for name/title, shown once → `color-grade`. Zero generation needed.
239
+ **Anti-patterns:** a static wide talking head running 30s uncut (reads as a raw webcam upload); captions slapped over the chin with no plate; head dead-center or too much headroom; missing the lower-third identity.
240
+ **Quality bar:** a face is on screen within 3s; the person framed is the person speaking; captions never cover the mouth or eyes.
241
+
242
+ ---
243
+
244
+ ## Map craft to CueFrame tools (never invent a tool, primitive, or param)
245
+
246
+ | Craft goal | Do this in CueFrame |
247
+ |---|---|
248
+ | Bring in the real thing | `import_media` — requires `url` (public https) + `filename` + `contentType` (from the fixed enum: `video/mp4`, `video/quicktime`, `image/png`, `audio/mpeg`, …). Poll `list_media` or `create_webhook` on `media.completed` (status inside: complete|failed). |
249
+ | Know where subject + speech are | `get_media_context` → face boxes per frame (with `faceId`) + transcript |
250
+ | Keep the speaker framed / punch-in | `setCropIntents` op (the PREFERRED authoring path) or inline `reframe.segments` on a `clip.add` source. Each segment needs `startSec`/`endSec`/`focus`/`zoom`; **segments must TILE the clip** (an uncovered span → `reframe_coverage_gap` at validate). `focus.mode`: `frame-center` \| `point{x,y}` \| `face{faceId, shotScale?: close\|standard\|wide}` \| `all-faces` \| `active-speaker`. `zoom<1` punches in, `=1` full frame, `>1` rejected (min 0.1). Times in **seconds**. |
251
+ | Captions that track real speech | `composition.captions.segments[].words[]` = `{text, startMs, endMs, emphasis?, annotate?: circle\|underline}` — word times in **milliseconds**. Style via `setCaptionStyle`: `position` (top\|center\|bottom), `entrance` (fade\|word-pop\|stagger-up), `emphasisPlate` + plate colors for legibility. **Captions have NO `zPlane`.** |
252
+ | Text behind the speaker's head | An `overlay` clip (a title/label primitive) with `zPlane:"behind-subject"` — NOT the caption layer. Render bakes the person matte + handles occlusion. |
253
+ | Name someone / label a step | `lower-third` scene from `list_catalog` |
254
+ | Title / closing wordmark | `cinematic-title` scene (closing, not opening) |
255
+ | Grade the look | `color-grade` scene/effect |
256
+ | Anchor an abstract mechanism | `generate_media` prompt → `manim` (diagrams of the real mechanism — NOT cinematic; a first-class grounded path) |
257
+ | Long-form → clips | `suggest_briefs` → `wait_job(kind:"suggestions")` → `compose({ suggestionId })` |
258
+ | Auto-reframe to another aspect | `derive_composition` (content-aware 9:16 / 1:1 / 4:5 from a 16:9 master) |
259
+ | Discover what to build with | `list_catalog` — over MCP it takes **NO input params**, so the FULL catalog (87 primitives + 7 scenes) + your installed components returns, and you filter the RESULT **client-side** by `category`/`kind`/`tier`/`useCase`/`mood`/`intent`. Each entry carries `placement` (how to author it), `tier`/`useCase`, and `fixedCopy` (baked text no param changes). Read `cueframe://component/{id}` for the full **prop schema**. |
260
+ | Own / fork a custom graphic | `get_component_source` / `create_component` (self-contained tsxSource) / `update_component` — **see `cueframe-component-authoring`** for the full fork→preview→push loop |
261
+ | Seed + edit the timeline | `apply_composition` (atomic batch ops; `dry_run:true` to check, `if_match` for OCC) — this is where clips, reframe, captions, and format are authored |
262
+ | Set the brand | `create_brand_kit` (402-gated) → set `brandKitId` on the **project** (`create_project` / `update_project`). It lives on the project, NOT on a composition op — trying to set it elsewhere is silently dropped. |
263
+ | Shape-check (NOT quality) | `validate_composition` → `{ valid, errors[] }` (`unknown_primitive`, `invalid_primitive_params`, `clip_source_track_mismatch`, `reframe_coverage_gap`, …); does **not** check trim bounds or image-on-video-track (those fail at save/render) |
264
+ | Look at real pixels | `preview_frame` at timestamps → PNG stills → LOOK |
265
+ | Preview one graphic | `preview_component` (async motion clip: 202 + jobId → `wait_job(kind:"preview")`; compile errors land on the job's failed terminal with the author-fixable message) |
266
+ | Independent grade (steered, un-gameable) | `score_composition` (sessionless; `editorialIntent`=your vision, `brandContext`=brand facts) → four fixed criteria + composite + worst-first critique, on frames it samples itself |
267
+ | Director ensemble compose | `compose` — set EXACTLY ONE of `fromComposition:true` (author from the seeded composition) or `suggestionId` (clipping path) → `wait_job(kind:"compose")` |
268
+ | Final MP4 | `create_render` → `wait_job(kind:"render")` or `create_webhook` on `render.completed`; `retry_render` (transient only) / `cancel_render` |
269
+ | Orient before spending | `get_account` FIRST — plan, entitlements, per-call cost ceilings; metered calls (`create_render`, `compose`, `generate_media`, `create_brand_kit`) 402 `billing_required`; `generate_media` 402 over its USD ceiling |
270
+
271
+ Everything needs a `projectId` — `create_project` is step 0.
272
+
273
+ **Hard limits — respect them, don't fake around them.** No cinematic AI generation: `generate_media` is Manim + limited text-to-video/text-to-image/image-to-video; treat generated assets as *supporting graphics* (a diagram, a texture), never a fake-cinematic hero. No screen capture: that's Kishu (external). When the right move needs footage CueFrame can't generate, `import_media` real footage — do not synthesize a substitute. **Units trap:** `startTime`/`duration`/`trim`/reframe `startSec`/`endSec`/`ease` are **seconds**; caption word times are **milliseconds**. **Render-time fail-loud errors to expect** (render never ships a wrong frame silently): `content_anchor` (a clip's `trim` frames *different* footage than its captions show — align the trim to the captioned moment), `behind_split_unsupported` (one media used under two *different* behind-subject windows — one behind-subject window per MEDIA; to render two different behind windows of one source, import it as two separate MEDIA ITEMS (distinct mediaIds) — duplicating the same mediaId into two clips still throws), `BehindMatteUnresolved`/`TrajectoryUnresolved` (the behind/face bake found no detectable person — drop the intent or fix the source).
274
+
275
+ **Worked alignment example (the error-prone mechanic).** You want the caption emphasis to land on the founder's stressed word "faster," and the frame to punch in on the same beat. From `get_media_context`, the transcript word "faster" runs `startMs:8120, endMs:8560` (transcript/source time). **For these round numbers, assume an untrimmed clip placed at timeline 0** — then source time, timeline time, and clip-relative time all coincide. So: put that word in `captions.segments[].words[]` with `emphasis:true` at `startMs:8120`; and author reframe with `setCropIntents` as a **contiguous segment list that tiles the whole clip** — e.g. a wide segment `{startSec:0, endSec:8.12, focus:{mode:"active-speaker"}, zoom:1}` then the punch `{startSec:8.12, endSec:<clipEnd>, focus:{mode:"face",faceId:"…",shotScale:"close"}, zoom:0.8, ease:{in:0.4,out:0}}` (ms → s: 8120ms = 8.12s). A lone mid-clip segment that leaves `[0..8.12]` uncovered fails validation with `reframe_coverage_gap`.
276
+
277
+ **Watch the timebase: reframe segment times are CLIP-RELATIVE; caption/transcript times are TIMELINE-based — convert when the clip is trimmed or not at t=0.** They coincide only for an untrimmed clip placed at timeline 0 (the case above). For a clip trimmed to start at source `trim.start` and sitting at `clip.startTime` on the timeline, the reframe boundary is `startSec = transcriptSec − trim.start`, and the caption time is `clip.startTime + (transcriptSec − trim.start)`. (The simple case just has `trim.start = 0` and `clip.startTime = 0`, so both reduce to `transcriptSec`.) Land the caption entrance *on* the stressed word, not a round frame like 8.0s — on-beat reads as craft. And if the clip's `trim` window doesn't actually contain source-second 8.12, the captioned word shows different footage → `content_anchor` at render.
278
+
279
+ ---
280
+
281
+ ## Craft principles (reason FROM these — the rules above are their consequences)
282
+
283
+ - **Curiosity is an information gap** (Loewenstein, 1994). A slide that *states* a fact satiates before it primes; a cold open that *poses* ("…and that's the number that made us kill the old pipeline") opens a gap the viewer must watch to close. Order clips to pose, not answer. Never lead with a definitional title card.
284
+ - **Emotion outweighs everything** (Murch's Rule of Six: emotion ~51%, then story, rhythm, eye-trace, planarity, spatial continuity). The slop instinct optimizes the bottom of the list — aligned text, smooth easing — while ignoring the top. When choosing where to cut, ask "does this land the emotion / advance the point?" first, "is it geometrically neat?" last.
285
+ - **Attention habituates; pattern interrupts reset it** (orienting response). Constant motion is itself a flat pattern the brain adapts to. Plan a *motivated* change of state every few seconds; vary shot scale between clips.
286
+ - **Sound is half the picture** (Chion, *Audio-Vision*; synchresis). Cut on stressed words / beats via transcript word-timing; hold a silence beat before the peak line. On-beat reads as craft, off-beat as accident.
287
+ - **Story is a value-shift** (McKee). Even a 30s piece must move from pain (real) → product (real) → win. A launch with no reversal is a list, not a story. (Ira Glass's storytelling model says it well another way: build a *sequence of raised-and-answered questions* — which is exactly "pose, don't answer.")
288
+ - **Premium = legible intent, not polish.** Audiences forgive imperfect video with a point of view; they don't forgive adequate video with no soul. Restraint, typographic discipline, and one consistent color/type/motion system across the whole piece are the premium signal. If you can't say *why* something moves, it shouldn't.
289
+
290
+ ### Deconstructed grammars (steal the structure, map to the tools)
291
+ These are *archetypes*, not documented cuts of specific films — reason from the grammar, don't cargo-cult a company.
292
+
293
+ - **The hardware-reveal grammar → "the product is the opening shot."** Open on black; the product materializes — no logo splash, no title card. One capability per shot. Numbers rationed, each on its own held frame. Negative space around one object = confidence. *CueFrame:* `import_media` real product footage → `preview_frame` the opening frame and ask "would this survive with zero text?" · `cinematic-title` for the *closing* wordmark only · `color-grade` for the hero look.
294
+ - **The founder-to-camera grammar → CueFrame's home field (the shape the SIA agent walked past).** Founder, medium shot, direct address: "Hey, I want to show you something." No sting, just a face and eye contact. Screen-share woven in as real capture under the continuing VO. Captions burned in, plated. Lower-third names the founder once. Imperfect on purpose — that's the credibility. *CueFrame:* `get_media_context` → `active-speaker`/`all-faces` reframe → transcript-timed captions with an `emphasisPlate` → a `zPlane:"behind-subject"` title → `lower-third` → `color-grade`. Zero generation.
295
+ - **The dark-kinetic-product grammar → "a gradient is a stage, not a subject."** Hard cut in on the UI in motion. Feature montage ~2–4s each, every beat a *real* UI interaction, cut on the music. The UI floats on a near-black stage with a subtle gradient — but the gradient is the *stage*; the real UI is always on top. One hero feature gets 8–10s to breathe. *CueFrame:* `import_media` UI captures → tight per-clip `trim`, cut on beat via clip durations → a dark `color-grade` + a `backgrounds` primitive as the *stage*, real footage on top. `preview_frame` a mid-montage frame: if there's no product on it, it's slop.
296
+
297
+ *The compressed lessons:* the product/human is the opening shot, not a title card · a real screen recording beats a beautiful fake · a gradient is a stage, not a subject · open on your single most satisfying real moment in the first 5s · founder-to-camera + real footage is home field · a purposeful diagram of the real mechanism is grounded too · show one task completed end-to-end, not a feature grid.
298
+
299
+ ---
300
+
301
+ ## The rubric template (write your video-specific version BEFORE rendering)
302
+
303
+ ```
304
+ VISION (one line): the ONE controlling idea for THIS video — a value + a cause.
305
+ FORMAT: [product-launch | social-clip | explainer | demo | talking-head]
306
+ SOURCE REALITY CHECK: what GROUNDS this video (after HUNTING for footage — 3a)? Real
307
+ footage, real UI/data, or a purposeful content-specific graphic (e.g. a Manim diagram
308
+ of the actual mechanism). If the only plan is generic filler, the 3b stop fired and
309
+ the user has explicitly said "proceed."
310
+
311
+ MUST-HAVES (each scoreable YES/NO on a NAMED frame, or 0–10):
312
+ H1. [t=…] …
313
+ ... (5–8 lines; anchor every one to a timestamp a PNG can answer)
314
+
315
+ KILL CRITERIA (any TRUE on any sampled frame = FAIL, regardless of score):
316
+ K1. [MANDATORY — preserve the meaning] Any sampled frame is a gradient/solid background with only
317
+ text and NO grounded subject — no real footage, no real UI/data, no purposeful
318
+ content-specific graphic, just decorative filler.
319
+ K2. [MANDATORY — preserve the meaning] Any on-screen number you cannot trace to a written
320
+ source, or any faked/mocked UI standing in for a real capture.
321
+ K3. [MANDATORY — preserve the meaning] Generic/decorative filler dominates the runtime — grounded,
322
+ specific content (real footage, real UI/data, or purposeful content-specific
323
+ graphics) does not.
324
+ K4+. … (add your own; encode this video's specific slop modes as disqualifiers)
325
+
326
+ PROVENANCE: for every on-screen number, write the source next to it here
327
+ (e.g. "12.4% — Table 3, arXiv:xxxx"). No written source → it does not go on screen.
328
+
329
+ PER-BEAT CHECKS: B1 (0:00–0:0X) … B2 … (each beat exists and lands, with a duration)
330
+
331
+ MEASURABLE THRESHOLDS:
332
+ T1. First grounded frame (real footage / real UI/data / purposeful graphic) at t ≤ __s.
333
+ T2. Grounded, content-specific visuals (real footage, real UI/data, or a visual of the
334
+ real mechanism/data) ≥ 60% of runtime; a beat whose only visual is animated text
335
+ over a background counts as filler, not grounded. (Footage-based formats: real
336
+ footage ≥ 60%.)
337
+ T3. ≤ __ on-screen stats, each held ≥ __s, each source-traceable.
338
+ T4. No single frame > __% empty decorative background.
339
+ T5. Caption legible (contrast/size, plate) on named frames.
340
+ T6. Cut/beat count in range __–__ (not a static hold, not a strobe).
341
+
342
+ SCORING: (a) your own frame-by-frame descriptions pass every MUST-HAVE with ZERO kill
343
+ criteria; AND (b) score_composition (editorialIntent = the VISION line;
344
+ brandContext = brand facts) composite ≥ 7.5/10 on its OWN sampled frames
345
+ (never set your bar below 7.5). Sample frames at [list incl t=0]. Budget 3–5 passes.
346
+ ```
347
+
348
+ ### Filled example — product launch (the anti-SIA rubric)
349
+ ```
350
+ VISION: "Two founders who clearly believe in SIA tell you, to your face, why it's
351
+ faster — and you watch it BE faster."
352
+ FORMAT: talking-head + real demo (NOT slides).
353
+ SOURCE REALITY CHECK: HUNT (3a) → Hexo's real launch = two founders to camera → import
354
+ it. If no footage: a real capture of SIA running, or a first-class Manim diagram of
355
+ SIA's actual pipeline (grounded, not a consolation) — NOT a gradient deck. Generic
356
+ filler = fail.
357
+
358
+ MUST-HAVES:
359
+ H1. [t=0–3s] A human FACE on screen within 3s (subject present, headroom).
360
+ H2. [t=0–3s] NO title card / logo splash before the face.
361
+ H3. [any speaking frame] The person framed is the person talking (reframe to
362
+ get_media_context faces; all-faces on the two-shot, active-speaker on singles).
363
+ H4. [speaking frames] Legible transcript captions, plated, never over the face.
364
+ H5. [one frame] Founder name in a lower-third, shown once, spelled correctly.
365
+ H6. [demo beat] Real SIA running (captured pixels), not a re-created UI card.
366
+ H7. [stat beat] Any number matches the source exactly (paper says 12.4% → the frame
367
+ says 12.4%, not 14x).
368
+ H8. [final] Wordmark + one line lands LAST, held ≥1.5s.
369
+
370
+ KILL CRITERIA:
371
+ K1. [mandatory] Gradient/solid + only text, no grounded subject (no real footage,
372
+ real UI/data, or purposeful content-specific graphic).
373
+ K2. [mandatory] Untraceable number (e.g. "14x") or a fake/static terminal.
374
+ K3. [mandatory] Generic/decorative filler dominates; grounded content does not.
375
+ K4. On >2 consecutive sampled beats, the frame's largest element is text on a
376
+ flat/gradient field with no grounded subject behind or beside it.
377
+
378
+ PROVENANCE: "12.4%" — Table 3 of the SIA paper. (No other on-screen numbers.)
379
+
380
+ PER-BEAT: B1(0:00–0:05) cold open on founder, direct address, caption running ·
381
+ B2(0:05–0:20) the "why," problem in one sentence, on the face · B3(0:20–0:35) real
382
+ SIA demo, the one satisfying moment, captioned · B4(0:35–0:45) the honest 12.4% on a
383
+ clean held frame · B5(0:45–0:50) face again + CTA + wordmark.
384
+
385
+ THRESHOLDS: T1 first grounded frame ≤ 3s · T2 real footage ≥ 60% of runtime · T3 ≤ 2
386
+ stats, each held ≥ 1.5s, source-traceable · T4 no frame > 30% empty background ·
387
+ T5 caption plate legible on B1,B3 · T6 ≥ 1 active-speaker/all-faces reframe.
388
+
389
+ SCORING: own descriptions pass H1–H8, zero kills; score_composition (editorialIntent
390
+ = VISION) composite ≥ 7.5/10 on its sampled frames. Sample at 0,3,10,20,35,45s.
391
+ Budget 3–5 passes.
392
+ ```
393
+
394
+ ### Filled example (compact) — social clip (9:16 from long-form)
395
+ ```
396
+ VISION: "In 20s, one surprising claim from the talk makes you stop scrolling."
397
+ FORMAT: social-clip (9:16, sound-off).
398
+ SOURCE: a real talking-head/podcast clip (the whole point of the clipping path).
399
+ MUST-HAVES: H1[0–1.5s] the single most surprising sentence is the FIRST thing said
400
+ (align to transcript) · H2[every frame] face in the vertical safe area, top of head
401
+ in-frame · H3[speaking] word-level animated captions, high-contrast, plated · H4
402
+ captions never cover mouth/eyes · H5[last 2s] soft loop or one-line handle.
403
+ KILL: K1[mandatory] gradient+text, no grounded subject · K2[mandatory] untraceable
404
+ number/fake UI · K3[mandatory] generic filler dominates, grounded content doesn't ·
405
+ K4 face cropped at forehead/chin OR vertical frame mostly empty · K5 opens on filler
406
+ ("um, so…") not the hook.
407
+ THRESHOLDS: 15–30s · hook ≤ 1.5s · caption height ≥ ~6% of frame · face box ≥ 25% of
408
+ frame area · real footage ≥ 60% · nothing critical in bottom ~12% or top ~10%.
409
+ SCORING: own descriptions pass, zero kills; score_composition (editorialIntent =
410
+ VISION) composite ≥ 7.5/10 on its sampled frames. Sample 0,1.5,5,10,18s. Budget 3–5 passes.
411
+ ```
412
+
413
+ Every line names a frame and asks a question a PNG can answer — is a grounded subject present, is text legible, is the background mostly empty decoration, does the number match its written source, is the hook first. None require reading the composition JSON. The kill criteria *are* the enforcement: K1–K3 encode the SIA failure modes as automatic disqualifiers a render can't be rationalized past.
414
+
415
+ ---
416
+
417
+ ## Red flags — stop and fix if any is true
418
+
419
+ - **You concluded "no footage" without hunting** → run step 3a (user-attached? subject's existing footage? ask). The SIA agent's whole failure was skipping this — footage is the strongest grounding.
420
+ - **Generic/decorative filler dominates the runtime** → grounded, specific content (real footage, real UI/data, or a purposeful content-specific graphic) doesn't. K3 trips. (For footage-based formats, real footage under ~60% is the usual symptom.)
421
+ - **An on-screen number the user didn't give you** → you fabricated it. CueFrame renders your number faithfully, so a wrong one is on you — write every stat's source in the rubric; no written source → it doesn't go on screen.
422
+ - **A terminal/UI that's a styled component, not a real capture** → it's a mock. Import the real capture or drop it.
423
+ - **A gradient/aurora you're calling "purposeful"** → it isn't. Purposeful means specific to THIS content (the real mechanism, the real data). A decorative gradient is always the slop default, never grounding.
424
+ - **You rendered before writing the rubric** → stop, write the rubric (step 2), then look at pixels.
425
+ - **You scored without describing the pixels** → you didn't look. Write one line of what's visible per still, then score.
426
+ - **You're the sole judge** → run `score_composition` (editorialIntent = vision); it samples its own frames — treat a low score on a frame you didn't pick as ground truth.
427
+
428
+ ---
429
+
430
+ ## Pre-render checklist (before `create_render`)
431
+
432
+ 0. `create_project` done; `get_account` shows the render/compose/generate calls are within plan entitlements and cost ceilings.
433
+ 1. Vision written as one sentence (value + cause); format chosen.
434
+ 2. Footage HUNTED (3a); if the plan is generic filler, the 3b tradeoff stated to the user and an explicit "proceed" received (a purposeful, specific graphic — e.g. a Manim diagram of the real mechanism — does NOT require the stop).
435
+ 3. Rubric written *before* any render — named-frame must-haves, measurable thresholds (grounded content dominates the runtime; footage-based formats real-footage ≥60%), the mandatory K1–K3 (meaning preserved, phrasing adapted to your video), and written provenance for every number.
436
+ 4. Real source imported (`list_media` shows it ready); `get_media_context` faces + transcript pulled and used for reframe + caption timing (when the piece uses footage).
437
+ 5. Components discovered via `list_catalog` (no hand-placed hex where a built-in exists); `fixedCopy` checked so no baked text lies. Brand set via `brandKitId` on the project if a brand kit exists.
438
+ 6. `validate_composition` is `{ valid: [] }` — shape sound, no `reframe_coverage_gap` (shape ≠ quality).
439
+ 7. `preview_frame` stills taken at every rubric timestamp incl t=0, each **described in words** then scored against the rubric.
440
+ 8. `score_composition` run with `editorialIntent`=vision, `brandContext`=brand; worst-first critique addressed; composite ≥ 7.5 on its own sampled frames.
441
+ 9. Every kill criterion false on every sampled frame; every on-screen number traces to its written source and matches it.
442
+ 10. Verify passes budgeted (3–5) and the rubric genuinely passes — then `create_render` → `wait_job(kind:"render")`.
@@ -35,7 +35,7 @@ extract brand (repo + live UI) → create_brand_kit
35
35
  → capture (Kishu: Playwright walkthrough of localhost → MP4) → import_media
36
36
  → get_media_context (faces + transcript)
37
37
  → apply_composition (edit plan + brand template, refs brandKitId + $brand:)
38
- → create_composition { fromComposition:true } → wait_job kind:compose
38
+ → compose { fromComposition:true } → wait_job kind:compose
39
39
  → create_render → wait_job kind:render → branded MP4
40
40
  ```
41
41
 
@@ -95,7 +95,7 @@ matter, click the features worth showing, pause on results.
95
95
 
96
96
  Get the recording into CueFrame with `import_media` (public https URL) — it's
97
97
  async; poll `list_media` for `processingStatus:"ready"` (or register
98
- `create_webhook` on `media.ready`). Keep the click points; you'll map them onto
98
+ `create_webhook` on `media.completed`). Keep the click points; you'll map them onto
99
99
  the rendered duration for the zoom.
100
100
 
101
101
  ## 3. Context → `get_media_context`
@@ -207,19 +207,19 @@ durations are illustrative — match your source.
207
207
  }
208
208
  ```
209
209
 
210
- ## 5. Refine + judge → `create_composition { fromComposition: true }`
210
+ ## 5. Refine + judge → `compose { fromComposition: true }`
211
211
 
212
- Hand the seed to the Director: `create_composition` with `{ fromComposition: true }`
212
+ Hand the seed to the Director: `compose` with `{ fromComposition: true }`
213
213
  authors an ensemble of candidates from your seed, runs the **server-side judge —
214
214
  including the brand axis** (on-brand color/type/voice cohesion), and saves the
215
215
  winner. Returns a `composeJobId`; `wait_job` `kind:"compose"` (or a webhook on
216
- `compose.complete`). The result carries the winner's composite score — verification
216
+ `compose.completed`). The result carries the winner's composite score — verification
217
217
  is built in. Pass your brief as `editorialIntent` so editorial is graded against
218
218
  what you meant. (To self-drive the loop instead, see `cueframe-compose-loop`.)
219
219
 
220
220
  ## 6. Render → branded MP4
221
221
 
222
- `create_render` → `wait_job` `kind:"render"` (or a webhook on `render.complete`)
222
+ `create_render` → `wait_job` `kind:"render"` (or a webhook on `render.completed`)
223
223
  for the download URL. The output is brand-frozen: the kit's **intro/outro** bumper
224
224
  the video, the **logo** bug sits in its corner, **motion** drives the overlay
225
225
  entrances, and every `$brand:` color/font is resolved. Verify the output (sample
@@ -27,9 +27,9 @@ Single self-contained module per component (`create_component` takes one `tsxSou
27
27
  ids from the catalog (`/v1/components`). *(Or author from scratch — skip to step 2.)*
28
28
  2. **Author/own it:** edit the `tsxSource`, then `create_component({ componentId, tsxSource, … })`
29
29
  to store your customized copy (origin `server-native`; if forked, `ejectedFrom` is stamped).
30
- 3. **Iterate (author→preview→fix):** `open_session` → `preview_component({ componentId, params })`
30
+ 3. **Iterate (author→preview→fix):** `preview_component({ componentId, params })` (sessionless — a cold first call returns 409 box_warming; retry in a few seconds)
31
31
  renders ONE still. A 422 `component_does_not_compile` returns the compiler error — read it, fix
32
- via `update_component` (same id, in place), preview again. `close_session` when done.
32
+ via `update_component` (same id, in place), preview again.
33
33
  4. **Render:** add it to a composition as an `alpha-layer` clip (`apply_composition`), then
34
34
  `create_render` → `wait_job kind:"render"` for the MP4.
35
35
 
@@ -57,7 +57,7 @@ MCP path stores. To preview before a full render, push it and use the MCP `previ
57
57
  The catalog (`/v1/components`) gives each primitive's `description` / `useWhen` / `tags` / `mood` /
58
58
  `tier` / `useCase` / `examples` (example params) + `propSchema` + its source via `get_component_source`.
59
59
  Read the spec + the code to pick a starting point. (Rendered preview thumbnails are a separate
60
- follow-up — today you choose from prose + params + source, or compose+`render_frame` to see it.)
60
+ follow-up — today you choose from prose + params + source, or compose+`preview_frame` to see it.)
61
61
 
62
62
  ## Don't
63
63
  - Don't expect a forked primitive to use rich named props — it's adapted to `({durationInFrames,