"""Merge-gate pinning tests (PR #73): the shot_spec cast-line preamble is SAFE.

Live evidence: take4 (2026-06-10) ran cast-line output through the full
production verify/normalize/bind path and rendered. These tests pin that
contract so the worry can never silently become true.
"""
from recoil.pipeline._lib.author_strategies import AUTHOR_STRATEGIES
from recoil.pipeline._lib.dispatch_payload import _normalize_authored_timecodes
from recoil.pipeline._lib.prose_validator import Severity, verify_authored_prose
from recoil.pipeline._lib.shot_primitive import ShotPrimitive


AUTHORED = (
    "Jade is a wiry female salvager, short red hair, grimy tank top, breather collar.\n"
    "\n"
    "[0:00-0:03] Wide shot down the empty corridor. Lights flicker. No one moves.\n"
    "\n"
    "[0:03-0:06] Tight insert. Jade lifts her left wrist into frame; the counter pulses.\n"
)


def _primitive():
    return ShotPrimitive(
        shot_id="EP001_TEST",
        scene_index=1,
        shot_type="WIDE",
        target_editorial_duration_s=6.0,
        intent="test",
        camera_side="A",
        screen_direction="left-to-right",
        char_ids=["JADE"],
        timing_segments=[{"duration_s": 3.0}, {"duration_s": 3.0}],
    )


def test_cast_line_preamble_passes_verify():
    strategy = AUTHOR_STRATEGIES[("seeddance-2.0", "r2v_multi", "shot_spec")]
    results = verify_authored_prose(AUTHORED, _primitive(), strategy)
    blocks = [r for r in results if r.severity == Severity.BLOCK]
    assert blocks == [], f"cast-line preamble must not BLOCK: {blocks}"


def test_cast_line_preamble_survives_normalization():
    normalized = _normalize_authored_timecodes(AUTHORED, _primitive())
    assert normalized.splitlines()[0].startswith("Jade is a wiry female salvager")
    assert "[0:00-0:03]" in normalized and "[0:03-0:06]" in normalized
