
    7jO                       U d Z ddlmZmZmZmZ g dZ edh      Zee	d<   i ddddd	d
g ddddd
ddddd	d
g ddddd
dddddd
dgdddddddddddd
g ddddd
ddddd d!dgddddddd"d#dd$dd
dgd%d&dd'd(d)d*d+dd,d-d-dgddddd
d.d/dd0d d!d*dgddddd
d1d2dd3dd
g d4d%dddd
d5d6dd7d8d
g d9d%dddd
d:d;dd<d8d
g d=d%dddd
d>d?dd@d8d
d:gd%dddddAdBdCdDddEd d!g dFddGddd
dHdIddJd d!dCgddGddd
dKdLddMd d!g dFddGddd
dNdOddPd8d
dKgddGddd
dQdRddSd d!g dFddGddd
i dTdUddVd8d
dQgddGddd
dWdXddYd d!dZgddddd
d[d\dd]d d!g d^dd_ddd
d`dadd]d d!g d^ddbdcdd%dddedfddgd d!dZd[gddhdd_dddidjdkddld d!degddhdd_dddidmdnddodd
g dpddhddbdddidqdrddsd d!g dtddhddudddidvdwddxdd
dWdegddddd
dZdyddzd d!g d{ddddd
d|d}dd~d d!dvgddddd
ddddd8d
d|gd%ddddddddddd
d>gd%dddd
ddddd8d
d*dgddddd%dddddd d!dg ddddddddddd8d
dgdd&dd'dd)ddddd d!g dddddd%ddi ddddd8d
ddgd%ddd'dd)ddddd d!dgdddd'dd)ddddd d!ddgd%dddd
ddddd8d
dgddddd%dddddd8d
dgddddd%dddddd8d
dgddddd%dddddsd8d
dgdd&dd'dd%dddddd d!g dddddd%d,dddddd d!d>dgddddd
ddddd d!g ddddd'd
ddddd8d
dg dddddd%ddddddd8d
dVg d¢d%ddddgd%ddĜdddddd
g dǢddddddddddd d!g dˢddddddgdd͜ddddd d!g dѢddddddddddd d!g d֢ddddddddddd d!g dۢddddddi ddddd d!ddgddddddddddd d!g ddddddddddddd d!g ddddddddddddd d!g dddddddddddd d!g dddddd$dddddddg dddddd,dddddd d!g dddddddd dddd d!g dddddddddddd d!g ddddddddd	dd
dd!g dddddddddddd d!g dddddd
ddddd d!g dddddd$dddddd d!dg ddddddddddd d!ddgddddd
ddddd d!dgddddddd d!dd"d d!ddgddddddd#d$dd%d d!g d&ddddddi d'd(dd)d d!d#dgddddddd*d+dd,d d!d#dgddddddd-d.dd/d d!g d0ddddddd1d2dd3d d!g d4ddddddd5d6dd7d d!g d8ddddddd9d:dd;d d!g d<ddddddd=d>dd?d d!g d@dddddMddAdBddCd d!dg dDddddddEdFddGd d!g dHdddddddIdJddKd d!g dLddMdddgddNdOdPddQd d!g dRdddd'd
dSdTddUd d!g dVdddd'd
dWdXddYd d!dgd%d%ddd'dZd[d\dd]d d!ddgddddd
d^d_dd`dd
dgd%dddd
dadbddcdd
d^dgd%ddddd
dedfddgdd
dadgddddd
dhddid d!dg djddddddkddld d!dSdgdddd'd
dmddndodog dpd%dqdrdd
dsdtdudd
dsdvdwd d!dsdxdyd d!dsdzd{d d!dsd|d}d~ddsddd d!dsgdddddddd d!dgdd&ddd
dddd d!dgddddd
dZ
eeeeef   f   e	d<   dedeeeef      fdZdedefdZdedeeeef      fdZdedee   fdZdedee   fdZdedee   fdZdeeeef      fdZy(  u  파이프라인 Step Manifest v4 + shot-more — 49단계 정의, 의존성, 설정.

이 파일이 파이프라인의 단일 진실 소스(Single Source of Truth).
v4 + shot-more: beat→shot 기반 파이프라인.

정확한 실측 baseline은 `docs/architecture/_step_manifest.generated.md` 참조
(재생성 — 저장소 루트에서:
 `backend/.venv/bin/python backend/scripts/dump_step_manifest.py > docs/architecture/_step_manifest.generated.md`).

구성 (총 50, 2026-04-27 기준)
  - analysis: 42 (always 34, if_planning_doc 1, on_demand 4, disabled 3)
  - image:     6 (always 4, if_has_outlooks 1, on_demand 1)
  - auxiliary: 2 (on_demand 1, disabled 1)

Active (분석 실행 경로, 40): always 38 + if_planning_doc 1 + if_has_outlooks 1

applicability 종류
  - always: 항상 실행
  - disabled: 실험용/비활성
  - on_demand: 사용자 요청 시만 (project_summary 등)
  - if_planning_doc: 기획서 있을 때만
  - if_has_outlooks: 아웃룩 있을 때만

Phase 1 추가 필드 (01-principles-revised.md §4, §5)
  - step_type (실측 3종, 2026-04-22):
      transform (41): 체크포인트 → 체크포인트 (DB 쓰기 금지)
      asset (6): 파일 + DB 메타 (이미지 계열)
      editorial (2): 타 step 체크포인트 수정 (t2i_review, scene_verify)
    (설계 초안의 `projection` 타입은 별도 step_type으로 분리되지 않고
     Phase 2의 CheckpointSyncService 5-way 분해로 흡수됨. step은 여전히
     transform/asset으로 남고 projection은 sync 레이어 책임.)
  - lifecycle: active | deprecated | removed
      실측 2026-08-25: 총 84 — active 73, deprecated 10, removed 1.
      (종전 주석은 "active 42, deprecated 6, removed 1" 이었다. 「실측」이라
       적힌 숫자가 낡으면 그대로 믿게 되므로 세어서 고친다.)
      ★lifecycle 은 **표시**일 뿐 실행을 막지 않는다. 막는 것은
       `applicability == "disabled"`(8개)이고, 그 둘은 축이 다르다 —
       차이 3개(outlook_extraction·scene_cinematography·scene_split)는
       `on_demand` 라 **요청하면 돈다.** 스텝 목록을 API 에서 받아 순서대로
       돌리는 운전 루프는 lifecycle 을 따로 걸러야 한다(API 응답에 이 칸이
       없다). 안 거르면 대체된 옛 단계에 유료 호출이 나간다 — 08-25 실측:
       outlook_extraction 3회 6,264자.
  - resume_sensitive: resume 모드에서도 재실행 필요 (bool, 기본 False)
  - modifies_checkpoints: editorial만 사용. 자신이 덮어쓰는 타 step 체크포인트 목록
  - replaced_by: deprecated만 사용. 대체된 step_id
  - allow_partial_downstream: 본 step 의 ``partial`` 결과가 downstream 으로
      cascade 되어도 안전한지 (bool, 기본 True). False 시 downstream
      cascade stop — analysis_dispatch_service 가 batch 중단, check_gate 가
      blocked. partial 시 incomplete 데이터로 후속 step 진행하면 잘못된 결과
      (asset/entity 누락) 가 발생하는 step 에 명시 False. (problems.md #11 contract)

default_model 컨벤션 (problems.md #5)
  - **반드시 LiteLLM Router 에 등록된 alias** (예: ``"gpt"``, ``"gpt-mini"``,
    ``"gemini-pro"``, ``"gemini-flash"``, ``"gemini-lite"``, ``"gemini-image"``,
    ``"fal-ai"``) 만 사용. 실 model ID (예: ``"gemini-3.1-flash-lite-preview"``)
    는 사용 금지 — alias 가 router 에서 model ID 로 해소되며, alias 통일이
    UI/admin/runtime parity 의 근거.
  - ``llm_client.PIPELINE_STEPS`` 가 본 manifest 의 default_model 을 derived view
    로 build (#5: STEP_MANIFEST 가 single source of truth).

참조: docs/architecture-refactor-final/02-final-roadmap.md §Phase 1
    )AnyDictListOptional)
pendingblockedrunnablerunning	completedpartialfailednot_applicablestale	cancelled
entity_t2i_LEGACY_SCHEMA_BUMP_ALLOWLISTplanning_doc_analysisu   기획서 분석analysiszgemini-litegeminiFif_planning_doc	transformactive)
labelcategoryorderdefault_modelprovider
depends_onfan_outapplicability	step_type	lifecycletext_cleanupu   텍스트 정리   alwaysscene_segmentationu   씬 세그먼테이션   zgemini-flash)r   r   r   r   r   r   r   r    r!   r"   schema_versionepisode_summaryu   에피소드 요약   zgpt-minivisual_world_rulesu   시각적 세계관 규칙   gptopenaiscene_splitu   큰 씬 분할 (레거시)   T	on_demand
deprecatedzbeat_extract,shot_extract)r   r   r   r   r   r   r   r    r!   r"   replaced_by
scene_saveu
   씬 저장   -entity_character_listu    인물 리스트 (사전 추출)g      @scene_summaryu   씬별 요약 (병렬)   )r4   r)   r+   beat_extractu   Beat 추출 (병렬)gffffff@z
gemini-pro)r4   r+   r7   shot_extractu   Shot 추출 (순차)g@)r:   r+   r7   shot_validatoru   Shot 검증g      @allow_failed_validator)r   r   r   r   r   r   r   r    r!   r"   allow_partial_downstreampartial_override_config_keyentity_all_characteru   인물 리스팅   )r4   r+   r<   grounding_a0if_not_chunk_producerentity_extract_characteru   인물 추출	   entity_all_locationu   배경 리스팅
   entity_extract_locationu   배경 추출   entity_all_propu   소품 리스팅   entity_extract_propu   소품 추출   entity_relationu   요소 변형 관계 추출g333333+@entity_mergerB   u   고증 후보 수집g      @)r4   r+   r<   if_grounding_v2grounding_chunku   고증 구간 판독 (C(c))if_chunk_producerllm)r   r   r   r   r   r   r   r    r!   r"   resume_sensitivegrounding_planu   고증 후보 분류·계획gL+@allow_missing_grounding)r   r   r   r   r   r   r>   r?   r   r    r!   r"   grounding_researchu#   고증 조사(출처 붙은 claims)gףp=
W+@grounding_screenu   참조 획득 의무 판별gRQ+@)rO   rB   rQ   r+   reference_acquisitionuD   참고 사진 획득 (검색 → 이미지 검색 → 종류 선택)gL3@)entity_filterrX   outlook_phase3if_grounding_referencerZ   u   저빈도 요소 필터링gffffff+@u   요소 중복 병합g      +@)rD   rH   rL   r8   r+   rQ   entity_detailu   요소 상세 + enum   u    요소 T2I 프롬프트 (병렬)   shot_selectionu   중요 샷 선택 (병렬)g      /@scene_directoru   씬 감독 (물리적 존재)   )r   r   r   r   r   r   r   r    r!   r"   #requires_projection_sync_before_runshot_directoru   Shot별 VE 판정g     0@)ra   r`   rN   r<   )r   r   r   r   r   r(   r   r   r    r!   r"   scene_cinematographyu   촬영 감독 (레거시)   shot_stagingscene_camera_flowu   씬 카메라 플로우g1@)r<   r`   ra   rO   r4   shot_cinematographyu"   Shot별 촬영 기법 (deprecated)g1@disabledscene_dependencyu*   씬 연관 분석 (레거시 — disabled)   shot_dependencyu   Shot 연관 분석 (병렬)g2@outlook_phase1u   아웃룩 목록 추출   outlook_phase2u   아웃룩 씬별 매핑g3@r[   u   아웃룩 병합 정리g3333333@outlook_extractionu   아웃룩 추출 (레거시)z,outlook_phase1,outlook_phase2,outlook_phase3)r   r   r   r   r   r   r   r    r!   r"   r3   rc   u   촬영 연출 (DP)g     3@)r<   r`   r+   rO   rh   )r   r   r   r   r   r   r   r    r!   r"   rT   r(   shot_essence_extractionu   샷 essence 추출g333333@if_shot_essence_enabledlocation_floor_planu4   위치 도면 생성 (deprecated, Phase 7로 대체)imageg     5@)r<   r`   r4   rO   r+   ra   background_plannerassetscene_consistencyu   씬 시각적 일관성gfffff3@)rg   rd   rO   r<   r`   r:   r4   r+   )r   r   r   r   r   r(   r   r   r    r!   r"   rT   r>   scene_detailu   씬 상세 분석 (병렬)g333335@)
rm   rd   r[   r   rg   rx   rY   background_promptepisode_reference_policyvisual_continuity_anchorshot_dependency_t2i)r   r   r   r   r   r(   r   r   r    r!   r"   consumes_downstreamrc   r>   u   Shot 연관 재계산 (LLM)g(\µ5@)ry   rx   rg   
t2i_reviewu   T2I 프롬프트 검수gQ5@)r   ry   r<   rg   r+   rO   r]   	editorial)r   r   r   r   r   r   r   r    r!   r"   modifies_checkpointsr(   zoom_continuity_anchorz%zoom continuity anchor (W21B-W7 W-C1)g{G5@)r}   ry   r   r4   r<   r`   rg   !if_zoom_continuity_anchor_enabledoutdoor_site_layoutu'   야외 site layout 좌표 SOT (W21B-W8)g(\5@)	ry   r   background_classifyr}   r4   r<   r`   rg   rd   if_outdoor_site_layout_enabledoutdoor_place_specu,   야외 장소 마커 스펙 (W22 직행 ①)gQ5@)r   r4   ra   r<   r`   rg   rO   r+    if_outdoor_direct_or_map_or_laneoutdoor_place_canonu%   장소 캐논 자산 (W22 직행 ②)gHz5@outdoor_lane_planoutdoor_shot_groundingu%   야외 샷 grounding (W22 직행 ③)g
ףp=5@)r   r   r4   ra   r<   r`   rg   if_outdoor_direct_composeu(   야외 3레인 lane plan (설계 v2 ①)gfffff5@)r   r4   ra   r<   r`   rg   if_outdoor_lane_plan)r   r   r>   r   r   r   r   r   r    r!   r"   r(   outdoor_frame_modeu    레인2 구도 판정 (E2E6 ③))r   r   r4   r<   r`   rg   ra   if_outdoor_frame_mode outdoor_structure_form_referenceu>   야외 구조물 형태 참조 검색·선택 (Stage D 선행)g
ףp=5@)rY   r   r   r   rO   r4   r+   if_outdoor_lane_pipegenerateoutdoor_structure_seedu'   야외 레인2 구조물 seed (Stage D)gQ5@zgemini-imagegoogle)r   r   r   rO   r4   shot_ref_classifyr   r<   r`   rg   ra   r   u   샷 참조 분류 (레시피)gfffff5@)r<   r`   r4   ra   if_still_recipebackground_share_planu$   배경 공유 계획 (전체 지휘)gHz5@if_background_share_planshot_continuityu    샷 연속성 저작 (레시피)g)\5@)r<   r`   r4   rO   shot_conti_lightu   경량 콘티 (레시피)g{G8@zgpt-image-2.5-sunburst)r   r   r   r   r<   r`   r4   ra   background_renderr   r   r   ry   r   u   배경 그룹 분류g(\3@)r<   r`   rO   r]   r+   ra   if_background_modebackground_master_planu   배경 마스터플랜gQ3@)r   r4   r<   r`   r+   floor_plan_promptu   도면 t2i 프롬프트g\(3@)r   r4   r<   r`   r+   floor_plan_renderu   도면 이미지 생성ǧ5@floor_plan_light_sidecaru'   도면 단순화 사이드카 (W21B-w5)g(\5@floor_plan_overlay_payloadu    도면 오버레이 페이로드gR5@base_location_dossieru   기초 위치 정보 (W20A)gGz5@)r   r   r   r   floor_plan_geometry_readbacku   도면 기하 readback (W20A2)gףp=
5@floor_plan_semantic_readbacku0   도면 마커 의미 fidelity readback (W21B-w4)gK5@shot_projection_cardu@   샷 projection card — 카메라 가시물 서술 SOT (W21B-w4)g+Η5@)r   r   r   r   r   r   rg   r4   bg_space_partitionu@   BG 공간분할 — plate group / anchor / ref DAG SOT (W21B-w5)gMb5@)r   r   r   dwelling_zone_mapu1   dwelling zone map — FP+VLM 공간 묶기 (W21B)gx&15@)r   r   r   r   r   space_set_bgu;   space set BG — frame/addon/life 3층 공간 세트 (W21B)g     6@)r   world_guider4   r<   r`   ra   shot_aware_bg_render_planz shot-aware BG render plan (W20B)gQ5@)r   r   r   r   rg   rz   u   배경 t2i 프롬프트g5@)r   r   r   r4   r<   r`   r+   r{   u   에피소드 참조 정책gfffff5@)rd   r`   r<   rO   rN   rW   rY   r|   u!   시각 연속성 anchor (W21B-W7)g)\5@)r4   r<   r`   rm   rg   rd   r   #if_visual_continuity_anchor_enabled)r   r   r   r   r   r   r   r    r!   r"   r~   r(   rv   u5   배경 생성 Planner (deprecated, Phase 7로 대체)ǧ3@)r<   r`   ra   rO   r]   r+   background_chain_planningu6   배경 chain 플래닝 (deprecated, Phase 7로 대체)g3@)r<   r`   rg   ra   rO   r]   r+   scene_verifyu   교차 검증 (레거시)   )r   r   r   r   r   r   r   rc   r    r!   r"   r   u   월드 가이드   ref_image_genu   요소 참조 이미지   composite_image_genu!   인물+아웃룩 합성 이미지   if_has_outlookscharacter_state_variantu%   인물 상태 변형 참조 이미지g     8@u   배경 이미지 생성gQ8@)r   rz   r   r   u3   배경 chain 렌더 (deprecated, Phase 7로 대체)g333338@u   씬 이미지 생성 (compound)   mixed)	r   r   r   r   r   r   r   r   r   prompt_translationu
   T2I 번역)idr   r   r   scene_t2i_genu   T2I 이미지 생성scene_t2i_validationu   이미지 검증prompt_sanitizeu   프롬프트 안전화angle_recommendu   앵글 추천fal_angle_applyu   fal.ai 앵글 적용zfal-aifalfinal_selectu   최종 선택)r   r   r   r   r   r   r   	sub_stepsr    r!   r"   u   아웃룩 중복 판별	auxiliaryd   u   프로젝트 요약 (미구현)e   removed)r   background_chain_renderscene_image_pipelineoutlook_dedupproject_summarySTEP_MANIFESTstep_idreturnc                 ,    t         j                  |       S )uF   주어진 step_id의 매니페스트 항목을 반환. 없으면 None.r   getr   s    L/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/step_manifest.pyget_step_infor         W%%    c                     | t         v S )u   등록된 step_id인지.)r   r   s    r   containsr     s    m##r   c                 ,    t         j                  |       S )u5   dict 형태의 manifest entry (읽기 전용 관례).r   r   s    r   get_manifest_dictr     r   r   c                 j    t         j                  |       }|g S t        |j                  dg             S )u<   주어진 step_id의 선행 의존 step_id 목록을 반환.r   )r   r   list)r   infos     r   get_depends_onr   	  s2    W%D|	r*++r   c           	          t         j                         D cg c]  \  }}| |j                  dg       v r| c}}S c c}}w )uI   주어진 step_id를 의존하는 직접 하위 step_id 목록을 반환.r   )r   itemsr   )r   sidr   s      r   get_downstream_stepsr   		  sI     +0022	Tdhh|R00 	2  s    <c                     t               }t        |       }|rC|j                  d      }||vr+|j                  |       |j	                  t        |             |rCt        |      S )uR   주어진 step_id의 모든 하위 의존 step_id를 재귀적으로 반환 (BFS).r   )setr   popaddextendsorted)r   visitedqueuecurrents       r   get_all_downstream_recursiver   	  sZ    5G )E
))A,'!KK LL-g67	 
 '?r   c                      g } t         j                         D ]  \  }}d|i|}| j                  |        | j                  d        | S )ug   order 기준으로 정렬된 매니페스트 항목 리스트 반환. 각 항목에 step_id 키 포함.r   c                     | d   S )Nr    )xs    r   <lambda>z#get_ordered_steps.<locals>.<lambda>#	  s    ajr   )key)r   r   appendsort)resultr   r   entrys       r   get_ordered_stepsr   	  sO    F"((*	TC(4(e + KK(K)Mr   N)__doc__typingr   r   r   r   STEP_STATUSES	frozensetr   __annotations__r   strr   boolr   r   r   r   r   r   r   r   r   <module>r      s  =~ - , ,5l^+D y DT", #&* 	T",$ #&! %T",> )'%&! 
 ?T",b &#! cT",| -()! }T",X -'+,$ !2YT",t +,! uT",T 3#%9:! UT",n )#M! oT",H '%S! IT",b '%U! cT",| %%&!  %*'?#}T",f #\ 1 gT",D  -. 1 !ET",b #\ 1 cT",@  %,- 1  AT",^ #\ 1 _T",|  %() 1 }T",Z .%&! [T",v 'L* wT",V	 .L, W	T",r	 /%~6 %*'@ + 's	T",\
 6'( %*'@* %]
T",D .  (
-
 %*'@ - I%ET",P W  N %*'@ 2 =QT",P -#
 )*:;! QT",r '
 ! sT",T '&'! UT",v 3%&'! wT",R -#'(! ST",l 0%#\2! /3mT",H $& _! ;IT",H ,%'($ !%IT",d * j!  eT",D 5%')9:# !%ET",` ='(# !(aT",| .')9:! }T",V *%'(! /3WT",r *%'(! /3sT",N *%'(! /3OT",j /%'($ !E/3kT",H %u!  IT",v %')9:2  wT",b G
 #!)cT",N *%  `!  
 %*-OT",D -%@ 
 !  !66/3 %*CBET",N .#
'!  1OT",H * N! !-~ > +IT",P 8
 < #QT",P :
 9 'QT",D ?
 
 <  5ET",F  8   !
 ;+G T",z  8
 4 #{ T",p! ; %* 
 / -q!T",j" 3$)
 0 'k"T",f# 'Q
 / I%)g#T",D% :'
  / I%E%T",^& 0

 *  +_&T",R' 7

 3 S'T",|' 3

 * 
 '}'T",t( ,1
4 *
 Q)u(T",L* '

 - M*T",t* )

 -  7u*T",t+ * 

 - )u+T",j, *!9
 -k,T",n- :  
 -!o-T",d. !3!9
 - #e.T",^/ .
 -  #_/T",^0 #1#
 -  #%_0T",`1 #C#
 - %a1T",n2 S	
 - +o2T",H4 S

 - +I4T",f5 D
 - -g5T",B7 N
 -+C7T",L8  3
 - : [."M8T",r9 * 	
 - /s9T",n: -
$ ! ;!o:T",J< 4
 >  !663!K<T",V= H
 # !W=T",@>  I

 # !"A>T",b> ,%&/3# !c>T",B? ##^4!C?T",Z? *'#n![?T",r? 4'&(89*s?T",J@ 8',n=! K@T",t@ + 	
 -3F G24IJ#!  3 
* ',Q[iqr"-CVdrz{)4FY^ltu$/GZ_muv$QVdlm$/EX`nst!Oeaij
 "[.f +'($   3()# KDT",tCc3h'( T"tD&3 &8DcN#; &$c $d $
&s &xS#X'? &
,C ,DI ,# $s) 	# 	$s) 	4S#X/ r   