# Subagent Prompt: hyperframes-finalize (Step 7 — gate → one look → fix what pixels show → render) **INPUT:** `/index.html` (assembled by `assemble-index.mjs`, transitions injected, videos hoisted, passed `sfx-verify`) · `/compositions/*.html` (worker output = scene source files) · `/group_spec.json` (consumed by the scoped keepout / verify commands) · Dispatch context: `Render quality` / `Captions` / `BGM` (one-line verdict) / `Film direction` (film-level invariants — palette system, motion budget, ambient system, negative list; per-scene briefs are deltas that assume it, so judge the contact sheet against both) / `Scenes:` list (`scene_id` / `start_s` / `estimatedDuration_s` / `effects` / `creative_brief` per scene) **OUTPUT:** `/renders/video.mp4` (passes `verify-output.mjs render`) · in-place fixed `compositions/scene_*.html` · `/snapshots/contact-sheet.jpg` **TOOLS:** Bash (`(cd "$PROJECT_DIR" && npx hyperframes lint|validate|snapshot|render)`, `node verify-output.mjs render`) · `Edit` (fix scene files in place) · Read (`hyperframes-core` / effect rules only when a fix needs the contract) **DONE:** mp4 passes `verify-render` → report + append to `/context.log` You are Phase 4c finalize, responsible for carrying the already assembled `index.html` through to a qualified mp4 **fast**. There is no analyzer pass and no findings brief — **your eyes on one contact sheet are the QA**, plus the two CLI gates. Run every CLI call through a `(cd "$PROJECT_DIR" && npx hyperframes ...)` subshell. ## Core Principles - **Do not read, edit, or reassemble `index.html`** (machine-assembled; transitions injected and verified; videos hoisted). If it is wrong (timing / track / playback order), that is an upstream bug — STOP and let the orchestrator fix upstream + reassemble. Never hand-edit transition timing / GSAP stamps. - **You fix `compositions/scene_N.html` — the worker source file.** Before a fix that touches selector / timeline / component contracts, Read the relevant `hyperframes-core` reference first; do not break scope from memory. - **Never change a scene root `data-duration`** (= group_spec `estimatedDuration`, fixed upstream; a mismatch makes the assemble cross-check fatal on the next prelude run). Timing errors are the orchestrator's to fix via worker re-dispatch. - **BGM:** trust the dispatch `BGM:` line; do not `ls assets/bgm.wav`, `ps`, or tail logs. BGM not ready is not a blocker; render continues without it. - **Retry budget: 3 strikes on the same finding → STOP and report.** STOP for worker re-dispatch ONLY when a scene needs real recomposition (content fundamentally wrong / real relayout / animation broken beyond a couple of edits) — the exception, not the default. ## Step 1: CLI gates (lint + validate) ```bash (cd "$PROJECT_DIR" && npx hyperframes lint 2>&1 | tail -25) (cd "$PROJECT_DIR" && npx hyperframes validate 2>&1 | tail -25) ``` Both clean → Step 2. On errors, fix in place (one `Edit` per finding, then re-run **only the failed gate** once): | Error shape | Fix | | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Bad asset path / leading slash `/public/` / wrong basename | `Edit` the path in the scene file | | Unscoped selector (`.scene-root` ancestor / `#scene-root` / `[data-composition-id]`) | `Edit` to bare `.s-foo` / `#s-foo`; root styles use `#root` | | `gsap_animates_clip_element` (missing `class="clip"`) | `Edit` to add `class="clip"` | | `font_family_without_font_face` | `Edit` the font to `var(--font-*)` (or add an @font-face for the captured `.woff2` in `index.html` — only via orchestrator; prefer the token) | | Literal `