hyperframes: add HTML/CSS/GSAP as a parallel composition runtime

Separates creative grammar (renderer_family) from technical engine
(render_runtime) so HyperFrames can stand alongside Remotion as a
first-class runtime instead of masquerading as a Remotion sub-case.
Locks runtime choice at proposal stage and enforces it end-to-end: the
schemas require it, video_compose routes by it, the reviewer fails
closed on silent swaps, and a parametrized contract test walks every
pipeline manifest to ensure each planning-stage skill explains the
conversation to the user. Adds hyperframes_compose (scaffold/lint/
validate/render/doctor/add_block), a playbook -> CSS style bridge, and
vendored HyperFrames Layer 3 skills from commit d291358, pinned via
PROVENANCE.md for future re-sync. Final_review now records
render_runtime_used and runtime_swap_detected so compose lies are
catchable after the fact.
This commit is contained in:
calesthio
2026-04-18 18:37:00 -07:00
parent 9e17263aa5
commit b4f7ec4eee
118 changed files with 10128 additions and 126 deletions
+10
View File
@@ -27,6 +27,7 @@ def score_slideshow_risk(
scenes: list[dict[str, Any]],
edit_decisions: dict[str, Any] | None = None,
renderer_family: str | None = None,
render_runtime: str | None = None,
) -> dict[str, Any]:
"""Score slideshow risk across 6 dimensions.
@@ -34,12 +35,19 @@ def score_slideshow_risk(
scenes: Scene list from scene_plan artifact.
edit_decisions: Optional edit_decisions artifact for transition analysis.
renderer_family: Optional renderer family for cinematic claim verification.
render_runtime: Optional render runtime (remotion/hyperframes/ffmpeg).
Passed through so dimension scoring can reason about runtime-specific
indicators when it's useful. Scoring logic is currently
runtime-neutral — a text-heavy HyperFrames composition is just as
slideshow-y as a text-heavy Remotion one — but the parameter is
part of the contract so callers record runtime alongside family.
Returns:
{
"average": float,
"verdict": str,
"dimensions": {dimension_name: {"score": float, "reason": str}},
"render_runtime": str | None,
}
"""
if not scenes:
@@ -47,6 +55,7 @@ def score_slideshow_risk(
"average": 5.0,
"verdict": "fail",
"dimensions": {},
"render_runtime": render_runtime,
}
dimensions = {
@@ -74,6 +83,7 @@ def score_slideshow_risk(
"average": round(average, 2),
"verdict": verdict,
"dimensions": dimensions,
"render_runtime": render_runtime,
}