# Semantic String Debt LLM Audit Findings

- result chunks: `864`
- findings: `863`

## `backend/app/api/v1/entities.py`

- `433-434` **P1 / semantic_string_judgment**
  - evidence: _re.finditer(r'\[\[([^\]]+)\]\+\[([^\]]+)\]\]', t2i_text)
  - why: Extracts character and outlook names from natural language prompt text using a specific bracket pattern. This makes entity resolution and reference attachment dependent on string formatting within open-world prose rather than structured metadata.
  - fix: Deprecate the name-based bracket pattern in favor of the ID-based pattern (C##O##) and ensure the LLM generates structured entity references.

- `792` **P2 / scenario_dependent_prompt**
  - evidence: "'Photorealistic cinematic still.' 같은 스타일 접두어도 그대로 유지하세요."
  - why: Hardcodes a specific visual style example ('Photorealistic cinematic still') in the translation prompt. This biases the LLM and should be part of a project-level style SOT.
  - fix: Inject style preservation rules and examples from the project's style settings (ProjectSettings.style_rules_json) instead of hardcoding them in the system prompt.

- `818` **P2 / scenario_dependent_prompt**
  - evidence: "'Photorealistic cinematic still.' 같은 스타일 접두어도 그대로 유지하세요."
  - why: Hardcodes a specific visual style example ('Photorealistic cinematic still') in the translation prompt. This biases the LLM and should be part of a project-level style SOT.
  - fix: Inject style preservation rules and examples from the project's style settings (ProjectSettings.style_rules_json) instead of hardcoding them in the system prompt.

## `backend/app/api/v1/images.py`

- `107-109` **P1 / semantic_string_judgment**
  - evidence: returns images whose prompt_used contains 'outlook_id:{outlook_id}'
  - why: The API documentation (and the underlying service logic it describes) indicates that filtering images by 'outlook_id' is performed via a substring check on the 'prompt_used' field. This field contains the natural-language prompt text. Using substring matching on prompt text to determine entity membership or drive data routing is brittle and violates the principle of using structured data for entity associations, especially when the result determines visible entity membership.
  - fix: Replace the substring search with a structured database relationship (e.g., a foreign key or a link table) between ImageAsset and EntityCanon to track which outlooks are present in an image, rather than embedding and parsing technical IDs within the prompt string.

## `backend/app/core/asset_readiness.py`

- `305` **P1 / semantic_string_judgment**
  - evidence: _STATE_LABELS = ("dead", "severely_injured", "unconscious")
  - why: The pipeline relies on a hardcoded list of semantic tropes to decide if a character requires a specific visual state variant. This creates a fragile dependency on exact string matches for open-world story states that should be defined in a structured SOT.
  - fix: Centralize character states in a shared SOT or Enum that is used by both the staging logic and the readiness validator.

- `435-440` **P1 / semantic_string_judgment**
  - evidence: gaze = ca.get("gaze_target", "") ... if gaze in ("dead", "severely_injured", "unconscious")
  - why: The code overloads the 'gaze_target' field to carry character health/life states. This is a semantic mismatch where a technical property is used to drive visual asset routing based on string patterns, which will fail if the upstream LLM or staging logic uses synonyms or different fields.
  - fix: Use a dedicated 'character_state' field in the manifest for character conditions and ensure it uses a controlled vocabulary.

## `backend/app/core/bg_state_vocab.py`

- `26-38` **P1 / llm_closed_list_instruction**
  - evidence: STATE_CLASS_ENUM: FrozenSet[str] = frozenset({"normal", "quiet", "busy", "busy_exit", "ransacked", "clean_after", "blood_scene", "intrusion", "arrival", "evidence_display", "dream_or_vision_state"})
  - why: This hardcoded list of semantic state classifiers is forced onto the LLM via prompts. It contains genre-specific tropes (e.g., 'blood_scene', 'ransacked') that bias the system toward crime/thriller scenarios and prevent arbitrary story generation.
  - fix: Move state class definitions to a scenario-specific configuration or a structured world SOT that can be injected into the prompt dynamically.

- `128-136` **P1 / llm_closed_list_instruction**
  - evidence: LOCATION_SPACE_KEY_VOCAB: FrozenSet[str] = frozenset({"main", "kitchen", "rooftop", "stairs", "yard", "exterior", "office"})
  - why: This list restricts the physical space types a location can have to a specific set of domestic/office environments. It is hardcoded in the core logic and forced into the entity extractor prompt, limiting the system's ability to handle diverse settings (e.g., sci-fi, nature).
  - fix: Define allowed space keys within the world/location schema in the SOT rather than as a global hardcoded constant.

## `backend/app/core/entity_protection.py`

- `70` **P1 / blind_string_mutation**
  - evidence: short_id.split("O")[0] if short_id and "O" in short_id else (short_id or "")
  - why: This logic attempts to extract a base ID from a composite (e.g., C01O01 -> C01) but fails for bare IDs starting with 'O' (e.g., O01 becomes an empty string) or containing 'O'. This directly contradicts the docstring on line 69 which states O## bare IDs should remain unchanged, leading to lost entity references in the protection cascade.
  - fix: Use a specific regex pattern (e.g., r'^(C\d+)O\d+$') to identify and split composite IDs, or verify the ID starts with 'C' and the 'O' is at a valid index before splitting.

- `181-182` **P2 / semantic_string_judgment**
  - evidence: if etype in ("location", "outlook"):
  - why: Hardcoded semantic entity types are used to bypass the low-frequency skip logic. This creates a hidden dependency on specific category names for pipeline routing and protection behavior that should be driven by the entity schema or a central SOT.
  - fix: Define protection behavior as a property of the entity type in a central schema or metadata rather than hardcoding strings in the logic.

## `backend/app/core/errors.py`

- `103-104` **P1 / semantic_string_judgment**
  - evidence: off-camera/off-screen/화면 밖 phrase
  - why: The system uses a hardcoded list of natural language phrases to determine entity visibility (dual SOT reconciliation). This pattern-based semantic judgment is fragile for open-world scenario descriptions.
  - fix: Replace natural language phrase detection with structured visibility attributes in the staging schema or use a dedicated LLM classification step for SOT reconciliation.

## `backend/app/core/frame_spatial_contract.py`

- `322-324` **P1 / semantic_string_judgment**
  - evidence: label_present = bool(label) and label in prompt_lower; zone_present = any(v in prompt_lower for v in zone_variants)
  - why: The phrase_diagnostic function uses substring matching to verify if entity labels and spatial keywords (from ZONE_PHRASES and DEPTH_PHRASES) appear in the generated t2i_prompt. This is a brittle semantic judgment on open-world natural language text, which is explicitly forbidden when used for validation or routing decisions, as it cannot reliably handle linguistic variation.
  - fix: Replace substring-based prompt validation with a structured LLM evaluation step or a vision-language model (VLM) check that can semantically verify the prompt's content against the spatial contract.

## `backend/app/core/name_matcher.py`

- `51-74` **P1 / blind_string_mutation**
  - evidence: _BRACKET_PATTERN = re.compile(r"[\(\[（［【〈《「『].*$")
  - why: The code blindly strips all text following any bracket character to create a 'bare' key for entity matching. This assumes that bracketed content is always a non-essential variant suffix (e.g., 'Character (Soul)'), which may not hold true for all open-world story names and can lead to incorrect entity resolution or collisions.
  - fix: Instead of blind regex stripping, use a structured entity registry where variants are explicitly linked to base entities in the database, or use a context-aware LLM resolution step for non-exact matches.

- `137-141` **P1 / semantic_string_judgment**
  - evidence: if not _BRACKET_PATTERN.search(raw): ... bare = normalize_name(raw)
  - why: The indexing logic uses the presence of brackets as a semantic marker to distinguish between 'base' and 'variant' entities, deciding that entities with brackets should 'yield' their bare name to those without. This hardcodes a specific naming convention into the entity resolution pipeline.
  - fix: Move entity relationship logic (base vs. variant) into the database schema or a structured world-rule SOT rather than inferring hierarchy from string patterns during index construction.

## `backend/app/core/pipeline_gate.py`

- `127` **P2 / scenario_dependent_code**
  - evidence: EntityCanon.short_id == "O00"
  - why: Hardcoded magic string 'O00' is used to identify a 'Null Outlook' to exclude it from composite requirements. This assumes a specific naming convention in the world-building data that may not be consistent across all scenarios or future schema versions.
  - fix: Use a boolean flag (e.g., is_null_outlook) or a system-level constant/enum on the EntityCanon model instead of a hardcoded short_id.

- `144-156` **P1 / semantic_string_judgment**
  - evidence: ImageAsset.prompt_used.like("%composite:%"), re.search(r'composite:([a-f0-9-]+):([a-f0-9-]+)', p)
  - why: The pipeline determines if a composite image is complete by regex-parsing the prompt_used field. This couples technical metadata (character/outlook IDs) to the natural language prompt text. If the prompt generation format changes or the field is cleaned for production, the gate logic will fail to identify existing assets, blocking the pipeline.
  - fix: Store character/outlook associations in a structured metadata column (JSON) or dedicated link table on the ImageAsset model instead of parsing the prompt string.

- `238-239` **P1 / semantic_string_judgment**
  - evidence: ImageAsset.prompt_used.like("%outlook_id:%")
  - why: The pipeline status reporting uses a different regex pattern ('outlook_id:') than the gate check ('composite:') to identify completed assets. This inconsistency in parsing natural-language prompt fields for technical status leads to drift between the gate and the UI status.
  - fix: Unify asset identification using structured metadata fields rather than multiple inconsistent string patterns in the prompt field.

## `backend/app/core/planning_doc_context.py`

- `44-47` **P1 / scenario_dependent_code**
  - evidence: if section == "characters_text" and not self.is_first_episode: return ""
  - why: This hardcodes a semantic routing decision that assumes character descriptions and visual traits are only necessary for the first episode. In a multi-episode pipeline, this leads to visual and narrative drift as subsequent episodes lose access to the foundational planning context.
  - fix: Remove the hardcoded episode-based filtering or move it to a configurable context-management policy within the pipeline's structured world/rule SOT.

## `backend/app/core/ref_contract_validator.py`

- `49-89` **P1 / semantic_string_judgment**
  - evidence: _CHARACTER_TOKENS, _BACKGROUND_TOKENS, _OBJECT_TOKENS, _GENERIC_VERB_TOKENS, _GENERIC_NOUN_TOKENS
  - why: These are hardcoded noun and verb lists used to classify the semantic meaning of 'from the reference' phrases in open-world prompts. This pattern-based approach to deciding whether a phrase refers to a character, background, or object is used to trigger or skip validation logic, which can lead to incorrect fail-fast errors (RefContractError) or missed validations based on arbitrary string patterns.
  - fix: Move the classification of prompt reference targets to a structured LLM analysis step or have the prompt generator emit explicit metadata indicating the target of each reference phrase.

- `91-190` **P1 / semantic_string_judgment**
  - evidence: _classify_window, _has_generic_instruction_signal, classify_from_the_reference
  - why: These functions implement semantic classification of open-world prompt text using substring checks and nearest-token heuristics. This logic decides the 'type' of a reference (character/object/background) which directly routes validation behavior in the visual generation pipeline.
  - fix: Replace the heuristic window-based classification with a robust semantic parser or an LLM-based classification step that provides structured output for reference targets.

## `backend/app/core/step_catalog.py`

- `49` **P1 / semantic_string_judgment**
  - evidence: applicability: str       # always | disabled | on_demand | if_*
  - why: The use of an 'if_*' string pattern for step applicability suggests that the pipeline routes story or visual steps by parsing string prefixes against scenario attributes. This is a pattern-based semantic judgment that couples step execution to arbitrary scenario-state strings rather than a structured rule system.
  - fix: Replace the string-pattern applicability with a structured condition object or an explicit enum of supported scenario conditions.

- `59-62` **P2 / scenario_dependent_code**
  - evidence: (zoom_in_detail 등)를 읽어 user_prompt에 주입
  - why: The documentation for 'consumes_downstream' describes a mechanism where steps have hardcoded knowledge of specific visual semantic tokens (like 'zoom_in_detail') produced by other steps to mutate prompts. This creates tight coupling between steps based on open-world visual concepts.
  - fix: Use a structured visual State of Truth (SOT) or standardized attribute keys instead of hardcoding specific visual concept names in step-to-step dependencies.

## `backend/app/core/steps/analysis_steps_legacy.py`

- `129-132` **P2 / semantic_string_judgment**
  - evidence: low_importance = { e["name"] for e in entities_review if int(e.get("importance", 50)) < 10 and int(e.get("appearances", 0)) < 2 }
  - why: The code uses hardcoded numeric thresholds (importance < 10 and appearances < 2) to prune entities from the story world. This is a semantic judgment that can lead to the accidental removal of rare but critical plot elements (e.g., a unique artifact that appears once).
  - fix: Allow the LLM to explicitly flag entities for exclusion based on context, or move these thresholds to a configurable project-level setting.

- `810-817` **P1 / scenario_dependent_prompt**
  - evidence: 인물: 자기 물리적 몸으로 존재하는 인물만. 대사를 하더라도 빙의/원격접속 중이면 제외... 인물A가 인물B의 몸에 접속/빙의/라이드했다면
  - why: The prompt hardcodes specific sci-fi/fantasy tropes (possession, remote access, riding) as the primary logic for determining physical presence. This biases the LLM toward these specific scenarios and may lead to incorrect reasoning in stories with different metaphysical rules (e.g., ghosts, projections, or simple off-screen dialogue).
  - fix: Move these specific examples into a 'World Rules' or 'Presence Logic' section of the SOT (Source of Truth) rather than hardcoding them in the pipeline step's prompt template.

## `backend/app/core/steps/background_chain_planning_step.py`

- `18-93` **P1 / semantic_string_judgment**
  - evidence: FLOOR PLAN 블록 있으면 outdoor skip 금지 ... [FLOOR PLAN] 블록이 prepend되어 outdoor skip 룰 회피
  - why: The pipeline's visual routing (skipping outdoor scenes) is controlled by the presence of a specific string marker '[FLOOR PLAN]'. This is a pattern-based semantic judgment that should be handled via structured metadata rather than string-based triggers.
  - fix: Replace the string-based trigger with a structured boolean or enum in the location/scene schema (e.g., 'has_floor_plan_context') to drive the skip logic.

- `91` **P2 / scenario_dependent_code**
  - evidence: fp_rooftop_unit
  - why: The documentation uses a scenario-specific place/prop name ('rooftop_unit') as a concrete example for logic, which indicates domain-specific pollution in the pipeline's design documentation.
  - fix: Use generic placeholders (e.g., 'fp_group_01') in comments and documentation to maintain scenario-agnostic logic.

## `backend/app/core/steps/beat_shot_steps.py`

- `114-115` **P1 / scenario_dependent_code**
  - evidence: if r.get("rule_type") in ("possession", "projection", "ghost"):
  - why: Hardcodes specific story tropes ('possession', 'projection', 'ghost') to filter visual guidelines. This prevents the pipeline from correctly handling other metaphysical or physical rules (e.g., holograms, illusions) that might be defined in the world rules SOT.
  - fix: Replace the hardcoded list with a boolean flag in the rule schema (e.g., 'affects_physical_presence') or move the trope list to a centralized world-building configuration.

- `323-324` **P1 / scenario_dependent_code**
  - evidence: if r.get("rule_type") in ("possession", "projection", "ghost"):
  - why: Duplicate of the hardcoded trope filtering logic in the shot extraction step. It assumes only these specific tropes are relevant for determining physical presence in visual descriptions.
  - fix: Unify the rule filtering logic and drive it via structured metadata in the world rules rather than hardcoded string matching.

## `backend/app/core/steps/detail_steps.py`

- `252` **P1 / semantic_string_judgment**
  - evidence: _STATE_VARIANT_GAZE_VALUES = ("unconscious", "dead", "severely_injured")
  - why: The pipeline determines if a character requires a 'state variant' reference (e.g., a corpse model) by checking for specific string patterns in the open-world 'gaze_target' field. This semantic judgment routes reference attachment and validation logic based on hardcoded keywords rather than a structured state SOT.
  - fix: Introduce a structured 'character_state' or 'visual_variant' enum in the staging schema and use it to drive reference attachment logic instead of hijacking the gaze_target string.

- `1940` **P2 / semantic_string_judgment**
  - evidence: re.split(r'\s*[\(（]', name)[0].strip()
  - why: The code determines character variant relationships by parsing entity names for parentheses. This relies on a naming convention in open-world story text to decide entity membership and variant grouping, which affects LLM instructions for ID selection.
  - fix: Use a structured 'parent_entity_id' or 'is_variant_of' field in the EntityCanon model to define relationships explicitly.

- `2289` **P2 / scenario_dependent_prompt**
  - evidence: 긴장=어둡고 대비 강한, 슬픔=탈색/청색, 분노=적색 등
  - why: The prompt contains hardcoded domain tropes for color theory (e.g., sadness = blue, anger = red). These specific visual mappings should be emitted by a structured world/style SOT to allow for different artistic directions across scenarios.
  - fix: Move color-emotion mappings to a project-level visual style configuration or world rule SOT.

- `2867-2869` **P2 / blind_string_mutation**
  - evidence: re.sub(r"focus on\s+'s", "focus on the figure's", prompt)
  - why: The code performs blind string replacement to fix broken possessives in generated prompts, assuming the missing entity is always a 'figure'. This is a semantic visual decision made via regex that may be incorrect for non-human entities.
  - fix: Improve the ID removal logic to handle possessives contextually or use the entity's type (e.g., 'the prop's', 'the character's') from the context if a replacement is necessary.

## `backend/app/core/steps/director_steps.py`

- `121` **P2 / scenario_dependent_prompt**
  - evidence: "시각적 존재 판단 참고사항 (단, 카메라에 보이면 무조건 포함):\n"
  - why: Hardcoded prompt instructions in the code logic instead of the prompt management system. This makes it difficult to localize or adjust instructions for different scenario types.
  - fix: Move this instruction into the 'scene_director' prompt template or a structured SOT.

- `125-127` **P1 / scenario_dependent_code**
  - evidence: if r.get("rule_type") in ("possession", "projection", "ghost")
  - why: The step runner filters visual guidelines based on a hardcoded list of story-specific tropes ('possession', 'projection', 'ghost'). This is scenario-dependent logic that prevents the pipeline from supporting other visual rule types (e.g., 'hologram', 'disguise', 'magic') without code changes.
  - fix: Replace the hardcoded list with a generic check for the presence of a 'visual_guideline' field or use a metadata flag in the rules SOT to indicate director relevance.

## `backend/app/core/steps/entity_steps.py`

- `328` **P1 / scenario_dependent_code**
  - evidence: max_scenes=2
  - why: Hardcoded threshold for filtering entities based on scene frequency. This is a semantic judgment on entity importance (story membership) that should be configurable or derived from project-specific rules rather than fixed in the StepRunner.
  - fix: Move the frequency threshold to project configuration or a structured world-rule SOT.

- `453-486` **P1 / scenario_dependent_prompt**
  - evidence: user_prompt = ( ... "인물(character)은 다른 타입과 중복될 가능성이 거의 없으니 주로 배경/소품 간 중복을 확인하세요." )
  - why: The entity merging prompt is hardcoded in the StepRunner and contains a closed-list semantic heuristic ('characters don't overlap with props') that biases the LLM's judgment of open-world story entities. This violates the principle of keeping prompts in managed templates and keeping domain logic in SOTs.
  - fix: Externalize the prompt to a template file and move domain heuristics to a structured world-rule SOT.

## `backend/app/core/steps/image_steps.py`

- `638-666` **P1 / semantic_string_judgment**
  - evidence: STATE_DESCRIPTIONS = { "dead": "...", ... } and if gaze in self.STATE_DESCRIPTIONS:
  - why: The code performs semantic classification of character states by matching strings in the 'gaze_target' field against a hardcoded dictionary. This dictionary contains fixed visual tropes ('pale/ashen skin', 'bruises and cuts') that are injected into image prompts, bypassing the structured world SOT and forcing specific visual interpretations of open-world story states.
  - fix: Move character state visual definitions to a structured World SOT or Rulebook. The scenario analysis step should provide the state description or a reference to a rulebook entry rather than relying on hardcoded strings in the step runner.

## `backend/app/core/steps/location_consistency_step.py`

- `104` **P1 / semantic_string_judgment**
  - evidence: if name in heading:
  - why: Determines location-scene membership (story routing) via substring match on natural language headings. This is prone to false positives (e.g., 'Hall' matching 'Hallway') and directly affects the context provided to the LLM for visual consistency extraction.
  - fix: Enforce the use of structured IDs (present_entity_ids) from the director step. If a fallback is necessary, use regex with word boundaries and ensure the name is not a substring of other entities.

- `179` **P2 / semantic_string_judgment**
  - evidence: if summary.startswith("실패"):
  - why: Uses a specific Korean string prefix ('실패' meaning 'Failure') within a natural language summary field to drive failure counting and resume logic. This couples control flow to localized UI/summary text.
  - fix: Introduce a structured 'status' enum field in the location result schema to explicitly track success/failure states.

- `223-226` **P2 / semantic_string_judgment**
  - evidence: if k.startswith(f"{name}:") and isinstance(v, dict):
  - why: Resolves entity identity by matching names against dictionary keys with a prefix heuristic. This is brittle if entity names are substrings of each other (e.g., 'Room' vs 'Room 101').
  - fix: Use unique entity IDs (L##) as keys in the entity_details dictionary instead of relying on name-based string heuristics.

- `258-266` **P2 / llm_closed_list_instruction**
  - evidence: user_prompt += ( "- 포함: 크기·형태·재질·색상·구조적 디테일·고정 소품" )
  - why: Hardcodes a closed list of semantic categories for the LLM to include or exclude when extracting visual descriptions. This defines the 'visual consistency' logic in code rather than in a structured SOT or externalized prompt.
  - fix: Move these extraction rules and category lists into the externalized system_prompt file.

## `backend/app/core/steps/location_floor_plan_step.py`

- `714-734` **P1 / semantic_string_judgment**
  - evidence: for sep in (". ", ".\n", "\n\n"): idx = text.find(sep) ... return text[:idx + 1].strip()
  - why: The code performs a blind truncation of visual prompt text based on punctuation patterns to create a 'summary' used as a spatial reference for subsequent generations. This assumes the first sentence captures all necessary consistency constraints, which is an unreliable semantic judgment that can lead to visual drift in multi-room floor plans.
  - fix: Require the LLM to provide an explicit 'spatial_summary' field in its structured response, or use a dedicated summarization step that preserves key entities and layout constraints instead of relying on punctuation-based slicing.

## `backend/app/core/steps/render_prompt_card.py`

- `114-408` **P1 / semantic_string_judgment**
  - evidence: _ID_BODY_PART_TRIGGERS, _CONTINUITY_GENERIC_PERSON_NOUNS, _SPATIAL_CAMERA_LOW_TOKENS
  - why: These constants define closed lists of natural language phrases (including mixed English/Korean patterns) used as ground-truth for detecting open-world story and visual meaning (e.g., body part focus, double descriptions, or spatial inconsistencies). This logic drives visual routing and validation via pattern matching rather than structured metadata or LLM-based semantic analysis.
  - fix: Move semantic classification logic to a dedicated LLM-based validator or drive it from structured SOT metadata (e.g., framing_scale enums or entity-specific spatial rules) rather than hardcoded substring lists.

- `1141-1146` **P2 / scenario_dependent_prompt**
  - evidence: "role_hint_from_outfit": ["in worker uniform", "in fisher workwear", "in detective coat", "in business suit"]
  - why: These are scenario-specific tropes and outfit examples hardcoded into the prompt builder. They pollute the generic prompt card logic with work-specific nomenclature that should be emitted by a structured world/rule SOT or character metadata.
  - fix: Inject these role hints from a structured world-building SOT or character-specific metadata field rather than hardcoding them in the prompt builder.

- `1495-1498` **P1 / blind_string_mutation**
  - evidence: "replace the common-noun person reference inside fixed_elements[i].description (e.g. 'An Asian man' / 'a woman' / 'a figure') with the matched C## or C##O##"
  - why: This instructs the LLM to perform blind string replacement of natural language descriptions based on pattern matching. This approach is prone to errors, ignores semantic context, and relies on a closed list of nouns to identify entities in open-world text.
  - fix: Provide the LLM with structured entity mappings and instruct it to rewrite the description to incorporate the correct IDs semantically, rather than performing blind substitution.

## `backend/app/core/steps/scene_consistency_step.py`

- `65-80` **P1 / semantic_string_judgment**
  - evidence: _ELEMENT_ID_CLOSE_REGEX and _DESCRIPTION_CLOSE_KEYWORDS
  - why: Hardcoded lists of body parts (wrist, eye, etc.) and framing keywords are used to determine if a visual element is a 'close-up'. This semantic judgment is used to block the pipeline if a conflict is detected, replacing flexible LLM understanding with rigid string matching on open-world descriptions.
  - fix: Move framing classification to the LLM extraction phase as a structured field in the schema, or use a dedicated visual classifier instead of regex on natural language strings.

- `103-121` **P1 / semantic_string_judgment**
  - evidence: def _classify_framing(element: Dict[str, Any]) -> str:
  - why: This function implements the logic that maps arbitrary element descriptions and IDs to a 'close' vs 'full' framing category using the forbidden regex/keyword patterns. This drives the deterministic validator that can fail the entire scene.
  - fix: Deprecate this function in favor of a structured 'framing_type' field emitted by the LLM during the scene_consistency extraction step.

- `749-751` **P2 / scenario_dependent_prompt**
  - evidence: 사망/부상/의식불명 인물의 자세와 위치... 깨진 창문, 열린 문, 혈흔 등
  - why: The prompt contains specific scenario tropes (death, injury, bloodstains) as examples. This pollutes the LLM's context with specific imagery that may not be relevant to the current story, potentially biasing the extraction of fixed elements toward these tropes.
  - fix: Replace specific trope examples with generic categories of visual consistency (e.g., 'character physical state', 'environmental damage', 'static prop placement').

## `backend/app/core/steps/scene_context_loader.py`

- `266` **P2 / semantic_string_judgment**
  - evidence: if summary.startswith("실패"):
  - why: Uses a natural language prefix ('실패' for failure) in a summary field to decide whether to filter out visual context. This is a pattern-based semantic judgment on open-world text.
  - fix: Use a structured status field (e.g., 'status': 'failed') in the location_consistency checkpoint instead of parsing the summary string.

- `468-478` **P1 / semantic_string_judgment**
  - evidence: detect_offscreen_drift(char_visible, cam, ctx.name_by_short_id, ...)
  - why: The loader triggers a fail-fast error (VisibleStagingDriftError) based on semantic analysis of the 'camera_direction' natural language string (cam). This makes validation and routing decisions based on open-world text patterns rather than structured SOT data.
  - fix: The staging step should output structured visibility metadata (e.g., a list of off-screen entity IDs) to be used for drift detection, rather than parsing the 'camera_direction' NL string in the loader or validator.

## `backend/app/core/steps/scene_steps.py`

- `127-134` **P1 / semantic_string_judgment**
  - evidence: f"씬 내부의 장소 전환('- 장소명')이 아니라 씬 번호('숫자.') 패턴으로 분리해야 합니다."
  - why: The pipeline makes a semantic judgment about story structure (distinguishing between scene headings and place transitions) based on hardcoded string patterns ('- 장소명', '숫자.'). This logic is used to trigger retries and provide feedback to the LLM, which forces a specific screenplay format and prevents the system from correctly handling scenarios with alternative formatting conventions.
  - fix: Abstract screenplay formatting rules into a structured 'Script Style' SOT or project configuration. The validation logic should check against these configured rules rather than hardcoded string examples.

## `backend/app/core/steps/shot_cinematography_step.py`

- `131-134` **P1 / scenario_dependent_prompt**
  - evidence: user_prompt += ("\n[다양성 규칙] 같은 씬의 연속 shot에 동일한 촬영 기법을 배정하지 마세요. ...")
  - why: A visual diversity heuristic is hardcoded in the pipeline logic rather than being part of a structured SOT or the prompt template. This enforces a specific cinematic style (avoiding repetition) across all scenarios, which limits artistic flexibility and pollutes the code with domain-specific rules.
  - fix: Relocate the diversity rule and any visual style constraints to the 'shot_cinematography' prompt template or a style-specific SOT.

## `backend/app/core/steps/shot_dependency_step.py`

- `141` **P1 / semantic_string_judgment**
  - evidence: if prev["location"] != cur_loc:
  - why: This performs exact string comparison on 'primary_location' values which are natural-language strings from the scene_director LLM output. This drives visual reference attachment (routing), and will fail to link shots if the LLM produces minor variations in the location name (e.g., 'Living Room' vs 'Living room').
  - fix: Resolve the location name to a unique ID (L##) using the name_matcher and the entity_t2i manifest before comparison.

- `149` **P2 / scenario_dependent_code**
  - evidence: score = len(intersection) - len(char_complement) * 3 - len(non_char_complement)
  - why: The scoring logic uses a hardcoded heuristic to prioritize character consistency (3x weight) over other entities. This is a semantic visual rule that should be part of a structured visual strategy or SOT rather than embedded in the step implementation.
  - fix: Externalize weighting factors to a configuration or a visual rule SOT.

## `backend/app/core/steps/shot_dependency_t2i_step.py`

- `187` **P2 / schema_or_enum_drift**
  - evidence: detail_cp.get("data", detail_cp).get("scenes", detail_cp.get("scenes", []))
  - why: The code uses multiple fallback attempts to locate the 'scenes' list within the checkpoint, indicating an unstable or poorly defined schema for the scene_detail output. This makes the pipeline fragile to changes in upstream data structures.
  - fix: Standardize the checkpoint schema for scene_detail and use a direct, validated access path (e.g., detail_cp['data']['scenes']).

- `189` **P2 / schema_or_enum_drift**
  - evidence: shot_idx = s.get("_shot_index")
  - why: The use of a leading-underscore field name ('_shot_index') suggests reliance on internal or non-standard implementation details of an upstream step rather than a stable, public SOT schema.
  - fix: Ensure the upstream step (scene_detail) promotes the required index to a stable, public field name (e.g., 'shot_index') and update this consumer to use it.

## `backend/app/core/steps/shot_essence_extraction_step.py`

- `78-88` **P1 / scenario_dependent_code**
  - evidence: (전체 처리 X — Codex H1 회귀 가드)
  - why: The routing logic that filters scenes based on selection is explicitly justified by a project-specific ID ('Codex H1') in the comments. This suggests the pipeline's behavior for handling missing selections is being tuned for specific scenario regressions rather than following a universal world-rule SOT or configuration.
  - fix: Move routing policies (e.g., how to handle scenes missing from selection) to a project-agnostic configuration or a structured SOT that defines pipeline behavior for different project types.

- `191-192` **P1 / llm_closed_list_instruction**
  - evidence: "아래 샷들의 description을 essence/peripheral/atmospheric 3분류로 나누세요."
  - why: The code hardcodes a semantic classification task for open-world story text ('description') into a closed list of categories ('essence/peripheral/atmospheric'). This nomenclature is specific to the Phase 1b prompt strategy and directly drives visual routing (deciding what is prepended to the image prompt), but it is embedded in the Python logic rather than a structured prompt template or SOT.
  - fix: Move the classification instructions and category definitions into the system_prompt template or a structured SOT, and use the schema to drive the keys dynamically.

- `284-286` **P2 / schema_or_enum_drift**
  - evidence: "essence": list(r.get("essence", [])), "peripheral": list(r.get("peripheral", [])), "atmospheric": list(r.get("atmospheric", []))
  - why: The extraction logic is hardcoded to specific semantic keys. If the analysis schema or the prompt strategy evolves (e.g., adding a 'lighting' or 'character_focus' category), this code will silently ignore the new data, creating a drift between the LLM output and the stored checkpoint.
  - fix: Iterate over the keys defined in the response_schema or the LLM response dynamically instead of hardcoding the category names.

## `backend/app/core/visible_entities_validator.py`

- `139-161` **P1 / semantic_string_judgment**
  - evidence: _FACE_CLOSE_UP_PATTERNS = [ ... ]
  - why: The validator uses a hardcoded list of English keywords ('face', 'eye', 'expression', 'gaze', 'stare') to classify the visual framing of a prompt. This semantic judgment on open-world text determines whether character ID validation is enforced or exempted, making it fragile to synonyms, phrasing variations, and different languages.
  - fix: Visual framing classification (e.g., 'is_face_closeup') should be a structured boolean field emitted by the scenario analyzer or prompt generator, rather than being inferred from the final prompt string via regex.

- `216-217` **P1 / semantic_string_judgment**
  - evidence: t.lower() in prompt_lower
  - why: The code performs a substring check of 'trigger phrases' (e.g., 'focus on', 'detail on') within the generated prompt to decide if character ID enforcement should be skipped. This is a pattern-based semantic judgment used to mutate validation pass/fail behavior.
  - fix: The decision to skip ID enforcement should be driven by a structured flag in the render_prompt_card (e.g., 'id_enforcement_mode') determined during the planning phase, rather than searching for keywords in the final prompt.

- `553-572` **P2 / semantic_string_judgment**
  - evidence: prompt_lower.find(name_lower, offset)
  - why: The validator uses dynamic entity names to perform semantic judgment on whether a character is being referenced in the prompt. This window-based heuristic is used to enforce ID presence and is prone to false positives/negatives based on how names are used in natural language.
  - fix: Transition to a system where the LLM explicitly tags entities in its output or provides a structured mapping of entities to prompt segments, rather than relying on name-string matching in the final prompt.

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

- `158-160` **P2 / semantic_string_judgment**
  - evidence: for _k, v in traits_data.items(): if isinstance(v, str): visual_traits.append(v)
  - why: This fallback logic assumes any string value within the entity's stable traits dictionary is a visual anchor. It pollutes the vision validation prompt with non-visual metadata (such as personality traits, roles, or internal story notes), which can bias the Vision LLM or cause false validation failures when the model attempts to verify abstract or non-visual concepts in an image.
  - fix: Enforce a strict schema for visual traits (e.g., requiring the 'visual_anchor_traits' key) and remove the blind iteration fallback that treats arbitrary metadata as visual requirements.

## `backend/app/modules/llm/llm_client.py`

- `278-304` **P1 / schema_or_enum_drift**
  - evidence: _PIPELINE_STEP_EXTENSIONS
  - why: Hardcodes pipeline steps, labels, and model assignments outside of the STEP_MANIFEST SOT. This creates a secondary, scattered source of truth for pipeline logic and results in 'dead' entries that the code itself identifies as problematic (line 330).
  - fix: Migrate all sub-steps and legacy steps into the central STEP_MANIFEST and remove the local extension dictionary.

- `551-553` **P1 / scenario_dependent_prompt**
  - evidence: safe_system = system_prompt + SAFETY_SYSTEM_SUFFIX
  - why: The Tier 2 fallback logic blindly appends a 'movie framing' suffix (SAFETY_SYSTEM_SUFFIX) to bypass safety filters. This forces a cinematic semantic bias onto arbitrary scenarios (e.g., novels, webtoons) that may not fit the 'movie' trope, potentially altering LLM reasoning and terminology.
  - fix: Move the safety framing instruction to the STEP_MANIFEST or project configuration so it can be tailored to the specific scenario type (e.g., 'fictional novel' vs 'movie script').

- `759-766` **P1 / scenario_dependent_prompt**
  - evidence: first["content"] = sys_content + SAFETY_SYSTEM_SUFFIX
  - why: In multi-turn calls, the system blindly appends a 'movie framing' suffix to the system message to bypass safety filters. This hardcodes a cinematic context for all multi-turn analysis, biasing the LLM's interpretation of characters and scenes toward movie tropes.
  - fix: Parameterize the safety framing suffix based on the scenario's actual medium/type provided by the SOT.

## `backend/app/modules/llm/safety.py`

- `26-73` **P1 / blind_string_mutation**
  - evidence: _SAFETY_REPLACEMENTS_KO and _SAFETY_REPLACEMENTS_EN
  - why: Hardcoded word-for-word replacement of story-significant terms (e.g., 'blood' to 'red paint', 'corpse' to 'motionless figure') forces a specific visual interpretation and story meaning regardless of the actual scenario context, bypassing safety filters via blind mutation.
  - fix: Move safety-related semantic transformations to a structured world-rule SOT or use an LLM-based rephrasing step that preserves the intended atmosphere without triggering filters, rather than using static string mapping.

- `94-102` **P1 / scenario_dependent_prompt**
  - evidence: SAFETY_SYSTEM_SUFFIX
  - why: The prompt contains concrete scenario-specific examples ('dark red stage paint pool', 'motionless figure in character', 'aged photograph prop') that bias the LLM towards a specific 'movie set' framing, which may conflict with the intended genre or style of arbitrary scenarios.
  - fix: Abstract the framing instructions to a higher-level rule set and provide examples dynamically based on the scenario's genre or style metadata.

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

- `11-13` **P2 / blind_string_mutation**
  - evidence: return _PAREN_RE.sub('', name).strip()
  - why: Heuristic removal of parentheses to find a 'base name' for identity matching. This assumes a specific naming convention for character variants that should be handled via structured metadata rather than runtime string manipulation.
  - fix: Store normalized base names as a separate field in the entity schema instead of performing regex-based mutation during matching.

- `27-30` **P1 / semantic_string_judgment**
  - evidence: if shot_name == base_name(entity_name): ... if len(shot_name) >= 2 and entity_name.startswith(shot_name):
  - why: Uses fuzzy string matching and blind substring checks to decide visible entity membership. This logic makes semantic assumptions about character identity based on name prefixes and parenthetical suffixes, which can lead to incorrect routing or reference attachment in complex scenarios.
  - fix: Replace fuzzy name matching with a structured entity resolution system using unique IDs or explicit name-variant mappings defined in the world SOT.

## `backend/app/modules/pipeline/background_chain_planning.py`

- `152-154` **P1 / semantic_string_judgment**
  - evidence: if len(ename) >= 2 and (loc_raw in ename or ename in loc_raw):
  - why: Uses a blind substring check to resolve location IDs from raw scenario text. This is a pattern-based heuristic for entity membership that can lead to incorrect shot grouping (routing) if names are similar or ambiguous.
  - fix: Use exact ID matching from the scene director or a structured mapping. If fuzzy matching is required, use a dedicated entity resolution step or LLM-based disambiguation.

- `390-501` **P2 / semantic_string_judgment**
  - evidence: if _NON_ASCII_TEXT_RE.search(summary):
  - why: Uses regex to detect non-ASCII characters in natural language fields (rationale, description, etc.) to enforce a 'universal noun' rule. This is a pattern-based semantic judgment that causes validation failure. It is brittle and may fail on valid technical or proper name edge cases.
  - fix: Enforce linguistic constraints through system prompt instructions and few-shot examples. If validation is necessary, use a dedicated language detection library or allow a threshold/exception list for proper names.

## `backend/app/modules/pipeline/background_chain_render.py`

- `57-61` **P1 / scenario_dependent_prompt**
  - evidence: _BACKGROUND_ONLY_REINFORCEMENT = ( "BACKGROUND-ONLY architectural still — empty space, NO people, NO faces, NO body posture, NO action, NO weapons, NO blood. Photoreal scene without any human figures.\n\n" )
  - why: This constant hardcodes a specific visual style ('Photoreal scene', 'architectural still') and a list of forbidden tropes ('NO weapons') into every background prompt. This biases the output against non-photoreal art styles or scenarios that might require specific props like weapons in the background (e.g., a fantasy armory).
  - fix: Move these visual constraints into the system prompt or a structured style SOT (Source of Truth) that can be configured per scenario or project.

- `89-92` **P2 / scenario_dependent_prompt**
  - evidence: "Thoroughly describe wall/floor/ceiling/lighting/palette since later children inherit from this rendered photo."
  - why: The prompt instruction hardcodes architectural elements ('wall/floor/ceiling'), assuming the location is an interior space. This biases the LLM's description for outdoor or abstract locations where these terms are inappropriate.
  - fix: Generalize the instruction to 'surfaces and boundaries' or move it to the user_template where it can be adjusted based on the location's 'kind' (e.g., interior vs. exterior).

## `backend/app/modules/pipeline/background_classify.py`

- `150-168` **P1 / semantic_string_judgment**
  - evidence: if kind == "chain_bg": ... total_shots < 3 ... if not has_indoor:
  - why: The code enforces a hard-coded semantic rule that a 'chain_bg' must have at least 3 shots and at least one indoor location. This is a story/visual heuristic embedded in the validation logic rather than being driven by the world rules or schema, which can lead to unexpected failures for valid but small-scale or outdoor-only scenarios.
  - fix: Move these heuristic constraints into the LLM system prompt as guidelines or into a configurable 'visual_world_rules' validator rather than hard-coding them in the pipeline logic.

## `backend/app/modules/pipeline/background_master_plan.py`

- `169-231` **P1 / semantic_string_judgment**
  - evidence: normalize_space_key(loc_id, bg["space_key_hint"], bg_profile)
  - why: The pipeline validates the structural link between backgrounds and floor plans by normalizing and comparing open-world string hints ('space_key_hint'). This makes the validation (fail/pass) dependent on pattern-based semantic interpretation of LLM-generated labels rather than stable IDs.
  - fix: Require the LLM to use explicit, stable identifiers for spaces/sub-locations defined in the location profile, or derive the space membership directly from the floor plan reference (depends_on_fp) without redundant string-based cross-checks.

- `366-385` **P1 / semantic_string_judgment**
  - evidence: sub_to_fp[sub] != first_fp
  - why: In the legacy validation path, the code uses the 'sub_location' string (an open-world label) as a key to enforce that all backgrounds in the same area reference the same floor plan. This relies on the LLM providing perfectly consistent string labels to pass validation.
  - fix: Migrate legacy logic to use structured space IDs from a canonical SOT instead of relying on LLM-generated sub_location strings for grouping and consistency checks.

## `backend/app/modules/pipeline/background_planner.py`

- `261-268` **P1 / scenario_dependent_code**
  - evidence: invariant 6: frequency rule: floor_plans[].shot_count ≥ 3
  - why: This is a hard-coded semantic heuristic that forbids floor plan generation for locations with fewer than 3 shots. This magic number dictates story/visual structure and may not apply to all scenarios (e.g., a critical 2-shot location).
  - fix: Move this frequency threshold to a configuration file or a structured 'World Rules' SOT so it can be adjusted per-project or per-scenario.

## `backend/app/modules/pipeline/background_prompt.py`

- `196-210` **P1 / semantic_string_judgment**
  - evidence: item.encode("ascii") ... "owned MUST be English canonical common nouns (round 4 Q2=B / round 6 BLOCKING 3)."
  - why: Uses a technical ASCII check to enforce a semantic language constraint (English common nouns) on open-world story entities (objects_owned_by_background). It also includes project-specific internal nomenclature ('round 4 Q2=B') which pollutes the validator and prevents the pipeline from supporting non-English or specialized scenario content.
  - fix: Move the language and content constraints to the system prompt or a structured visual SOT. Remove project-specific 'round' references from the code and use a more flexible validation approach if non-ASCII characters are required for specific scenarios.

## `backend/app/modules/pipeline/background_render.py`

- `22-26` **P1 / scenario_dependent_prompt**
  - evidence: _BACKGROUND_ONLY_REINFORCEMENT = ( "BACKGROUND-ONLY architectural still — empty space, NO people, NO faces, NO body posture, NO action, NO weapons, NO blood. Photoreal scene without any human figures.\n\n" )
  - why: This reinforcement string hardcodes specific visual styles ('architectural still', 'photoreal') and content exclusions ('NO weapons', 'NO blood') into the pipeline. This biases the generator against non-photoreal styles or scenarios requiring specific environmental storytelling elements (e.g., a battle-scarred background) and should not be hardcoded in the renderer.
  - fix: Move these visual constraints and negative prompts to a structured style/rule SOT or a configuration object that can be overridden per scenario or project.

## `backend/app/modules/pipeline/entity_extractor_v2_legacy.py`

- `193-196` **P1 / semantic_string_judgment**
  - evidence: e.get("importance") == "none" and int(e.get("appearances", 0)) < 2
  - why: This logic prunes entities from the visual generation pipeline based on a hardcoded string literal ('none') and a count heuristic. It makes a critical decision about story membership and visual presence using a semantic label returned by an LLM, which is fragile and should be handled by structured rules or LLM-driven filtering rather than hardcoded Python gates.
  - fix: Move the pruning logic into the LLM prompt instructions or use a structured importance score (integer) with a configurable threshold in the system settings.

- `286-289` **P2 / scenario_dependent_prompt**
  - evidence: 기존 요소가 이번 에피소드에도 등장하면 이름을 동일하게 유지하세요.
  - why: This is a hardcoded story continuity instruction embedded directly in the Python logic. It bypasses the externalized prompt system (PROMPT_DIR) and pollutes the code with scenario-specific rules about naming and episode consistency.
  - fix: Move this instruction into the base system prompt or the specific turn templates in the prompts directory.

- `370` **P2 / scenario_dependent_prompt**
  - evidence: system_prompt="시나리오 분석 전문가. 요소별 시각적 상세 정보(즉, 외모 외형 보이는 부분 중심)를 관련성 있는 부분을 최대한 많이 추출한다."
  - why: The system prompt for the entity detail batch extraction is hardcoded in the Python call. This bypasses the versioned prompt management system used for other turns in the same file, making it harder to tune extraction behavior without code changes.
  - fix: Externalize this system prompt into a markdown file in the PROMPT_DIR and load it using the existing _load_turn_prompt or _load_system_prompt utilities.

## `backend/app/modules/pipeline/entity_filter.py`

- `71-83` **P1 / blind_string_mutation**
  - evidence: stripped = re.sub(r'^[CLP]\d{2,3}\s*', '', raw_name).strip()
  - why: The code uses regex to guess the original entity name from LLM output by stripping potential ID prefixes. This is a fragile heuristic used to drive entity membership (filtering) decisions in the story pipeline.
  - fix: Modify the LLM response schema to explicitly return the 'short_id' for each decision, and use that ID for direct lookup instead of regex-based name normalization.

- `84-91` **P1 / semantic_string_judgment**
  - evidence: if e["name"] not in rnames
  - why: Entity removal is performed by matching natural language name strings. This is unreliable in open-world scenarios where multiple entities might share the same name (e.g., 'Villager') or where the LLM might slightly vary the name string.
  - fix: Perform filtering based on unique 'short_id' keys rather than name strings.

## `backend/app/modules/pipeline/entity_lister.py`

- `96-303` **P2 / llm_closed_list_instruction**
  - evidence: "위 목록에 없는 새로운 요소만 추가하세요."
  - why: Hardcoded natural language instructions for LLM deduplication behavior (lines 96-99, 299-303) are embedded in the Python logic. This bypasses the prompt management system and makes it harder to tune the chaining behavior across different models or languages.
  - fix: Move the chaining/deduplication instructions into a dedicated prompt template or a system message fragment managed by the prompt loader.

- `199-240` **P1 / blind_string_mutation**
  - evidence: .replace("scene_count", "shot_count").replace("등장하는 씬 수", "등장하는 샷(스틸컷) 수")
  - why: The code performs blind string replacement and manual concatenation on natural language prompt text to change semantic instructions (lines 199, 238-240). This is fragile as it depends on exact phrasing in the base prompt. If the base prompt is updated, the replacement may fail silently while the schema is still patched, leading to LLM hallucination or validation failure.
  - fix: Use separate prompt templates for shot-based analysis or use a templating engine with variables for 'scene/shot' terminology.

- `354-371` **P2 / schema_or_enum_drift**
  - evidence: def _patch_schema_shot_count(schema: Dict) -> Dict:
  - why: Manually mutating the JSON schema at runtime to rename keys (scene_count to shot_count) creates a drift between the source-of-truth schema files and the actual validation logic. This makes it difficult to maintain and audit the expected LLM output structure.
  - fix: Define a separate schema file for shot-based entity extraction instead of patching the scene-based schema in code.

## `backend/app/modules/pipeline/entity_relation.py`

- `30-32` **P1 / semantic_string_judgment**
  - evidence: bn = base_name(name); if bn: groups.setdefault(bn, []).append((sid, name))
  - why: The pipeline uses a string-pattern heuristic (base_name) to group entities as variants. This logic decides entity membership and reference attachment based on name substrings, which is an open-world semantic decision made through blind string matching.
  - fix: Shift variant detection to the LLM using the full entity descriptions and context, or rely on a structured SOT where these relationships are explicitly defined by the user/creator rather than inferred from name strings.

- `39-40` **P2 / scenario_dependent_code**
  - evidence: members.sort(key=lambda x: (len(x[0]), x[0])); base_sid, base_nm = members[0]
  - why: The code hardcodes a rule that the 'base' entity of a variant group is determined by the shortest ID string. This is a scenario-dependent heuristic for visual/story routing that ignores the actual semantic hierarchy described in the text.
  - fix: Allow the LLM or the structured input to designate which entity is the 'base' reference, rather than relying on ID length as a proxy for semantic priority.

## `backend/app/modules/pipeline/entity_reviewer.py`

- `26-32` **P2 / scenario_dependent_prompt**
  - evidence: f"추출된 인물: ... 추출된 배경: ... 추출된 소품: ... "위 요소 목록을 검토하여..."
  - why: The user prompt assembly hardcodes a closed list of entity categories (characters, locations, props) and Korean instructions. This makes the pipeline rigid to schema changes (e.g., adding new entity types) and scatters domain nomenclature that should be managed via structured templates or SOT-driven logic.
  - fix: Externalize the user prompt to a template and iterate over entity categories dynamically based on the input schema or a central SOT definition.

## `backend/app/modules/pipeline/outlook_dedup.py`

- `65-83` **P2 / blind_string_mutation**
  - evidence: re.sub(r'C\d{2,3}O\d{2,3}', _replace_sid, text)
  - why: Blindly removes duplicate markers from natural language T2I prompts. This can corrupt sentence structure (e.g., 'Character A and Character A' becomes 'Character A and ') and forces a semantic decision that duplicates are never intentional based solely on string patterns.
  - fix: Avoid mutating natural language strings via regex for semantic cleanup. If deduplication is necessary, it should be performed on structured scene data before prompt assembly.

- `140` **P1 / scenario_dependent_prompt**
  - evidence: (예: "검은정장1"과 "검은정장2"는 다를 수 있음)
  - why: The prompt contains scenario-specific naming examples ('Black Suit 1', 'Black Suit 2') to instruct the LLM on merging logic. This biases the model's judgment for arbitrary future scenarios and pollutes the pipeline with domain-specific nomenclature.
  - fix: Remove specific naming examples or move them to a structured 'rules' or 'examples' section provided by the project SOT.

- `271-301` **P1 / blind_string_mutation**
  - evidence: remove_marker = f"[{remove_name}]" ... t2i_cin.replace(remove_marker, keep_marker)
  - why: Performs blind string replacement of entity names within natural language T2I prompts (cinematic and closeup). This risks accidental corruption if entity names are common words or if the marker syntax appears in non-marker contexts within the prompt prose.
  - fix: Use structured IDs (e.g., C01O02) for all internal prompt references and only resolve to names at the final rendering stage, or use a proper parser to identify and replace markers.

## `backend/app/modules/pipeline/outlook_merger.py`

- `97` **P1 / blind_string_mutation**
  - evidence: t2i.replace(f"[{old_name}]", f"[{new_name}]")
  - why: This performs a blind substring replacement on the generated t2i_prompt using names derived from open-world scenario text. It assumes a specific bracketed format and can lead to incorrect visual prompts if names overlap or if the LLM output format is inconsistent.
  - fix: Perform name unification on the structured scene/outlook data before the T2I prompt is generated, or use a robust tokenization system for entity references in prompts.

- `104` **P1 / blind_string_mutation**
  - evidence: vt2i.replace(f"[{old_name}]", f"[{new_name}]")
  - why: Similar to line 97, this mutates variation prompts using blind string replacement, which is a high-risk way to manage visual entity consistency in open-world stories.
  - fix: Ensure all outlook name mapping is resolved at the data level before natural language prompt assembly.

## `backend/app/modules/pipeline/scene_extractor_v2.py`

- `93` **P2 / schema_or_enum_drift**
  - evidence: enum: ["normal", "montage", "flashback", "dream", "voiceover", "transition"]
  - why: Hardcoded list of story tropes used to classify scenes. This limits the open-world analysis to a fixed set of categories that may not cover all narrative styles and should ideally be defined in a world-rule SOT.
  - fix: Move these categories to a configurable SOT or allow the LLM to provide a 'type' with a 'reasoning' field.

- `214-450` **P1 / semantic_string_judgment**
  - evidence: scene_text.find(st, ...), fulltext.find(start_text, ...), if split_text in scene_text:
  - why: The pipeline determines scene boundaries by performing exact substring matches on text fragments returned by an LLM. This is highly fragile as LLMs often introduce minor variations in whitespace, punctuation, or phrasing when 'copying' text, leading to failed segmentation or incorrect character offsets.
  - fix: Request character offsets or line indices from the LLM instead of raw text, or implement fuzzy matching for boundary detection.

- `736-741` **P2 / blind_string_mutation**
  - evidence: _re_cine.sub(r'카메라 구도 선택지:.*?주의:', '주의:', turn_msg, flags=_re_cine.DOTALL)
  - why: Modifies the prompt template instructions using regex substitution based on the presence of cinematography data. This is a fragile way to handle conditional prompt logic and makes the system sensitive to minor changes in the prompt text.
  - fix: Use a proper templating engine (like Jinja2) or structured prompt assembly logic to handle conditional sections instead of post-hoc regex modification.

- `808-823` **P1 / blind_string_mutation**
  - evidence: var["t2i_prompt"] = current_t2i.rstrip() + " " + suffix
  - why: The code detects missing entities in a generated T2I prompt using substring checks and blindly appends a hardcoded English suffix (e.g., 'visible in the background'). This bypasses the LLM's semantic understanding and can result in contradictory or poorly composed visual prompts.
  - fix: Include the required entities in the initial prompt instructions or use a second LLM pass to integrate missing elements into the narrative description naturally.

- `909` **P2 / scenario_dependent_prompt**
  - evidence: f"  - [[{c['name']}]+[아웃룩이름]]"
  - why: The prompt contains a hardcoded Korean placeholder '아웃룩이름' (Outlook Name) as an example. This is scenario-specific pollution that should be replaced with a generic instruction or a structured example from the SOT.
  - fix: Use a generic placeholder or move the example to a structured world-rule SOT.

## `backend/app/modules/pipeline/scene_image_pipeline.py`

- `68` **P1 / llm_closed_list_instruction**
  - evidence: "type": {"type": "string", "description": "angle | color | angle+color"}
  - why: Forces the LVM to classify visual improvements into a hardcoded set of categories. This restricts the model's ability to suggest open-world visual improvements and limits the pipeline's flexibility to handle diverse visual styles or world-rules.
  - fix: Allow the LVM to provide free-form improvement types or derive valid improvement categories from a structured world-rule SOT.

- `243` **P2 / semantic_string_judgment**
  - evidence: "Previous scene (same location)"
  - why: Hardcodes a semantic assumption that the previous scene is always in the same location. This is a story-level decision that may be incorrect for scenes involving location changes, potentially confusing the T2I model's reference processing.
  - fix: Pass the relationship label as a parameter derived from scenario analysis (e.g., comparing location IDs) rather than hardcoding the 'same location' assumption.

- `452-458` **P1 / scenario_dependent_code**
  - evidence: if imp_type == "color": ... elif imp_type == "angle": ...
  - why: The pipeline performs visual routing based on a closed-list semantic classifier ('imp_type') returned by the LLM. This creates a tight coupling between the code and specific visual categories that should be handled generically.
  - fix: Use a more generic I2I editing interface that accepts the improvement type as a hint or parameter without hardcoded branching logic in the pipeline.

- `455` **P1 / blind_string_mutation**
  - evidence: f"Camera angle adjustment: {i2i_prompt}"
  - why: Blindly prepends a hardcoded string to the I2I prompt based on a semantic category. This is a pattern-based visual decision that can pollute or override the LLM's intended descriptive text in the i2i_prompt.
  - fix: Include the improvement intent in the prompt template or pass it as structured metadata to the editor rather than using string concatenation in the pipeline logic.

## `backend/app/modules/pipeline/scene_validator.py`

- `144` **P1 / scenario_dependent_prompt**
  - evidence: "동녘(강의원)" 같은 표현 → 동녘의 몸만 있고, 강의원은 원격에서 조종 중이므로 강의원은 false
  - why: The prompt includes specific character names ('동녘', '강의원') and a specific plot context ('remote control') as examples. This pollutes the general-purpose pipeline with scenario-specific logic and can bias the LLM when processing unrelated stories.
  - fix: Use abstract examples (e.g., 'Character A (Character B)') or move scenario-specific logic to a dynamic context provided by the world-building SOT.

- `232-235` **P2 / blind_string_mutation**
  - evidence: re.sub(rf'\[\[{escaped}\]\+\[[^\]]*\]\]', '', prompt)
  - why: The code uses regex to remove entities from the 't2i_prompt' based on their natural-language names. This is a blind string mutation that can cause unintended side effects if names are substrings of other words or if the prompt structure varies.
  - fix: Transition to a fully structured prompt assembly where the T2I prompt is generated from a list of active entity IDs rather than post-processing a string with name-based regex.

## `backend/app/modules/pipeline/shot_director.py`

- `182-199` **P1 / semantic_string_judgment**
  - evidence: excluded_map = detect_gaze_pattern_exclusions(desc, name_to_char_id)
  - why: The code uses a deterministic heuristic (detect_gaze_pattern_exclusions) to analyze natural language shot descriptions and remove entities from the 'visible_entity_ids' list. This is a pattern-based semantic judgment that overrides the LLM's open-world visibility determination, potentially leading to incorrect rendering contracts if the description contains complex or non-standard phrasing.
  - fix: Integrate gaze and off-screen detection into the LLM's structured output instructions. If a deterministic check is required for safety, it should be used as a validation flag or audit field rather than silently mutating the primary visibility SOT.

## `backend/app/modules/pipeline/shot_visibility.py`

- `37-302` **P1 / semantic_string_judgment**
  - evidence: _KOREAN_GAZE_STEMS, _BODY_PART_NOUNS, detect_gaze_pattern_exclusions
  - why: The pipeline determines character visibility by parsing open-world Korean descriptions using hardcoded lists of verbs and body parts. This heuristic-based approach to visual semantics is fragile and scenario-dependent, as it relies on an incomplete list of domain-specific nomenclature to decide which entities are off-camera.
  - fix: Shift visibility determination to a structured LLM output (e.g., a 'visible_entities' list in the shot schema) rather than post-processing natural language with regex heuristics.

- `85-445` **P1 / semantic_string_judgment**
  - evidence: _OFFSCREEN_PHRASES, detect_offscreen_drift
  - why: Detects 'off-screen' status by searching for specific phrases in natural language camera directions and checking proximity to character names. This makes visual validation and fail-fast behavior dependent on fragile string patterns and magic proximity windows.
  - fix: Require the staging LLM to provide structured visibility metadata (e.g., an 'is_off_screen' boolean or location enum) per character instead of parsing natural language strings in the pipeline.

## `backend/app/modules/pipeline/t2i_review.py`

- `394-395` **P1 / blind_string_mutation**
  - evidence: if target in old: c["t2i_prompt"] = old.replace(target, suggestion)
  - why: Uses blind substring replacement to modify visual prompts. This lacks token or word-boundary awareness, which can lead to accidental corruption of unrelated words (e.g., replacing 'art' inside 'earth' or 'heart').
  - fix: Use a more robust replacement strategy, such as token-based matching or having the LLM return the full corrected prompt instead of a target/suggestion pair.

- `401-402` **P1 / blind_string_mutation**
  - evidence: if target in old: v["t2i_prompt"] = old.replace(target, suggestion)
  - why: Identical blind replacement logic applied to the 'completed' entity dictionary, risking prompt corruption.
  - fix: Switch to full-string replacement or token-aware substitution.

- `450-451` **P1 / blind_string_mutation**
  - evidence: if target and target in old_prompt: variation["t2i_prompt"] = old_prompt.replace(target, suggestion)
  - why: Blind substring replacement in scene-level T2I prompts. Since these prompts often contain comma-separated tags, a substring match can easily hit unintended parts of the prompt.
  - fix: Request the full corrected prompt from the LLM or implement regex-based word-boundary matching for the target string.

## `backend/app/modules/pipeline/text_cleaner.py`

- `31` **P1 / scenario_dependent_prompt**
  - evidence: 예: "네메\\n시스" → "네메시스"
  - why: The prompt uses a specific story-related name ('Nemesis') as an example for line-break correction. This introduces scenario-specific pollution into a general text-cleaning utility that should be domain-agnostic regarding specific story content.
  - fix: Replace scenario-specific names with generic placeholders (e.g., '가\\n나다' or 'Ex\\nample') to ensure the prompt remains independent of any single project's nomenclature.

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

- `67-73` **P1 / llm_closed_list_instruction**
  - evidence: _STATE_GUIDANCE: Dict[str, str] = { "dead": "Do not rewrite as alive...", ... }
  - why: Hard-codes the visual and narrative meaning of character states (dead, unconscious, injured) as negative constraints for the LLM. This creates a maintenance bottleneck and risks semantic inconsistency across the pipeline if these definitions are not synchronized with a central world-rule SOT.
  - fix: Move state-to-instruction mappings to a centralized world-rule SOT or include them in the prompt template metadata rather than hard-coding them in the logic.

- `100-104` **P2 / schema_or_enum_drift**
  - evidence: for key in ( "preserve_pose", "preserve_subject_state", "forbid_state_polarity_rewrite", ... ):
  - why: The list of semantic flags is hard-coded in the rendering logic. This creates a drift risk where new flags added to the semantic contract schema will be silently ignored by the prompt generator.
  - fix: Iterate over the constraints dictionary based on a shared schema or registry of valid semantic flags.

- `146-150` **P1 / blind_string_mutation**
  - evidence: idx = prompt.find(_SEMANTIC_OVERRIDE_MARKER); if idx >= 0: head = prompt[:idx].rstrip(); return head + "\n\n" + block
  - why: Truncates LLM-generated natural language prompts based on a substring match of a technical marker. If the LLM happens to include the marker text in its response, the prompt will be silently corrupted/truncated, affecting visual output.
  - fix: Use structured output fields to separate the LLM's generated prose from system-appended overrides, or use a more unique/non-natural-language delimiter.

- `229-230` **P2 / blind_string_mutation**
  - evidence: if not sanitized.startswith(strategy["prefix"].strip()[:40]): sanitized = strategy["prefix"] + sanitized
  - why: Uses a brittle 40-character substring check on LLM-generated natural language to decide whether to prepend a strategy prefix. This heuristic is unreliable and can lead to corrupted or redundant prompt text if the LLM output varies slightly.
  - fix: Ensure the strategy prefix is handled via the system prompt instructions or a dedicated structured field rather than post-hoc string matching.

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

- `61-98` **P1 / scenario_dependent_code**
  - evidence: mapping = { "character": [ ..., "현대 한국/근미래 한국 기준의 현실적 기본 복장을 사용하라." ] }
  - why: The reference image generator hardcodes a specific cultural and temporal setting (Modern/Near-future Korea) for all character entities. This biases image generation for scenarios that might be historical, high-fantasy, or set in different geographic locations, violating the open-world requirement.
  - fix: Remove the hardcoded setting strings from the mapping. These constraints should be passed in via the world_guide (e.g., costume_guardrails) or a dedicated style SOT.

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

- `62-64` **P1 / blind_string_mutation**
  - evidence: world_summary = world_summary[:200].rsplit(".", 1)[0] + "."
  - why: Blindly truncating the world setting summary to 200 characters by splitting on the last period can remove critical semantic context required for consistent visual generation.
  - fix: Pass the full summary or use an LLM-based summarizer that preserves key visual anchors if length constraints are required.

- `97` **P2 / blind_string_mutation**
  - evidence: brief_traits = " (" + ", ".join(anchors[:3]) + ")"
  - why: Arbitrarily selecting only the first three visual anchor traits for a character reference label may omit defining features that appear later in the list, leading to identity drift.
  - fix: Include all visual anchor traits or use a priority-based selection mechanism defined in the character SOT.

- `296` **P2 / blind_string_mutation**
  - evidence: brief_traits = ". " + ", ".join(anchors[:4])
  - why: Similar to line 97, this arbitrarily selects the first four traits for Gemini reference labels, creating inconsistency and potentially losing identity-defining visual information.
  - fix: Standardize trait selection logic and ensure all critical visual anchors are preserved in the prompt.

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

- `19-192` **P1 / semantic_string_judgment**
  - evidence: HEADING_PREFIXES = ("INT.", "EXT.", "INT/EXT.", "I/E.")
  - why: Scene boundary detection (a core structural analysis step) is performed using a hardcoded list of English-only screenplay prefixes. This causes the 'heading_catalog' to be empty or incorrect for Korean/Japanese scenarios, breaking the LLM's ability to reference scene indices correctly despite the module claiming support for those languages.
  - fix: Abstract scene heading detection into a configurable SOT that supports multiple languages and screenplay formats (e.g., S#, #Scene, etc.) instead of hardcoded string prefixes.

- `69-75` **P2 / llm_closed_list_instruction**
  - evidence: "still_kind": { "type": "string", "enum": [ "establishing", "group", "dialogue", "action", "detail", "reaction", "reveal", "insert", "climax", "aftermath", "other" ] }
  - why: The LLM is forced to classify open-world visual intent into a closed list of domain tropes hardcoded in the schema. This limits the system's ability to handle diverse visual styles or specific directorial requirements that should be defined in a structured visual SOT.
  - fix: Define visual shot types in a central SOT and inject them into the JSON schema at runtime to allow for genre-specific or project-specific visual vocabularies.

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

- `22` **P1 / semantic_string_judgment**
  - evidence: IMMOBILIZED_GAZE: frozenset[str] = frozenset({"dead", "unconscious", "severely_injured"})
  - why: The code uses a hardcoded list of natural-language state strings ('dead', 'unconscious', etc.) to decide if a character should be 'immobilized'. This is a semantic judgment based on open-world story concepts that should be driven by structured metadata or a world-rule SOT rather than a static list in the router code.
  - fix: Move these semantic state definitions to a centralized world-rule configuration or ensure the LLM-produced SOT explicitly flags 'immobilized' status as a boolean or enum field (e.g., subject_state.is_immobilized) instead of relying on string matching against 'gaze_target'.

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

- `13-15` **P2 / llm_closed_list_instruction**
  - evidence: "era": {"type": "string", "description": "시대 배경 (현대, 근미래, 중세 등)"}, "region": {"type": "string", "description": "국가/지역 (한국, 일본, 우주 등)"}, "genre_tone": {"type": "string", "description": "장르 톤 (리얼리즘, SF, 판타지 등)"}
  - why: The schema descriptions contain hardcoded trope examples (Modern, Medieval, Korea, SF, etc.). These function as a closed-list classifier for open-world scenario analysis, biasing the LLM's extraction of story metadata toward these specific categories instead of allowing for arbitrary scenario context.
  - fix: Remove specific trope examples from the schema descriptions to allow for unbiased open-world extraction. If a restricted set of values is intended, use a formal enum or provide the allowed list via a dynamic SOT.

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

- `30` **P2 / llm_closed_list_instruction**
  - evidence: "description": "angle | color | angle+color | none"
  - why: The variation type is defined as a closed set of semantic categories within a string description rather than a formal JSON enum. This forces the LLM to perform classification based on a text-only list that is not strictly enforced by the schema structure, which can lead to unexpected values that break downstream logic.
  - fix: Use a formal JSON `enum` property for the `type` field: `"enum": ["angle", "color", "angle+color", "none"]`.

- `45-49` **P2 / llm_closed_list_instruction**
  - evidence: "e.g. 'tight close-up on face', 'wide establishing shot', 'over-shoulder framing'" ... "e.g. 'warm golden hour', 'cold blue moonlight'"
  - why: Hardcoded domain trope lists (cinematography and lighting) are embedded directly in the schema descriptions. These examples bias the LLM's visual recommendations and should be managed via a centralized visual SOT to ensure consistency across different modules and scenarios.
  - fix: Inject these examples from a structured visual rulebook or SOT instead of hardcoding them in the schema definition.

- `62` **P2 / schema_or_enum_drift**
  - evidence: "recommended": {"type": "string"}
  - why: The docstring (line 90) specifies that 'recommended' should be one of 'A', 'B', or 'original', but the JSON schema defines it as a generic string. This allows the LLM to return arbitrary values, violating the contract expected by the calling code.
  - fix: Update the schema to use `"enum": ["A", "B", "original"]`.

## `backend/app/services/checkpoint_sync/episode_projection_service.py`

- `242-251` **P1 / semantic_string_judgment**
  - evidence: re.finditer(r'(C\d{2,3})(O\d{2,3})', t2i_text)
  - why: The system determines visual entity membership (appearance counts) by performing regex-based pattern matching on natural language T2I prompts. This is a fragile semantic judgment that cannot distinguish between an entity being present in a scene versus being mentioned in a negative or descriptive context within the prompt, leading to inaccurate visual metadata.
  - fix: Update the T2I generation pipeline to emit a structured list of entity IDs actually used in the shot, and store this in a dedicated metadata field (e.g., in SceneStill) to avoid scraping natural language strings.

## `backend/app/services/checkpoint_sync/relation_sync_service.py`

- `62-64` **P2 / scenario_dependent_code**
  - evidence: "시각적 변형 — 기본 요소에 의존"
  - why: This hardcoded Korean string provides a default semantic explanation for a 'visual_variant' relationship. Since this value populates the 'continuity_reason' field, it directly affects the natural-language context provided to downstream LLMs or image generation prompts, introducing language-specific and domain-specific bias that should be managed via a structured world-rule SOT or localized configuration.
  - fix: Move the default relationship reason to a centralized configuration or a localized string table, or ensure the upstream analysis phase always provides a structured reason.

## `backend/app/services/checkpoint_sync/scene_still_normalizer.py`

- `69-76` **P1 / semantic_string_judgment**
  - evidence: used = set(_BARE_ID_RE.findall(text)) ... return [sid for sid in director_ve if sid in used]
  - why: Determines visible entity membership for a shot by scanning natural-language prompt strings for ID patterns (C##/L##/P##). This makes the visual composition of a shot dependent on string-matching within a field intended for image generation instructions, rather than a structured source of truth.
  - fix: Derive entity visibility from a structured list of IDs provided by the scene/shot analysis step instead of parsing the t2i_prompt string.

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

- `850` **P1 / semantic_string_judgment**
  - evidence: co_combos = set(_re.findall(r'C\d{2,3}O\d{2,3}', t2i_text))
  - why: This logic extracts character-outfit combinations (C##O##) from the natural-language T2I prompt text to decide which composite reference images to display in the export. This creates a brittle dependency on the LLM's prose output and bypasses structured metadata for visual entity membership.
  - fix: Store the specific outfit or composite IDs used for a shot in a structured field (e.g., within SceneStill or ImageAsset metadata) during the generation phase, and use that field for lookup instead of regexing the prompt string.

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

- `91-119` **P1 / scenario_dependent_prompt**
  - evidence: Photorealistic cinematic still.
  - why: The service hardcodes a specific visual style ('Photorealistic cinematic still') as a prefix for all T2I prompts. This imposes a specific aesthetic bias (photorealism) on the visual generation pipeline that should instead be derived from a structured style SOT or project-specific settings.
  - fix: Move the default style prefix to a configurable field in ProjectSettings or a global style rule SOT rather than hardcoding it in the service logic.

- `144` **P1 / semantic_string_judgment**
  - evidence: ImageAsset.prompt_used.like(f"%outlook_id:{outlook_id}%")
  - why: This uses a SQL LIKE substring search on the 'prompt_used' field (which contains the generated natural-language T2I prompt) to determine entity membership for 'outlook_id'. Relying on technical tags embedded in natural language strings for routing or filtering is fragile and violates the separation of technical metadata from generated content.
  - fix: Store outlook_id in a dedicated foreign key column or a structured JSON metadata field on the ImageAsset model instead of parsing it from the prompt text.

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

- `104-105` **P1 / semantic_string_judgment**
  - evidence: still_data["t2i_prompt_cinematic"] = t2i.get("a", ""); still_data["t2i_prompt_closeup"] = t2i.get("b", "")
  - why: The code relies on arbitrary keys 'a' and 'b' from an LLM-generated dictionary to assign specific visual shot types (cinematic vs. closeup). This creates a brittle, implicit contract between the LLM prompt and the service logic.
  - fix: Use a structured schema (e.g., Pydantic) for the LLM output with explicit fields like 'cinematic_prompt' and 'closeup_prompt'.

- `127-129` **P1 / semantic_string_judgment**
  - evidence: still_data["t2i_prompt_cinematic"] = t2i_vars[0].get("t2i_prompt", ""); still_data["t2i_prompt_closeup"] = t2i_vars[1].get("t2i_prompt", "")
  - why: The code assumes the order of variations in a list (index 0 and 1) determines their visual semantic role (cinematic vs. closeup). This positional dependency is fragile and lacks explicit semantic labeling.
  - fix: Store variations with explicit type labels (e.g., 'shot_type': 'cinematic') and filter by label instead of relying on list index.

- `131-133` **P2 / blind_string_mutation**
  - evidence: still_data["t2i_prompt_cinematic"] = still_data.get("still_frame_prompt", "")
  - why: It promotes raw story/scene text ('still_frame_prompt') directly to a T2I prompt field without visual transformation. Story text often contains narrative elements that are unsuitable for direct T2I generation.
  - fix: Ensure all T2I prompts pass through a visual converter or use a more descriptive fallback that indicates it is a raw scene description.

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

- `33` **P2 / scenario_dependent_prompt**
  - evidence: The input is a Korean film/drama project name.
  - why: The prompt hardcodes the 'film/drama' domain, which biases the LLM's translation/transliteration logic toward specific industry naming conventions rather than remaining domain-agnostic.
  - fix: Inject the project domain as a variable or use a more generic description of the input text.

- `45` **P2 / blind_string_mutation**
  - evidence: re.sub(r'[^a-zA-Z0-9 ]', '', korean_name).strip() or "Project"
  - why: This fallback logic blindly strips all non-ASCII characters to create an 'English' name. For Korean titles, this results in a total loss of semantic identity, defaulting to the generic string 'Project'.
  - fix: Use a romanization library for the fallback to preserve the phonetic identity of the title.

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

- `64-116` **P1 / semantic_string_judgment**
  - evidence: if "previous shot" in label_lower ... if "wearing" in label_lower ... if "prop" in label_lower
  - why: Uses substring matching on natural language labels (which may be LLM-generated) to determine the semantic role and routing of reference images (e.g., character vs. background vs. outfit).
  - fix: Use a structured enum or metadata field for reference types instead of parsing natural language labels.

- `153-169` **P2 / semantic_string_judgment**
  - evidence: if "keep" in lower or "ignore" in lower:
  - why: Uses substring checks on label sentences to decide whether to include them as instructions, which is a fragile way to handle semantic intent from LLM-generated text.
  - fix: Use structured metadata to flag specific instructions or 'keep/ignore' logic instead of parsing strings.

- `296-301` **P1 / blind_string_mutation**
  - evidence: re.sub(r"In a (low angle|dutch angle|high angle|bird eye|wide|tracking|over the shoulder)\s*(frame|composition|shot|view)\s*", "", cleaned)
  - why: Blindly removes camera angle descriptions from the prompt using a hardcoded list of keywords. This mutates the visual semantics of the scene description without context.
  - fix: Handle camera angles as structured metadata or allow them to persist if they are part of the intended scene description.

- `365-370` **P2 / llm_closed_list_instruction**
  - evidence: 'from the reference', 'from Reference image N' 같은 표현은 절대 새로 만들지 마세요 (phantom guard 충돌).
  - why: Hardcodes specific phrase prohibitions in a system prompt to work around a downstream regex-based validator ('phantom guard'). This pollutes the translation logic with implementation-specific constraints.
  - fix: Move phrase prohibitions to a centralized prompt configuration or improve the downstream validator to be more context-aware.

- `415-421` **P1 / scenario_dependent_prompt**
  - evidence: "Photorealistic cinematic still." ... "If only a body part is shown, do NOT add the face."
  - why: Hardcodes specific style ('Photorealistic cinematic still') and rendering logic ('do NOT add the face') directly in the assembly code, biasing all generated prompts regardless of the actual scenario or style requirements.
  - fix: Move style and rendering constraints to a structured style SOT or a configurable prompt template.

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

- `78` **P1 / semantic_string_judgment**
  - evidence: ~ImageAsset.prompt_used.like("[composite:%")
  - why: Uses a substring check on the 'prompt_used' field to distinguish between base reference images and generated composites. This is a brittle routing decision based on a string pattern in a field that should contain natural language prompts.
  - fix: Introduce a structured 'asset_subtype' or 'is_composite' column in the ImageAsset model to handle this classification.

- `103` **P2 / scenario_dependent_prompt**
  - evidence: "Full body shot, standing pose, plain neutral background. Dress the character in the outfit shown in the reference images."
  - why: Hardcodes specific visual style and pose instructions ('Full body shot', 'standing pose', 'plain neutral background') as a fallback. This pollutes the code with visual decisions that should be managed via a structured SOT or template system to maintain project-wide style consistency.
  - fix: Move the fallback prompt to a template configuration or the SOT.

- `135` **P1 / semantic_string_judgment**
  - evidence: prompt_used LIKE :key
  - why: Performs a database update based on a string pattern match in the 'prompt_used' field. This couples business logic (deactivating old composites) to a specific string prefix convention rather than structured metadata.
  - fix: Use a dedicated foreign key or metadata field to identify related composite assets for deactivation.

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

- `95-119` **P2 / scenario_dependent_code**
  - evidence: ref_entity_type = "character_nonhuman" if is_null_outlook else entity.get("entity_type", "character")
  - why: Semantic classification of an entity as 'nonhuman' is derived from a technical ID list (is_null_outlook / _o00_char_ids) rather than being an explicit attribute of the entity. This couples visual routing and prompt generation to ID naming conventions.
  - fix: Explicitly define entity sub-types (like 'nonhuman') in the entity metadata or SOT instead of inferring them from ID patterns.

- `98-117` **P1 / scenario_dependent_prompt**
  - evidence: variant_instruction = ( ... "Keep the EXACT same face, bone structure, skin tone, and identity." ... )
  - why: Hardcoded visual consistency rules for character variants are embedded in the service logic. These instructions assume humanoid features and identity-based consistency which may not apply to all scenarios (e.g., abstract or non-humanoid projects).
  - fix: Move visual consistency rules to a structured rule SOT or a prompt template system that can be configured per project or entity type.

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

- `61-79` **P1 / scenario_dependent_code**
  - evidence: "Photorealistic cinematic still."
  - why: The visual style 'Photorealistic cinematic still' is hardcoded as a default context for translation and potentially visual generation. This biases the LLM's interpretation of costume descriptions toward a specific aesthetic regardless of the project's actual style requirements, which should be driven by a structured SOT.
  - fix: Retrieve the base style prompt from ProjectSettings or a style-specific SOT instead of hardcoding it in the service logic.

- `155-156` **P2 / scenario_dependent_prompt**
  - evidence: "Translate the Korean costume description to English", "세계관:", "의상:"
  - why: The translation prompt hardcodes the source language as Korean and uses Korean labels. This prevents the pipeline from being used for scenarios written in other languages without code changes.
  - fix: Use localized templates or generic instructions that do not assume a specific source language.

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

- `98-114` **P1 / semantic_string_judgment**
  - evidence: ImageAsset.prompt_used.like(f"%{composite_key}%"), ~ImageAsset.prompt_used.like("[composite:%")
  - why: The service uses substring matching on the 'prompt_used' field to identify existing composites and to filter out non-base references. This drives reference attachment and generation routing based on string prefixes in a field that also contains natural language, which is brittle and bypasses structured metadata.
  - fix: Introduce a structured 'asset_subtype' or 'origin_type' column in the ImageAsset model to explicitly track whether an image is a base reference, a composite, or an outlook-specific variant, rather than parsing the prompt string.

- `162` **P1 / scenario_dependent_prompt**
  - evidence: composite_prompt = "Full body shot, standing pose, plain neutral background. Dress the character in the outfit shown in the reference images."
  - why: Hardcodes specific visual composition (full body, standing pose) and style (plain neutral background) as a fallback. These visual decisions should be driven by a style SOT or a configurable template rather than being embedded in the service logic, as they bias the output of all composite generations to a specific pose/background.
  - fix: Move the fallback prompt to a centralized configuration or template system that can be adjusted per-project or per-style.

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

- `353` **P1 / scenario_dependent_code**
  - evidence: EntityCanon.short_id == "O00"
  - why: Hardcoding a specific ID ('O00') to identify 'Null Outlooks' is a project-specific convention. This drives visual generation logic (identifying characters for full-body images) and creates a dependency on specific naming conventions in the database.
  - fix: Replace the hardcoded ID check with a boolean flag on the EntityCanon model (e.g., is_null_outlook) or a system-level configuration that maps semantic roles to IDs.

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

- `176-179` **P1 / scenario_dependent_prompt**
  - evidence: "label": (f"background chain ref ({bg_id} for {loc_id}) — match wall/floor/ceiling/lighting")
  - why: Hardcoding specific architectural elements ('wall/floor/ceiling/lighting') into a reference label biases the visual generation pipeline. If the scenario is an outdoor or non-architectural setting, these terms act as prompt pollution that forces the model to consider interior architectural components.
  - fix: Move the descriptive matching criteria to a structured SOT or configuration, or use a generic label that does not assume specific prop categories.

- `273-276` **P1 / scenario_dependent_prompt**
  - evidence: "label": (f"background chain ref ({node_id} for {loc_id}) — match wall/floor/ceiling/lighting")
  - why: This legacy fallback path repeats the hardcoded architectural tropes, ensuring that even older data structures inject biased semantic instructions into the visual pipeline.
  - fix: Use a generic reference label or derive the matching criteria from the scene's metadata or a centralized rule set.

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

- `465-483` **P1 / scenario_dependent_prompt**
  - evidence: Photorealistic cinematic still.
  - why: The visual style 'Photorealistic cinematic still' is hardcoded as a default prefix or fallback. This is a style trope that should be emitted by a structured world/rule SOT rather than being baked into the coordinator logic.
  - fix: Move the default style prefix to a project-level configuration or the visual world rules SOT.

- `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: A substring check is used to decide whether to mutate the visual prompt by prepending a camera directive. This is a pattern-based semantic judgment over open-world prompt text.
  - fix: Handle camera directive prepending during the initial prompt construction phase in the prompt service, or use structured metadata to track whether a camera directive has already been applied.

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

- `380-381` **P1 / semantic_string_judgment**
  - evidence: entity_lookup[eid].get("entity_type") == "location"
  - why: The code uses a hardcoded string check for 'location' to decide whether to populate the location_scene_history map. This history is used to drive visual consistency (reference attachment) in the image generation pipeline. Relying on a string pattern to decide visual routing for specific entity categories is brittle and bypasses structured world rules.
  - fix: Replace the string check with a property-based check from the EntityCanon model (e.g., is_background_entity) or use a centralized entity-type registry that defines which types require visual history tracking.

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

- `425-426` **P1 / semantic_string_judgment**
  - evidence: for match in _re.finditer(r'\[\[([^\]]+)\]\+\[([^\]]+)\]\]', t2i_prompt):
  - why: This legacy pattern extracts character and outlook names directly from the prompt string to resolve references. This is a pattern-based semantic judgment on open-world story text that bypasses structured IDs.
  - fix: Deprecate the legacy bracketed name pattern in favor of the structured C##O## ID system or a dedicated reference attachment SOT.

- `444` **P1 / semantic_string_judgment**
  - evidence: if outlook_name == "미지정":
  - why: Hardcoded Korean string check ('unspecified') used to route reference resolution logic. This is a domain-specific semantic classifier embedded in code.
  - fix: Use a null value or a specific enum constant from the outlook SOT instead of a natural language string check.

- `557` **P2 / blind_string_mutation**
  - evidence: text_map[ck] = f"{char_desc}, wearing {outfit_desc}"
  - why: Blindly assumes the relationship between a character and an outlook is always 'wearing'. This is a visual semantic decision made via string concatenation.
  - fix: Move relationship description to a template driven by the entity type or a structured world-rule SOT.

- `932-989` **P1 / semantic_string_judgment**
  - evidence: in ("unconscious", "dead", "severely_injured")
  - why: Hardcoded list of semantic character states used to drive visual routing (attaching state variants) and prompt labeling. These are domain tropes that should be defined in a structured SOT.
  - fix: Define character states in a central registry or enum and use those constants to drive reference selection.

- `936-938` **P1 / scenario_dependent_prompt**
  - evidence: Keep motionless figures (dead/unconscious bodies) exactly as they are.
  - why: The prompt instructions contain specific logic for handling 'dead/unconscious bodies' and 'human silhouettes' based on hardcoded story-state branches. This couples the service to specific scenario tropes.
  - fix: Abstract background interpretation rules into a structured prompt-template system driven by the scene's semantic metadata.

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

- `93-97` **P1 / semantic_string_judgment**
  - evidence: if score < 60: ... status = "needs_fix"
  - why: A hardcoded numeric threshold (60) is used to decide the semantic 'needs_fix' status of a scene. This logic forces a specific quality judgment across all projects and scenarios without allowing for project-specific quality standards or world-rule sensitivity.
  - fix: Move the validation threshold to a project-level configuration or a structured validation policy SOT.

## `backend/experiments/entity_loc_prop_shots.py`

- `52-58` **P1 / scenario_dependent_prompt**
  - evidence: (아머+헬멧→아머), UI 화면, 에피소드당 5~10개 목표
  - why: The prompt contains hard-coded genre-specific examples (Armor/Helmet), specific prop exclusions (UI screens), and arbitrary heuristic constraints (3+ shots, 5-10 items). These bias the extraction process toward specific story types and may exclude valid elements in other genres.
  - fix: Move extraction heuristics and genre-specific examples to a project-level configuration or a structured rule SOT rather than hard-coding them in the base prompt.

- `190` **P2 / llm_closed_list_instruction**
  - evidence: 위 목록에 없는 새로운 요소만 추가하세요.
  - why: Instructs the LLM to perform semantic deduplication against a closed list of strings, which is unreliable for open-world entity discovery and should be handled by structured logic.
  - fix: Extract all entities and perform deduplication in a post-processing step using an entity registry or a dedicated resolution prompt.

- `229-235` **P1 / semantic_string_judgment**
  - evidence: if name in existing_names: ... existing["shot_count"] += new_sc
  - why: Entity identity and shot count aggregation are determined by exact string matching of names generated by the LLM. This is fragile in open-world scenarios where the LLM might use synonyms, different casing, or formatting variations for the same entity across different chunks.
  - fix: Implement a canonical entity resolution step using fuzzy matching or a secondary LLM pass to unify entities before aggregating counts.

## `backend/scripts/canary_single_vs_batch_refs.py`

- `149-154` **P2 / scenario_dependent_code**
  - evidence: entry.get("expected_actual_ref_labels_p0")
  - why: The validation logic branches on a scenario-specific key suffix ('_p0') to handle 'prop carry' logic for specific scenes (S21), indicating that the test fixture schema and the validator are not scenario-agnostic.
  - fix: Standardize the fixture schema to use a single field for expected references, or use a generic metadata field to indicate the state/phase instead of encoding it into the JSON key name.

## `backend/scripts/experiment_360_interior.py`

- `37-50` **P1 / scenario_dependent_code**
  - evidence: for k in ("stories", "primary_material", ..., "lighting_fixtures", "general_clutter_level")
  - why: Hardcodes specific architectural and interior attribute keys for extraction. This creates a maintenance burden and causes the script to ignore new or modified attributes in the environment canon SOT.
  - fix: Iterate over all keys in the canon object or use a schema-driven extraction method instead of a hardcoded list of strings.

- `62` **P2 / scenario_dependent_prompt**
  - evidence: opposite the entry
  - why: Hardcodes a spatial relationship (South = opposite entry) that is scenario-dependent and may conflict with the actual floor plan reference provided.
  - fix: Remove specific spatial assumptions from the direction descriptions or derive them from the floor plan analysis.

- `85-86` **P1 / scenario_dependent_prompt**
  - evidence: (weak floor lamp, faint old television glow if visible)
  - why: Injects specific domestic props and lighting effects into the prompt regardless of the actual room type or canon description, biasing the visual generation toward a specific 'lived-in domestic' trope.
  - fix: Move specific prop and lighting descriptions to the environment canon or a separate style SOT rather than hardcoding them in the base prompt template.

## `backend/scripts/experiment_bg_angles.py`

- `19-64` **P1 / scenario_dependent_prompt**
  - evidence: LOCATION_DESC = (...) DIRECTIONS = { ... } (...) STYLE = (...)
  - why: The script hardcodes specific story details for 'L05' (rooftop apartment), including its internal spatial layout (e.g., mapping 'shoe rack', 'television', and 'sink' to specific compass directions) and scene-specific lighting/style choices. This scenario-specific pollution biases the generation logic and should be managed in a structured World/Location SOT rather than being embedded in code.
  - fix: Move location descriptions, directional layouts, and scene-specific style parameters into a structured SOT (e.g., a JSON or DB-backed location registry) and parameterize the script to accept a location ID.

## `backend/scripts/experiment_chain_bg_floorplan_rebuild.py`

- `55-79` **P1 / scenario_dependent_prompt**
  - evidence: NEW_CHAIN_BG_PROMPT = ( ... "single rooftop room (옥탑방)" ... "ONE small old CRT television" ... )
  - why: The prompt contains hardcoded, scenario-specific visual details such as specific props (CRT television), architectural types (옥탑방), and lighting styles. This pollutes the generation logic with specific story elements that should be dynamically injected from a structured world-state or SOT to ensure the pipeline remains scenario-agnostic.
  - fix: Move scenario-specific descriptions into a structured configuration or database (SOT) and use templates to assemble the prompt dynamically.

- `82-98` **P1 / scenario_dependent_prompt**
  - evidence: PROMPT_A_ORIGINAL = ( ... "[L05: A cramped modern Korean 옥탑방 ..." ... "C04O06 in a plain apron" ... "P06 rests rinsed beside the sink" ... )
  - why: The prompt contains hardcoded character IDs (C04O06), prop IDs (P06), and specific scene actions/descriptions. This creates a tight coupling between the generation script and a specific scenario, which is a form of prompt pollution that biases the pipeline toward specific story instances.
  - fix: Parameterize the prompt to accept character/prop descriptions and scene context from a structured scenario analysis output rather than hardcoding them in the script.

## `backend/scripts/experiment_chain_bg_floorplan_v2.py`

- `56-138` **P1 / scenario_dependent_prompt**
  - evidence: FLOORPLAN_V2_PROMPT, CHAIN_BG_V2_PROMPT, PROMPT_A_ORIGINAL
  - why: Prompts contain hardcoded scenario-specific details such as '옥탑방', specific furniture placement ('TV on left wall'), lighting styles ('muted yellow-gray'), and character/prop IDs ('C04O06', 'P06'). This couples the generation logic to a specific scene and should instead be driven by a structured SOT.
  - fix: Refactor prompts into templates that accept parameters from a structured scenario-of-truth (SOT) or world-rule definition.

- `264-280` **P1 / scenario_dependent_prompt**
  - evidence: input_images labels
  - why: The labels provided to the Gemini model for reference images contain hardcoded semantic descriptions of the scene layout ('TV on left wall, sofa on right wall'), which duplicates scenario-specific logic and biases the model's interpretation of the references.
  - fix: Generate reference labels dynamically based on the same structured SOT used for the main prompts.

## `backend/scripts/experiment_chain_bg_floorplan_v3_tworoom.py`

- `54-184` **P1 / scenario_dependent_prompt**
  - evidence: MAIN BEDROOM (안방 — mother's room...), DAUGHTER'S BEDROOM (수리영 방...), C04O06 in a plain apron, P01 clenched low at her side
  - why: These prompts hardcode specific location layouts (L05), room names, character actions, and prop states. This bypasses the structured world-building and scenario analysis SOT, making the pipeline dependent on manual string updates for specific scenes and locations rather than using a generalized layout engine or structured data.
  - fix: Move location layouts, room definitions, and character/prop states to a structured SOT (e.g., a YAML or JSON world-state) and generate these prompts using templates that pull from that data.

- `309-337` **P1 / scenario_dependent_prompt**
  - evidence: object P01 (small bloodstained photograph), object P04 (backpack with doll)
  - why: The labels passed to the LLM as part of the multi-modal input contain hardcoded semantic descriptions of props and characters. This couples the pipeline logic to specific story details and prevents the system from scaling to arbitrary scenarios without code changes.
  - fix: Retrieve entity descriptions and labels from a centralized entity database or SOT using the entity IDs (C##, P##) instead of hardcoding them in the script.

## `backend/scripts/experiment_chain_bg_with_floorplan.py`

- `55-75` **P1 / scenario_dependent_prompt**
  - evidence: FLOOR_PLAN_PROMPT = ( "Top-down architectural floor plan diagram... Korean apartment... Left wall: a small CRT television... labeled 'TV'... )
  - why: The spatial layout and object labeling are hardcoded as a natural language string. This creates a 'hidden' source of truth for the scene geometry that is not synchronized with the actual scenario or world-building database.
  - fix: Define the floor plan layout in a structured format (e.g., JSON or a dedicated layout SOT) and generate the prompt programmatically from that data.

- `78-94` **P1 / scenario_dependent_prompt**
  - evidence: PROMPT_A_ORIGINAL = ( "Photorealistic cinematic still. [L05: A cramped modern Korean 옥탑방... C04O06 in a plain apron... P06 rests rinsed beside the sink..." )
  - why: This prompt contains hardcoded character IDs (C04O06), prop IDs (P06), and location IDs (L05) along with specific narrative details. This is scenario pollution that should be handled by a prompt assembly pipeline using structured entity data.
  - fix: Use a template-based prompt generator that pulls character, prop, and location descriptions from a centralized SOT based on the provided IDs.

- `203-213` **P2 / scenario_dependent_prompt**
  - evidence: "spatial layout reference (floor plan, top-down) — use this to understand the room layout...", "background chain ref (interior_living_kitchen_day_normal for L05)"
  - why: Semantic labels for reference images are hardcoded with scenario-specific IDs (L05) and instructions. This logic should be part of the model's reference-handling protocol rather than hardcoded in the execution script.
  - fix: Derive reference labels from the metadata of the attached assets (e.g., asset type, entity ID, and variant name).

## `backend/scripts/experiment_chain_shot_render_temp.py`

- `50-51` **P1 / scenario_dependent_prompt**
  - evidence: "a Korean woman in her early 20s, slim, mid-length black hair, casual student look with a backpack", "rooftop dwelling", "rear courtyard"
  - why: The prompt uses concrete character and location examples which pollute the LLM's context with specific story tropes, potentially biasing generation for unrelated scenarios towards these specific archetypes.
  - fix: Use generic placeholders for examples or move scenario-specific guidance to a structured world-rule SOT.

- `59` **P1 / llm_closed_list_instruction**
  - evidence: NO blood, NO broken glass, NO gore, NO explicit violence.
  - why: Hardcoded negative constraints for visual elements act as a rigid semantic filter, preventing the pipeline from supporting scenarios that require these elements (e.g., action or thriller genres) without manual prompt editing.
  - fix: Externalize visual content policies into a configurable SOT or style profile that can be adjusted per project.

## `backend/scripts/experiment_chain_structure_planning.py`

- `68-84` **P1 / llm_closed_list_instruction**
  - evidence: "small bedroom interior", "living-kitchen entry corner", "rooftop terrace overlook", "small bedroom doorway", "interior vs. rooftop terrace exterior"
  - why: The system prompt uses specific architectural and domestic tropes as examples to guide the LLM's shot clustering and anchor selection logic. This biases the model toward residential/rooftop scenarios and may result in poor performance or 'hallucinated' domestic anchors when processing non-residential environments (e.g., industrial, natural, or sci-fi).
  - fix: Replace scenario-specific examples with abstract placeholders or move them to a scenario-specific 'guidance' field in the input context that is injected into the prompt dynamically.

- `346` **P2 / scenario_dependent_code**
  - evidence: help="콤마 구분, 옥탑방 관련만: 'small_rooftop_room_interior,rooftop_terrace_and_entry'"
  - why: The CLI help text contains hardcoded scenario-specific IDs and Korean labels ('옥탑방' - rooftop room), indicating the script is coupled to a specific project's data structure rather than being a generic pipeline tool.
  - fix: Use generic ID examples in the help text (e.g., 'plan_id_1,plan_id_2') to maintain the script's utility as a general-purpose planner.

## `backend/scripts/experiment_chain_structure_planning_gpt.py`

- `45-115` **P1 / scenario_dependent_prompt**
  - evidence: ["heavily-ransacked", "water-tank corner", "rooftop_terrace_night", "courtyard_stairs_approach"]
  - why: The system prompt contains numerous concrete examples of rooms, props, and plot-specific states (e.g., 'ransacked') that are specific to the 'Rooftop' scenario. This pollutes the LLM's context and biases it toward specific tropes or layouts that may not apply to other scenarios.
  - fix: Replace scenario-specific examples with generic placeholders or move them to the dynamic user prompt as 'few-shot' examples derived from the current scenario's SOT.

- `189` **P1 / semantic_string_judgment**
  - evidence: extra_keywords = extra_keywords or ["옥탑", "옥상", "rooftop"]
  - why: Hardcoded scenario-specific keywords are used to filter scenes into the analysis scope via substring matching. This makes the logic dependent on specific story vocabulary rather than structured metadata or IDs.
  - fix: Pass the scope keywords as an argument from a configuration file or use structured location IDs/tags from the scenario SOT to determine scope.

- `333-334` **P2 / scenario_dependent_prompt**
  - evidence: "== SHOTS (rooftop-related, full inventory) =="
  - why: The user prompt assembly uses hardcoded labels that assume the scenario is 'rooftop-related', which is scenario-specific pollution in the prompt structure.
  - fix: Use generic labels like 'SHOTS IN SCOPE' or inject the location name dynamically from the context metadata.

## `backend/scripts/experiment_chain_structure_render.py`

- `53-57` **P1 / scenario_dependent_prompt**
  - evidence: 35mm cinematic still aesthetic, Eye-level approx 1.6m, NO people, NO blood, NO broken glass
  - why: Hardcodes specific visual style, camera parameters, and content exclusions directly into the system prompt. This prevents the pipeline from being used for scenarios with different aesthetic requirements or content needs.
  - fix: Inject these constraints from a structured Style/World SOT or configuration object instead of hardcoding them in the prompt string.

- `58-59` **P2 / scenario_dependent_prompt**
  - evidence: match its wall finish, floor, ceiling, lighting tone, and color palette
  - why: The prompt assumes an indoor architectural context by explicitly listing 'wall, floor, ceiling'. This biases the LLM and may produce nonsensical prompts for outdoor or non-architectural scenarios.
  - fix: Generalize the attribute list or derive it from the node's 'kind' or 'spatial' context.

- `128` **P1 / semantic_string_judgment**
  - evidence: if bp["id"] in gn or gn in bp["id"]:
  - why: Uses substring matching between group names and base plan IDs to determine which floor plan to use as a visual reference. This heuristic is prone to collisions or misses in open-world scenarios where names might overlap or be ambiguous.
  - fix: Replace substring matching with an explicit 'base_plan_id' field in the group or node definition within the input JSON.

## `backend/scripts/experiment_chain_structure_render_gpt.py`

- `50-54` **P1 / scenario_dependent_prompt**
  - evidence: 35mm cinematic still aesthetic ... Eye-level approx 1.6m ... NO people, NO blood, NO broken glass, NO action.
  - why: The system prompt contains hardcoded style specifications (35mm, 1.6m height) and a negative constraint list of specific scenario tropes ('blood', 'broken glass', 'action'). These constraints bias the visual generation toward a specific genre/project and should not be hardcoded in the pipeline prompt.
  - fix: Move style constraints and content filters to a structured style/rule SOT (Source of Truth) that is injected into the prompt based on the specific scenario's requirements.

- `81-117` **P1 / semantic_string_judgment**
  - evidence: extra_keywords = extra_keywords or ["옥탑", "옥상", "rooftop"] ... if any(kw in h or kw in txt for kw in extra_keywords):
  - why: The script uses a hardcoded list of scenario-specific place names ('rooftop' in Korean/English) to perform substring matching on scene headings and text to determine if a scene is 'in scope'. This is a pattern-based semantic judgment that routes processing based on specific story content.
  - fix: Remove hardcoded keywords. Scope detection should rely on structured metadata (e.g., tags or explicit scope IDs) provided in the context.json or step2_plan_specs.json.

## `backend/scripts/experiment_floor_plan.py`

- `47-48` **P1 / scenario_dependent_code**
  - evidence: OKTAP_SCENES = [4, 5, 10, 11, 12, 13, 14, 17, 18, 25, 27]
  - why: Hardcoding specific scene and location indices for a single scenario ('옥탑방') prevents the script from being used as a generic floor-plan generation tool for other story segments.
  - fix: Pass scene and location filters as parameters or fetch them from a structured scenario manifest.

- `170-204` **P1 / scenario_dependent_prompt**
  - evidence: SYSTEM_PROMPT = "...Suriyoung · 수리영... 옥탑방 실내(거실·주방·민숙 방·수리영 방·안방)... S12 (엄마 시신 발견)..."
  - why: The system prompt contains concrete character names, specific room layouts, and hardcoded story logic (e.g., identifying S12 as a murder scene). This pollutes the LLM's reasoning with scenario-specific knowledge that should be derived from the provided context.
  - fix: Generalize the system prompt to handle arbitrary locations and characters, and move story-specific selection logic (like prioritizing murder scenes) into a configuration or a separate analysis step.

- `212` **P2 / scenario_dependent_prompt**
  - evidence: "## 옥탑방 관련 전체 컨텍스트 (금월도 1부)\n\n"
  - why: Hardcoded project name and scenario part in the user prompt assembly.
  - fix: Inject the project/scenario title from the metadata provided in the context object.

## `backend/scripts/experiment_floor_plan_compare.py`

- `51-52` **P2 / scenario_dependent_code**
  - evidence: OKTAP_SCENES = [4, 5, 10, 11, 12, 13, 14, 17, 18, 25, 27]
  - why: Hardcoded scene and location IDs are used to filter context for analysis, which couples the script logic to a specific story episode and prevents reuse for other scenarios.
  - fix: Parameterize the scene and location filters or derive them from the input context metadata.

- `114-165` **P1 / scenario_dependent_prompt**
  - evidence: SYSTEM_PROMPT = """... 민숙 방 ... 수리영 방 ... 시체 발견 위치 ... 찻잔 2개, 하나 엎어짐 ..."""
  - why: The system prompt and user message assembly contain hardcoded character names, specific props (e.g., 'overturned teacup'), and plot-specific spatial details (e.g., 'body discovery location'). This pollution biases the LLM and prevents the prompt from being used as a generic architectural analyzer for different scenarios.
  - fix: Move scenario-specific details into the structured context (ctx) and keep the system prompt focused on the task of architectural translation and layout rules.

## `backend/scripts/experiment_floor_plan_v3.py`

- `111-112` **P2 / scenario_dependent_prompt**
  - evidence: "인천 변두리 다세대 빌라"
  - why: The system prompt includes a specific Korean location example ('Incheon outskirts multi-family villa') to guide abstraction. This introduces scenario-specific pollution into a prompt explicitly labeled as 'scenario-independent' in line 1.
  - fix: Remove specific geographic or scenario names from the system prompt and use generic placeholders or few-shot examples.

- `187-196` **P1 / llm_closed_list_instruction**
  - evidence: avoid: dead, corpse, deceased, victim, body ... 사용: "motionless seated figure marker"
  - why: Hardcoded semantic mapping of story concepts (death, blood, violence) to sanitized visual markers to bypass moderation. This is a closed-list semantic classifier that mutates visual output and should be managed via a structured SOT for style and safety.
  - fix: Move safety-related semantic substitutions to a centralized SOT or a dedicated prompt-processing utility.

- `458-461` **P1 / llm_closed_list_instruction**
  - evidence: (a) 어느 base_plan_id 위에 overlay할지 spatial.space_groups의 covers_location_ids와 해당 씬 primary_location 매칭으로 결정
  - why: Delegates the routing decision (matching a shot to a specific floor plan ID) to LLM reasoning based on ID strings. This is a deterministic operation that should be handled in code to prevent hallucination-driven routing errors.
  - fix: Resolve the base_plan_id in Python by comparing location IDs before constructing the prompt, and pass only the relevant plan context to the LLM.

## `backend/scripts/experiment_floor_plan_v4.py`

- `491-493` **P1 / scenario_dependent_prompt**
  - evidence: "doll" + "backpack" + "dim bedroom" + "stain/footprint"
  - why: The system prompt contains highly specific trope combinations used as negative examples for safety. This pollutes the prompt with scenario-specific imagery that biases the model's visual generation for arbitrary future scenarios.
  - fix: Move specific trope or safety examples to a structured visual_rules SOT that can be injected dynamically or handled by a separate validator.

- `1025-1033` **P1 / semantic_string_judgment**
  - evidence: grep_unsafe(payload, words), grep_scenario(payload, banned)
  - why: Uses substring checks ('in text') against hardcoded phrase lists to determine if LLM-generated story or visual content is 'safe' or 'scenario-compliant'. This logic directly triggers retries (fail/pass behavior) based on open-world natural language patterns.
  - fix: Replace substring matching with a dedicated LLM-based moderation check or structured attribute extraction to verify compliance.

- `1252-1257` **P2 / semantic_string_judgment**
  - evidence: keys.append(v.split()[0].lower()), k not in prompt
  - why: Performs brittle validation of semantic coverage by checking if the first word of a canon attribute exists as a substring in the generated natural language prompt.
  - fix: Use an LLM-based validator to verify that the generated prompt adheres to the environment canon, or compare structured attributes extracted from the prompt.

- `1269-1272` **P2 / semantic_string_judgment**
  - evidence: any(w in text for w in ["no people", "empty room", ...])
  - why: Validates the presence of visual constraints in generated prompts using a closed list of substrings. This is fragile and fails to account for semantic variations in natural language instructions.
  - fix: Use structured output for negative prompts or an LLM-based validator to check for the presence of required visual constraints.

## `backend/scripts/experiment_fp_ref_bias.py`

- `76-105` **P1 / scenario_dependent_prompt**
  - evidence: PROMPT_F = ( "옥탑방 거실 내부..." ... ) and PROMPT_E = ( "Korean rooftop room (옥탑방)..." ... )
  - why: These prompts contain hardcoded scenario-specific details such as 'rooftop room', 'Seoul', 'vinyl-finish wallpaper', and 'fluorescent ceiling light'. These are domain-specific tropes and props that should be managed via a structured World SOT or visual ruleset rather than being scattered in prompt strings, especially as they contradict the script's own goal of avoiding hardcoded scenario words (line 10).
  - fix: Extract scenario-specific descriptors into a structured configuration or World SOT that can be injected into prompts dynamically.

## `backend/scripts/experiment_gemini_45deg_chain.py`

- `70-79` **P1 / scenario_dependent_prompt**
  - evidence: 35mm cinematic still aesthetic ... lived-in texture (worn wallpaper, dust, scuff) ... no blood, no broken glass
  - why: The prompt hardcodes specific visual textures, lighting styles, and genre-specific negative constraints (e.g., blood, broken glass) that bias the model toward a gritty aesthetic. These details should be provided by the structured scenario context (SOT) rather than fixed in the pipeline code.
  - fix: Move stylistic descriptors and negative constraints to the environment_canon or visual_domain fields in the input JSON and inject them dynamically into the prompt.

- `337-341` **P2 / scenario_dependent_prompt**
  - evidence: overall material aging — same room, just rotated
  - why: The image generation loop hardcodes 'material aging' as a consistency requirement, which forces a specific 'worn' look even if the scenario describes a clean or modern environment.
  - fix: Generalize the consistency instruction to refer to 'material properties' or derive specific attributes from the atmosphere_canon.

## `backend/scripts/experiment_gemini_redrawn_plan_45deg.py`

- `65-68` **P2 / scenario_dependent_prompt**
  - evidence: cam_0 facing 0° (toward the wall labeled NORTH on the plan) ... cam_90 facing 90° clockwise from cam_0 (toward the wall labeled EAST)
  - why: Hardcodes a fixed mapping between camera indices and compass directions. This assumes the plan is oriented with North at 0 degrees and that the scenario requires exactly these 45-degree increments, which should be derived from the plan's metadata or spatial SOT.
  - fix: Define camera orientations and their relation to the plan's coordinate system in the input context (step1_spatial.json) rather than hardcoding the mapping in the system prompt.

- `78-81` **P1 / scenario_dependent_prompt**
  - evidence: eye-level approx 1.6m, slight wide angle ~28mm... soft natural daylight + dim domestic practicals
  - why: Hardcodes specific camera height, lens, and lighting style ('domestic practicals') into the system prompt. This pollutes the visual generation for scenarios that are not domestic or require different lighting/camera setups (e.g., night scenes, industrial settings), potentially conflicting with the 'visual_domain' or 'lighting' fields provided in the context.
  - fix: Move these visual parameters to the 'spatial' or 'shot' context (SOT) and have the prompt reference the provided context instead of hardcoding them.

- `374-379` **P2 / scenario_dependent_prompt**
  - evidence: Match its wall finish, floor finish, ceiling, lighting tone, color palette, and overall material aging — same room, just rotated.
  - why: Hardcoded consistency instructions for sequential rotation steps. This logic is specific to the '45deg' experiment and may not apply to other view generation strategies, yet it is injected as a raw string mutation during prompt assembly.
  - fix: Parameterize consistency instructions or move them to a structured 'generation_strategy' field in the input context.

## `backend/scripts/experiment_gpt_planned_4view_chain.py`

- `53` **P2 / llm_closed_list_instruction**
  - evidence: kitchen_wall, bed_corner, entry_door_wall
  - why: Provides specific domestic room examples for label generation. This can bias the LLM's spatial reasoning and naming conventions towards residential layouts even when the input scenario might be a different environment type.
  - fix: Use generic placeholders like 'wall_a' or 'corner_b' in examples, or instruct the LLM to generate labels based on the 'elements_meta' provided in the context.

- `58-63` **P1 / scenario_dependent_prompt**
  - evidence: 35mm cinematic still aesthetic, soft natural daylight + dim domestic practicals, realistic shadows
  - why: Hardcodes specific lighting and camera style instructions. This overrides or biases the 'visual_domain' and 'lighting' specs passed in the user prompt, preventing the pipeline from supporting diverse scenario atmospheres (e.g., sci-fi, horror, or non-domestic settings).
  - fix: Remove hardcoded style strings. Instruct the LLM to derive aesthetic and lighting parameters exclusively from the 'visual_domain', 'lighting', and 'environment_canon' sections provided in the user prompt.

- `72` **P1 / scenario_dependent_prompt**
  - evidence: no blood, no broken glass, no action
  - why: Hardcodes specific narrative trope exclusions. While intended as a filter, these are scenario-dependent (e.g., a thriller or post-disaster scene might require broken glass). These constraints should be part of a structured world-rule SOT rather than hardcoded in the generation script.
  - fix: Move narrative and content constraints to a structured configuration or the 'atmosphere_canon' provided in the context.

## `backend/scripts/experiment_line_art_composition.py`

- `148-154` **P1 / scenario_dependent_prompt**
  - evidence: 혈흔/액체 패턴: red dots (#FF0000)
  - why: The system prompt hardcodes specific story tropes (blood/liquid) and entity roles (primary/secondary) to specific colors. This biases the LLM toward specific visual interpretations that may not apply to all scenes and should instead be provided as a structured style-map or SOT-driven legend.
  - fix: Pass the color-to-entity mapping as a dynamic context variable derived from the project's visual style guide or scene-specific entity list.

- `159` **P2 / llm_closed_list_instruction**
  - evidence: C##은 사용 금지 — "character 1 in cyan", "character 2 in magenta" 식
  - why: This instruction forces the LLM to discard structured entity IDs (C##) in favor of ordinal natural language labels. This makes it difficult to programmatically map the generated prompt content back to specific entities in the database if the LLM's assignment of 'character 1' deviates from the input order.
  - fix: Allow the use of IDs in the prompt or provide a strict mapping of ID to Label in the user prompt context to ensure traceability.

## `backend/scripts/experiment_line_elevation_quad.py`

- `40-53` **P2 / schema_or_enum_drift**
  - evidence: for k in ("stories", "primary_material", "exterior_stairs", "rooftop_features", "window_pattern", "weathering"): ... for k in ("wall_finish", "floor_finish", "ceiling", "lighting_fixtures", "general_clutter_level")
  - why: The script hardcodes a closed list of architectural and interior attributes to extract from the canon. This creates drift risk if the upstream schema for 'environment_canon' evolves, and limits the LLM's awareness of other attributes present in the source data.
  - fix: Iterate over the canon dictionary keys dynamically or use a shared schema definition to drive the extraction.

- `93` **P1 / scenario_dependent_prompt**
  - evidence: "aged residential interior, modest domestic clutter"
  - why: Hardcoded fallback scenario string biases the LLM towards a specific 'aged residential' setting when the input canon is missing, rather than using a generic or world-derived default.
  - fix: Replace the hardcoded fallback with a generic default or require the canon to be provided from a structured source of truth.

- `126-129` **P1 / scenario_dependent_prompt**
  - evidence: "Soft natural daylight from window mixed with dim domestic practicals (weak floor lamp, faint old television glow). Realistic shadows, subtle film grain, lived-in details (dust motes, scuff marks, subtle wear)."
  - why: The prompt contains overly specific visual style instructions and props (TV glow, dust motes, scuff marks) that are scenario-dependent and should be emitted by a structured world/style SOT rather than being hardcoded in the pipeline logic.
  - fix: Move visual style and atmospheric details into the environment canon or a separate style configuration object.

- `135` **P1 / scenario_dependent_prompt**
  - evidence: "aged residential interior, modest domestic clutter"
  - why: Duplicate of the hardcoded fallback scenario string found in the photorealistic prompt generator.
  - fix: Centralize scenario defaults in a configuration file or SOT.

## `backend/scripts/experiment_panorama_and_quad.py`

- `72-77` **P1 / scenario_dependent_prompt**
  - evidence: Soft natural daylight from windows mixed with dim domestic practicals (weak floor lamp, faint television glow)... dust motes, scuff marks... aged residential interior
  - why: The prompt hardcodes specific lighting, props, and textures that belong to a specific story scenario, preventing the script from being used for arbitrary environments (e.g. sci-fi, clean modern, or outdoor-adjacent).
  - fix: Move these stylistic and environmental details into the 'canon' or 'spatial' data structure and inject them dynamically.

- `97-101` **P1 / scenario_dependent_prompt**
  - evidence: soft natural daylight + dim practicals... aged residential interior, modest domestic clutter
  - why: Redundant hardcoding of scenario-specific lighting and fallback descriptions in the quad-view prompt, biasing visual generation regardless of the input floor plan's actual context.
  - fix: Derive lighting and atmosphere descriptions from the structured canon input instead of hardcoding them in the prompt template.

## `backend/scripts/experiment_plan_to_photo.py`

- `53-55` **P1 / scenario_dependent_prompt**
  - evidence: 인명이 붙은 방 → "the small bedroom" / "the adjacent small bedroom"
  - why: Hardcodes specific replacement strings for character-owned rooms, assuming a specific room type ('small bedroom') and size, which biases arbitrary scenarios toward a specific domestic setting.
  - fix: Implement a generic rule to strip possessive names or use a structured mapping from the world SOT to provide neutral room labels.

- `62-65` **P1 / scenario_dependent_prompt**
  - evidence: "weathered red mark on wall", "circular stain", "faded ring shape", "dark dried floor stain"
  - why: Hardcodes specific visual details (stains, red marks, weathered textures) that bias the T2I prompt towards a crime or thriller genre, even if the input scenario is unrelated.
  - fix: Move these visual descriptors to a scenario-specific 'visual style' or 'prop list' SOT rather than hardcoding them in the base system prompt.

- `70-72` **P1 / llm_closed_list_instruction**
  - evidence: "low angle through doorway/door gap" + "bedroom" + "floor stain"
  - why: Uses a closed list of specific trope combinations (dolls, backpacks, floor stains in bedrooms) to drive visual routing and safety behavior. This is highly scenario-specific and fragile.
  - fix: Define safety constraints using abstract categories or a general moderation layer that does not rely on specific prop/location combinations.

## `backend/scripts/experiment_scene_aware_line_quad.py`

- `98-104` **P1 / llm_closed_list_instruction**
  - evidence: 35mm cinematic still aesthetic... no blood, no broken glass... Say 'a small bedroom door' not '<character name>'s bedroom'
  - why: The prompt hardcodes specific visual styles (35mm, natural daylight) and narrative tropes (blood, broken glass) to define 'neutrality'. It also uses specific naming examples to enforce anonymity. These constraints should be managed via a structured style/rule SOT to allow the pipeline to handle diverse genres or projects without manual prompt editing.
  - fix: Move style and content constraints into a structured 'Environment Canon' or 'Style SOT' that is injected into the prompt dynamically based on the project's requirements.

- `144` **P1 / scenario_dependent_prompt**
  - evidence: base_photo_t2i (contains NORTH/SOUTH/EAST/WEST wall sentences)
  - why: The prompt hardcodes a semantic assumption about the internal structure of a natural-language field ('t2i_prompt'). This creates a fragile dependency on the upstream generator's phrasing and may lead to LLM hallucination if the input text does not follow this specific cardinal-direction pattern.
  - fix: Instead of assuming the structure of a raw string, pass the wall-by-wall information as a structured dictionary in the context, or use a validator to ensure the input string meets the expected format before passing it to the LLM.

## `backend/scripts/experiment_set_design.py`

- `127` **P1 / scenario_dependent_prompt**
  - evidence: "Photorealistic cinematic. ... include exactly 3 person-shaped DOTTED LINE silhouettes"
  - why: The prompt hardcodes a specific visual style ('Photorealistic cinematic') and a fixed number of silhouettes ('exactly 3'), ignoring the project's actual style SOT and the specific character counts provided in the shot data.
  - fix: Inject the project's style description from a structured SOT and calculate the required silhouette count based on the maximum character count in the provided shots.

- `202-205` **P2 / scenario_dependent_prompt**
  - evidence: "Maintain the same wall colors, flooring, furniture style, window shape, and overall condition."
  - why: The consistency instruction assumes the location is an interior space (furniture, windows, flooring), which may bias or confuse the model when generating exterior or abstract locations.
  - fix: Use more generic consistency instructions (e.g., 'Maintain all architectural and environmental details') or derive specific attributes to maintain from the location's visual traits.

## `backend/scripts/experiment_set_regen.py`

- `40-42` **P1 / blind_string_mutation**
  - evidence: re.sub(r'NO people\s*[—–-]\s*instead include.*?placement guides\.?', '', prompt, flags=re.DOTALL)
  - why: This performs a blind regex replacement on natural language prompts to remove specific silhouette instructions and appends a hardcoded 'Empty room only' constraint. This assumes a specific prompt structure and scene type, which will fail or produce incorrect visual results for non-room or differently structured scenarios.
  - fix: Instead of mutating strings, the prompt generation logic should be controlled via structured parameters (e.g., a 'silhouette' boolean flag) in the SOT that determines whether to include or exclude these instructions during initial assembly.

- `60-75` **P2 / scenario_dependent_prompt**
  - evidence: "Maintain the same wall colors, flooring, furniture style, window shape, and overall condition." and "Same room, different angle"
  - why: The prompt instructions for visual consistency are polluted with indoor-specific tropes (walls, flooring, furniture, windows, 'room'). This biases the image generator and makes the script unsuitable for outdoor, natural, or abstract environments.
  - fix: Move consistency instructions to a structured style-guide or environment-type SOT that provides context-appropriate attributes (e.g., 'foliage type' for forests vs 'wall color' for rooms).

- `115-116` **P1 / semantic_string_judgment**
  - evidence: pattern = rf'{short_id}(O\d{2,3})' ... re.search(pattern, t2i_text)
  - why: The code uses regex to parse a natural language prompt string to extract outfit IDs (e.g., O01). This extracted ID is then used to query the database and attach reference images. This is a high-signal violation where visual routing depends on string patterns in generated text rather than structured metadata.
  - fix: Pass the outfit ID as a structured field in the shot/entity metadata rather than attempting to extract it from the prompt text.

- `214` **P2 / scenario_dependent_code**
  - evidence: if "L05" not in s.get("visible_entities", [])
  - why: The script contains a hardcoded scenario-specific location ID ('L05') used to filter scenes for processing. This makes the script non-portable and couples the logic to a specific project's data.
  - fix: Pass the target location ID or filter criteria as a command-line argument or configuration parameter.

## `backend/scripts/experiment_set_shots.py`

- `59-60` **P2 / scenario_dependent_code**
  - evidence: if "L05" not in ve:
  - why: Hardcoded scenario-specific location ID ('L05') used to filter scenes, making the script non-portable to other scenarios or episodes.
  - fix: Pass the target location ID as a parameter or configuration instead of hardcoding it in the logic.

- `96-97` **P1 / semantic_string_judgment**
  - evidence: pattern = rf'{short_id}(O\d{{2,3}})'\n            m = re.search(pattern, t2i_text)
  - why: The script parses the generated T2I prompt text using regex to determine entity-outfit relationships. This makes visual reference attachment dependent on the exact string formatting of the LLM-generated prompt.
  - fix: Store entity-outfit associations in a structured manifest or metadata field (e.g., in shot_data) rather than extracting them from the natural language prompt string.

## `backend/scripts/experiment_set_v3.py`

- `71-79` **P1 / scenario_dependent_code**
  - evidence: if info.get("short_id") == "L05": ... if "L05" not in ve: continue
  - why: The data loading and shot filtering logic is hardcoded to a specific location ID ('L05'), preventing the script from being used for arbitrary locations without manual code modification.
  - fix: Pass the target location ID as a parameter to the function or script.

- `121-126` **P1 / llm_closed_list_instruction**
  - evidence: blood, mess, unnaturally clean, etc.
  - why: The prompt defines 'States' (story-driven changes) using a closed list of specific story tropes, which biases the LLM's analysis of open-world scenario text toward these specific examples.
  - fix: Replace specific trope examples with abstract definitions or move them to a structured world-rule SOT.

- `134` **P1 / llm_closed_list_instruction**
  - evidence: NEVER include skin tone / face color modifiers (pale, drained, flushed, ashen, gray, white face, etc.)
  - why: This is a hardcoded negative constraint list for visual generation. It forces the LLM to filter specific semantic descriptors from the story text based on a fixed list of 'forbidden' tokens.
  - fix: Move visual generation constraints to a centralized style-guide or prompt-engineering module rather than embedding them in scenario analysis prompts.

- `134` **P1 / llm_closed_list_instruction**
  - evidence: Express fear/shock through body language and expression words only (frozen, trembling, wide eyes, clenched jaw, etc.)
  - why: This is a hardcoded positive constraint list that forces the LLM to use specific tokens for character emotions, overriding the original scenario's descriptive nuance with a fixed set of tropes.
  - fix: Allow the LLM to derive appropriate descriptors from the scenario context or a structured character-state SOT.

- `232-234` **P2 / scenario_dependent_prompt**
  - evidence: Maintain identical wall colors, flooring, furniture style, window shape.
  - why: The prompt assembly hardcodes specific architectural/visual features to ensure consistency. This assumes all sets will have these specific properties (e.g., windows, furniture).
  - fix: Generalize the consistency instruction or derive relevant features from the location's visual traits metadata.

## `backend/scripts/experiment_set_v4.py`

- `101-125` **P2 / llm_closed_list_instruction**
  - evidence: 문, 창문, 싱크대, 냉장고, TV, 침대, 식탁, 가스레인지, 선반 등
  - why: The VLM prompts for blueprint extraction and consistency verification use a closed list of domestic furniture/props. This biases the visual analysis toward indoor/residential settings and may fail to identify key structures in other environments (e.g., a forest, a spaceship).
  - fix: Inject the list of expected 'fixed installations' from the location's structured metadata (SOT) into the prompt instead of hardcoding domestic examples.

- `177-179` **P1 / scenario_dependent_prompt**
  - evidence: NEVER include gore (blood-soaked, corpse, dead body, exposed flesh, torn) — soften to (motionless figure, slumped, stain, mark)
  - why: The prompt contains a closed list of scenario-specific tropes and instructions on how to 'soften' them. This logic is hardcoded into the system prompt rather than being derived from a structured world-rule SOT.
  - fix: Move content constraints and 'softening' rules to a structured configuration or a dedicated safety/style module that can be adjusted per project.

- `392-394` **P1 / semantic_string_judgment**
  - evidence: re.search(rf'(?<![CO\d]){sid}', t2i_text)
  - why: The system decides whether to attach a reference image (character or prop) by searching for entity IDs within natural language prompt text. This is a pattern-based semantic judgment that relies on the LLM correctly emitting IDs in the string.
  - fix: Pass visible entities as a structured list (e.g., a JSON array of IDs) alongside the prompt text instead of parsing the prompt string to find them.

- `431-442` **P0 / blind_string_mutation**
  - evidence: re.sub(r'blood-soaked torn shoulder and collarbone of the slumped corpse', 'a motionless figure slumped behind the curtain', text)
  - why: This function performs hardcoded, scenario-specific string replacements for very specific story beats. It pollutes the pipeline with content from a single work and will fail or produce nonsensical results for any other scenario.
  - fix: Remove hardcoded story-beat replacements. Use a centralized safety filter or a structured 'visual style' SOT to handle content moderation and aesthetic softening.

## `backend/scripts/experiment_set_v5.py`

- `98` **P1 / semantic_string_judgment**
  - evidence: any(kw in desc for kw in ["내부", "실내", "방", "사무실", "조타실"])
  - why: Determines visual generation routing (indoor vs outdoor logic) based on a hardcoded list of Korean keywords, including scenario-specific terms like 'wheelhouse' (조타실).
  - fix: Move location type classification to a structured metadata field in the location SOT or use an LLM classifier.

- `114-117` **P1 / semantic_string_judgment**
  - evidence: any(kw in w for kw in ['room', 'wall', 'floor', 'window', 'curtain', 'bed', 'door', ...])
  - why: Filters open-world story text (t2i_prompt) using a hardcoded list of English nouns to decide what constitutes a 'background element' for the grid prompt.
  - fix: Use an LLM to extract background elements or define them in a structured 'set_dressing' field in the location manifest.

- `123-126` **P1 / scenario_dependent_prompt**
  - evidence: TOP-LEFT: Looking toward the kitchen/sink wall\nTOP-RIGHT: Looking toward the main window wall...
  - why: The grid generation prompt hardcodes a specific room layout (kitchen, window, entrance, bedroom), making the script unusable for arbitrary locations.
  - fix: Parameterize quadrant descriptions based on the specific location's layout defined in the SOT.

- `175-177` **P2 / llm_closed_list_instruction**
  - evidence: NEVER include skin tone/face color modifiers (pale, drained, flushed, ashen, gray). ... soften to (motionless figure, slumped, stain, mark).
  - why: Instructs the LLM to classify and transform open-world meaning based on a closed list of phrases/examples provided in the prompt rather than a structured rule set.
  - fix: Move visual style and safety constraints to a global style SOT or system-level prompt configuration.

- `254-258` **P1 / scenario_dependent_code**
  - evidence: QUADRANT_DIRECTIONS = { "SET_TL": "the TOP-LEFT quadrant (kitchen/sink direction)", ... }
  - why: Hardcodes semantic mapping of technical IDs (SET_TL) to specific story-world locations (kitchen/sink), which is scenario-specific pollution.
  - fix: Derive quadrant labels and directions from the location's structured manifest.

- `386-393` **P1 / blind_string_mutation**
  - evidence: re.sub(r'blood-soaked torn shoulder and collarbone of the slumped corpse', 'a motionless figure slumped behind the curtain', text)
  - why: Performs blind string replacement on visual prompts using highly specific story-beat descriptions as regex targets. This is fragile and bypasses structured analysis.
  - fix: Handle visual transformations (like gore softening) during the LLM analysis phase using structured rules.

## `backend/scripts/experiment_set_v8.py`

- `73` **P2 / scenario_dependent_code**
  - evidence: if "L05" not in ve: continue
  - why: The script logic is hardcoded to filter for a specific location ID ('L05'), which is scenario-specific pollution that prevents the script from being used for arbitrary scenarios without modification.
  - fix: Pass the target location ID as a parameter or configuration variable rather than hardcoding it in the loop.

- `108` **P2 / llm_closed_list_instruction**
  - evidence: Use "previous_shot" when the background state CHANGES due to story events (blood appears, room gets messy, items move)
  - why: The LLM prompt uses specific story-state examples to define the logic for background selection. This biases the model towards these specific tropes and should be replaced with abstract criteria.
  - fix: Replace specific examples with abstract categories of state change (e.g., 'permanent environmental modifications' or 'transient object movement').

- `169-180` **P1 / semantic_string_judgment**
  - evidence: re.search(rf'{sid}(O\d{{2,3}})', t2i_text)
  - why: The code determines which character outfit (O##) to use by parsing the natural language prompt string with regex. This makes visual entity membership and reference attachment dependent on string patterns rather than structured metadata.
  - fix: Pass outfit selection as structured metadata (e.g., a mapping of character IDs to outfit IDs) rather than embedding and parsing them from the prompt string.

- `249-258` **P1 / blind_string_mutation**
  - evidence: re.sub(r'blood-soaked torn shoulder and collarbone of the slumped corpse', 'a motionless figure slumped behind the curtain', text)
  - why: The function uses hardcoded, scenario-specific natural language patterns to perform blind string replacement. This couples the code to a specific story's content and bypasses structured safety or style controls with fragile regex.
  - fix: Move content-based prompt adjustments to a structured SOT or use LLM-based rewriting with general safety guidelines rather than hardcoded story phrases.

## `backend/scripts/experiment_set_v9.py`

- `73-74` **P1 / scenario_dependent_code**
  - evidence: if "L05" not in ve: continue
  - why: Hardcodes a specific location ID ('L05') as a filter, preventing the pipeline from processing other locations without manual code changes.
  - fix: Remove the hardcoded filter or move it to a configuration/argument passed to the script.

- `183-252` **P1 / scenario_dependent_prompt**
  - evidence: fictional Korean film screenplay storyboard... thriller movie script... apartment... kitchen side, bedroom side
  - why: Prompts contain scenario-specific pollution (genre, location type, and room names) that biases the LLM's analysis toward a specific setting instead of remaining open-world.
  - fix: Inject location types and genre context from a structured Source of Truth (SOT) rather than hardcoding them in the prompt template.

- `401-412` **P1 / semantic_string_judgment**
  - evidence: re.search(rf'(?<![CO\d]){sid}', t2i_text)
  - why: Uses regex to detect entity IDs within natural language prompt strings to decide whether to attach reference images. This is unreliable as it depends on the specific phrasing of the prompt rather than structured visibility data.
  - fix: Rely on the structured 'visible_entities' list or a dedicated entity-to-shot mapping rather than parsing natural language strings.

- `439-444` **P1 / blind_string_mutation**
  - evidence: re.sub(r'blood-soaked|corpse|dead body|dead woman|exposed flesh|torn shoulder', '', text, flags=re.IGNORECASE)
  - why: The sanitize_gore function uses a hardcoded list of keywords to perform blind string replacement on story/visual prompts. This is a fragile, pattern-based semantic judgment that can break prompt intent or fail to catch variations.
  - fix: Use a dedicated LLM-based safety/refinement pass or a structured attribute-based system to handle content moderation.

## `backend/scripts/experiment_v4_main_shot_render_temp.py`

- `126-129` **P2 / semantic_string_judgment**
  - evidence: re.search(r"[가-힣]", desc_en) ... [t for t in traits if not re.search(r"[가-힣]", str(t))]
  - why: The code uses regex to detect Korean characters and silently drops visual traits or descriptions that contain them. This is a semantic judgment based on string patterns that can lead to loss of visual information if the source data is mixed-language or if the SOT contains non-English descriptors.
  - fix: Visual traits should be filtered or translated at the SOT/data-ingestion layer based on structured metadata (e.g., a 'language' or 'type' field) rather than using regex in the prompt assembly logic.

- `313-315` **P1 / scenario_dependent_prompt**
  - evidence: "Photorealistic 35mm cinematic still.", "match its wall finish, floor, ceiling, lighting tone, color palette."
  - why: These lines hardcode specific visual styles and technical camera constraints directly into the prompt. This biases all generated images to a specific '35mm cinematic' look and 'photorealistic' style, which should instead be controlled by a structured style SOT or scenario-specific metadata.
  - fix: Move style and technical descriptors to a configuration file or a structured 'Style SOT' that can be varied per project or scenario.

- `322-324` **P2 / scenario_dependent_prompt**
  - evidence: "ignore Korean proper names"
  - why: This prompt instruction asks the LLM to perform semantic classification (distinguishing between descriptors and proper names) on the fly. This logic is prone to inconsistency and should be handled by providing pre-filtered, structured data from the SOT.
  - fix: Ensure the 'visible_entities' data passed to the prompt generator is already cleaned of proper names at the source, rather than relying on the LLM to filter them.

## `backend/scripts/experiment_v4_main_shot_render_with_refs.py`

- `363-366` **P1 / scenario_dependent_code**
  - evidence: LOCATION_FALLBACK = {"L04": "photo_base_dense_low_rise_rooftop_site", "L05": "photo_base_small_rooftop_room_interior"}
  - why: Hardcodes specific location IDs (L04, L05) and their visual node names for the 'Rooftop' scenario. This logic is not portable to other scenarios and forces a specific visual mapping based on ID strings.
  - fix: Inject location-to-node mappings via a configuration file or include them in the planning data (SOT) rather than hardcoding them in the script.

- `413-416` **P2 / scenario_dependent_prompt**
  - evidence: First reference image is the room/space — match its wall finish, floor, ceiling...
  - why: The prompt assumes an indoor 'room/space' context with specific architectural features (wall, floor, ceiling), which will cause issues or hallucinations in scenarios with different environments (e.g., outdoor, space).
  - fix: Use environment-agnostic language or derive environment descriptions from the scene's metadata/location type.

- `423-424` **P2 / scenario_dependent_prompt**
  - evidence: ignore Korean proper names
  - why: Instructs the LLM to filter scenario-specific pollution (Korean names) within the prompt itself, rather than ensuring the input data (Entity Canon) is clean at the source.
  - fix: Ensure the entity trait extraction pipeline removes non-visual proper names before prompt assembly.

## `backend/scripts/generate_line_art_s12.py`

- `13` **P1 / scenario_dependent_prompt**
  - evidence: SHOT_1 = "...Character 1 in cyan... Character 2 in magenta... red tattoo mark... crumpled photograph..."
  - why: The prompt contains hardcoded scenario-specific entities, props, and plot points (S12 specific) that should be dynamically injected from a structured scenario/world SOT to ensure the pipeline remains scenario-agnostic.
  - fix: Parameterize the prompt template to accept character descriptions, prop lists, and scene layouts from a structured data source.

- `15` **P1 / scenario_dependent_prompt**
  - evidence: SHOT_2 = "...Character 1 in cyan... Character 2 in magenta... ritual circle..."
  - why: The prompt contains hardcoded scenario-specific entities and plot points (ritual circle) and manual consistency instructions ('FIXED CORPSE POSE') that should be handled by a structured world/rule SOT.
  - fix: Move scenario-specific visual requirements and consistency rules into a structured SOT and use a generic prompt generator.

- `20` **P2 / scenario_dependent_code**
  - evidence: operation_type="line_art_s12"
  - why: The operation type is hardcoded to a specific scenario ID ('s12'), indicating that the script or its execution context is coupled to a single story instance.
  - fix: Pass the scenario ID as a variable or argument to the context setter.

## `backend/scripts/generate_line_art_s12_multiturn.py`

- `14-36` **P1 / scenario_dependent_prompt**
  - evidence: SHOT_1 = """...""", SHOT_2_CONTINUATION = """..."""
  - why: The prompts contain hardcoded scenario-specific entities (Character 1/2), props (crumpled photograph, red tattoo), and visual style constants (hex codes) that should be managed by a structured Source of Truth (SOT). This makes the generation logic brittle and scenario-locked.
  - fix: Extract character descriptions, prop definitions, and style constants into a structured SOT and use a template engine to assemble prompts dynamically.

- `41` **P2 / scenario_dependent_code**
  - evidence: operation_type="line_art_multiturn_s12"
  - why: The operation type is hardcoded with a specific scenario ID ('s12'), which prevents the script from being generic or reusable for other scenarios.
  - fix: Parameterize the operation type or pass the scenario ID as a separate metadata field.

## `backend/scripts/generate_line_art_s12_v2.py`

- `14-32` **P1 / scenario_dependent_prompt**
  - evidence: SHOT_1 = """Pure line drawing... interior of a cramped Korean rooftop room (옥탑방)... Character 1 in cyan (#00E5FF)... Character 2 in magenta (#FF00FF)... orange (#FFA500) geometric outline."""
  - why: The prompt contains hardcoded scenario-specific entities, colors, and props. This prevents the generation logic from being reused for arbitrary scenarios and forces manual script duplication for every new scene.
  - fix: Extract scenario-specific details (characters, colors, props, environment) into a structured SOT and use a generic prompt template to assemble the final string.

- `35-52` **P1 / scenario_dependent_prompt**
  - evidence: SHOT_2_CONTINUATION = """Continue the exact same line drawing style... same cramped Korean rooftop room (옥탑방)... magenta character 2... orange photograph..."""
  - why: This prompt hardcodes continuity logic and specific story elements (e.g., 'magenta character 2', 'orange photograph'). Visual consistency should be managed via structured entity tracking rather than hardcoded prose in a scenario-specific script.
  - fix: Implement a scene-state or entity-tracking system that passes structured attributes (color, pose, status) to the prompt generator.

## `backend/scripts/verify_scene_director.py`

- `31-33` **P2 / llm_closed_list_instruction**
  - evidence: 대화 속 언급, 회상, 상상 속 인물은 제외 / 빙의/변신 등으로 육체가 존재하면 포함 / 엔티티 목록에 없는 인물(단역, 엑스트라)은 무시
  - why: The prompt hardcodes specific scenario tropes (flashbacks, imagination, possession) to define 'physical presence'. This logic is genre-dependent and should be driven by a structured world/rule SOT rather than being scattered in validation prompts.
  - fix: Move these semantic inclusion/exclusion rules to a project-level configuration or a shared 'Scenario Analysis Rules' SOT that can be injected into the prompt.

- `100` **P2 / schema_or_enum_drift**
  - evidence: for etype in ["characters", "locations", "props"]:
  - why: Hardcoded list of entity types for verification. If the entity schema expands (e.g., to include 'creatures' or 'vehicles' as separate categories), this verification script will silently omit them from the context provided to the LLM.
  - fix: Iterate over the keys of the entities dictionary or use a centralized entity type registry.

- `104` **P2 / blind_string_mutation**
  - evidence: etype[:-1]
  - why: Blindly slicing the last character to singularize entity types for the prompt. This assumes all types end in 's' and will fail for types like 'scenery' or 'staff', leading to confusing labels in the LLM prompt.
  - fix: Use a mapping dictionary for singular labels or store the singular name in the entity schema.

## `prompts/_base/background_chain_planning/1.202604271600/system.md`

- `16-19` **P1 / llm_closed_list_instruction**
  - evidence: different room state (clean / lived-in / disturbed / heavily-ransacked) ... e.g. "open window with torn curtain"
  - why: The prompt uses a closed list of narrative tropes and a specific prop example to define when a background node should be split. This biases the LLM toward these specific states and should instead be derived from the provided VISUAL_WORLD_RULES or a structured state schema.
  - fix: Remove specific state examples and the 'torn curtain' prop. Instruct the LLM to split nodes based on state changes defined in the VISUAL_WORLD_RULES or the input shot beats.

- `49` **P1 / llm_closed_list_instruction**
  - evidence: surface condition (clean / disturbed / ransacked etc.)
  - why: Hardcoded state examples in the field description instruct the LLM to classify open-world scenario text into a narrow set of predefined tropes.
  - fix: Replace the hardcoded list with a reference to the state categories defined in the project's visual world rules.

- `68` **P1 / llm_closed_list_instruction**
  - evidence: (day vs. night vs. dusk; clean vs. disturbed vs. ransacked)
  - why: This strict rule forces the LLM to use a specific set of semantic states for node splitting, which may conflict with or limit the actual requirements of a specific scenario.
  - fix: Abstract these state categories into the VISUAL_WORLD_RULES or a project-specific state-change schema provided in the input.

## `prompts/_base/background_chain_planning/2.202604272110/schema.json`

- `5-8` **P1 / llm_closed_list_instruction**
  - evidence: (street, road, coast, sea, forest, yard, park, exterior rooftop, public square, beach, dock, vehicle exterior, etc.)
  - why: The LLM is instructed to classify open-world location types into a 'skip_chain' boolean based on a hardcoded list of environment tropes. This logic bypasses structured world-state (SOT) metadata and relies on the LLM's interpretation of a closed list of examples to drive pipeline routing and visual continuity strategy.
  - fix: Remove the specific environment examples from the schema description. Instead, the location metadata (SOT) should provide a boolean or enum (e.g., 'environment_type': 'outdoor') which the LLM or a simple code check uses to set 'skip_chain'.

## `prompts/_base/background_chain_planning/2.202604272110/system.md`

- `11-22` **P1 / llm_closed_list_instruction**
  - evidence: OUTDOOR / OPEN-AIR (street, road, alley, coast, sea, beach, dock, yard, garden, park, public square, forest, mountain, exterior rooftop view, vehicle exterior, open-air market, etc.)
  - why: The prompt instructs the LLM to make a critical pipeline routing decision (skip_chain) by classifying open-world location text against a hardcoded list of examples. This is a brittle semantic judgment that should be driven by structured metadata.
  - fix: Replace the keyword-based classification with a structured boolean or enum (e.g., 'is_controlled_environment') in the input location context.

- `32-88` **P2 / scenario_dependent_prompt**
  - evidence: clean / lived-in / disturbed / heavily-ransacked
  - why: The prompt hardcodes specific room states as the primary criteria for node splitting and description. These are domain-specific tropes that bias the LLM and should instead be provided via the 'visual_world_rules' or 'visual_traits' input.
  - fix: Generalize the instruction to split nodes based on 'significant visual state changes' and move the specific state definitions to the project-level SOT or input context.

## `prompts/_base/background_chain_planning/2.202604272110/user_template.md`

- `14-20` **P1 / llm_closed_list_instruction**
  - evidence: Decide first whether to skip chain rendering... A) If SKIP applies (outdoor / open-air)... B) Otherwise (indoor / enclosed / fixed-set)
  - why: The prompt uses natural language categories ('outdoor / open-air' vs 'indoor / enclosed / fixed-set') to drive technical pipeline routing. This forces the LLM to make a semantic judgment on open-world location descriptions to determine the JSON structure and execution path, which is prone to inconsistency and should be defined in the location's structured metadata.
  - fix: Include a structured field in the location context (e.g., 'requires_chain_planning': boolean) and use that to explicitly instruct the LLM on which JSON branch to output.

## `prompts/_base/background_chain_planning/3.202604290417/schema.json`

- `5-8` **P2 / llm_closed_list_instruction**
  - evidence: (street, road, coast, sea, forest, yard, park, exterior rooftop, public square, beach, dock, vehicle exterior, etc.)
  - why: The schema description provides a closed list of domain tropes to guide the LLM in classifying open-world locations as 'OUTDOOR'. This classification determines whether to skip background chain rendering, a significant routing decision that should ideally be driven by structured metadata (SOT) rather than heuristic string matching or LLM inference against a hardcoded list in the schema.
  - fix: Inject the 'is_outdoor' or 'skip_chain' flag into the prompt context from the location's SOT metadata, rather than asking the LLM to infer it from a list of examples in the schema description.

## `prompts/_base/background_chain_planning/3.202604290417/system.md`

- `18-29` **P1 / llm_closed_list_instruction**
  - evidence: If the location is OUTDOOR / OPEN-AIR (street, road, alley, coast, sea, beach, dock, yard, garden, park, public square, forest, mountain, exterior rooftop view, vehicle exterior, open-air market, etc.)
  - why: The skip_chain routing decision is driven by a hardcoded list of location keywords in the system prompt. This forces the LLM to perform semantic classification against a closed list of examples rather than relying on structured metadata from the location SOT.
  - fix: Replace the keyword-based heuristic with a structured boolean or enum (e.g., 'continuity_mode': 'skip' | 'plan') provided in the LOCATION CONTEXT input.

- `38-42` **P1 / llm_closed_list_instruction**
  - evidence: different time-of-day (day / night / dusk / dawn) ... different room state (clean / lived-in / disturbed / heavily-ransacked)
  - why: The logic for splitting background nodes relies on a hardcoded list of semantic states and tropes (e.g., 'ransacked'). This limits the planner's ability to handle arbitrary or project-specific state changes that aren't explicitly listed in the system prompt.
  - fix: Move the definition of significant state-change dimensions to the VISUAL_WORLD_RULES or provide a structured list of valid states for the specific location in the input context.

## `prompts/_base/background_chain_planning/3.202604290417/user_template.md`

- `14-20` **P1 / llm_closed_list_instruction**
  - evidence: A) If SKIP applies (outdoor / open-air): ... B) Otherwise (indoor / enclosed / fixed-set):
  - why: The pipeline uses the LLM to perform a semantic classification (indoor vs. outdoor) to decide whether to skip background chain generation. This makes routing dependent on natural language interpretation of 'open-world' descriptions rather than structured metadata, which can lead to inconsistent behavior across different scenarios.
  - fix: Define the 'skip_chain' or 'environment_type' property as a structured field in the location SOT and pass it as a boolean or enum to the prompt, rather than asking the LLM to decide based on a description.

## `prompts/_base/background_chain_planning/4.202604291315/schema.json`

- `7` **P2 / llm_closed_list_instruction**
  - evidence: (street, road, coast, sea, forest, yard, park, exterior rooftop, public square, beach, dock, vehicle exterior, etc.)
  - why: The schema description uses a hardcoded list of environment tropes to define the semantic boundary for the 'skip_chain' routing decision. This biases the LLM toward specific outdoor types and should ideally be handled by a centralized world-rule SOT or a more abstract definition of environment properties.
  - fix: Remove the specific list of examples from the schema description. Instead, refer to a 'is_outdoor' or 'is_open_air' property that should be determined during the location analysis phase based on project-wide world rules.

## `prompts/_base/background_chain_planning/4.202604291315/system.md`

- `21-25` **P1 / llm_closed_list_instruction**
  - evidence: rooftop slab, building yard, courtyard, parking lot, building entrance staircase, vehicle deck of an enclosed boat... a road far from any building, an unrelated forest, a wide beach, a public street block, a mountain trail, a public square
  - why: The LLM is instructed to classify open-world locations into 'IMMEDIATE EXTERIORS' or 'DETACHED OPEN AREA' using a hardcoded list of examples to drive the skip_chain routing decision. This creates a maintenance burden and potential for misclassification as the variety of locations grows.
  - fix: Move location classification (chained vs. detached) to a structured metadata field in the input JSON or define the classification criteria in the VISUAL_WORLD_RULES SOT.

- `48-82` **P1 / scenario_dependent_prompt**
  - evidence: clean / lived-in / disturbed / heavily-ransacked
  - why: Specific visual states and surface conditions are hardcoded as examples for node splitting and description generation. These are domain-specific tropes that should be provided by the project-specific VISUAL_WORLD_RULES rather than being baked into the base system prompt.
  - fix: Remove specific state examples from the system prompt and rely on the VISUAL_WORLD_RULES excerpt (line 59) to define valid states for the current project.

## `prompts/_base/background_chain_planning/4.202604291315/user_template.md`

- `16-20` **P1 / llm_closed_list_instruction**
  - evidence: (outdoor / open-air) ... (indoor / enclosed / fixed-set)
  - why: The prompt provides a closed list of semantic examples to guide a binary routing decision (skip_chain). This forces the LLM to map open-world location descriptions to these specific tropes, which may not be exhaustive or appropriate for all scenarios. Such logic should be defined in the system message or derived from the structured world rules rather than hard-coded in the user template.
  - fix: Remove the parenthetical examples from lines 16 and 20. Rely on the 'SKIP DECISION' logic in the system message and the provided 'world_rules_excerpt' to guide the LLM's decision-making process.

## `prompts/_base/background_chain_render/1.202604271700/system.md`

- `17` **P2 / scenario_dependent_prompt**
  - evidence: Eye-level approx 1.6m, slight wide angle ~28mm
  - why: Hardcoding a default camera height and focal length in the system prompt can conflict with scenario-specific camera requirements (e.g., low-angle shots, telephoto shots) even with the provided caveat, as LLMs often over-prioritize explicit numeric constraints in 'Hard Constraints' sections.
  - fix: Pass camera parameters as structured variables in the user message rather than hardcoding defaults in the system prompt.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: NO broken glass, NO action, NO weapons. Reflect atmosphere only via worn surfaces, dust, dim light, weathered furniture, etc.
  - why: This instruction hardcodes both specific negative constraints (broken glass, weapons) and a specific 'gritty' aesthetic (worn surfaces, dust, weathered furniture). This biases the visual generation pipeline toward a specific genre or state, preventing the system from accurately rendering clean, modern, or high-end backgrounds as defined in an arbitrary open-world scenario.
  - fix: Move stylistic preferences and specific prop exclusions to a structured Style of Truth (SOT) or scenario-specific configuration rather than hardcoding them in the base system prompt.

## `prompts/_base/background_chain_render/1.202604271700/user_template.md`

- `21` **P1 / scenario_dependent_prompt**
  - evidence: NO people, NO blood, NO weapons, NO action — empty/quiet space only.
  - why: Hardcodes semantic exclusions and atmospheric constraints (quiet/empty) that may conflict with specific story genres like horror, war, or cluttered environments. These should be driven by the scenario's visual rules or metadata rather than being hardcoded in a base template.
  - fix: Remove hardcoded exclusions and replace with a reference to scenario-specific style/content rules provided in the context.

- `24-25` **P1 / scenario_dependent_prompt**
  - evidence: thoroughly describe wall finish, floor, ceiling, lighting, palette. ... doors, windows, fixtures, furniture.
  - why: Assumes all root background nodes are interior architectural spaces. This forces the LLM to hallucinate or misapply interior descriptors to outdoor or abstract environments (e.g., forests, space, or open landscapes).
  - fix: Generalize the requirement to 'environmental boundaries and surfaces' or provide a conditional list of descriptors based on the node's environment type (e.g., interior vs. exterior).

## `prompts/_base/background_chain_render/2.202604282201/system.md`

- `16-17` **P1 / scenario_dependent_prompt**
  - evidence: 35mm cinematic still aesthetic... Eye-level approx 1.6m, slight wide angle ~28mm
  - why: Hardcoding specific focal lengths and aesthetic styles ('35mm', '28mm') into the system prompt limits the visual variety of the pipeline. These parameters should be provided by a global style SOT or per-shot metadata.
  - fix: Move aesthetic and camera defaults to a configuration object or a 'Visual Style' SOT section.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: NO people, NO blood, NO broken glass, NO action, NO weapons.
  - why: This is a hardcoded list of semantic exclusions. While 'no people' is appropriate for a background render, 'no blood' and 'no broken glass' are scenario-dependent (e.g., a crime scene or post-disaster setting) and represent domain trope pollution.
  - fix: Replace hardcoded exclusions with a dynamic 'Visual Constraints' list derived from the scenario's genre or environment rules.

- `36-43` **P2 / scenario_dependent_prompt**
  - evidence: TV is in the upper-left... sofa cluster... window on the right... DO NOT redraw the TV/sofa/window
  - why: The use of specific domestic props (TV, sofa) in instructions biases the LLM's spatial reasoning toward residential interiors, which may be inappropriate for other scenario types (e.g., outdoor, industrial, or sci-fi).
  - fix: Use abstract placeholders like '[Primary Object]' or '[Furniture A]' in guide examples.

## `prompts/_base/background_chain_render/2.202604282201/user_template.md`

- `21` **P2 / llm_closed_list_instruction**
  - evidence: NO people, NO blood, NO weapons, NO action — empty/quiet space only.
  - why: Hardcoding specific visual exclusions like 'blood' or 'weapons' in a base template prevents the pipeline from supporting scenarios where these elements are contextually appropriate (e.g., a crime scene, a hospital, or an armory). These constraints represent domain-specific tropes that should be emitted by a structured world/rule SOT or passed as dynamic style variables.
  - fix: Replace the hardcoded list with a template variable such as {content_constraints} or {negative_prompt_instructions} derived from the scenario's genre or safety configuration.

## `prompts/_base/background_classify/1.202604300430/system.md`

- `6-21` **P1 / semantic_string_judgment**
  - evidence: has at least one indoor anchor
  - why: The pipeline routes rendering strategies based on the LLM's semantic interpretation of 'indoor' vs 'outdoor' locations. This open-world classification of scenario text drives critical visual pipeline branching without a structured SOT attribute.
  - fix: Provide an explicit 'is_indoor' boolean in the location input data and use it in the heuristic logic.

- `11-13` **P2 / scenario_dependent_prompt**
  - evidence: rooftop building, bg_rooftop_unit, 옥탑방_단지
  - why: The prompt contains scenario-specific tropes (rooftop units) and Korean-specific place names as examples. This pollutes the base system prompt with domain-specific nomenclature that should be abstracted to remain generic.
  - fix: Replace scenario-specific examples with generic placeholders like 'building_a' or 'location_type_x'.

## `prompts/_base/background_classify/3.202604300520/system.md`

- `18-20` **P1 / llm_closed_list_instruction**
  - evidence: Korean clues that often imply indoor: 내부 / 안 / 방 / 실 / 층 / 차내 / 매장 안 / 사무실 ... Korean clues: 외부 / 옥상 / 거리 / 도로 / 공터 / 골목 / 해안 / 숲 / 마당
  - why: The prompt uses a closed list of specific Korean tokens to drive open-world semantic classification (is_indoor). This biases the LLM toward specific vocabulary and may fail or misclassify locations that use synonymous or context-dependent terminology not present in the list.
  - fix: Remove the specific keyword lists. Instead, provide high-level spatial reasoning principles or rely on a structured World SOT where location properties are pre-defined or analyzed by a separate spatial reasoning step.

- `53-54` **P1 / scenario_dependent_prompt**
  - evidence: total_shots >= 3 AND has_indoor -> chain_bg
  - why: This is a hardcoded heuristic (magic number '3') that directly routes the visual generation pipeline between dedicated background rendering and reference-based rendering. Such logic should be part of a configurable policy or SOT rather than embedded in a system prompt.
  - fix: Move the threshold and routing logic to a configuration file or a structured rule-set (SOT) that the pipeline consumes, rather than hardcoding the '3 shots' rule in the prompt text.

## `prompts/_base/background_classify/3.202604300520/user_template.md`

- `15` **P1 / llm_closed_list_instruction**
  - evidence: assign kind per the heuristic (chain_bg if total_shots>=3 AND has_indoor, else prev_shot_ref)
  - why: This line embeds a hardcoded semantic classification heuristic ('chain_bg' vs 'prev_shot_ref') based on shot counts and indoor status. This logic dictates visual routing and background handling, but relies on the LLM to correctly interpret and apply the math/logic within a natural language prompt rather than using a structured rule set or code-driven classification.
  - fix: Move the classification logic to the data processing layer before the prompt is called, or define the 'kind' assignment rules in a structured visual world rule SOT.

## `prompts/_base/background_master_plan/1.202604292000/system.md`

- `19` **P2 / scenario_dependent_prompt**
  - evidence: ok-tab-bang_living_room
  - why: Uses a specific cultural/scenario-based name as a negative example. While intended to prevent pollution, the example itself is scenario-specific pollution in a base prompt.
  - fix: Use a generic placeholder like 'protagonist_home_living_room' as the negative example.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: dusk_ransacked, night_blood_curtain_drawn
  - why: The prompt provides specific visual tropes (ransacked, blood) as examples for the state_label field, which is the primary driver for downstream image generation. This biases the LLM toward these specific tropes and encourages hardcoded semantic strings instead of deriving states from a structured world SOT.
  - fix: Replace specific trope examples with abstract categories or instructions to derive state labels from the provided scene text using a structured schema defined in the world SOT.

- `39` **P1 / scenario_dependent_prompt**
  - evidence: day_normal, dusk_ransacked, night_blood_curtain_drawn
  - why: Repetition of scenario-specific visual state examples in field definitions, reinforcing the bias toward specific plot tropes (ransacked, blood) in the generated output.
  - fix: Use generic architectural or lighting state examples (e.g., 'day_clear', 'night_interior_lit') and refer to the world SOT for plot-specific state requirements.

## `prompts/_base/background_master_plan/2.202605091400/schema.json`

- `31` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["main", "kitchen", "rooftop", "stairs", "yard", "exterior", "office"]
  - why: Forces the LLM to categorize backgrounds into a fixed set of common domestic/office locations, which fails for non-urban or non-modern scenarios (e.g., sci-fi, fantasy, or nature-based stories).
  - fix: Change to a string field or move the enum to a scenario-specific configuration that is injected at runtime.

- `39-43` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["normal", "quiet", "busy", "busy_exit", "ransacked", "clean_after", "blood_scene", "intrusion", "arrival", "evidence_display", "dream_or_vision_state"]
  - why: Contains scenario-specific narrative tropes (e.g., 'blood_scene', 'ransacked', 'evidence_display') that pollute the base schema with crime-genre assumptions, biasing arbitrary future scenarios.
  - fix: Replace the hardcoded enum with a string field or a dynamic enum sourced from the specific scenario's world-building rules.

## `prompts/_base/background_master_plan/2.202605091400/system.md`

- `26` **P1 / llm_closed_list_instruction**
  - evidence: "main" | "kitchen" | "rooftop" | "stairs" | "yard" | "exterior" | "office"
  - why: This is a closed list of architectural labels used to classify open-world story locations. It forces diverse settings (e.g., laboratories, dungeons, cockpits) into a narrow set of domestic/office tropes, biasing downstream visual generation.
  - fix: Allow the LLM to generate a semantic space_key based on the scenario text or move this list to a project-specific world-rule SOT.

- `39-43` **P1 / llm_closed_list_instruction**
  - evidence: `normal` / `quiet` / `busy` / `busy_exit` / `ransacked` / `clean_after` / `blood_scene` / `intrusion` / `arrival` / `evidence_display` / `dream_or_vision_state`
  - why: The state_class enum contains genre-specific tropes (crime/thriller) that pollute the master planner's ability to handle arbitrary scenarios. Forcing the LLM to map story events to these specific labels limits visual and narrative flexibility.
  - fix: Define state_class requirements in the input scenario spec or allow the LLM to propose descriptive state keys that are then normalized by a separate genre-aware validator.

## `prompts/_base/background_master_plan/3.202605092023/schema.json`

- `15` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["main", "kitchen", "rooftop", "stairs", "yard", "exterior", "office"]
  - why: The space_key_hint enum (also appearing on line 36) restricts location categorization to a fixed set of residential/office types, which fails to scale to diverse scenarios such as wilderness, industrial, or fantasy settings.
  - fix: Replace the fixed enum with a dynamic reference to a world-building SOT or use broader, more abstract categories (e.g., interior/exterior/transitional).

- `44-48` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["normal", "quiet", "busy", "busy_exit", "ransacked", "clean_after", "blood_scene", "intrusion", "arrival", "evidence_display", "dream_or_vision_state"]
  - why: The state_class enum hardcodes specific narrative tropes like 'blood_scene', 'ransacked', and 'evidence_display' into the schema, forcing the LLM to map arbitrary story events into a narrow, pre-defined set of visual states.
  - fix: Abstract the state_class into visual/narrative intensity levels or move these trope-specific labels to a scenario-specific configuration file.

## `prompts/_base/background_master_plan/3.202605092023/system.md`

- `19` **P1 / llm_closed_list_instruction**
  - evidence: "main" | "kitchen" | "rooftop" | "stairs" | "yard" | "exterior" | "office"
  - why: Forces open-world story locations into a hardcoded set of spatial categories. This causes semantic drift when the scenario involves spaces not in the list (e.g., a 'spaceship' or 'cave'), leading to the 'main' fallback mentioned on line 90.
  - fix: Allow the LLM to generate a semantic 'space_key' based on the scenario context or provide the valid space keys for the specific building group in the input context.

- `43` **P1 / llm_closed_list_instruction**
  - evidence: `normal` / `quiet` / `busy` / `busy_exit` / `ransacked` / `clean_after` / `blood_scene` / `intrusion` / `arrival` / `evidence_display` / `dream_or_vision_state`
  - why: The state_class enum contains highly specific story tropes (e.g., 'blood_scene', 'ransacked', 'evidence_display') that pollute the base prompt with scenario-specific assumptions. This limits the system's ability to handle genres or plots where these states are irrelevant or where other states are critical.
  - fix: Move state classification to a scenario-specific configuration or allow the LLM to define the state label naturally, using a broader set of architectural/atmospheric categories if an enum is required.

- `74-78` **P2 / scenario_dependent_prompt**
  - evidence: Example (group `bg_large_mart` covers L09 외부 + L10 매장 + L14 사무실)
  - why: Uses a concrete scenario (a large mart) to define the logic for floor plan linking. While illustrative, it embeds specific domain nomenclature like 'sales_floor' and 'exterior_entrance' as the primary reference for the LLM's reasoning pattern.
  - fix: Use abstract placeholders (e.g., Group_A, Loc_01, Space_X) in examples to ensure the LLM focuses on the structural logic rather than specific scenario types.

## `prompts/_base/background_planner/1.202604290417/schema.json`

- `24` **P2 / scenario_dependent_prompt**
  - evidence: e.g. 'okt_room'
  - why: The use of 'okt_room' (옥탑방) as a primary example for a building group is a scenario-specific trope that can bias the LLM's spatial reasoning or naming conventions in non-urban or different genre scenarios.
  - fix: Replace with a generic example like 'building_a' or 'main_house'.

- `146` **P1 / llm_closed_list_instruction**
  - evidence: enum: ["outdoor_3+", "low_freq_2", "single_shot"]
  - why: This enum forces the LLM to perform a combined semantic (outdoor vs indoor) and quantitative (shot count) classification into a single string. This logic is redundant as 'shot_count' is already a field (line 140) and 'outdoor' status should be a structured property of the location rather than a string-based classification label.
  - fix: Split into separate fields: 'is_outdoor' (boolean) and 'frequency_category' (enum), or derive this classification in post-processing logic based on the 'shot_count' and location metadata.

## `prompts/_base/background_planner/2.202604291245/schema.json`

- `24` **P2 / scenario_dependent_prompt**
  - evidence: e.g. 'okt_room'
  - why: The description uses a specific Korean drama trope (rooftop room) as a hardcoded example in a base schema, which can bias the LLM toward specific architectural patterns.
  - fix: Replace with a generic architectural example like 'main_building' or 'detached_house'.

- `146` **P1 / llm_closed_list_instruction**
  - evidence: ["outdoor_3+", "low_freq_2", "single_shot"]
  - why: This enum forces the LLM to perform semantic classification and frequency counting (spatial type + shot count) to drive pipeline routing. These heuristics are brittle and should be handled by code or a structured SOT rather than being encoded as string-based buckets in the LLM output schema.
  - fix: Separate spatial classification (indoor/outdoor) from frequency metadata, and let downstream logic handle the '3+' or 'low_freq' thresholds.

## `prompts/_base/background_planner/2.202604291245/system.md`

- `10-24` **P1 / llm_closed_list_instruction**
  - evidence: bathroom, office, meeting room, CEO room, living room, bedroom, hallway, kitchen, storage, rooftop slab, parking lot, entrance plaza, shop front sidewalk
  - why: The prompt uses a closed list of common architectural tropes to instruct the LLM on how to determine physical connectivity and building membership. This biases the planner toward specific modern/urban settings and may lead to incorrect groupings in scenarios with different architectural logic (e.g., sci-fi, fantasy, or historical).
  - fix: Replace specific room and feature examples with abstract physical constraints or move these examples to a structured 'Architectural Logic' SOT that can be swapped per project.

- `30` **P2 / scenario_dependent_prompt**
  - evidence: apt_unit_a, studio_loft, cafe_first_floor, rooftop_dwelling, mart_complex
  - why: The identifier examples contain specific scenario types (cafe, mart, loft) which act as subtle pollution for the LLM's naming conventions.
  - fix: Use generic placeholders for ID examples, such as complex_alpha or building_01.

- `60` **P2 / scenario_dependent_prompt**
  - evidence: cb_l05_living_night_blood
  - why: The example ID includes a specific narrative state ('blood') which is scenario-specific pollution and may bias the LLM to look for or create similar violent state variants.
  - fix: Change the example to a neutral state variant, e.g., cb_l05_living_night_v2.

## `prompts/_base/background_planner/3.202604291500/schema.json`

- `24` **P2 / scenario_dependent_prompt**
  - evidence: e.g. 'okt_room'
  - why: The example 'okt_room' (rooftop room) is a scenario-specific trope (common in K-dramas) used in a base schema description, which can bias the LLM toward specific architectural patterns.
  - fix: Replace with a neutral example like 'main_building' or 'residence_01'.

- `157` **P1 / llm_closed_list_instruction**
  - evidence: enum: ["outdoor_3+", "low_freq_2", "single_shot"]
  - why: The enum 'outdoor_3+' forces the LLM to perform semantic categorization ('outdoor') and apply a frequency heuristic ('3+') simultaneously. This couples visual/spatial semantics with pipeline routing logic in a single string, making it harder to adjust thresholds or handle 'outdoor' logic consistently across different scenarios.
  - fix: Provide raw attributes (is_outdoor: bool, shot_count: int) and let the system or a dedicated logic step determine the 'kind' of handling required.

## `prompts/_base/background_planner/3.202604291500/system.md`

- `10-30` **P1 / llm_closed_list_instruction**
  - evidence: CEO room, mart_complex, rooftop_dwelling, parking lot behind a shop, office tower
  - why: The prompt uses a closed list of modern/urban architectural examples to define 'building_group' membership and connectivity. This biases the LLM's semantic judgment of physical space toward specific genres (corporate/urban) rather than relying on abstract physical rules or a structured World SOT.
  - fix: Replace specific room and building types with abstract physical relationship descriptions (e.g., 'enclosed sub-spaces', 'contiguous structural footprints') and move domain-specific examples to an external SOT or few-shot examples block.

- `65` **P2 / scenario_dependent_prompt**
  - evidence: (/거실 → /안방 → /욕실 etc.)
  - why: Hardcoded Korean room names serve as semantic triggers for floor plan generation logic, creating a dependency on specific domestic scenario nomenclature.
  - fix: Use generic placeholders or refer to the [ALL LOCATIONS] input for valid room labels.

- `82` **P2 / scenario_dependent_prompt**
  - evidence: cb_l05_living_night_blood
  - why: The inclusion of 'blood' as a state identifier example introduces scenario-specific narrative pollution (horror/action tropes) into the technical ID generation pattern.
  - fix: Use neutral state descriptors like 'variant_a', 'damaged', or 'event_1' in examples.

## `prompts/_base/background_prompt/1.202604292053/system.md`

- `15` **P2 / scenario_dependent_prompt**
  - evidence: drawn curtain, broken window, scattered debris
  - why: The examples provided for 'plot-critical visual devices' are narrow and suggest a specific 'damaged' or 'messy' aesthetic, which may bias the model's focus in cleaner or different scenarios.
  - fix: Use a broader range of examples for visual devices, including neutral or positive props (e.g., 'specific flower arrangement', 'open laptop', 'unique wall art').

- `17` **P1 / scenario_dependent_prompt**
  - evidence: dusk_ransacked, night_blood_curtain_drawn
  - why: These examples bake specific narrative tropes into the base system prompt, biasing the LLM's interpretation of the state_label field toward a specific genre (crime/horror) instead of treating it as a generic semantic key.
  - fix: Replace specific trope examples with neutral, structural examples (e.g., 'day_clear', 'night_interior_lit') and move scenario-specific state definitions to the input context or a dedicated SOT.

## `prompts/_base/background_prompt/2.202604300800/system.md`

- `13` **P2 / scenario_dependent_prompt**
  - evidence: standing human height (~1.6m), 35mm-class lens
  - why: Hardcoding specific camera height and lens values in the system prompt limits the flexibility of the pipeline for different cinematic styles or scenarios. These are style examples that should be emitted by a structured world/rule SOT.
  - fix: Move these defaults to a configuration object or the visual_world_rules SOT to allow for scenario-specific camera styles.

- `15` **P2 / scenario_dependent_prompt**
  - evidence: (e.g., 한국어 "옷장")
  - why: The use of a specific language example (Korean) and a specific prop (wardrobe) in a system prompt introduces scenario-specific pollution into a generic instruction set.
  - fix: Use abstract placeholders or multiple language examples to maintain neutrality in the base prompt.

- `17` **P2 / scenario_dependent_prompt**
  - evidence: end t2i_prompt with a "16:9 시네마틱 화면비" / "16:9 cinematic aspect ratio" hint
  - why: Hardcoding specific natural language strings for visual metadata (aspect ratio) into the prompt body creates scenario and language dependency. This should be handled by the image generation parameters or a structured metadata field rather than forced prose.
  - fix: Remove hardcoded strings and pass aspect ratio as a parameter to the generation function, or use a placeholder that the system fills based on the target language.

- `18` **P1 / llm_closed_list_instruction**
  - evidence: state_label drives lighting/mood/decor (e.g., day_norm, dusk_lit, night_dim)
  - why: The LLM is instructed to derive visual mood from technical tokens (day_norm, etc.) without a structured definition of what these states imply. This forces the LLM to use internal bias or pattern-matching for specific string tokens rather than following a world-rule SOT.
  - fix: Provide a mapping or description for each state_label within the visual_world_rules or a dedicated state definition object in the input.

## `prompts/_base/background_prompt/4.202604301033/system.md`

- `13-17` **P2 / scenario_dependent_prompt**
  - evidence: "실제 카메라로 촬영한 다큐멘터리 풍 사진" / "16:9 가로 비율, 실제 카메라 촬영본"
  - why: The prompt hardcodes specific Korean translation examples for style and framing hints. This biases the LLM toward these exact strings and provides irrelevant or confusing context when the source_language is not Korean (e.g., English or Japanese), potentially leading to mixed-language outputs or rigid phrasing.
  - fix: Replace hardcoded language-specific examples with generic instructions or move them to a language-specific configuration mapping that is injected based on the source_language.

- `19` **P1 / llm_closed_list_instruction**
  - evidence: Avoid in source language: words like "cinematic look", "film grain emulation", "color graded", "stylized", "concept art", "illustrated", "rendered", "moody artistic". Prefer instead: words like "real DSLR photo", "natural daylight", "actual location reference", "documentary photo", "matter-of-fact photograph", "no post-processing".
  - why: This is a closed list of semantic visual tropes used to steer the LLM's open-world visual generation. Hardcoding these stylistic constraints in the system prompt prevents the pipeline from supporting scenarios that might require specific 'photoreal' variations (e.g., period-accurate film looks or specific lighting moods) that overlap with the forbidden list. Such definitions should come from a structured style SOT or the visual_world_rules.
  - fix: Move the anti-stylization checklist to a structured style SOT or include it as part of the visual_world_rules input to allow for scenario-specific flexibility.

## `prompts/_base/background_prompt/5.202605032354/schema.json`

- `23` **P1 / llm_closed_list_instruction**
  - evidence: round 4 Q2=B — 한국어/일본어 시나리오에서도 영어 고정 ... 예: ['door', 'window', 'TV', 'wardrobe']. scene_detail 이 redraw 하지 않도록 contract.
  - why: The schema description contains project-specific versioning ('round 4 Q2=B') and specific examples that bias LLM output. Furthermore, it defines a 'contract' where the presence of these strings dictates downstream visual behavior (preventing redraw), which is a semantic dependency on natural language strings.
  - fix: Remove project-specific references and examples from the description. Define the 'no-redraw' behavior through a structured boolean flag or a dedicated metadata field rather than relying on string-based contracts in natural language.

## `prompts/_base/background_prompt/5.202605032354/system.md`

- `13-17` **P1 / scenario_dependent_prompt**
  - evidence: "실제 카메라로 촬영한 다큐멘터리 풍 사진" / "real camera documentary-style photograph"
  - why: Hardcodes specific natural language strings for visual style and framing in specific languages (KO/EN). This biases the LLM toward these exact phrases and fails to scale to other supported languages (e.g., JA), bypassing a structured style SOT.
  - fix: Remove hardcoded strings from the system prompt. Provide style and framing requirements as conceptual instructions or via a structured style SOT that includes localized strings for the target language.

- `19` **P1 / llm_closed_list_instruction**
  - evidence: Avoid in source language: words like "cinematic look", "film grain emulation", "color graded", "stylized", "concept art", "illustrated", "rendered", "moody artistic". Prefer instead: words like "real DSLR photo", "natural daylight", "actual location reference", "documentary photo", "matter-of-fact photograph", "no post-processing".
  - why: Defines the 'photoreal' visual domain using a closed list of scattered keywords and tropes. This scattered domain nomenclature should be centralized in a style SOT to allow for consistent visual governance across different prompt types.
  - fix: Move the anti-stylization checklist and preferred vocabulary to a centralized visual style SOT or configuration file.

- `20` **P2 / scenario_dependent_prompt**
  - evidence: 한국어 시나리오에서도 ["문", "창문"] 금지 — 항상 영어로. ... (round 4 Q2=B)
  - why: Includes language-specific instructions ('Korean scenarios') and internal project-specific references ('round 4 Q2=B') in a base system prompt. This is scenario-dependent pollution that clutters the prompt logic.
  - fix: State the requirement for English canonical nouns as a general schema constraint without language-specific examples or internal test references.

## `prompts/_base/background_prompt/6.202605091200/schema.json`

- `23` **P2 / scenario_dependent_prompt**
  - evidence: (round 4 Q2=B — 한국어/일본어 시나리오에서도 영어 고정) ... scene_detail 이 redraw 하지 않도록 contract.
  - why: The description includes project-specific versioning ('round 4 Q2=B') and internal pipeline coordination logic ('contract' with 'scene_detail') which should be abstracted into a system prompt or a structured rule set rather than being hardcoded in the schema definition.
  - fix: Remove project-specific milestone tags and internal pipeline logic from the schema description. Use a separate system prompt or a structured 'World Rules' SOT to define these constraints.

## `prompts/_base/beat_extract/2.202603290030/user.md`

- `25-26` **P2 / scenario_dependent_prompt**
  - evidence: (예: 앞 씬에서 부상 → 현재 씬에서 부상 상태로 등장) ... (예: 낮→밤, 비가 그침)
  - why: The prompt provides concrete story-state examples (injury, weather) to illustrate state changes. These specific tropes can bias the LLM to prioritize or look for similar physical/environmental changes even in scenarios where they are irrelevant or where other types of changes (e.g., psychological, technical) are more critical.
  - fix: Replace concrete story examples with abstract descriptions of state continuity or move specific trope examples to a scenario-specific configuration or SOT that guides the extraction logic.

## `prompts/_base/beat_extract/3.202603301500/user.md`

- `6-13` **P2 / llm_closed_list_instruction**
  - evidence: 1. 행동 변화 (action) ... 7. 상황/환경 변화 (situation)
  - why: The prompt restricts the LLM's definition of a 'Beat' to a hardcoded list of seven categories. This closed-list classification can bias or limit the analysis of diverse story genres where state changes might occur in dimensions not listed here.
  - fix: Move the state-change categories to a structured SOT or configuration file that can be injected based on the project's narrative requirements.

- `26-28` **P2 / scenario_dependent_prompt**
  - evidence: 갈등, 추격, 대화 ... 부상 ... 낮→밤, 비가 그침
  - why: The prompt uses specific domain tropes (injury, weather changes, chases) as examples to guide the LLM. These are scenario-dependent and may not apply to all story worlds (e.g., sci-fi, abstract, or non-humanoid settings), leading to biased extraction.
  - fix: Replace concrete trope examples with abstract logic or move them to a scenario-specific reference section provided by the world-building SOT.

## `prompts/_base/character_state_variant/1.202604101200/system.md`

- `12` **P1 / scenario_dependent_prompt**
  - evidence: Change ONLY: expression, skin pallor, posture, wounds/blood as appropriate for the state
  - why: The prompt hardcodes a closed list of visual tropes (wounds/blood, skin pallor) as the exclusive allowed changes. This biases the LLM toward injury-related states and prevents the system from correctly handling other state types (e.g., environmental, magical, or temporal) that are not covered by this specific list.
  - fix: Replace the hardcoded list with a generic instruction to apply changes defined in the {state_description} while maintaining character consistency, or move the specific tropes into the state-specific SOT/description.

## `prompts/_base/entity_all/2.202603260725/character.md`

- `25-28` **P1 / llm_closed_list_instruction**
  - evidence: 인간↔요괴, 인간↔괴물, 본체↔변신체 ... 빙의/합체
  - why: The prompt uses specific fantasy and supernatural tropes as the primary examples for character splitting logic. This biases the LLM's semantic judgment toward these genres and may lead to inconsistent extraction in other contexts (e.g., sci-fi augmentations or realistic aging) where the provided examples do not apply.
  - fix: Generalize the splitting criteria to focus on visual consistency (e.g., 'significant change in facial features or body structure') and move genre-specific tropes to a separate world-rule SOT.

- `31` **P1 / llm_closed_list_instruction**
  - evidence: 이름 구분: "A", "A (변형 상태)" — 괄호 안에 변형 상태를 명시
  - why: This instruction forces the LLM to encode semantic state metadata directly into the character's name string. This creates a 'blind string' that downstream components must parse to resolve identity, increasing the risk of mismatching characters across scenes when their visual state changes.
  - fix: Modify the extraction schema to include a separate 'state' or 'variant' field, allowing the 'name' field to remain a stable unique identifier for the character entity.

## `prompts/_base/entity_all/2.202603260725/prop.md`

- `19-22` **P1 / llm_closed_list_instruction**
  - evidence: 우주복, 갑옷, 제복, 입는 장치나 로봇, 벽면 모니터, TV, CCTV, 문, 창문, 계단, 엘리베이터, 상태창, 모니터 화면, HUD
  - why: The prompt instructs the LLM to classify and exclude entities based on a closed list of genre-specific examples (sci-fi, fantasy, game tropes). This pollutes the base prompt with scenario-specific nomenclature and forces the LLM to make semantic judgments based on scattered examples rather than a structured ontology or abstract definitions.
  - fix: Replace genre-specific examples with abstract ontological categories (e.g., 'wearable equipment', 'fixed architectural elements', 'digital overlays') or move these definitions to a centralized Source of Truth (SOT) that defines entity types across the pipeline.

## `prompts/_base/entity_all/3.202603290500/character.md`

- `25-28` **P2 / llm_closed_list_instruction**
  - evidence: 인간↔요괴, 인간↔괴물, 본체↔변신체 ... 빙의/합체
  - why: The prompt defines character separation logic using specific genre tropes (Youkai, monsters, possession). This scattered domain nomenclature in a base prompt can bias the LLM's semantic judgment of character identity across different genres and should instead be derived from a structured SOT or abstract visual rules.
  - fix: Replace genre-specific examples with abstract visual criteria (e.g., 'significant change in physical silhouette, species, or facial features') and provide genre-specific examples only via dynamic context or a world-rule SOT.

## `prompts/_base/entity_all/3.202603290500/prop.md`

- `10-28` **P1 / llm_closed_list_instruction**
  - evidence: 무기, 도구, 편지, 열쇠 등... 수트, 우주복, 갑옷, 제복, 의상, 입는 장치나 로봇은 제외... 피, 물, 불, 연기... 자동차, 트럭, 버스, 자전거 등
  - why: The prompt uses a collection of specific object types to define the 'Prop' category. This forces the LLM to perform semantic classification based on a closed list of examples, which can lead to the omission of story-critical items in specific genres (e.g., a power suit in sci-fi or a specific vehicle in a racing story) that require visual consistency but are explicitly excluded or discouraged by these rules.
  - fix: Define 'Prop' using abstract visual consistency requirements (e.g., 'any non-character entity requiring a persistent design across shots') and move genre-specific exclusions to a configurable SOT or a higher-level scenario analysis step.

## `prompts/_base/entity_all/4.202603310100/character.md`

- `30` **P1 / llm_closed_list_instruction**
  - evidence: 수식어(이무기, 구미호, 요괴화, 뱀파이어 등)
  - why: This instruction directs the LLM to perform entity splitting based on a closed list of specific Korean fantasy tropes (Imugi, Gumiho, etc.) acting as string modifiers. This biases the extraction logic toward specific genres and uses scattered domain nomenclature instead of generalized visual or narrative rules.
  - fix: Replace the specific trope examples with abstract categories of transformation (e.g., 'mythical form', 'species change') and move specific keyword lists to a structured world-rule SOT or project-specific configuration.

## `prompts/_base/entity_all/4.202603310100/prop.md`

- `21-28` **P1 / llm_closed_list_instruction**
  - evidence: 수트, 우주복, 갑옷, 제복, 의상, 입는 장치나 로봇... 피, 물, 불, 연기, 안개, 먼지, 눈, 비... 자동차, 트럭, 버스, 자전거... 의자, 탁자, 접시, 컵, 마이크... 번호표, 명함, 영수증
  - why: The prompt uses a closed list of semantic categories and domain tropes to instruct the LLM on what to exclude from the 'Prop' entity type. This hardcodes genre-specific assumptions (e.g., sci-fi/fantasy tropes like spacesuits, robots, HUDs) and forces the LLM to perform classification based on scattered nomenclature rather than a structured world-rule SOT.
  - fix: Replace the specific trope lists with high-level conceptual definitions (e.g., 'exclude wearable items', 'exclude environmental effects', 'exclude common furniture without unique identifiers') and move specific category mappings to a centralized schema or world-rule SOT that can be injected based on the scenario's genre.

## `prompts/_base/entity_character_list/2.202605011057/system.md`

- `10` **P2 / llm_closed_list_instruction**
  - evidence: (인간, 요괴, 동물, 로봇, 외계인 등)
  - why: This provides a specific list of domain tropes as examples for character classification. Such nomenclature should be derived from a structured World SOT to avoid biasing the LLM toward specific genres or categories not present in the current scenario. Additionally, the 'head and body' constraint is a visual semantic judgment that may exclude valid non-humanoid characters.
  - fix: Replace the specific trope list with a generic definition of sentient or narrative-driving entities, and move visual constraints to a style-specific SOT.

- `12` **P1 / semantic_string_judgment**
  - evidence: 여러번 출현하는 경우만 추출
  - why: This is a heuristic-based filter for entity membership that forces the LLM to make a semantic judgment on character importance based on frequency. This can lead to the exclusion of narratively significant characters who appear once but require visual assets or drive the plot.
  - fix: Extract all characters and perform filtering or prioritization in a downstream logic step based on explicit narrative importance or asset requirements.

## `prompts/_base/entity_extract_v4/6.202603261200/prop.md`

- `22-25` **P1 / llm_closed_list_instruction**
  - evidence: 수트, 우주복, 갑옷, 제복, 의상, 입는 장치 나 로봇... 벽면 모니터, TV, CCTV... 문, 창문, 계단, 엘리베이터... 상태창, 모니터 화면, HUD
  - why: The prompt uses a hardcoded list of genre-specific tropes (Sci-Fi, Fantasy, Game) to define exclusion boundaries. This forces the LLM to perform semantic classification based on a closed list of examples, which may lead to incorrect exclusions in scenarios where these items are primary props requiring visual consistency.
  - fix: Replace specific object examples with abstract category definitions (e.g., 'standard character attire', 'fixed architectural elements', 'ephemeral UI overlays'). Move genre-specific examples to a structured World/Genre Rule SOT that can be injected based on the scenario context.

## `prompts/_base/entity_extract_v4/7.202603261400/prop.md`

- `22-25` **P1 / llm_closed_list_instruction**
  - evidence: 수트, 우주복, 갑옷, 제복, 의상, 입는 장치 나 로봇 ... 벽면 모니터, TV, CCTV ... 문, 창문, 계단, 엘리베이터 ... 상태창, 모니터 화면, HUD
  - why: The prompt uses hardcoded lists of domain-specific tropes (sci-fi, fantasy, modern) to instruct the LLM on what to exclude from 'prop' extraction. This forces the LLM to perform semantic classification based on scattered nomenclature rather than a structured ontology or SOT, which can bias extraction results across different genres.
  - fix: Replace the hardcoded lists with high-level category definitions (e.g., 'Wearable Items', 'Fixed Architectural Elements', 'Digital Interfaces') and move the specific examples to a configuration-driven SOT or a few-shot context that can be adjusted per project or genre.

## `prompts/_base/entity_extract_v4/7.202603261400/system.md`

- `8` **P2 / llm_closed_list_instruction**
  - evidence: 엑스트라(행인, 군중, 이름 없는 단역 등)
  - why: Hardcodes a specific list of tropes to define 'extras'. This semantic classification should be driven by a structured policy or SOT to ensure consistency across different genres or scenario types where the definition of a 'minor character' might vary.
  - fix: Move the definition of 'extractable entities' to a structured configuration or SOT that can be injected into the prompt, rather than hardcoding specific examples like 'passersby' or 'crowds'.

- `14-17` **P2 / llm_closed_list_instruction**
  - evidence: 회상, 상상, 꿈, 화상통화 등 실제 존재하지 않더라도 **카메라에 찍히는 인물/배경/소품은 추출 대상**이다.
  - why: Uses a closed list of narrative contexts (flashbacks, dreams, video calls) to instruct the LLM on visual presence. This is a domain trope list that biases the extractor toward specific storytelling modes.
  - fix: Abstract the instruction to focus on 'visual manifestation in the scene' regardless of narrative context, or provide the list of valid contexts via a structured SOT.

- `25-26` **P2 / llm_closed_list_instruction**
  - evidence: 상태 변화(부상, 결박, 사망) ... 장비 장착 상태
  - why: Provides specific examples of character states and equipment to define entity boundaries. These are semantic judgments that might conflict with specific scenario requirements (e.g., where a 'wounded' version of a character is a distinct visual asset).
  - fix: Define entity resolution rules (what constitutes a variant vs a new entity) in a structured schema or world-rule SOT.

## `prompts/_base/entity_extract_v4/8.202603290500/prop.md`

- `8` **P2 / semantic_string_judgment**
  - evidence: 정확한 고유명사가 없다면 씬간의 세밀한 판단 필요
  - why: Instructs the LLM to perform identity resolution and visual consistency logic based on the presence or absence of 'proper nouns' versus descriptive text. This is a pattern-based semantic judgment for entity membership.
  - fix: Provide a structured entity resolution strategy or a reference-matching schema that handles aliases and descriptions without relying on the LLM's internal heuristic for 'proper nouns'.

- `22-26` **P1 / llm_closed_list_instruction**
  - evidence: 수트, 우주복, 갑옷, 제복, 의상, 입는 장치나 로봇... 벽면 모니터, TV, CCTV... 문, 창문, 계단, 엘리베이터... 상태창, 모니터 화면, HUD... 피, 물, 불, 연기, 안개
  - why: The prompt uses a closed list of domain-specific examples (Sci-Fi, Fantasy, Game-lit) to define the semantic boundaries of what constitutes a 'prop'. This hardcodes genre-specific assumptions into a base prompt, which should instead rely on abstract category definitions or a structured SOT.
  - fix: Replace specific examples with abstract category definitions (e.g., 'wearables', 'architectural elements', 'environmental effects', 'UI elements') and move scenario-specific exclusions to a configuration layer or a specialized SOT.

## `prompts/_base/entity_extraction/v5/chunk_system.md`

- `36` **P2 / llm_closed_list_instruction**
  - evidence: rooms, roads, cars, terminals, devices, tools, guns, containers, and documents
  - why: Using a hardcoded list of nouns to define 'generic' entities creates a bias against these categories, even when they might be continuity-critical in specific scenarios.
  - fix: Rely on abstract criteria for exclusion (e.g., lack of unique identity or plot significance) rather than a list of specific object types.

- `48` **P1 / llm_closed_list_instruction**
  - evidence: age, disguise, injury, costume, hair_makeup, time_of_day, weather, damage, crowd_density, open_closed, ownership, blood_stain, or loaded_empty
  - why: Providing a hardcoded list of concrete labels for variant axes instructs the LLM to classify open-world visual states into a closed set of examples, which may not fit all scenarios and biases the extraction.
  - fix: Inject these labels from a structured world-rule SOT or allow the LLM to generate natural labels that are subsequently normalized.

- `58` **P1 / llm_closed_list_instruction**
  - evidence: identity reveal, family tie, alliance, hostility, command chain, ownership, possession, containment, residence, workplace, target pursuit, object custody, object use, body-control, hiding place, imprisonment, transport, activation, transformation
  - why: This list of relationship tropes acts as a closed-list semantic classifier for open-world story relationships. It restricts the LLM's interpretation to a predefined set of domain nomenclature.
  - fix: Move relationship types to a configuration-driven SOT that can be adjusted per project or genre.

## `prompts/_base/entity_extraction/v6/chunk_system.md`

- `36` **P2 / llm_closed_list_instruction**
  - evidence: rooms, roads, cars, terminals, devices, tools, guns, containers, and documents
  - why: The LLM is instructed to exclude entities based on a hardcoded list of generic nouns, which is a pattern-based semantic judgment that should be handled by a more flexible world-rule system or a structured SOT.
  - fix: Move the list of generic/excludable categories to a structured SOT or configuration file that can be adjusted per-project.

- `48` **P2 / llm_closed_list_instruction**
  - evidence: age, disguise, injury, costume, hair_makeup, time_of_day, weather, damage, crowd_density, open_closed, ownership, blood_stain, or loaded_empty
  - why: This line provides a hardcoded list of domain-specific trope labels for the LLM to use as variant axes. This scattered nomenclature should be managed in a central SOT to ensure consistency across different extraction passes and scenarios.
  - fix: Define allowed variant axes in a structured schema or SOT and inject them into the prompt as a dynamic list.

- `55-56` **P1 / llm_closed_list_instruction**
  - evidence: identity, transformation, possession, containment
  - why: The prompt defines a closed set of relationship types in natural language. This hardcodes the ontology of the continuity graph, making it difficult to extend or modify without editing the base prompt.
  - fix: Define the relationship ontology (types and roles) in a structured schema or SOT and pass it to the LLM as a reference.

## `prompts/_base/entity_extraction/v6/final_system.md`

- `5` **P1 / llm_closed_list_instruction**
  - evidence: Exclude kinship, social, conflict, collaboration, membership, control, goal, and event relations.
  - why: The prompt uses a hard-coded list of narrative tropes to filter open-world story relations. This restricts the LLM's semantic judgment to a fixed set of categories that may not cover all visually relevant scenarios (e.g., 'membership' for uniforms or 'kinship' for character likeness).
  - fix: Inject the list of allowed and excluded relation types from a structured ontology or project-specific configuration (SOT) instead of hard-coding them in the base prompt.

- `22` **P1 / llm_closed_list_instruction**
  - evidence: Keep only visually relevant relation facts (identity, transformation, possession, containment)
  - why: This defines a closed set of 'visually relevant' relations in a base prompt, preventing the system from adapting to scenarios where other relations might have visual impact.
  - fix: Parameterize the list of allowed relation types based on the specific requirements of the visual generation pipeline's ontology.

## `prompts/_base/entity_extraction/v6/final_user.md`

- `4` **P1 / llm_closed_list_instruction**
  - evidence: visually relevant relation facts (identity, transformation, possession, containment) ... Exclude kinship, social, conflict, collaboration, membership, control, goal, and event relations.
  - why: The prompt uses a hardcoded list of semantic categories to instruct the LLM on what to include or exclude. This 'visual relevance' logic is scenario-agnostic but domain-rigid, preventing the pipeline from capturing relations that might have visual manifestations in specific contexts (e.g., 'membership' via uniforms or 'social' via specific blocking) unless the prompt is manually edited.
  - fix: Inject the list of allowed and excluded relation types from a centralized schema or SOT configuration variable.

## `prompts/_base/entity_extraction/v7/chunk_system.md`

- `24` **P1 / scenario_dependent_prompt**
  - evidence: 예: 은성<->ZRBB51
  - why: The example uses a specific character name ('은성') and a unique prop identifier ('ZRBB51'). Base prompts should remain scenario-agnostic to avoid biasing the LLM toward specific naming patterns or entity types from a single project.
  - fix: Replace specific names with generic placeholders such as 'Character Name <-> Unique Item ID' or 'Protagonist <-> Signature Weapon'.

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

- `8` **P2 / scenario_dependent_prompt**
  - evidence: Set in near-future Korea.
  - why: This is a concrete scenario-specific example embedded in a base prompt. It can bias the LLM toward specific modern/near-future settings even when the target scenario is different (e.g., historical or high fantasy).
  - fix: Replace with a generic placeholder example or remove the specific location/era reference.

- `10-22` **P1 / scenario_dependent_prompt**
  - evidence: Passport-style ID photo... Photorealistic cinematic establishing shot... Photorealistic product photo... pencil sketch
  - why: The prompt hardcodes specific visual compositions (ID photos for characters, product shots for objects) and artistic choices (pencil sketches for mounting targets). These are semantic visual decisions that should be driven by a structured style SOT or project-level configuration rather than being fixed in the base entity extraction logic.
  - fix: Parameterize the visual composition templates so they can be injected based on the project's art direction or a global style SOT.

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

- `26-27` **P1 / llm_closed_list_instruction**
  - evidence: "전투 준비 상태" — 프롬프트에 "무장한" 추가하면 됨
  - why: These lines perform direct semantic mapping from story-level states to specific visual keywords ("무장한", "묶인") within the base extraction prompt. This hardcodes specific visual interpretations of open-world story states and bypasses the downstream T2I prompt generation logic.
  - fix: Remove specific keyword mappings. Use abstract instructions to categorize these as 'temporary states' that should be described in the scene prompt rather than as entity variants.

- `28` **P2 / llm_closed_list_instruction**
  - evidence: "두 동강 난 상태"
  - why: Uses a highly specific, visceral action-genre trope as a classification example in a base prompt. This is scattered domain nomenclature that biases the extractor toward specific types of scenarios.
  - fix: Replace with a more generic example of a physical state change, such as 'damaged' or 'altered state'.

- `35` **P2 / scenario_dependent_prompt**
  - evidence: A의 정신이 B의 몸에 들어가면 → B의 외형 그대로
  - why: This hardcodes logic for a specific narrative trope (possession/body-swapping). While common in some genres, it is scenario-specific pollution in a base prompt that should instead rely on a general 'Visual Identity' rule.
  - fix: Replace with a general principle stating that entity extraction is based strictly on physical appearance regardless of narrative identity or internal state.

## `prompts/_base/entity_extractor_v2/4.202604021900/turn0_style.md`

- `13-14` **P2 / llm_closed_list_instruction**
  - evidence: 원격 접속/조종/빙의/텔레파시, 몽타주/교차편집
  - why: The prompt provides a closed list of specific sci-fi tropes and cinematic techniques to define 'physical presence'. This restricts the LLM's semantic judgment to these specific patterns, potentially missing other scenario-specific ways an entity might be non-physically present.
  - fix: Provide a more abstract instruction for determining physical presence (e.g., 'Identify any narrative or technical reason why a character appearing in a scene might not be physically present') instead of listing specific tropes.

- `17-22` **P1 / llm_closed_list_instruction**
  - evidence: 조선시대, 한국 서울, 가상의 왕국, 한옥, 한복, 중세 갑옷
  - why: The prompt uses specific cultural and historical tropes (Joseon era, Hanok, Hanbok, Seoul) as classification examples. This biases the LLM towards these specific settings and pollutes the general extraction logic with scenario-specific nomenclature that should be derived from the scenario text or a structured SOT.
  - fix: Replace specific examples with abstract definitions (e.g., 'Historical period', 'Specific geographic location') or move these examples to a project-specific configuration/SOT.

## `prompts/_base/entity_extractor_v2/4.202604021900/turn1_7_detail_batch.md`

- `13` **P1 / llm_closed_list_instruction**
  - evidence: 국적 또는 인종(예: Korean, East Asian, South Asian, Black, White, Hispanic 등)을 description 첫 부분에 명시
  - why: The prompt requires the LLM to classify characters (including non-human entities like aliens or robots if they look human) into a closed list of ethnic/national categories. This hardcodes domain nomenclature into the prompt, leading to potential bias or inconsistent labeling that should be managed by a structured SOT or character metadata rather than being hallucinated or forced by prompt examples.
  - fix: Remove the hardcoded list of ethnic examples and the 'must' requirement for classification. Instead, provide a reference to a structured SOT for valid traits or instruct the LLM to extract these details only when explicitly defined in the scenario text.

## `prompts/_base/entity_extractor_v2/4.202604021900/turn2.md`

- `10-11` **P2 / llm_closed_list_instruction**
  - evidence: 허용: 20대→60대 같은 큰 나이 변화, 완전히 다른 실루엣(전신 갑옷 등)... 금지: 의상만 바뀌는 경우(군복/정장/일상복...), 부상/결박/사망 상태
  - why: The prompt defines the logic for character variants using a closed list of specific semantic tropes (e.g., injury, death, specific clothing types). This forces the LLM to perform semantic classification based on scattered examples rather than abstract principles or a structured SOT, which can lead to inconsistent extraction in scenarios involving other types of transient or permanent states.
  - fix: Define the boundary between 'Character Variant' and 'Scene State' using abstract criteria (e.g., 'structural/permanent changes' vs 'transient/contextual states') and move specific trope lists to a centralized configuration or SOT.

## `prompts/_base/entity_extractor_v2/4.202604021900/turn3.md`

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: 시간대 변화 (낮/밤/새벽), 날씨 변화 (맑음/비/안개), 상태 변화 (화재 이후/파괴된/정상)
  - why: The prompt provides specific visual tropes (fire, destruction, specific weather/times) as examples, which biases the LLM's extraction process toward these closed categories and may cause it to overlook or misclassify other valid open-world state changes present in the scenario.
  - fix: Replace specific trope examples with abstract instructions to identify any temporal, environmental, or structural variations mentioned in the source text.

## `prompts/_base/entity_extractor_v2/4.202604021900/turn4.md`

- `6` **P2 / llm_closed_list_instruction**
  - evidence: 일반적인 물건 (의자, 테이블 등)은 제외하고
  - why: The LLM is instructed to classify 'general' vs 'important' props using a closed list of examples (chairs, tables). This can lead to the omission of significant entities in scenarios where these specific objects are narratively or visually critical.
  - fix: Remove hardcoded prop examples from the base prompt and rely on abstract importance criteria or scenario-specific configuration.

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

- `7-8` **P1 / scenario_dependent_prompt**
  - evidence: "Set in [시대], [지역]." ... "Set in near-future Korea."
  - why: Instructs the LLM to infer high-level world parameters (Era, Region) from the scenario text to prefix T2I prompts. These should be provided as structured metadata from a Scenario SOT to ensure consistency across all entities. The specific example 'near-future Korea' in a base prompt can bias the LLM's extraction.
  - fix: Pass Era and Region as variables (e.g., {era}, {region}) from the scenario configuration instead of asking the LLM to extract or infer them from the story text.

- `10-18` **P1 / llm_closed_list_instruction**
  - evidence: "Passport-style ID photo", "Photorealistic cinematic establishing shot", "Photorealistic product photo"
  - why: Hardcodes specific visual tropes and shot compositions for different entity types within a base prompt. This limits the pipeline's ability to adapt to different artistic styles or shot requirements (e.g., non-photorealistic styles or non-ID-photo character references) which should be defined in a centralized Style SOT.
  - fix: Move these visual templates to a style configuration or SOT and inject them into the prompt as variables based on the desired project style.

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

- `9` **P2 / scenario_dependent_prompt**
  - evidence: Set in near-future 인천, Korea.
  - why: The prompt uses a specific real-world location and time period as a concrete example, which can bias the LLM toward Korean or near-future contexts even when processing unrelated scenarios.
  - fix: Replace the concrete example with a generic placeholder or a more diverse set of abstract examples (e.g., 'Set in [Era], [Location]').

- `15-16` **P1 / llm_closed_list_instruction**
  - evidence: Korean, Japanese, American... East Asian, Caucasian, Black, Middle Eastern
  - why: This provides a closed list of semantic classifiers for race and nationality within the prompt. This logic should be driven by a structured world-building SOT (Source of Truth) to allow for fantasy races, fictional nationalities, or different demographic distributions without modifying the core extractor prompt.
  - fix: Remove the hardcoded list and instruct the LLM to use the nationality or race defined in the provided world-building context or scenario text.

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

- `81-86` **P1 / llm_closed_list_instruction**
  - evidence: allowed_space_keys 는 controlled vocab 안에서 선택: main / kitchen / rooftop / stairs / yard / exterior / office. ... 위 controlled vocab 밖 단어 사용 절대 금지.
  - why: The prompt forces the LLM to classify arbitrary scenario locations into a narrow, hard-coded list of semantic labels. This prevents the system from accurately representing diverse environments (e.g., 'laboratory', 'cockpit', 'throne_room') in the structured metadata, which directly drives deterministic background ID assignment in downstream steps.
  - fix: Remove the hard-coded list from the system prompt. Allow the LLM to generate descriptive keys based on the scenario text, or move the controlled vocabulary to a dynamic world-rule SOT that can be updated per project.

## `prompts/_base/entity_extractor_v2/6.202605091300/turn0_style.md`

- `3` **P1 / scenario_dependent_prompt**
  - evidence: 모든 이미지는 실사 영화 촬영 스타일입니다.
  - why: Hard-codes a specific visual style (live-action movie) for all scenarios, preventing the pipeline from supporting other styles (animation, illustration, etc.) without prompt modification.
  - fix: Move the base rendering style to a configuration variable or a world-level SOT field.

- `13-14` **P2 / llm_closed_list_instruction**
  - evidence: 원격 접속/조종/빙의/텔레파시 등 기술이 있다면... 몽타주/교차편집
  - why: Provides a closed list of specific tropes and cinematic techniques to determine physical presence rules, biasing the LLM toward these specific concepts.
  - fix: Generalize the instruction to ask for any rules regarding non-physical presence or editing-driven visual logic without listing specific tropes.

- `17-23` **P2 / llm_closed_list_instruction**
  - evidence: 예: 근미래, 현대, 조선시대, 중세 유럽 ... 예: 현대 한국 도시 + 미래 연구시설, 조선시대 한옥
  - why: Uses specific historical and genre-based examples to guide extraction, which can bias the LLM's categorization towards these specific cultural or temporal markers.
  - fix: Remove specific cultural/historical examples or replace them with abstract descriptions of the expected output format.

## `prompts/_base/entity_extractor_v2/6.202605091300/turn1_7_detail_batch.md`

- `13` **P1 / llm_closed_list_instruction**
  - evidence: Korean, East Asian, South Asian, Black, White, Hispanic 등
  - why: The prompt provides a specific list of ethnic/national labels to classify open-world characters. This hardcodes a semantic classification scheme into the prompt rather than deriving it from a structured world-building SOT, leading to potential bias or inconsistent labeling across different story domains.
  - fix: Remove the specific list of examples from the prompt and instead instruct the LLM to describe the character's perceived ethnicity/nationality based on the project's global style guide or a provided world-rule SOT.

## `prompts/_base/entity_extractor_v2/6.202605091300/turn2.md`

- `10-12` **P2 / llm_closed_list_instruction**
  - evidence: 20대→60대 같은 큰 나이 변화, 완전히 다른 실루엣(전신 갑옷 등) ... 군복/정장/일상복 ... 대부분의 인물은 변형 없음이 정상
  - why: The prompt uses specific visual tropes (age, armor, specific outfits) and a frequency bias ('most characters have no variants') to instruct the LLM on how to classify character variants (C##V##). This hardcodes a specific interpretation of visual identity that may conflict with genre-specific requirements (e.g., magical transformations or uniform-centric stories) and biases the model against detecting valid variants.
  - fix: Abstract the definition of 'Visual Variant' into a structured rule-set or ontology provided in the system context, rather than using hardcoded examples and frequency assumptions in the extraction prompt.

## `prompts/_base/entity_extractor_v2/6.202605091300/turn3.md`

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: - 시간대 변화 (낮/밤/새벽), - 날씨 변화 (맑음/비/안개), - 상태 변화 (화재 이후/파괴된/정상)
  - why: These lines provide specific examples of visual variations (time, weather, and states like 'after fire') which function as a closed list. This biases the LLM to only look for or categorize variations into these specific buckets, potentially missing or misclassifying unique visual states present in an open-world scenario.
  - fix: Generalize the instruction to extract any visual variations described in the text without providing a fixed list of tropes, or move these definitions to a structured world-building SOT.

## `prompts/_base/entity_extractor_v2/6.202605091300/turn4.md`

- `6` **P2 / llm_closed_list_instruction**
  - evidence: 일반적인 물건 (의자, 테이블 등)은 제외하고
  - why: The prompt uses hardcoded examples ('chair', 'table') to define what should be excluded as 'common'. This is a semantic judgment based on a closed list of examples that may bias the LLM against extracting these objects even when they are visually or narratively significant in a specific scenario.
  - fix: Remove specific object examples and replace with a criteria-based instruction for importance (e.g., 'exclude objects that are part of the static background and do not contribute to the unique visual identity of the scene') or move the definition of 'common objects' to a structured world-rule configuration.

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

- `8` **P2 / scenario_dependent_prompt**
  - evidence: "Set in near-future Korea."
  - why: Uses a specific scenario (near-future Korea) as a formatting example, which can bias the LLM's understanding of the 'world core' field toward specific regions or eras.
  - fix: Replace with a generic placeholder like 'Set in [Era], [Location].'

- `10-18` **P1 / scenario_dependent_prompt**
  - evidence: "Passport-style ID photo", "Photorealistic cinematic establishing shot", "Photorealistic product photo"
  - why: Hardcodes specific visual styles and compositions for different entity types. This forces a specific aesthetic (e.g., ID photos for characters) that should be defined in a style SOT or configuration, rather than being baked into the extraction prompt.
  - fix: Inject style requirements via a variable or reference a structured Style SOT instead of hardcoding specific prose like 'Passport-style'.

- `13-18` **P2 / llm_closed_list_instruction**
  - evidence: "장식품(리본, 꽃 등), 상처/피/흙, 변장, 특수 메이크업", "폭발 후, 파괴된 상태", "파손, 분해"
  - why: Uses a closed list of specific props and states to define what to exclude. This is scenario-specific pollution that should be handled by a general rule about 'canonical vs. situational' states.
  - fix: Replace specific examples with a general instruction to exclude 'situational or transient states' and provide a separate rule-set for canonical entity definitions.

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

- `82-86` **P1 / llm_closed_list_instruction**
  - evidence: allowed_space_keys` 는 controlled vocab 안에서 선택: `main` / `kitchen` / `rooftop` / `stairs` / `yard` / `exterior` / `office`
  - why: This forces the LLM to classify arbitrary scenario locations into a fixed set of strings. This is a semantic bottleneck that limits the system's ability to handle diverse environments and forces a fallback to 'main' for any location not in the list, losing visual specificity during the entity extraction phase.
  - fix: Replace the hardcoded list with a dynamic vocabulary provided via a World SOT or allow the LLM to propose descriptive keys that are normalized or mapped in a separate stage.

## `prompts/_base/entity_extractor_v2/7.202605091845/turn0_style.md`

- `3` **P1 / scenario_dependent_prompt**
  - evidence: 모든 이미지는 실사 영화 촬영 스타일입니다.
  - why: Hardcodes a specific rendering style (live-action movie) for all scenarios in a base prompt, preventing the pipeline from supporting other visual styles like animation or illustration without manual prompt changes.
  - fix: Move the global rendering style constraint to a configuration file or a structured style SOT that can be varied per project.

- `13-14` **P1 / llm_closed_list_instruction**
  - evidence: 원격 접속/조종/빙의/텔레파시 등 기술이 있다면
  - why: Instructs the LLM to determine physical presence based on a closed list of specific sci-fi/fantasy tropes. This biases the visual world rules towards these specific concepts and may miss other forms of non-physical presence not listed.
  - fix: Generalize the instruction to identify any narrative element that creates ambiguity regarding a character's physical presence at a location.

- `17-23` **P2 / llm_closed_list_instruction**
  - evidence: 조선시대, 한옥, 미래 연구시설, 중세 유럽, 현대 한국 도시
  - why: Uses specific domain tropes and culturally-specific examples (e.g., Joseon Dynasty, Hanok) to guide extraction. These examples in a base prompt can bias the LLM's categorization of arbitrary scenarios and represent scattered domain nomenclature.
  - fix: Replace specific trope examples with abstract category descriptions or move them to a domain-specific style guide.

## `prompts/_base/entity_extractor_v2/7.202605091845/turn1_7_detail_batch.md`

- `13` **P1 / llm_closed_list_instruction**
  - evidence: Korean, East Asian, South Asian, Black, White, Hispanic 등
  - why: The prompt provides a specific list of racial and ethnic categories as examples for the LLM to use when describing characters. This hardcodes a classification schema for open-world visual attributes into the base extractor prompt, which should instead be defined in a structured world-rule SOT to ensure consistency and flexibility across different projects.
  - fix: Remove the hardcoded list of ethnicities and instead reference a structured SOT or inject the allowed/preferred categories dynamically based on the project's world-building rules.

## `prompts/_base/entity_extractor_v2/7.202605091845/turn2.md`

- `10-11` **P2 / llm_closed_list_instruction**
  - evidence: 20대→60대 같은 큰 나이 변화, 완전히 다른 실루엣(전신 갑옷 등), 군복/정장/일상복
  - why: The prompt uses specific domain tropes and outfit examples to define the semantic boundary between a 'visual variant' and a 'scene state'. This hardcodes classification logic using natural language examples rather than relying on a structured SOT or rule-based definition of entity state transitions.
  - fix: Move the definition of 'Visual Variant' vs 'Scene State' to a structured system-of-truth (SOT) or a centralized rule set that defines state-change thresholds, and reference those abstract rules in the prompt instead of specific trope examples.

## `prompts/_base/entity_extractor_v2/7.202605091845/turn3.md`

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: 시간대 변화 (낮/밤/새벽), 날씨 변화 (맑음/비/안개), 상태 변화 (화재 이후/파괴된/정상)
  - why: The prompt provides a closed list of specific semantic examples for visual variations. This biases the LLM to categorize scene changes into these specific buckets (time, weather, destruction) and may lead it to overlook other types of visual transformations or hallucinate these specific states in scenarios where they do not apply.
  - fix: Replace the specific examples with a generic instruction to identify any significant visual state changes described in the text, or move these categories to a structured world-rule SOT that can be injected based on the genre.

## `prompts/_base/entity_extractor_v2/7.202605091845/turn4.md`

- `6` **P2 / llm_closed_list_instruction**
  - evidence: 의자, 테이블 등
  - why: The prompt uses specific common noun examples ('chairs, tables') to define the 'general' category for semantic filtering. This instructs the LLM to classify open-world meaning (what is 'core' vs 'general') based on a closed list of examples, which may cause the omission of contextually significant props that happen to be common objects.
  - fix: Define 'core visual information' based on narrative or functional importance within the scene context rather than providing a hardcoded list of objects to exclude.

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

- `6-17` **P1 / scenario_dependent_prompt**
  - evidence: 실사 영화 촬영 스타일... Passport-style ID photo... Photorealistic cinematic establishing shot... Photorealistic product photo
  - why: The prompt hardcodes 'live-action movie' and 'photorealistic' styles for all entity types. This forces a specific visual aesthetic at the base extraction level, preventing the pipeline from supporting non-photorealistic or stylized scenarios (e.g., animation, 2D art) without modifying core prompts.
  - fix: Abstract the visual style requirements into a configuration object or a 'Style SOT' that is injected into the prompt based on the project's target aesthetic.

- `8` **P1 / scenario_dependent_prompt**
  - evidence: 예: "Set in near-future Korea."
  - why: Providing a concrete scenario-specific example (near-future Korea) in a base prompt can bias the LLM's output for arbitrary scenarios, leading to hallucinations or stylistic drift toward the example's domain.
  - fix: Replace the concrete example with generic placeholders like 'Set in [Era], [Region]' or inject the example dynamically from the scenario's world SOT.

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

- `20-30` **P2 / scenario_dependent_prompt**
  - evidence: 20대 → 60대, 평상복 → 전신 갑옷, "전투 준비 상태", "결박된 상태", "부상 상태", "두 동강 난 상태"
  - why: Uses specific scenario-based physical states and tropes to define extraction boundaries. This pollutes the general extraction logic with concrete examples that may bias the LLM's judgment on what constitutes a 'variant' in unrelated genres.
  - fix: Define the logic using abstract visual criteria (e.g., 'structural silhouette change' vs 'accessory addition') rather than specific story-state examples.

- `82-86` **P1 / llm_closed_list_instruction**
  - evidence: allowed_space_keys 는 controlled vocab 안에서 선택: main / kitchen / rooftop / stairs / yard / exterior / office
  - why: Forces the LLM to map open-world story locations into a narrow, hardcoded set of semantic labels. This prevents accurate spatial modeling for scenarios outside of modern domestic or office settings, such as fantasy or sci-fi environments, by forcing a fallback to 'main'.
  - fix: Remove the hardcoded list from the system prompt and provide it via a dynamic configuration or allow the LLM to propose descriptive keys that are subsequently normalized.

## `prompts/_base/entity_extractor_v2/8.202605121200/turn0_style.md`

- `13-14` **P2 / llm_closed_list_instruction**
  - evidence: 원격 접속/조종/빙의/텔레파시
  - why: The prompt instructs the LLM to look for a specific list of sci-fi/fantasy tropes (remote access, possession, telepathy) to determine physical presence rules. This is a closed-list semantic classifier for open-world story mechanics that may miss other relevant mechanics or over-index on the listed ones.
  - fix: Rephrase to ask the LLM to identify any mechanics that separate consciousness or agency from physical presence generally, rather than listing specific tropes.

- `17-23` **P1 / llm_closed_list_instruction**
  - evidence: 예: 근미래, 현대, 조선시대, 중세 유럽 ... 예: 한국 서울, 미국 뉴욕, 가상의 왕국 ... 예: 조선시대 한옥 ... 예: 한복, 중세 갑옷
  - why: The prompt provides concrete examples of specific eras, locations, and cultural props (Joseon Dynasty, Hanbok, Medieval Europe). This biases the LLM toward these specific domains and can lead to forced classifications or 'hallucinated' style associations when the input scenario is outside these specific tropes.
  - fix: Remove concrete examples from the base prompt. If examples are necessary for few-shot guidance, they should be generic or provided via a separate world-building SOT injected at runtime based on the project context.

## `prompts/_base/entity_extractor_v2/8.202605121200/turn1_7_detail_batch.md`

- `13` **P1 / llm_closed_list_instruction**
  - evidence: 국적 또는 인종(예: Korean, East Asian, South Asian, Black, White, Hispanic 등)
  - why: The prompt provides a specific list of ethnic/racial labels to the LLM. This biases the extraction process toward these categories and can lead to misclassification or awkward descriptions for scenarios outside these specific cultural contexts. Such taxonomies should be managed via a structured world-rule SOT rather than hardcoded prompt examples.
  - fix: Remove the specific examples from the prompt and instead instruct the LLM to extract the nationality or ethnicity as described in the scenario text, or provide a reference to a project-specific character taxonomy SOT.

## `prompts/_base/entity_extractor_v2/8.202605121200/turn2.md`

- `10-11` **P2 / llm_closed_list_instruction**
  - evidence: 20대→60대 같은 큰 나이 변화, 완전히 다른 실루엣(전신 갑옷 등), 변장... 군복/정장/일상복 → 씬 프롬프트로 처리, 부상/결박/사망 상태
  - why: The prompt uses specific semantic examples (age gaps, armor, military uniforms, injuries) to instruct the LLM on how to distinguish between a character variant and a scene-level attribute. This hardcodes domain-specific tropes into the extraction logic, which can lead to inconsistent classification for similar but unlisted items (e.g., space suits or magical auras) that should be governed by abstract architectural rules.
  - fix: Replace specific trope examples with abstract definitions of 'Variant' (e.g., identity-altering or permanent physical changes) versus 'Scene Attribute' (e.g., situational states or standard wardrobe changes) to ensure consistent open-world behavior.

## `prompts/_base/entity_extractor_v2/8.202605121200/turn3.md`

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: 시간대 변화 (낮/밤/새벽), 날씨 변화 (맑음/비/안개), 상태 변화 (화재 이후/파괴된/정상)
  - why: The prompt provides specific examples of visual variations, including scenario-specific tropes like 'after fire' (화재 이후) and 'destroyed' (파괴된). This biases the LLM to look for these specific states in open-world scenarios rather than identifying variations purely from the narrative context or a structured world-rule SOT.
  - fix: Replace specific trope examples with abstract categories or instructions to identify any narrative-driven visual state changes mentioned in the text.

## `prompts/_base/entity_extractor_v2/8.202605121200/turn4.md`

- `6` **P2 / llm_closed_list_instruction**
  - evidence: 일반적인 물건 (의자, 테이블 등)은 제외하고
  - why: Hardcoding specific examples like 'chairs' and 'tables' as items to exclude biases the LLM's judgment of what constitutes a 'common' vs. 'important' prop. This can lead to the omission of relevant props if they happen to match these examples in a specific scenario context (e.g., a ritual chair).
  - fix: Remove specific object examples. Instead, provide a conceptual definition of 'background' or 'ambient' props, or allow the importance to be determined by the scenario's structural metadata (SOT).

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

- `10-17` **P1 / scenario_dependent_prompt**
  - evidence: "Passport-style ID photo", "Photorealistic cinematic establishing shot", "Photorealistic product photo"
  - why: These hardcoded visual styles and framing constraints are applied globally, potentially contradicting the 'visual_world_rules' (Line 8) and biasing the T2I prompt generation toward realism and specific photography styles regardless of the scenario's intended art direction.
  - fix: Move visual style and framing constraints (e.g., 'Photorealistic', 'Passport-style') to the 'visual_world_rules' SOT or a style-specific configuration that is injected into the prompt.

- `14-18` **P2 / llm_closed_list_instruction**
  - evidence: 장식품(리본, 꽃 등), 상처/피/흙, 변장, 특수 메이크업, 폭발 후, 파괴된 상태, 파손, 분해
  - why: The prompt uses a closed list of specific tropes to define 'temporary states' to be excluded. This can lead to false negatives where permanent character or object features (e.g., a signature ribbon or a pre-existing scar) are incorrectly stripped because they match the example list.
  - fix: Replace specific examples with abstract criteria for 'permanent' vs 'temporary' states, or allow the 'visual_world_rules' to define what constitutes a core entity feature versus a scene-specific variant.

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

- `97-101` **P1 / llm_closed_list_instruction**
  - evidence: allowed_space_keys 는 controlled vocab 안에서 선택: main / kitchen / rooftop / stairs / yard / exterior / office.
  - why: The prompt imposes a hardcoded list of sub-space labels on open-world scenario analysis. This forces the LLM to use a narrow set of terms (e.g., 'kitchen', 'yard') regardless of the scenario's genre or setting (e.g., sci-fi, fantasy), leading to semantic inaccuracy or over-reliance on the 'main' fallback for any space not explicitly listed. This is scenario-specific pollution that biases the extractor toward modern domestic settings.
  - fix: Replace the hardcoded list with an open-ended descriptive requirement or move the vocabulary to a dynamically provided configuration (SOT) that can vary by project or genre.

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

- `13-14` **P1 / llm_closed_list_instruction**
  - evidence: 원격 접속/조종/빙의/텔레파시 ... 몽타주/교차편집
  - why: The prompt defines 'physical presence' logic using a closed list of specific tropes and cinematic techniques. This biases the LLM to only consider these patterns when determining if an entity should be rendered in a scene, potentially failing on novel scenario mechanics or different narrative genres.
  - fix: Generalize the instruction to identify any narrative or technical condition where an entity's visual appearance does not imply physical presence at the location, rather than listing specific tropes.

- `17-23` **P2 / scenario_dependent_prompt**
  - evidence: 조선시대, 중세 유럽, 한국 서울, 미국 뉴욕, 가상의 왕국
  - why: Concrete historical and geographical examples (Joseon, Medieval Europe, etc.) are provided as hints. These act as semantic anchors that can bias the LLM toward these specific tropes even when the scenario text is ambiguous or describes a different setting.
  - fix: Remove specific cultural/historical examples and replace them with abstract category descriptions (e.g., 'Historical period', 'Geographic location') to avoid anchoring bias.

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

- `13` **P1 / llm_closed_list_instruction**
  - evidence: Korean, East Asian, South Asian, Black, White, Hispanic 등
  - why: The prompt provides a specific list of ethnic/national labels and mandates their use for character descriptions. This hard-codes a visual taxonomy into the prompt, which can lead to inconsistent or biased character generation and makes the system harder to update with new categories.
  - fix: Replace the hard-coded list with a placeholder that is populated from a structured source of truth (SOT) containing the allowed or preferred visual taxonomy for characters.

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

- `10-11` **P1 / llm_closed_list_instruction**
  - evidence: 허용: 20대→60대 같은 큰 나이 변화, 완전히 다른 실루엣(전신 갑옷 등) ... 금지: 의상만 바뀌는 경우(군복/정장/일상복 ...)
  - why: The prompt defines the logic for 'Visual Variants' using specific scenario-dependent examples (age gaps, full armor, military uniforms, suits). This forces the LLM to classify open-world visual meaning based on a closed list of tropes, which may bias extraction or fail to generalize across different story genres (e.g., fantasy vs. modern drama).
  - fix: Define the criteria for variants using abstract principles (e.g., 'permanent physical changes' vs. 'transient outfit/state changes') and move specific visual examples to a genre-specific SOT or configuration.

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

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: - 시간대 변화 (낮/밤/새벽)\n    - 날씨 변화 (맑음/비/안개)\n    - 상태 변화 (화재 이후/파괴된/정상)
  - why: The prompt uses specific scenario-dependent examples (especially 'after fire/destroyed') to define visual variation states. This biases the LLM's extraction logic toward these specific tropes and may lead to missed or forced classifications in arbitrary scenarios that do not fit these specific categories.
  - fix: Replace specific examples with abstract definitions of variation types (e.g., temporal, meteorological, or structural state) and ensure that valid state transitions are defined in a structured world-rule SOT rather than hardcoded in the base prompt.

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

- `6` **P2 / llm_closed_list_instruction**
  - evidence: 일반적인 물건 (의자, 테이블 등)은 제외하고
  - why: Hardcoding specific examples like 'chairs' and 'tables' to define 'general items' biases the LLM's filtering logic. In certain scenarios, such as an antique shop or a carpenter's workshop, these items might be core visual information, but the prompt instructs their exclusion based on a fixed list of examples.
  - fix: Move the definition of 'general' or 'ignorable' items to a configuration or SOT, or use a more abstract instruction that defines 'importance' relative to the scene's narrative focus rather than specific object types.

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

- `6-18` **P1 / scenario_dependent_prompt**
  - evidence: 실사 영화 촬영 스타일, Passport-style ID photo, Photorealistic cinematic establishing shot, Photorealistic product photo
  - why: The prompt hardcodes 'live-action' and 'photorealistic' styles as the default for T2I prompt generation. This creates scenario-specific pollution that biases the visual output and prevents the pipeline from supporting non-photorealistic styles (e.g., animation) without modifying the base prompt logic.
  - fix: Parameterize the visual style (e.g., 'photorealistic', 'cinematic') by deriving it from the visual_world_rules SOT, similar to how era and region are handled in line 8.

- `24` **P2 / semantic_string_judgment**
  - evidence: 이 specific prop 이 시각적으로 유니크한 정체성을 가져 reference image 가 필요한지 판단. **fixed object category list 추론 금지**.
  - why: The LLM is asked to perform an open-world semantic judgment on whether a prop is 'visually unique' to determine if a reference image is required, while being explicitly told not to use a fixed category list. This makes the reference attachment logic non-deterministic and reliant on LLM internal bias.
  - fix: Provide a structured set of criteria or a category-based mapping in the SOT to determine reference requirements, rather than relying on LLM intuition.

## `prompts/_base/entity_filter/2.202603241900/system.md`

- `12-13` **P1 / llm_closed_list_instruction**
  - evidence: (수트, 우주복, 갑옷, 제복 등, 완전 몸을 깜사는 형태 장치나 입는 로봇 등도 제거) ... (벽면 모니터, TV, CCTV 등)
  - why: The prompt instructs the LLM to classify and remove entities based on a closed list of specific prop examples (spacesuits, armor, CCTV, etc.). This hardcodes domain-specific tropes into the base filtering logic, which can lead to the accidental removal of unique, plot-critical entities in scenarios where these items are central (e.g., a story about a specific sentient suit or a critical surveillance monitor).
  - fix: Replace specific prop examples with abstract criteria or move these genre-specific exclusions to a scenario-specific configuration or SOT. Use functional definitions (e.g., 'generic background props without unique identifiers') rather than naming specific objects like 'CCTV' or 'spacesuits'.

## `prompts/_base/entity_relation/1.202603301200/system.md`

- `9-23` **P1 / llm_closed_list_instruction**
  - evidence: 인물 예시... 요괴/괴물 형태... 영웅 → 갑옷 착용... 무기 → 각성/강화... 배경 예시... 파괴된 형태
  - why: The prompt uses scattered domain nomenclature (fantasy, action, post-apocalyptic tropes) to define the semantic boundaries of entity transformations. This biases the LLM toward specific genres and may lead to incorrect reasoning in scenarios that do not fit these tropes (e.g., realistic drama or hard sci-fi).
  - fix: Replace concrete trope examples with abstract categories of transformation (e.g., biological aging, functional state change, environmental degradation) or move genre-specific examples to a scenario-specific SOT.

- `28-37` **P1 / llm_closed_list_instruction**
  - evidence: 사람이 늙어도 얼굴 특징은 유지됨... 요괴로 변해도... 로봇이 자동차로 변환
  - why: The logic for visual similarity is defined through specific narrative examples like 'robots' and 'monsters'. This forces the LLM to classify open-world visual meaning based on a closed list of examples that may not be relevant to the current scenario's visual rules.
  - fix: Define visual similarity criteria based on structural, textural, or geometric persistence (e.g., 'retention of key facial landmarks' or 'consistent color palette') rather than specific story-driven examples.

## `prompts/_base/entity_relation/2.202603301800/system.md`

- `9-22` **P1 / llm_closed_list_instruction**
  - evidence: 인물 예시... 소품 예시... 배경 예시...
  - why: The prompt defines the 'variant' relationship using a closed list of specific tropes (aging, monster transformation, armor, awakened weapons, ruins). This biases the LLM to only look for these specific types of transformations rather than applying a general principle of identity continuity.
  - fix: Replace specific trope examples with abstract criteria for identity continuity and move specific examples to a separate few-shot or SOT configuration.

- `29-37` **P1 / llm_closed_list_instruction**
  - evidence: 사람이 늙어도 얼굴 특징은 유지됨 → true... 사람이 완전히 다른 동물로 변신 → false
  - why: Hardcodes visual similarity logic (true/false) based on specific semantic examples. This prevents the LLM from evaluating visual continuity in creative edge cases where identity might be preserved despite drastic changes.
  - fix: Instruct the LLM to evaluate visual similarity based on the presence of shared visual descriptors or 'anchor features' rather than hardcoding specific transformation types.

- `43` **P2 / scenario_dependent_prompt**
  - evidence: 수리검을 던져서 실 그물이 생긴 것
  - why: Uses a specific scenario-based example (shuriken/thread net) to define a negative constraint, which is scenario-specific pollution.
  - fix: Use a more generic example of an action/effect relationship.

## `prompts/_base/entity_review_v4/2.202603241900/system.md`

- `12-15` **P1 / llm_closed_list_instruction**
  - evidence: 감정, 심리, 추상 개념, CG 효과/현상 / 수트, 우주복, 갑옷 등 / 벽면 모니터, TV 등
  - why: The LLM is instructed to classify and filter entities based on a closed list of semantic examples (e.g., space suits, armor, monitors). This creates a dependency on specific genre tropes and prevents the system from handling diverse scenarios where these items might be categorized differently or where other non-visual elements exist.
  - fix: Replace the hardcoded examples with a reference to a structured Entity Type Definition (SOT) that defines the properties of 'Outlook', 'Prop', and 'Background' entities.

## `prompts/_base/floor_plan_prompt/1.202604292033/system.md`

- `11` **P2 / scenario_dependent_prompt**
  - evidence: a curtain that hides a body, a broken window, a hidden compartment
  - why: These are specific narrative tropes used as examples for 'plot-critical visual devices'. Such specific examples can bias the LLM toward identifying or hallucinating these exact items in scenarios where they do not exist, rather than identifying elements based on the provided scene text.
  - fix: Replace specific narrative examples with abstract functional descriptions or instructions to follow explicit markers in the input spec.

## `prompts/_base/floor_plan_prompt/3.202604301041/system.md`

- `10` **P1 / llm_closed_list_instruction**
  - evidence: living = pale yellow, bedroom = pale blue, kitchen = pale green, bathroom = pale cyan, rooftop = pale gray, hallway = pale beige
  - why: Hardcodes a visual mapping (color) to specific semantic room types. This biases the LLM toward a fixed set of rooms and forces a specific visual style that should be defined in a style SOT or derived from visual_world_rules.
  - fix: Remove the specific color-to-room mapping. Instruct the LLM to assign unique, distinct pastel colors to each area identified in the spec, or provide a mapping in the input SOT.

- `13` **P1 / llm_closed_list_instruction**
  - evidence: bed = rectangle with pillow shape; sofa = long rectangle with cushion division; table = simple rectangle/square; door = arc with line indicating swing; window = double parallel line in the wall; sink/toilet = standard plan symbols
  - why: Hardcodes a visual vocabulary for specific furniture and architectural elements. This limits the LLM's ability to represent diverse or period-specific objects not in this list, and should be part of a visual style SOT.
  - fix: Instruct the LLM to use standard architectural symbols appropriate to the era and region defined in the visual_world_rules, rather than prescribing specific geometric shapes in the system prompt.

- `16` **P2 / scenario_dependent_prompt**
  - evidence: low ondol-friendly bed vs western mattress; wall-mounted air-con position; built-in wardrobe on a specific wall
  - why: Contains specific prop and layout examples that pollute the prompt with domain-specific tropes (e.g., Korean 'ondol', modern 'air-con'). This biases the LLM's 'derivation' logic toward these specific examples.
  - fix: Replace specific prop examples with abstract descriptions of layout considerations (e.g., 'furniture placement relative to heating/cooling sources' or 'period-appropriate sleeping arrangements').

## `prompts/_base/floor_plan_prompt/4.202605091200/system.md`

- `10` **P1 / llm_closed_list_instruction**
  - evidence: living = pale yellow, bedroom = pale blue, kitchen = pale green, bathroom = pale cyan, rooftop = pale gray, hallway = pale beige
  - why: Hardcodes a mapping between semantic room types and visual colors. This forces the LLM to use a specific color palette for a specific set of rooms, which may not apply to all scenarios (e.g., a dungeon, a spaceship) and should be defined in a world-level SOT.
  - fix: Move the color mapping to the visual_world_rules or a separate style configuration object passed as input.

- `16` **P1 / scenario_dependent_prompt**
  - evidence: low ondol-friendly bed vs western mattress; wall-mounted air-con position; built-in wardrobe on a specific wall
  - why: Includes scenario-specific props (ondol, air-con) as examples for architectural layout cues in a base prompt. This pollutes the prompt with domain-specific nomenclature that may conflict with arbitrary future scenarios (e.g., fantasy or sci-fi).
  - fix: Use abstract examples of layout conventions (e.g., 'seating arrangements', 'utility placement') or move these specific examples to the scenario-specific visual_world_rules input.

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

- `7-59` **P1 / scenario_dependent_prompt**
  - evidence: "같은 항구가 씬마다 대형 선박 vs 작은 어선으로 바뀌거나", "a single diesel engine housing at center", "A small wooden fishing boat", "a traditional Korean fishing village harbor"
  - why: The prompt is heavily polluted with maritime and Korean-specific examples (fishing boats, harbors, masts, diesel engines). This anchors the LLM to a specific scenario's domain, biasing its interpretation of 'fixed physical form' and 'visual consistency' toward these specific tropes rather than general principles.
  - fix: Abstract the examples to cover multiple domains (e.g., a generic room, a vehicle, a natural landmark) or use placeholders to demonstrate the required level of detail without scenario-specific bias.

## `prompts/_base/location_floor_plan/1.202604282315/system.md`

- `12` **P2 / llm_closed_list_instruction**
  - evidence: e.g., 'NOT a balcony, NOT a multi-floor building, NOT a single-room studio'
  - why: Provides specific negative visual constraints as examples, which can bias the LLM to include these specific exclusions in the output prompt regardless of their relevance to the actual scenario.
  - fix: Use abstract examples of negative constraints or instruct the LLM to derive exclusions based on the absence of features in the provided scenario text.

- `17` **P1 / llm_closed_list_instruction**
  - evidence: Identify zone markers (e.g., '/거실', '/안방', '/욕실', '/현관', '/욕조').
  - why: The LLM is instructed to identify spatial zones using a specific list of Korean tokens and a prefix convention ('/'). This anchors the analysis to a closed set of residential nomenclature, potentially leading to missed zones or incorrect parsing if the scenario uses different terminology or markers.
  - fix: Remove the specific Korean examples or move them to a structured 'World Rules' or 'Location Schema' SOT that defines how zones are marked in the specific project's screenplay format.

## `prompts/_base/location_floor_plan/2.202604290417/system.md`

- `17` **P1 / llm_closed_list_instruction**
  - evidence: Identify zone markers (e.g., '/거실', '/안방', '/욕실', '/현관', '/욕조').
  - why: The prompt hardcodes specific Korean tokens as markers for identifying spatial zones. This biases the LLM toward a specific set of room types and screenplay formatting conventions, which should be abstracted or provided via a structured world-building SOT to ensure the pipeline remains scenario-agnostic.
  - fix: Replace the hardcoded Korean examples with a generic instruction to identify zones based on the screenplay's structural markers, or inject a project-specific 'Zone SOT' into the context.

## `prompts/_base/location_floor_plan/3.202604291130/system.md`

- `22-25` **P1 / semantic_string_judgment**
  - evidence: 거실/안방, 부엌/거실, 침실/욕실, 방1/방2, "문을 열고 들어간다", "방으로 들어선다", "건너편에서", "문 너머"
  - why: The prompt provides a closed list of Korean keywords and movement phrases to drive the LLM's spatial reasoning (room separation and connectivity). This forces the LLM to perform semantic classification based on a hardcoded set of examples rather than general architectural or linguistic principles, which may fail on diverse or non-standard screenplay descriptions.
  - fix: Abstract these spatial cues into a structured 'Spatial Reasoning SOT' or provide generalized instructions for identifying transitions (e.g., 'identify distinct nouns representing separate architectural volumes') rather than listing specific Korean strings.

- `31` **P2 / llm_closed_list_instruction**
  - evidence: "옥탑방 안 / 실내", "한옥 / 안방 / 마루"
  - why: The prompt uses specific scenario-dependent architectural tropes (Rooftop room, Hanok) as examples for parsing scene headings. This introduces cultural and scenario-specific bias into the general floor-plan generation logic.
  - fix: Replace specific architectural examples with generic structural placeholders like 'Location / Sub-location / Zone' to maintain scenario neutrality.

## `prompts/_base/lvm_prompts/1.202603171237/style_rules_generator.md`

- `5-11` **P1 / llm_closed_list_instruction**
  - evidence: 현대/근미래/중세/조선시대 등, 한국/일본/미국/가상 등, 현대 도시/한옥/미래 시설 등, 현대복/군복/한복/우주복 등
  - why: The prompt uses specific cultural tropes (Joseon era, Hanok, Hanbok) and genre examples as classification guides. This biases the LLM's analysis of arbitrary scenarios, potentially leading to incorrect style extraction or forcing scenarios into these specific categories regardless of their actual content.
  - fix: Replace specific examples with abstract definitions of the required visual dimensions. If specific categories are required, they should be provided via a structured SOT or schema rather than hardcoded examples in the prompt text.

## `prompts/_base/lvm_prompts/2.202603181600/style_rules_generator.md`

- `5-11` **P2 / llm_closed_list_instruction**
  - evidence: 조선시대, 한옥, 한복
  - why: The prompt provides specific cultural and domain-specific examples (e.g., Joseon era, Hanok, Hanbok) to guide the LLM's extraction of style rules. This biases the LLM towards these specific tropes and represents hardcoded domain knowledge that should ideally be managed in a structured SOT or kept generic to support arbitrary scenarios.
  - fix: Replace specific cultural examples with generic placeholders or move the domain-specific trope lists to a configuration file/SOT that is injected into the prompt context based on the project type.

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

- `9-11` **P2 / llm_closed_list_instruction**
  - evidence: 군복, 교복, 유니폼, 경비복 등 조직에서 지급하는 동일 복장
  - why: The prompt defines the 'shared outlook' exception using a closed list of domain-specific tropes (military, school, guard uniforms). This logic should be driven by a genre-aware world-rule SOT rather than hardcoded examples in a base prompt.
  - fix: Replace the hardcoded list with a reference to 'official uniforms or organizational attire defined in the world rules' and inject specific examples via a dynamic SOT context.

- `16` **P2 / llm_closed_list_instruction**
  - evidence: 인간형 기계장치(메카, 파워드슈트, 강화복, 갑옷 로봇 등)
  - why: The prompt expands the definition of 'outlook' to include specific sci-fi and fantasy tropes (mecha, powered suits, robots). Hardcoding these in a base extractor prompt pollutes the model's focus for non-sci-fi scenarios and should be part of a genre-specific configuration.
  - fix: Move the inclusion of mechanical/armored entities to a genre-specific rule set or a 'World Rules' section of the prompt assembly.

## `prompts/_base/outlook_extractor/10.202603261238/phase2.md`

- `13` **P2 / scenario_dependent_prompt**
  - evidence: 정장→피의갑옷
  - why: The prompt uses specific genre-heavy prop examples like 'Blood Armor' (피의갑옷) which can bias the LLM's extraction logic or influence its interpretation of ambiguous scene text toward specific tropes.
  - fix: Use generic placeholders for examples (e.g., 'Outfit A -> Outfit B') to avoid genre bias in the extractor's persona.

- `20` **P1 / semantic_string_judgment**
  - evidence: 가장 유사한 다른 인물의 아웃룩을 배정하세요
  - why: This instructs the LLM to perform an arbitrary semantic similarity judgment to resolve missing data in the catalog. This leads to unpredictable visual mapping and breaks strict continuity by allowing the LLM to guess 'similar' outfits across different characters.
  - fix: Require the LLM to flag missing outlooks as 'UNKNOWN' or 'MISSING' so the system can handle the fallback deterministically based on structured metadata.

## `prompts/_base/outlook_extractor/10.202603261238/phase3.md`

- `6` **P1 / scenario_dependent_prompt**
  - evidence: "고급선비복1"과 "고급선비복2"
  - why: The prompt uses specific scenario-dependent prop names ('Gogeup Seonbi-bok', a traditional Korean outfit) as examples for merging logic. This pollutes the base prompt with domain-specific nomenclature that may bias the LLM when processing different genres or scenarios.
  - fix: Replace scenario-specific examples with generic placeholders like 'Item A' and 'Item B' or move the examples to a scenario-specific configuration.

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

- `7` **P2 / llm_closed_list_instruction**
  - evidence: 정장1, 정장2, 드레스1, 티셔츠1, 티셔츠2
  - why: Providing specific clothing types as examples can bias the LLM toward these common modern/formal categories, potentially limiting its creativity or accuracy in historical, sci-fi, or fantasy scenarios.
  - fix: Replace specific clothing names with abstract placeholders like [OutfitType]1, [OutfitType]2.

- `10` **P2 / llm_closed_list_instruction**
  - evidence: 군복, 교복, 유니폼, 경비복
  - why: These specific examples of shared uniforms bias the model toward modern institutional settings. In a fantasy setting, this might miss 'cult robes' or 'guild armor' if the model over-indexes on the provided list.
  - fix: Use a generic instruction: 'Identify clothing items that are standardized across a group or organization (is_shared=true).'

- `12` **P2 / llm_closed_list_instruction**
  - evidence: "검은더블정장", "네이비싱글정장", "낡은갈색점퍼"
  - why: Specific naming examples like 'Navy Single Suit' or 'Old Brown Jumper' anchor the LLM to modern-day fashion descriptions, which may pollute the naming convention for non-modern scenarios.
  - fix: Provide a structural naming rule (e.g., [Color/Condition] + [Style] + [Item]) rather than specific modern examples.

- `23-24` **P1 / llm_closed_list_instruction**
  - evidence: 동물, 뱀, 곤충 떼, 박쥐 떼, 물체, 차량 등 / 인간, 인간형 요괴/괴물, 뱀파이어, 좀비 등
  - why: This is a closed-list semantic classifier for 'humanoid' vs 'non-humanoid'. It uses specific tropes (vampires, zombies, swarms) to define a visual/story routing decision (whether to generate an 'outlook'). This should be driven by a structured world-rule SOT or a more abstract definition of 'humanoid' (e.g., bipedal with head/limbs) to avoid missing edge cases in diverse genres.
  - fix: Define 'humanoid' based on anatomical structure (e.g., bipedal, head, two arms) rather than a list of creature types.

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

- `13` **P2 / llm_closed_list_instruction**
  - evidence: 정장→피의갑옷
  - why: The prompt uses a highly specific prop example ('Blood Armor') which constitutes scenario-specific pollution in a base prompt. This can bias the LLM's interpretation of outfit transitions in unrelated genres.
  - fix: Replace specific prop examples with generic placeholders or remove them entirely to maintain genre-neutrality.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: 가장 유사한 다른 인물의 아웃룩을 배정하세요
  - why: This instructs the LLM to perform a subjective semantic 'similarity' judgment to bridge data gaps. This bypasses strict character-asset ownership rules and can lead to incorrect visual routing or hallucinations where one character's assets are incorrectly assigned to another.
  - fix: Change the fallback behavior to return a null value or a specific 'MISSING' token so the system can handle the error deterministically rather than relying on LLM guesswork.

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

- `6` **P1 / scenario_dependent_prompt**
  - evidence: (예: "고급선비복1"과 "고급선비복2"가 색상/재질까지 동일)
  - why: The prompt uses specific historical/cultural prop names ('Seonbibok') as examples for merging logic. This pollutes a base prompt with scenario-specific nomenclature, which can bias the LLM's judgment of visual similarity in arbitrary future scenarios.
  - fix: Replace scenario-specific examples with generic placeholders (e.g., 'Item A' and 'Item B') or abstract descriptions of visual identity.

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

- `10` **P2 / llm_closed_list_instruction**
  - evidence: 군복, 교복, 유니폼, 경비복
  - why: The prompt uses a closed list of specific uniform types to define the 'is_shared' logic. This biases the LLM to only consider these specific categories as shared, potentially missing other scenario-specific shared attire (e.g., ritual robes, sports team gear) that should be determined by a structured rule set.
  - fix: Replace the closed list with a generic definition of shared organizational attire and move specific examples to a configurable world-rule SOT.

- `16` **P1 / llm_closed_list_instruction**
  - evidence: 메카, 파워드슈트, 강화복, 갑옷 로봇
  - why: This line hardcodes a domain-specific trope list (sci-fi/mecha) into the base extraction logic. It forces the LLM to treat mechanical entities as 'outlooks' (clothing), which is a genre-specific semantic decision that should be driven by the project's world-building SOT rather than a generic extractor prompt.
  - fix: Remove the specific mecha examples and use a generic instruction for 'wearable or piloted entities' if applicable, or move this logic to a genre-specific prompt layer.

## `prompts/_base/outlook_extractor/9.202603261200/phase2.md`

- `13` **P1 / scenario_dependent_prompt**
  - evidence: 정장→피의갑옷
  - why: The term '피의갑옷' (Blood Armor) is a highly specific, genre-heavy prop name used as an example in a base prompt. This introduces scenario-specific pollution into a shared component, potentially biasing the LLM's extraction behavior for other genres.
  - fix: Replace specific prop names with generic placeholders such as '정장→전투복' or '의상A→의상B'.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: 서바이벌강하복1, 서바이벌강하복2
  - why: The use of '서바이벌강하복' (Survival Descent Suit) as a concrete example for merging logic is scenario-specific pollution. Base prompts should remain agnostic to specific story props to avoid biasing the extractor's semantic boundaries.
  - fix: Use generic naming conventions in examples, such as '의상명_변형1, 의상명_변형2'.

## `prompts/_base/outlook_extractor/9.202603261200/phase3.md`

- `6` **P2 / scenario_dependent_prompt**
  - evidence: "서바이벌강하복1", "서바이벌강하복2" → "서바이벌강하복"
  - why: The prompt uses a specific scenario-based prop name ('Survival Descent Suit') as a concrete example for merging logic. This introduces scenario-specific pollution into a base prompt template, which can bias the LLM's classification behavior for unrelated genres or story types.
  - fix: Replace scenario-specific examples with generic placeholders like 'Outfit_A_v1' and 'Outfit_A_v2' or 'Uniform_Type_A'.

- `9` **P1 / semantic_string_judgment**
  - evidence: 같은 씬에서 비슷한 의상을 입는 인물들의 아웃룩 통합
  - why: This instruction requires the LLM to make open-world semantic judgments about visual 'similarity' to merge character outlooks. Without a structured world-rule SOT or specific visual attributes to compare, this can lead to the loss of intentional character-specific visual details or incorrect grouping of distinct entities, affecting visual consistency.
  - fix: Define explicit criteria for 'similarity' (e.g., color, type, material) or move this logic to a step that references a structured character/world SOT to ensure visual identity is preserved.

## `prompts/_base/outlook_merger/1.202603181600/merge_prompt.md`

- `7-9` **P2 / llm_closed_list_instruction**
  - evidence: (예: "군복"과 "전투복"과 "택티컬 유니폼") ... (예: "군복"과 "정장"은 다름)
  - why: The prompt uses specific domain tropes (military/tactical vs formal wear) to instruct the LLM on visual similarity, biasing the merger logic with hardcoded examples that should be abstract or derived from a structured SOT.
  - fix: Replace specific prop examples with abstract criteria for visual identity or move them to a genre-specific configuration.

## `prompts/_base/prompt_sanitizer/2.202605112104/sanitize_system.md`

- `11-15` **P1 / llm_closed_list_instruction**
  - evidence: 폭력: 직접적 폭력 → 긴장감 있는 대치/직후 정적 장면으로 변환 ... 아동: 아동 위험 상황 → 보호자와 함께 있는 안전한 장면으로
  - why: This section hardcodes a mapping between open-world semantic categories (violence, weapons, etc.) and specific visual tropes (tension, background implication, etc.). This logic should be defined in a structured safety/visual policy SOT to allow for scenario-specific mitigation strategies without modifying the system prompt.
  - fix: Move the safety transformation rules to a structured configuration or SOT that can be injected into the prompt based on the scenario's specific requirements.

- `17-22` **P1 / scenario_dependent_prompt**
  - evidence: attempt 1 — film_previs ... attempt 2 — movie_poster ... attempt 3 — aftermath ... 모든 전략의 출력은 포토리얼리스틱(실사)이어야 한다
  - why: The prompt hardcodes specific visual strategies ('film_previs', 'movie_poster', 'aftermath') and a strict 'photorealistic' style constraint. These are domain-specific tropes and style requirements that bias the sanitizer against scenarios requiring different visual languages (e.g., stylized illustration) or different narrative strategies.
  - fix: Parameterize the 'attempts' and style constraints so they can be provided by the calling pipeline or a structured world-rule SOT.

## `prompts/_base/prompt_sanitizer/2.202605112104/sanitize_user.md`

- `14` **P1 / scenario_dependent_prompt**
  - evidence: 포토리얼리스틱 스타일로 수정해주세요
  - why: The instruction hardcodes 'photorealistic style', which forces all sanitized prompts into a specific visual domain regardless of the original scenario's artistic requirements or the user's intent. This prevents the sanitizer from being used for non-photorealistic (e.g., stylized, anime, or painterly) scenarios.
  - fix: Inject the target style as a variable from the scenario configuration or SOT instead of hardcoding it in the base sanitizer prompt.

## `prompts/_base/prompt_sanitizer/v1/sanitize_system.md`

- `11-15` **P1 / llm_closed_list_instruction**
  - evidence: 폭력: 직접적 폭력 → 긴장감 있는 대치/직후 정적 장면으로 변환
  - why: The prompt instructs the LLM to perform semantic classification and transformation based on a closed list of visual tropes (e.g., 'tense confrontation', 'implied weapons', 'distance and gaze'). This hardcodes the visual 'solution' for safety rejections, which should be driven by a structured SOT to maintain consistency with the specific scenario's tone and world rules.
  - fix: Decouple the safety transformation logic from the system prompt. Use a structured SOT to provide the LLM with context-appropriate visual fallbacks for different safety categories.

## `prompts/_base/prompt_sanitizer/v1/sanitize_user.md`

- `12` **P1 / scenario_dependent_prompt**
  - evidence: 포토리얼리스틱 스타일로 수정해주세요
  - why: Hardcoding a specific visual style ('photorealistic') in the sanitizer forces all sanitized prompts into that style, overriding the original scenario's artistic intent and preventing style-agnostic safety filtering.
  - fix: Remove the hardcoded style or replace it with a {target_style} placeholder passed from the scenario's style configuration.

## `prompts/_base/prototype_prompts/v5/entity_reference_en.md`

- `25` **P2 / llm_closed_list_instruction**
  - evidence: Remove temporary damage, dirt, blood, wetness, restraints, ribbons, smoke, sparks, debris, muzzle flash, and other momentary scene-state elements.
  - why: Hardcodes a specific list of visual tokens to define 'scene-state'. This can lead to the removal of legitimate entity features (e.g., a character whose identity includes ribbons or sparks) and should be managed via a structured SOT.
  - fix: Move the list of scene-state elements to a configurable SOT or the {entity_type_rules} block.

- `27` **P1 / scenario_dependent_prompt**
  - evidence: Characters should use realistic present-day / near-future Korean baseline clothing.
  - why: Hardcodes a specific cultural and temporal setting (Modern Korea) into a base reference prompt, biasing all character generation regardless of the actual story world provided in the guide.
  - fix: Remove the hardcoded setting. Clothing style should be derived from the {world_guide_block} or {traits_block}.

- `33` **P1 / llm_closed_list_instruction**
  - evidence: Do not introduce historical, fantasy, medieval, retro-period-drama, or space-opera styling.
  - why: Explicitly blacklists common genres in a base prompt, preventing the system from supporting open-world scenarios that fall into these categories.
  - fix: Remove the negative genre list. Style constraints should be managed via the world-building context provided in variables.

## `prompts/_base/prototype_prompts/v5/entity_reference_ko.md`

- `27` **P1 / scenario_dependent_prompt**
  - evidence: 인물은 현대 한국/근미래 한국 기준의 현실적 기본 복장으로
  - why: Hardcodes a specific setting (Modern/Near-future Korea) into a base reference prompt, biasing all entity generation regardless of the actual scenario's world-building.
  - fix: Move setting-specific defaults to the {world_guide_block} or a separate configuration variable.

- `33` **P1 / scenario_dependent_prompt**
  - evidence: 사극, 전통 복식, 중세풍, 판타지풍, 복고 시대극풍, 레트로 우주복, 시대 착오적 패션 금지.
  - why: Hardcodes genre prohibitions that should be determined by the scenario's world-building rules. This prevents the system from being used for non-modern genres.
  - fix: Move genre constraints to a structured world-rule SOT or pass them as a variable.

## `prompts/_base/prototype_prompts/v5/scene_image_en.md`

- `31-33` **P1 / scenario_dependent_prompt**
  - evidence: grounded in contemporary / near-future Korea... No... historical costume, fantasy armor, medieval architecture... Near-future gear should stay close to modern military, police, industrial, or biotech equipment
  - why: These lines hardcode a specific setting (Korea) and genre (near-future/military/biotech) into a base prompt. This creates scenario pollution that will bias or conflict with arbitrary future scenarios (e.g., a historical drama or high-fantasy setting) that use this same base template.
  - fix: Move era-specific, location-specific, and genre-specific visual constraints into the {world_guide_block} or a dedicated style SOT that is injected dynamically based on the scenario metadata.

## `prompts/_base/prototype_prompts/v5/scene_image_ko.md`

- `31-33` **P1 / scenario_dependent_prompt**
  - evidence: 동시대~근미래 한국 기준... 사극풍 복식, 판타지 갑옷, 중세풍 건축 금지... 전신 파워아머, 우주복, 초대형 메카처럼 과장하지 마라
  - why: These lines hardcode a specific 'grounded near-future Korea' setting and explicitly forbid fantasy, historical, or high-sci-fi tropes. This pollutes the base prompt with scenario-specific constraints, preventing its use for arbitrary story worlds and biasing visual generation.
  - fix: Remove these hardcoded constraints from the base prompt and move them into the {world_guide_block} or a dynamically injected style SOT provided by the scenario configuration.

## `prompts/_base/prototype_prompts/v5/webbook_package_system.md`

- `19` **P1 / llm_closed_list_instruction**
  - evidence: restraint state, damage, dirt, weapon possession
  - why: This is a closed list of domain-specific tropes used to guide continuity analysis. It biases the LLM to look for these specific attributes (common in action/thriller) even in scenarios where they are irrelevant, while potentially ignoring other critical continuity markers not in the list.
  - fix: Replace the specific list with a reference to a structured 'continuity_keys' list provided in the SOT or use more generic categories like 'character appearance' and 'environmental state'.

- `21` **P2 / scenario_dependent_prompt**
  - evidence: 6,500-10,000 characters in Korean prose
  - why: The prompt specifies a character count target specifically for 'Korean prose'. This creates a project-specific bias in a base prompt that is intended to handle dynamic languages, potentially leading to incorrect length targets for non-Korean scenarios.
  - fix: Parameterize the character count target and the language name (e.g., '{target_length} characters in {source_language_name} prose') to ensure the instruction scales with the input scenario.

## `prompts/_base/prototype_prompts/v5/world_guide_system.md`

- `10` **P2 / llm_closed_list_instruction**
  - evidence: explicitly forbid historical costumes, fantasy reinterpretation, and period drama styling
  - why: This instruction forces the LLM to use a hard-coded list of tropes as negative constraints when it classifies a story as contemporary. This introduces scenario-specific bias into the world guide extraction process instead of allowing the LLM to derive constraints purely from the screenplay's context or a structured SOT.
  - fix: Replace the specific trope list with a general instruction to identify and exclude visual elements that would be anachronistic or stylistically inconsistent with the identified era and technology baseline.

## `prompts/_base/prototype_prompts/v6/entity_reference_en.md`

- `25` **P1 / llm_closed_list_instruction**
  - evidence: restraints, ribbons, smoke, sparks, debris, flashes
  - why: This hardcoded list of 'momentary' elements includes specific items like 'ribbons' or 'restraints' which may be core identity features for certain characters. Explicitly listing them for removal biases the LLM against valid permanent traits and forces a semantic judgment on what constitutes 'momentary' noise.
  - fix: Move specific visual noise examples to a structured 'neutralization_guide' or use more abstract categories (e.g., 'transient environmental effects') while allowing the 'Identity anchor traits' to override them.

- `33` **P2 / scenario_dependent_prompt**
  - evidence: do not add fantasy elements to a contemporary guide, do not add modern gear to a historical guide
  - why: The prompt uses specific genre-clash examples (fantasy vs contemporary, modern vs historical) to define consistency. This is scenario-specific pollution in a base prompt that should rely on the provided world guide's internal logic and may confuse the LLM in hybrid-genre scenarios (e.g., Urban Fantasy).
  - fix: Replace specific genre examples with a generic instruction to strictly adhere to the era and style defined in the 'World and era guide'.

## `prompts/_base/prototype_prompts/v6/entity_reference_ko.md`

- `24-25` **P2 / scenario_dependent_prompt**
  - evidence: 포승줄, 리본, 먼지, 연기, 파편, 섬광
  - why: Specific props and visual effects like 'binding ropes' or 'ribbons' are listed as negative constraints. These appear to be scenario-specific leftovers that bias the LLM's definition of 'momentary states' and should be generalized.
  - fix: Replace specific prop examples with generic categories of 'temporary accessories' or 'transient environmental effects', or move them to a scenario-specific exclusion list.

- `27-30` **P2 / llm_closed_list_instruction**
  - evidence: 인물은... 배경은... 소품은...
  - why: The prompt hardcodes a closed list of entity types (Person, Background, Prop) and their specific neutralization rules. This logic overlaps with the {entity_type_rules} placeholder and prevents the system from handling new entity types without prompt modification.
  - fix: Consolidate type-specific instructions into the {entity_type_rules} injection block and use generic language in the base template.

- `33` **P2 / scenario_dependent_prompt**
  - evidence: 예: 동시대 가이드에 판타지 요소를 더하거나, 역사물 가이드에 근대 장비를 더하는 등
  - why: Hardcoded genre tropes (Fantasy, Historical, Modern) are used as examples of mismatch. This can bias the LLM or cause contradictions if the world guide defines a hybrid genre (e.g., Modern Fantasy).
  - fix: Use abstract descriptions of 'anachronisms' or 'genre inconsistencies' instead of specific trope examples.

## `prompts/_base/prototype_prompts/v6/webbook_package_system.md`

- `19` **P1 / llm_closed_list_instruction**
  - evidence: wardrobe, restraint state, damage, dirt, weapon possession, and location state
  - why: This list hardcodes specific continuity focus points (like 'restraint state' and 'weapon possession') that are genre-specific (action/thriller). It forces the LLM to prioritize these semantic attributes even in scenarios where they are irrelevant, potentially leading to hallucinations or awkward narrative focus in non-action genres.
  - fix: Inject these continuity focus points from a structured World Rules or Scenario Metadata SOT instead of hardcoding them in the base system prompt.

- `21` **P2 / scenario_dependent_prompt**
  - evidence: 6,500-10,000 characters in Korean prose
  - why: The prompt hardcodes a character count target specifically for Korean prose. This creates a mismatch when the 'source_language_name' is not Korean, as character density and length expectations vary significantly between languages (e.g., English vs. Korean).
  - fix: Use a dynamic variable for the character count range or provide language-specific length guidelines based on the 'source_language_code'.

## `prompts/_base/prototype_prompts/v6/world_guide_system.md`

- `10` **P1 / llm_closed_list_instruction**
  - evidence: explicitly forbid historical costumes, fantasy reinterpretation, and period drama styling
  - why: The prompt hardcodes a specific set of genre-based exclusions for 'contemporary' stories. This forces the LLM to use a closed list of tropes to define what is 'not' allowed, which can conflict with hybrid genres (e.g., urban fantasy) and should instead be derived from a structured world-rule SOT or the screenplay's specific genre analysis.
  - fix: Remove the hardcoded list of forbidden styles. Instead, instruct the LLM to identify the era and genre, then derive 'must_avoid' elements based on the specific screenplay context and a generalized set of consistency rules.

## `prompts/_base/ref_image_prompts/3.202603251000/character_composite_ref.md`

- `1-2` **P2 / scenario_dependent_prompt**
  - evidence: Full body shot, standing pose, plain neutral background. Head to toe visible. Studio lighting, fashion photography style.
  - why: Hardcodes a specific 'fashion photography' aesthetic and 'standing pose' into a base prompt. This biases the visual generation of character references toward a modern studio look, which may conflict with scenarios requiring different artistic styles or poses that should be defined in a style SOT.
  - fix: Move style and pose instructions to a configurable style SOT or inject them as variables to allow for scenario-appropriate reference generation.

- `13` **P2 / scenario_dependent_prompt**
  - evidence: e.g., armor over uniform
  - why: Uses genre-specific tropes (armor, uniform) as examples for layering logic. This can bias the LLM's interpretation of outfit assembly toward specific domains like fantasy or military, rather than remaining genre-agnostic.
  - fix: Replace with more generic examples of layering, such as 'e.g., outer layers over inner layers' or 'accessories over clothing'.

## `prompts/_base/ref_image_prompts/3.202603251000/character_ref.md`

- `1` **P1 / scenario_dependent_prompt**
  - evidence: passport-style ID photo. ... Studio lighting.
  - why: The prompt hardcodes specific modern photographic tropes ('passport-style', 'Studio lighting') which biases the visual generation toward a contemporary aesthetic. This is problematic for scenarios set in historical, fantasy, or non-photorealistic worlds where such concepts are anachronistic or stylistically inconsistent.
  - fix: Move style and lighting descriptors to a structured style SOT or scenario-level configuration, replacing them with placeholders like {reference_composition_style} and {reference_lighting}.

## `prompts/_base/ref_image_prompts/4.202603251000/character_composite_ref.md`

- `2` **P2 / scenario_dependent_prompt**
  - evidence: Studio lighting, fashion photography style.
  - why: Hardcoding a specific visual style ('fashion photography') into a base character reference prompt biases all character generation toward a specific aesthetic, which may conflict with scenarios requiring different styles (e.g., hand-drawn, gritty, or period-accurate).
  - fix: Move style-specific keywords to a style SOT or parameterize the style section to allow scenario-specific overrides.

- `13` **P2 / scenario_dependent_prompt**
  - evidence: e.g., armor over uniform
  - why: Using domain-specific props like 'armor' and 'uniform' as examples for layering logic introduces genre bias (fantasy/military) into a base prompt that should remain genre-agnostic.
  - fix: Use more generic examples for layering (e.g., 'jacket over shirt') or remove the specific examples to rely on the general instruction.

## `prompts/_base/ref_image_prompts/4.202603251000/prop_ref.md`

- `3-5` **P1 / llm_closed_list_instruction**
  - evidence: earring, necklace, bracelet, mask, weapon held in hand, shoulder armor, backpack... ear, neck, wrist, face, hand, shoulder, torso
  - why: The prompt forces the LLM to classify open-world entity descriptions into visual composition categories (worn/held vs freestanding) using a hardcoded list of examples. This relies on LLM inference for a structural visual decision (silhouette inclusion and type) that should be explicitly defined in the entity SOT to ensure consistency across different prop types.
  - fix: Replace the conditional logic and example lists with structured variables passed from the entity SOT, such as 'attachment_point' or 'display_mode', to explicitly dictate the visual composition.

## `prompts/_base/ref_image_prompts/5.202603311724/prop_ref.md`

- `3-5` **P2 / llm_closed_list_instruction**
  - evidence: e.g. earring, necklace, bracelet, mask, weapon held in hand, shoulder armor, backpack
  - why: The prompt relies on the LLM to semantically classify an entity as 'worn' or 'freestanding' based on a closed list of examples to decide visual composition (silhouette presence). This logic is better handled by structured metadata in the SOT to ensure consistent visual output across different prop types.
  - fix: Pass a structured attribute (e.g., 'is_worn' or 'display_mode') from the entity SOT and use conditional prompt assembly instead of providing examples for LLM inference.

## `prompts/_base/reference_image/v2/prop.md`

- `2` **P2 / scenario_dependent_prompt**
  - evidence: Photorealistic product photo style
  - why: Hardcoding a specific visual style ('Photorealistic') in a base prompt prevents the pipeline from adapting to different artistic directions (e.g., stylized, anime, or sketch-based scenarios). This creates visual pollution for non-photorealistic stories.
  - fix: Replace the hardcoded style with a template variable or reference a style SOT that can provide appropriate style descriptors based on the current scenario's art direction.

## `prompts/_base/scene_camera_flow/1.202604151200/schema.json`

- `16-19` **P2 / llm_closed_list_instruction**
  - evidence: establishing / approach / close_observation / reaction / reveal / withdraw / transition 등 자유 라벨
  - why: The description provides a list of domain-specific cinematic tropes to guide the LLM in labeling scene stages. While marked as a 'free label', providing such a list in the prompt/schema description biases the LLM toward a closed set of semantic categories for open-world story analysis, which should ideally be managed via a structured SOT or a formal enum if the system logic depends on these categories.
  - fix: Move the list of stage labels to a central cinematography SOT or convert 'stage_label' into a formal enum if these categories drive downstream logic.

## `prompts/_base/scene_camera_flow/1.202604151200/system.md`

- `44-45` **P1 / scenario_dependent_prompt**
  - evidence: 엔티티 ID (C##, L##, P##) 사용 금지 — 보통명사와 인물 이름으로만
  - why: By forbidding structured IDs (C##, L##, P##) and requiring natural language names, the prompt forces the LLM to generate scenario-specific strings that are harder to validate and map consistently in downstream visual generation steps. This increases the risk of entity confusion and semantic drift between the camera flow and the actual scene entities.
  - fix: Modify the instruction to encourage or require the use of structured IDs (C##, L##) within the camera flow descriptions (e.g., in visual_focus) to ensure precise entity tracking across the pipeline.

## `prompts/_base/scene_cinematography/1.202603220900/system.md`

- `5` **P2 / scenario_dependent_prompt**
  - evidence: 긴장 고조 → 폭발 → 감정 정리
  - why: Hardcoding a specific emotional arc (Tension -> Explosion -> Resolution) as a selection principle biases the LLM to force cinematography choices into a traditional 3-act structure, which may not apply to all scenarios (e.g., ambient, slice-of-life, or non-linear narratives).
  - fix: Reference a dynamic emotional arc or narrative phase provided in the input context instead of hardcoding a specific pattern.

## `prompts/_base/scene_cinematography/2.202603261200/system.md`

- `5` **P1 / scenario_dependent_prompt**
  - evidence: 긴장 고조 → 폭발 → 감정 정리
  - why: This line hardcodes a specific narrative arc (Tension -> Explosion -> Resolution) as the standard for cinematography selection. This biases the LLM's visual choices toward a specific dramatic structure, which may conflict with scenarios that have different emotional pacing or structures (e.g., slice-of-life, horror, or non-linear narratives).
  - fix: Replace the hardcoded arc with a reference to the scenario's actual emotional metadata or pacing instructions provided in the input context (e.g., 'Follow the emotional curve defined in the scenario metadata').

## `prompts/_base/scene_consistency/2.202604141200/schema.json`

- `19` **P2 / scenario_dependent_prompt**
  - evidence: dead_woman_by_door
  - why: The example provided for the element_id field uses a highly specific narrative prop ('dead_woman_by_door'), which introduces scenario-specific bias into the LLM's generation of identifiers for arbitrary stories.
  - fix: Replace the specific narrative example with a generic placeholder like 'object_identifier' or 'character_state_description'.

## `prompts/_base/scene_consistency/2.202604141200/system.md`

- `9-36` **P1 / scenario_dependent_prompt**
  - evidence: 사망, 부상, 의식불명 (line 9), 시체는 움직이지 않으므로 (line 12), blood pool, tattoo (line 13), shattered (line 17), 낙서, 그림, 자국 (line 35), 깜빡이는 불 (line 36)
  - why: The prompt uses specific crime/thriller tropes as primary examples and definitions for continuity elements. This biases the LLM to prioritize these specific visual markers (blood, tattoos, damage) and may lead to poor performance or hallucination in other genres (e.g., romance, sci-fi).
  - fix: Replace genre-specific examples with abstract categories of visual persistence, such as 'physical orientation', 'surface markings', and 'environmental state', and provide a diverse set of examples across different genres.

- `32` **P1 / scenario_dependent_prompt**
  - evidence: 인종/국적 명기: 인물 묘사 시 인종/국적을 반드시 포함
  - why: Mandating the inclusion of race/nationality in a continuity prompt forces the LLM to hallucinate these attributes if they are not explicitly mentioned in the source text. These core character attributes should be sourced from a structured character SOT to ensure global consistency.
  - fix: Modify the instruction to require race/nationality only when provided in the character reference or scenario context, or move this requirement to a character-specific SOT lookup.

## `prompts/_base/scene_consistency/3.202604201230/schema.json`

- `19` **P2 / scenario_dependent_prompt**
  - evidence: dead_woman_by_door
  - why: Providing a concrete, narrative-specific example like 'dead_woman_by_door' in a schema description biases the LLM's naming conventions and potentially its conceptualization of scene elements toward specific tropes or morbid scenarios.
  - fix: Use a generic, neutral example such as 'object_identifier' or 'scene_element_name'.

## `prompts/_base/scene_consistency/3.202604201230/system.md`

- `9-37` **P2 / llm_closed_list_instruction**
  - evidence: 수면·의식불명·기절·휴식·부상·사망
  - why: The prompt provides a closed list of semantic tropes (sleep, unconsciousness, injury, etc.) and visual features (tattoos, scars, shattered glass) to guide the LLM's identification of 'consistency' elements. This biases the analysis toward these specific examples rather than allowing for arbitrary open-world visual elements found in a scenario.
  - fix: Replace specific trope lists with a generalized instruction to identify any physical state or environmental detail that remains static across multiple shots.

- `13-22` **P2 / scenario_dependent_prompt**
  - evidence: a young person asleep on a sofa, curled on the left side, one arm tucked under the cheek
  - why: The prompt includes overly specific visual examples (e.g., 'curled on the left side', 'left pane of the window is shattered') that can bias the LLM's output toward these specific configurations or level of detail, rather than being driven purely by the scenario text.
  - fix: Use more abstract examples or a wider variety of shots to demonstrate the required level of detail without biasing specific spatial configurations.

- `29-32` **P1 / scenario_dependent_prompt**
  - evidence: 엔티티 ID(C##, L##, P##) 절대 금지. 보통명사로만 묘사
  - why: The prompt explicitly forbids the use of structured SOT identifiers (C##, P##, etc.) and mandates the use of natural language names for entity tracking. This breaks the link to the global source of truth (SOT) and forces the LLM to rely on scenario-specific strings, which increases the risk of ambiguity and visual drift.
  - fix: Allow and require the use of structured IDs (C##, P##) to ensure that visual descriptions are correctly mapped to the global character and prop definitions.

- `33` **P1 / scenario_dependent_prompt**
  - evidence: 인종/국적 명기: 인물 묘사 시 인종/국적을 반드시 포함
  - why: This instruction forces the LLM to generate race/nationality attributes for every character description. These are core identity traits that should be defined in a structured Character SOT and referenced via ID, not mandated as a general prompt instruction which leads to hallucination or inconsistency with the intended character design.
  - fix: Remove the mandatory race/nationality requirement from the general scene consistency prompt and ensure these attributes are pulled from the Character SOT profile.

## `prompts/_base/scene_consistency/4.202604201700/schema.json`

- `19` **P2 / scenario_dependent_prompt**
  - evidence: e.g. dead_woman_by_door
  - why: The schema description uses a concrete, scenario-specific example ('dead_woman_by_door') to illustrate a technical format (snake_case). This introduces genre/scenario bias into the LLM's structured output generation.
  - fix: Replace the scenario-specific example with a generic placeholder like 'element_name_here' or 'character_state_description'.

## `prompts/_base/scene_consistency/4.202604201700/system.md`

- `9-14` **P2 / llm_closed_list_instruction**
  - evidence: 수면·의식불명·기절·휴식·부상·사망 등 모든 "정지 상태" 해당
  - why: Defines 'character_state' using a closed list of specific semantic tropes. This biases the LLM to only recognize these specific states as valid 'static' elements, potentially missing other scenario-specific static conditions not listed.
  - fix: Define 'character_state' by the property of being 'unchanging throughout the scene' rather than providing a closed list of semantic states.

- `30-35` **P1 / llm_closed_list_instruction**
  - evidence: shot description / staging의 camera_direction / character_angles를 기준으로 각 샷의 지배적 프레이밍을 판정하세요: ... 전신형(full) ... 확대형(zoom)
  - why: Instructs the LLM to classify open-world shot descriptions into a closed set of framing categories (full vs zoom) to drive the routing of visual descriptions. This semantic judgment is used to prevent T2I artifacts but should be derived from structured shot metadata (e.g., shot scale) rather than LLM interpretation of prose.
  - fix: Pass structured shot scale metadata (e.g., ECU, CU, MS, FS) to the prompt and use it to drive the splitting logic instead of asking the LLM to 'judge' the framing from text.

- `46-79` **P1 / scenario_dependent_prompt**
  - evidence: 씬 S12에 민숙(사망, C04)이 등장, 선택된 샷이 Shot1(전신 구도), Shot2(발끝만 확대), Shot19(손목 확대)라고 가정
  - why: The system prompt contains a concrete, highly specific scenario example including character names (Min-sook), specific IDs (C04), and plot points (death, wooden floor). This introduces scenario-specific pollution that can bias the LLM's output for unrelated scenarios, leading to trope leakage or hallucinations.
  - fix: Replace the concrete scenario example with a generic, abstract example (e.g., Character A, Object B) or move the example to a separate few-shot template that is not part of the core system prompt.

## `prompts/_base/scene_consistency/5.202605021400/schema.json`

- `19` **P2 / scenario_dependent_prompt**
  - evidence: e.g. dead_woman_by_door
  - why: The schema description uses a specific, scenario-laden example to illustrate a technical naming convention. This introduces narrative bias and specific trope pollution into the schema definition which should be domain-agnostic.
  - fix: Replace with a generic placeholder such as 'element_name_or_state'.

- `37` **P2 / llm_closed_list_instruction**
  - evidence: 전신형과 확대형은 서로 겹치지 않도록 분리
  - why: The instruction requires the LLM to classify and separate shots based on shot-type categories ('full body' vs 'close up') that are not defined in the schema or a structured SOT, relying on inconsistent internal LLM interpretation of domain nomenclature.
  - fix: Reference a centralized shot-type classification system or provide an enum of allowed shot categories in the schema.

## `prompts/_base/scene_consistency/5.202605021400/system.md`

- `9-11` **P2 / llm_closed_list_instruction**
  - evidence: 수면·의식불명·기절·휴식·부상·사망 등 모든 "정지 상태" 해당
  - why: The prompt defines the 'character_state' category using a closed list of specific story tropes. This biases the LLM's identification of persistent states toward these examples and may cause it to miss other valid 'static' states not listed in this domain trope list.
  - fix: Define the category by its functional requirement (e.g., 'any physical state that remains static across shots') rather than providing a list of specific narrative tropes.

- `30-33` **P1 / llm_closed_list_instruction**
  - evidence: camera_direction / character_angles를 기준으로 각 샷의 지배적 프레이밍을 판정하세요: ... close-up / tight on / focus on body part / detail shot
  - why: The LLM is instructed to classify open-world visual framing (full vs zoom) based on a closed list of natural language keywords. This classification is used to split character states to avoid T2I artifacts, making a critical visual routing decision dependent on keyword-based semantic judgment rather than structured metadata.
  - fix: Pass the framing type (e.g., 'FULL_BODY', 'CLOSE_UP') as a structured enum from the upstream shot analysis or staging data instead of asking the LLM to infer it from strings.

## `prompts/_base/scene_consistency/6.202605031033/system.md`

- `30-35` **P1 / llm_closed_list_instruction**
  - evidence: 전신형(full): 전신/상반신/미디엄 ... 확대형(zoom): close-up / tight on / focus on body part / detail shot
  - why: The LLM is instructed to perform semantic classification of shot framing based on a closed list of keywords. This classification directly routes which visual descriptions (character_state) are applied to which shots to avoid 'double body' artifacts. Hard-coding these keywords in the prompt makes the system brittle to variations in staging nomenclature that might appear in the open-world scenario text.
  - fix: Move framing classification to a structured staging analysis step (SOT) where shot scale is an explicit enum, or allow the LLM to determine framing scale based on the full context of the shot description without a restrictive keyword list.

## `prompts/_base/scene_dependency/2.202603231200/system.md`

- `8` **P2 / scenario_dependent_prompt**
  - evidence: 예: 같은 집 거실, 같은 사무실, 같은 거리
  - why: The prompt uses specific modern-day location examples to define 'visual similarity'. This introduces genre bias into the base analysis logic, which should ideally be genre-agnostic or driven by the scenario's own world-building SOT.
  - fix: Replace specific location examples with abstract principles of visual continuity (e.g., 'shared architectural features', 'identical environmental markers') or move examples to a genre-specific layer.

## `prompts/_base/scene_detail/10.202604301430/system.md`

- `124-244` **P1 / scenario_dependent_prompt**
  - evidence: Korean woman, Korean man
  - why: Hardcoded ethnicity in multiple 'Correct' (✓) examples (lines 124, 126, 128, 244) biases the LLM towards a specific demographic. This is scenario-specific pollution that should be replaced with generic placeholders or instructions to pull from the world SOT.
  - fix: Replace 'Korean woman/man' with generic placeholders like '[Race/Nationality] [Gender]' or 'a person' in all examples.

- `134-144` **P1 / blind_string_mutation**
  - evidence: 고정 요소 description의 보통명사 인물 묘사...를 해당 C##으로 대체
  - why: Instructs the LLM to perform string replacement of common nouns with IDs within a natural language description. This is a semantic judgment task prone to error (e.g., if multiple characters of the same gender/age are present) and should be handled by structured data or explicit tagging.
  - fix: Provide structured character-to-ID mappings in the input JSON rather than asking the LLM to perform string-based replacement on prose.

- `277-299` **P2 / llm_closed_list_instruction**
  - evidence: attacker / assailant / aggressor / predator / pursuer, tearing flesh, ripped skin, blood spray
  - why: Provides a closed list of semantic descriptors for violence and power dynamics. This is scenario-specific (genre-specific) pollution that should be managed via a structured SOT for tone/genre rather than being hardcoded in the system prompt.
  - fix: Move the 'Vocabulary Palette' to a separate, context-aware SOT or style guide that is injected only when relevant to the scene's genre.

## `prompts/_base/scene_detail/11.202604301730/system.md`

- `11-107` **P2 / llm_closed_list_instruction**
  - evidence: and then, while ~ing, after ~ing, face filling the entire frame, red light cuts across, approximately X meters wide
  - why: The prompt contains multiple closed lists of forbidden natural language phrases to enforce technical or stylistic constraints (temporal singularity, framing, lighting, dimensions).
  - fix: Consolidate these negative constraints into a structured 'style_guide' SOT or use a post-generation validator to flag these patterns.

- `31-48` **P1 / semantic_string_judgment**
  - evidence: Focus on / close on / tight on / detail on + 특정 신체 부위
  - why: The prompt uses specific natural language patterns to decide whether to use a character ID (C##) or a common noun. This is a semantic judgment based on string patterns that mutates entity representation in the final T2I prompt.
  - fix: Move this logic to a structured validator or use a dedicated field in the shot schema to indicate 'body-part-only' focus, rather than relying on LLM pattern matching.

- `119-130` **P1 / semantic_string_judgment**
  - evidence: 사진, 포스터, 그림, 초상화, 모니터, TV, 거울, 창유리 반사, 투영 — 은 C##O## 절대 금지
  - why: The prompt requires the LLM to judge the 'reality' of an entity (real vs 2D media) based on scenario context to decide on ID usage. This is a semantic routing decision that should be handled by structured metadata.
  - fix: Introduce a 'media_type' or 'is_reflection' attribute in the entity/shot schema to drive this behavior programmatically.

- `351-368` **P1 / llm_closed_list_instruction**
  - evidence: Asian, East Asian, South Asian, Southeast Asian, Black, Middle Eastern, Hispanic, Caucasian
  - why: The prompt hardcodes a closed list of demographic/racial labels for open-world entity classification. This should be part of a structured world-rule SOT (Source of Truth) to allow for scenario-specific diversity and regional settings.
  - fix: Inject demographic descriptors from a structured 'visual_world_rules' SOT rather than hardcoding them in the system prompt.

- `431-442` **P1 / llm_closed_list_instruction**
  - evidence: attacker / assailant / aggressor / predator / pursuer / victim / prey / target
  - why: The prompt provides a hardcoded 'vocabulary palette' for violence and power dynamics. This is domain-specific trope pollution that should be emitted by a structured rule SOT based on the scenario's genre and intensity.
  - fix: Move domain-specific vocabulary and trope lists to a separate configuration or SOT that is injected based on the scenario's metadata (e.g., genre: thriller).

## `prompts/_base/scene_detail/12.202605021300/system.md`

- `412-418` **P2 / scenario_dependent_prompt**
  - evidence: C11O13 in a security uniform, an East Asian man in his 30s ... C03O05 in fisher workwear, a young Southeast Asian man
  - why: These examples use scenario-specific roles (security uniform, fisher workwear) and demographic mappings that reflect the current project's setting (TheRoad-I1), potentially biasing the LLM's generation for other scenarios.
  - fix: Use more generic examples that demonstrate the structure of the demographic descriptor without tying them to specific scenario roles or regions.

- `482-492` **P1 / llm_closed_list_instruction**
  - evidence: attacker / assailant / aggressor / predator / pursuer ... tearing flesh, ripped skin, gaping wound, jagged gash, raw tissue
  - why: This provides a closed list of high-intensity tropes and nomenclature for violence. It forces the LLM to use specific 'predatory' or 'brutal' language for any conflict scene, biasing the visual output regardless of the actual scenario's tone or genre. This nomenclature should be provided by a structured world/rule SOT.
  - fix: Remove the hardcoded vocabulary palette. Instead, provide intensity levels or genre-specific descriptors through a structured world/rule SOT or the scene's staging metadata.

- `552` **P1 / scenario_dependent_prompt**
  - evidence: Photorealistic cinematic still.
  - why: The visual style is hardcoded as 'Photorealistic' in the system prompt. This prevents the pipeline from supporting different artistic styles (e.g., stylized, animated, or period-specific mediums) that should be defined in a global style SOT.
  - fix: Replace the hardcoded style string with a placeholder or variable that is populated from the project's visual style configuration.

## `prompts/_base/scene_detail/13.202605022141/detail_schema.json`

- `16` **P1 / blind_string_mutation**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: This instructs the LLM to perform semantic classification of visual tropes (close-ups, mirrors) to decide whether to use a structured ID (C01O02) or a generic noun. This introduces inconsistency in character tracking and relies on subjective LLM judgment to mutate the string format, which can break downstream automated substitution logic (the 'Image N' replacement mentioned in the same line).
  - fix: Maintain consistent ID usage (C01O02) in the t2i_prompt regardless of shot type, and handle visual-context-specific prompt adjustments (like 'a hand' vs 'the character') in a dedicated post-processing step or via the T2I adapter logic.

## `prompts/_base/scene_detail/13.202605022141/system.md`

- `48` **P1 / semantic_string_judgment**
  - evidence: Focus on / close on / tight on / detail on
  - why: Instructs the LLM to switch from entity IDs to common nouns based on the presence of specific natural language phrasing patterns, which is a form of pattern-based semantic routing.
  - fix: Use structured framing metadata to decide entity representation rather than parsing natural language focus phrases.

- `119` **P1 / llm_closed_list_instruction**
  - evidence: 사진, 포스터, 그림, 초상화, 모니터, TV, 거울, 창유리 반사, 투영
  - why: Provides a closed list of media types to determine whether an entity is a 2D representation or a physical person, which affects ID usage routing.
  - fix: Define media representation status in the entity or scene schema rather than relying on a hardcoded list of nouns in the prompt.

- `339-341` **P1 / semantic_string_judgment**
  - evidence: close-up, CU, MCU, ECU, XCU, extreme close-up, 클로즈업, 손가락이, 손이, 눈이, 얼굴이
  - why: Uses a list of specific body part keywords and shot type abbreviations to determine the framing scale. This is keyword-based routing of visual logic.
  - fix: Rely on structured shot metadata (framing_scale) rather than scanning natural language descriptions for body parts or abbreviations.

- `403-424` **P1 / llm_closed_list_instruction**
  - evidence: Asian, East Asian, South Asian, Southeast Asian, Black, Middle Eastern, Hispanic, Caucasian
  - why: The prompt provides a hardcoded list of demographic and ethnic labels for the LLM to use when describing characters. This should be part of a structured world/rule SOT rather than being hardcoded in the system prompt.
  - fix: Move demographic classification labels to a structured visual world rule SOT and have the prompt reference those categories dynamically.

- `482-503` **P1 / llm_closed_list_instruction**
  - evidence: attacker / assailant / aggressor / predator / pursuer, tearing flesh, ripped skin, gaping wound, blood spray, spurting blood
  - why: The prompt provides a specific 'vocabulary palette' and genre-based constraints for violence. This biases the LLM towards specific tropes and descriptors instead of allowing the world/genre SOT to define the appropriate tone.
  - fix: Remove hardcoded trope lists and instead provide high-level instructions to match the tone and intensity defined in the scenario or genre SOT.

- `529-533` **P1 / semantic_string_judgment**
  - evidence: running, riding, walking, moving, chasing, pedaling, rowing
  - why: Uses a list of specific motion verbs to trigger a 'Reframe' strategy for complex scenes. This is keyword-based routing of story/visual logic.
  - fix: Use structured action tags or motion metadata to trigger reframing strategies instead of keyword matching over scenario text.

## `prompts/_base/scene_detail/14.202605031033/system.md`

- `339-341` **P1 / semantic_string_judgment**
  - evidence: close framing: `close-up`, `CU`, `MCU`, `ECU`, `XCU`, `extreme close-up`, `클로즈업`, `손가락이`, `손이`, `눈이`, `얼굴이`
  - why: The prompt instructs the LLM to classify the shot's framing scale (routing logic for Rule J and Rule E) based on a closed list of natural language keywords and body part nouns found in the input description.
  - fix: Pass the framing scale as a structured enum in the shot metadata rather than relying on the LLM to parse it from natural language strings.

- `403-418` **P1 / llm_closed_list_instruction**
  - evidence: Asian, East Asian, South Asian, Southeast Asian, Black, Middle Eastern, Hispanic, Caucasian
  - why: The prompt provides a closed list of demographic descriptors and maps them to specific regions. This biases the LLM's output toward these specific labels and creates a maintenance burden if the world-building regions change.
  - fix: Demographic descriptors should be sourced directly from the 'visual_world_rules' or 'character_metadata' rather than being hardcoded as examples in the system prompt.

- `477-499` **P1 / scenario_dependent_prompt**
  - evidence: attacker / assailant / aggressor / predator / pursuer ... tearing flesh, ripped skin, gaping wound
  - why: This section provides a hardcoded 'vocabulary palette' for violence and physical conflict. This pollutes the prompt with domain-specific tropes that should be derived from the scenario text or a structured world-rule SOT, potentially biasing the LLM toward extreme descriptions even when not warranted.
  - fix: Remove the hardcoded vocabulary list. If specific intensity levels are needed, define them in a structured 'visual_world_rules' or 'genre_guide' provided as context.

- `649-651` **P1 / semantic_string_judgment**
  - evidence: 동적 동사 (`running`, `riding`, `walking`, `moving`, `chasing`, `pedaling`, `rowing`)
  - why: The prompt uses a closed list of verbs to trigger specific 'mid-action freeze' logic. This is a pattern-based semantic judgment that may fail to capture other synonyms or contextually relevant movement verbs.
  - fix: Use a structured 'motion_state' flag in the input schema to indicate when mid-action freeze logic should be applied.

## `prompts/_base/scene_detail/15.202605032354/detail_schema.json`

- `16` **P1 / blind_string_mutation**
  - evidence: 인물+아웃룩은 복합 ID(C01O02)를 사용 — 합성 단계가 'the character from Image N'으로 자동 치환. ... 소품은 P01, 배경은 [L01: 설명] 형태.
  - why: The pipeline relies on blind string replacement of IDs (C01O02) and regex-based extraction of location descriptions from bracketed patterns ([L01: 설명]). This couples visual reference logic to fragile string patterns within natural language prompts, making the system vulnerable to LLM formatting deviations.
  - fix: Pass structured references (e.g., an array of entity objects with ID and description) alongside the prompt instead of embedding them in a custom bracketed syntax that requires regex parsing.

- `16` **P2 / llm_closed_list_instruction**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: Instructs the LLM to classify open-world visual meaning (mirror, close-up, photo) to decide whether to use a structured ID or a common noun. This semantic routing should be handled by the pipeline logic or a structured flag rather than varying the string format based on trope classification.
  - fix: Define a structured field for the type of visual representation (direct, reflection, media) and let the synthesis stage decide the prompt phrasing based on that metadata.

## `prompts/_base/scene_detail/15.202605032354/system.md`

- `48` **P1 / semantic_string_judgment**
  - evidence: Focus on / close on / tight on / detail on + 특정 신체 부위
  - why: This uses specific natural language string patterns to decide whether to use a character ID (C##) or a common noun, which is a semantic routing decision based on substring matching.
  - fix: Pass a structured 'is_closeup' or 'target_entity_type' flag from the scene analysis stage instead of relying on the LLM to parse these phrases.

- `135` **P1 / blind_string_mutation**
  - evidence: 고정 요소 description의 보통명사 인물 묘사('An Asian man', 'a woman' 등)를 해당 C##으로 대체
  - why: This instructs the LLM to perform a blind replacement of natural language descriptions with IDs, which can lead to grammatical errors or incorrect entity mapping if the source text varies.
  - fix: Use a structured character_state object where the description and character_id are separate fields, rather than mutating the description string.

- `209` **P2 / scenario_dependent_code**
  - evidence: round 4 Q1=B
  - why: This is a reference to a specific internal evaluation round or logic branch that pollutes the general system prompt with project-specific metadata.
  - fix: Remove internal evaluation references from production system prompts.

- `223` **P2 / semantic_string_judgment**
  - evidence: 회피 표현: portal for door, screen for TV — 의미상 redraw 면 위반
  - why: This uses a closed list of synonyms to judge semantic 'evasion' of background rules, which is fragile and scenario-dependent.
  - fix: Use a more robust semantic similarity check or rely on the structured 'owned objects' list without hardcoding specific synonym examples.

- `233` **P1 / semantic_string_judgment**
  - evidence: camera_direction 자연어에 close-framing tag — ECU, XCU, extreme close-up, MCU, medium close-up, close-up, CU — 가 하나라도 포함되면
  - why: The pipeline's decision to skip reference images is driven by the presence of specific natural language tags in a string, which is a semantic judgment that should be handled by structured metadata.
  - fix: Define framing scale as an enum in the shot metadata and use that to drive the reference skip logic.

- `342-347` **P1 / llm_closed_list_instruction**
  - evidence: close-up, CU, MCU, ECU, XCU, extreme close-up, 클로즈업, 손가락이, 손이, 눈이, 얼굴이
  - why: This forces the LLM to classify framing scale based on a closed list of keywords and body parts, which is a semantic judgment that dictates entity visibility and background handling.
  - fix: Provide the framing scale as a structured enum (e.g., CLOSE, MEDIUM, WIDE) in the input rather than having the LLM infer it from keywords.

- `482-504` **P2 / scenario_dependent_prompt**
  - evidence: 사용 가능 어휘 팔레트 (attacker / assailant / aggressor / predator / pursuer ... tearing flesh, ripped skin, gaping wound)
  - why: This is a hardcoded list of domain-specific tropes and vocabulary for violence. Such palettes should be part of a genre-specific SOT rather than the base system prompt.
  - fix: Move genre-specific vocabulary palettes to a separate 'style' or 'genre' rulebook injected only when relevant.

## `prompts/_base/scene_detail/16.202605041200/detail_schema.json`

- `16` **P1 / llm_closed_list_instruction**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: The LLM is required to classify the visual context (e.g., mirror, photo, close-up) to decide between using a structured ID or a common noun. This forces the LLM to perform semantic judgment to satisfy a formatting rule, which leads to inconsistent prompt structures and makes the downstream 'composition stage' dependent on the LLM's subjective classification of the scene.
  - fix: Standardize the use of IDs in the LLM output and handle the conversion to common nouns or specific phrases in a dedicated post-processing or rendering step that uses structured scene metadata.

## `prompts/_base/scene_detail/16.202605041200/system.md`

- `360-691` **P1 / semantic_string_judgment**
  - evidence: "`손가락이`, `손이`, `눈이`, `얼굴이`", "`running`, `riding`, `walking`, `moving`, `chasing`, `pedaling`, `rowing`"
  - why: The prompt instructs the LLM to infer framing scale and motion state from specific natural language tokens (including Korean body parts), which is brittle and should be driven by structured metadata rather than string patterns.
  - fix: Move framing scale and motion state to structured shot metadata (e.g., framing_scale enum and motion_state flag) to ensure deterministic visual routing.

- `424-513` **P1 / scenario_dependent_prompt**
  - evidence: "`Asian`, `East Asian`, ...", "`attacker`, `assailant`, ..."
  - why: Hardcodes demographic and violence nomenclature/tropes that should be injected from a World/Genre SOT to support arbitrary scenarios (e.g., non-human races or different levels of gore).
  - fix: Inject nomenclature from a structured SOT based on the scenario's region and genre instead of hardcoding them in the system prompt.

- `584-586` **P1 / scenario_dependent_prompt**
  - evidence: "`vehicle`, `bicycle`, `motorcycle`, `boat`, `cart`, `wheelchair`"
  - why: Hardcodes a list of props to trigger specific visual routing (Rule D), which is brittle and fails for other large props not included in the list.
  - fix: Use asset metadata (e.g., an 'is_large_prop' or 'requires_body_visibility' flag) to trigger Rule D logic.

## `prompts/_base/scene_detail/17.202605042018/system.md`

- `297-299` **P1 / semantic_string_judgment**
  - evidence: "클로즈업, 손가락이, 손이, 눈이, 얼굴이 (특정 신체 부위 명시 + close 의미)"
  - why: Uses a keyword list of body parts and shot types to classify the framing scale of a shot. This is a pattern-based semantic judgment that should be derived from structured metadata or a more robust visual analysis, as it can misclassify shots where these nouns appear in a wide context.
  - fix: Derive framing scale from a structured field in the RenderPromptCard or a dedicated visual analysis step that considers the full context of the shot.

- `361-376` **P2 / llm_closed_list_instruction**
  - evidence: "Asian, East Asian, South Asian, Southeast Asian, Black, Middle Eastern, Hispanic, Caucasian"
  - why: Provides a hardcoded list of demographic descriptors for the LLM to use as a classifier. This domain nomenclature should come from a structured world SOT to ensure consistency across different scenarios and regions.
  - fix: Inject demographic options from a structured world/region SOT instead of hardcoding them in the system prompt.

- `435-457` **P1 / scenario_dependent_prompt**
  - evidence: "attacker / assailant / aggressor / predator / pursuer", "tearing flesh, ripped skin, gaping wound"
  - why: Contains a hardcoded vocabulary palette of tropes and specific descriptors for violent scenarios. This is scenario-specific pollution that biases the LLM and should be part of a structured world-building SOT or a specialized style guide, not embedded in the general system prompt.
  - fix: Move scenario-specific trope lists and vocabulary to a structured world/rule SOT or a dynamic style injection based on the scene's genre/tags.

- `491` **P2 / semantic_string_judgment**
  - evidence: "running / riding / walking / swimming 류"
  - why: Uses a keyword list of motion verbs to decide when to apply a 'Reframe' strategy. This is a pattern-based decision on story meaning (motion) that should be handled by structured action metadata.
  - fix: Use structured action tags or a more robust semantic analysis to trigger reframing strategies.

## `prompts/_base/scene_detail/18.202605041549/detail_schema.json`

- `16` **P1 / llm_closed_list_instruction**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: This instruction requires the LLM to perform semantic classification of the visual scene (identifying 'close-ups' or 'mirrors') to decide whether to suppress character IDs. This logic is scattered in natural language rather than being driven by a structured visual-rule SOT, leading to inconsistent character tracking in complex shots.
  - fix: Define a structured 'composition_rules' SOT that maps specific shot types to ID-suppression behavior, and have the LLM output a 'composition_type' field instead of making formatting decisions based on natural language examples.

## `prompts/_base/scene_detail/18.202605041549/system.md`

- `41-43` **P1 / semantic_string_judgment**
  - evidence: trigger_phrases (focus on / close on / tight on / detail on + 신체부위)
  - why: The prompt instructs the LLM to use specific string patterns to decide whether to suppress character IDs (C##O##). This is a pattern-based semantic judgment that affects entity representation and should be handled by structured metadata.
  - fix: Move the trigger phrase logic to a structured classifier or rely on explicit flags in the RenderPromptCard rather than string matching in the prompt.

- `258-259` **P1 / semantic_string_judgment**
  - evidence: 판정 키워드 ... close-up, CU, MCU, ECU, XCU, extreme close-up, 클로즈업, 손가락이, 손이, 눈이, 얼굴이
  - why: The prompt uses a hardcoded list of keywords (including body parts) to classify the framing scale of a shot. This classification then drives logic for entity visibility and ID usage, making it a high-signal semantic judgment based on string patterns.
  - fix: The framing scale should be a structured enum in the RenderPromptCard (e.g., framing_scale: 'close') rather than being inferred from natural language keywords in the prompt.

- `353-375` **P2 / llm_closed_list_instruction**
  - evidence: 사용 가능 어휘 팔레트 ... attacker / assailant / aggressor / predator / pursuer ... forceful, firm, aggressive, violent, brutal, savage, feral, predatory, vicious
  - why: This section provides a closed list of domain-specific tropes and vocabulary for violence. While intended to guide the LLM, it pollutes the prompt with scenario-specific nomenclature that should ideally be part of a structured world/rule SOT or style guide.
  - fix: Externalize domain-specific vocabulary palettes into a structured 'visual_world_rules' or 'style_guide' SOT that can be injected based on the scenario's genre or tags.

## `prompts/_base/scene_detail/19.202605050814/detail_schema.json`

- `16` **P2 / llm_closed_list_instruction**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: This instructs the LLM to perform semantic classification of the visual scene (e.g., identifying a 'mirror' or 'close-up') to decide whether to use a technical ID or a common noun. This logic is a pattern-based semantic judgment that affects the downstream composition stage's ability to identify and replace character IDs.
  - fix: Move the logic for ID-to-noun replacement to a post-processing step or a dedicated visual-logic SOT that defines these 'exception' conditions more formally, rather than relying on the LLM's ad-hoc interpretation of visual categories within a field description.

## `prompts/_base/scene_detail/19.202605050814/system.md`

- `224-225` **P1 / semantic_string_judgment**
  - evidence: 'close-up', 'CU', 'MCU', 'ECU', 'XCU', 'extreme close-up', '클로즈업', '손가락이', '손이', '눈이', '얼굴이', 'wide shot', 'establishing', 'aerial', '전경', '전신'
  - why: The prompt defines a list of English and Korean keywords to classify the framing scale of a shot. This classification drives significant visual logic (Rule J), such as entity visibility and focus, but relies on fragile string matching of open-world scenario text.
  - fix: Pass the framing scale as a structured enum (e.g., 'CLOSE', 'WIDE', 'MEDIUM') in the RenderPromptCard metadata instead of performing keyword-based inference in the prompt.

- `356` **P1 / semantic_string_judgment**
  - evidence: running / riding / walking / swimming 류
  - why: The prompt instructs the LLM to detect complex motion or action based on a specific list of verbs to trigger 'Strategy C: Reframe'. This is a semantic routing decision based on string patterns in the scenario description.
  - fix: Use a structured 'is_complex_motion' or 'action_category' field in the input schema to trigger reframing strategies.

- `474` **P1 / semantic_string_judgment**
  - evidence: running, riding, walking, moving, chasing, pedaling, rowing
  - why: The prompt uses a hardcoded list of verbs to identify 'dynamic' shots that require motion direction preservation. This is a pattern-based judgment of open-world story content.
  - fix: Explicitly tag shots with a 'motion_state' attribute in the metadata to drive the application of freeze-frame motion rules.

## `prompts/_base/scene_detail/20.202605051240/system.md`

- `151` **P1 / semantic_string_judgment**
  - evidence: framing_scale_keywords: close-up, CU, MCU, ECU, XCU, extreme close-up, 클로즈업, 손가락이, 손이, 눈이, 얼굴이 (총 11 entries)
  - why: Uses a hardcoded list of natural language tokens (including body parts like 'fingers' and 'eyes') to perform semantic classification of framing scale, which drives visual routing logic.
  - fix: Move framing scale classification to a structured metadata field in the RenderPromptCard or a dedicated scene analysis SOT.

- `189-211` **P1 / llm_closed_list_instruction**
  - evidence: 사용 가능 어휘 팔레트 (해당 씬에서만 꺼내 쓸 것) ... attacker / assailant / aggressor / predator / pursuer ... tearing flesh, ripped skin, gaping wound
  - why: Provides a hardcoded 'Vocabulary Palette' of violence tropes and descriptors. This is scenario-specific pollution that should be emitted by a structured world/rule SOT rather than being baked into the system prompt.
  - fix: Inject scene-type specific vocabulary and behavioral rules via a dynamic 'World Rule' or 'Genre Rule' SOT based on the scenario's metadata.

- `277` **P2 / semantic_string_judgment**
  - evidence: vehicle, bicycle, motorcycle, boat, cart, wheelchair
  - why: A hardcoded list of specific props used to trigger 'Rule D' (prop body visibility). This logic should be driven by asset metadata (e.g., a 'large_prop' or 'mountable' tag) rather than string matching in the prompt.
  - fix: Define prop categories in the asset schema and pass the requirement via the RenderPromptCard's asset_requirements.

- `363` **P2 / semantic_string_judgment**
  - evidence: running, riding, walking, moving, chasing, pedaling, rowing
  - why: Hardcoded list of motion verbs used to trigger 'motion direction' freeze logic. This is a semantic judgment on open-world actions that should be handled by structured action metadata.
  - fix: Use an action-type enum or metadata flag in the shot staging data to trigger motion-specific prompt requirements.

## `prompts/_base/scene_detail/21.202605061636/system.md`

- `41-43` **P1 / llm_closed_list_instruction**
  - evidence: trigger_phrases (focus on / close on / tight on / detail on + 신체부위)
  - why: The LLM is instructed to detect specific English phrase patterns combined with arbitrary body parts to decide whether to forbid character ID usage (C##O##). This is a semantic judgment based on a hardcoded phrase list.
  - fix: Move the trigger phrase detection logic to a pre-processing step or define the specific triggers within the id_policy schema of the RenderPromptCard.

- `151` **P1 / llm_closed_list_instruction**
  - evidence: close 판정 키워드 = 'close-up', 'CU', 'MCU', 'ECU', 'XCU', 'extreme close-up', '클로즈업', '손가락이', '손이', '눈이', '얼굴이' (총 11 entries)
  - why: The prompt hardcodes a list of 11 keywords (including specific Korean body parts) to classify a shot as 'close'. This semantic classification should be driven by the structured SOT (RenderPromptCard) rather than prose reminders.
  - fix: Ensure the framing_scale_keywords are exclusively provided via the RenderPromptCard and remove the hardcoded list from the system prompt prose.

- `271` **P1 / llm_closed_list_instruction**
  - evidence: 일반 가용 어휘: forceful, firm, decisive, sudden, intense
  - why: The prompt provides a hardcoded list of intensity adjectives for violence/contact scenes. This biases the LLM toward specific vocabulary regardless of the scenario's unique tone.
  - fix: Inject allowed intensity tokens via the entity_canon or scenario-specific style rules rather than hardcoding them in the base prompt.

- `470-472` **P1 / llm_closed_list_instruction**
  - evidence: 동적 동사 (running, riding, walking, moving, chasing, pedaling, rowing)
  - why: The prompt uses a hardcoded list of verbs to trigger 'motion freeze' logic. This is a semantic classifier that should be handled by the scenario analysis pipeline or defined in a structured rule set.
  - fix: Move the motion verb classification to the shot_extract or staging analysis phase and pass a 'motion_detected' flag in the RenderPromptCard.

## `prompts/_base/scene_detail/21.202605062217/detail_schema.json`

- `16` **P1 / blind_string_mutation**
  - evidence: 합성 단계가 'the character from Image N'으로 자동 치환
  - why: This documents a downstream blind string replacement where structured IDs are swapped for natural language phrases ('the character from Image N'). This couples the prompt generation to a specific string-based substitution logic in the composition stage rather than using a structured reference system.
  - fix: Pass the structured ID (C01O02) to the composition engine and let the engine decide the reference string based on its internal state/context, rather than relying on a blind string replacement of the prompt text.

- `16` **P2 / llm_closed_list_instruction**
  - evidence: 신체 부위 클로즈업/사진·거울 속 인물 등 system prompt가 명시한 예외 구도에서는 보통명사로 대체
  - why: The LLM is instructed to classify visual meaning (close-ups, mirrors, photos) from a closed list of examples to decide whether to use a structured ID or a common noun. This logic is scattered in the schema description and should be driven by a centralized visual rule SOT.
  - fix: Define these visual exceptions in a structured 'Visual Rules' SOT and have the LLM reference that SOT, or ideally, always use IDs and let the downstream renderer/validator handle the conversion to common nouns for specific shots.

## `prompts/_base/scene_detail/21.202605062217/system.md`

- `27` **P1 / semantic_string_judgment**
  - evidence: 'and then', 'while ~ing', 'after ~ing', 'as ~', 'before ~', '~하자', '~하며', '~한 뒤'
  - why: Hardcoded list of forbidden time-related conjunctions used to enforce 'single moment' semantics. This is a pattern-based semantic judgment that should be handled by general reasoning or a more flexible rule-set.
  - fix: Replace the token list with a high-level semantic instruction to describe only a single instantaneous moment.

- `41-44` **P1 / llm_closed_list_instruction**
  - evidence: body_part_focus_rule.trigger_phrases (focus on / close on / tight on / detail on + 신체부위)
  - why: Hardcoded string patterns used to decide visual semantics (disabling character IDs). This is a pattern-based semantic judgment that should be driven by the RenderPromptCard.
  - fix: Instruct the LLM to use the trigger_phrases provided in the RenderPromptCard instead of hardcoding them in the prompt prose.

- `49-51` **P1 / llm_closed_list_instruction**
  - evidence: reproduction_surface_rule.applies_to_surfaces (사진·포스터·모니터·거울·반사·투영 등)
  - why: Hardcoded list of semantic surface categories used to mutate ID policy. This should be managed as a structured list in the RenderPromptCard to ensure consistency across different scenarios.
  - fix: Rely solely on the applies_to_surfaces field in the RenderPromptCard and remove the hardcoded examples from the prose.

- `88` **P1 / semantic_string_judgment**
  - evidence: cut / slice / split / carve / bisect + 신체 부위 조합 절대 금지
  - why: Blind string-pattern check for specific verbs to prevent lighting-induced body distortion. This is a pattern-based semantic judgment that may miss synonyms or flag valid metaphorical uses.
  - fix: Replace the verb list with a semantic instruction to avoid lighting descriptions that imply physical separation of body parts.

- `151` **P1 / llm_closed_list_instruction**
  - evidence: framing_scale_keywords: close 판정 키워드 = 'close-up', 'CU', 'MCU', 'ECU', 'XCU', 'extreme close-up', '클로즈업', '손가락이', '손이', '눈이', '얼굴이' (총 11 entries)
  - why: Hardcoded list of 11 semantic keywords used to classify framing scale. This should be driven by the structured SOT (RenderPromptCard) to allow for open-world flexibility and avoid drift.
  - fix: Remove the hardcoded list from the prompt prose and instruct the LLM to use the keywords provided in the RenderPromptCard.

- `176-177` **P1 / llm_closed_list_instruction**
  - evidence: jaw / chin / nose / cheek / forehead / mouth / eye / 이목구비 / 윤곽
  - why: Hardcoded list of forbidden facial feature words for silhouette shots. This is a closed-list semantic classifier that should be part of a structured silhouette policy in the SOT.
  - fix: Move the forbidden word list to a structured configuration or the RenderPromptCard's constraints.

- `352` **P1 / llm_closed_list_instruction**
  - evidence: vehicle, bicycle, motorcycle, boat, cart, wheelchair 등 인물이 잡고 있거나 타고 있는 큰 prop
  - why: Hardcoded list of prop types used to trigger Rule D. This is a closed-list semantic classifier for open-world objects that should be defined in a world-rule SOT.
  - fix: Move the list of 'large props' to a structured configuration or the RenderPromptCard.

- `488` **P1 / llm_closed_list_instruction**
  - evidence: running, riding, walking, moving, chasing, pedaling, rowing
  - why: Hardcoded list of motion verbs used to trigger 'freeze' logic. This limits the system's ability to handle other motion-related verbs and should be handled by semantic reasoning.
  - fix: Instruct the LLM to identify motion-related verbs semantically or provide the trigger list via the RenderPromptCard.

## `prompts/_base/scene_detail/22.202605122049/system.md`

- `41-44` **P1 / semantic_string_judgment**
  - evidence: body_part_focus_rule.trigger_phrases (`focus on / close on / tight on / detail on` + 신체부위) 패턴이 등장하면 ... C##O## 사용 금지
  - why: Decides entity ID usage (visual routing) based on substring patterns and noun matching (body parts) in the scenario text.
  - fix: Use a structured focus_target field in the shot metadata instead of parsing trigger phrases.

- `119` **P1 / blind_string_mutation**
  - evidence: fixed_elements[i].description 안 보통명사 인물 ... 이 ... 조건 만족 시 해당 보통명사를 C##/C##O## 로 치환
  - why: Performs blind string substitution of natural language nouns with technical IDs based on a mapping, which risks incorrect replacements in complex sentences.
  - fix: Use structured entity references in the fixed_elements description instead of post-hoc string replacement.

- `155` **P1 / semantic_string_judgment**
  - evidence: framing_scale_keywords: close 판정 키워드 = `close-up`, ..., `손가락이`, `손이`, `눈이`, `얼굴이`
  - why: Uses a closed list of natural language tokens (including body parts in Korean) to classify open-world framing scale, which should be determined by structured metadata.
  - fix: Move framing classification to the RenderPromptCard or a dedicated SOT that provides the framing_scale enum directly.

- `175-176` **P1 / semantic_string_judgment**
  - evidence: face fully obscured / no visible facial features / face hidden in shadow 같은 face-obscured 표현을 포함하면
  - why: Triggers specific visual logic (silhouette policy) by matching specific natural language strings in entity traits.
  - fix: Define a boolean or enum flag (e.g., visibility_state: obscured) in the entity_canon schema.

- `226-230` **P2 / scenario_dependent_prompt**
  - evidence: non-standard canine structure / altered eye coloration / injury marker
  - why: The prompt contains scenario-specific examples and domain-specific trope lists (e.g., canine structure) that should be emitted by a structured world/rule SOT.
  - fix: Remove specific trait examples from the system prompt and rely on the injected stable_traits block.

- `320-324` **P1 / semantic_string_judgment**
  - evidence: running / riding / walking / swimming 류 ... 동작A하며 동작B 같은 두 동작 합성 표현을 묘사하면
  - why: Uses a list of verbs and syntactic patterns to trigger 'Strategy C: Reframe', making visual routing decisions based on open-world string patterns.
  - fix: Move motion complexity analysis to a pre-processing step that sets a reframe_required flag in the RenderPromptCard.

- `466-470` **P1 / semantic_string_judgment**
  - evidence: entity_canon.name 이 prompt 안에 등장하면 그 specific entity 의 ID 가 같은 sentence + ±60 char window 안에 있어야 한다
  - why: Enforces a validation rule based on the presence of open-world names (entity_canon.name) within a character window, which is a pattern-based semantic judgment.
  - fix: Validate entity presence using structured ID tags rather than natural language names.

## `prompts/_base/scene_detail/23.202605141758/system.md`

- `155` **P1 / llm_closed_list_instruction**
  - evidence: close 판정 키워드 = `close-up`, `CU`, `MCU`, `ECU`, `XCU`, `extreme close-up`, `클로즈업`, `손가락이`, `손이`, `눈이`, `얼굴이` (총 11 entries; freeze-frame `정지 컷` 류는 무관)
  - why: The LLM is instructed to classify the framing scale (a visual semantic property) based on a hardcoded list of 11 string patterns, including specific body parts in Korean. This is a heuristic-based semantic judgment that should be derived from structured metadata (SOT) rather than string matching in the prompt prose.
  - fix: Remove the hardcoded list from the prompt prose. Ensure the framing scale classification is performed upstream or passed as a structured enum/boolean in the RenderPromptCard, and have the LLM follow the card's explicit instruction rather than performing its own string-based detection.

## `prompts/_base/scene_detail/24.202605151451/system.md`

- `41-44` **P1 / semantic_string_judgment**
  - evidence: trigger_phrases (focus on / close on / tight on / detail on + 신체부위) 패턴이 등장하면 ... C##O## 사용 금지
  - why: The prompt uses a hardcoded list of natural language phrases to trigger a change in entity representation (ID policy). This logic should be driven by structured metadata in the RenderPromptCard rather than pattern matching on the prompt's own reasoning or source text.
  - fix: Move the trigger logic to the shot_staging or card generation phase, providing a boolean flag (e.g., is_body_part_focus) instead of relying on phrase matching.

- `140-144` **P1 / blind_string_mutation**
  - evidence: the existing X / from the reference / use the X from the reference / preserving the same room perspective / maintaining the reference's framing / do not generate a new X
  - why: This is a hardcoded list of forbidden phrases used to enforce background binding rules. Relying on a closed list of phrases to prevent specific visual mentions is fragile and prevents the LLM from using natural variations that might be necessary for the scene.
  - fix: Define the constraint semantically (e.g., 'do not mention the background reference') and allow the LLM to handle the phrasing, or use a more robust validation step.

- `220-226` **P1 / semantic_string_judgment**
  - evidence: face fully obscured / no visible facial features / face hidden in shadow ... jaw / chin / nose / cheek / forehead / mouth / eye / 이목구비 / 윤곽 같은 face-feature 단어를 직접 출력하지 마라
  - why: The prompt instructs the LLM to perform semantic classification on trait strings to decide whether to suppress a specific list of nouns. This is a pattern-based visual decision that should be explicitly signaled by a structured status (e.g., face_visibility: obscured) in the entity traits.
  - fix: Replace the string-matching logic with a structured visibility enum in the entity_canon or stable_traits.

- `511-515` **P1 / semantic_string_judgment**
  - evidence: entity_canon.name 이 prompt 안에 등장하면 그 specific entity 의 ID ... 가 같은 sentence + ±60 char window 안에 있어야 한다.
  - why: This is a highly specific string-level validation rule (window-based proximity) embedded in the prompt to ensure ID-Name association. This type of technical constraint is difficult for LLMs to follow precisely and indicates a lack of structured mapping between names and IDs in the generation pipeline.
  - fix: Ensure the LLM always uses a standard template for entity introduction (e.g., 'Name (ID)') rather than enforcing a character-count window check.

## `prompts/_base/scene_detail/7.202604201230/system.md`

- `96-135` **P1 / scenario_dependent_prompt**
  - evidence: "middle-aged Korean woman", "Korean man in his 30s", "young Korean woman", "A Korean man", "Korean woman"
  - why: The prompt repeatedly uses 'Korean' as the default ethnicity in examples across multiple sections (photos, consistency, perspective). This creates a strong few-shot bias that pollutes the LLM's output, likely causing it to generate 'Korean' even for scenarios where it is inappropriate, despite the instruction in line 46 to avoid fixing the setting.
  - fix: Replace specific ethnicities in examples with generic placeholders like '[Race/Nationality]' or use diverse, non-specific descriptions to ensure the LLM remains neutral and follows the provided scenario/world SOT.

- `169-170` **P2 / llm_closed_list_instruction**
  - evidence: "the aggressor / the one being attacked", "firm, forceful, aggressive, violent"
  - why: This section provides a closed list of semantic labels and adjectives to describe physical conflict. While intended to mitigate T2I model bias (intimacy bias), hardcoding these specific terms in the system prompt forces a 'violence' framing on all physical interactions, which should instead be derived from the scenario's specific tone or a structured interaction SOT.
  - fix: Abstract these instructions to focus on 'physical tension' and 'asymmetric positioning' rather than providing a specific vocabulary list, or move the vocabulary to a domain-specific rule SOT.

## `prompts/_base/scene_detail/8.202604201530/system.md`

- `19-27` **P1 / semantic_string_judgment**
  - evidence: C## 사용 여부는 얼굴이 식별 가능한지로 판단... 완전히 뒤돌아선 인물... 실루엣... OTS에서 뒷통수/어깨만...
  - why: The LLM is tasked with making a critical routing decision (using a technical ID vs. a common noun) based on its open-world interpretation of visual identifiability. This directly affects whether the T2I pipeline attaches face reference images, making the visual consistency dependent on pattern-based semantic judgment.
  - fix: Define face visibility/identifiability as a structured field in the shot metadata or SOT rather than relying on LLM interpretation of the scene description.

- `96-100` **P2 / scenario_dependent_prompt**
  - evidence: middle-aged Korean woman... a Korean man in his 30s... young Korean woman
  - why: The examples are polluted with scenario-specific demographic details ('Korean') which can bias the LLM's generation for scenarios set in different regions or involving different ethnicities.
  - fix: Use more generic or diverse examples (e.g., 'a middle-aged woman', 'a man in his 30s') to avoid demographic bias in the system prompt.

- `107` **P2 / blind_string_mutation**
  - evidence: 고정 요소 description의 보통명사 인물 묘사('A Korean man', 'a woman' 등)를 해당 C##으로 대체
  - why: Instructs the LLM to perform a semantic replacement of natural language descriptions with IDs. This is a form of blind string mutation that risks incorrect entity mapping if the scenario contains multiple characters matching the common noun description.
  - fix: Ensure character mapping is handled by explicit entity IDs in the source text rather than requiring the LLM to perform string-based semantic replacement.

- `168-184` **P1 / llm_closed_list_instruction**
  - evidence: 사용 가능 어휘 팔레트... attacker / assailant / aggressor / predator / pursuer... tearing flesh, ripped skin, gaping wound...
  - why: This provides a hardcoded list of high-signal tokens for the LLM to inject based on its interpretation of violence in the scenario. This scattered domain nomenclature should be managed by a structured world-rule SOT to avoid biasing open-world descriptions with a fixed vocabulary.
  - fix: Move the violence vocabulary and intensity mapping to a structured world-rule SOT or a dedicated configuration file.

## `prompts/_base/scene_detail/9.202604201700/system.md`

- `96-171` **P2 / scenario_dependent_prompt**
  - evidence: middle-aged Korean woman ... Korean man in his 30s ... young Korean woman ... A Korean man stands rigidly ... furrowed brow of a Korean woman
  - why: The base prompt uses ethnicity-specific (Korean) examples for character descriptions. While appropriate for a specific project, hardcoding these in a base prompt limits its reusability for other scenarios and introduces demographic bias into the LLM's generation logic.
  - fix: Replace ethnicity-specific examples with generic placeholders or diverse examples (e.g., 'a middle-aged woman', 'a man in his 30s') to maintain the prompt's neutrality as a base component.

- `204-226` **P1 / llm_closed_list_instruction**
  - evidence: attacker / assailant / aggressor / predator / pursuer ... tearing flesh, ripped skin, gaping wound, jagged gash, raw tissue
  - why: Hardcoded domain-specific vocabulary for violence and physical conflict biases the LLM toward specific graphic tropes. This nomenclature should be provided via a structured World or Genre SOT rather than being baked into the base system prompt, as it forces a specific 'flavor' of violence that may not suit all scenarios.
  - fix: Move the violence vocabulary palette to a separate genre-specific or world-specific SOT and inject it dynamically based on the scenario's metadata.

## `prompts/_base/scene_detail_owned_judge/1.202605032354/system.md`

- `7` **P2 / scenario_dependent_prompt**
  - evidence: round 4 Q2=B / round 5 BLOCKING 1
  - why: Internal project tracking, versioning history, or blocking notes are embedded in the system prompt, which constitutes scenario-specific pollution.
  - fix: Remove internal project management references and historical context from the production system prompt.

- `18-19` **P1 / llm_closed_list_instruction**
  - evidence: portal for door, screen for TV, a TV displaying a news bulletin in the corner
  - why: The prompt uses specific noun substitutions and scenario-specific prop examples to define semantic violations. This forces the LLM to classify open-world meaning based on a closed list of examples, which may conflict with valid scenario-specific objects (e.g., a sci-fi 'portal' that is not a 'door').
  - fix: Instruct the LLM to use general semantic reasoning to identify synonyms or redrawing attempts, or move specific object mappings to a structured SOT/world-rule input.

## `prompts/_base/scene_detail_owned_judge/2.202605051641/system.md`

- `7` **P2 / scenario_dependent_prompt**
  - evidence: round 4 Q2=B / round 5 BLOCKING 1
  - why: Internal project-specific milestone markers and logic references are embedded in the system prompt, which is scenario-specific pollution.
  - fix: Remove internal project tracking references from the production system prompt.

- `16-20` **P1 / llm_closed_list_instruction**
  - evidence: portal for door, screen for TV
  - why: The prompt instructs the LLM to detect 'evasive expressions' using a closed list of specific synonym examples. This is a brittle semantic classifier for open-world story text.
  - fix: Use a more generalized instruction for semantic equivalence or rely on a structured world-rule SOT to define prohibited object mutations.

- `23-28` **P1 / llm_closed_list_instruction**
  - evidence: near the doorway, beside the table, against the wall by the window
  - why: The LLM is provided with a closed list of natural language anchor phrases to distinguish valid references from violations. This biases the judge against valid but differently phrased spatial references.
  - fix: Define the semantic criteria for 'anchoring' (e.g., spatial preposition + reference to existing context) rather than providing a fixed list of examples.

- `31` **P1 / semantic_string_judgment**
  - evidence: ambiguous case (e.g. "the table" 단순 등장) → redraw_violation
  - why: Hardcoded semantic rule that treats simple noun presence as a violation unless specific anchor patterns are met. This is a pattern-based judgment on open-world text.
  - fix: Allow the LLM to use broader context to determine if a noun phrase refers to an existing object or a new one, rather than enforcing a rigid default based on phrase structure.

## `prompts/_base/scene_detail_owned_judge/3.202605051746/system.md`

- `21-32` **P1 / semantic_string_judgment**
  - evidence: owned 객체의 의미적 우회 표현 (예: `portal` 로 `door` 우회, `screen` 으로 `TV` 우회)
  - why: This instructs the LLM to perform open-world semantic mapping based on specific examples, which contradicts the 'exact match' instruction in line 7. It forces the LLM to guess intent for 'bypass' words not present in the structured owned_list, leading to inconsistent validation.
  - fix: Enforce strict matching as per line 7 and ensure that any valid aliases (like 'portal' for a specific door) are included in the 'owned_list' provided to the prompt.

## `prompts/_base/scene_director/6.202603251200/analyze_schema.json`

- `11` **P2 / llm_closed_list_instruction**
  - evidence: "scene_type": {"type": "string", "description": "normal | montage | flashback | dream | voiceover | transition | other"}
  - why: The LLM is instructed to classify open-world narrative structure into a hardcoded list of cinematic tropes. This limits the system's ability to handle diverse storytelling modes (e.g., 'simulation', 'hallucination', 'meta-commentary') without schema modification. These categories should ideally be defined in a project-level SOT.
  - fix: Move the narrative mode definitions to a structured World/Director SOT and inject them into the prompt dynamically, or use a formal JSON Schema 'enum' if these are intended to be immutable system constants.

## `prompts/_base/scene_director/6.202603251200/system.md`

- `7-33` **P1 / llm_closed_list_instruction**
  - evidence: 영상통화, CCTV, 방송 화면, 홀로그램, VR, 원격 조종/빙의 기술, 유령, 영혼, 아스트랄 투영, 변장, 쌍둥이 교체, 바디더블, 회상(플래시백), 꿈/환상/상상
  - why: The prompt instructs the LLM to classify entity presence based on a hardcoded list of narrative tropes. This is a closed-list semantic classifier for open-world story meaning. Specific tropes like 'astral projection' or 'possession' are genre-dependent and should not be hardcoded in a base system prompt, as they may conflict with the internal logic of specific scenarios (e.g., a world where holograms are physical entities).
  - fix: Relocate narrative presence logic and trope-specific rules to a structured 'World Rules' or 'Scenario Context' SOT. The system prompt should be generalized to apply rules provided in the input context rather than hardcoding specific genre tropes.

## `prompts/_base/scene_director/7.202604031800/system.md`

- `8-24` **P2 / llm_closed_list_instruction**
  - evidence: 영상통화, CCTV, 방송 화면, 홀로그램, VR, 원격 조종/빙의 기술 ... 변장, 쌍둥이 교체, 바디더블 ... 유령 ... 빙의/원격접속
  - why: The prompt defines entity presence/visibility using a closed list of genre-specific tropes (sci-fi, supernatural, etc.). This hardcodes semantic judgment logic that should be derived from a structured world-rule SOT, as different scenarios may have different rules for how these entities are visually represented or identified.
  - fix: Abstract visibility and identity rules into a structured world-rule SOT that is injected into the prompt, rather than hardcoding specific trope examples in the base system instructions.

## `prompts/_base/scene_director/8.202604081200/system.md`

- `8-34` **P2 / llm_closed_list_instruction**
  - evidence: 영상통화, CCTV, 방송 화면, 홀로그램, VR, 원격 조종/빙의 기술 ... 변장, 쌍둥이 교체, 바디더블 ... 유령 ... (빙의/원격/V.O. 등)
  - why: The prompt uses a closed list of specific domain tropes (sci-fi tech, supernatural beings, specific plot devices) to define the semantic boundary of 'visibility'. This pollutes the base scene director logic with scenario-specific concepts that may not apply to all genres and should instead be defined in a world-rule SOT.
  - fix: Generalize the visibility criteria to focus on 'physical presence in the scene's spatial context' and move specific trope-based examples to a scenario-specific configuration or a world-rule SOT injected at runtime.

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

- `60` **P1 / scenario_dependent_prompt**
  - evidence: "동녘(강의원)" → 동녘의 몸만 보이고, 강의원은 다른 곳에 있으므로 강의원 제외
  - why: The base prompt includes specific character names ('동녘', '강의원') and a specific plot mechanic (remote control/possession) as an example. This pollutes the generic scene extraction logic with scenario-specific data that should not exist in a base template.
  - fix: Use generic placeholders like 'Character A (Character B)' or 'Pilot (Remote Operator)' to explain the visibility rule.

- `63` **P2 / scenario_dependent_prompt**
  - evidence: "캡슐속 남자들" → 캡슐이 이 장소에 없으면 제외
  - why: Uses a specific scenario-derived phrase ('Men in capsules') as a logic example for excluding non-present props, which is scenario-specific pollution in a base prompt.
  - fix: Replace with a generic example like 'The man in the car' (where the car is not in the current scene).

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

- `66-68` **P1 / scenario_dependent_prompt**
  - evidence: 예: 한국 배경이면 "Korean police officer", "Korean-style apartment", "Korean convenience store" ... 예: 조선시대면 "Joseon-era nobleman", "tiled-roof wooden structure" ... ("police officer" → "Korean police officer")
  - why: Hardcoded scenario-specific examples (Korean, Joseon) bias the LLM towards specific cultural tropes instead of deriving them from the provided world SOT. This is scenario leakage in a base prompt.
  - fix: Replace specific cultural examples with generic instructions to utilize the 'world_context' or 'era' metadata provided in the input.

- `74-75` **P1 / llm_closed_list_instruction**
  - evidence: 카메라 구도 선택지: low angle / high angle / dutch angle / over-the-shoulder / bird's eye / extreme wide / tight medium ... 색감 선택지: warm amber / cold blue / high contrast / desaturated / golden hour / neon-lit / silhouette backlight
  - why: Restricts visual variety to a hardcoded list in a base prompt, preventing scenario-specific or artist-driven styles from being used unless they happen to be in this list.
  - fix: Inject these options as a dynamic configuration or allow the LLM to suggest appropriate styles based on the scene's mood and world SOT.

- `91` **P2 / scenario_dependent_prompt**
  - evidence: 예: "캡슐속 남자들"이 헬기에 타고 있다면 → 캡슐은 헬기에 없으므로 제외
  - why: Contains a specific story-based example ("Men in capsules", "Helicopter") which is scenario pollution in a base prompt used to explain visibility logic.
  - fix: Use an abstract logic example (e.g., "If an object is mentioned as being inside a container that is not present in the current scene...").

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

- `60` **P1 / scenario_dependent_prompt**
  - evidence: "동녘(강의원)"
  - why: The base system prompt includes specific character names from a particular scenario as examples. This pollutes the model's context and can bias entity extraction or reasoning when applied to different stories.
  - fix: Replace specific names with generic placeholders like 'Character A (Character B)' or 'Person A'.

- `63` **P1 / scenario_dependent_prompt**
  - evidence: "캡슐속 남자들"
  - why: Uses a scenario-specific prop/description as an example in a base prompt, leading to domain pollution and potential bias in how the LLM handles similar props in other scenarios.
  - fix: Use a generic example like 'Object A' or 'Item in a container'.

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

- `76-78` **P1 / scenario_dependent_prompt**
  - evidence: 예: 한국 배경이면 "Korean police officer", "Korean-style apartment" ... 예: 조선시대면 "Joseon-era nobleman"
  - why: The prompt hardcodes specific cultural and historical tropes as examples for the LLM to follow. This biases the LLM's generation towards these specific patterns and pollutes the base prompt with domain-specific nomenclature that should be derived from the world SOT.
  - fix: Remove specific cultural examples. Use generic instructions like 'Apply the cultural and historical context defined in the world setting to all descriptions' without hardcoding 'Korean' or 'Joseon' as the target.

- `101` **P2 / scenario_dependent_prompt**
  - evidence: 예: "캡슐속 남자들"이 헬기에 타고 있다면 -> 캡슐은 헬기에 없으므로 제외
  - why: Uses a specific story scenario (men in capsules, helicopter) to explain entity visibility logic, introducing scenario-specific pollution into a base prompt.
  - fix: Replace with a generic example, e.g., 'If a character is inside a vehicle that is not visible in the current shot, do not include the vehicle in the visible entities list.'

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

- `60` **P1 / scenario_dependent_prompt**
  - evidence: "동녘(강의원)"
  - why: The prompt uses specific character names from a particular scenario to illustrate entity visibility logic. This pollutes the general extraction instructions with scenario-specific data, which can bias the LLM when processing different stories.
  - fix: Replace specific character names with generic placeholders such as 'Character A (Character B)'.

- `63` **P2 / scenario_dependent_prompt**
  - evidence: "캡슐속 남자들"
  - why: Uses a specific scenario-derived prop/phrase as an example for exclusion logic in a base prompt, which should remain scenario-agnostic.
  - fix: Use a generic example like 'Background characters mentioned in dialogue' or 'Generic Object A'.

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

- `83-85` **P1 / scenario_dependent_prompt**
  - evidence: 예: 한국 배경이면 "Korean police officer", "Korean-style apartment" ... 예: 조선시대면 "Joseon-era nobleman"
  - why: The base prompt contains hardcoded cultural and historical examples to guide the LLM's descriptive style. This forces the LLM to perform semantic mapping of a 'world setting' to specific strings like 'Korean' or 'Joseon' using scattered examples rather than a structured World/SOT definition.
  - fix: Remove specific cultural examples from the base prompt. Instead, provide a 'World Context' variable in the prompt that contains these descriptive requirements (e.g., 'Nationality: Korean', 'Era: Joseon') derived from the project's metadata.

- `108` **P2 / scenario_dependent_prompt**
  - evidence: 예: "캡슐속 남자들"이 헬기에 타고 있다면 → 캡슐은 헬기에 없으므로 제외
  - why: This is a concrete story-specific example (likely from a specific project involving 'men in capsules' and 'helicopters') used to illustrate a logic rule. It pollutes the base prompt with scenario-specific entities.
  - fix: Replace the scenario-specific example with a generic one, such as 'If a character is mentioned as being inside a car that is not present in the current scene, do not include the car in the visible entities.'

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

- `60` **P1 / scenario_dependent_prompt**
  - evidence: "<visible_body_name>(<remote_identity_name>)"
  - why: This hardcodes a specific sci-fi/fantasy trope (possession) and a naming convention into the base system prompt to drive entity visibility logic. It instructs the LLM to perform semantic exclusion based on a specific string pattern, which should instead be derived from a structured SOT or scenario-specific rules.
  - fix: Remove the hardcoded string pattern example and instruct the LLM to rely solely on the structured visual_world_rules provided in the context for determining visibility in possession cases.

- `63` **P1 / scenario_dependent_prompt**
  - evidence: "<container descriptor> 안의 인물들"
  - why: This uses a specific natural language pattern to define entity exclusion logic. This is scenario-dependent (e.g., characters inside a vehicle, screen, or container) and should be handled by structured scene analysis or general spatial reasoning rather than a hardcoded string pattern in the base system prompt.
  - fix: Move container-based visibility logic to a structured rule set or handle it via general spatial reasoning instructions rather than specific string patterns.

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

- `34-38` **P1 / semantic_string_judgment**
  - evidence: 얼굴/형태 식별 불가 인물 — short_id 사용 금지
  - why: This instructs the LLM to omit entity IDs (C##O##) based on its semantic interpretation of the scene (e.g., silhouettes, shadows). This directly controls reference attachment routing; if the ID is omitted, the downstream T2I pipeline cannot attach the character's reference image, breaking visual consistency based on a subjective LLM judgment.
  - fix: Retain the short_id for entity tracking and use a separate boolean flag or visual modifier (e.g., 'is_silhouette: true') in the structured output to control reference attachment logic.

- `83-85` **P1 / scenario_dependent_prompt**
  - evidence: <region-derived demonym> police officer`, `<region-style apartment>
  - why: The prompt instructs the LLM to 'derive' regional and temporal markers from scenario 'cues' and inject them into the prompt. This relies on open-world LLM interpretation of the setting rather than using a structured World SOT (e.g., 'Region: Joseon', 'Era: 18th Century'), leading to inconsistent visual branding across scenes.
  - fix: Inject structured world-building attributes (Region, Era, Culture) from a central SOT into the prompt variables instead of asking the LLM to derive them from the scenario text.

- `91-92` **P2 / llm_closed_list_instruction**
  - evidence: warm amber / cold blue / high contrast / desaturated / golden hour / neon-lit / silhouette backlight
  - why: Hardcoded lists of visual styles and lighting options within the prompt limit the visual language to a fixed set of tropes. These should be externalized to a style SOT or configuration to allow for project-specific visual direction.
  - fix: Pass the available style and camera options as a dynamic variable `{available_styles}` sourced from a project-level configuration.

## `prompts/_base/scene_generator/v1/scene_rules_en.md`

- `5` **P1 / scenario_dependent_prompt**
  - evidence: realistic contemporary-to-near-future Korean aesthetics
  - why: Hardcodes a specific cultural and temporal setting into a base prompt. This prevents the pipeline from supporting arbitrary scenarios (e.g., historical, Western, or sci-fi) without modifying core prompt files.
  - fix: Move aesthetic and temporal constraints to a structured World SOT or scenario-specific configuration that is injected at runtime.

- `6` **P1 / scenario_dependent_prompt**
  - evidence: fantasy armor, or medieval architecture
  - why: Hardcodes genre-specific negative constraints. These tropes are only 'anachronistic' if the scenario is contemporary; they would be valid in other settings, making this prompt scenario-polluted.
  - fix: Move genre-specific negative constraints to a style/genre configuration block or a dynamic rule-set.

## `prompts/_base/scene_generator/v1/scene_rules_ko.md`

- `5-6` **P1 / scenario_dependent_prompt**
  - evidence: 동시대~근미래 한국 기준 ... 사극풍 복식, 판타지 갑옷, 중세풍 건축 금지
  - why: These lines hardcode a specific setting (Modern Korea) and genre-specific negative constraints (no fantasy/history) into a base prompt. This prevents the pipeline from being used for diverse scenarios or different cultural contexts without manual prompt modification.
  - fix: Move setting-specific constraints and genre-based negative prompts to a structured World SOT or Scenario Configuration that is injected into the prompt template dynamically.

## `prompts/_base/scene_generator/v1/style_rules_generator.md`

- `5-10` **P1 / llm_closed_list_instruction**
  - evidence: 현대, 근미래, SF, 중세, 조선시대, 고대 등 ... 한국, 일본, 미국, 유럽, 우주, 가상세계 등 ... 현대복, 군복, 갑옷, 한복, 우주복 등
  - why: The prompt uses specific cultural and historical examples (e.g., Joseon Dynasty, Hanbok) as classification anchors for style generation. This creates a bias toward these specific tropes and limits the system's ability to handle arbitrary open-world scenarios without pollution from these predefined categories.
  - fix: Replace the hardcoded examples with instructions to extract these attributes directly from the scenario text or a provided structured World SOT.

## `prompts/_base/scene_generator/v2/scene_rules_en.md`

- `6` **P1 / scenario_dependent_prompt**
  - evidence: fantasy armor, or medieval architecture
  - why: These are domain-specific trope exclusions hardcoded into a base prompt. This creates a conflict if the 'world rules' (referenced in line 5) define a fantasy or historical setting, preventing the generator from being truly open-world.
  - fix: Remove specific genre tropes from the base rules. Rely on the 'world rules' or 'style guide' to define era-appropriate constraints and exclusions dynamically.

## `prompts/_base/scene_generator/v2/scene_rules_ko.md`

- `6` **P1 / scenario_dependent_prompt**
  - evidence: 사극풍 복식, 판타지 갑옷, 중세풍 건축 금지
  - why: This line hardcodes specific genre and era exclusions (historical drama clothing, fantasy armor, medieval architecture) into the base scene generation rules. This is scenario-specific pollution that should be managed by the world-building SOT or style guide mentioned in line 5, rather than being globally prohibited.
  - fix: Remove specific genre tropes from the base rules and delegate style/era constraints to the structured world rules SOT.

## `prompts/_base/scene_generator/v2/style_rules_generator.md`

- `5-10` **P1 / llm_closed_list_instruction**
  - evidence: 현대, 근미래, SF, 중세, 조선시대, 고대 등 ... 한국, 일본, 미국, 유럽, 우주, 가상세계 등 ... 리얼리즘, 판타지, 사이버펑크, 누아르, 코미디 등
  - why: The prompt provides hardcoded examples for era, region, genre, and style classification. This biases the LLM's analysis toward specific cultural and genre tropes (e.g., Joseon era, Hanbok) and creates maintenance debt. These categories should be injected from a structured Source of Truth (SOT) to ensure consistency across different projects and avoid regional/genre bias in the base prompt.
  - fix: Remove hardcoded trope lists and replace them with dynamically injected categories or a reference to a structured world-building schema provided in the context.

## `prompts/_base/scene_image/1.202603181600/translate_prompt.md`

- `5` **P2 / scenario_dependent_prompt**
  - evidence: e.g., "a young Korean man", "an elderly woman"
  - why: Provides specific demographic examples that can bias the LLM's character descriptions toward a specific ethnicity or age group, rather than relying on the provided character metadata or reference roles.
  - fix: Use abstract placeholders or remove the examples, ensuring character descriptions are strictly derived from the provided {ref_roles_text}.

- `10` **P1 / scenario_dependent_prompt**
  - evidence: Do NOT include camera angles or shot types (no "close-up", "wide shot", "medium shot")
  - why: Hard-strips cinematic intent from the prompt using a closed list of shot types. This is a semantic decision that limits the visual variety of the output and should be controlled by the scenario analysis or a specific shot-type SOT.
  - fix: Allow shot types if they are present in the source prompt or manage them through a structured field in the prompt assembly.

- `11` **P1 / scenario_dependent_prompt**
  - evidence: Keep "Photorealistic cinematic still." at the beginning
  - why: Hardcodes a specific visual style (photorealism) into the base translation prompt, preventing the pipeline from supporting other styles (e.g., stylized, illustrative) without modifying the base prompt.
  - fix: Move the style prefix to a configuration variable or include it within the {style_context} variable.

## `prompts/_base/scene_image/2.202603251100/translate_prompt.md`

- `12` **P1 / scenario_dependent_prompt**
  - evidence: Do NOT include "Photorealistic cinematic still." — it will be added separately
  - why: Hardcoding a specific visual style string ('Photorealistic cinematic still') in the base translation prompt biases the LLM's semantic understanding of the scene toward photorealism. It also creates a tight coupling between the prompt logic and a specific global style suffix that should be managed via a structured style SOT or dynamic variable.
  - fix: Replace the hardcoded string with a dynamic placeholder or a generic instruction to remove style-related suffixes that are handled by the post-processing/assembly layer.

## `prompts/_base/scene_image/3.202605101200/translate_prompt.md`

- `23-26` **P1 / semantic_string_judgment**
  - evidence: NEVER produce the phrases "from the reference", "from Reference image N", "from a reference image" ... These phrases trigger a downstream phantom-reference validator and will fail the render
  - why: The pipeline relies on a brittle substring-based validator to fail/pass renders based on natural language output. This forces the prompt to maintain a blacklist of phrases, which is a form of pattern-based semantic judgment that can lead to false positives in valid story descriptions.
  - fix: Replace the downstream substring-based 'phantom-reference' validator with a semantic LLM-based check or validate against structured metadata rather than natural language prompt content.

## `prompts/_base/scene_verify/1.202603231200/system.md`

- `7` **P2 / scenario_dependent_prompt**
  - evidence: 빙의/영혼 상태: 다른 인물의 몸에 들어간 경우, 원래 몸은 visible=false, 빙의된 몸은 visible=true
  - why: This hardcodes a specific narrative trope (possession/soul swap) into the base verification logic. Such domain-specific rules should be injected via a structured World Rule SOT rather than being part of the global system prompt, as they may bias or confuse the LLM in scenarios where these mechanics do not apply.
  - fix: Move trope-specific visibility rules to a scenario-specific 'World Rules' or 'SOT' section that is appended to the prompt only when relevant.

## `prompts/_base/shot_cinematography/1.202603281644/system.md`

- `5` **P1 / scenario_dependent_prompt**
  - evidence: 긴장 고조 → 폭발 → 감정 정리
  - why: The prompt defines the 'emotional curve' using a specific three-stage dramatic arc (tension-explosion-resolution). This forces the DP agent to apply a specific narrative framework to all scenarios, which is a form of scenario-specific pollution that should instead be derived from the actual story content or a structured SOT.
  - fix: Generalize the instruction to 'Consider the emotional curve of the episode as defined in the scenario context' and remove the hardcoded sequence of beats.

## `prompts/_base/shot_dependency_t2i/3.202604101200/schema.json`

- `28` **P2 / scenario_dependent_prompt**
  - evidence: Ignore the blood on the floor.
  - why: The example uses a specific narrative prop ('blood on the floor') which pollutes the base schema with scenario-specific imagery, potentially biasing the LLM toward certain genres or specific visual states during shot dependency analysis.
  - fix: Replace the specific example with a generic one, such as 'Ignore the specific furniture' or 'Ignore the lighting color'.

## `prompts/_base/shot_dependency_t2i/3.202604101200/system.md`

- `37-49` **P1 / scenario_dependent_prompt**
  - evidence: "the woman in red", "blood stains", "broken glass", "police tape and detectives", "stairwell"
  - why: The prompt uses specific story tropes (crime/thriller) and concrete props/places as examples for visual descriptions and constraints. This introduces scenario-specific pollution into a general pipeline component, potentially biasing the LLM's output for arbitrary open-world scenarios that do not fit these tropes.
  - fix: Replace scenario-specific examples with generic placeholders or abstract descriptions (e.g., 'the person in the background', 'the object on the table') to maintain genre and scenario neutrality.

## `prompts/_base/shot_dependency_t2i/4.202604141200/schema.json`

- `28` **P2 / scenario_dependent_prompt**
  - evidence: Ignore the blood on the floor.
  - why: Hardcoded scenario-specific prop example in a base schema description biases the LLM toward specific genres or content types.
  - fix: Replace with generic examples of transient environmental details.

- `33` **P2 / scenario_dependent_prompt**
  - evidence: immobile characters (dead/unconscious bodies)
  - why: Hardcoded domain trope used to define character state logic in a base schema.
  - fix: Use generic descriptions for immobile entities such as 'characters in a fixed state'.

## `prompts/_base/shot_dependency_t2i/4.202604141200/system.md`

- `31-50` **P1 / llm_closed_list_instruction**
  - evidence: 죽은, 의식불명, 심하게 다친 인물... 이 인물은 환경의 일부입니다
  - why: Hardcodes a semantic rule for visual continuity based on specific story tropes (death/injury). This forces the LLM to perform open-world interpretation of character states to apply a visual routing rule (keep vs ignore), which should be generalized to 'immobile entities' and driven by structured SOT metadata.
  - fix: Generalize the instruction to refer to 'immobile entities' and rely on the '[고정 인물 상태]' (Fixed Character State) metadata provided in the input.

- `46-47` **P1 / semantic_string_judgment**
  - evidence: 엔티티 ID (C01, O02, P03, L04 등) 사용 절대 금지 → 보통명사만 사용
  - why: Forbidding structured IDs in the output forces the LLM to generate natural language descriptions that cannot be programmatically mapped back to the SOT. This prevents automated validation of continuity rules (e.g., ensuring a specific character is not ignored) and relies on ambiguous string matching in downstream visual generation steps.
  - fix: Require the inclusion of Entity IDs alongside natural language descriptions in the output (e.g., a JSON object with 'id' and 'description' fields) to maintain traceability.

- `53-66` **P2 / scenario_dependent_prompt**
  - evidence: "the detective walking in", "the body on the floor", "police tape", "the unconscious man slumped against the wall"
  - why: The prompt contains scenario-specific examples (crime/thriller tropes) that can bias the LLM's descriptive style and logic across different genres. These examples should be generic or diverse to avoid scenario pollution.
  - fix: Replace scenario-specific examples with generic placeholders or a broader range of genre-neutral examples.

## `prompts/_base/shot_dependency_t2i/5.202604201700/schema.json`

- `28` **P2 / scenario_dependent_prompt**
  - evidence: E.g. 'Ignore the standing man by the door.'
  - why: The description uses a concrete story-specific example to instruct the LLM, which can bias the model towards specific character/prop types or phrasing styles instead of remaining scenario-agnostic.
  - fix: Replace the concrete example with a generic description of the expected string format or a more abstract example like 'Ignore specific foreground objects or characters that have moved.'

- `33` **P2 / scenario_dependent_prompt**
  - evidence: immobile characters (dead/unconscious bodies)
  - why: The instruction includes a specific domain trope ('dead/unconscious bodies') as the primary example of 'immobile characters'. This biases the LLM's semantic understanding of character continuity towards violent or specific states, potentially missing other immobile states (e.g., sleeping, sitting still).
  - fix: Use more neutral or comprehensive examples for immobile characters, such as 'characters who remain stationary between shots (e.g., sleeping, sitting, or otherwise unmoving).'

## `prompts/_base/shot_dependency_t2i/5.202604201700/system.md`

- `61-70` **P1 / scenario_dependent_prompt**
  - evidence: 죽은/의식불명/움직이지 않는 인물 처리 (매우 중요)
  - why: The prompt hardcodes specific story tropes (death, unconsciousness) as a special logic branch for visual continuity. This forces the LLM to perform semantic classification based on a closed list of states that may not apply to all scenarios and should instead be derived from a structured 'static/dynamic' property in the SOT.
  - fix: Replace the specific state checks with a generic instruction to check for a 'static_status' field in the entity metadata provided in the context.

- `97` **P2 / scenario_dependent_prompt**
  - evidence: Ignore the detective walking in. Keep the body on the floor as-is.
  - why: The example uses scenario-specific roles ('detective') and states ('body on the floor'), which can bias the LLM toward specific narrative genres during shot analysis.
  - fix: Use neutral, generic examples like 'the person entering the room' or 'the object on the floor'.

- `111` **P2 / scenario_dependent_prompt**
  - evidence: the body lying face-down on the floor", "the unconscious man slumped against the wall
  - why: Provides specific visual descriptions of death and injury as templates for the 'keep_elements' field, polluting the prompt with domain-specific tropes.
  - fix: Use abstract placeholders or generic descriptions for stationary entities in examples.

## `prompts/_base/shot_dependency_t2i/7.202605151200/system.md`

- `101-111` **P1 / scenario_dependent_prompt**
  - evidence: detective walking in", "police tape", "body on the floor
  - why: Instructional examples for the ignore_elements field are heavily biased toward a crime scene scenario. This 'scenario pollution' can lead the LLM to over-index on these types of entities or fail to generalize when analyzing unrelated story genres.
  - fix: Replace scenario-specific examples with generic descriptions of movement and temporary objects (e.g., 'a person walking', 'a temporary prop').

- `149-156` **P1 / llm_closed_list_instruction**
  - evidence: detective / prisoner / woman in apron / dead body on the bed
  - why: The prompt uses a hardcoded list of domain-specific tropes and keywords to enforce semantic boundaries for 'non-person' entities. This biases the LLM toward crime/thriller scenarios and may fail to catch characters in other genres (e.g., sci-fi, fantasy) while hardcoding specific visual states into the base system prompt.
  - fix: Abstract the forbidden list to focus on 'sentient entities' or 'characters' generally, and move genre-specific examples to a scenario-specific configuration or few-shot layer.

- `169` **P2 / scenario_dependent_prompt**
  - evidence: small reddish mark on the wrist
  - why: Uses an overly specific visual detail as a reference example for zoom_in_detail, which can bias the LLM's attention toward similar specific body marks or medical details in other contexts.
  - fix: Use a generic visual continuity example, such as 'a specific pattern on a surface' or 'a unique texture'.

## `prompts/_base/shot_director/1.202603301500/system.md`

- `20-22` **P1 / scenario_dependent_prompt**
  - evidence: 백련이 요괴화된 후이면 → C01 대신 C02
  - why: The system prompt uses a specific character name ('백련') and a specific plot event ('요괴화' - monster transformation) as examples. This introduces scenario-specific pollution into a base pipeline prompt, which should remain agnostic of the story content and rely on structured SOT data.
  - fix: Replace specific character names and transformation descriptions with generic placeholders (e.g., 'Character A', 'Transformation State') to ensure the prompt is reusable across different scenarios.

## `prompts/_base/shot_director/2.202604031800/system.md`

- `21-23` **P1 / scenario_dependent_prompt**
  - evidence: 백련이 요괴화된 후이면 → C01 대신 C02... 백련이 아직 변형 전이면 → C01
  - why: The prompt uses a specific character name ('백련') and a specific story trope ('요괴화' - monster transformation) to instruct the LLM on ID mapping. This pollutes the base prompt with scenario-specific data that should be derived from the provided SOT, potentially biasing the LLM's interpretation of other scenarios.
  - fix: Replace specific character names and story-specific transformations with abstract placeholders like 'Character A' and 'Variant Form B' to maintain scenario-agnostic logic.

## `prompts/_base/shot_director/3.202605101200/system.md`

- `17-32` **P1 / semantic_string_judgment**
  - evidence: X[를을] (응시하|...)... Y[의] (얼굴|...)
  - why: The prompt instructs the LLM to use specific Korean grammatical patterns and verb lists to determine entity visibility (off-camera vs in-frame). This is a semantic judgment that should be handled by general reasoning or a structured SOT, not hardcoded phrase structures.
  - fix: Remove specific linguistic patterns and replace with high-level semantic principles for visibility (e.g., 'If the description focuses on a character's reaction to an unseen entity, mark the entity as off-camera').

- `19-44` **P1 / scenario_dependent_prompt**
  - evidence: 혜수, 수리영, 인우, 백련, 요괴화
  - why: The system prompt contains specific character names and plot-specific transformation states ('요괴화') as examples. This pollutes the base prompt with scenario-specific data and can bias the LLM's behavior across different stories.
  - fix: Replace scenario-specific names and plot points with generic placeholders like 'Character A', 'Character B', and 'Variant Form'.

- `23-24` **P2 / llm_closed_list_instruction**
  - evidence: off-camera, off-screen, 화면 밖, 프레임 밖
  - why: The prompt provides a closed list of phrases to be used as semantic classifiers for visibility. This restricts the LLM's natural language understanding and may lead to missed detections of off-camera status in varied descriptions.
  - fix: Instruct the LLM to identify off-camera status based on the spatial context of the scene description rather than a fixed list of keywords.

## `prompts/_base/shot_director/4.202605121200/system.md`

- `15-33` **P1 / llm_closed_list_instruction**
  - evidence: Gaze-target close-up 패턴 — `X[를을] (응시하|올려다보|내려다보|바라보|쳐다보|마주보|노려보|돌아보)... Y[의] (얼굴|눈|표정|상체|뒷모습|시선|옆얼굴|옆모습) (클로즈업|CU|ECU|MCU|샷|숏)`
  - why: The prompt instructs the LLM to determine entity visibility (off-camera vs in-frame) using a closed list of linguistic patterns, specific keywords, and rigid sentence structures. This is brittle and fails to account for the variety of ways a scenario might describe spatial positioning, leading to incorrect visible_entity_ids if the text deviates from these specific examples.
  - fix: Remove the rigid string patterns and keywords. Instead, provide general principles for determining visibility based on camera focus, spatial occlusion, and explicit staging directions. Rely on the LLM's semantic understanding rather than pattern matching.

## `prompts/_base/shot_director/5.202605131800/system.md`

- `33-37` **P1 / llm_closed_list_instruction**
  - evidence: X[를을] (응시하|올려다보|내려다보|바라보|쳐다보|마주보|노려보|돌아보)... Y[의] (얼굴|눈|표정|상체|뒷모습|시선|옆얼굴|옆모습) (클로즈업|CU|ECU|MCU|샷|숏)
  - why: The prompt forces the LLM to use a pseudo-regex pattern to identify gaze targets and exclude them from visibility. This limits the LLM's natural language understanding and fails on variations of these expressions or different languages/styles not captured by the list.
  - fix: Replace the pattern-based instruction with a high-level semantic requirement: 'Exclude entities that are the target of a gaze if the shot is a close-up focusing solely on the observer's face/reaction.'

- `38-41` **P2 / llm_closed_list_instruction**
  - evidence: 영어: `off-camera`, `off-screen` ... 한국어: `화면 밖`, `프레임 밖`
  - why: Hardcoding specific technical phrases as the primary signals for off-camera status can lead the LLM to ignore contextual cues that imply the same state without using these exact words.
  - fix: Instruct the LLM to identify off-camera status based on the spatial relationship and framing described in the text, using these phrases as examples rather than an exhaustive list.

- `43-45` **P1 / llm_closed_list_instruction**
  - evidence: (차단|막다|가리다|block|obstruct) (대상)[을를]?
  - why: Uses a closed list of verbs to define physical blocking. This is a semantic judgment that should be derived from the LLM's understanding of the scene's physical layout rather than keyword matching.
  - fix: Define the rule in terms of physical occlusion: 'If an entity is explicitly described as being completely hidden or blocked by another object or character, exclude it from visible_entity_ids.'

- `47-49` **P1 / llm_closed_list_instruction**
  - evidence: "(상대) 의 목소리를 듣고 굳어진 (주체) 의 얼굴"
  - why: Hardcodes a specific sentence structure as a heuristic for excluding characters. This is a brittle pattern-based approach to a complex narrative interpretation task.
  - fix: Generalize the instruction to focus on the 'Reaction-only' concept: 'If a character is mentioned only as a source of sound or a trigger for another character's reaction, and the framing is tight on the reacting character, exclude the trigger character.'

## `prompts/_base/shot_essence_extraction/1.202604281800/system.md`

- `39` **P2 / scenario_dependent_prompt**
  - evidence: 민숙이 거실 바닥에 엎어진 채 누워있다
  - why: Uses a concrete character name ('민숙') in a base system prompt example, which constitutes scenario-specific pollution in a generic extraction template.
  - fix: Replace specific names with generic placeholders like '인물 A' or '주인공' to avoid biasing the LLM toward specific character contexts.

- `53-57` **P1 / llm_closed_list_instruction**
  - evidence: "사망/부상/의식불명 인물"의 자세는 essence ... 그 인물 옆 혈흔은 atmospheric ... "흐트러진 머리카락"은 peripheral
  - why: Hard-codes semantic classification and routing logic for specific visual tropes (bloodstains, injury, hair). This forces open-world story elements into fixed categories regardless of their narrative importance in a specific shot (e.g., a close-up on bloodstains should be essence, but this rule forces it to atmospheric/background).
  - fix: Remove specific trope-to-category mappings. Instead, provide abstract criteria for what constitutes 'essence' vs 'atmospheric' based on the shot's focus, or allow the SOT to define importance levels for specific props.

## `prompts/_base/shot_essence_extraction/2.202604290900/system.md`

- `44-76` **P1 / scenario_dependent_prompt**
  - evidence: "민숙", "수리영", "인형 백팩"
  - why: The base system prompt uses specific character names and unique props (e.g., 'doll backpack') in its few-shot examples. This introduces scenario-specific pollution into a generic pipeline component, which should remain agnostic to specific story content to avoid biasing the LLM or leaking domain-specific nomenclature into other scenarios.
  - fix: Replace specific character names with generic placeholders (e.g., '인물 A', '여성') and specific props with common objects (e.g., '가방', '상자') to ensure the prompt is truly scenario-agnostic.

## `prompts/_base/shot_essence_extraction/3.202605081814/system.md`

- `13-83` **P1 / semantic_string_judgment**
  - evidence: 사건의 영구 흔적 (혈흔, 깨진 유리, 부상 흔적)은 essence
  - why: Hardcodes a semantic rule that specific visual tropes (blood, broken glass, injury marks) must be classified as 'essence' to compensate for technical limitations of the background consistency system (chain bg). This forces the LLM to perform pattern-based judgment on open-world content using a closed list of examples rather than narrative logic.
  - fix: Define these rules in a structured visual logic SOT or metadata that can be updated without modifying the core system prompt, or allow the LLM to determine essence based on narrative importance rather than specific prop types.

- `60-67` **P1 / scenario_dependent_prompt**
  - evidence: description: "C08이 P03을 들어 올린다." ... essence: ["여인이 인형 백팩을 들어 올린다"]
  - why: Uses specific entity IDs (C08, P03) and a concrete prop (doll backpack) from a specific scenario as a ground-truth example. This pollutes the base prompt with scenario-specific data and biases the LLM's understanding of ID-to-entity mapping for arbitrary scenarios.
  - fix: Replace scenario-specific IDs and props in examples with generic placeholders (e.g., 'Character A', 'Object B') or use widely applicable generic examples.

## `prompts/_base/shot_extract/10.202604151200/system.md`

- `35` **P2 / llm_closed_list_instruction**
  - evidence: 인간형(외계인/귀신/돌연변이 포함)이면 인종/국적을 반드시 포함
  - why: Hardcodes specific entity types (alien, ghost, mutant) as the trigger for a specific description rule. This is a domain-specific trope list that biases the LLM toward certain genres.
  - fix: Generalize the instruction to apply to any humanoid entity not in the character list, or move entity-type definitions to a structured world SOT.

- `41-51` **P1 / llm_closed_list_instruction**
  - evidence: 나이 변화, 변장/성형 전후, 빙의... 부상, 출혈, 창백해짐, 피멍, 화상... 눈 색, 비늘, 손톱/송곳니, 꼬리
  - why: The prompt uses a hardcoded list of tropes to define what constitutes a 'Variant' (identity change) versus a 'State' (temporary change). This forces the LLM to perform semantic classification based on a closed list of examples (like 'scales' or 'possession') rather than a generic rule or a world-specific SOT.
  - fix: Define 'Variant' vs 'State' using abstract criteria (e.g., identity-altering vs. temporary condition) and provide the specific trope classifications via a project-specific SOT or configuration.

## `prompts/_base/shot_extract/10.202604151200/user.md`

- `18-19` **P1 / llm_closed_list_instruction**
  - evidence: "~하자" / "~하면서" / "~하며" / "~하고" / "~한 뒤" / "~한 후" / "~하고 나서", "and then", "while ~ing"
  - why: Enforces the 'single moment' semantic constraint using a hardcoded list of linguistic patterns. This is brittle and prevents the LLM from using natural language to describe complex single-frame states that might coincidentally use these tokens.
  - fix: Replace the negative token list with a high-level semantic requirement for 'single-frame temporal consistency' and provide abstract examples of temporal vs. static descriptions.

- `49-57` **P1 / llm_closed_list_instruction**
  - evidence: "나이 변화, 변장/성형 전후, 빙의", "부상, 출혈, 창백해짐, 피멍, 화상", "눈 색, 비늘, 손톱/송곳니, 꼬리"
  - why: Hardcodes a list of story-specific tropes and physical conditions to define the 'transformation' vs 'state' boundary. This logic (what constitutes a character variant) is scenario-dependent and should be externalized to a world-rule SOT.
  - fix: Inject the transformation/state classification rules from a structured world-rule SOT or character metadata rather than hardcoding tropes in the base prompt.

- `63` **P2 / scenario_dependent_prompt**
  - evidence: "한국인 경찰", "동양인 노파"
  - why: Hardcoded demographic examples for background characters can bias the LLM's open-world generation toward specific ethnicities or roles not necessarily present in the current scenario.
  - fix: Use generic placeholders or instruct the LLM to derive background character descriptions from the scene's cultural/geographic context provided in the SOT.

## `prompts/_base/shot_extract/11.202604201230/system.md`

- `16-18` **P1 / llm_closed_list_instruction**
  - evidence: "~하자", "~하면서", "~하며", "~하고", "~한 뒤", "~한 후", "~하고 나서", "and then", "while ~ing", "after ~ing", "as ~"
  - why: Uses a closed list of linguistic patterns to define the semantic boundary of a 'still moment'. This heuristic-based approach can lead to rejection of valid single-moment descriptions or force unnatural phrasing.
  - fix: Define the 'still moment' concept conceptually rather than through a forbidden phrase list, or move temporal validation to a separate review step.

- `35` **P2 / scenario_dependent_prompt**
  - evidence: 인간형(외계인/귀신/돌연변이 포함)이면 인종/국적을 반드시 포함
  - why: Forces real-world demographic attributes (race/nationality) onto all humanoid entities, which may be inappropriate for specific sci-fi or fantasy settings and introduces visual bias.
  - fix: Move visual description requirements for extras to a world-building SOT or allow the scenario context to dictate relevant attributes.

- `40-51` **P1 / llm_closed_list_instruction**
  - evidence: "나이 변화, 분장/변장 전후, 외모가 근본적으로 바뀌는 상황", "종·형상 자체의 변화", "부상, 얼룩, 창백해짐, 멍, 화상 등"
  - why: Hardcodes the semantic definition of character 'variants' versus 'states' using a fixed list of tropes. This logic drives character identity routing and should be defined in a structured World SOT to accommodate different story rules.
  - fix: Externalize variant classification rules to a scenario-specific SOT or a centralized world-rule configuration.

## `prompts/_base/shot_extract/11.202604201230/user.md`

- `47-57` **P1 / llm_closed_list_instruction**
  - evidence: 나이 변화, 변장/성형 전후, 빙의... 부상, 출혈, 창백해짐, 피멍, 화상... 눈 색, 비늘, 손톱/송곳니, 꼬리
  - why: The prompt hardcodes a semantic boundary for 'character variants' using a specific list of visual tropes (fantasy, action, horror). This logic determines whether a character is treated as a new entity variant or a state change, which directly affects entity membership and naming. This should be defined in a structured world-rule SOT as it varies significantly by genre.
  - fix: Move the definition of 'variant' (what constitutes a visual identity change) to a structured world-rule SOT or a scenario-specific configuration that is injected into the prompt.

- `63` **P2 / scenario_dependent_prompt**
  - evidence: 인간형이면 인종/국적을 반드시 포함 (예: '한국인 경찰', '동양인 노파')
  - why: This instruction mandates specific demographic attributes (race/nationality) for unknown characters based on hardcoded examples. This biases the LLM's visual descriptions and may lead to inappropriate or redundant descriptors in scenarios where such attributes are not the primary visual identifier.
  - fix: Replace hardcoded examples with a generic instruction to provide 'essential visual identifiers' or pull required attribute types from a structured entity-generation schema.

## `prompts/_base/shot_extract/9.202604081200/user.md`

- `31-42` **P1 / llm_closed_list_instruction**
  - evidence: 변형이란 얼굴이 크게 달라지거나... 괄호 표기하지 않는 것 (절대 포함 금지): - 일시적 상태: 부상, 출혈... - 부분적 변화: 눈 색 변화, 비늘 올라옴...
  - why: Hardcodes the definition of character 'variants' (transformations) using a closed list of semantic examples. This logic dictates visual identity syntax but is rigid and scenario-agnostic, preventing genre-specific definitions of what constitutes a significant visual change (e.g., a tail might be a major transformation in one genre but a minor detail in another).
  - fix: Move transformation criteria to a structured World Rule SOT or a configuration object that can be injected per-scenario.

- `47` **P2 / scenario_dependent_prompt**
  - evidence: 인간형(외계인, 로봇, 귀신, 돌연변이 등이라도 인간과 외모가 유사한 경우 포함)이면 인종/국적을 반드시 포함한다 (예: '한국인 경찰', '동양인 노파')
  - why: Mandates the inclusion of race/nationality for all humanoid extras based on specific examples. This is a visual generation bias that may not be appropriate for all story worlds (e.g., non-Earth settings) and should be part of a style or world-building guide rather than a base extraction prompt.
  - fix: Generalize the requirement to 'visual descriptors' and provide demographic preferences via a separate style or world-building context.

## `prompts/_base/shot_selection/2.202604151200/system.md`

- `37` **P2 / llm_closed_list_instruction**
  - evidence: 손이 물체에 닿기 직전, 문고리가 돌아가기 직전 등
  - why: The prompt uses specific visual props (hand, doorknob) and actions as hardcoded examples of 'unimportant' transitions. This biases the LLM's semantic judgment of what constitutes a 'simple connection' based on specific props rather than abstract narrative value, which may not apply to all genres or scenarios.
  - fix: Replace specific prop examples with abstract descriptions of temporal transitions (e.g., 'pre-action anticipation' or 'mechanical initiation phases') or move these examples to a structured 'Visual Editing Rules' SOT.

## `prompts/_base/shot_selection/3.202604181300/system.md`

- `38-48` **P2 / llm_closed_list_instruction**
  - evidence: 연결 순간 단독 선택 금지... 일상 이동 남용 금지... 대사만 오가는 반복 정면 샷... 인물 A가 인물 B에게 다가가 접촉하는 장면... 추격/달리기 장면
  - why: The prompt hardcodes narrative importance judgments based on a closed list of action tropes and cinematic patterns (e.g., 'contact' vs 'approach', 'chases', 'transportation', 'talking heads'). This forces the LLM to apply specific storytelling rules that may not be universally applicable across all genres or specific narrative intentions, potentially filtering out shots that carry significant tension or atmosphere.
  - fix: Define narrative importance through abstract criteria (e.g., 'state transitions', 'character agency', 'thematic resonance') and move specific cinematic heuristics into a structured 'Director's Handbook' or genre-specific SOT.

## `prompts/_base/shot_selection/4.202604191600/selection_schema.json`

- `13` **P2 / scenario_dependent_prompt**
  - evidence: 예: '서사 High / 시각 High — 관계 전환점'
  - why: The schema description includes a specific narrative trope ('Relationship Turning Point') as an example. This biases the LLM's selection logic toward specific story patterns and introduces scenario-specific nomenclature into a base schema that should remain agnostic.
  - fix: Replace the specific trope example with a generic format description or a placeholder that does not imply specific narrative content.

## `prompts/_base/shot_selection/4.202604191600/system.md`

- `54-65` **P1 / llm_closed_list_instruction**
  - evidence: ## 절대 금지 사항 ... ## 선택하지 말 것 (판단 예시 — 범용 원칙)
  - why: The prompt hard-codes narrative importance based on a closed list of tropes (chase, transport, work) and action phases. This forces a specific 'efficiency-first' storytelling logic that biases the LLM against atmospheric or character-driven moments that do not fit these specific 'transition point' definitions, potentially suppressing valid visual storytelling in non-action genres.
  - fix: Move trope-specific selection logic to a structured SOT or context-aware configuration to allow for different narrative styles (e.g., 'Action' vs 'Slice-of-Life') rather than hard-coding them as universal principles.

## `prompts/_base/shot_staging/10.202605141617/schema.json`

- `13` **P2 / scenario_dependent_prompt**
  - evidence: (CCTV/phone/binoculars)
  - why: Includes specific device examples which may bias the LLM toward these common tropes even if the story specifies a different device (e.g., a futuristic scanner or a magic mirror).
  - fix: Remove specific examples or move them to a separate technical reference.

- `24` **P1 / scenario_dependent_prompt**
  - evidence: 'one foot on pedal', 'leaning against doorframe', 'crouching behind desk', 'slumping into chair'
  - why: The description embeds specific prop-based examples (pedal, doorframe, desk, chair) which biases the LLM toward these specific scenarios and props instead of deriving poses from the actual story context.
  - fix: Remove specific prop examples. Use abstract descriptions of 'action-grounded' or 'state-grounded' poses, or move examples to a separate style-guide SOT.

- `25` **P1 / llm_closed_list_instruction**
  - evidence: 'unconscious', 'dead', 'severely_injured'
  - why: The gaze_target field mixes physical directions with semantic character states. This forces the LLM to classify story-level health/consciousness states into a closed string list for a visual field.
  - fix: Separate physical gaze direction from character state. Use a dedicated state field or allow the gaze target to be a reference to an entity/direction without hardcoding semantic outcomes.

## `prompts/_base/shot_staging/10.202605141617/system.md`

- `99` **P2 / scenario_dependent_prompt**
  - evidence: 법정 선서, 장례식 고별, 점호, 연설단, 결혼식 서약
  - why: Hardcoded list of specific scenario tropes used to justify exceptions to a technical rule (static poses). This pollutes the prompt with domain-specific examples that should be handled by general logic or SOT.
  - fix: Replace specific scenario examples with abstract criteria for when a static pose is semantically significant (e.g., 'ceremonial or formal contexts').

- `135-137` **P1 / llm_closed_list_instruction**
  - evidence: "closed" 또는 "unconscious", "dead", "severely_injured"
  - why: Instructs the LLM to use semantic character states as spatial gaze targets. This forces the LLM to perform semantic judgment on character status and map it to a specific string label, mixing state tracking with spatial metadata.
  - fix: Move character state tracking (dead, unconscious) to a separate structured field or SOT, and keep gaze_target strictly for spatial entities or directions.

- `164-170` **P1 / llm_closed_list_instruction**
  - evidence: directionality_class, 반드시 emit ... 5 class 중 의미 기반으로 하나 선택
  - why: Forces the LLM to classify arbitrary open-world objects into a closed set of 5 semantic categories (content_surface, reflective_surface, etc.) to drive visual orientation logic. This is a pattern-based semantic judgment that should be part of the object's metadata.
  - fix: Define object directionality in a structured world SOT (Entity/Prop metadata) rather than requiring the LLM to classify it per shot.

- `216-227` **P1 / llm_closed_list_instruction**
  - evidence: reason="movement_direction", reason="points_to_anchor", reason="looks_to_anchor", reason="shared_space_relation", reason="required_background_position", reason="primary_subject_isolation"
  - why: Requires the LLM to classify the underlying spatial logic of a scene into a closed list of reasons to trigger a spatial contract. This is a semantic judgment that routes how spatial constraints are applied.
  - fix: Derive the need for spatial contracts from structured scene analysis or SOT-defined interactions rather than LLM classification of 'reasons'.

## `prompts/_base/shot_staging/11.202605150319/schema.json`

- `18` **P2 / scenario_dependent_prompt**
  - evidence: (CCTV/phone/binoculars)
  - why: Specific modern-day props used as examples for a visual perception mode bias the LLM toward contemporary settings.
  - fix: Use abstract terms like 'optical_instrument' or 'electronic_display'.

- `29` **P1 / scenario_dependent_prompt**
  - evidence: 'one foot on pedal', 'leaning against doorframe', 'crouching behind desk', 'slumping into chair'
  - why: Hardcoded prop-specific examples in the schema description bias the LLM's pose generation toward modern/indoor settings, polluting the open-world story context.
  - fix: Replace specific prop examples with abstract descriptions of physical interaction (e.g., 'interacting with environment', 'weight shifted on support').

- `30` **P2 / llm_closed_list_instruction**
  - evidence: 'closed', 'unconscious', 'dead', 'severely_injured'
  - why: Character health and consciousness states are mixed into a spatial gaze target field as a closed list, forcing semantic classification of character state into a fixed set of strings.
  - fix: Separate character state from gaze target and keep gaze_target focused on spatial vectors or entity IDs.

## `prompts/_base/shot_staging/11.202605150319/system.md`

- `85-87` **P2 / scenario_dependent_prompt**
  - evidence: 법정 선서, 장례식 고별, 점호, 연설단, 결혼식 서약
  - why: The prompt uses specific scenario tropes (courtroom, funeral, etc.) as hardcoded examples to justify an exception to the 'no standing' rule. This biases the LLM towards these specific contexts and should be handled by a more generic rule or a structured world-rule SOT.
  - fix: Replace specific scenario examples with abstract criteria for 'justified static poses' (e.g., formal ceremonies, ritualistic stillness) or move these to a scenario-specific configuration.

- `119-123` **P2 / llm_closed_list_instruction**
  - evidence: "distant", "void", "closed", "unconscious", "dead", "severely_injured"
  - why: The prompt instructs the LLM to classify character gaze and physical states into a closed list of semantic strings. These labels represent semantic interpretations of character status that should be derived from structured state data rather than inferred and hardcoded in the base prompt.
  - fix: Define these states in a shared schema or enum, and ensure the LLM receives character status as structured input rather than inferring it from narrative text to emit these specific strings.

## `prompts/_base/shot_staging/6.202604151200/schema.json`

- `11-22` **P2 / llm_closed_list_instruction**
  - evidence: voyeur, hallucination, dream, memory
  - why: Hardcodes a limited set of narrative and visual tropes into the schema descriptions. This restricts open-world flexibility and forces the LLM to map scenario-specific visual contexts into a closed set of predefined modes, which should ideally be driven by a style-specific SOT.
  - fix: Transition these fields to use values defined by a Style SOT or allow for open-ended visual treatment descriptions.

- `40` **P2 / llm_closed_list_instruction**
  - evidence: 'unconscious', 'dead', 'severely_injured'
  - why: Overloads the gaze_target field with narrative character health states. This forces the LLM to perform semantic classification of a character's physical condition within a field intended for spatial orientation.
  - fix: Separate character physical status into a dedicated field or allow natural language descriptions of eye/facial state.

## `prompts/_base/shot_staging/6.202604151200/system.md`

- `68-70` **P1 / llm_closed_list_instruction**
  - evidence: "unconscious", "dead", "severely_injured"
  - why: The prompt forces the LLM to classify character health/consciousness states into specific string tokens for the 'gaze_target' field. This is a semantic judgment that should be handled by the scenario's state or described visually rather than being a hardcoded nomenclature in the staging prompt.
  - fix: Generalize the gaze_target instructions to focus on visual direction or eye state (e.g., 'eyes closed', 'fixed gaze') rather than medical/status classifications.

- `82` **P2 / scenario_dependent_prompt**
  - evidence: 바닥 혈흔 질감
  - why: The use of 'bloodstain texture' as a framing example introduces scenario-specific (thriller/horror) pollution into a base prompt, which can bias the model's creative suggestions.
  - fix: Replace with neutral texture examples like 'surface grain' or 'material patterns'.

## `prompts/_base/shot_staging/7.202604181200/schema.json`

- `21` **P2 / scenario_dependent_prompt**
  - evidence: through_device (CCTV/phone/binoculars)
  - why: Hardcoded examples of modern technology bias the LLM's interpretation of 'through_device' for non-modern or fantasy scenarios where such devices do not exist.
  - fix: Remove specific prop examples or replace them with abstract categories (e.g., 'optical instrument', 'remote sensor').

- `39` **P2 / scenario_dependent_prompt**
  - evidence: 'one foot on pedal', 'leaning against doorframe', 'crouching behind desk', 'slumping into chair'
  - why: The description uses specific modern/interior props as examples for body poses and includes a negative constraint on the word 'standing'. This biases the LLM in scenarios where these objects are unavailable and uses a token-based heuristic to force visual variety. It also contains a hardcoded reference to a specific Korean section name in another prompt.
  - fix: Use abstract pose descriptions (e.g., 'braced against a surface') and move variety guidance to a general style SOT rather than hardcoding prop-dependent examples.

- `40` **P2 / llm_closed_list_instruction**
  - evidence: 'closed', 'unconscious', 'dead', 'severely_injured'
  - why: Narrative character states are hardcoded as valid 'gaze_target' values. This forces the LLM to perform semantic classification of character health/status within a field intended for spatial targeting, which should be driven by a character status SOT.
  - fix: Separate visual eye-state from narrative status, or ensure these states are provided by the character's current state metadata.

## `prompts/_base/shot_staging/7.202604181200/system.md`

- `99-100` **P1 / llm_closed_list_instruction**
  - evidence: 법정 선서, 장례식 고별, 점호, 연설단, 결혼식 서약
  - why: The prompt provides a closed list of specific scenario types (courtroom, funeral, etc.) to justify exceptions for the 'standing' pose rule. This biases the LLM to only allow static poses in these specific tropes rather than deriving the logic from the scene's emotional context.
  - fix: Remove specific scenario examples and replace with a generalized rule based on the 'formality' or 'ritualistic nature' of the scene as defined in the world/scene SOT.

- `135-137` **P1 / llm_closed_list_instruction**
  - evidence: "closed" 또는 "unconscious" ... "dead" ... "severely_injured"
  - why: These are hardcoded semantic labels for character states being used as 'gaze_target' values. This forces the LLM to perform a classification of the character's medical/physical state into a fixed string list rather than describing the visual focus.
  - fix: Allow the gaze_target to be a natural language description or move character state (dead/injured) to a separate structured status field.

- `146-151` **P2 / scenario_dependent_prompt**
  - evidence: 커튼 틈새, 책장 사이 ... 바닥 혈흔 질감, 유리 결로, 먼지 입자, 깨진 유리
  - why: The prompt includes highly specific prop and environment examples (blood texture, broken glass, curtains) to inspire 'creative framing'. While intended as examples, they often leak into LLM outputs as default 'creative' choices regardless of the actual scenario context.
  - fix: Move these examples to a separate 'style/technique' reference SOT or use more abstract cinematic terms (e.g., 'occlusion', 'texture focus', 'environmental reflection').

## `prompts/_base/shot_staging/8.202604201230/schema.json`

- `21` **P1 / llm_closed_list_instruction**
  - evidence: hallucination, dream, memory, reflection, through_device (CCTV/phone/binoculars), projection
  - why: This field uses a closed list of semantic tropes to drive visual routing ('Affects visual treatment'). This restricts the open-world nature of visual storytelling to a fixed set of predefined categories rather than allowing the scenario to define its own visual modes.
  - fix: Allow natural language descriptions for visual treatment or move these to a structured style SOT that can be extended per scenario.

- `39` **P2 / scenario_dependent_prompt**
  - evidence: 'one foot on pedal', 'leaning against doorframe', 'crouching behind desk', 'slumping into chair'
  - why: The description contains specific props (pedal, doorframe, desk, chair) as examples for body poses. This can bias the LLM towards these objects even when they are not present in the current scenario context.
  - fix: Use abstract or generic examples (e.g., 'leaning against a surface', 'interacting with a tool') and remove specific prop references from the base schema.

- `40` **P1 / llm_closed_list_instruction**
  - evidence: 'unconscious', 'dead', 'severely_injured'
  - why: Semantic character states are used as a closed-list classifier for a visual property (gaze). This forces the LLM to map complex character states to a few hardcoded strings to communicate visual intent, which should instead be derived from a character state SOT.
  - fix: Separate character physical state from gaze target, or allow natural language for state-driven gaze descriptions.

- `53` **P2 / scenario_dependent_prompt**
  - evidence: 'screen facing camera', 'back panel visible', 'reflecting character face'
  - why: The orientation field uses specific props (screen, back panel) and scenario-specific visual outcomes (reflecting face) as examples, which biases the LLM's generation for arbitrary background elements.
  - fix: Replace with generic orientation examples such as 'front side facing camera' or 'angled away from viewer'.

## `prompts/_base/shot_staging/8.202604201230/system.md`

- `132-138` **P2 / schema_or_enum_drift**
  - evidence: ("휴대전화", "벽의 표식", "창가의 사진") vs ("distant", "void", "dead")
  - why: The 'gaze_target' field is instructed to contain a mix of Korean natural language (for objects), character names (from context), and English keywords (for states/directions). This inconsistency makes the field difficult to parse, validate, or translate reliably in the downstream pipeline.
  - fix: Standardize the language of the 'gaze_target' field (preferably English) and use a consistent format for distinguishing between entities and keywords.

- `135-137` **P1 / llm_closed_list_instruction**
  - evidence: "closed" 또는 "unconscious", "dead", "severely_injured"
  - why: The prompt instructs the LLM to classify character states into a closed list of English string tokens within the 'gaze_target' field. This overloads a spatial property with semantic status information and creates a hidden dependency on these specific strings for downstream visual logic or T2I prompt construction.
  - fix: Separate character state (e.g., 'status') from spatial gaze target. Define these states in a shared schema or SOT rather than hardcoding them as gaze target values.

## `prompts/_base/shot_staging/9.202605121441/schema.json`

- `39` **P2 / semantic_string_judgment**
  - evidence: Must NOT use 'standing' alone — use action-grounded or state-grounded poses such as 'one foot on pedal', 'leaning against doorframe'
  - why: Implements a hard negative constraint on natural language ('standing') and provides specific prop-based examples (pedal, doorframe, desk) which biases the LLM towards certain environmental tropes. It also references an external system prompt 'body_pose 다양화' for guidance, indicating scattered logic.
  - fix: Remove the hard negative constraint and move pose variety guidance to a style-guide SOT that doesn't rely on specific prop examples in the schema.

- `40` **P1 / llm_closed_list_instruction**
  - evidence: 'unconscious', 'dead', 'severely_injured'
  - why: The gaze_target field is overloaded with character health and consciousness states. This forces the LLM to use specific semantic strings to signal character status within a field intended for spatial orientation, leading to brittle visual routing and schema drift.
  - fix: Move character status (dead, injured, unconscious) to a dedicated character_state field and keep gaze_target strictly for spatial or object targets.

- `58-62` **P1 / llm_closed_list_instruction**
  - evidence: directionality_class
  - why: The LLM is instructed to perform semantic classification of arbitrary background elements into a closed list (content_surface, reflective_surface, etc.) to drive conditional description requirements. The instruction 'Judge by meaning, not by surface vocabulary' forces the LLM to perform open-world semantic judgment to satisfy schema validation.
  - fix: Derive directionality from a structured world-state or object-property SOT rather than asking the LLM to classify it on-the-fly during shot staging.

## `prompts/_base/shot_staging/9.202605121441/system.md`

- `99-100` **P1 / scenario_dependent_prompt**
  - evidence: 법정 선서, 장례식 고별, 점호, 연설단, 결혼식 서약
  - why: Specific scenario tropes (courtroom, funeral, etc.) are used to define logic exceptions for character poses. This biases the LLM towards these specific contexts and should be abstracted into a 'formal_context' or 'ceremonial' flag in the SOT rather than being hardcoded in the base prompt.
  - fix: Replace specific scenario names with abstract categories or move the exception logic to a structured scene attribute (e.g., is_ceremonial: true).

- `136-137` **P2 / llm_closed_list_instruction**
  - evidence: "dead" 또는 "severely_injured"
  - why: Hardcodes specific semantic states as valid gaze targets. This is a closed-list classifier for open-world character states that might be better handled by natural language description or a broader state enum from the SOT.
  - fix: Allow natural language descriptions for gaze targets or use a standardized character state enum from the SOT.

- `146-151` **P2 / scenario_dependent_prompt**
  - evidence: TV 빛만으로 조명, 블라인드 줄무늬 그림자, 역광 실루엣, 촛불, 네온
  - why: Specific visual tropes and props are provided as examples for creative framing. This can bias the LLM to inject these specific elements (like TV light or neon) into scenarios where they may not be contextually appropriate.
  - fix: Use more abstract descriptions of lighting and framing techniques (e.g., 'high contrast lighting', 'obstructed view') instead of specific prop-based examples.

## `prompts/_base/shot_validator/1.202604181200/system.md`

- `11-15` **P1 / llm_closed_list_instruction**
  - evidence: - "~하자", "~하면서", "~하며", "~하고", "~한 뒤", "~한 후", "~하고 나서" ... "and then", "while ~ing"
  - why: The prompt instructs the LLM to classify shot validity based on a hardcoded list of natural language connectors. This is a pattern-based semantic judgment that can lead to brittle validation across different writing styles or languages.
  - fix: Replace the forbidden phrase list with a conceptual definition of temporal progression and provide diverse examples of 'state' vs 'action' that do not rely on specific substrings.

- `19-27` **P2 / scenario_dependent_prompt**
  - evidence: "피묻은 손으로 칼을 쥐고 있는", "총을 겨누며", "총을 겨눈 채"
  - why: The validation logic is illustrated using specific action/thriller tropes (bloody hands, guns). This scenario-specific pollution biases the LLM's understanding of 'static states' toward a narrow set of genres.
  - fix: Use genre-neutral examples (e.g., 'holding an object', 'gazing at a horizon') to define the visual boundaries of a single moment.

## `prompts/_base/shot_validator/3.202604301730/system.md`

- `14-16` **P1 / llm_closed_list_instruction**
  - evidence: "- ~하자", "~하면서", "~하며", "~하고", "~한 뒤", "~한 후", "~하고 나서", "and then", "while ~ing", "after ~ing", "as ~"
  - why: The prompt uses a closed list of specific Korean and English linguistic connectors to define what constitutes a 'sequential action' violation. This limits the LLM's ability to generalize to other ways of expressing temporal sequence in open-world story text and creates a maintenance burden.
  - fix: Define the 'sequential action' constraint as a semantic principle (e.g., 'identify any temporal sequence between two distinct actions') and provide illustrative examples rather than a hardcoded list of forbidden phrases.

- `37-41` **P1 / llm_closed_list_instruction**
  - evidence: locomotion: running / sprinting / walking / striding / climbing, riding/driving: riding (a bicycle / motorcycle / horse), driving, pedaling, water/swim: swimming, rowing, paddling, jumping/leaping: leaping, jumping over, vaulting, chasing/fleeing: chasing, fleeing, escaping
  - why: The prompt hardcodes a list of action categories to trigger specific 'motion direction' visual logic. This is a closed-list semantic classifier for open-world actions; if a scenario uses a verb not in this list (e.g., 'skating', 'sliding'), the logic may fail to trigger.
  - fix: Use a broader semantic definition for 'propulsive motion' or 'locomotion' to allow the LLM to generalize to any action involving physical displacement.

- `55-59` **P1 / llm_closed_list_instruction**
  - evidence: "one knee bent in down-stroke", "one foot just lifted off the ground", "one arm lifted above water"
  - why: These are prescriptive visual pose templates for specific actions. They force a specific 'mid-action' look that may not fit all artistic styles or scenario contexts. These domain-specific visual tropes should be part of a structured visual rule SOT rather than hardcoded in a validator prompt.
  - fix: Define the principle of 'mid-action pose' and 'motion direction' (e.g., 'describe the physical tension and direction of movement in a single frozen frame') without prescribing specific limb positions.

## `prompts/_base/shot_validator/4.202605061408/system.md`

- `12-16` **P1 / llm_closed_list_instruction**
  - evidence: "~하자", "~하면서", "and then", "while ~ing"
  - why: Uses a closed list of linguistic patterns to decide if a description violates the 'single moment' rule, which can lead to brittle validation of open-world story text.
  - fix: Shift to high-level semantic principles or use a structured grammar validator if strictness is required.

- `36-41` **P1 / llm_closed_list_instruction**
  - evidence: locomotion: running / sprinting / walking / striding / climbing
  - why: Hardcodes specific action categories to trigger motion-direction preservation logic, biasing the LLM toward a fixed set of verbs for open-world motion analysis.
  - fix: Define these categories in a structured World/Action SOT and pass them as context rather than hardcoding in the system prompt.

- `80-86` **P1 / semantic_string_judgment**
  - evidence: entity name 정확 일치 또는 description 안 character 표현이 entity name substring 일치
  - why: Instructs the LLM to use substring matching for entity mapping, which is a pattern-based semantic judgment that can lead to false positives in character identification.
  - fix: Use unique identifiers or a more robust semantic similarity check backed by a character registry.

- `113-115` **P1 / llm_closed_list_instruction**
  - evidence: stabbing, slashing, piercing, 찌름, 베기, 칼날
  - why: Hardcodes violence-related keywords to trigger 'active contact' freeze rules, creating a closed-world classifier for open-world actions.
  - fix: Move action classification to a dedicated semantic analysis step or use a broader ontological definition.

- `159-161` **P1 / llm_closed_list_instruction**
  - evidence: 얼굴, 손, 다리, 팔, 머리, 가슴, 목, 입, 눈, 어깨, 등, 발, 무릎, 허벅지, face, hand, leg, arm
  - why: Uses a hardcoded list of body parts and basic actions to detect 'visible-human-action', which is a brittle way to determine entity presence and affects fail-fast routing.
  - fix: Rely on the structured entity map and scene director's present_entity_ids rather than keyword detection.

## `prompts/_base/shot_validator/5.202605081700/system.md`

- `14-16` **P2 / llm_closed_list_instruction**
  - evidence: "~하자", "~하면서", "~하며", "~하고", "~한 뒤", "~한 후", "~하고 나서" ... "and then", "while ~ing", "after ~ing", "as ~"
  - why: Enforcing the 'single moment' rule via a closed list of temporal connectors is a pattern-based judgment. It may fail to catch sequential actions described without these specific words or incorrectly flag valid descriptions where these words are used non-sequentially.
  - fix: Focus the instruction on the semantic concept of a 'single shutter moment' (1/1000s) and provide examples of sequential vs. static logic rather than a list of forbidden strings.

- `80-86` **P1 / semantic_string_judgment**
  - evidence: entity name substring 일치... name / stable_traits substring 매칭
  - why: Instructing the LLM to use substring matching to resolve entity IDs (C##) from natural language descriptions is a brittle heuristic. It risks incorrect character tagging if common nouns in the description overlap with entity names or traits.
  - fix: Remove substring matching instructions. Rely on the LLM's semantic understanding of the entity map or use a dedicated entity resolution step that handles ambiguity through context rather than string patterns.

- `159-161` **P2 / llm_closed_list_instruction**
  - evidence: 신체 부위 표현 (얼굴, 손, 다리, 팔, 머리, 가슴, 목, 입, 눈, 어깨, 등, 발, 무릎, 허벅지, face, hand, leg, arm 등) 등장
  - why: The prompt defines 'visible-human-action' using a closed list of body parts and verbs. This classification drives a fail-fast condition (Line 172), which can lead to false negatives if a human action is described using synonyms or specific terms not included in the list.
  - fix: Define 'visible-human-action' semantically (e.g., 'any action performed by or involving a human figure') and allow the LLM to use its internal knowledge to identify these cases instead of relying on a token list.

## `prompts/_base/t2i_composer/v1/system.md`

- `32` **P2 / scenario_dependent_prompt**
  - evidence: "near-future"
  - why: The term 'near-future' is a specific genre or setting description, unlike 'photorealistic' or 'cinematic lighting' which are generic T2I quality tags. Including it in a base system prompt's negative constraints indicates scenario-specific pollution that could suppress valid setting descriptions if the system is used for diverse genres.
  - fix: Remove 'near-future' from the base boilerplate blacklist. Genre-specific negative constraints should be handled via a structured style SOT or a scenario-specific prompt layer.

## `prompts/_base/t2i_review/1.202604051200/entity_system.md`

- `12` **P2 / llm_closed_list_instruction**
  - evidence: 1. **국적/인종 누락**: 인간형 인물이나 사진/그림 속 인물에 국적/인종이 빠진 경우
  - why: Enforces a mandatory semantic visual attribute (nationality/race) for all human entities. This is an open-world visual decision that should be governed by a world-rule SOT or scenario context rather than a hard-coded instruction in a base review prompt.
  - fix: Make this check optional or drive it from a structured 'required_attributes' list in the entity SOT.

- `13` **P1 / scenario_dependent_prompt**
  - evidence: (예: "Incheon" → "인천"이어야 함)
  - why: Uses a specific real-world location ('Incheon') as a hard-coded example to define a translation rule. This pollutes the base prompt with scenario-specific data and implies a potentially problematic requirement to use Korean characters in English T2I prompts.
  - fix: Remove the specific example or move it to a scenario-specific configuration. Define translation/transliteration rules in a structured SOT.

## `prompts/_base/t2i_review/1.202604051200/scene_system.md`

- `15-17` **P1 / scenario_dependent_prompt**
  - evidence: 직원, 경찰, 행인 등 / "Incheon" → "인천" / 특정 문화권의 고유 공간/물건/관습
  - why: The prompt uses scenario-specific examples (Incheon, Korean names) and instructs the LLM to perform semantic classification of 'common nouns' and 'cultural items' based on its internal bias. This assumes a Korean-centric scenario and forces the LLM to decide what constitutes a cultural object or 'original language' without a structured World/Rule SOT.
  - fix: Remove scenario-specific examples like 'Incheon'. Replace the open-ended cultural restoration instruction with a reference to a structured glossary or world-rule SOT that defines which terms must remain in their original language and what that language is for the current scenario.

- `16` **P2 / schema_or_enum_drift**
  - evidence: 지명·상호명 등이 영어로 번역된 경우 (예: "Incheon" → "인천")
  - why: There is a logical contradiction between the instruction 'translated to English' and the example provided ('Incheon' -> '인천'), where the suggestion is Korean. Additionally, this contradicts line 12 which states T2I prompts are English.
  - fix: Clarify whether the T2I prompt should contain English or original-language proper nouns, and ensure the example matches the direction of the transformation.

## `prompts/_base/t2i_review/2.202604301730/entity_schema.json`

- `16` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation"]
  - why: Hardcoding specific semantic error categories like 'missing_ethnicity' and 'proper_noun_translated' into the schema forces the LLM to apply these specific visual and linguistic policies regardless of the scenario context. These rules should be part of a dynamic SOT (Source of Truth) rather than fixed schema enums.
  - fix: Move these validation rules to a dynamic configuration or a structured 'Rule SOT' that the LLM references, and allow the 'type' field to be a more flexible string or a broader set of categories provided at runtime.

- `17-18` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: The schema is designed to facilitate string-level search-and-replace ('target' and 'suggestion') to 'fix' T2I prompts. This is a fragile pattern that can lead to unintended mutations if the target string appears in multiple contexts or if the LLM selects an ambiguous substring. It bypasses structured prompt generation.
  - fix: Replace the string-replacement mechanism with structured feedback that allows the pipeline to re-generate the prompt from the original entity/scene data, or use a more robust merging strategy that doesn't rely on raw string matching.

## `prompts/_base/t2i_review/2.202604301730/entity_system.md`

- `11` **P1 / llm_closed_list_instruction**
  - evidence: 1. **국적/인종 누락**: 인간형 인물이나 사진/그림 속 인물에 국적/인종이 빠진 경우
  - why: This hard-codes a visual requirement (nationality/race) for all humanoid entities. This is a visual policy decision that should be part of a structured style SOT or entity schema. Forcing this at the reviewer level without checking if the source scenario requires it leads to hallucinated requirements or biased visual generation.
  - fix: Move visual requirements like mandatory nationality/race to a structured style SOT or entity-specific metadata, and instruct the reviewer to check against those specific requirements.

- `12-13` **P1 / llm_closed_list_instruction**
  - evidence: 2. **고유명사 번역**: 지명·상호명 등 고유명사가 영어로 번역되어 원어 뉘앙스가 손실된 경우... 3. **원어 어색**
  - why: These instructions require the LLM to make subjective semantic judgments on 'nuance loss' and 'awkwardness' for open-world proper nouns (places, businesses). This logic should be supported by a structured glossary or entity SOT to ensure consistent handling of names and places across the pipeline, rather than relying on LLM intuition.
  - fix: Provide a structured glossary or entity mapping in the context and instruct the reviewer to validate translations against that mapping.

## `prompts/_base/t2i_review/2.202604301730/scene_schema.json`

- `19-26` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation", "close_framing_existing_ref", "physical_inconsistency", "unshared_fg_bg_actors"]
  - why: The review process is restricted to a hardcoded set of semantic categories. This forces the LLM to map open-world visual/story issues into a closed list of domain tropes (e.g., ethnicity, actor sharing) that should instead be defined by a structured Rule/Quality SOT.
  - fix: Move these categories to a dynamic configuration or a structured 'Quality Rule' SOT that the LLM can reference, allowing the review criteria to evolve without schema changes.

- `28-29` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상 (unique sub-string)"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: The schema facilitates prompt editing via substring replacement ('target' and 'suggestion'). This is a 'blind replace' pattern that can lead to corruption of the visual prompt if the target string is not unique or appears as a substring of other words, rather than using a structured prompt update mechanism.
  - fix: Use a structured prompt representation (e.g., an object with specific fields for actors, setting, and style) so that updates can be applied to specific nodes rather than via raw string replacement.

## `prompts/_base/t2i_review/2.202604301730/scene_system.md`

- `16-19` **P1 / llm_closed_list_instruction**
  - evidence: missing_ethnicity — 보통명사 인물의 국적/인종 누락... suggestion: 인종 형용사를 포함한 형태 (예: "an Asian man in a security uniform")
  - why: Instructs the LLM to inject specific demographic adjectives (race/ethnicity) into common nouns based on a closed-list logic. This forces visual decisions that should be driven by a structured world/character SOT rather than a blind reviewer rule.
  - fix: Remove demographic injection logic from the reviewer prompt and ensure common noun demographics are handled by the scene generation SOT or character metadata.

- `35-70` **P1 / semantic_string_judgment**
  - evidence: "the existing tabletop / kitchen / desk / curtain / doorway" ... "low at ground/floor/quay level" ... "Figure A occupies the right foreground..."
  - why: Uses closed lists of props, camera positions, and spatial descriptions to judge visual/physical validity and trigger prompt mutations. This pattern-based semantic judgment is brittle and fails for open-world scenarios not covered by these specific phrases (e.g., 'quay level' is highly specific).
  - fix: Replace hard-coded phrase lists with abstract physical/spatial constraints or move the validation logic to a structured geometric/physical validator.

- `46-78` **P2 / scenario_dependent_prompt**
  - evidence: "dark bitter herbal drink", "kitchenette", "worn wooden table" ... "casual jacket", "bench", "can"
  - why: The examples contain scenario-specific props and detailed descriptions that can bias the LLM's review behavior towards specific story contexts or tropes.
  - fix: Use generic or abstract examples (e.g., 'a specific beverage', 'a piece of furniture') to demonstrate the review logic without polluting the prompt with scenario-specific details.

## `prompts/_base/t2i_review/2.202605081200/entity_schema.json`

- `16` **P1 / llm_closed_list_instruction**
  - evidence: "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation"]
  - why: Hardcoding 'missing_ethnicity' as a primary validation category enforces a specific visual requirement that may not be universally applicable (e.g., for non-human entities or stylized characters). This closed-list approach biases the review process toward specific visual traits that should instead be driven by the scenario's SOT or style guide.
  - fix: Generalize the validation types to allow for arbitrary attribute checks (e.g., 'missing_required_attribute') where the specific attribute is determined by the world-rule or entity definition.

- `17-18` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: The schema facilitates direct substring replacement ('target' to 'suggestion') in the T2I prompt based on LLM judgment. This is a blind mutation pattern that can fail if the LLM provides an inexact match or if the same substring appears in multiple contexts, potentially corrupting the prompt's semantic structure or visual intent.
  - fix: Implement a structured update mechanism that targets specific entity attributes or prompt components (e.g., updating a 'physical_description' field) rather than performing raw string substitution on the final prompt text.

## `prompts/_base/t2i_review/2.202605081200/scene_schema.json`

- `38-39` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상 (unique sub-string)"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: The schema instructs the LLM to perform direct substring replacement ('blind replace') on the T2I prompt text. This bypasses structured semantic control and risks corrupting the prompt if the LLM identifies an incorrect or non-unique substring, or if the replacement creates grammatical or semantic incoherence in the final visual prompt.
  - fix: Transition to a structured prompt update mechanism where the LLM identifies specific semantic components (e.g., 'subject', 'lighting', 'framing') to be modified, rather than performing raw string substitution.

## `prompts/_base/t2i_review/2.202605081200/scene_system.md`

- `16-19` **P1 / llm_closed_list_instruction**
  - evidence: 보통명사 인물(직원, 경찰, 행인 등)에 국적/인종이 빠진 경우 ... (예: "an Asian man in a security uniform")
  - why: The prompt instructs the LLM to classify 'common nouns' and inject ethnicity based on a hardcoded example ('Asian man'). This demographic logic should come from a structured world SOT or scenario context, not hardcoded reviewer bias.
  - fix: Remove the hardcoded ethnicity example and instruct the LLM to use the demographic rules provided in the {t2i_context} for all characters, including common nouns.

- `34-47` **P1 / llm_closed_list_instruction**
  - evidence: "the existing X" 표현 (the existing tabletop / kitchen / desk / curtain / doorway 등) ... the reference kitchenette sits softly out of focus
  - why: The rule uses a closed list of specific prop names (tabletop, kitchen, desk, etc.) and natural language patterns to detect reference leaks. This is fragile and contains scenario-specific pollution in a base prompt.
  - fix: Generalize the detection pattern to look for any reference to 'existing' or 'reference' assets without listing specific props, or move prop-specific logic to a scenario-specific configuration.

- `52-63` **P1 / semantic_string_judgment**
  - evidence: 카메라 "low at ground/floor/quay level" + 묘사 "<surface> visible behind subject's hands" ... Wet dock planks visible behind her hands
  - why: Physical consistency is judged using specific string combinations and scenario-specific examples ('quay level', 'wet dock planks'). This is a pattern-based semantic judgment of open-world physics.
  - fix: Define physical consistency rules using abstract spatial relationships or structured camera/subject metadata rather than specific natural language string pairs.

- `68-79` **P1 / semantic_string_judgment**
  - evidence: "Figure A occupies the right foreground... Figure B sits hunched..." ... C01O01 in a casual jacket sits hunched on the bench
  - why: Spatial consistency between foreground and background actors is detected using specific phrasing patterns and scenario-specific props ('casual jacket', 'bench', 'can').
  - fix: Instruct the LLM to ensure spatial anchors (shared surfaces) exist for all multi-actor shots based on the scene description, without relying on specific phrasing examples.

## `prompts/_base/t2i_review/2.202605081600/entity_schema.json`

- `16` **P2 / llm_closed_list_instruction**
  - evidence: "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation"]
  - why: This hardcodes a narrow set of semantic issue types for the LLM to use during review. It biases the validator toward specific domain tropes (like ethnicity) and linguistic checks, while potentially ignoring other critical visual or narrative discrepancies not covered by the enum.
  - fix: Move review categories to a dynamic configuration or a scenario-specific SOT that defines what aspects of an entity (e.g., ethnicity, age, style) must be validated.

- `17-18` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: This schema defines a mechanism where the LLM performs semantic 'fixes' via substring replacement on the generated T2I prompt. This is a 'blind replace' pattern used to mutate visual meaning, which is fragile and bypasses structured SOT-based generation in favor of string-level patching.
  - fix: Instead of substring replacement, have the review process output structured corrections that are fed back into the prompt assembly pipeline to regenerate the prompt from the source of truth.

## `prompts/_base/t2i_review/2.202605081600/scene_system.md`

- `16-30` **P1 / semantic_string_judgment**
  - evidence: 인종 형용사가 누락된 보통명사, 고유명사가 영어로 번역되어 원어보다 어색한 경우
  - why: Instructs the LLM to perform subjective semantic classification (ethnicity requirement, translation 'awkwardness') based on string patterns rather than structured world rules.
  - fix: Move demographic requirements and translation policies to a structured SOT (Source of Truth) that the LLM can reference.

- `35-74` **P1 / llm_closed_list_instruction**
  - evidence: the existing tabletop / kitchen / desk / curtain / doorway, low at ground/floor/quay level, shared bench/shared table
  - why: Uses a closed list of specific props and phrases to define semantic detection logic for open-world visual scenarios, biasing the reviewer toward specific tropes.
  - fix: Define detection logic using abstract semantic categories and move specific prop/scenario examples to a separate, dynamically injected context.

- `46-78` **P2 / scenario_dependent_prompt**
  - evidence: dark bitter herbal drink, Wet dock planks, C01O01 in a casual jacket sits hunched on the bench
  - why: Examples contain highly specific scenario details that pollute the general system prompt and may bias the LLM's judgment.
  - fix: Use generic or placeholder examples that demonstrate the structure of the fix without introducing specific story elements.

## `prompts/_base/t2i_review/3.202605121200/entity_schema.json`

- `16` **P2 / llm_closed_list_instruction**
  - evidence: "enum": ["missing_ethnicity", "proper_noun_translated", "awkward_translation"]
  - why: Hardcodes specific semantic error types for T2I review. 'missing_ethnicity' is a specific visual requirement that may not be universally applicable to all open-world scenarios (e.g., non-human entities or abstract scenes), yet it is baked into the validator's classification logic.
  - fix: Allow the LLM to provide a natural language 'category' or 'reason' and move specific checks like ethnicity into a separate, dynamically injected rule-set or SOT.

- `17-18` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상"}, "suggestion": {"type": "string", "description": "target을 대체할 문자열"}
  - why: Establishes a pattern of fixing T2I prompts through string-based find-and-replace. This is fragile in open-world generation as it relies on the LLM identifying an exact substring and can lead to corrupted prompts if the target is ambiguous or if the replacement breaks sentence structure.
  - fix: Use structured prompt reconstruction where the LLM provides the full corrected prompt or specific attribute updates rather than performing blind string substitution on the raw prompt text.

## `prompts/_base/t2i_review/3.202605121200/entity_system.md`

- `11` **P1 / semantic_string_judgment**
  - evidence: 1. **국적/인종 누락**: 인간형 인물이나 사진/그림 속 인물에 국적/인종이 빠진 경우
  - why: This instruction mandates the inclusion of nationality or race in T2I prompts even when not specified in the source scenario. This compels the generation pipeline to make arbitrary visual decisions, leading to hallucinated character traits and potential bias in the final images.
  - fix: Modify the instruction to verify that the prompt is consistent with the provided entity context, rather than mandating specific attributes that may not be present in the source.

- `12-13` **P2 / semantic_string_judgment**
  - evidence: 2. **고유명사 번역**: 지명·상호명 등 고유명사가 영어로 번역되어 원어 뉘앙스가 손실된 경우 (원본 언어 표기로 복원); 3. **원어 어색**: 원어가 자연스러운데 영어로 번역되어 어색한 표현
  - why: These instructions rely on the LLM's subjective judgment of 'nuance' and 'naturalness' to trigger prompt mutations. This bypasses structured translation controls and can result in inconsistent handling of proper nouns and expressions across different scenarios.
  - fix: Implement a project-specific glossary or translation SOT to handle proper nouns and idiomatic expressions consistently, rather than relying on heuristic LLM review.

## `prompts/_base/t2i_review/3.202605121200/scene_schema.json`

- `38-39` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상 (unique sub-string)"}
  - why: The schema codifies a 'find-and-replace' mechanism for prompt correction. Relying on LLMs to identify 'unique sub-strings' for mutation is fragile and constitutes blind string replacement to decide visual/story meaning, rather than using structured re-generation or attribute-based updates.
  - fix: Shift from substring replacement to a structured delta format or full prompt re-generation where the LLM provides the entire corrected field, or use specific attribute overrides instead of arbitrary string surgery.

## `prompts/_base/t2i_review/3.202605121200/scene_system.md`

- `35-39` **P1 / llm_closed_list_instruction**
  - evidence: "the existing tabletop / kitchen / desk / curtain / doorway 등"
  - why: The prompt instructs the LLM to detect reference leakage using a closed list of specific props. This biases the validator toward these examples and may miss other environment elements (e.g., 'existing balcony', 'existing street') that cause the same hallucination issue in close-up shots.
  - fix: Replace the specific prop list with a general semantic rule instructing the LLM to identify any environment-anchored 'existing' or 'reference' descriptions that contradict the close-framing context.

- `53-55` **P1 / llm_closed_list_instruction**
  - evidence: "low at ground/floor/quay level" + 묘사 "<surface> visible behind subject's hands"
  - why: It defines physical inconsistency through hardcoded string combinations and specific props like 'quay level'. This is a pattern-based semantic judgment that fails to generalize to other camera/surface height conflicts.
  - fix: Define the physical principle (e.g., 'vertical alignment between camera height and visible ground/surface planes') rather than matching specific phrase combinations.

- `69-70` **P1 / llm_closed_list_instruction**
  - evidence: "Figure A occupies the right foreground... Figure B sits hunched in the left background."
  - why: The prompt uses specific sentence structures as 'detection patterns' for missing spatial anchors. This makes the validator fragile to variations in how the LLM describes foreground/background separation.
  - fix: Instruct the LLM to verify the presence of a shared spatial anchor (surface, room, or interaction) whenever actors are split across depth planes, regardless of the specific phrasing used.

## `prompts/_base/t2i_review/4.202605150957/scene_schema.json`

- `38-39` **P1 / blind_string_mutation**
  - evidence: "target": {"type": "string", "description": "T2I 원문에서 정확히 찾을 수 있는 치환 대상 (unique sub-string)"}
  - why: The review process relies on the LLM identifying a 'unique sub-string' for replacement. This is a fragile pattern for mutating natural language prompts as it can lead to unintended collisions, partial replacements, or broken syntax when the same token appears multiple times or in different contexts, directly affecting visual semantics.
  - fix: Instead of substring replacement, the review should return a fully reconstructed prompt or use a structured representation (e.g., a list of entities and attributes) where specific nodes can be updated without string-matching ambiguity.

## `prompts/_base/t2i_review/4.202605150957/scene_system.md`

- `16-19` **P1 / llm_closed_list_instruction**
  - evidence: suggestion: 인종 형용사를 포함한 형태 (예: "an Asian man in a security uniform")
  - why: The prompt provides a specific demographic ('Asian') as a hardcoded example for correcting missing ethnicities. This biases the LLM to inject specific demographics into open-world scenarios rather than deriving them from a structured world SOT.
  - fix: Remove specific demographic examples. Instruct the LLM to refer to the provided {t2i_context} or a global demographic rule-set for appropriate ethnicity assignment.

- `34-39` **P1 / llm_closed_list_instruction**
  - evidence: "the existing X" 표현 (the existing tabletop / kitchen / desk / curtain / doorway 등)
  - why: The detection pattern for reference leaks relies on a hardcoded list of common props ('tabletop', 'kitchen', etc.). This is a closed-list semantic classifier that may miss scenario-specific props or incorrectly flag valid descriptions.
  - fix: Generalize the detection logic to look for any 'existing' or 'reference' keywords relative to the entities defined in the scene context rather than a hardcoded list of props.

- `52-55` **P1 / semantic_string_judgment**
  - evidence: 카메라 "low at ground/floor/quay level" + 묘사 "<surface> visible behind subject's hands"
  - why: This rule attempts to perform physical/spatial validation using specific string combinations. The inclusion of 'quay level' suggests scenario-specific pollution (likely from a harbor/dock scenario) being used as a general heuristic.
  - fix: Abstract the physical contradiction logic. Instead of hardcoding 'quay', use generic spatial relationships (e.g., 'ground-level camera' vs 'high-surface interaction') and ensure the list of surfaces is derived from the scene's layout metadata.

- `88-89` **P0 / blind_string_mutation**
  - evidence: target: T2I 프롬프트 원문에서 정확히 찾을 수 있는 문자열 (sub-string 매치) ... suggestion: target을 대체할 문자열 — 시스템이 1회 치환 적용
  - why: The system performs a blind substring replacement based on the LLM's semantic judgment. If the LLM identifies a common word as a 'target' (as warned in line 91), it can lead to unintended corruption of the T2I prompt across the entire string.
  - fix: Use a more robust mutation strategy, such as returning the full corrected prompt or using unique block identifiers (e.g., [L##]) to scope the replacement, rather than raw substring matching.

## `prompts/_base/t2i_visual_converter/v1/system.md`

- `6-8` **P1 / scenario_dependent_prompt**
  - evidence: "Soul Ride vehicle", "Dr. Nex's laboratory", "Club House"
  - why: The prompt uses concrete story-specific names and props as negative examples. This pollutes the base system prompt with scenario-specific nomenclature that should be abstracted to ensure the LLM handles any arbitrary story without bias from previous projects.
  - fix: Replace specific names with generic placeholders like '[Proper Noun] [Object]' or '[Character Name]'s [Location]' to demonstrate the transformation rule without scenario pollution.

- `14` **P1 / scenario_dependent_prompt**
  - evidence: Photorealistic style — All prompts target photorealistic image generation.
  - why: This hard-codes a specific visual style (photorealism) into the base converter logic. It prevents the pipeline from supporting stylized, animated, or genre-specific visual aesthetics (e.g., noir, cyberpunk, anime) which should be driven by the scenario's visual SOT rather than a fixed system instruction.
  - fix: Inject the target visual style as a variable or instruction derived from the scenario's global visual configuration (SOT).

## `prompts/_base/t2i_visual_converter/v2/system.md`

- `15-18` **P1 / llm_closed_list_instruction**
  - evidence: Three shot types only: 1. Establishing shot... 2. Relationship shot... 3. Action moment shot
  - why: This forces all visual storytelling into three narrow semantic categories. It prevents the LLM from utilizing a full cinematic vocabulary (e.g., close-ups, POV, inserts) for open-world scenarios, potentially losing critical narrative detail by shoehorning scenes into these three buckets.
  - fix: Remove the 'only' constraint and provide a broader, non-exhaustive list of cinematic shot types, or allow the LLM to determine the shot type based on the scenario context.

- `46-63` **P1 / scenario_dependent_prompt**
  - evidence: corridor of glowing human pods, dark sci-fi facility, tactical soldier, mechanical devices on their necks
  - why: The 'Good vs Bad' examples are heavily polluted with specific sci-fi and dystopian world-building elements. This biases the LLM's visual generation toward these specific tropes even when the input scenario might be a different genre, and hardcodes props (like neck devices) that should be defined in a structured SOT.
  - fix: Replace scenario-specific examples with genre-neutral structural examples (e.g., 'A person reading a book in a sunlit library') to demonstrate the 'One Shot = One Sentence' rule without biasing the content.

- `86-88` **P2 / scenario_dependent_prompt**
  - evidence: corridor of glowing pods, restrained man staring through a transparent capsule door
  - why: The final template examples reinforce the sci-fi/dystopian bias found earlier in the prompt, further narrowing the LLM's expected output range to specific scenario types.
  - fix: Use diverse, genre-agnostic examples in the final template section.

## `prompts/_base/t2i_visual_converter/v3/system.md`

- `19-49` **P2 / scenario_dependent_prompt**
  - evidence: 청록색 발광, 지하 극저온 저장 시설, 산업적 조명
  - why: Specific sci-fi tropes and lighting styles used as 'good' examples can bias the LLM towards these aesthetics (e.g., cyan glow, industrial lighting) regardless of the actual input scenario's genre or mood.
  - fix: Replace specific genre-heavy examples with more neutral or varied examples, or move style-specific guidance to a dynamic style SOT.

- `59` **P1 / scenario_dependent_prompt**
  - evidence: 흰 배경 프로필
  - why: Hardcodes a specific visual requirement (white background) for character entities. This is a visual decision that should be driven by a style SOT or the specific technical needs of the downstream generation task, not fixed in the base prompt.
  - fix: Remove the hardcoded background instruction or make it a variable injected from the project's visual style configuration.

## `prompts/_base/t2i_visual_converter/v4/system.md`

- `46-49` **P2 / scenario_dependent_prompt**
  - evidence: "중년의 보안 요원", "지하 극저온 저장 시설", "산업적 조명"
  - why: The use of specific sci-fi and industrial scenario examples in a base system prompt can bias the LLM's descriptive style and vocabulary choice for unrelated genres (e.g., fantasy or period drama).
  - fix: Replace concrete scenario details with generic placeholders like [인물], [장소], [조명] or provide genre-neutral examples to demonstrate the formatting rules.

- `59` **P2 / scenario_dependent_prompt**
  - evidence: "흰 배경 프로필"
  - why: Hardcoding a 'white background profile' style for character entities restricts the visual variety of reference images. This visual decision should be driven by a style SOT or configuration rather than being fixed in the base prompt.
  - fix: Replace the hardcoded style with a variable placeholder like {character_reference_style} that can be populated based on the project's visual requirements.

## `prompts/_base/variation_recommender/v2/system.md`

- `23` **P2 / scenario_dependent_prompt**
  - evidence: Examples: "tight close-up on face", "wide establishing shot", "over-shoulder framing", "low angle hero shot"
  - why: Hardcoded framing tropes in the system prompt bias the LLM toward specific shot types. These should be derived from a structured style SOT to ensure consistency with the specific scenario's art direction.
  - fix: Replace hardcoded examples with a reference to a dynamic style/framing SOT or use more abstract guidance.

- `29` **P2 / scenario_dependent_prompt**
  - evidence: Examples: "warm golden hour lighting", "cold blue moonlight", "high contrast noir shadows", "desaturated muted tones"
  - why: Hardcoded lighting tropes (e.g., 'noir shadows', 'golden hour') bias the variation recommender. These visual moods should be provided by a world-rule SOT rather than being fixed in the base prompt.
  - fix: Inject valid lighting/color variations from a project-level configuration or use abstract instructions.

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

- `9` **P2 / llm_closed_list_instruction**
  - evidence: possession, transformation, ghost, time_period, costume, technology 등
  - why: Hardcoding specific tropes in the schema description biases the LLM's scenario analysis, potentially forcing open-world story rules into a narrow set of predefined categories.
  - fix: Remove specific trope examples from the schema description or move them to a dynamic configuration/SOT that defines valid rule types for the specific project context.

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

- `8` **P1 / semantic_string_judgment**
  - evidence: 빙의/소울라이드: 인물 A가 인물 B의 몸에 빙의한 경우, 이미지에는 B의 외형을 그려야 함 (A의 얼굴이 아님)
  - why: This hardcodes a specific visual interpretation for a narrative trope (possession) directly into the system prompt. It forces a single visual solution (Person B's appearance) rather than allowing the scenario or a structured world-rule SOT to define how possession is visually manifested in a specific story.
  - fix: Remove the specific visual instruction. Instruct the LLM to extract the visual manifestation of possession as defined by the scenario text or a separate world-rule configuration.

- `16-22` **P2 / scenario_dependent_prompt**
  - evidence: 조선시대, 한복
  - why: The prompt uses specific domain tropes (Korean historical era and clothing) as examples. This can bias the LLM toward these specific cultural contexts even when analyzing scenarios from different cultures or genres, leading to 'hallucinated' cultural markers in the extracted rules.
  - fix: Replace specific cultural examples with generic placeholders or a broader range of cross-genre examples (e.g., 'Historical/Fantasy/Sci-fi' and 'Period-appropriate attire').

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

- `9` **P2 / llm_closed_list_instruction**
  - evidence: possession, transformation, ghost, time_period, costume, technology 등
  - why: The description provides a list of specific tropes as examples for rule types. This biases the LLM toward classifying open-world story rules into these specific buckets rather than identifying novel or scenario-appropriate categories.
  - fix: Use more abstract category examples (e.g., 'physical_law', 'character_state', 'environmental_effect') or move trope-specific examples to a separate reference document.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: 예: A가 B의 몸을 소울라이드 중이면 A는 물리적 존재가 아님
  - why: Uses a highly specific story mechanic ('soul-ride') as the primary example for determining physical presence. This pollutes the base schema with domain-specific logic that should be defined in a scenario-specific SOT, potentially confusing the LLM when dealing with different types of non-physicality.
  - fix: Replace the specific 'soul-ride' example with a generic logical description of how to determine physical presence based on the provided rules.

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

- `8` **P1 / scenario_dependent_prompt**
  - evidence: 빙의/소울라이드
  - why: The term '소울라이드' (Soul-ride) is a specific story-world concept likely originating from a particular scenario, polluting the base prompt with domain-specific nomenclature.
  - fix: Remove scenario-specific terms like '소울라이드' and use generic terms like '빙의' (possession) or '정신 지배' (mind control).

- `28` **P1 / llm_closed_list_instruction**
  - evidence: rule_type은 다음 중 선택: possession, transformation, ghost, projection, superpower, body_deformation, time_period, costume, technology, other
  - why: This forces the LLM to classify open-world story phenomena into a closed set of categories. This limits the system's ability to handle novel or hybrid tropes not covered by the list.
  - fix: Allow the LLM to generate descriptive category tags or move the trope taxonomy to a separate, extensible SOT configuration.

- `52` **P1 / scenario_dependent_prompt**
  - evidence: All human characters are Korean unless stated otherwise.
  - why: Hardcoding a specific nationality ('Korean') as a default in a base prompt biases the visual generation for all scenarios, even those set in different cultures or worlds.
  - fix: Move nationality/ethnicity defaults to a scenario-specific configuration or a dynamic variable injected during prompt assembly.

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

- `9` **P2 / llm_closed_list_instruction**
  - evidence: possession, transformation, ghost, time_period, costume, technology 등
  - why: The description provides a hardcoded list of genre tropes which biases the LLM to categorize world rules into these specific buckets rather than discovering them from the scenario text.
  - fix: Remove the specific trope examples or move them to a separate 'available_rule_types' enum/SOT if they are intended to be a closed set.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: 예: A가 B의 몸을 소울라이드 중이면 A는 물리적 존재가 아님
  - why: The example uses a specific story mechanic ('soulride') which pollutes the base schema with scenario-specific logic, potentially biasing the LLM's reasoning for unrelated stories.
  - fix: Replace the specific 'soulride' example with a generic physical/metaphysical logic example (e.g., 'if a character is a hologram').

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

- `8` **P2 / scenario_dependent_prompt**
  - evidence: 빙의/소울라이드
  - why: The term 'Soulride' is project-specific domain nomenclature. Including it in a base system prompt as a primary extraction target pollutes the prompt with scenario-specific concepts that should be defined in a structured world-rule SOT.
  - fix: Use generic terms like 'Possession' or 'Remote Control' and move project-specific tropes to a dynamic scenario-specific configuration.

- `28` **P1 / llm_closed_list_instruction**
  - evidence: rule_type은 다음 중 선택: possession, transformation, ghost, projection, superpower, body_deformation, time_period, costume, technology, other
  - why: This is a closed-list semantic classifier for open-world story elements. It forces diverse narrative phenomena into a fixed set of tropes, which acts as a semantic bottleneck and requires prompt updates for new story genres or mechanics.
  - fix: Allow the LLM to generate descriptive category tags or move the trope list to a dynamic configuration injected from the world-building SOT.

- `52` **P1 / scenario_dependent_prompt**
  - evidence: All human characters are Korean unless stated otherwise.
  - why: Hardcoding a specific nationality/race as the default example in a base prompt introduces a strong visual bias. This can lead to incorrect image generation for scenarios set in different cultural contexts or locations.
  - fix: Remove the specific nationality from the base prompt and instruct the LLM to derive the default nationality/race from the scenario's 'region' or 'era' metadata.

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

- `9` **P2 / scenario_dependent_prompt**
  - evidence: possession, transformation, ghost, time_period, costume, technology
  - why: Hardcoded trope examples in the schema description bias the LLM toward specific genres and may lead to forced classification of open-world rules into these categories.
  - fix: Move trope examples to a separate documentation or dynamic context; keep the schema description generic.

- `20` **P2 / scenario_dependent_prompt**
  - evidence: 예: A가 B의 몸을 소울라이드 중이면 A는 물리적 존재가 아님
  - why: Contains a specific story mechanic ('soul-ride') as an example. This pollutes the schema with project-specific or genre-specific logic that may not apply to all scenarios.
  - fix: Use a generic physical/non-physical example or remove the specific 'soul-ride' terminology.

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

- `8` **P1 / semantic_string_judgment**
  - evidence: 인물 A가 인물 B의 몸에 빙의한 경우, 이미지에는 B의 외형을 그려야 함 (A의 얼굴이 아님)
  - why: This hard-codes a specific visual interpretation of the 'possession' trope (drawing the host's body only) as a global rule, preventing scenarios where a visual blend or the possessor's face is intended.
  - fix: Change the instruction to ask the LLM to extract the specific visual rule for possession from the scenario text rather than prescribing one.

- `45-46` **P1 / scenario_dependent_prompt**
  - evidence: 작품 고유명사를 사용하되, 범용 규칙이 아닌 이 작품에서만 필요한 판단 기준을 작성하세요.
  - why: Instructing the LLM to generate logic ('판단 기준') using scenario-specific proper nouns creates unstructured, non-standardized semantic rules that the downstream pipeline must interpret, leading to fragile character-presence logic.
  - fix: Use a structured schema for physical presence (e.g., mapping specific entity IDs to states like 'astral', 'physical', 'remote') instead of free-text rules using proper nouns.

- `64` **P2 / scenario_dependent_prompt**
  - evidence: All human characters are Korean unless stated otherwise.
  - why: This example provides a specific ethnic bias ('Korean') in a general system prompt, which can lead the LLM to hallucinate this constraint for non-Korean scenarios if the scenario text is ambiguous.
  - fix: Replace the specific nationality with a placeholder or a more neutral instruction to identify nationality/race from the scenario context.

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

- `9` **P2 / llm_closed_list_instruction**
  - evidence: possession, transformation, ghost, time_period, costume, technology 등
  - why: Providing a list of specific genre tropes as examples for 'rule_type' biases the LLM toward these categories, which should ideally be derived from a structured world-rule SOT or the scenario context without pre-defined trope bias.
  - fix: Abstract the examples or reference an external SOT for valid rule categories.

- `20` **P1 / scenario_dependent_prompt**
  - evidence: 예: A가 B의 몸을 소울라이드 중이면 A는 물리적 존재가 아님
  - why: The schema description uses a specific story mechanic ('soul-ride') to instruct the LLM on how to determine physical presence. This pollutes the general world-rule schema with scenario-specific logic, biasing the LLM's semantic judgment of entity visibility.
  - fix: Replace the scenario-specific example with a generic logical principle regarding non-corporeal or internal states.

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

- `31-36` **P1 / llm_closed_list_instruction**
  - evidence: 빙의/소울라이드: ... 이미지에는 B의 외형을 그려야 함 (A의 얼굴이 아님)
  - why: The prompt prescribes specific visual handling for open-world tropes (possession, ghosts, etc.) as part of the extraction target definition. This hard-codes visual logic (e.g., whose face to show during possession) that should be derived from the scenario's internal logic or a separate world-building SOT, rather than being fixed in the base extraction prompt.
  - fix: Remove prescriptive visual logic from the extraction targets. Instead, instruct the LLM to extract the scenario's own logic for these phenomena, or move these as default rules to a structured World Rule SOT.

- `68-72` **P1 / llm_closed_list_instruction**
  - evidence: 회상/F.B 장면의 인물·소품·혈흔 등은 ... 현재 씬 공간에는 물리적으로 존재하지 않는다.
  - why: These 'correct examples' for director notes prescribe specific visual interpretations for scene types (flashbacks, hallucinations, CCTV). Providing these as the only examples often leads the LLM to copy them verbatim, forcing a specific visual logic on all scenarios regardless of their actual narrative needs.
  - fix: Provide more abstract examples that focus on the format and level of detail required, rather than prescribing the specific visual outcome for common tropes.

- `98` **P1 / scenario_dependent_prompt**
  - evidence: 인물의 기본 국적/인종 (예: "All human characters are Korean unless stated otherwise.")
  - why: Hard-codes a specific nationality ('Korean') as a mandatory example/default for the visual style summary. This pollutes the output with scenario-specific assumptions that should be provided via project-level metadata or extracted from the scenario text.
  - fix: Replace the specific nationality with a placeholder (e.g., '[Default Nationality/Race]') and ensure this information is injected from a project-specific configuration.

- `106` **P1 / blind_string_mutation**
  - evidence: ("피", "blood", "gore" 등 graphic 단어 자제 — "dark", "moody", "tense"로 추상화)
  - why: Instructs the LLM to perform semantic mapping/suppression of specific visual tokens ('blood', 'gore') to abstract moods ('dark', 'moody'). This is a pattern-based mutation of visual meaning that biases the visual prompt generation process.
  - fix: Move safety and style filtering to a dedicated post-processing layer or a specialized style-transfer prompt that can handle these mappings more robustly without polluting the extraction logic.

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

- `9` **P1 / llm_closed_list_instruction**
  - evidence: possession, transformation, ghost, time_period, costume, technology 등
  - why: The description provides a hardcoded list of domain tropes to guide the LLM's classification of rule types. This biases the LLM toward specific genres and should instead be derived from a structured world-rule SOT or the scenario context.
  - fix: Remove the specific trope examples from the description or move them to a separate configuration file that defines valid rule categories for the specific project context.

- `20` **P2 / scenario_dependent_prompt**
  - evidence: 예: A의 영혼이 B의 몸에 전이된 경우 A는 물리적 존재가 아님
  - why: The description uses a specific story trope (soul transfer/possession) to define the logic for physical existence. This pollutes the schema with scenario-specific logic that may bias the LLM's judgment in unrelated scenarios.
  - fix: Replace the specific example with a generic instruction regarding the determination of physical presence based on the story's internal logic.

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

- `24-51` **P1 / llm_closed_list_instruction**
  - evidence: rule_type은 다음 중 선택: possession, transformation, ghost, projection, superpower, body_deformation, time_period, costume, technology, other
  - why: The prompt hard-codes a limited set of story tropes (possession, ghost, etc.) and their visual treatments (e.g., line 31: 'draw B's appearance, not A's face'). This forces a specific visual logic for open-world story elements that should be defined in a project-specific SOT or a more flexible world-rule schema.
  - fix: Move the trope definitions and their associated visual logic to a dynamic configuration or a structured World Rule SOT that can be updated without modifying the core extraction prompt.

- `98` **P1 / scenario_dependent_prompt**
  - evidence: All human characters are <region-derived demonym> unless stated otherwise.
  - why: This instruction forces a visual decision (race/nationality) based on a string pattern (the scenario's region). This creates a hard-coded bias that may conflict with specific character descriptions in the scenario or diverse casting requirements.
  - fix: Allow the LLM to derive character appearance from the scenario text or a character-specific SOT rather than forcing a global demonym based on the region string.

- `106` **P2 / llm_closed_list_instruction**
  - evidence: blood, gore 등 graphic 단어 자제 — dark, moody, tense로 추상화
  - why: This is a prompt-level instruction to perform semantic abstraction/replacement of specific tokens. While intended for safety, it is a form of blind mutation that can lose important visual context (e.g., a 'blood-stained letter' becomes a 'moody letter').
  - fix: Use a separate safety/style filter or allow the LLM to describe the visual mood naturally without hard-coded word-to-word mapping.

## `prototype_ui/app.py`

- `521` **P2 / scenario_dependent_code**
  - evidence: ref_groups: Dict[str, list] = {"character": [], "location": [], "prop": []}
  - why: The UI hardcodes a specific story ontology (character, location, prop) as the primary buckets for entity grouping. This is a domain trope list that should be derived from the world guide schema or the pipeline's entity classification rather than being baked into the UI logic, as it biases the display toward specific story structures.
  - fix: Initialize ref_groups as an empty dictionary and allow the pipeline's entity 'type' field to dynamically define the grouping keys, or fetch the allowed entity types from a central world-building schema (SOT).

## `screenplay/extract_entities.py`

- `318-323` **P2 / scenario_dependent_code**
  - evidence: --input "screenplay/srd part 1 blue revision.pdf"
  - why: Hardcoded scenario-specific file paths and project names ('srd') are used as default arguments in a generic extraction utility, polluting the codebase with specific project context.
  - fix: Remove scenario-specific defaults or move them to a configuration file or environment variables.

- `817-846` **P1 / scenario_dependent_code**
  - evidence: item["importance"] in {"major", "supporting"} and has_reference_value(item)
  - why: Hardcoded semantic filtering logic decides which entities are 'visible' or 'members' of the story graph based on importance levels and trait counts. This logic should be driven by a structured SOT or configuration, as 'minor' entities may still be required for specific visual contexts or downstream analysis.
  - fix: Move pruning logic to a configurable policy or allow the downstream consumer to decide which entities to filter based on the extracted metadata.

- `856-860` **P1 / semantic_string_judgment**
  - evidence: identifiers = {normalize_name(str(item["name"]))}
  - why: Entity identity is determined by a blind intersection of normalized name and alias strings. This heuristic fails in open-world scenarios where different characters share common names or titles (e.g., 'Guard 1', 'The Captain'), leading to incorrect entity merging and loss of story data.
  - fix: Use unique persistent IDs (e.g., C##) or rely on the LLM to perform entity resolution against a provided stateful memory rather than post-processing string sets.

- `862-878` **P2 / semantic_string_judgment**
  - evidence: return candidate_name if len(candidate_name) > len(current_name) else current_name
  - why: Canonical name selection is based on string length heuristics. This is a blind mutation of story data that may prefer a descriptive phrase over a proper name simply because it is longer.
  - fix: Implement a more robust canonicalization strategy, perhaps by having the LLM explicitly designate the primary name during extraction.

- `1020-1034` **P1 / semantic_string_judgment**
  - evidence: signature = "||".join([...normalized["relation_type"], ...])
  - why: Relation identity is determined by a string-based signature that includes 'relation_type', which is an open-world natural language string. This leads to duplicate or missed merges based on phrasing variations (e.g., 'is father of' vs 'father').
  - fix: Normalize relation types to a closed enum or use a semantic similarity check for merging relation facts.

## `screenplay/extract_scene_stills.py`

- `438-447` **P1 / semantic_string_judgment**
  - evidence: choose_canonical_name
  - why: Uses string length and substring containment to decide which name variant is 'canonical' for an open-world entity. This is a brittle heuristic for managing story identity.
  - fix: Use a unique entity ID from a source-of-truth or allow the LLM to resolve canonical names based on context.

- `450-493` **P1 / semantic_string_judgment**
  - evidence: similarity_score
  - why: Determines identity of open-world entities (characters, locations) using substring checks, token overlap ratios, and hardcoded thresholds (0.94, 0.88, 0.93). This logic directly routes entity IDs and reference attachments based on string patterns.
  - fix: Delegate entity resolution to a dedicated cross-scene linking step or use vector embeddings/LLM-based verification for identity matching.

- `607` **P1 / semantic_string_judgment**
  - evidence: if best_index is not None and best_score >= 0.9:
  - why: Uses a hardcoded similarity threshold (0.9) to resolve visible entities to existing candidates. This is a pattern-based semantic judgment that can lead to incorrect entity linking in visual prompts.
  - fix: Use a more robust identity verification method or move thresholds to a configurable SOT.

- `711` **P2 / blind_string_mutation**
  - evidence: localized = localized.replace(english, translated)
  - why: Performs blind string replacement of technical terms within potentially natural-language strings. This can cause partial word corruption (e.g., 'Hard' -> '하드' inside 'Hardly').
  - fix: Use word-boundary regex or only translate exact matches of the entire field value.

## `screenplay/prototype_episode_novel.py`

- `46-637` **P2 / semantic_string_judgment**
  - evidence: score += 6 if relation.get("relation_family") in DIRECT_RELATION_FAMILIES else 3
  - why: The script uses a hardcoded list of semantic relationship types (identity, kinship, etc.) to drive visual priority scoring for image generation.
  - fix: Define relationship weights in a configuration file or the World SOT to allow for different story genres where different relationship types might carry more visual weight.

- `57-108` **P1 / scenario_dependent_code**
  - evidence: SPECIAL_ENTITY_GUARDRAILS = { "DR.NEX": { ... }, "한치호": { ... }, "은성": { ... }, "서현": { ... }, "오리엔티스": { ... } }
  - why: Hardcoded character and location names from a specific project ('SRD') are embedded in the code with specific visual instructions. This prevents the prototype from being used for arbitrary scenarios without manual code modification.
  - fix: Move these entity-specific guardrails into the project's World SOT or a separate configuration JSON loaded at runtime.

- `418-420` **P2 / scenario_dependent_code**
  - evidence: can_seed_from_episode1_cache = input_path.name == "srd part 1 blue revision.pdf"
  - why: The logic for seeding analysis from cache is tied to a specific hardcoded filename, making the pipeline fragile and scenario-dependent.
  - fix: Use a hash of the input file content or a generic command-line argument to specify cache seeds rather than checking for a specific filename.

- `810-847` **P1 / scenario_dependent_prompt**
  - evidence: "Use realistic present-day / near-future Korean baseline clothing."
  - why: Visual style instructions for characters are hardcoded with specific cultural and era-based tropes ('Korean', 'near-future') inside the prompt assembly logic, biasing all future scenarios.
  - fix: Move these baseline visual rules into the World Guide or a style-specific SOT that is passed into the prompt generator.

- `862-865` **P1 / scenario_dependent_code**
  - evidence: if entity["name"] == "DR.NEX":
  - why: The code performs a hardcoded string check on a character name to inject specific visual descriptions into the prompt.
  - fix: Ensure these descriptions are part of the entity's metadata in the structured analysis output (entities.json) rather than being hardcoded in the assembly logic.

## `scripts/build_phase91_compare_viewer.py`

- `52-53` **P1 / scenario_dependent_code**
  - evidence: DEFECTS = {(5, 13), (6, 1), (10, 6), (12, 8), (12, 16), (13, 6), (15, 2), (20, 5), (23, 4), (24, 2), (27, 2), (28, 4), (29, 7)}
  - why: Manual hardcoding of scene/shot indices as 'defects' encodes semantic quality judgments directly in code rather than using structured metadata or database flags. This makes the script non-reusable for other episodes and hides quality data from the primary SOT.
  - fix: Migrate defect tracking to the database (e.g., a 'review_status' or 'is_defect' column in SceneStill) to allow the script to remain generic across different episodes.

- `125` **P2 / scenario_dependent_code**
  - evidence: OpenAI safety filter가 prompt 거부 (혈흔/폭력 묘사)
  - why: Hardcodes a specific scenario-based reason (blood/violence) for image generation failure in the UI output, which biases the viewer's interpretation and may not apply to other episodes.
  - fix: Use a generic failure message or pull the actual rejection reason from the generation logs/metadata if available.

## `scripts/canary/_g4_3_common.py`

- `43-47` **P1 / semantic_string_judgment**
  - evidence: _ID_AGE_BANDS, _ID_BODY_PART_TRIGGERS, _ID_CLOSE_FACE_FORBIDDEN_PHRASES, _ID_ETHNICITY_COMPONENTS, _ID_REPRODUCTION_SURFACES
  - why: These constants represent hardcoded keyword and phrase lists used to perform semantic validation (detecting age, body parts, forbidden phrases, ethnicity, and surfaces) on open-world scenario and prompt content. This approach relies on closed-list string matching to judge visual and demographic meaning, which should instead be driven by a structured SOT or flexible LLM analysis.
  - fix: Move these semantic definitions into a structured World/Rule SOT or use an LLM-based classifier that understands the concepts rather than relying on hardcoded keyword lists.

## `scripts/canary/_g4_4_common.py`

- `44-52` **P1 / semantic_string_judgment**
  - evidence: _CONTINUITY_GENERIC_PERSON_NOUNS, _CONTINUITY_FURNITURE_LAYOUT_TOKENS, _ID_BODY_PART_TRIGGERS
  - why: These constants represent hardcoded lists of nouns and tokens used to identify and classify open-world story entities (people, furniture, body parts) for continuity and layout logic. Using closed phrase lists to decide story meaning or entity membership biases the pipeline against arbitrary scenarios.
  - fix: Move entity classification to a structured SOT or use an LLM-based semantic classifier that does not rely on hardcoded string lists. If these are used for validation, they should be derived from the world-state/schema rather than global constants.

## `scripts/canary/g4_2_camera_wording.py`

- `48-53` **P1 / semantic_string_judgment**
  - evidence: CAMERA_WORDING_PATTERNS: List[str] = [
  - why: The script uses regex to detect camera consistency instructions within natural language 't2i_prompt' strings. This is a pattern-based semantic judgment that fails to account for synonymous phrasing (e.g., 'keep the same perspective' vs 'match reference camera'), making the degradation guard fragile to LLM output variations that preserve meaning.
  - fix: Replace regex-based detection with a structured 'camera_consistency' flag in the scene metadata or use an LLM-based semantic evaluator to verify the presence of the instruction regardless of specific wording.

## `scripts/canary/g4_2_close_forbidden.py`

- `33-46` **P1 / semantic_string_judgment**
  - evidence: CLOSE_FORBIDDEN_PATTERNS: List[str] = [ ... r"preserving the same room perspective", ... ]
  - why: The script performs pass/fail validation of open-world visual prompts by scanning for specific natural language phrases. This is a brittle semantic judgment that relies on string patterns rather than structured state or schema-based constraints, making it sensitive to minor wording variations in LLM output.
  - fix: If these constraints are part of a 'Rule E' logic, they should be validated against structured fields in the scene/shot metadata (e.g., background_binding.constraints) rather than scanning the final natural language prompt string.

## `scripts/canary/g4_3_body_part_focus.py`

- `55-58` **P1 / semantic_string_judgment**
  - evidence: BODY_PART_FOCUS_PATTERN = re.compile(r"\b(?:" + _TRIGGER_ALT + r")\s+C\d{2}(?:O\d{2})?'s\s+\w+", re.IGNORECASE)
  - why: This regex performs a semantic judgment by assuming any word following a possessive character ID and a specific trigger phrase is a 'body part'. It is used to fail/pass candidates (line 242), making it a gating semantic validator based on string patterns rather than structured metadata.
  - fix: Instead of regex-based detection on the final prompt string, the pipeline should emit structured focus/framing metadata (e.g., a 'focus_target' field in the shot schema) which can be validated against a schema or allowed enum.

## `scripts/canary/g4_3_close_framing_face_forbidden.py`

- `63-71` **P1 / semantic_string_judgment**
  - evidence: phrase.lower() in pl
  - why: The script performs case-insensitive literal substring matching on the generated 't2i_prompt' to detect forbidden visual descriptions (e.g., 'his face fills the frame'). This uses a closed list of phrases to judge open-world visual meaning and determines the success or failure of the canary validation.
  - fix: Transition to a structured visual constraint validation where the LLM or a vision-language model evaluates the framing intent, or check for specific metadata flags in the scene analysis rather than searching for natural language patterns in the final prompt.

## `scripts/canary/g4_3_demographic_descriptor_present.py`

- `95-105` **P1 / semantic_string_judgment**
  - evidence: ethnicity.lower() in window ... age.lower() in window
  - why: The script uses substring matching against keyword lists (ethnicity and age bands) to determine if a character ID in a generated prompt is 'demographically described'. This is a brittle heuristic for semantic judgment of open-world natural language and directly affects the canary's pass/fail metrics.
  - fix: Replace substring checks with an LLM-based semantic classifier or validate against a structured SOT that defines required attributes for each ID.

- `221-223` **P2 / semantic_string_judgment**
  - evidence: surf.lower() in pl
  - why: Uses a keyword list (_ID_REPRODUCTION_SURFACES) to detect semantic concepts within natural language prompts for diagnostic flags. This relies on pattern-based semantic judgment rather than structured metadata.
  - fix: Transition to structured metadata for tracking reproduction surfaces or use an LLM for semantic detection.

## `scripts/canary/g4_3_reproduction_surface.py`

- `82-91` **P1 / semantic_string_judgment**
  - evidence: for surface in _ID_REPRODUCTION_SURFACES: ... idx = pl.find(s_lower, start)
  - why: The script identifies visual entities (reproduction surfaces) in the t2i_prompt using substring matching against a list of natural language keywords. This is a pattern-based semantic judgment used to determine validation failure (fail/pass behavior).
  - fix: Use a structured SOT or a dedicated LLM-based classifier to identify the presence and span of reproduction surfaces instead of relying on a hardcoded list of keywords and substring searches.

- `240-243` **P1 / semantic_string_judgment**
  - evidence: for surf in _ID_REPRODUCTION_SURFACES: if surf.lower() in pl:
  - why: Uses substring matching to set diagnostic flags ('has_reproduction_surface') which are included in the final validation report. This propagates pattern-based semantic judgments into the analysis output.
  - fix: Derive visual entity presence from structured metadata or a semantic analysis step rather than keyword matching.

## `scripts/canary/g4_4_atmosphere_no_layout_import.py`

- `76-79` **P1 / semantic_string_judgment**
  - evidence: if token.lower() in prompt_lower: found.append(token)
  - why: The script performs case-insensitive substring matching on the natural-language 't2i_prompt' to detect layout-related tokens. This is a brittle heuristic for semantic validation that cannot distinguish between layout instructions and natural descriptions or negations (e.g., 'no furniture'), leading to false positives or missed detections in open-world story text.
  - fix: Replace the substring check with an LLM-based semantic judge or ensure the layout intent is captured in a structured metadata field during the scene analysis phase before prompt generation.

## `scripts/canary/g4_4_double_description.py`

- `248-251` **P1 / semantic_string_judgment**
  - evidence: for noun in _CONTINUITY_GENERIC_PERSON_NOUNS: if noun.lower() in window:
  - why: The script performs a substring check on generated natural-language prompts using a closed list of nouns to detect 'double descriptions'. This pattern-based semantic judgment determines the success or failure of the prompt version, which is a high-signal routing/validation risk for open-world story content.
  - fix: Replace substring-based semantic detection with a structured check during prompt assembly or use an LLM-based evaluator to identify redundant character descriptions in context.

## `scripts/canary/g4_4_view_mixing.py`

- `67-75` **P1 / semantic_string_judgment**
  - evidence: _VIEW_MIXING_FULL_BODY_VERBS
  - why: Hardcoded list of English verbs ('stands', 'seated', 'walking', etc.) used to semantically classify a prompt as 'full-body' view. This is a closed-world heuristic for open-world visual descriptions.
  - fix: Move semantic view classification to a structured SOT or an LLM-based validator that understands visual context beyond a fixed verb list.

- `79-82` **P1 / semantic_string_judgment**
  - evidence: _BODY_PART_FOCUS_PATTERN
  - why: Uses a regex pattern to identify 'body-part focus' based on a closed list of triggers and a specific possessive syntax, which fails to capture the variety of natural language descriptions for close-ups.
  - fix: Use an LLM-based semantic analyzer to identify close-up or focus intent rather than relying on rigid regex patterns.

- `131-133` **P1 / semantic_string_judgment**
  - evidence: any(v in window for v in _VIEW_MIXING_FULL_BODY_VERBS)
  - why: Uses substring matching against a fixed verb list to determine the visual composition of a scene, which is used to trigger validation failures.
  - fix: Replace substring-based view detection with a vision-language model or a dedicated LLM classifier that evaluates the entire prompt context.

## `scripts/canary/g4_4_zoom_in_detail_no_new_entity.py`

- `60-75` **P1 / semantic_string_judgment**
  - evidence: extract_entity_set(prompt: str)
  - why: The script determines which characters (C##) and props (P##) are present in a shot by regex-scanning the natural-language 't2i_prompt' string. This uses pattern matching on generated text to decide 'visible entity membership', which is then used to fail or pass the canary. This makes the continuity check fragile to the LLM's phrasing rather than relying on a structured source of truth for entity presence.
  - fix: Use a structured metadata field (e.g., 'entities' or 'continuity_elements') that explicitly lists the IDs present in the shot, rather than parsing them from the natural-language prompt text.

## `scripts/canary/g4_5a_camera_frame_consistency.py`

- `59-160` **P1 / semantic_string_judgment**
  - evidence: _SPATIAL_CAMERA_LOW_TOKENS, _LOW_CONTRADICTION_TOKENS, and _detect_violations_in_window logic
  - why: The script performs semantic contradiction detection (Rule F) by scanning for specific natural language substrings (e.g., 'chest', 'floor', '가슴') within a character window in the t2i_prompt. This pattern-based judgment of open-world visual meaning is brittle and used to fail the pipeline.
  - fix: Migrate the Rule F consistency check to an LLM-based validator or a structured spatial reasoning engine as suggested in the module's own documentation.

## `scripts/canary/g4_5a_fg_bg_shared_anchor.py`

- `183-190` **P1 / semantic_string_judgment**
  - evidence: _has_any_token(prompt, _SPATIAL_INTERACTION_VERBS) and _has_any_token(prompt, _SPATIAL_SHARED_ANCHOR_KEYWORDS)
  - why: The script performs pass/fail validation on open-world natural language prompts by checking for the presence of specific verbs and anchor keywords. This pattern-based semantic judgment is brittle and cannot reliably capture the nuance of spatial interactions in diverse story scenarios, leading to false positives or missed violations.
  - fix: Replace the substring-based detection logic with an LLM-based validator (e.g., gpt-4o-mini) as suggested in the file's own O-17 override comment, using a structured prompt to evaluate Rule G compliance based on the actual meaning of the prompt.

## `scripts/canary/g4_5a_primary_framing.py`

- `88-93` **P1 / semantic_string_judgment**
  - evidence: _FULL_BODY_KEYWORDS: tuple[str, ...] = ("stands", "seated", "leaning", "전신")
  - why: Hardcoded list of natural language verbs used as a semantic classifier to determine the visual state (full-body) of a character. This is an open-world visual judgment implemented as a closed string list, which is prone to false negatives and scenario-specific bias.
  - fix: Move these semantic anchors to a structured World/Rule SOT or transition to the LLM-based validator (gpt-5.4-mini) as noted in the file's own comments at line 35.

- `171-178` **P1 / semantic_string_judgment**
  - evidence: for trigger in _ID_BODY_PART_TRIGGERS: ... if window_text == trigger.lower():
  - why: Uses exact string matching on natural language tokens to identify 'body-part close-up' triggers. This heuristic-based semantic detection drives the pass/fail behavior of the canary validator.
  - fix: Replace token-matching heuristics with a semantic analysis step that uses structured shot intent or an LLM judge to identify body-part focus.

- `184` **P1 / semantic_string_judgment**
  - evidence: if any(kw.lower() in tok_lower for kw in _FULL_BODY_KEYWORDS):
  - why: Uses substring matching on natural language tokens to decide if a prompt describes a full-body shot. This is a pattern-based semantic judgment used to validate open-world story/visual meaning.
  - fix: Use a structured representation of character pose/framing or an LLM-based classifier to determine visual state.

- `318` **P1 / semantic_string_judgment**
  - evidence: has_close = any(kw in prompt_lower for kw in close_kw_lower)
  - why: Determines the 'close-framing' scope of a shot by checking for the presence of specific keywords in the generated prompt text. This routes the validation logic based on string patterns rather than structured metadata.
  - fix: Use structured shot metadata (e.g., framing type from the scene manifest) to determine the shot scope instead of parsing the generated prompt text.

## `scripts/canary/g4_5a_view_mixing_extension.py`

- `74-90` **P1 / semantic_string_judgment**
  - evidence: _VIEW_MIXING_FULL_BODY_VERBS, _FACE_CLOSE_UP_KEYWORDS
  - why: Hardcoded lists of verbs and keywords (including Korean terms like '눈', '얼굴') are used as semantic classifiers to judge open-world visual content. This approach is prone to false positives/negatives and lacks contextual awareness.
  - fix: Centralize these definitions in a structured world/rule SOT and transition to an LLM-based validator for semantic judgment.

- `151-211` **P1 / semantic_string_judgment**
  - evidence: any(v.lower() in tok_lower for v in _VIEW_MIXING_FULL_BODY_VERBS), window_text == trigger.lower(), kw.lower() in prompt_lower
  - why: The script uses blind substring matching and case-insensitive comparisons to determine if a prompt violates visual rules. This logic cannot distinguish between intended character actions and incidental mentions of keywords in the prompt text.
  - fix: Replace keyword-based detection with an LLM-based judge that can understand the relationship between character IDs and their described poses/framing.

## `scripts/canary/g4_6_label_routing_face_substring_fix.py`

- `54-56` **P1 / semantic_string_judgment**
  - evidence: if "face framing" not in label.lower():
  - why: The test confirms that the underlying routing logic (resolve_ref_roles) is sensitive to specific visual keywords like 'face framing' within natural language labels, leading to misclassification of reference roles (background vs. character).
  - fix: Replace substring-based routing in the prompt service with structured metadata or explicit role enums that are independent of the visual description text.

- `60-66` **P2 / schema_or_enum_drift**
  - evidence: if not any("BACKGROUND from a previous shot (SAME ROOM)" in r for r in res.ref_roles):
  - why: The routing validation relies on matching long natural language strings rather than stable enum constants. This makes the pipeline fragile to minor phrasing changes in the prompt service or LLM instructions.
  - fix: Ensure resolve_ref_roles returns structured category IDs or enums instead of searching for natural language substrings in the output.

## `scripts/regen_phase91_with_model.py`

- `233-314` **P1 / semantic_string_judgment**
  - evidence: _CLOSE_FRAMING_RE.search(camera_direction)
  - why: Visual routing (deciding whether to include a background reference) is driven by a regex search on a natural language camera_direction string. This makes the pipeline sensitive to specific phrasing and prevents robust visual composition control.
  - fix: The staging or scenario analysis phase should emit a structured framing_type enum or a boolean is_close_up flag in the source of truth, which the image generation pipeline should consume directly instead of performing string matching.
