feat(atelier): forbid hero-component spine; captions/text dedup rule (F12 + F9)

F12 — Hero-component spine is a templating anti-pattern. The first
atelier proof (alexandria-fire) leaned on a single candle as scaffolding
under every scene with different text below — same hero, different
caption — which is exactly the "branded slides" pattern atelier was
supposed to break. The signature device is meant to appear in ONE or
at most two beats (typically the climactic moment), not as the visual
scaffolding of every scene. Each scene must earn its own composition:
a different primary visual subject, a different scale, a different motion
register. Doctrine added as step 1.5 in skills/meta/bespoke-composition.md
("Plan each scene as its own composition") plus a reviewer
scene_distinctness gate enforced at compose stage — the reviewer samples
one representative frame per scene and refuses to pass if two or more
scenes share their primary visual subject.

F9 — Captions/on-screen-text dedup. When a SerifLine reads the script
verbatim AND auto-captions emit the same text, the piece looks amateurish
even when the rest is beautiful. Rule added under engine mechanics: decide
once per piece whether captions add meaning (numbers, names, translations,
attributions) or are accessibility subtitles echoing narration — never
both for the same content. Reviewer gate at compose stage compares active
caption text against on-screen text in the same time window.

Both gates are CRITICAL; the publish-stage check was updated to expect
six (was four) resolved atelier findings.

Self-audit of alexandria-fire under the new rules: 4 of 5 scenes share
the candle as their primary visual subject — would now flag CRITICAL
scene_distinctness and require re-planning. (Re-author the piece in a
follow-up; the doctrine is the deliverable here.)
This commit is contained in:
calesthio
2026-06-27 11:36:51 -07:00
parent 0f10381f2b
commit f9f86ac9f8
2 changed files with 47 additions and 3 deletions

View File

@@ -43,6 +43,37 @@ direction each time. Write it down (a short `art-direction.md` in the project) a
Ask yourself: *what visual metaphor belongs to this subject that I have not used before?* If the
answer resembles a past piece, you haven't found the direction yet.
### 1.5 Plan each scene as its own composition — no hero-component spine
The most insidious form of templating sneaks back in at the *scene* level: pick one striking
visual (a candle, a browser frame, a score ring), then re-use it every scene with different
text underneath. The piece feels custom because the hero is custom — but every scene is
mechanically the same composition. That's branded slides, not a film. **Don't do that.**
The signature device named in your art-direction is meant to appear in **one or at most two
beats** — typically the climactic moment — not as the visual scaffolding of every scene. It
earns its weight by being scarce.
For each scene in the plan, answer concretely *before* writing code:
- **What is this scene's primary visual subject?** It must be *different* from the previous
scene's. A character. A diagram. A piece of evidence. A landscape. A typographic moment. The
signature device. A void. Each scene's primary subject is its job.
- **Why does this beat exist?** What does it do for the story that no other beat does? If you
can collapse two scenes into one without losing meaning, you should.
- **How does it differ visually from the scene before and after?** Different composition (rule
of thirds vs centered vs split). Different scale (intimate close vs wide field). Different
motion register (still vs busy). Different palette emphasis. Different type treatment.
- **If you removed the signature device from this scene, would the scene still work?** If yes,
the signature device probably doesn't belong in this scene — it's there as filler. Cut it.
The reviewer enforces this as a "scene_distinctness" check (see
`skills/meta/reviewer.md` → Composition Authoring Mode Review): a recorded inventory of
each scene's primary subject + first frame, and an explicit answer to "do any two scenes
share their primary visual subject?" Yes ⇒ CRITICAL ⇒ re-plan.
The corollary: the per-scene plan is a *first-class artifact*, not implied. Write it down
(in `art-direction.md` or a sibling `scenes.md`) before authoring `Composition.tsx`.
### 2. Decide the motion language — principles, not presets
Reach for **principle** skills, never finished animations:
- **`framer-motion`** and **`lottie-bodymovin`** — Disney's 12 principles (anticipation, staging,
@@ -75,6 +106,13 @@ Recurring mechanics that bite if you don't know them:
- **GSAP-in-Remotion**: use a `paused` timeline and `.seek(frame/fps)` — never `requestAnimationFrame`
— so frames render deterministically.
- **Fonts**: `loadFont()` from `@remotion/google-fonts/<Name>` at module scope, once.
- **Captions vs on-screen text — pick one role, never both for the same content.** Decide
once per piece, before authoring: are captions adding meaning the spoken words can't carry
(a number, a name, a translation, a quote attribution), OR are they accessibility subtitles
echoing the narration? If your scene already displays a SerifLine that reads the script
verbatim, do NOT also emit an auto-caption with the same text — the doubled phrase looks
amateurish even when the rest of the scene is beautiful. Empty `captions=[]` in props, or
scope captions only to scenes where the on-screen text differs from what's being said.
### 5. Render through the atelier path (project-local, throwaway)
Bespoke scenes are **throwaway and project-local** — they never enter the shared `src/` registry.

View File

@@ -327,11 +327,17 @@ The templated→atelier inversion (`AGENT_GUIDE.md` → "Composition Authoring M
1. The compose stage's `final_review.checks.atelier` block must exist. If absent: **CRITICAL** — "Atelier render skipped doctrine checks — `_render_via_atelier` returned without `atelier` checks; investigate tool wiring."
2. If `final_review.checks.atelier.stock_reuse_detected == true`: **CRITICAL** — "Stock-registry import inside bespoke project ({offending_imports[0].file} → {offending_imports[0].import}). Hand-author the scene; do not import from the stock src/."
3. If `final_review.checks.atelier.art_direction_declared == false`: **CRITICAL** — "Atelier render with no art-direction declaration. Set `edit_decisions.bespoke.art_direction` before re-render."
4. **Distinctness review (human-judged, mandatory).** Before approving the render, the reviewer must explicitly answer in the review record:
4. **Scene distinctness — no hero-component spine (mandatory record).** Sample one representative frame per scene (e.g. mid-window of each `props.sections[i]`) and answer in the review record:
- *Does each scene have a distinct primary visual subject?* If two or more scenes share their primary visual (same hero element merely re-captioned — the candle that never leaves, the browser frame on every beat, the score ring as scaffolding): **CRITICAL** — "Hero-component spine detected: scenes {ids} share their primary visual subject. Per `skills/meta/bespoke-composition.md` step 1.5, each scene must earn its own composition; the signature device belongs to one climactic beat, not as scaffolding. Re-plan the affected scenes."
- *Is the signature device named in `art_direction` actually present in at least one beat?* (no ⇒ CRITICAL, re-author or update the declaration to match what was actually built)
- *Is the signature device present in **most** beats?* (yes ⇒ CRITICAL — see hero-component-spine above; signature is meant to be scarce)
This check cannot be skipped silently; absence of a recorded scene-by-scene inventory is itself **CRITICAL** ("scene_distinctness inventory not recorded").
5. **Captions / on-screen text dedup (mandatory check).** Compare the active caption text to any on-screen text rendered in the same time window:
- If they are the same content (caption echoes the scene's title/headline that the narration is already reading aloud): **CRITICAL** — "Caption duplicates on-screen text at {t}s ('{text}'). Decide once per piece whether captions add meaning (numbers, names, translations) or are accessibility subtitles; do not do both for the same line. Either clear `captions=[]` for these scenes or remove the redundant on-screen SerifLine."
6. **Distinctness review (human-judged, mandatory).** Before approving the render, the reviewer must explicitly answer in the review record:
- *"Could this video be any other product's video?"* (yes ⇒ CRITICAL, re-author art direction)
- *"Does its visual language reuse a look from a prior piece I've made?"* (yes ⇒ CRITICAL, re-author)
- *"Is the signature device named in `art_direction` actually present in the rendered frames?"* (no ⇒ CRITICAL, re-author or update the declaration to match what was actually built)
Distinctness is taste-call territory the tool can't automate; reviewer absence on this question is itself a **CRITICAL** finding ("distinctness review not recorded").
### At publish stage (when composition_mode == "atelier"):
1. All four atelier compose-stage findings above must show `resolved` in the review record. Any unresolved: **CRITICAL** — "Cannot publish atelier piece with unresolved doctrine or distinctness findings."
1. All six atelier compose-stage checks above (existence of `atelier` block, stock_reuse, art_direction_declared, scene_distinctness, captions/text dedup, human distinctness review) must show `resolved` in the review record. Any unresolved: **CRITICAL** — "Cannot publish atelier piece with unresolved doctrine or distinctness findings."