mirror of
https://github.com/calesthio/OpenMontage.git
synced 2026-08-05 15:20:40 +08:00
Implementation spec: governance, decision intelligence, theme system, and E2E bug fixes
Implements the 2026-04-02 transformation spec (Phases 1-8) and fixes all critical bugs found during 5-pipeline E2E testing. Governance & Decision Intelligence: - Pipeline-specific stage order in checkpoint (replaces global STAGES list) - Provider scoring engine (lib/scoring.py) with 7-dimension weighted ranking - Decision log artifact enforced at proposal/idea stage across all 10 pipelines - Delivery promise classifier prevents silent motion-to-still downgrades - Structured shot language in scene_plan schema (camera, lens, lighting, DOF) - Variation checker and slideshow risk scorer block samey output before render - Creative intake, capability extension, and creative-intake meta skills - Final self-review artifact with 5 mandatory checks before presenting output - Source media review contract for user-supplied footage Render & Theme System: - Remotion AnimatedBackground now derives colors from playbook (no more hardcoded dark blue fintech gradient on every video) - video_compose builds custom ThemeConfig from playbook YAML colors/fonts — custom playbooks flow through to Remotion automatically - Explainer component wires theme to all child components (charts, cards, etc.) - resolveAsset() handles absolute paths on Windows/Unix via file:// URIs - RENDERER_FAMILY_MAP synced with actual Remotion compositions Critical Bug Fixes: - Windows npx subprocess: run_command() resolves .cmd wrappers via shutil.which() - Silent renderer downgrade: Remotion failure now returns explicit error with options instead of silently falling back to FFmpeg - .env inline comment parsing strips trailing # comments from API keys - concat_path UnboundLocalError in video_compose finally block - audio_mixer and showcase_card capture=True kwarg bug - Selector estimate_cost() calls fixed (_select_tool -> _select_best_tool) - asset_manifest schema expanded with provider, license, subtype fields - screen-demo subtitle_gen moved from required to optional tools - Duration drift detection in post-render final review (>25% warns)
This commit is contained in:
@@ -85,3 +85,53 @@ def get_stage_review_focus(manifest: dict, stage_name: str) -> list[str]:
|
||||
if stage["name"] == stage_name:
|
||||
return stage.get("review_focus", [])
|
||||
return []
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Capability-Extension Enforcement
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class ExtensionNotPermitted(PermissionError):
|
||||
"""Raised when a capability extension is used but not permitted by the pipeline."""
|
||||
|
||||
|
||||
def check_extension_permitted(
|
||||
manifest: dict,
|
||||
extension_type: str,
|
||||
) -> None:
|
||||
"""Enforce that a capability extension is permitted by the pipeline manifest.
|
||||
|
||||
Args:
|
||||
manifest: Loaded pipeline manifest dict.
|
||||
extension_type: One of 'custom_scripts', 'custom_playbooks',
|
||||
'custom_skills', 'custom_tools'.
|
||||
|
||||
Raises:
|
||||
ExtensionNotPermitted: If the extension is not allowed.
|
||||
"""
|
||||
valid_extensions = {"custom_scripts", "custom_playbooks", "custom_skills", "custom_tools"}
|
||||
if extension_type not in valid_extensions:
|
||||
raise ValueError(
|
||||
f"Unknown extension type {extension_type!r}. "
|
||||
f"Valid types: {sorted(valid_extensions)}"
|
||||
)
|
||||
|
||||
extensions = manifest.get("extensions", {})
|
||||
if not extensions.get(extension_type, False):
|
||||
raise ExtensionNotPermitted(
|
||||
f"Pipeline {manifest.get('name', 'unknown')!r} does not permit "
|
||||
f"{extension_type}. Set extensions.{extension_type}: true in the "
|
||||
f"pipeline manifest to allow this."
|
||||
)
|
||||
|
||||
|
||||
def get_permitted_extensions(manifest: dict) -> dict[str, bool]:
|
||||
"""Return the extension permission flags for a pipeline."""
|
||||
defaults = {
|
||||
"custom_scripts": False,
|
||||
"custom_playbooks": False,
|
||||
"custom_skills": False,
|
||||
"custom_tools": False,
|
||||
}
|
||||
extensions = manifest.get("extensions", {})
|
||||
return {k: extensions.get(k, v) for k, v in defaults.items()}
|
||||
|
||||
Reference in New Issue
Block a user