# Copyright 2026 Umbra Tools (umbratools.com) # SPDX-License-Identifier: Apache-2.0 """Guard tests for the character-discovery prompt's over-detection rules. These rules exist because discovery was missing obvious speakers (characters identified only by a comparative/ordinal designation, e.g. "the tallest", "the oldest" in a crowd of six) and producing polluted names ("Walking tallest"). If someone rewrites CHARACTER_DISCOVERY_PROMPT.md and drops them, these fail. """ from __future__ import annotations from pathlib import Path import pytest from umbraaudio.analysis.character_discovery import ( PROMPT_PATH, CharacterDiscoverer, ) @pytest.fixture(scope="module") def prompt() -> str: d = CharacterDiscoverer.__new__(CharacterDiscoverer) d._prompt_template = None return d._load_prompt() def test_prompt_loads_and_renders(prompt: str) -> None: # The real code path uses .replace(), not .format(), because the JSON schema # block contains literal braces. rendered = prompt.replace("{known_speakers_section}", "(Aksenzo, Hallr)") assert "{known_speakers_section}" not in rendered assert len(rendered) > 5000 def test_rule_8_every_speaking_line_is_a_speaker(prompt: str) -> None: assert "Rule 8: Every Speaking Line Is a Speaker" in prompt # Must name comparative/ordinal designations explicitly. for designation in ["the tallest", "the shortest", "the youngest", "the oldest"]: assert designation in prompt, f"missing designation example: {designation}" # Must state the over-detection bias. low = prompt.lower() assert "still list both" in low, "must instruct to list both when unsure" def test_rule_9_name_hygiene(prompt: str) -> None: assert "Rule 9: Name Hygiene" in prompt low = prompt.lower() assert "narration verbs" in low # The concrete bug this rule fixes. assert "Walking tallest" in prompt # Internal labels must never end up in a name. assert "(Scene 2)" in prompt def test_unidentified_covers_designations(prompt: str) -> None: low = prompt.lower() assert "designation" in low # Must forbid upgrading a designation into a guessed proper name. assert "never becomes" in low or "not upgrade" in low def test_prompt_file_is_markdown() -> None: assert PROMPT_PATH.suffix == ".md" assert PROMPT_PATH.exists()