From 8561672eca389fd76b75c0b5c2ad78ed7c6fb7db Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Thu, 16 Apr 2026 23:31:05 -0700 Subject: [PATCH] feat(skills): pre-plan persistent-subject choreography (Addition C) User feedback from eval 5 exposed a real R4 failure mode: - p2 Thread: Maya's card persisted across scenes (good) but often landed in positions that didn't fit the scene's content hierarchy (bad). Semantic-mismatch. - p3 Vermeer: painting zoomed to 2.1x in scene 2, blocking the right-column metadata the scene subagent had authored. Size- collision. Root cause: expansion identifies the subject, scene subagents author their scenes INDEPENDENTLY (picking their own layouts), and the scaffold tweens the subject's position/scale across transitions as an afterthought. Scene subagents don't know how big the subject will be in THEIR scene, so they place their chrome wherever, and then the scaffold's tween scales the subject up or moves it into regions already filled. Fix: expansion pre-plans the choreography BEFORE the per-scene detailed breakdown. Per-scene block specifies: - position (center x, y) - scale - size_envelope (actual on-screen footprint in this scene) - role (focal / background anchor / data-point / glyph-slot / ...) - reserved_region (rectangle scene subagent must leave empty) - scene_must_avoid (short instruction) Orchestrator (multi-scene.md) passes each scene subagent its scene's choreography block plus the contract: - The scaffold owns the subject's DOM + timeline. - Your scene layout MUST respect the reserved region. - Design your scene chrome around the element's role in this scene. - Do NOT animate the persistent subject in your timeline. Invariants: - Size envelope reflects the SETTLED state (if the subject scales up during the scene, reserve for the larger size). - Scene-to-scene positions trace a visually-coherent path, not leapfrogs. - Role changes drive reserved-region size. Branch worktree only. Not synced to installed main skill path. --- skills/hyperframes/references/multi-scene.md | 22 +++++++ .../references/prompt-expansion.md | 58 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/skills/hyperframes/references/multi-scene.md b/skills/hyperframes/references/multi-scene.md index 3d6dced0..7de628db 100644 --- a/skills/hyperframes/references/multi-scene.md +++ b/skills/hyperframes/references/multi-scene.md @@ -112,9 +112,31 @@ Dispatch one subagent per scene, running in parallel (concurrently with the scaf - The global animation rules from the prompt - That scene's specific prompt section only - The scene number `N` and start time — used for the `s{N}-` prefix and `var SN = {start_time};` +- **The persistent-subject choreography block for this scene**, if any — see below Each subagent focuses its entire context on making ONE scene visually rich: parallax layers, micro-animations, kinetic typography, ambient motion, background decoratives. No boilerplate, no other scenes. **Each subagent must write to a file** — text returned in conversation is not accessible to the assembly agent. +### Persistent-subject choreography contract + +If the expansion identified a persistent subject (R4 applies), the expansion will have produced a choreography plan with one block per scene. See [`prompt-expansion.md` → Pre-plan the persistent-subject choreography](./prompt-expansion.md). + +When dispatching scene subagents, **the orchestrator must pass each subagent its scene's choreography block** along with these instructions: + +1. **The persistent subject lives in a shared overlay layer outside your scene container.** Do NOT author the subject inside your scene fragment. The scaffold owns the subject's DOM + timeline. +2. **Your scene's layout must respect the reserved region.** No typography, no decoratives, no scene chrome may be placed inside the reserved region specified for your scene. The subject will occupy it. +3. **Design your scene's content around the element's role in this scene.** If the role is _focal subject_, your scene chrome is thin margins and light labels around it. If _background anchor_, your chrome fills the frame and the subject is a small corner anchor. If _data-point in a row_, your scene includes the row structure and reserves a slot for the subject. +4. **Do NOT animate the persistent subject in your GSAP timeline.** The scaffold authors the subject's tweens across scene boundaries on the `tl` timeline. Your scene tweens animate the scene's own content only. +5. **Your scene may reference the subject's position as a fixed anchor** — e.g., "the label line points at the subject's center at {x, y}." Treat it like a pre-placed element the scaffold will render for you. + +The scaffold's responsibility: + +1. Create the subject's DOM in the shared overlay layer outside `.scene` containers. +2. Author tweens on the subject that move it between choreography positions across scene boundaries — the transitions' timing determines when the subject starts its move. +3. Use `xPercent: -50, yPercent: -50` on the subject so position coords are center coords. +4. Coordinate scene crossfades with subject moves so the subject's motion spans the crossfade midpoint (so the viewer tracks one element through the cut). + +Without this contract: scene subagents place their content where they think looks good, then the scaffold animates the subject into a region that was already filled — producing the size-collision and semantic-mismatch failures observed in prior evals. + ## Phase 2b: Streaming evaluation As each scene file appears in `.hyperframes/scenes/`, dispatch an evaluator subagent immediately — don't wait for all scenes to finish. The evaluator receives: diff --git a/skills/hyperframes/references/prompt-expansion.md b/skills/hyperframes/references/prompt-expansion.md index cf4235bd..d142e527 100644 --- a/skills/hyperframes/references/prompt-expansion.md +++ b/skills/hyperframes/references/prompt-expansion.md @@ -77,6 +77,64 @@ If the composition is about a specific, named, real-world artifact — a photogr These are the exceptions. The default is: use what's real. +## Pre-plan the persistent-subject choreography + +When R4 applies (a subject persists across scenes via shared overlay), the subject's position, size, and role across scenes **must be pre-planned by the expansion**, not left for scene subagents to improvise. Without a pre-plan, two failures happen: + +1. **Semantic-mismatch positions** — scene 2's layout puts the subject somewhere that fits scene 2 alone, but the path from scene 1's position to scene 2's position doesn't read as a coherent camera/lens move. +2. **Size collisions** — scene 2 is authored with its own typography and metadata in regions that the subject will later occupy (because the scaffold scales it up mid-transition). The result: the scaled-up subject blocks the scene's content. + +The root cause of both: scene subagents currently author their scenes without knowing how big the subject will be in THEIR scene, or what region they must leave empty for it. + +### What the expansion must produce + +Before the per-scene breakdown, emit a **choreography plan** for each persistent subject. Per scene, specify: + +- **position** — center coordinates `{ x, y }` in the 1920×1080 frame. +- **scale** — the subject's on-screen scale when the scene is at its hold. +- **size_envelope** — actual bounding box `{ w, h }` reflecting the SETTLED size in this scene (if the subject scales up or down during the scene, use the largest size it reaches). +- **role** — the subject's semantic role in this scene: _focal subject_, _background anchor_, _data-point in a row_, _glyph-slot_, _map pin_, _frame margin ornament_, etc. +- **reserved_region** — rectangular region `{ x: [min,max], y: [min,max] }` the scene subagent must leave empty. If the element fills the frame at this scale, the region fills the frame and typography must live in narrow margins or overlay-over-subject. +- **scene_must_avoid** — a short instruction for the scene subagent, e.g. "do not place other content in the reserved region" or "typography goes to top-left + bottom-left margins only; no right-column meta at this scale." + +Example for a Vermeer painting scene 2 where the painting zooms to 2.1×: + +```yaml +persistent_subject: + id: "#painting" + form: "" + +choreography: + scene1: + position: { x: 1380, y: 540 } + scale: 1.0 + size_envelope: { w: 540, h: 680 } + role: focal subject, held still on the right third + reserved_region: { x: [1100, 1920], y: [180, 900] } + scene_must_avoid: title/byline typography lives in the left column only + scene2: + position: { x: 960, y: 540 } + scale: 2.1 + size_envelope: { w: 1134, h: 1428 } + role: zoom focus on the pearl/jaw; the painting IS the frame + reserved_region: { x: [240, 1680], y: [-250, 1250] } + scene_must_avoid: typography goes to top-left + bottom-left margins only; NO right-column meta at this scale + scene3: + position: { x: 620, y: 540 } + scale: 0.85 + size_envelope: { w: 460, h: 580 } + role: closing subject, held left-of-center + reserved_region: { x: [380, 860], y: [250, 830] } + scene_must_avoid: closing stanza goes to right column +``` + +### Invariants + +- **Size envelope reflects the settled state.** If the subject enters scene 2 at scale 1 and tweens up to scale 2.1, the envelope for scene 2 is at scale 2.1. Scenes reserve for the FINAL state, not the entry state. +- **The choreography plan traces a visually-coherent path.** Scene-to-scene positions should read like a deliberate camera/lens move (push-in, pull-back, pan, reposition), not a leapfrog. +- **Role changes drive reserved-region size.** When the subject is _focal_, the reserved region is large (the subject dominates). When _background anchor_, the region is small or corner-pinned. +- **Scene subagents receive their scene's choreography block.** See `multi-scene.md` for the dispatch contract. + ## What to generate Expand into a full production prompt with these sections: