
    Oj6)                        U d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
mZmZ ddlmZmZmZmZmZmZmZ  ed       G d d	             ZeZeZdd
ZddZ e       Zded<   ddZ ddZddZddZddZ!ddZ"dd dZ#d!dZ$ddZ%ddZ&g dZ'y)"u  Step Catalog — manifest + class + applicability 통합 단일 계약.

Phase 1.1 (architecture-refactor-final/02-final-roadmap.md §Phase 1).

원칙 (01-principles-revised.md §5):
- `STEP_MANIFEST` (step_manifest.py)는 **데이터 소스**. 수정은 여기서.
- `STEP_CLASSES` (steps/__init__.py)는 runner 바인딩.
- `STEP_CATALOG` (본 파일)는 **소비자 전용 View**. manifest + class + 파생 정보 병합.

소비자는 STEP_CATALOG만 본다. manifest/classes를 직접 참조하지 않음.

순환 import 주의 (Claude Phase 1 리뷰 M1):
- 본 모듈은 `app.core.steps` 전체를 지연 import (`_build()` 내부).
- `app.core.steps` 하위 개별 step 파일은 `app.core.step_catalog`를 import하면 안 됨.
  필요 시 step 파일 내부 함수에서 지연 import로 회피.
- 부팅 시점 `STEP_CATALOG = _build()`가 즉시 실행되어 `STEP_CLASSES`가 한 번 빌드되므로,
  ImportError/부수효과는 서버 기동 시점에 조기 노출됨 (late crash 방지).
    )annotations)	dataclassfield)AnyDictListOptionalSetType)STEP_MANIFESTcontainsget_all_downstream_recursiveget_depends_onget_downstream_stepsget_manifest_dictget_ordered_stepsT)frozenc                      e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   d
ed<   ded<   ded<   ded<   ded<   dZded<   dZded<   dZded<    ee	      Z
d
ed<   dZded<   dZded<   dZded<   y)	StepEntryu   Step의 모든 메타데이터와 runner 클래스 바인딩을 담은 단일 레코드.

    manifest에서 가져온 필드 + STEP_CLASSES에서 바인딩한 runner_cls + 파생 필드.
    strstep_idlabelcategoryfloatorderdefault_modelprovider	List[str]
depends_onboolfan_outapplicability	step_type	lifecycleFresume_sensitiveNzOptional[List[str]]modifies_checkpointsinvalidate_downstream_on_edit)default_factoryconsumes_downstreamOptional[str]replaced_byzOptional[List[Dict[str, Any]]]	sub_stepszOptional[Type[Any]]
runner_cls)__name__
__module____qualname____doc____annotations__r%   r&   r'   r   listr)   r+   r,   r-        K/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/step_catalog.pyr   r   #   s     LJMLMMNN"d"04-4*/!4/ &+4%@@!%K%04I-4&*J#*r5   r   c                 <    t        t        j                               S )uL   등록된 전체 step_id 목록 — STEP_CATALOG 구축 이전에도 안전.)r3   r   keysr4   r5   r6   get_step_idsr9   Q   s    ""$%%r5   Dict[str, StepEntry]c                 N   ddl m}  i }t        j                         D ]@  \  }}t	        di d|d|d   d|d   d|d   d|j                  dd      d	|j                  d	d      d
t        |j                  d
g             dt        |j                  dd            d|j                  dd      d|d   d|d   dt        |j                  dd            d|j                  d      dt        |j                  dd            dt        |j                  dg             d|j                  d      d|j                  d      d| j                  |      ||<   C ddlm	} ddl
m}m}m}m} ddlm}	m}
 |j%                  |t'        |      t'        |      ||
|	|       |S )u=   STEP_MANIFEST + STEP_CLASSES 병합하여 StepCatalog 구축.r   )STEP_CLASSESr   r   r   r   r   -r   r   r!   Fr"   alwaysr#   r$   r%   r&   r'   r)   r+   r,   r-   )grounding_activation_contract)GROUNDING_MODE_V2_CHUNKGROUNDING_MODESPLANNED_MODESbuys_v2_research)MATERIALIZABLE_OWNER_TYPESREFERENCE_SUPPORTED_OWNERS)accepted_modesplanned_modes
chunk_modereference_ownersledger_ownersbuys_legacy_researchr4   )app.core.stepsr<   r   itemsr   getr3   r    app.corer?   app.core.grounding_moder@   rA   rB   rC   .app.modules.pipeline.grounding_entity_contractrD   rE   assert_activationset)r<   catalogsidinfo_actr@   rA   rB   rC   rD   rE   s              r6   _buildrX   V   s    ,$&G"((*	T  

w-
 *%
 w-	

 ((?C8
 XXj#.
 DHH\267
 )U34
 ((?H=
 ;'
 ;'
 "$((+=u"EF
 "&*@!A
 +/txx8WY^/_*`
 !%TXX.CR%H I
  /!
" hh{+#
$ $'',%
 +2 ?; ;@ 	O 4-(*30-  / Nr5   STEP_CATALOGc                ,    t         j                  |       S N)rY   rN   )r   s    r6   	get_entryr\      s    G$$r5   c                ^    t         j                  |       }|rt        |j                        S g S r[   )rY   rN   r3   r   r   entrys     r6   r   r      s*    W%E%*4  !22r5   c                z    t         j                         D cg c]  \  }}| |j                  v s| c}}S c c}}w )u!   직접 의존 하위 step 목록.)rY   rM   r   r   rU   es      r6   r   r      s4    *002N2FCg6MC2NNNs   77c                    t               }t        |       }|rC|j                  d      }||vr+|j                  |       |j	                  t        |             |rCt        |      S )u-   재귀적 downstream (BFS). 결과는 정렬.r   )rS   r   popaddextendsorted)r   visitedqueuecurrents       r6   r   r      sZ    G )E
))A,'!KK LL-g67	 
 '?r5   c                 B    t        t        j                         d       S )u'   order 오름차순 StepEntry 리스트.c                    | j                   S r[   )r   )rb   s    r6   <lambda>z%get_ordered_entries.<locals>.<lambda>   s    qwwr5   )key)rg   rY   valuesr4   r5   r6   get_ordered_entriesrp      s    ,%%'->??r5   c                 v    t         j                         D  cg c]  \  } }|j                  s|  c}} S c c}} w )uD   resume_sensitive=True인 step_id 목록 (Phase 1.3 steps.py 소비).)rY   rM   r%   )rU   rb   s     r6   get_resume_sensitive_step_idsrr      s1    *002I2FCa6H6HC2IIIs   55Nc                |    t               D cg c]$  }|j                  dk(  r| |j                  | k(  r|& c}S c c}w )u   lifecycle=active이며 (옵션) 특정 category 일치.

    applicability는 여기서 해석하지 않음 — 그건 StepRunner 런타임에서
    app.core.applicability.resolve_applicability가 처리.
    active)rp   r$   r   )r   rb   s     r6   get_active_entriesru      sH     '((a;;("(8AJJ(<R 	
(  s   )9c                    t         j                         D cg c]0  \  }}|j                  dk(  r|j                  r| |j                  v r|2 c}}S c c}}w )u   target_step_id의 체크포인트를 수정하는 editorial step 목록.

    t2i_review가 entity_t2i/scene_detail을 덮어쓰는 것과 같은 관계 조회용.
    Phase 2/3에서 editorial invalidation 설계 시 사용.
    	editorial)rY   rM   r#   r&   )target_step_idrU   rb   s      r6   get_modifiers_ofry      sY     ',,..Q;;+%""a444 	.  s   5Ac                ^    t         j                  |       }|rt        |j                        S g S )u&  step_id가 역참조로 소비하는 하류 step_id 목록. 2-pass 의존성 선언.

    상류 force 시 cascade invalidation에서 이 목록의 체크포인트 파일은 보존된다
    (DB는 stale). 기본 대응: 상류 force 완료 후 선언된 하류도 수동 재실행 권장.
    )rY   rN   r3   r)   r^   s     r6   get_consumes_downstreamr{      s,     W%E.34))*;;r5   c                    t        t        j                         D cg c]  \  }}| |j                  v r| c}}      S c c}}w )u(  step_id를 consumes_downstream으로 역참조 소비하는 상류 step_id 목록.

    `get_consumes_downstream`의 역방향 조회. UI가 "이 step이 stale인 이유가 상류의
    2-pass 소비 때문인가?"를 판단해 drift stale을 일반 stale과 구분 표시하는 데 사용.
    )rg   rY   rM   r)   ra   s      r6   get_consumers_ofr}      sL     &,,..Qa+++ 	.   s   ?
)r   rY   r\   r   r   r   rp   rr   ru   ry   r{   r}   r   r   r9   )returnr   )r~   r:   )r   r   r~   zOptional[StepEntry])r   r   r~   r   )r~   List[StepEntry]r[   )r   r*   r~   r   )rx   r   r~   r   )(r1   
__future__r   dataclassesr   r   typingr   r   r   r	   r
   r   app.core.step_manifestr   r   _manifest_containsr   _manifest_get_downstreamr   _manifest_get_depends_onr   _manifest_get_direct_downstreamr   _manifest_get_manifest_dictr   _manifest_get_orderedr   r9   rX   rY   r2   r\   rp   rr   ru   ry   r{   r}   __all__r4   r5   r6   <module>r      s   $ # ( 7 7   $!+ !+ !+R / &
-` &,X" -%3
O
	@
J
	<	r5   