W21B-W7 — visual_continuity_anchor 1차 production 설계 범위 C+D
2026-06-12 · Claude 작성 · Codex 판정: APPROVED_WITH_NARROW_DECISIONS (6절 판정 로그) · 스펙 SOT = Codex PROP_ANCHOR_CANARY_REVIEW production 1차 가이드 8항목 · 본문은 판정 반영 완료본
0. 문제 정의 (1차 범위)
| 버킷 | 증상 (B-run 실측) | 스파이크 검증된 해법 |
|---|---|---|
| C | zoom 샷이 dep(wide) 샷과 같은 순간인데 pose/소품 모순 — 텍스트 pose-lock(W1)으로 보장 불가(사용자 확정) | 같은 순간 그룹에 visual anchor → wide 에 zoom 대상 실재 보장 → zoom 은 wide 이미지의 crop+i2i fill (독립 T2I 0) |
| D | printed prop canon 이 원문의 인물 구성 누락 + 크기 계약 0 → 본문↔ref 충돌 + 포스터화 | 원문 전체에서 printed_content 통합 추출(evidence) + physical_form + scale_contract → prop ref 프롬프트에 구조적 공급 |
B(VE/ref 부착), A(작문 staging)는 후속 wave — 이 설계 비범위 (Codex 가이드 1).
1. 신규 stage: visual_continuity_anchor
manifest 항목
"visual_continuity_anchor": {
"label": "시각 연속성 anchor (W21B-W7)",
"category": "analysis",
"order": 21.66, # episode_reference_policy(21.65) 직후 / scene_detail(21.70) 직전
"default_model": "gpt", # gpt-5.5 (스파이크 그대로)
"provider": "openai",
"depends_on": [
"scene_save", # 씬 원문 전체 (LLM 입력, 자르지 않음)
"shot_validator", "shot_selection",
"shot_dependency", # C seed: ref_usage=zoom_in_detail dep pair (18.1 SOT)
"shot_staging", # 멤버 샷 staging (LLM 입력)
"shot_director", # D seed: per-shot VE (prop 멤버십)
"entity_t2i", # 현 canon t2i_prompt (LLM 입력 — prop + 연관 인물)
],
"fan_out": False,
"applicability": "if_visual_continuity_anchor_enabled",
"step_type": "transform",
"lifecycle": "active",
"schema_version": 1,
}
- flag:
settings.visual_continuity_anchor_enabled(default False) →applicability.pyvalidator 등록. OFF 시 not_applicable cp 만, 기존 경로 영향 0. - 위치 근거 (가이드 2 해소): prop ref 프롬프트 텍스트 생성(entity_t2i=15)은 seed 가 필요한 shot_selection(15.5)보다 앞 → stage 를 15 이전으로 못 당김. 대신 immutable anchor manifest(21.66 cp) 저장 + 실제 ref 이미지 생성 ref_image_gen(23)이 manifest 를 읽음. 선례 = episode_reference_policy(21.65).
- shot_dependency_t2i(21.71) 관계: seed 는 18.1 hard dep SOT. 21.71 refined cp 존재(resume) 시 soft 우선 소비(order-robust degrade 선례). drift 는 diagnostics 만(비차단).
seed 탐지 (deterministic, LLM 0 — 가이드 3 "좁게")
- C seed (zoom_continuity) [판정 ①+W-A 개명]: v1 은 zoom_in_detail 만. exact same-moment(
exact_background)는 production 소비 없음 — diagnostics 후보candidate_same_moment_exact_background로만 기록. 추가 조건: source_wide still 실존 또는 같은 run 내 선생성 가능. - D seed (printed_prop) [판정 ④]: base = prop short_id 가 2개 이상 selected shots 의 VE 또는 required_refs 에 등장. framing 은 hard gate 가 아니라 priority score(scene_detail required_refs kind=prop soft 역참조=최강 신호 > staging framing structured enum). 의미 판단은 LLM — 코드 단어 regex/substring 판별 절대 금지. cap 초과 시 score 순 선별.
- cap: per-episode LLM 콜 cap(기본 8 그룹 제안). 초과 seed 는
skipped(reason="cap")진단 — silent drop 금지 (bg_space_partition 선례). - seed 0 → groups=[] 빈 manifest 정상 완료.
LLM anchor 추출 (그룹당 1콜, gpt-5.5)
- 입력(자르지 않음): 멤버 샷들이 속한 씬 원문 전체(여러 씬이면 전부) + 멤버 description/staging + 기존 t2i_prompt + (D) prop·연관 인물 canon t2i.
- C = 스파이크1 ANCHOR_SYS 포팅: locked_elements(evidence_quote+confidence) + wide_shot_contract + "zoom focal subject 는 wide contract 에 반드시 존재" + no invention.
- D = 스파이크2 ANCHOR_SYS 포팅 + generic 화(photograph 고정 표현 제거 — printed/displayed content 를 가진 물리 prop 일반).
- 가이드 7: D 프롬프트에 "문구 자구 고정 금지 — printed content 의 구조(장소+인물 구성)만 고정" 명시.
- 가이드 6: canon t2i_prompt 수동 패치 없음 — extractor 가 원문에서 통합해 manifest 로 공급.
output schema (immutable manifest cp — 가이드 4 "최소")
{
"schema_version": 1,
"groups": [{
"group_id": "vca-<scene>-<type>-<n>",
"anchor_type": "zoom_continuity" | "printed_prop",
"members": [{"scene_index":12,"shot_index":7,"role":"source_wide"},
{"scene_index":12,"shot_index":12,"role":"zoom"}],
"locked_elements": [{"kind":"subject_pose|held_prop|prop_state|surface_state",
"description":"...","evidence_quote":"...","confidence":"high|medium|low"}],
"wide_shot_contract": ["..."], // zoom_continuity 만
"prop_anchor": {"prop_short_id":"P##", // printed_prop 만
"printed_content":"...","physical_form":"...","scale_contract":"..."},
"per_shot_consumption_hints": {
"12:7": {"include_in_wide": true},
"12:12": {"crop_from_source": true},
"25:4": {"keep_real_scale": true}}
}],
"diagnostics": {"seeds_detected":0,"groups_extracted":0,
"skipped":[{"seed":"...","reason":"cap|llm_error|join_missing"}],
"ref_usage_source":"shot_dependency|shot_dependency_t2i"}
}
validator (얇게 — 가이드 5)
deterministic = schema parse + 조인 무결성만(members 좌표 실존 / prop_short_id 실존 / evidence_quote 비공백 / crop_from_source 멤버에 source_wide 존재). 의미 게이트 없음 — 품질은 diagnostics + review 갤러리(checkpoint dir review_html/, geometry_readback 선례) + 육안.
2. Consumers (모두 같은 flag 뒤, OFF 시 byte-identical)
D-① ref_image_gen(23) — reference image generation prompt overlay (entity_t2i 수정 아님)
- 조인점:
reference_phase1_service.py_gen_ref— 현재t2i = entity.get("t2i_prompt") or ...(L105). - printed_prop anchor 보유 prop 이면 deterministic overlay 조립(LLM 재호출 0): anchor 의 printed_content/physical_form/scale_contract 가 우선하되 기존 canon t2i 를 버리지 않고 스타일/맥락 유지 + original canon 은 provenance 기록 (Codex note). manifest 로드는 orchestrator(ctx) 1회.
- 기존 ref 교체는 force 시에만 — resume 정책 불변.
D-② scene_detail(21.70) + attach 라벨 — scale 계약
scene_detail.depends_on+=visual_continuity_anchor(ordering 만 강제 — producer not_applicable 이어도 동작, 선례 있음). 해당 샷 LLM 컨텍스트에 anchor 요약+scale_contract 주입.- 이미지 생성 시 prop ref 라벨(
scene_reference_service)에 keep_real_scale 샷 한정 scale 문구 1줄. - [판정 ③] scene_detail cp shape 불변 → schema bump 불요 / config drift 필요: config_hash 에 flag + anchor manifest stamp(schema_version+group_count+digest). flag ON+groups present 면 hash 변경 → resume 이 no-anchor 결과를 재사용 못 함. OFF/empty 시 기존 prompt byte-identical 목표.
C-① scene_detail — wide 계약 주입
source_wide 멤버 t2i 작문 시 wide_shot_contract + locked_elements 컨텍스트 주입 — zoom focal subject 가 wide 프레임에 실재(스파이크1 검증).
C-② zoom 렌더 경로 — crop + i2i fill (스파이크1 ③ 포팅)
- crop_from_source still: 독립 T2I 대신 ①source_wide primary 이미지 로드 ②VLM bbox(gpt-5.5 vision, focal subject 는 locked_elements 에서) ③16:9 확장 crop(중심 유지+클램프, ×1.15) → upscale ④gemini i2i fill(위치 불변+디테일 보강, prop ref 동반, PromptSanitizer 재사용).
- [판정 ②] 분기 위치 = scene_image_pipeline 내부 공통 still 생성 경로 (still 생성 직전 crop_from_source hint branch). post-pass 금지(primary/retry/단건 regen 경로 drift 전례) — gallery 생성용만 허용. batch 와 단건 regen 이 같은 helper(예: generate_continuity_crop_still) 호출.
- 비차단 fallback: source 부재 / bbox not found / i2i 실패 → 기존 T2I + diagnostic. step 은 pass 처리하되 canary acceptance 에서는 실패로 간주. (composition/pose anchor 이지 "완전 픽셀 lock" 아님.)
- 순서 보장: source_wide 를 zoom 보다 먼저(그룹 위상 정렬). W-C 진입 전 scene/batch order·still overwrite 정책 read-only pin 의무.
3. wave 분할 (1차 안에서)
| wave | 내용 | canary |
|---|---|---|
| W-A | stage 본체 (seed join + LLM 추출 + manifest cp + validator + review 갤러리 + flag) | 금월도 PID step 단독 실행 → manifest/갤러리 육안 (S12 C-그룹, P02 D-그룹 재현 기대) |
| W-B | D 배선 (ref_image_gen 보강 + scene_detail/라벨 scale) | P02 ref 재생성 + S25/S29 sh4 단건 regen → 스파이크2 동등 |
| W-C | C 배선 (scene_detail wide 계약 + zoom crop/i2i-fill 경로) | S12 sh7 재생성 → sh12 crop 경로 → 스파이크1 동등 |
각 wave: 구현 → Codex 리뷰 → canary 육안 → 사용자 GO 후 다음. 비용: wave 당 LLM 수콜 + 이미지 수장(소액 자율 범위).
4. 테스트 (핵심 계약 최소만)
- W-A: seed 조인 1건 + schema parse/조인 무결성 1건
- W-B/W-C: flag OFF byte-identical 각 1건 + fallback 비차단 1건
- LLM/이미지 결과물은 deterministic 테스트 비대상 — canary + 육안 (★★★★ 절대 규칙)
5. 열린 결정 4 — 판정으로 해소 (본문 반영 완료)
- C seed 폭 → zoom_in_detail 만
- C-② 분기 → scene_image_pipeline 내부 공통 경로, post-pass 금지
- scene_detail → schema bump 불요 / config drift 필요
- D seed → repetition base + priority score + cap, regex 금지
6. Codex 판정 로그 (2026-06-12)
VISUAL_CONTINUITY_ANCHOR_DESIGN_REVIEW: APPROVED_WITH_NARROW_DECISIONS — 전체 방향 승인(immutable manifest 판단 정확, P02 수동 패치 금지·C+D 한정 유지).
- D consumer 는 "entity_t2i prompt 수정"이 아니라 reference image generation prompt overlay.
- D overlay 시 기존 canon t2i 보존(provenance) + anchor 우선 조립.
- C crop path: W-C 전에 scene/batch order·overwrite 정책 read-only pin.
- review gallery 는 W-A 부터 필수 — anchor JSON 만 보면 pass 착각.
- wave gating: W-A 구현 진입 승인 / W-B 는 W-A 갤러리에서 S25/S29 anchor 재현 확인 후 / W-C 는 W-B 와 같은 commit 금지.
7. 명시적 비범위
- B(VE staged 인물 누락→ref 미부착) / A(작문 staging 광학모순) — 후속 wave. W2 backstop 불활성 유지.
- 혈흔 moderation 옅음 / 간판 문구 자유 발명(의도된 비고정) — 후속 조정 과제.
- W1 변경분(scene_reference_service/prompt_service + 테스트 2) 커밋 그룹핑 — 사용자 GO 별도.
8. Codex W-A 판정 로그 (W_A_STAGE_REVIEW)
APPROVED_FOR_WB_D_ONLY / C_PATH_NEEDS_NARROW_BEFORE_WC
- W-B(D) 진입 승인 — vca-p02-prop 조건 충족. W-B commit 은 D 전용(C 와 분리). pass 판단은 이미지 before/after 갤러리로.
- W-C 는 NOT YET — fresh-run ordering: canary C groups 는 기존 refined cp 덕분, fresh run 첫 pass 는 C seed 0. W-C 전 narrow(C1 resume/repair 한정 / C2 새 deterministic 신호 / C3 C anchor 별도 step 분리) 결정 필요. 권고=W-B 먼저.
- 개명 반영: immobile_pose →
zoom_continuity(seed 유지+이름 변경). - cap 공정성 반영: D 예약 슬롯 default 2 + skipped reason=cap_after_priority_score+score.
- commit caveat: "C groups are canary from existing refined cp; fresh-run C path not yet proven".
9. W-C narrow 설계 (실측 기반 — Codex 합의 대기)
실측 3건: ①C2 신호 기각 — 18.1 무신호 + based_on_beat 평가 TP1/FP5/FN6 (zoom 은 beat 직교) ②image phase 시점엔 refined cp 항상 존재(21.71<22) — 문제는 anchor 추출 시점(21.66)뿐 ③렌더 배치=still 단위 ThreadPool 병렬이지만 build_scene_dependency_graph+topological_sort_scenes 기존 메커니즘 존재.
판정: C1=fresh 효과 0 / C2=데이터 기각 / C3 권고 — C anchor 를 별도 step 분리.
- 신규
zoom_continuity_anchor(21.73) — t2i_review 직후/image 전. hard dep=shot_dependency_t2i(fresh-run proof)+scene_detail+t2i_review. 기존 seed/provider 재사용 + 스파이크1 ② wide 재작문(revised_wide_t2i) 산출. flag 별도(default OFF). 21.66 은 D 전용으로 좁힘(SOT 1곳). - C-① = 이미지 시점 substitution: source_wide still 생성 시 revised_wide_t2i 사용 (scene_detail cp 불변, prompt_used 로 추적) — fresh 1-pass 에서 wide 계약 충족.
- C-② crop/i2i: 공용 helper, 순서 보장=기존 dep graph 에 (zoom→source) edge 추가만. 비차단 fallback.
- wave: W-C1(step+D 전용화)→육안→W-C2(렌더 배선). W-B 와 commit 분리.
Codex 의견 요청: ①revised_wide_t2i substitution 의 cp↔프롬프트 분기 허용 ②21.66 D 전용화(직전 커밋 변경) ③crop i2i 모델 구성 유지.
10. Codex W-C 판정 + W-C1 결과
APPROVE_C3_VARIANT_WITH_CONTRACT_GUARDS / APPROVED_FOR_WC1_ENTRY — ①substitution 허용=image-phase prompt override 명시(cp 불변+prompt_used 실사용+provenance hash)+안전안(새 토큰·ref 요구 금지) ②21.66 D 전용화 동의 ③crop 구성 유지+단계별 artifacts 의무+dep edge=zoom→source+race guard.
W-C1 완료: zoom_continuity_anchor(21.73, hard dep=21.71→fresh-run proof, flag OFF)+토큰 audit+provenance. canary 7/7·audit 위반 0. 갤러리 8896/geom_zca_wc1. W-C2 는 canary 검토 후.
11. W-C2a 결과 (Codex APPROVED_TO_COMMIT_WITH_BATCH_GUARDS)
단건 경로 배선 완료 + S12 canary 성공(sh7 override 실증, sh12=crop/i2i-fill viability ok·fallback 0 — "팔이 너무 나왔어" 픽셀 해소). 갤러리 8896/geom_zca_wc2. W-C2b 가드: S12 batch 재현 먼저·dep edge=zoom→source·fallback=acceptance 실패·focal 은 artifact 판정·동일 provenance·call cap 확인.
12. W-C2b 결과 (Codex APPROVED_TO_COMMIT_WITH_RANGE_REVIEW_BEFORE_PUSH)
batch 배선(dep edge zoom→source+barrier race guard+override/crop 동일 provenance) + S12 batch canary 성공(sh12=sh7 확대, viability ok, fallback 0). call cap: i2i=gemini cap 적용, VLM bbox=group_cap 8 bounded. 확장 가드: S7/S20(close source) 분리 먼저, acceptance=fallback 0+로그+timestamp+artifacts+육안. push 전 W-C1~W-C2b range review.
13. 7그룹 확장 + concurrent DB fix (Codex APPROVED_TO_COMMIT_NARROW)
7/7 crop path produced — 5 ok + 2 weak_zoom observed(분리 표기). weak_zoom=S16(0.955)/S20(0.836): source 가 이미 close — 코드 변경 없이 기록+육안(후속=soft rewrite hint 후보). fix=batch worker 의 db 조회 제거(scene_paths 맵에서 source bytes 주입). VLM hang=별도 carry(timeout 보강, 입력 축약 금지). 갤러리 8896/geom_zca_ext.
14. S29 subject gate + Cinematography 3축 (2026-06-12 후속)
실측: S29=무인물 wide 가 인물 zoom 의 source(상류 모순)→REWRITE 가 인물을 이름으로 주입→ref 미부착→얼굴 발명. zoom 인물 토큰 ⊄ source 프롬프트 그룹=S16/S20/S23/S29 — weak_zoom 2건과 정확히 일치. staging(camera_direction/framing/angles enum)은 REWRITE·crop 에 무반영 — 생존 3그룹 중 S7(정면→프로필)/S13(측면→정면)이 crop 으로 실현 불가한 앵글 전환, S12 만 합치.
설계(직접 재검토): ①S29 fix=VE 조인 대신 프롬프트 char 토큰 조인(VE 위반 검사 불변식 하에서 strictly 포함+ref 메커니즘 직결) — 전 variation 부적격=seed skip(zoom_subject_absent_in_source) ②REWRITE 에 "원본에 없는 인물 ID/이름/묘사 추가 금지" hard rule ③camera_relation(same_axis_punch_in/different_camera_same_moment/uncertain) anchor structured 판정 — punch-in 만 crop, 그 외 zoom 은 자기 camera plan t2i+locked weave(rewrite_zoom_prompts, 동일 audit)→기존 override 맵 소비(coordinator 무변경). 판정 기준은 "본질적 staging 위반 없는 crop 대체 가능성"으로 정밀화(1차 과판정 S12 교정).
canary: gate 제외 4 정확+생존 3 판정 ground truth 일치(S12=punch_in/S7·S13=different). 단건 regen 5 육안 전부 통과 — S29 외국인 해소(무인물 establishing 복원+동아시아 얼굴), S7/S13 camera plan 실현+continuity 유지, S12 crop 회귀 없음. 3533 green+신규 계약 테스트 2. 갤러리 8896/geom_zca_3axis.
15. P02 사진 단일 실물 전수조사 + fix (Codex APPROVED_TO_COMMIT_NARROW)
전수조사: 액자(P05/S18) 빼고 핵심 사진은 전부 한 장 P02(S12=S25=S28=S29, 원문 "바로 그 사진"). 누수 3건: S28sh5 VE 누락(ref 미부착→빈 종이)/S25sh7 손+벽 중복(bg ref 가 sh4 의 꽂힌 사진 운반)/마모 편차.
code fix: helper 확장 — prop_ref 라벨에 physical_form+동일 실물 identity 문장, previous_shot_same_room bg ref 의 metadata["ignore"] 에 stale 사본 무시(bg role 표기는 고정 문자열이라 ignore 채널이 유일 도달 경로 — 실측. ignore 미소비 role 은 set 에서 제외+negative test). 운영 데이터 수습(코드 아님, 분리 기록): S28sh5 shot_director VE 수동 보정(+21.66 force 로 anchor membership 회복)+redo-shot invalidation 이 삭제한 하류 cp 5개 archive 복원+step_run 원복. 육안: S25sh7 중복 완전 해소+붉은 원 정합, S28sh5 동일 실물 교정. 갤러리 8896/geom_zca_3axis/p02_gallery.html. caveat: shot_dependency_t2i 의 S28sh5 ref_usage 구프롬프트 기준(경미)/ignore 채널 role 확장은 prompt_service 출력 추가+테스트 후에만.