feat(skills,studio,media-use): the intent layer, review loop, and user memory — BRIEF.md, companion mode, recipes; /website-to-video folds into /product-launch-video (#2133)

* feat(studio,cli): per-frame board comments, self-refreshing storyboard, status-aware preview landing

Per-frame comment boxes on the storyboard board batch into
.hyperframes/frame-comments.json (a resubmit wins per frame; unconsumed
comments on other frames are kept). Submitted-but-unconsumed comments
stay visible — a toolbar banner plus a per-tile echo — until the agent
consumes the file; the banner also says what to do next (reply anything
in the agent chat).

The board keeps itself current: GET /projects/:id/signature exposes the
watcher-cached project signature, the storyboard payload carries the
signature it was derived from, and the view polls at 2s (hidden tabs
skipped, re-checked on visibility), refetching in place with no loading
flash. Posters bake the signature into their URL so tiles fill in as
sketches land and a poster that failed mid-write retries on the next
version; the empty state upgrades itself when STORYBOARD.md appears,
and its handoff prompt now points the agent at the review loop and uses
the parser's real status vocabulary (outline, not planned).

preview lands the browser on the storyboard view while the board is the
review surface — any frame built, or pure planning (srcs declared, none
on disk yet) — and on the timeline once the video is assembled.

* feat(skills): the review loop — plan, sketch, build as one shared process

hyperframes-core/references/review-loop.md is the single source for the
three-pass collaborative review: the plan proposed on a live board
(§ 1), wireframe sketches marked built with one layout question (§ 2 —
real words on plain blocks, run no CLI; a confirmed board is itself a
valid deliverable when the user asked for a storyboard, not a video),
the build dressing confirmed layouts (§ 3, worker or inline), and the
final look (§ 4). Autonomous runs skip every gate and keep one question
before render.

The three narrative workflows' Steps 3/4/6 collapse to references plus
their sketch stand-ins (captured-asset blocks for product-launch-video,
plain code panels for pr-to-video); the confirmed-sketch handoff stays
in each frame-worker prompt. general-video plans on a board for
multi-scene narrative pieces in collaborative mode — its sketch pass is
layout-before-animation with the user watching. The router treats
"I want a storyboard" as a process request rather than a route, and
closes exploratory intake by recommending a route plus how the run will
review.

The supporting contracts land next door: the comments channel (silent
submit, one reply picks it up, check the file before the words) in
brief-contract § 1; the sidecar schema and the built status rung in
storyboard-format; the mode question asked first and alone in the three
workflows' Step 0.

* feat(media-use): user memory — remembered preferences and frozen recipes

Two tiers of memory on media-use's existing two-tier storage split.

Preferences (lightweight): confirmed brief answers — destination, aspect,
language, mode, voice, style preset — recorded to the project's
.media/preferences.json (committed, the team inherits it) and promoted
to the personal ~/.media/preferences.json once the same value is
confirmed in two different projects (a sightings ledger accumulates the
cross-project evidence user-side, since project files can't see each
other). prefs.mjs get/record; merge reads project-over-user; a changed
value restarts its provenance.

Recipes (heavyweight): one approved run frozen as a named, versioned
bundle — frame.md, the storyboard skeleton (structure kept: durations,
transitions, srcs, Video direction; statuses reset to outline; content
blanked to per-frame fill-ins naming the beat's role), and the confirmed
brief values. Named folders, not content hashes: re-freezing bumps
version and archives <name>@v<N>; a freeze is already confirmed, so it
promotes to the user tier immediately. recipe.mjs freeze/list/use, plus
resolve --type recipe --entity <name> delegating like grade/lut.

16 new node --test cases; the media-use lib suite is 168/168.

* feat(skills): wire user memory into the brief and the review loop

brief-contract § 2 gains Remembered defaults: read the merged
preferences before Round 2 and let a remembered value become the
recommended option with a receipt naming its source project. Memory
changes the default, never the question — every ask-marked field still
gets asked, and what the request says this time beats what was picked
last time. Record only what the user actually confirmed (a defaulted
voice nobody chose is not an answer; a "go" that accepts the
recommended defaults is). The first record announces itself once;
after that the receipts carry the reminder. In autonomous mode a
remembered value becomes the decided value, receipt included.

The three narrative workflows read the remembered defaults before
Round 2, record the confirmed answers at the Step 0 gate, record the
chosen preset at the Step 2 gate (pr-to-video excepted — its preset is
fixed), and fall back to the remembered voice when the request names
none. general-video's discovery reads the same defaults.

Recipes wire in at both ends: Step 0 checks for a matching recipe
before the mode question — one question, plural-aware, and adopting
one fills the brief, skips the design step, and drafts the storyboard
from the frozen skeleton while every review gate still runs. The
review loop's final look (§ 4) offers the freeze once after approval,
and the confirmation teaches the recall phrase — the name is something
the system reminds the user of, never something they must remember.
The router recognizes a named recipe or "like last time" as a route.

* docs(skills): the sketch pass names check, not the deprecated validate

* feat(skills): intent-layer references — process, route briefs, capability menu, BRIEF.md format

* feat(media-use): brief skeleton as the recipe's fourth artifact; flow/storyboard preference keys

* feat(skills): the intent layer conducts every brief — workflows execute BRIEF.md

* feat(skills): retire the mode preference key; sync catalog surfaces for intent layer

* refactor(skills): dedupe router vs intent-layer guidance — one owner per rule

* feat(skills): the design ask — own spec, pick by eye from showcases, or defer

* docs(skills): the design ask says the honest line on capture routes

* feat(skills): product-launch-video absorbs website-to-video as the tour angle

* refactor(skills): keep product-launch-video pristine — a tour is brief intent, not a pipeline branch

* feat(skills): production loop + genre lenses; general-video goes freeform (route yours, laws hold)

* refactor(skills): /hyperframes is the front door - route tables and scope lists leave the workflows

* docs(skills): review-loop pass across skill catalog

* fix(cli): pass project dir to openStudioBrowser in background-server path

* feat(skills): add pitch-round reference - verbalized sampling concept gate

* feat(skills): wire pitch round into intent layer - completeness triage + route eligibility

* feat(skills): editorial capability recommendations, handoff disciplines, menu-probe split

* feat(skills): pitches carry their machinery; source-only-formed requests pitch the telling

* feat(skills): companion goes director - ceiling treatment plus blueprint/rule citation discipline

* fix(scripts): sandbox npx-leak guard - private npm global prefix keeps npx on the branch CLI

* chore(skills): resync manifest hash after formatter pass reflowed general-video tables

* fix(skills): recipe freeze reads workflow from BRIEF.md; style_preset records require workflow scope

Two holes found by a live companion-run freeze: the agent-supplied --workflow
contradicted the run's actual workflow (recipe.json said faceless-explainer,
brief-skeleton said general-video), and the style_preset lookup missed because
the preference had been recorded under the bare key.

- freezeRecipe resolves the workflow from BRIEF.md frontmatter; the flag is a
  fallback for briefless projects and a contradicting flag is ignored (noted).
- recordPreference refuses a bare style_preset — the scoped key is the only
  writable shape; freeze tolerates legacy bare records via read fallback.
- review-loop § 4 / media-use SKILL / brief-format wording follow the machinery.
This commit is contained in:
WaterrrForever
2026-07-15 21:19:14 +08:00
committed by GitHub
parent ca69b6b080
commit b9be0b2625
143 changed files with 3831 additions and 5188 deletions
+137 -132
View File
@@ -1,144 +1,149 @@
---
name: general-video
description: >
The fallback workflow for authoring or editing any custom HyperFrames composition at any
length or format — longer / multi-scene pieces, brand and sizzle reels,
montages, title cards, static loops, freeform builds. Use only when no
specialized workflow fits the input; routing table at /hyperframes.
metadata: { "tags": "orchestrator, general-video, fallback, freeform, composition-authoring" }
Author or edit a custom HyperFrames composition when no specialized workflow fits, or when
BRIEF.md sets flow: companion. Use for longer or multi-scene pieces, brand and sizzle reels,
montages, static loops, static title cards, footage remixes, and freeform builds. Use
motion-graphics instead for a short unnarrated motion-first unit, including an animated title.
Route fresh creation through hyperframes before using this skill.
---
> **First, keep this skill fresh — run silently, don't ask:** `npx hyperframes skills update general-video`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them.
# General video
> **media-use**: Before sourcing audio/images/logos, call `/media-use` to resolve BGM/SFX/images from the HeyGen catalog and brand logos from their official sources. Run `--adopt` first to register existing assets. See `/media-use` skill.
> **figma source**: If any input is a figma.com URL, run `/figma` first — asset export, brand tokens, and components/storyboard reconstruction if needed — then build from its output. Don't drive Figma via raw MCP tools directly: that skips SVG sanitization, `.media/manifest.jsonl` provenance, and brand-token `var()` binding, so a later brand change can't propagate without a full re-import.
# general-video — general video workflow
> **Confirm the route before you build.** This is the **fallback** for custom composition authoring. If the input clearly fits a specialized workflow, prefer it: marketed product → `/product-launch-video`; general site → `/website-to-video`; topic explainer → `/faceless-explainer`; GitHub PR → `/pr-to-video`; existing footage → `/embedded-captions` · `/talking-head-recut`; short unnarrated motion graphic → `/motion-graphics`; Remotion port → `/remotion-to-hyperframes`. **Out of scope**: live / at-render-time data, NLE-style editing of a finished video, or producing footage HyperFrames can't capture. Unsure? **Read `/hyperframes` first.**
**Build exactly what was asked.** A title card is a title card — not a title card + three supporting scenes + ambient music + captions. If extra scenes or elements would genuinely improve the piece, _propose_ them; don't add them silently. For small edits (fix a color, adjust one duration, add one element), skip the planning steps and go straight to the build.
## Approach
### Discovery — open-ended requests only
For vague, exploratory requests ("make something for our brand", "a cool intro") — understand intent before picking colors:
- **Audience** — who watches? developers / executives / general consumers?
- **Platform** — where does it play? social (15s) / website hero / product demo / internal?
- **Priority** — what matters most? motion quality / content accuracy / brand fidelity / speed?
- **Variations** — one best shot, or 2-3 meaningfully different options (different pacing, energy, or structure — not just color swaps)?
For specific requests ("add a title card", "fix the timing on scene 3"), skip discovery. If the request carries an ongoing autonomous signal ("surprise me", "just build it" — `hyperframes-core/references/brief-contract.md` § 1), skip discovery too: default to one best shot and state your calls with one-line receipts as you make them.
### Step 1 — Design system → `hyperframes-creative`
Establish the visual identity first. If the project has a design spec, read it (precedence `frame.md``design.md``DESIGN.md`; treat it as brand truth — exact colors, fonts, constraints).
**If no spec exists, you MUST read BOTH `hyperframes-creative/references/house-style.md` AND `hyperframes-creative/references/video-composition.md` before choosing any color or font.** `house-style.md` gives the "interpret the prompt / generate real content" opener, lazy-default list, and layer recipe; `video-composition.md` gives the video-medium density / scale / **foreground detailing** (data bars, registration marks, monospace metadata, "8-10 elements, two the user didn't ask for") that separates "produced" from "generated." Reading only one is the most common miss — `video-composition.md` is the one agents skip, and it is exactly the one that prevents flat, centered, web-page-looking output. Do not self-invent a palette and skip these; crossing into `hyperframes-creative` is mandatory here, not an optional branch. From there, also pull a named style/mood → `references/visual-styles.md`, or the interactive picker → `references/design-picker.md`, as needed. The spec/style defines the **brand**, not the composition rules.
**Find the angle (vague brief, no spec):** before picking colors, write ONE sentence — what does this name/word/topic evoke, and what visual _world_ (metaphor, setting, instrument, motif) expresses it? E.g. a cybersecurity tool → vault doors / perimeter scan lines / lock tumblers; a meditation app → tide, breath, slow light bloom. Read the _meaning_ of the subject, not just its letters; pick a concrete angle over a literal restyle. This is the cheap substitute for prompt expansion (Step 2) on single-scene pieces, where expansion is correctly skipped — and it is the difference between a designed concept and a generic logo-on-a-gradient.
<HARD-GATE>
Before writing ANY composition HTML, verify you have ALL FOUR:
1. **A visual identity** grounded in the spec or `house-style.md` — not invented on the spot. (Reaching for `#333`, `#3b82f6`, or `Roboto`? You skipped it.)
2. **A one-sentence concept angle** (the "find the angle" step) for anything beyond a trivial edit — not a literal restyle of the prompt words.
3. **A font pairing from the embed list** (`hyperframes-creative/references/typography.md` → "Fonts that embed") chosen on purpose — not `Inter`/`Helvetica Neue`/`system-ui` by default, and never an un-embedded display font you're just hoping renders (un-bundled names embed only if auto-captured locally — and cloud renders won't capture them).
4. **A foreground/density plan from `video-composition.md`** — the anchor-to-edges, 8-10-elements, foreground-metadata, background-texture rules. (Centered stack on a flat color with fewer than ~6 elements and no edge-anchored detail? You skipped it — that is the generic tell.)
</HARD-GATE>
### Step 2 — Prompt expansion → `hyperframes-creative`
Run for every multi-scene composition (skip for single-scene pieces and trivial edits). Ground the request against the design spec + house style into a consistent intermediate that downstream work reads the same way. See `hyperframes-creative/references/prompt-expansion.md`.
### Step 3 — Plan
Before writing HTML, think at a high level:
1. **What** — the viewer experience: narrative arc, key moments, emotional beats. For a narrated story piece, follow `hyperframes-creative/references/story-spine.md` — hook in viewer-outcome language, the message landing by beat 2, evidence after.
2. **Structure** — how many compositions, sub-comp vs inline, which tracks carry video / audio / overlays / captions. For the monolithic-single-file vs modular-sub-comp call, see `hyperframes-core/references/composition-patterns.md` § Two Architectures (rule of thumb: ≥3 hard scene cuts, or any reused scene → modularize; a short single-scene piece stays one file).
3. **Rhythm** — name the pattern before implementing (e.g. `fast-fast-SLOW-SHADER-hold`); see `hyperframes-creative/references/beat-direction.md`.
4. **Timing** — which clips drive duration, where transitions land, the pacing.
5. **Layout** — build the end state first (see below).
6. **Animate** — then add motion via `hyperframes-animation`.
## Layout Before Animation
Position every element where it sits at its **most visible moment** — fully entered, correctly placed, not yet exiting. Write that as static HTML + CSS first. **No GSAP yet.**
**Why:** if you position elements at their animated start state (offscreen, scaled to 0, opacity 0) and tween to where you _think_ they land, you are guessing the final layout — overlaps stay invisible until render. Build the end state first and you see and fix layout problems before adding motion.
1. **Identify the hero frame** for each scene — the moment the most elements are simultaneously visible. That is the layout you build.
2. **Write static CSS** for that frame. The content container must fill the scene with padding, not absolute offsets:
```css
.scene-content {
display: flex;
flex-direction: column;
justify-content: center;
width: 100%;
height: 100%;
padding: 120px 160px; /* padding positions content; fills any scene size */
gap: 24px;
box-sizing: border-box;
}
```
Never use `position: absolute; top: Npx` on a content container — it overflows when content is taller than the space. Reserve absolute positioning for decoratives.
> ⚠ **The `width/height: 100%` above only resolves if every ancestor has a resolved height.** The root `<div data-composition-id>` and any wrapper between it and `.scene-content` must be sized (`position: relative; width: 1920px; height: 1080px` on the root — see `hyperframes-core` → "Root must be sized"). Skip this and the flex container collapses to ~0, content piles into the **top-left corner**, and the first glyph clips at x=0 — while `lint`/`inspect` still report 0 issues. And **always keep the `padding`** (≥80px) on `.scene-content`: it is the title-safe margin. Never replace it with bare `gap`.
3. **Add entrances** — animate FROM offscreen/invisible TO the CSS position with `gsap.from()` (in sub-compositions prefer `gsap.fromTo()` so the start state is explicit; see `hyperframes-core/references/sub-compositions.md`). The CSS position is ground truth; the tween is the journey to it.
4. **Exits are transition-handled** — per the scene-transition rules in `hyperframes-animation/transitions/`, only the **final** scene animates elements out; between scenes the transition IS the exit.
**Shared space across time:** if element A exits before element B enters in the same area, both still need correct CSS positions for their respective hero frames — timeline ordering keeps them from coexisting, and the layout step catches accidental overlap. Layered glows/shadows and z-stacked depth are _intentional_ overlap; the step is about catching _unintentional_ collisions (two headlines on top of each other, content bleeding off-frame).
## Build — delegate to the domain skills
This maps the skill's full surface (see the `description`) to its references — non-exhaustive; when an intent isn't listed, route through `hyperframes-creative` (look/concept), `hyperframes-animation` (motion), `hyperframes-core` (contract), `media-use` (audio/captions). **The first row is ADDITIVE — read it AND your intent row, not one or the other.**
| Building… | Read first (in order) |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ALWAYS — every non-trivial piece, on top of your intent row below** | `hyperframes-creative/references/house-style.md` + `references/video-composition.md` (also gated in Step 1 / HARD-GATE; the "produced, not generated" foreground detailing) |
| **Kinetic typography / text-forward** | `hyperframes-animation/techniques.md` (kinetic type) + `adapters/gsap-easing-and-stagger.md` + `rules/kinetic-beat-slam.md` |
| **Title card / lower-third / overlay / PiP / text-behind-subject** | `hyperframes-creative/references/composition-patterns.md` + (for the centered/sized frame) `hyperframes-core` → "Root must be sized" |
| **Logo / brand-mark reveal** | `hyperframes-animation/rules/svg-path-draw.md` (draw-on) + `rules/3d-text-depth-layers.md` + `rules/scale-swap-transition.md` |
| **Data / stats / numbers** | `hyperframes-animation/rules/counting-dynamic-scale.md` + `rules/stat-bars-and-fills.md` + `hyperframes-creative/references/data-in-motion.md` |
| **Product / app / UI demo** | `hyperframes-animation/rules/3d-page-scroll.md` + `rules/cursor-click-ripple.md` + `rules/press-release-spring.md` |
| **Audio-reactive / music-driven** | `hyperframes-creative/references/audio-reactive.md` (pre-extract bands; map to motion) |
| **Narrated / voiceover / music / SFX / captions** | `media-use` → the shared audio engine `scripts/audio.mjs` (one call = TTS + BGM + SFX → `audio_meta.json`); caption authoring + asset placement via `hyperframes-core`. See **Audio** below. |
| **Multi-scene / transitions** | `hyperframes-animation/transitions/overview.md` **then** `transitions/catalog.md` (you are not done after the overview — the GSAP recipe is in the catalog) |
| **Modular / sub-compositions** | `hyperframes-core/references/composition-patterns.md` + `references/sub-compositions.md` |
### Audio: one engine (TTS · BGM · SFX)
Only when the piece calls for it (per "build exactly what was asked" — no ambient music on a title card). Don't hand-roll TTS or vendor a copy: write a neutral `audio_request.json` and call the shared engine in `media-use`. It auto-degrades on one switch — HeyGen credential present → HeyGen TTS + music/SFX **retrieval**; absent → ElevenLabs/Kokoro TTS, Lyria/MusicGen BGM **generation**, and the bundled SFX library. Full flag list + request/meta schema: the header comment of `media-use/audio/scripts/audio.mjs`.
```jsonc
// audio_request.json — one line per narrated segment; `id` is yours (joins audio_meta back)
{
"lines": [
{ "id": "s1", "text": "Your opening line.", "sfx": ["whoosh"] },
{ "id": "s2", "text": "The next beat." },
],
"bgm": { "query": "calm cinematic underscore" }, // omit "mode" → auto (retrieve if HeyGen, else generate); "none" to disable
}
```
Before relying on this workflow, run:
```bash
# <MEDIA_DIR> = the installed media-use skill dir (sibling of this skill)
node <MEDIA_DIR>/scripts/audio.mjs --request ./audio_request.json --hyperframes . --out ./audio_meta.json
npx hyperframes skills update general-video
```
Then read `audio_meta.json`: mount each `voices[].path` + (`bgm.path`, `sfx[]`) as `<audio>` tracks and use `voices[].words` for captions, all per `hyperframes-core` (audio tracks + caption authoring). If BGM took the generate path (`bgm_pending: true`), run `media-use/audio/scripts/wait-bgm.mjs` before final render.
A successful no-op means the skill is current. Surface an update failure instead of continuing from memory.
## Output checklist → `hyperframes-cli`
## 1. Apply cross-cutting source adapters
- [ ] `npx hyperframes check` pass (block on results)
- [ ] design adherence verified if a spec (`frame.md` / `design.md`) exists — checklist in `hyperframes-creative/references/design-adherence.md`
- [ ] `npx hyperframes check` passes, or every overflow is intentionally marked
- [ ] contrast warnings addressed; for multi-scene work, review the animation map (`hyperframes-animation/scripts/animation-map.mjs`)
- [ ] deliver the preview; render to MP4 only on explicit request
- [ ] surface the preview **only at handoff** (it is the stable, final preview); don't pop one mid-build — build-phase snapshots are headless
- **Media:** For any audio, image, icon, logo, voice, grade, LUT, caption, or media-operation need, load `/media-use` and follow its adoption, resolution, provider, provenance, and reuse contracts. Before the first authenticated provider action, run `npx hyperframes auth status` and relay its output verbatim. If signed out, apply the gate in `../hyperframes-core/references/brief-contract.md`: collaborative waits for sign-in or an explicit offline choice; autonomous states the status and continues through an available offline provider. Surface a blocker when no offline provider can satisfy a required capability. Local adoption alone does not require an auth gate.
- **Figma:** If any input is a `figma.com` URL, run `/figma` first. Build from its exported assets, tokens, components, or storyboard frames. Do not use raw Figma MCP calls because they skip SVG sanitization, media provenance, and brand-token binding.
These adapters do not change the workflow selected by `/hyperframes`.
## 2. Start from project state
Apply the first matching row; do not evaluate lower state rows:
| State | Action |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Specific edit | Make the edit, preserve existing project decisions, then rerun affected checks. Do not reopen discovery. |
| `BRIEF.md` exists | Read it. If `workflow` names another workflow and `flow` is not `companion`, hand off. Ask no brief questions. |
| No brief, but `hyperframes.json` or `STORYBOARD.md` exists | Resume from files and recorded preferences. Backfill `BRIEF.md` only from known facts. |
| Fresh creation | Run `/hyperframes` and its intent layer. Return here only for `workflow: general-video` or `flow: companion`. |
For a new project, choose a kebab-case directory name from the brief and scaffold before writing the brief:
```bash
npx hyperframes init "videos/<project>" --non-interactive --example=blank
```
Then write `BRIEF.md` at the project root using `../hyperframes-core/references/brief-format.md`. In an existing project, the root is the directory containing `hyperframes.json`. Record only the confirmed preference-backed fields named by the brief format, using `node <MEDIA_DIR>/scripts/prefs.mjs record --hyperframes <PROJECT_ROOT>`; never record inferred defaults. Here `<MEDIA_DIR>` is the installed `/media-use` skill directory and `<PROJECT_ROOT>` is the directory containing `hyperframes.json`. If the intent layer adopted a recipe, apply it now with `node <MEDIA_DIR>/scripts/recipe.mjs use --hyperframes <PROJECT_ROOT> --name <name>` and do not ask again.
## 3. Interpret the run shape
Use only the canonical terms from `../hyperframes-core/references/brief-contract.md`:
| Field | Meaning | Effect |
| -------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
| `flow` | Who drives | `automation`: choose and execute the route. `companion`: co-create in conversation. |
| `storyboard` | Whether the board is a review surface | `yes`: run plan and sketch review. `no`: build without the board. |
| derived `mode` | How checkpoint gates behave | Follow the brief contract. Never ask the user to name a mode. |
Do not invent synonyms for these states. An ongoing “just build it” signal is handled by the intent layer and arrives as `flow: automation`, `storyboard: no`.
- For `flow: automation`, choose the route and state it in one line in the first progress update.
- For a specific edit, make the edit without inventing a new route.
### Companion flow
When `flow: companion`:
- Read `BRIEF.md` and reconcile accepted `## Assets` and `## Customizations` with project artifacts. Complete accepted work that is still pending; leave completed work alone; do not offer an accepted capability again as if it were new.
- **Arrive as the director, not the contractor.** A user who chose companion chose involvement and quality; the honest response is the best version you can design, not the smallest one you can defend. The first plan is the ceiling treatment: the story arc (borrow the nearest genre lens — menu § Genre lenses), the design spec, each scene's motion treatment cited by name (§ 5's plan discipline), the transitions, the audio identity — music and sound marks, or deliberate silence — the user's material placed, and a designed open and close. Say what each layer adds in one line; flag the expensive ones (render time, sign-in, billing) as you name them. The user trims a treatment down; they should never have to assemble one approval by approval.
- **The ceiling belongs to the concept, not the toolbox.** Every layer must serve the brief's message — a treatment that would dress any video the same way is decoration. Craft rises to the ceiling; content never grows past what was asked (§ 6).
- Between checkpoints, `../hyperframes/references/capability-menu.md` works two ways. As the trigger list: offer a relevant capability when the user mentions its input or the build reaches its need. As each pass's upgrade channel: a plan, sketch, or build checkpoint may carry one or two traced offers pointed at material the user is looking at ("scene 3's stat wants the count-up treatment"). Read it before offering; never dump the full catalog.
- After the user accepts a capability, produce its artifact and record the decision in the matching `BRIEF.md` body section immediately. Rewrite a frontmatter field and record the confirmed preference only when the user explicitly changes it.
- Keep the same storyboard, validation, final-preview, and render-approval gates. Companion changes who steers, not what quality requires.
## 4. Load required knowledge before each stage
These reads are mandatory when their condition matches:
| Condition | Read before acting |
| ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Any composition HTML or scene layout | `/hyperframes-core`; use `references/determinism-rules.md` for its layout contract |
| Any non-trivial creation or visual treatment | `/hyperframes-creative``references/house-style.md` and `references/video-composition.md` |
| Any motion, animation, or scene transition | `/hyperframes-animation`; follow its routing to the matching rules, adapters, blueprints, or transition references |
| `storyboard: yes` | `../hyperframes-core/references/storyboard-format.md` and `../hyperframes-core/references/review-loop.md` |
| Any media asset or operation, including narration, BGM, SFX, captions, grading, or transforms | `/media-use`; for framework playback and placement also read `/hyperframes-core``references/variables-and-media.md` |
| Multi-scene assembly | `../hyperframes-core/references/production-loop.md` |
| `flow: companion`, before the first plan | `/hyperframes-creative``references/story-spine.md` and `references/house-style.md`; the nearest genre lens and the full `../hyperframes/references/capability-menu.md` — the ceiling treatment is designed from these, not recalled |
| A companion capability offer, capture, beat grid, generative video, map, publishing, or cross-workflow capability | `../hyperframes/references/capability-menu.md` |
| A design spec exists, before final approval | `/hyperframes-creative``references/design-adherence.md` |
Do not replace these reads with recollection. Progressive disclosure saves context only when the matching reference is actually loaded.
## 5. Execute the composition
Use this dependency order. Skip a stage only when its input is absent.
1. **Plan.** State the viewer arc, structure, rhythm, and duration driver. Use one file for a short single scene; use sub-compositions for three or more hard scene cuts or any reused scene. Read `/hyperframes-creative``references/story-spine.md` for narrated arcs, `references/beat-direction.md` for rhythm, and `/hyperframes-core``references/composition-patterns.md` for structure. For an open-ended multi-scene brief, expand the prompt through `/hyperframes-creative``references/prompt-expansion.md`. A multi-scene plan cites each scene's shape: a blueprint id from `/hyperframes-animation``blueprints-index.md` when one fits, or the named rules it composes from `rules-index.md` when none does — motion names come from those indexes, never invented. Story truth decides which scenes exist; the citation dresses them.
2. **Review the plan when requested.** For `storyboard: yes`, write one `## Frame N` per scene with `status: outline` and a declared `src`, then run the shared review loop. For `storyboard: no`, continue without opening the board.
3. **Resolve dependencies.** Install registry blocks before parallel work. Stage user assets, adopt existing media, and resolve only what the brief requires. Start audio early when its timings drive duration.
4. **Build static hero layouts.** Implement every scene at its most visible moment before adding motion. The confirmed wireframe, when present, is this end state and must not be redrawn. Follow `/hyperframes-core` for the layout contract.
5. **Animate.** Build each scene from its cited blueprint or rules: read the full recipe body (`/hyperframes-animation``blueprints/<id>.md`, `rules/<id>.md`) before writing its motion, and keep to it. Use `/hyperframes-animation` for runtime adapters and scene transitions. Keep animation details in that owning skill rather than re-defining them here.
6. **Assemble.** Mount scenes, media, transitions, captions, and audio using the production loop. Real voice duration overrides estimates.
7. **Verify.** Use `npx hyperframes lint` for fast feedback after the first HTML pass and structural changes. For the final gate, run `npx hyperframes check`; it reruns lint internally, so do not run a redundant standalone lint immediately before it. For sub-compositions, inspect midpoint snapshots. For multi-scene work, review the animation map.
8. **Final approval.** Open the final Studio preview only after checks pass. Ask whether to render or revise. Render only after approval.
## 6. Gates that always apply
### Keep scope exact
Build what the user asked for. A title card is not a title card plus three scenes, music, and captions. Offer additions before adding them.
### Establish design before HTML
Resolve the design source in this order: `frame.md``design.md``DESIGN.md`. Treat the first file found as brand truth.
When no design spec exists, complete all four items before writing composition HTML:
1. Ground the visual identity in `house-style.md` and `video-composition.md`.
2. Write one sentence naming the concept angle for every non-trivial creation.
3. Choose an embeddable font pairing from `/hyperframes-creative``references/typography.md`; do not assume an unbundled display font exists in cloud rendering.
4. Define the focal element, edge anchors, supporting detail, and background treatment.
Match density to the requested format and message. Density examples are guidance for produced frames, not permission to invent claims, scenes, or a fixed number of elements.
For a named style or mood, read `/hyperframes-creative``references/visual-styles.md`. When the user needs to choose visually and no shipped preset fits, read `/hyperframes-creative``references/design-picker.md` and run the interactive design selection there.
### Preserve the composition contract
Timed elements use `class="clip"`; the root and relevant ancestors are sized; each composition registers one paused, seek-safe timeline on `window.__timelines`; rendering is deterministic. Do not use render-time network fetches, clocks, or unseeded randomness.
### Borrow workflows safely
When the piece resembles a shipped workflow, borrow its genre references as examples. First run `npx hyperframes skills update <workflow-name>`. Borrow its story shape and taste, not its private scripts, pipeline state, or directory contract. The generic build remains owned by this skill.
## 7. Done
A run is complete only when:
- requested scope is implemented;
- for `flow: companion`, the treatment is delivered, not just the scope: every scene's cited blueprint or rules realized, the audio identity present (or the silence chosen and said), the open and close designed rather than defaulted;
- `npx hyperframes check` passes, including its built-in lint stage;
- design adherence is reviewed against `/hyperframes-creative``references/design-adherence.md` when a design spec exists;
- contrast findings are resolved;
- sub-composition snapshots are inspected when applicable;
- an autonomous handoff includes an inspected contact or snapshot sheet; multi-scene sheets use scene midpoints;
- the handoff names the final preview or rendered artifact as applicable and reports the actual duration for a time-based deliverable;
- `hyperframes-animation/scripts/animation-map.mjs` is reviewed for multi-scene work;
- the user approves the final Studio preview before render;
- the rendered file is verified when a render was requested.
After final approval, offer once to freeze the run as a recipe, following `../hyperframes-core/references/review-loop.md` § 4.