Adds the new atelier-mode bespoke piece (Library of Alexandria) to the
showcase block, right after THE LAST BANANA. Removes the prior 'Into the
Abyss' anime piece to keep the section focused.
Showcases the doctrine shipped in #203: every scene crafted from scratch
with no shared components — the signature device (the candle + Burning
Counter) appears in only one of five scenes (the climax), per the
scene-distinctness rule in skills/meta/bespoke-composition.md.
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.)
Closes the remaining three atelier audit gaps.
F1 — atelier projects live under repo-root projects/<slug>/ (the
established OpenMontage convention), not under remotion-composer/.
_render_via_atelier now auto-stages source files into
remotion-composer/projects/<slug>/ via mtime-skip copy when the entry
isn't already under the composer tree. Originally tried a directory
junction, but webpack walks up from the entry's REAL location to
resolve node_modules — junctions get dereferenced and module resolution
fails. Copy keeps source-of-truth under projects/, is invisible to the
user's project view, and is cheap (typical project is a few small .tsx
files). Output stays wherever output_path says. effective_entry is
returned in tool data for transparency.
F3 — scripts/scaffold_atelier_project.py generates the engine
boilerplate (index.tsx / Root.tsx / Composition.tsx / art-direction.md /
props template / README) ONLY. No creative content emitted — the
Composition.tsx is a deliberately blank black placeholder with prominent
TODOs. This removes the friction that nudged agents back to templated
mode while making it impossible to ship the scaffold unauthored (review
correctly flags black frames / silent audio as 'revise'). Verified
end-to-end: scaffold → render → review fires the right warnings.
F5 — schemas extended to know about atelier:
- decision_log: 'composition_mode' added to category enum.
- proposal_packet.production_plan: composition_mode + art_direction.
- edit_decisions: composition_mode + bespoke{entry, composition_id,
art_direction, props_path, public_dir, scale, crf, concurrency}.
- final_review.checks: 'atelier' block (stock_reuse_detected,
offending_imports[], art_direction_declared, art_direction).
- final_review.recommended_action: 're_author' added.
- final_review.transcript_comparison: allow null word_accuracy /
transcript_matches_script (pre-existing latent bug surfaced here).
Both pass and fail shapes of the atelier render's final_review now
validate against the updated schema.
Closes the two biggest gaps from the atelier audit: hero bespoke renders
were skipping every automated quality gate, and the templated→atelier
inversion was advisory rather than enforced.
F6 — _render_via_atelier now runs the full _run_final_review (technical
probe + visual spotcheck + audio spotcheck + duration drift + transcript
comparison) plus two atelier-specific doctrine checks:
- stock_reuse_check: rglobs the bespoke project tree for imports from
the stock creative registry (src/components, src/Explainer, etc.).
Any hit fails the render with status="fail" and names the offending
file — the doctrine bypass is now mechanically caught.
- art_direction_check: requires edit_decisions.bespoke.art_direction.
Missing → warning surfaced in final_review.issues_found; forcing
function for step 1 of skills/meta/bespoke-composition.md.
Verified end-to-end on the compound-snowball proof render: positive case
status=pass, atelier checks clean; negative case (deliberate stock import
+ missing art_direction) returns status=fail with both findings named.
F7 — skills/meta/reviewer.md gets a "Composition Authoring Mode Review"
section that enforces the inversion at every stage:
- proposal: composition_mode must be a presented decision with both
options; hero briefs default to atelier; templated for hero requires
an explicit sanctioned reason.
- scene_plan/edit: any stock cut.type in an atelier piece is CRITICAL;
bespoke.{entry, composition_id, art_direction} required.
- compose: consumes final_review.checks.atelier from F6; mandates a
recorded distinctness review (the human taste call the tool can't
automate — its absence is itself CRITICAL).
- publish: blocks ship on any unresolved atelier finding.
Engine knowledge stays reusable; creative components don't.
Introduce a hand-authored, project-local Remotion render path that bypasses
the cut-schema and the stock scene-type registry, for hero/bespoke videos
that must look distinct from one another.
- video_compose: composition_mode="atelier" (or renderer_family="bespoke")
routes to _render_via_atelier, which renders a project-local entry under
remotion-composer/projects/<slug>/ with an optional per-project public_dir
(skips copying the bloated shared public/). No cut-schema, no stock registry.
- skills/meta/bespoke-composition.md: routing skill — art direction
(visual-style) -> motion principles (Disney 12) -> engine mechanics
(remotion-best-practices + stock components read only as a mechanics codex)
-> atelier render. Doctrine: reuse engine knowledge, never creative components.
- AGENT_GUIDE: "Composition Authoring Mode" (templated vs atelier); default
atelier for hero work; scene-type catalog reframed as a mechanics codex.
- animation-runtime-selector + INDEX: authoring-mode-first pointers.
- base_tool.run_command: decode subprocess output as UTF-8/replace (Windows
cp1252 crashed the reader thread on Remotion's Unicode progress output).
- .gitignore: remotion-composer/projects/ (throwaway bespoke compositions).
The GSAP family README described HyperFrames as a 'future' engine ('if the
parallel HyperFrames engine gets wired in', 'becomes a day-1 skill', 'Future
hyperframes_compose tool — if added'). Every other artifact (AGENT_GUIDE.md,
skills/core/hyperframes.md, skills/INDEX.md) treats HyperFrames as a fully
production composition runtime, and hyperframes_compose is a registered tool.
Update the HyperFrames references to present-tense production reality. Also add
a scope note: this directory has no SKILL.md and is not a loadable skill — it
is a navigation map for the sibling gsap-* skills, which removes the ambiguity
about why it is not loadable via agent_skills[].
Closes#61
Three skill directories ship a long-form upstream AGENTS.md alongside their
loadable SKILL.md:
.agents/skills/flux-best-practices/AGENTS.md
.agents/skills/vercel-composition-patterns/AGENTS.md
.agents/skills/vercel-react-best-practices/AGENTS.md
None were referenced by their parent SKILL.md, skills/INDEX.md, AGENT_GUIDE.md,
or any pipeline manifest, leaving their authority scope undefined relative to
the repository-root AGENTS.md (override / extend / ignore?).
Reference each from its SKILL.md with explicit scope: the AGENTS.md is
supplementary upstream reference material for that skill only, SKILL.md is the
loadable entry point and the authority, and it does not override or extend the
root AGENTS.md / AGENT_GUIDE.md. Preserves the vendored content while removing
the ambiguity.
Refs #61
runway (estimate_cost/estimate_runtime/execute) defaulted to gen4_turbo and
higgsfield (execute) defaulted to kling_3.0, while both schemas advertise
seedance_2.0 as model.default. Omitting model under-quoted cost (runway 6x:
$0.25 vs $1.50) and silently generated a different model than advertised,
violating the Decision-Communication / cost-accuracy contract.
Root cause was a default duplicated across schema + 3 methods that drifted.
Collapse it to a single _DEFAULT_MODEL constant referenced everywhere.
Add tests/tools/test_provider_model_defaults.py to lock each tool's
estimate default to its schema default and guard the execute path.
The video-reference-analyst capability audit pre-locked Remotion as the
default composition engine ('Remotion is the default ... Never default to
FFmpeg when Remotion is available'). Because the analyst skill runs first
in any reference-led flow, this silently locked the runtime before the user
was ever offered a choice — violating the 'Present Both Composition Runtimes
(HARD RULE)' in AGENT_GUIDE.md, which forbids silently picking a default and
treats Remotion and HyperFrames as parallel, non-ranked runtimes.
It also omitted HyperFrames from the engine list entirely, so it was never
surfaced as an option in the reference-led path.
Update Step 2 (Capability Audit) to:
- add HyperFrames to the audited runtime list
- remove the 'Remotion is the default / preferred' framing
- defer engine selection to the AGENT_GUIDE 'Present Both' gate
- keep FFmpeg scoped to standalone ops, not composition
Closes#60
tools/video/green_screen_composite.py imports numpy at module level (and
declares "python:numpy" as a dependency), but numpy was missing from
requirements.txt. Because registry.discover() imports every tool module,
a fresh `make setup` followed by the mandatory preflight crashes with
ModuleNotFoundError: No module named 'numpy'. Add numpy>=1.24.
Also gitignore *.onnx/*.onnx.json so Piper TTS voice models fetched at
runtime (e.g. en_US-lessac-medium.onnx, ~60MB) aren't accidentally
committed to the repo root.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The repo had no .github issue or PR templates, so bug reports arrived
with inconsistent detail and questions landed on the tracker instead of
Discussions.
Add GitHub community templates:
- ISSUE_TEMPLATE/bug_report.yml: structured form (OS, pipeline, runtime,
repro, expected vs actual, logs)
- ISSUE_TEMPLATE/feature_request.yml: problem / solution / alternatives
- ISSUE_TEMPLATE/config.yml: disables blank issues and routes questions,
ideas, and show-and-tell to the existing Discussions categories
- PULL_REQUEST_TEMPLATE.md: summary, linked issue, testing, checklist
Additive only; no source changes.
Closes#189
Without a .gitattributes, line-ending normalization depends on each
contributor's local core.autocrlf. On Windows checkouts this can
materialize text files — and shell scripts like render-demo.sh — with
CRLF, which breaks script shebangs and produces noisy cross-platform
diffs.
Add a root .gitattributes that:
- defaults all text files to LF (* text=auto eol=lf)
- pins shell scripts, Makefile and .env.example to LF explicitly
- keeps .bat/.cmd as CRLF
- marks image/video/audio/font assets as binary so Git never
normalizes or diffs them
Only the policy file is added; existing files are intentionally left
unrenormalized to keep this change reviewable.
Closes#187
On Windows, passing --props and the JSON path as two separate CLI
arguments causes Remotion to mis-parse the value due to platform quote
escaping, failing with "neither valid JSON nor a file path to a valid
JSON file". Switch to the --props=<path> equals form, which Remotion
recommends for file paths and which works consistently across
platforms.
Fixes#172
- Add get_torch_device() helper in _shared.py: cuda > mps > cpu
- Guard MPS detection for torch builds lacking torch.backends.mps
- Check both is_built() and is_available() for MPS
- Route load_diffusers_pipeline() to resolved device instead of hardcoded cuda
- Use float32 on CPU (float16 is emulated/unreliable), float16 on MPS, bfloat16 on CUDA
- Guard enable_model_cpu_offload() to CUDA-only; fall back to .to(device) on MPS
- Enable attention slicing for MPS memory safety
- Add inspect-based signature guard for device= arg on RealESRGANer/GFPGANer
- Update install_instructions on all LOCAL_GPU tools to mention MPS/Apple Silicon
tests/qa/test_08_end_to_end.py runs at module import, so pytest fails
collection with CheckpointValidationError: the Stage 5 edit_decisions
fixture omits render_runtime, which edit_decisions.schema.json lists as
required. Per AGENT_GUIDE the runtime is locked at proposal and carried
through edit unchanged, so the fixture now sources it from the same
proposal_packet["production_plan"]["render_runtime"] ("remotion")
instead of hardcoding an unrelated value, keeping the fixture internally
consistent with the proposal it builds on.
Google's TTS and Imagen tools advertised service-account auth
(GOOGLE_APPLICATION_CREDENTIALS) but only ever authenticated with an API
key string, so users with a service-account JSON could not use either tool.
google_tts.get_status() also over-reported availability when the JSON was
set, then failed at execute() — a silent-availability bug.
Separately, both hand-rolled _load_dotenv parsers kept inline comments as
values, so after `cp .env.example .env` every keyed tool falsely reported
"available" with no real credentials.
Changes:
- Add tools/google_credentials.py: lazy google-auth Bearer-token helper.
- google_tts: authenticate via Cloud TTS Bearer token when only a service
account is configured; make get_status() honest.
- google_imagen: route service-account auth to Vertex AI
({location}-aiplatform.googleapis.com) with project/location resolution,
alongside the existing AI Studio API-key path.
- Fix both _load_dotenv parsers to strip inline comments (quote-aware).
- Add google-auth to requirements; document the new env vars in .env.example.
- .gitignore: never commit GCP service-account key files.
Verified locally with a real service account: TTS produced a valid MP3 and
Imagen produced a valid 1408x768 PNG via Vertex AI. Existing test suite
passes (2 unrelated pre-existing failures only).
Closes#131
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>