shot_projection_card — production wiring brief

TheRoad Scene Lab · W21B-wave-4 · 2026-05-30 · Claude 초안 → Codex cross-review 합의 반영

DRAFT v0 DOC ONLY — 코드/DB/render 변경 0 design brief = why/schema SOT

이 문서의 위치. shot_projection_card왜 / schemadocs/w21b-wave4-shot-projection-card-20260530/index.html (design brief v0, §1~§10 lock)이 SOT다. pack(prompts/_base/shot_projection_card/1.202605302212/)·dry A/B/C·real-BG E2E(b2)·사용자 육안(8797 "fp랑 배경 정합 좋아졌어")까지 PASS했다. 본 문서는 그 위에서 "정확히 어느 파일 / contract가, 어떤 순서·acceptance로 바뀌는가"만 다루는 production integration blueprint다. 여전히 코드/DB/API/render 변경은 0이며, 변경의 명세만 동결한다.

1. Scope & non-goals

Scope: shot_projection_card를 production 파이프라인에 default-OFF로 끼워넣기 위한 step 등록 / config / manifest / contract delta / cache / acceptance matrix / rollout 순서.

2. Wiring anchor inventory (실측)

변경 대상 파일과 그 성격. order/flag는 backend/app/core/step_manifest.py·config.py grep 실측.

파일변경commit
backend/app/core/steps/shot_projection_card_step.py신규 step (semantic_readback_step.py 패턴 미러). SCHEMA_VERSION/PROMPT_VERSION 상수 + provider 호출 + validator.C2
backend/app/modules/pipeline/shot_projection_card.py신규 순수 로직: card envelope 조립 / source_hash / deterministic gate / leakage check.C2
backend/app/modules/pipeline/shot_projection_card_provider.py신규 real VLM provider(default 미사용; _real_provider_enabled gating).C2
backend/app/core/step_manifest.pycard entry order 21.593 추가(semantic 21.591 < card < plan 21.595).C2
backend/app/core/config.py3-flag 추가: shot_projection_card_enabled=False / shot_projection_card_real_provider_enabled=False / shot_projection_card_prompt_version="1".C2
backend/app/core/steps/__init__.pyregistry 등록("shot_projection_card": ShotProjectionCardStep).C2
shot_aware_bg_render_plan_step.py + plan moduleplan vNext: card-aware fields 추가, camera_decision demote(§5).C3
background_prompt step/moduleanchor card bg_plate_visible_description 주입 consumer(§6).C4
scene_detail step/module같은 card scene_visible_description + card_hash 소비(§7).C5+

현 manifest 순서 (실측 order): floor_plan_prompt 19.61 → floor_plan_render 21.55 → overlay_payload 21.57 → base_location_dossier 21.58 → geometry_readback 21.59 → semantic_readback 21.591 default OFFshot_projection_card 21.593 (신규) → shot_aware_bg_render_plan 21.595 → background_prompt 21.60 → background_render → scene_detail 21.70.

3. Step A 등록 spec — shot_projection_card

항목
step idshot_projection_card
order21.593 — semantic_readback(21.591) 이후 / plan(21.595) 이전 (design brief §10 결정1)
defaultOFF — 3-flag 전부 false/"1". 첫 land=dry/schema only, real VLM은 explicit force/cap(기존 wave 패턴)
granularity(bg_id, shot_id) per-shot(design brief §4.1)

3.1 의존성 — hard dep vs optional gate (Codex 보강 #1)

입력성격없을 때
floor_plan_render (detailed FP PNG)hard dep — BG visual anchor / substratecard 생성 불가 → skip
floor_plan_overlay_payload (번호/label legend)hard dep — VLM 입력 legendcard 생성 불가 → skip
base_location_dossierhard dep — expected_label SOTcard 생성 불가 → skip
floor_plan_geometry_readbackhard dep — marker grid sanity(deterministic grounding)card 생성 불가 → skip
floor_plan_semantic_readbackoptional gate — enabled면 gate 입력, disabled면 pass-throughnot hard dep. disabled → semantic_gate_state=not_available
floor_plan_prompt.camera_recommendationshard dep — pose 후보(VLM 선택·서술, 생성 아님)card 생성 불가 → skip
light_fp analysis rastersubstrate(있으면 grounding↑)detailed FP fallback + confidence downgrade/needs_review(design brief §10 결정5)
semantic gate 소비 규칙 (design brief §10 결정1 재확인): semantic enabled & state=needs_fix(FP가 dossier에서 drift) → card fail-closed(§9). enabled & pass/needs_review → 통과(needs_review는 diagnostic). disabled → semantic_gate_state=not_available, hard 전제로 쓰지 않음.

3.2 fp-less BG (Codex 보강 #1)

fp-less BG(direct-plate / exterior, 예: L04B02·L09B04·L09B05·L15B02)는 card 대상이 아니다. projection_card_state = not_applicable로 기록하고 기존 plate-only / direct path로 빠진다. 이는 card 실패가 아니다 — §9 acceptance matrix에서 별도 행으로 취급.

3.3 버전 sync 의무

step의 SCHEMA_VERSION ↔ pack schema.json, PROMPT_VERSION ↔ pack dir(1.202605302212) 동기. semantic_readback_step이 manifest 주석에 명시한 sync 의무와 동일 패턴.

4. Cache / source_hash 구현

2-pass로 VLM 콜이 늘어나므로 cache가 필수다. active 21 전부가 아니라 변경된 FP/BG부터 재실행할 수 있어야 한다(design brief §6).

source_hashes = {
  fp_render_hash,            # detailed FP PNG
  substrate_hash,           # light_fp (or "not_available")
  overlay_hash,
  geometry_hash,
  semantic_hash,            # or "not_available"  (gate disabled 시)
  camera_rec_hash,
  shot_context_hash,        # ★ raw text 아님 = normalized (shot text/shot_guides/visible_entities)
  prompt_version, schema_version, model, provider
}
card_cache_key = hash(source_hashes + bg_id + shot_id)
항목결정
shot text 포함?YES — 정합 SOT이므로 입력 변경이 card를 무효화해야 함(design brief §10 결정3). 단 raw 금지, shot_context_hash로 normalize.
invalidation trigger위 source_hash 中 하나라도 변경 → card 재생성. prompt/schema version bump도 trigger.
changed-only reruncache hit이면 VLM 콜 skip, 기존 card envelope 재사용.
저장 위치semantic_readback sidecar/cache 패턴 미러(구현 세부는 C2에서 확정). card envelope이 provenance(card_id/hash/state) 포함.

5. Plan vNext (B) — contract delta · demote, NOT delete

shot_aware_bg_render_plan(21.595)는 카메라 결정에서 손 떼고 reference graph / reuse / render_action 전역 결정만 한다. 단 v0에서 기존 필드를 삭제하지 않는다.

제거-금지 목록 (blast radius 차단, Codex 보강 #2)

5.1 추가 필드 (최소)

필드의미
anchor_shot_idplate별 대표 shot. background_render가 이 shot의 card만 주입(sibling은 diagnostic).
projection_card_id주입할 anchor card 식별자.
projection_card_hash소비자(C/D)가 같은 card 따르는지 검증용. 불일치 → diagnostic/fail-closed.
projection_card_statepass | needs_review | blocked | not_applicable(fp-less).
projection_card_fallback_reasonfail-closed 시 사유(low_confidence / missing_inputs / semantic_needs_fix / stale / leak / contradiction).
projection_card_source_bg_idreuse 상속 시 실제 픽셀을 만든 target bg_id(=reuse_target_bg_id). non-reuse면 self.
projection_card_inheritedtrue면 이 plate가 target anchor card를 상속한 reuse(§8 decision-lock).

planner 주 역할 = reference graph / reuse / render_action + 어떤 card를 같은 plate로 묶을지 / anchor 선택. camera_decision은 demote된 audit/compat field.

6. background_prompt vNext (C) — consumer

항목내용
주입 대상plate의 anchor shot cardbg_plate_visible_descriptionplate-only(base 구조/고정 가구/재질/조명/framing만, transient 제외).
주입 방식card prose를 BG t2i_prompt에 자연스럽게 통합(design brief §3.1 C). full scene_visible_description은 BG에 쓰지 않음(transient 누수 방지).
leakage guardinternal token(marker 번호 / 영어 enum literal / card_id) exact 누출 0 검사(design brief §5.1). 위반 시 fail-closed.
fail-closedcard blocked/stale/leak/semantic_needs_fix → card 주입 안 하고 기존 v10 prompt path로 fallback(design brief §5.2). image 검증 완료된 v10이 안전망.

7. scene_detail / I2I (D) — 같은 card 소비

BG와 최종 scene t2i가 같은 shot contract를 따르게 하는 정합 SOT 단계.

항목내용
소비 필드scene_visible_description(FULL — base + transient 모두) + card_hash.
정합 검증scene_detail의 card_hash가 BG가 쓴 anchor card_hash와 같은지 확인 → 같은 SOT 보장.
phase 분리scene_detail consumer는 C5+ 별도 phase. BG path(C2~C4)가 안정된 후 land(Codex 보강 #4).

8. Edge cases

edge처리
fp-less fallbackprojection_card_state=not_applicable → plate-only/direct path. 실패 아님(§3.2).
same-space / reuse (L20 edge)W21B-w3 reuse alias 유지 → image call 0. ★ decision-lock(v0, Codex review): reuse plate는 target anchor card를 상속한다(별도 card 안 만듦). 실제 픽셀을 만든 건 target이므로 provenance도 target을 가리켜야 함. enum 안 늘리고 projection_card_state=pass + projection_card_source_bg_id=reuse_target_bg_id + projection_card_inherited=true 기록. child shot 자체의 scene_visible_description card는 scene_detail/I2I용 diagnostic로만(BG plate block 조건으로 쓰지 않음 — image 0이 W21B-w3 contract 핵심).
transient splitcard schema가 marker_layer(base/transient/ignored)를 echo. C(BG)=base-only(bg_plate_visible_description), D(scene)=full(scene_visible_description). 코드가 prose를 slice하지 않음 — VLM이 layer 알고 분리 작성(schema §3b).
multi-shot BG anchor 선택plan vNext(B)가 plate별 anchor 1개 선택. sibling card는 compatibility diagnostic(§9).
sibling diagnosticanchor 아닌 shot card는 BG 주입 안 함. anchor와 모순되면 diagnostic 기록(v0 block 아님).

9. Fail-closed & acceptance matrix (path별, Codex 보강 #3)

입력 조건card_stateBG path
card pass + anchor selected + leak 0 + hash matchpassbackground_prompt vNext path (card 주입)
card blocked / missing / stale(hash mismatch) / leak / semantic needs_fix / self_consistency=contradictoryblockedv10 fallback (검증된 기존 prompt path). fallback_reason 기록. v0=fail-closed
card 생성됐으나 confidence 낮음 / semantic needs_reviewneeds_reviewv0=diagnostic only(block 아님). card 주입하되 needs_review 플래그. 후속 hard gate에서 강화
fp-less BGnot_applicabledirect/plate-only fallback. card 실패로 취급 안 함
sibling-only fail(anchor는 pass)anchor=passBG plate block 금지. sibling은 diagnostic only
same-space reuse (decision-lock: 상속)pass + inherited=trueimage call 0 유지. projection_card_source_bg_id=reuse_target_bg_id provenance 기록(§8)
단계화(design brief §5): v0 첫 land = deterministic hard(card present / hash match / leakage 0 / no-missing) + diagnostic(품질 위반 → needs_review). must_show/must_not_show hard gate는 dry/E2E 안정 후 후속.
contradiction 분류(Codex review 반영): VLM self_consistency=contradictory self-report는 blocked → v10 fallback(prose가 structured와 모순이면 BG에 주입 금지, D dry/validator sketch 기준). confidence 낮음·semantic needs_review만 needs_review diagnostic. 코드 레벨 deep contradiction 검증은 후속.

10. Rollout sequence — commit boundary (Codex 보강 #4)

commit내용테스트
C1doc-only wiring brief (본 문서)
C2step/config/manifest registration default OFF + card module + provider(미사용)deterministic validator tests(envelope shape / source_hash / leakage / gate)
C3plan vNext anchor fields(anchor_shot_id 등) + camera_decision demotedry no-real-call tests(plate grouping / anchor 선택 / reuse 상속 결정)
C4background_prompt vNext consumer + fail-closedleakage / fallback(v10) tests
C5+scene_detail / I2I consumer (별도 phase로 분리 가능)card_hash 정합 tests

11. 시나리오 leakage 금지 증명