Skip to content

fix(styles): make the anime-ghibli playbook loadable again - #468

Open
bbudaedu wants to merge 1 commit into
calesthio:mainfrom
bbudaedu:fix/playbook-schema-overlay-vocabulary
Open

fix(styles): make the anime-ghibli playbook loadable again#468
bbudaedu wants to merge 1 commit into
calesthio:mainfrom
bbudaedu:fix/playbook-schema-overlay-vocabulary

Conversation

@bbudaedu

@bbudaedu bbudaedu commented Aug 3, 2026

Copy link
Copy Markdown

The defect

load_playbook("anime-ghibli") raises a ValidationError on current main. Because lib/checkpoint.py::_validate_style_playbook fails closed, that takes down every run using the style:

from lib.checkpoint import init_project
init_project("demo", title="Demo", pipeline_type="animation",
             pipeline_dir=tmp, style_playbook="anime-ghibli")
clean-professional     init_project OK
anime-ghibli           init_project FAILED: CheckpointValidationError
    Unknown or invalid style_playbook 'anime-ghibli'.
    Available playbooks: ['clean-professional', 'flat-motion-graphics',
                          'premium-minimalist', 'anime-ghibli', 'minimalist-diagram'].

The playbook is returned by list_playbooks() and offered by name in pipeline_defs/animation.yaml, so the error names it as an available alternative to itself. A run that selects it cannot write a checkpoint at all.

There is a quieter half too: VideoCompose._build_theme_from_playbook("anime-ghibli") swallows the load error and returns {}, so no themeConfig reaches Remotion and the style silently falls back to the default dark theme at render time.

The repair

Four distinct schema violations. Each was repaired on the side the evidence pointed to — widen the schema where a shipped renderer feature backs the key, conform the playbook where it is only vocabulary drift:

Violation Side repaired Evidence
overlays.section_title schema The Overlay union in remotion-composer/src/Explainer.tsx renders section_title/stat_reveal/hero_title/provider_chip. The schema allowed stat_card/key_term/code_blocknot one of the types the renderer supports. Added all four, plus accent on overlay_style to match the renderer's accentColor prop.
asset_generation extras schema scene_type, multi_image_per_scene, images_per_scene, image_variation_guidance, default_particles, default_particle_color, default_vignette map onto real AnimeScene props (images, particles, particleColor, vignette).
identity.category: anime-illustration, pace: gentle playbook No code reads either field for behavior — identity.category is only ever written by lib/playbook_generator.py, and hyperframes_style_bridge reads motion.pace, not identity.pace. Using the canonical custom/slow beats expanding a public enum for one style.
color_palette.spirit_glow, golden_hour playbook Ad-hoc named colors with no consumer. Folded into the accent array; both hexes are preserved and still referenced by name in consistency_anchors.

After the fix, _build_theme_from_playbook("anime-ghibli") returns the Ghibli palette (primaryColor: "#2D5016", accentColor: "#FFB347", backgroundColor: "#0A0A1A", …) instead of {}.

Why it slipped, and the coverage that stops it recurring

tests/qa/test_07_playbook_intelligence.py:50 loads a hardcoded list of three playbook names — the three that existed when it was written. anime-ghibli and premium-minimalist were added later and never got load coverage.

tests/styles/test_playbook_catalog.py iterates the catalog instead, asserting the invariant that makes this class of bug impossible to ship:

  • every name list_playbooks() advertises also passes load_playbook()
  • every advertised playbook is accepted by init_project() — guarding the fail-closed checkpoint path specifically
  • the schema's overlay vocabulary covers every overlay type the renderer declares

Verification

  • 6 of the 15 new tests fail on the unfixed tree (anime-ghibli load, anime-ghibli init_project, and all four overlay types); all pass after.
  • Full suite: 964 → 979 passed, 10 skipped, no regressions.
  • make lint: passed.

🤖 Generated with Claude Code

`load_playbook("anime-ghibli")` raised a ValidationError, and since
`lib.checkpoint._validate_style_playbook` fails closed, that took down every
run using the style:

    init_project(..., style_playbook="anime-ghibli")
    CheckpointValidationError: Unknown or invalid style_playbook 'anime-ghibli'.
      Available playbooks: [..., 'anime-ghibli', ...]

The playbook is listed by `list_playbooks()` and offered by name in
`pipeline_defs/animation.yaml`, so the error even names it as an available
alternative to itself.

Four schema violations, repaired on whichever side the evidence pointed to —
widen the schema where a shipped renderer feature backs the key, conform the
playbook where it is only vocabulary drift:

- `overlays.section_title` — the schema allowed stat_card/key_term/code_block
  and none of the four overlay types `Overlay` in Explainer.tsx actually
  renders. Added section_title/stat_reveal/hero_title/provider_chip, plus
  `accent` on overlay_style to match the renderer's accentColor prop.
- `asset_generation` anime_scene knobs — scene_type, multi_image_per_scene,
  images_per_scene, image_variation_guidance, default_particles,
  default_particle_color, default_vignette all map onto real AnimeScene props.
  Added to the schema.
- `identity.category: anime-illustration` and `pace: gentle` — no code reads
  either field for behavior, so the playbook now uses the canonical `custom`
  and `slow` rather than expanding the enums for one style.
- `color_palette.spirit_glow` / `golden_hour` — ad-hoc named colors. Folded
  into the `accent` array; both hexes are preserved and still referenced by
  name in consistency_anchors.

With this, `_build_theme_from_playbook("anime-ghibli")` returns the Ghibli
palette instead of `{}`, so the style no longer silently falls back to the
default dark theme at render time.

Regression coverage iterates the catalog instead of a hardcoded list, which is
how this slipped: tests/qa/test_07_playbook_intelligence.py names the three
playbooks that existed when it was written, so anime-ghibli and
premium-minimalist never had load coverage. The new tests assert that every
playbook `list_playbooks()` advertises both validates and is accepted by
`init_project`, and that the schema's overlay vocabulary tracks the renderer's.

Verified: 6 of the new tests fail on the unfixed tree; full suite goes
964 -> 979 passed with no regressions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant