Commit Graph
9 Commits
Author SHA1 Message Date
ukimsanovandClaude Opus 4.7 a5bc11632f fix(skill): address PR #1026 review — find $HOME, order-indep audioRegex, cached reads
Three issues from Miguel's + Rames's reviews:

**[Blocking] find / violates CLAUDE.md guidance (Miguel)**

CLAUDE.md says: "When running find, search from . (or a specific path),
not / — scanning the full filesystem can exhaust system resources on
large trees." I introduced 3 instances of `find /` in skill prose to
help sub-agents locate skill files from unknown CWDs. Replaced all 3
with `find "$HOME" ... -maxdepth 10`. Verified all 4 skill files
resolve correctly under $HOME on the testbed setup.

Files: step-3-storyboard.md (×2), step-5-build.md, step-6-validate.md.

**[Blocking] SFX audio regex assumed attribute ordering (Miguel + Rames)**

The v2 audioRegex required src= to appear lexically BEFORE data-start=
in the same <audio> tag. But capabilities.md:365 — in the same skill —
documents the canonical pattern with src= LAST:

  <audio id="..." data-start="..." data-duration="..." data-volume="..."
         data-track-index="..." src="...">

Real compositions following the docs would have audio tags that don't
match the regex → SFX reported as MISSING → false FAIL in the script
output → false alarm in the user-facing summary. Exactly what v2 was
supposed to fix.

Replaced with the same two-step shape that readBeatDurationsFromIndex
already uses correctly: match `<audio[^>]*?>` to grab the whole tag,
then extract src= and data-start= from the tag string with independent
regexes. Verified both attribute orderings (src first, src last) now
work via inline node test.

**[Minor] readBeatCompositions / readBeatDurationsFromIndex re-read on
every call (Rames)**

Added process-scoped caches to both helpers. The script is a one-shot
CLI so no invalidation needed — first call hits disk, subsequent calls
return the cached result. readBeatCompositions was called 3×,
readBeatDurationsFromIndex 2× — now 1× each.

**Regression checks**

- huly-v3: 4 PASS · 3 FAIL · 1 INFO (unchanged — same 3 real issues
  flagged: 48px wordmark, missing shaders, 3 SFX drifts)
- huly-launch-v4: 6 PASS · 0 FAIL · 2 INFO (unchanged)
- Lint + format: clean

2 files changed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 10:44:45 -07:00
ukimsanovandClaude Opus 4.7 f4a7961bc1 fix(skill): w2h-verify v2 — kill false positives from real-agent debrief
A fresh agent session ran the v1 verify script and the disclosure pasted
into their final summary showed 3 FAIL rows for things that weren't
actually defects:

  Headline font-size: flagged Beat 2 (wordmark SVG), Beat 3 (UI grid),
    Beat 5 (terminal). None of these legitimately have text headlines.
  Timeline coverage: flagged 5/6 beats because the script's regex only
    saw `tl.X(..., 2.5)` literal positions and missed forEach loops,
    variable-position tweens, and long-duration scaler tweens.
  Beat durations: flagged 2 beats because my "duration X.Xs near beat
    label" fallback false-matched non-beat durations
    (e.g., "shader runs — duration 0.7s" near a "Beat 1" mention).

The agent had to write ~5 paragraphs defensively justifying each false
FAIL. That's friction we can fix.

Tested against the agent's actual project (huly-launch-v4): went from
4 FAIL (3 false positives + 1 real bare-table parser miss) to 0 FAIL.
Also re-verified huly-v3 still correctly catches its 3 real issues
(48px wordmark, missing shaders, 3 SFX drifts) — no regression.

**Brand visuals check**

Switched from "≥30% asset usage" (gameable, rewards quantity over quality)
to "at least 1 beat references a captured hero/image/svg" — quality
signal that's cheap to satisfy when real, hard to fake. Excludes fonts,
logos, favicons, contact-sheets.

**Headline check**

Now only flags beats where the LARGEST font-size is in the 40–<80px
range — the "aspiring headline but too small" zone. Below 40px = beat
has no text headline by design (terminal, UI labels, SVG-only); skip.
≥80px = proper headline; pass. Eliminates the false positives on
SVG-dominated and UI-grid beats while still catching the real "headline
too small" failure (Beat 4 at 72px in this run; Beat 1 wordmark at 48px
in another).

**Timeline coverage check**

Three improvements:
1. Detects forEach loops + for-loops containing tl.X() calls — beats
   with these have events at positions the static parser can't read;
   mark as INFO-skipped rather than failed.
2. Detects long-duration tweens — if a single tween's duration covers
   ≥70% of the beat duration (camera dolly, breathing animation), the
   beat has full coverage via persistent motion; skip the position check.
3. New paren-balanced parser for extracting tl.X() position arguments —
   the v1 regex was matching `rgba(86,131,218,0.35)` and capturing 0.35
   as a tween position. The new parser walks paren depth and only
   captures top-level trailing numeric args. No more rgba false matches.

**Shader transitions check**

Two fixes:
1. Filter out inventory lines — lines listing 3+ shader names are
   "what's available," not "what's planned for use." Real use
   mentions one or two shaders per line.
2. Apply the same SFX-context exclusion to the declared side that the
   present-check side already had — "glitch" inside `sfx/glitch-1.mp3`
   no longer counts as a declared shader transition.

For huly-v3: was 6 declared (1 phantom from inventory + 5 + glitch
from SFX), now 2 declared (light-leak, cinematic-zoom) — matches the
storyboard's actual plan.

**Beat duration check**

1. Dropped the "duration X.Xs within 200 chars of beat label" fallback
   — too loose; matched shader durations, animation durations, anything
   labeled "duration". This was the source of the 0.70s misread in the
   debrief.
2. Added a bare-number timing-table parser for the format
   `| 1 | 0.00s | 5.20s | 5.20s | ... |` (with optional `>` blockquote
   prefix). Computes duration = end - start.
3. Added a negative lookahead so `\bB3\b` doesn't false-match "B3.1"
   sub-beats and grab the wrong row.
4. Filter buildBeatIds to only numbered beats — skips the root
   composition (`data-composition-id="main"`) so it doesn't inflate
   "parseable" count.

**Brand visuals + asset count**

Excluded fonts/ subdirectory (always-used via @font-face → would
always pass) and contact-sheet-*.jpg (pipeline outputs, not website
inputs). Both inflated the denominator and weakened the signal.

**Edge case fixes**

- Removed `basename` unused import (oxlint).
- Fixed shader-name substring overlap: longest-name-first matching so
  "cross-warp-morph" doesn't double-count as "cross-warp".
- SFX timestamps now collect ALL audio tags per file (multi-timestamp
  SFX like click×3); picks closest index timestamp to each storyboard
  timestamp instead of just keeping the last.

**Step 6 doc**

Updated the skill's "w2h-verify — the source of truth" section to
describe the new checks accurately and what failure mode each catches.

2 files changed, +486/-109. Format + lint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 09:03:35 -07:00
ukimsanovandClaude Opus 4.7 190f1ec71a feat(skill): w2h-verify script + Step 6 DoD wiring — tooling-based enforcement
Three rounds of text-based enforcement plateaued. A third agent debrief
showed the same failures: 9% asset usage (vs ≥30% floor), shader
transitions declared in STORYBOARD.md but not in shipping index.html,
SFX timestamps drifted up to 12.4s, animation-map skipped, MP4 not
rendered, honest-disclosure section omitted from final summary.

The pattern is clear: language-only enforcement is selectively
interpretable by the agent under ship pressure. Move enforcement into
tooling — facts the agent can't fudge.

**New script: `skills/website-to-hyperframes/scripts/w2h-verify.mjs`**

Pure file-analysis script (no shell spawns). Computes six checks and
prints a PASS/FAIL/INFO table:

1. Asset usage — assets referenced in compositions ÷ assets captured;
   target ≥30%. Tested against videos/huly-v3: caught 6/74 = 8% FAIL.
2. Shader transitions consistency — STORYBOARD.md-declared shaders vs
   index.html. Longest-name matching to avoid substring false positives
   (cross-warp-morph not double-counted as cross-warp). Tested: caught
   6 declared / 1 present / 5 missing.
3. SFX timestamp drift — parses STORYBOARD.md table rows for
   `sfx/X.mp3` + time-with-`s`, parses index.html <audio data-start>,
   flags drift >0.5s. Tested: caught 12.4s drift on click.mp3 that
   the agent debrief didn't even mention.
4. animation-map.json existence — explicit file check.
5. Rendered MP4 existence — scans project root, output/, renders/.
6. Required artifacts — STORYBOARD.md, DESIGN.md, SCRIPT.md, index.html
   all present.

Exit code: 0 (all pass) or 1 (one or more fail). The script's output
becomes the Step 6 deliverable — paste verbatim into the user-facing
summary.

**Skill update: `step-6-validate.md`**

Adds `w2h-verify report` to the DoD checklist with the rule: paste the
FULL output verbatim into the final summary. Cherry-picking rows,
substituting adjectives for percentages, or omitting FAIL lines is
explicitly forbidden. If a row says FAIL, either fix it and re-run
until PASS or include the FAIL line verbatim in "What I did NOT
verify" with a one-sentence reason.

Test run against the project that prompted this:

```
SUMMARY: 1 PASS · 4 FAIL · 1 INFO
- Asset usage: FAIL 6/74 (8%) target ≥30%
- Shader transitions: FAIL 6 declared, 1 present, 5 missing
- SFX timestamps: FAIL 3 drifted >0.5s (max 12.4s)
- animation-map.json: FAIL missing
- Rendered MP4: INFO no .mp4 found
- Required artifacts: PASS
```

The agent could selectively ignore "the WCAG warnings are false
positives." The agent cannot selectively ignore a line that says
`6/74 (8%) — target ≥30%`.

2 files changed (+ 1 new script, ~330 lines). Format checks pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 00:45:42 -07:00
ukimsanovandClaude Opus 4.7 5594a8286c fix(skill): w2h enforcement round 2 — close the deeper shirking patterns
A second agent debrief (different session, with the prior enforcement edits
applied) revealed the most damning failure yet: the agent used 1 of 65
captured assets. They wrote their own "Asset Audit" table saying SKIP for
64 hero illustrations, brand SVGs, and signature visuals. The entire point
of capture is to USE the brand's assets — that gate was bypassed entirely.

The debrief also revealed 5 other patterns the prior enforcement missed.
This commit closes all 6.

**Pattern A — Asset Audit gate (step-3-storyboard.md)** — BIGGEST FIX

Adds a non-skippable Asset Audit section in Step 3 that requires viewing
every page of capture/assets/contact-sheet-*.jpg + svgs/contact-sheet-*.jpg,
pasting 5 distinctive assets per page (with descriptions of what's actually
pictured), and choosing USE/SKIP per asset with one-sentence justification
for each SKIP. Brand-defaults floor: at least one beat MUST use a captured
hero illustration/photograph/signature diagram — not just the logo. The
forbidden list explicitly calls out: reading asset-descriptions.md alone
without opening the contact sheets, and rebuilding signature graphics in
CSS when the brand's own SVG of that graphic is in capture/assets/.

**Pattern B — Auto mode scope (SKILL.md + step-2-brief.md)**

Clarifies that auto mode covers user-PREFERENCE gates (TTS provider,
voice, beat count, captions yes/no — where the agent decides on the
user's behalf) but NOT quality-VERIFICATION gates (Asset Audit, per-beat
HTML read, DoD checklist, honest disclosure). Adds explicit test for
distinguishing: if the answer changes the content of the video, it's a
preference; if the answer is "did the verification happen?", it's a
quality gate. The agent that skipped the captions question by reasoning
"auto mode says bias toward action" was misusing auto mode.

**Pattern C — 3-path audio/motion verification (step-6-validate.md)**

Replaces the prior "Path 1 or explicit deferred" with three explicit
paths: (1) Play preview in Playwright, (2) render low-res MP4 and read
frames at ≥5fps, or (3) explicit deferred disclosure with QUANTIFIED
coverage gap ("18/900 frames = 2% coverage"). The percentage in Path 3 is
mandatory — vague "deferred to user" was the loophole. Forbidden: claiming
"confirmed via snapshot" as audio/motion evidence; 18 PNGs from a 900-
frame video is 2% coverage, not verification.

**Pattern D — Sub-agent diagnoses are hypotheses (beat-builder-guide.md)**

When a sub-agent reports "this is a linter false positive" / "this is a
known bug", that is a HYPOTHESIS from one symptom — not a verified
finding. Before propagating the workaround to other beats, main agent
must EITHER read the source to confirm OR explicitly disclose the
unverified claim. The debrief showed the main agent applied beat-2's
"linter false positive" diagnosis to beat-4 without ever reading
packages/core/src/lint/utils.ts to confirm.

**Pattern E — Re-snapshot after parallel sub-agents (step-5-build.md)**

When sub-agents run in parallel, each snapshots a project where sibling
beats may not exist yet. Their snapshots at beat boundaries or during
shader transitions show the WRONG content (typically previous beat).
Required after all complete: a canonical project-wide snapshot via the
CLI — that's what Step 6's DoD uses. Sub-agents' intermediate snapshots
are sanity checks, not the deliverable.

**Pattern F — STORYBOARD.md must be updated when divergence accepted
(beat-builder-guide.md)**

When a sub-agent diverges from spec ("the real brand mark is lowercase
'huly' not uppercase 'HULY'") AND the main agent accepts the divergence,
the main agent MUST patch STORYBOARD.md to reflect reality. Otherwise
the spec lies and the next session reading it as ground truth gets the
wrong information. Examples covered: brand mark casing, cell size at
scale, SFX timing alignment.

6 files changed, +131/-11 (net +120 lines of enforcement).
Format checks pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 21:51:52 -07:00
ukimsanovandClaude Opus 4.7 18444decde fix(skill): w2h enforcement edits — close the 9 shirking patterns from agent debrief
After the audit-fix commit (e47bc6c6) landed clarity fixes, a real test run
revealed that the skill still got skipped at the gates that matter most.
The agent's honest debrief listed 9 distinct patterns where it judged
"deliver fast" over "verify what the skill said to verify."

This commit forces evidence at each of those gates so silent skips are no
longer possible without lying — at which point the gate fails by design.

**Patterns 1, 3, 8 — step-5-build.md**

- Pattern 1: "Read each beat HTML top-to-bottom" gate now requires a
  structured evidence block per beat with quoted CSS hex codes, headline
  font-size, captured asset paths, GSAP first/last events, and SFX trigger.
  "I read it and it looks fine" / "the sub-agent confirmed" are not
  acceptable. Snapshots are 3 frames out of 300+ in motion.
- Pattern 3: SFX timestamp computation rule. Every data-start MUST be
  computed (beat-local + beat global start = global timestamp), not
  estimated by eye. The agent typed `data-start="6.0"` for a storyboard
  moment at 5.0s — a 1-second drift, not a rounding error.
- Pattern 8: Recurring sub-agent workarounds must be surfaced under
  "Tooling issues encountered" — burying them means the next session
  hits the same bug.

**Patterns 2, 6, 7, 9 — step-6-validate.md**

- Pattern 2: WCAG contrast warnings now require per-warning verification
  with quoted validator output and opacity check at the sampled timestamp.
  Blanket dismissal as "mostly transition-window false positives" is
  explicitly forbidden.
- Pattern 6: animation-map.json check added to the DoD checklist —
  runs `skills/hyperframes/scripts/animation-map.mjs` and confirms
  per-beat event coverage.
- Pattern 7: Audio + motion verification is now a separate DoD item from
  snapshot verification. Snapshots are silent stills; you must actually
  play the preview and confirm SFX lands at storyboard timestamps within
  ±0.1s. CLI-only sessions must explicitly disclose this as deferred.
- Pattern 9: Honest disclosure section added — final user-facing summary
  MUST end with "What I verified" and "What I did NOT verify" blocks.
  "Looks great, ready to ship" with no disclosure now fails the gate.

**Patterns 4, 5 — beat-builder-guide.md**

- Pattern 4: Sub-agent FLAG protocol. Required phrasing for non-blocking
  issues is concrete and actionable with line numbers. Forbidden phrasing:
  "if X feels too long, you could...", "consider tweaking...", "might
  want to...". Main agent must address each FLAG or write a rejection.
- Pattern 5: Spec ambiguity escalation. If the storyboard names a
  transition without establishing the start state ("Row 1 transitions
  blue → orange" but Row 1's initial color isn't specified), sub-agent
  MUST flag it and ask for confirmation rather than guess. Picking an
  interpretation silently means the build "looks fine" while diverging
  from intent.

3 files changed, +170/-21 (net +149 lines of enforcement language).
Format checks pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 20:12:46 -07:00
ukimsanovandClaude Opus 4.7 e47bc6c6db fix(skill): w2h audit — resolve contradictions, path issues, missing fallbacks
10 fixes from an audit of skills/website-to-hyperframes/ targeting clarity for
AI agents following the pipeline. Each fix is a surgical edit; no behavior
changes for human readers.

**Critical contradictions resolved:**
- capabilities.md: `onUpdate`/`tl.call` was simultaneously documented as required
  (canvas/WebGL/typing patterns) and banned (determinism). Sub-agents reading
  the ban would silently strip working code from Canvas 2D and Three.js beats.
- step-1-design.md: Removed "Depth & Elevation" section template that the same
  file's Rules section forbade. Renumbered remaining sections (6→5).
- beat-builder-guide.md: Narrowed "no onUpdate for counters" rule so canvas
  rendering loops aren't caught by the prohibition.

**Path resolution fixes for sub-agents:**
Sub-agents run from `<project-dir>` (e.g. videos/foo/), not repo root, so
repo-relative paths like `skills/website-to-hyperframes/assets/sfx/manifest.json`
fail silently. Replaced with `find / -path ...` patterns that work from any CWD.
- step-3-storyboard.md: sfx/manifest.json + text-effects.md paths
- step-5-build.md: beat-builder-guide.md path

**Missing fallbacks added:**
- step-3-storyboard.md Gate: autonomous mode now propagates from Step 2 — gate
  no longer blocks on explicit approval when user said "surprise me".
- step-4-vo.md: timing-formula recalibration now has concrete steps for both
  "too short" (add pauses) and "too long" (cut highest-density beat).
- step-6-validate.md: agent-authored descriptions fallback when GEMINI_API_KEY
  is unavailable — DoD checklist no longer has a dead end.

**Quick Reference polish:**
- SKILL.md: step-1-design entry now mentions 50-line fast-path exception.

8 files changed, +32/-37 (net -5 lines). Format checks pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:57:08 -07:00
ukimsanov 24aef5475c fix(skill): eval feedback — font src paths, WCAG pairings, flash-through-white regression
Five fixes from Ular's first-pass workflow run:

1. step-1-design.md Fonts section — sub-agents pointed @font-face for
   "ES Build Neutral" at the Inter .woff2 files because DESIGN.md
   only named families, never emitted exact src: paths. Now the
   Fonts section example shows per-family + per-weight file paths
   AND a copy-verbatim @font-face block sub-agents can paste, so
   there's no inference step. Adds an explicit narrative of the
   real failure mode and how to avoid it.

2. beat-builder-guide.md FONTS rule — was "brand fonts with
   capture/assets/fonts/ path need @font-face in <style>." Now:
   "copy the @font-face block VERBATIM from DESIGN.md. Do NOT guess
   which .woff2 file belongs to which family — capture filenames
   are content-hashed and there is no visible mapping. If DESIGN.md
   doesn't include exact src: paths per family, STOP and ask the
   main agent; never pair an arbitrary .woff2 with a family name
   from memory."

3. step-1-design.md Colors section — Sub-agents reproduced brand
   colors faithfully and hit WCAG AA failures on dark surfaces
   (#68686A on #18191B = 3.16:1). Now the Colors section example
   computes per-pairing contrast ratios with /⚠/ markers,
   documents the dark-surface substitute color when the brand's own
   palette fails, and points at the /hyperframes-contrast skill for
   ratio computation. Sub-agents pick text colors by surface
   context, not by "this is the brand's secondary text color."

4. capabilities.md flash-through-white entry — the "ideal as
   invisible bridge at duration: 0.01" framing caused agents to
   scatter white flashes through every composition as transition
   bridges. The fix was documented in the branch's HANDOFF but
   never landed. Now: "Fade through white midpoint — a visible
   white flash between scenes. Use only when the brand specifically
   calls for a white-flash beat boundary; this is NOT a neutral
   'default' transition."

5. step-6-validate.md Warnings list — adds a paragraph on WCAG
   contrast false positives. The validator samples at fixed
   timestamps; elements at opacity:0 / mid-fade get measured as if
   fully visible, producing spurious failures. Tells the agent to
   verify visually before changing colors to clear a WCAG warning
   — bumping a color to fix a sampling artifact changes brand
   identity for no real benefit.
2026-05-21 11:08:52 -07:00
ukimsanov 051c9c9de4 chore(skill): drop visual-vocabulary.md + use published npx hyperframes
- Delete `references/visual-vocabulary.md` and scrub the four call
  sites that referenced it. The 6-axis lookup framing it introduced
  contradicted the rest of the skill's "design from the brand, not
  from a table" stance.
- Replace all `npx tsx packages/cli/src/cli.ts <cmd>` invocations
  with `npx hyperframes <cmd>` in step-0-capture.md, step-5-build.md,
  step-6-validate.md, and beat-builder-guide.md. The capture- and
  snapshot-pipeline improvements that previously required the local
  CLI now ship in the published CLI via the stack's PRs #987 and
  #988, so once the stack lands the published CLI is the right
  invocation for the skill prose.
- Remove the now-contradictory "ALWAYS use the local CLI — never
  npx hyperframes" warnings in step-0-capture.md and step-6-validate.md.
2026-05-21 11:08:51 -07:00
ukimsanov a1ffb6e7bf feat(skill): website-to-hyperframes — concept-first authoring + per-beat read protocol
Rewrite of the website-to-hyperframes skill that came out of 11
evaluation rounds. The honest read of those evals: prose-only
guidance had hit its ceiling — sub-agents kept reporting "0 errors,
looks good" without doing the work, producing slideshow-quality
videos with mismatched brand colors, missing logos, and beats that
didn't serve the storyboard. This restructure addresses the
failure modes that real videos showed, not theoretical ones.

**Step structure (replaces 7-step layout with concept-first 6-step)**

Old: capture → design → script → storyboard → vo → build → validate
New: capture → design → brief → storyboard → vo → build → validate

The brief step (Step 2) is new: a conversation-shaped step that
aligns message + audience + arc before any beat-writing happens.
Concept-first throughout — message → arc → beats that serve the arc
→ which assets and techniques bring each beat to life.

**Step 0 (capture)**

- "View the contact sheets — carefully, every cell, not a glance"
  closes the failure mode where agents reported "viewed the contact
  sheet" after one scroll and later wrote beats referencing assets
  that didn't exist or missed the brand logo.
- Names the right artifacts to read in order (tokens.json →
  design-styles.json → asset-descriptions.md → fonts-manifest.json),
  with read-on-demand guidance for the rest.

**Step 1 (design)**

- DESIGN.md authoring guide. Restored component CSS sections
  (Component Stylings, Spacing & Layout, Depth & Elevation) that
  earlier batches over-collapsed.

**Step 2 (brief)**

- Strategy/messaging step. Clear instruction for "Surprise me" /
  minimal direction: state the minimum context (where the video
  runs, who it's for) and proceed bold.

**Step 3 (storyboard + script)**

- Concept gate at the top — answer "what makes this video distinct"
  before writing beat 1.
- Brand-floor MUST rules (logo in opener + closer; signature visual
  somewhere in the video).
- Captured assets (SVG logos, illustrations, hero art, gradients)
  are first-class beat content alongside composed UIs — many of
  them carry beats outright. The constraint is only that you start
  from the message, not the asset inventory.

**Step 4 (vo)**

- TTS ranking: HeyGen first (auto word timestamps), ElevenLabs
  second, Kokoro free. Audio timing reconciliation gate: if actual
  audio duration ≠ storyboard planned ±15%, rescale beats or trim
  script before Step 5.

**Step 5 (build) + beat-builder-guide.md**

- Sub-agent template now pastes brand values inline rather than
  telling the sub-agent to re-read DESIGN.md. Targeted file reads
  with specific sections + line ranges.
- "Patterns that ARE shots" affirmative list (captured logo
  draw-on, hero illustration push-in, captured screenshot with
  parallax layers, kinetic typography over captured asset).
- Webpage-mimicry patterns (full CSS browser chrome, parked-camera
  composition, ±2px breathing motion) marked ⚠ rather than  —
  fine when the storyboard genuinely calls for them as the subject.
- Required cinematography per beat: shot type, camera move, depth
  strategy, purpose.

**Step 6 (validate) — per-beat read protocol**

This replaces the previous "spawn verify-beats CLI" gate. A grep
of composition HTML can catch structural lies (missing hex codes,
wrong asset paths) but it can't catch boring beats, off-screen
logos, GSAP timelines that only cover the first 2 seconds, or
camera moves that don't match the storyboard. Those failures only
surface when somebody opens the file and reads it.

Per-beat verdict template names the brand hex codes used, captured
asset paths referenced, headline `font-size`, GSAP timeline
coverage, and storyboard alignment. Critic sub-agent scores a
"Captured asset utilization" dimension specifically so the eval
captures whether captured SVGs/illustrations carried beats or got
recreated as divs.

**Asset bundle**

- 20 Pixabay-licensed SFX files with `CREDITS.md` documenting
  provenance. SFX assignment moved to Step 3 (creative decision)
  so Step 5 implements rather than improvises.
- Capabilities reference + html-in-canvas-patterns updated:
  Three.js 0.181.2 + ESM jsm imports, mulberry32 seeded PRNG for
  deterministic shatter, 24-effect text-animation catalog
  referenced (catalog itself lands in the hyperframes-skill PR).
- Visual vocabulary rewritten: replaces user-word lookup tables
  with brand-first derivation across 6 axes; user words land as
  modifiers, not replacements.
2026-05-21 11:08:51 -07:00