
    #&i                        d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	  ej                  e      ZdZdZeefz   ZdZ	 d	 	 	 	 	 dd	Z	 d	 	 	 	 	 dd
Z	 d	 	 	 	 	 ddZddZy)u   G3.1 evidence/inference 4-field helpers — single source.

LLM strict schema 가 강제 못하는 contract consistency 와 옛 checkpoint
backfill 을 처리. 두 step (scene_consistency, scene_detail) 이 공유.
    )annotationsN)AnyDictUnion)AppErrorlegacy)highmediumlow)source_factsvisual_inferencescreative_decisionsc                   t        | t              s| S d}t        D ]!  }|| vst        | |   t              rg | |<   d}# d| vs| d   t        vrt
        | d<   d}n|r	t
        | d<   |r|rt        j                  d|       | S )u  G3.1 lazy backfill — 4 evidence 필드 누락 시 default 주입.

    **옛 checkpoint 전용** (CRITICAL #2). 새 LLM 응답에는 호출 금지 — strict schema
    가 4 필드 강제. 이 함수가 빈자리 채우면 strict 우회 silent backfill 회귀 발생.

    Mutation in-place. file 안 건드림.

    Type guard (Cl-M1 fix): item 이 dict 아니면 그대로 반환 — caller 가 list-of-X
    iter 중 비-dict element 를 만나도 AttributeError 안 남.
    FT
confidencez(evidence backfill marker=legacy where=%s)
isinstancedictEVIDENCE_FIELDSlistVALID_STORED_CONFIDENCELEGACY_CONFIDENCEloggerdebug)itemwhere
backfilledfields       V/Users/manta/Documents/Projects/TheRoad-I1/backend/app/core/steps/_evidence_helpers.py_normalize_evidence_fieldsr      s     dD!J JtE{D$ADKJ !
 44#5=T#T.\
	.\e?GK    c                    t        | t              s| S | j                  d      }t        |t              sg | d<   | S |D ]  }t	        ||        | S )u  fixed_elements 각 element normalize. PROBLEM #3: malformed container type guard.

    Codex BLOCKING 2 fix: helper 가 'list 아니면 silent return' 으로 끝내면 downstream
    consumer (shot_dependency_t2i / t2i_review / scene_checkpoint_loaders) 가 list
    가정하고 ``v.get()`` 호출 → AttributeError. fixed_elements/t2i_variations 가
    malformed 일 때 helper 가 in-place 로 빈 list 강제 → consumer 정상 (빈 iter, noop).
    옛 데이터 손실은 어차피 malformed 라 의미 없음.
    fixed_elementsr   r   r   getr   r   )scene_resultr   fixedfes       r   #_normalize_scene_consistency_resultr(   7   sZ     lD)-.EeT")+%&"2U3 r   c                    t        | t              s| S | j                  d      }t        |t              sg | d<   | S |D ]  }t	        ||        | S )u   t2i_variations 각 variation normalize. type guard.

    Codex BLOCKING 2 fix: malformed t2i_variations 가 list 아니면 in-place 빈 list
    강제 (consumer AttributeError 차단).
    t2i_variationsr"   r#   )r%   r   vars_vars       r   _normalize_scene_detail_resultr-   N   sZ     lD)-.EeT")+%&"3e4 r   c                P   | j                  d      }|t        k(  rt        d| dd      | j                  d      xs g }| j                  d      xs g }| j                  d      xs g }|s|d	k7  rt        d| d
| dd      |s|s|s|d	k7  rt        d| d| d      yyyy)u  post-parse contract validator (IMPROVEMENT #2).

    LLM strict schema = 4 필드 존재만 강제. contract consistency 추가 검증:
      - confidence == "legacy" → reject (LLM 출력 금지, adapter-only)
      - source_facts == [] AND confidence != "low" → violation
      - 4 lists 모두 [] AND confidence != "low" → violation

    AppError(code="step.contract_violation") raise → step_runner retry path.
    **새 LLM 응답에만 호출**. 옛 cp 는 normalize 가 처리.
    r   zstep.contract_violationu9   : LLM 출력에 confidence='legacy' 금지 (adapter-only)i  )codemessagestatus_coder   r   r   r   u$   : source_facts=[] 인데 confidence=u    (low 여야 함)u-   : 4 lists 모두 비어있음 — confidence=N)r$   r   r   )r   	step_namer   sfvicds         r   assert_fresh_llm_evidencer6   a   s     ,'J&&* k!Z[
 	

 
.	!	'RB	%	&	,"B	&	'	-2B*%* k!Ej\Qbc
 	

 "
e 3* k!Nzl[
 	
 !4"Br   ) )r   Union[Dict[str, Any], Any]r   strreturnr8   )r%   Dict[str, Any]r   r9   r:   r;   )r   r;   r2   r9   r:   None)__doc__
__future__r   loggingtypingr   r   r   app.core.errorsr   	getLogger__name__r   r   VALID_LLM_CONFIDENCEr   r   r   r(   r-   r6    r   r   <module>rF      s   
 #  # # $			8	$ 0 .2C1EE M 46
$-0F 02 ),0 02 ),& 
r   