# Semantic String Debt LLM Audit Findings

- result chunks: `16`
- findings: `19`

## `backend/app/modules/semantic_contract_router.py`

- `22-107` **P1 / semantic_string_judgment**
  - evidence: IMMOBILIZED_GAZE: frozenset[str] = frozenset({"dead", "unconscious", "severely_injured"}) ... if gaze not in IMMOBILIZED_GAZE: continue
  - why: The 'gaze_target' field is being overloaded to carry physical state information. The code uses a brittle list of natural-language strings to infer an 'immobilized' state, which subsequently triggers strict sanitization constraints such as 'forbid_state_polarity_rewrite'. This is a semantic judgment over an overloaded channel.
  - fix: Migrate to a dedicated structured field (e.g., 'subject_state.immobility_state') in the shot_staging schema as planned in the file's docstring, and use a canonical enum instead of inferring state from gaze targets.

## `backend/app/modules/t2i_visual_converter.py`

- `128-159` **P1 / blind_string_mutation**
  - evidence: 1. 각 씬 아래의 '★ 엔티티 목록'에 있는 이름만 [이름] 마커 사용 가능 ... 4. [] 마커는 참조 이미지 치환용이므로 목록 외 사용 시 시스템 오류 발생
  - why: The prompt establishes a contract where the LLM must identify entities and wrap them in exact bracketed markers ([Name]) for later blind string substitution. This is brittle because it relies on the LLM's ability to perfectly replicate names (including spacing) and assumes downstream code can safely replace these markers without context, which often leads to broken prompts or failed matches.
  - fix: Transition to a structured prompt assembly where the LLM identifies entity presence and their specific scene-contextual descriptions as separate fields, allowing the backend to inject visual references using stable IDs rather than performing substring replacement on natural language output.

## `backend/app/services/scene_generation_coordinator.py`

- `718-719` **P1 / semantic_string_judgment**
  - evidence: if shot_name and shot_name.lower() not in var_t2i.lower(): var_t2i = f"[Camera: {shot_name}] {var_t2i}"
  - why: This code performs a case-insensitive substring check on the natural-language T2I prompt (var_t2i) to decide whether to mutate it by prepending a camera directive. This is brittle because the same semantic meaning (the shot type) can be expressed in many ways in the prompt (e.g., 'CU' vs 'Close Up'), leading to redundant or conflicting instructions if the pattern match fails.
  - fix: Pass the shot_name as a separate structured parameter to the generation pipeline or use a more robust semantic check to determine if the camera directive is already present.

## `prompts/_base/entity_extractor_v2/9.202605130226/system.md`

- `97-101` **P2 / llm_closed_list_instruction**
  - evidence: allowed_space_keys 는 controlled vocab 안에서 선택: main / kitchen / rooftop / stairs / yard / exterior / office.
  - why: The LLM is instructed to map arbitrary scenario locations to a hard-coded list of sub-space types. This is a closed-world semantic classifier applied to open-world story text, which will fail or lose detail for scenarios involving spaces not in the list (e.g., 'bedroom', 'cave', 'bridge').
  - fix: Transition to a more flexible or descriptive key generation strategy, or move the classification logic to a stage that can handle a broader ontology.

## `prompts/_base/entity_extractor_v2/9.202605130226/turn_entity_detail.md`

- `10-18` **P1 / llm_closed_list_instruction**
  - evidence: "Passport-style ID photo, head and upper chest visible, ... plain white background.", "Photorealistic cinematic establishing shot, ... no people, no vehicles, no objects.", "Photorealistic product photo, isolated object, ... plain neutral background."
  - why: The prompt forces all open-world entities into three rigid visual templates (Passport, Establishing Shot, Product Photo) based on their type. This acts as a closed-list semantic classifier for visual identity, which may bias or incorrectly represent entities that do not fit these specific photographic metaphors (e.g., non-humanoid characters, abstract locations, or complex props).
  - fix: Replace rigid templates with descriptive goals (e.g., 'isolate the entity against a neutral background') or allow the LLM to select from a broader, more flexible set of visual styles appropriate for the entity's nature.

- `21-23` **P2 / schema_or_enum_drift**
  - evidence: "kind": "single_space", "kind": "multi_space", "system prompt 의 controlled vocab 따라"
  - why: The prompt explicitly references a 'controlled vocab' from the system prompt and hardcodes specific enum values ('single_space', 'multi_space') into the instructions. This creates a synchronization risk where changes to the central schema or system prompt may not be reflected here, leading to validation failures.
  - fix: Ensure these enum values are derived from a central SOT and passed into the prompt as variables, or use a shared schema definition that the LLM is instructed to follow.

## `prompts/_base/location_consistency/2.202604201230/system.md`

- `5` **P1 / semantic_string_judgment**
  - evidence: `[L##: 설명]` 블록이 location의 유일한 시각 정보입니다
  - why: The system relies on a brittle bracketed string pattern ([L##: description]) within natural language prompts to identify and isolate location-specific visual information, implying downstream regex or substring dependency.
  - fix: Pass location descriptions as structured metadata or separate prompt segments rather than relying on pattern-matching within a single prompt string.

- `11` **P1 / blind_string_mutation**
  - evidence: 이 문장은 나중에 scene_detail이 t2i_prompt에 그대로 삽입하므로
  - why: The prompt establishes a contract for blind string insertion of generated prose into a downstream T2I prompt. This bypasses structured validation and risks breaking prompt syntax or introducing semantic conflicts.
  - fix: Use a structured templating system or a dedicated prompt assembly step that validates the generated description before integration into the final T2I prompt.

## `prompts/_base/outlook_extractor/11.202603311724/phase1.md`

- `16` **P2 / semantic_string_judgment**
  - evidence: 사람이 탑승하거나 착용하는 인간형 기계장치(메카, 파워드슈트, 강화복, 갑옷 로봇 등)도 아웃룩으로 추출
  - why: This rule forces a semantic mapping where specific physical object categories (mecha, power suits) are treated as 'outlooks' (clothing). This is a non-obvious semantic instruction that biases how the LLM categorizes complex entities into the clothing schema.
  - fix: Allow the schema to handle 'equipment' or 'mechanical_shell' as distinct categories rather than overloading the 'outlook' field with mechanical entities.

- `22-26` **P1 / llm_closed_list_instruction**
  - evidence: 사람 형상이 아닌 캐릭터: 동물, 뱀, 곤충 떼, 박쥐 떼, 물체, 차량 등 / 사람 형상인 캐릭터: 인간, 인간형 요괴/괴물, 뱀파이어, 좀비 등 ... 비인간형 캐릭터는 아웃룩이 필요 없으므로 outlooks에서 제외하세요
  - why: The prompt uses a closed list of specific examples (insect swarms, bat swarms, vampires, zombies) to instruct the LLM on a binary semantic classification (humanoid vs non-humanoid). This classification directly controls entity membership in the 'outlooks' schema, creating a brittle semantic boundary based on specific tropes that may bias or fail for other non-humanoid types.
  - fix: Define a formal 'entity_type' in the character schema and move the classification logic to a dedicated stage or use a more robust semantic definition that doesn't rely on a list of specific creature examples.

## `prompts/_base/scene_extractor_v2/18.202605150955/system.md`

- `44-52` **P2 / schema_or_enum_drift**
  - evidence: normal, montage, flashback, dream, voiceover, transition
  - why: These scene types function as a semantic enum for classification but are defined only as a list in the prompt instructions. If downstream code or other prompt stages expect these exact strings, it creates a synchronization risk without schema enforcement.
  - fix: Define these scene types in a central JSON schema enum and reference that schema in the prompt to ensure consistency across the pipeline.

- `47` **P1 / semantic_string_judgment**
  - evidence: (<몽타주> 표시 또는 빠른 컷 전환)
  - why: The prompt instructs the LLM to classify a scene as 'montage' based on the presence of a specific string marker ('<몽타주>') in the input scenario text, which is a brittle pattern-based semantic judgment.
  - fix: Pass the scene type or montage status as a structured metadata field from the upstream parser instead of relying on the LLM to detect string markers in natural language.

- `58-60` **P1 / semantic_string_judgment**
  - evidence: V.O., 전화 통화, 무전, 방송 음성 / "<visible_body_name>(<remote_identity_name>)"
  - why: The prompt uses a list of keywords (V.O., phone call, etc.) and a specific parenthetical string pattern to determine physical entity visibility. This relies on the LLM performing string-based semantic routing to include or exclude entities from the visual frame.
  - fix: Use structured entity state flags (e.g., is_offscreen, is_voice_only, is_remote_possession) in the input payload rather than asking the LLM to infer visibility from screenplay notations or name patterns.

## `prompts/_base/scene_extractor_v2/18.202605150955/turn_scene_detail.md`

- `34-38` **P1 / semantic_string_judgment**
  - evidence: 얼굴/형태 식별 불가 인물 — short_id 사용 금지: 실루엣, 그림자, 창문 반사, 역광, 안개 속 등으로 인물의 얼굴이나 신체 형태를 식별할 수 없는 경우 C##O## short_id를 사용하지 마세요.
  - why: This instruction requires the LLM to perform a semantic classification of the visual scene (identifying silhouettes, shadows, etc.) to decide whether to suppress technical identifiers (short_id). This logic couples visual interpretation with technical payload routing, which can lead to inconsistent ID enforcement if the LLM's interpretation of 'silhouette' or 'fog' varies.
  - fix: Pass a structured 'visibility_state' or 'is_silhouette' flag in the character-outlook mapping and instruct the LLM to omit the short_id based on that explicit flag rather than inferring it from the scene text.

- `57-63` **P2 / llm_closed_list_instruction**
  - evidence: 카메라 기법 이름을 T2I 텍스트에 그대로 쓰지 마세요... 'soft_light_intimate' → 'soft warm light from one side, shallow depth of field blurring the background'
  - why: The prompt contains a hardcoded mapping of technical enums (e.g., soft_light_intimate, dutch_angle) to specific natural language descriptions. This creates a maintenance burden and potential drift between the system's technical vocabulary and the prompt's translation logic.
  - fix: Provide the descriptive text directly in the input data (e.g., in a camera_config object) instead of asking the LLM to translate technical strings into prose based on a list in the prompt.

- `82-85` **P2 / scenario_dependent_prompt**
  - evidence: `<region-derived demonym> police officer`, `<region-style apartment>`, `<region-style convenience store>`
  - why: These instructions force the LLM to use specific linguistic templates for regional/cultural markers. This biases the generation towards a specific structure and may result in unnatural phrasing or 'hallucinated' cultural markers if the 'region' cue is not well-defined in the source scenario.
  - fix: Allow the LLM to describe the region naturally based on the provided world-building context rather than enforcing a specific bracketed template for every entity.

## `prompts/_base/visual_world_rules/6.202605021400/rules_schema.json`

- `9` **P2 / schema_or_enum_drift**
  - evidence: "rule_type": {"type": "string", "description": "규칙 유형 (possession, transformation, ghost, time_period, costume, technology 등)"}
  - why: The schema defines a semantic taxonomy (possession, ghost, etc.) within a string description rather than using a formal JSON enum. This creates an unenforced contract that downstream logic likely relies on for visual or behavioral routing.
  - fix: Convert the rule_type field into a formal JSON enum if the categories are used for downstream logic, or move the examples to a separate documentation field if they are purely illustrative.

- `17-21` **P2 / scenario_dependent_prompt**
  - evidence: "예: A의 영혼이 B의 몸에 전이된 경우 A는 물리적 존재가 아님"
  - why: The description contains a concrete scenario-specific trope (soul transfer/possession) to explain physical presence logic. This can bias the LLM's reasoning towards specific supernatural genres instead of maintaining a neutral, abstract definition of physical presence.
  - fix: Replace the specific trope example with an abstract definition of physical presence (e.g., 'whether the entity occupies physical space and interacts with the environment').

## `prompts/_base/visual_world_rules/6.202605021400/system.md`

- `51` **P2 / llm_closed_list_instruction**
  - evidence: rule_type은 다음 중 선택: possession, transformation, ghost, projection, superpower, body_deformation, time_period, costume, technology, other
  - why: The LLM is instructed to classify diverse, open-world narrative phenomena into a fixed set of categories. This rigid classification can fail to capture the nuances of unique story elements or force them into ill-fitting buckets like 'other', potentially leading to incorrect downstream visual processing if those categories drive specific rendering logic.
  - fix: Transition to a more flexible tagging system or allow the LLM to provide a 'category_name' and 'category_description' pair instead of selecting from a hardcoded list.
