Merge remote-tracking branch 'origin/main' into codex/repair-pr-442

# Conflicts:
#	.env.example
This commit is contained in:
calesthio
2026-08-13 09:07:59 -07:00
105 changed files with 5907 additions and 403 deletions

View File

@@ -0,0 +1,31 @@
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[2]
def _read(relative_path: str) -> str:
return (REPO_ROOT / relative_path).read_text(encoding="utf-8")
def test_music_plans_discover_all_music_capabilities() -> None:
instruction_files = [
"AGENT_GUIDE.md",
"skills/pipelines/cinematic/idea-director.md",
"skills/pipelines/cinematic/proposal-director.md",
"skills/pipelines/documentary-montage/idea-director.md",
"skills/pipelines/explainer/proposal-director.md",
]
for relative_path in instruction_files:
text = _read(relative_path)
for capability in ("music_library", "music_search", "music_generation"):
assert f'get_by_capability("{capability}")' in text, (
f"{relative_path} omits the {capability!r} music source"
)
def test_explainer_directors_do_not_reference_fictitious_submit_functions() -> None:
for stage in ("idea", "script", "scene"):
text = _read(f"skills/pipelines/explainer/{stage}-director.md")
assert "handle_explainer_" not in text

View File

@@ -6,6 +6,7 @@ import json
import pytest
from lib.checkpoint import (
CANONICAL_STAGE_ARTIFACTS,
CheckpointValidationError,
HISTORY_DIRNAME,
PROJECT_MARKER_FILENAME,
@@ -27,6 +28,22 @@ def _minimal_script() -> dict:
}
def _approve_predecessors(tmp_path, project_id, pipeline_type, *stages) -> None:
from tests.contracts.test_phase0_contracts import sample_artifact
for stage in stages:
artifact_name = CANONICAL_STAGE_ARTIFACTS[stage]
write_checkpoint(
tmp_path,
project_id,
stage,
"completed",
artifacts={artifact_name: sample_artifact(artifact_name)},
pipeline_type=pipeline_type,
human_approved=True,
)
class TestGateEnforcement:
"""GI-4: gated stages cannot be completed without approval evidence."""
@@ -39,6 +56,9 @@ class TestGateEnforcement:
)
def test_awaiting_human_is_the_correct_gate_state(self, tmp_path):
_approve_predecessors(
tmp_path, "proj", "animated-explainer", "research", "proposal"
)
path = write_checkpoint(
tmp_path, "proj", "script", "awaiting_human",
artifacts={"script": _minimal_script()},
@@ -51,6 +71,9 @@ class TestGateEnforcement:
assert cp["human_approval_required"] is True
def test_completed_with_approval_passes(self, tmp_path):
_approve_predecessors(
tmp_path, "proj", "animated-explainer", "research", "proposal"
)
path = write_checkpoint(
tmp_path, "proj", "script", "completed",
artifacts={"script": _minimal_script()},
@@ -84,6 +107,9 @@ class TestCheckpointHistory:
"""Superseded checkpoints are archived, not destroyed."""
def test_overwrite_archives_previous(self, tmp_path):
_approve_predecessors(
tmp_path, "proj", "animated-explainer", "research", "proposal"
)
write_checkpoint(
tmp_path, "proj", "script", "awaiting_human",
artifacts={"script": _minimal_script()},

View File

@@ -0,0 +1,19 @@
from pathlib import Path
from dotenv import dotenv_values
REPO_ROOT = Path(__file__).resolve().parents[2]
def test_env_example_does_not_turn_comments_into_credentials() -> None:
"""A fresh copy of .env.example must leave every documented key unset."""
values = dotenv_values(REPO_ROOT / ".env.example")
false_credentials = {
key: value
for key, value in values.items()
if isinstance(value, str) and value.lstrip().startswith("#")
}
assert false_credentials == {}

View File

@@ -174,10 +174,14 @@ class TestPhase2ErrorHandling:
# Either succeeds (provider available) or fails gracefully
assert isinstance(r, ToolResult)
def test_diagram_gen_empty_boxes(self):
def test_diagram_gen_empty_boxes(self, tmp_path):
tool = DiagramGen()
if tool.get_status() == ToolStatus.AVAILABLE:
r = tool.execute({"diagram_type": "boxes", "boxes": []})
r = tool.execute({
"diagram_type": "boxes",
"boxes": [],
"output_path": str(tmp_path / "empty-boxes.png"),
})
assert isinstance(r, ToolResult)

View File

@@ -9,6 +9,7 @@ import builtins
import base64
import os
import shutil
from types import SimpleNamespace
from pathlib import Path
from unittest.mock import MagicMock, patch
@@ -571,16 +572,26 @@ class TestVeoVideo:
called_kwargs = mock_client.models.generate_videos.call_args[1]
assert called_kwargs["image"] is not None
def test_vertex_ai_mode_rejection(self):
def test_vertex_ai_mode_requires_inline_video_bytes(self):
tool = VeoVideo()
mock_client = MagicMock()
mock_client.vertexai = True
if hasattr(mock_client, "_api_client"):
delattr(mock_client, "_api_client")
mock_client.models.generate_videos.return_value = SimpleNamespace(
done=True,
error=None,
response=SimpleNamespace(
generated_videos=[
SimpleNamespace(video=SimpleNamespace(video_bytes=None))
]
),
)
with (
patch.dict(os.environ, {"GEMINI_API_KEY": "test_key"}),
patch("google.genai.Client", return_value=mock_client),
patch(
"tools.google_credentials.get_genai_client",
return_value=mock_client,
),
):
inputs = {
"prompt": "cinematic shot",
@@ -589,7 +600,7 @@ class TestVeoVideo:
res = tool.execute(inputs)
assert res.success is False
assert res.error is not None
assert "only supported using the Gemini Developer API" in res.error
assert "without inline bytes" in res.error
def test_missing_local_image_paths(self):
tool = VeoVideo()

View File

@@ -0,0 +1,9 @@
"""Contracts for the category vocabulary used by shipped pipelines."""
from lib.pipeline_loader import load_pipeline
def test_documentary_pipeline_uses_a_schema_supported_category() -> None:
manifest = load_pipeline("documentary-montage")
assert manifest["category"] == "documentary"

View File

@@ -0,0 +1,28 @@
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[2]
def test_video_scene_honors_hard_cut_tokens_and_backing_color() -> None:
source = (REPO_ROOT / "remotion-composer/src/Explainer.tsx").read_text(
encoding="utf-8"
)
assert '["cut", "none"].includes((transitionIn || "").toLowerCase())' in source
assert '["cut", "none"].includes((transitionOut || "").toLowerCase())' in source
assert "transitionIn={cut.transition_in}" in source
assert "transitionOut={cut.transition_out}" in source
assert "sceneDurationSeconds={cut.out_seconds - cut.in_seconds}" in source
assert "Math.round(sceneDurationSeconds * fps)" in source
assert "durationInFrames - transitionFrames" in source
assert "backgroundColor={cut.backgroundColor}" in source
def test_cinematic_fades_are_bounded_by_each_scene_duration() -> None:
source = (REPO_ROOT / "remotion-composer/src/CinematicRenderer.tsx").read_text(
encoding="utf-8"
)
assert "Math.round(scene.durationSeconds * fps)" in source
assert "durationInFrames - fadeOutFrames" in source

View File

@@ -0,0 +1,30 @@
import ast
from pathlib import Path
import pytest
REPO_ROOT = Path(__file__).resolve().parents[2]
RUNTIME_FILES = [
"lib/checkpoint.py",
"lib/pipeline_loader.py",
"schemas/artifacts/__init__.py",
"styles/playbook_loader.py",
]
@pytest.mark.parametrize("relative_path", RUNTIME_FILES)
def test_pipeline_contract_files_use_explicit_utf8(relative_path: str) -> None:
path = REPO_ROOT / relative_path
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
bare_opens = []
for node in ast.walk(tree):
if not isinstance(node, ast.Call):
continue
if not isinstance(node.func, ast.Name) or node.func.id != "open":
continue
if not any(keyword.arg == "encoding" for keyword in node.keywords):
bare_opens.append(node.lineno)
assert bare_opens == [], f"bare open() calls at lines {bare_opens}"