Draft v1 - 2026-05-22 - read-only analysis plus implementation plan

C10 Screen Presence Reconciliation

이 문서는 S15_Shot5에서 드러난 visible_entity_idsshot_staging.character_angles의 발산을 C10 장기 방향과 연결해 정리한다. 목적은 당장 막힌 scene_detail contract violation을 작은 실험으로 해소하면서, 향후 중간 상태 구조화와 agentic editing layer가 어떤 데이터 모델을 필요로 하는지 판단하는 것이다.

Executive Verdict

Phase 0 + Phase 1을 먼저 진행하는 방향은 맞다. 단, 이번 작업은 새 schema를 먼저 추가하는 C10 본체가 아니라 "기존 구조 신호를 이용한 deterministic reconciliation" 실험으로 제한한다.

즉시 수정의 핵심은 다음 한 줄이다.

C## is in shot_director.visible_entity_ids
AND shot_staging.character_angles is non-empty
AND C## is absent from shot_staging.character_angles
AND C## is not the POV character
AND camera_direction has explicit off-screen language
=> downgrade that subject's identity policy to generic_descriptor_allowed inside build_render_prompt_card()

Name proximity near the off-screen phrase is confidence/provenance only, not a hard gate.

이 방식은 C01을 강제로 T2I prompt에 넣게 하지 않는다. 대신 "후보 집합에는 있으나 실제 프레임에는 없는/부재로 연출된 인물"로 조정해, LLM과 validator가 같은 정책을 보게 한다.

Observed Failure

Item Evidence Meaning
Failed step scene_detail, S15_Shot5 LLM omitted C01, validator raised subject_reference_policy.base_id_missing.
shot_director visible_entity_ids=["C02","C01"], description says Hyesu shouts toward Suriyoung's back. C01 was treated as part of the shot-level subject set.
shot_staging camera_direction says "off-screen direction where 수리영 has run" and "the absence". Later staging describes C01 as absent/off-screen, not drawable foreground/background identity.
character_angles Only C02/Hyesu appears. C01/Suriyoung is absent. Given schema wording, membership is the usable in-frame signal.
subject_reference_policy [] Falls back to DEFAULT_POLICY=id_and_outlook_required, so C01 base ID becomes mandatory.

Operational note: current diagnosis must use live DB/checkpoints/artifacts specified by the run. Local SQLite files are not a source of truth for this project unless explicitly stated otherwise.

Code And Prompt Evidence

Evidence Path Impact
Default subject policy backend/app/core/subject_reference_policy.py:28 Missing policy defaults to id_and_outlook_required.
Generic policy behavior backend/app/core/subject_reference_policy.py:53-55 generic_descriptor_allowed disables base/outlook requirements.
Forward base-ID validator backend/app/core/visible_entities_validator.py:469-488 Raises only when the subject's policy has base_required=True.
Canonical-name validator backend/app/core/visible_entities_validator.py:530-557 Even after downgrade, using "수리영" without an ID can still fail. Phase 1 must account for this.
Card builder choke point backend/app/core/steps/render_prompt_card.py:3514-3539 Policy override belongs before normalize_subject_reference_policy_items().
Name map threading gap backend/app/core/steps/render_prompt_card.py:3451-3475 build_render_prompt_card() currently has no name_by_short_id input, so Phase 1 must thread the map through card inputs.
Name map source backend/app/core/steps/scene_context_loader.py:71-72 SceneContextLoader already prebuilds ctx.name_by_short_id, so no worker-thread DB query is needed.
Asset requirements consumes policy map backend/app/core/steps/render_prompt_card.py:3569-3577 Override before this point keeps reference requirements aligned.
Shot staging schema prompts/_base/shot_staging/15.202605201730/schema.json:21-45 character_angles is for visible characters, excluding POV.
Gaze off-screen is not visibility prompts/_base/shot_staging/15.202605201730/schema.json:30-37 off_screen means eye direction outside frame, not subject outside frame.
Current Path 1 miss backend/app/modules/pipeline/shot_visibility.py:316-395 Requires looks_at_character and gaze_target_id, so S15 misses.
Current Path 2 only logs backend/app/core/steps/scene_context_loader.py:493-504 S15-style proximity drift is diagnostic only and cannot reconcile policy.

What Must Not Be Done

Immediate Files