
    Oj>                    6   U d Z ddlmZ ddlZddlZddlmZmZmZ  ej                  e
      ZdZdZddd	 	 	 	 	 d dZd	Zd
ZdZdZdZeeeefZded<   eefZded<   dZdZdZeeefZded<   dZd!dZd"dZd#dZd#dZd$dZ dZ!dZ" G d de#      Z$d%dZ%d&dZ&y)'ur  ★참조 획득 — **엔티티마다 참고 사진을 찾아 온다.** GROUNDING-V2 §2-4.

사용자 설계(2026-08-30):

    이미지 모델이 만들기 어려운 것은 한 번만 나와도 엔티티에 등록하고,
    그 엔티티는 **검색 → 이미지 검색**을 탄다.
    사전 검색은 판정이 아니라 **「무엇을 찾을지」 자료를 모으는 것**이다.
    VLM 은 **「우리가 찾던 종류가 맞나」만** 본다. 없으면 좁혀서 한 번 더.

★★**새로 만드는 것이 아니다.** 검색·안전 다운로드·선택 primitive 는
`search_grounded_ref` 에 이미 있고 지금은 **야외 구조물(21.915)** 만 쓴다.
이 모듈은 그 **호출 소유권을 앞으로 옮긴다** — primitive 를 복사하지 않는다.

호출자는 딱 하나여야 한다. 앞뒤 두 곳이 각각 사면 같은 것을 두 번 산다.
    )annotationsN)AnyDictOptional   reference_acquisition)coarse_versionref_versionc                8   ddl m} ddl m} ddlm} t        j                         }|j                  t        t              j                                |j                  d       | xs |j                  }|j                  |j                  |j                  fD ]}  }||j                  k(  rdnd}		  ||j                  ||	|      }
|j                  t        |
xs i j!                  d	      xs d
      j                  d             |j                  d        |j                  |j%                  |xs |j&                        j                                |j                  d       t)        |      t*        usd|cxk  r|j,                  k  sn t/        d|j,                   d|d      |}|j                  | d|j0                   d||j0                  z   j                                |j3                         dd S # t"        $ r |j                  d       Y w xY w)u7  ★★**참조 신원을 지배하는 것 전부**의 해시. 한 곳에서만 만든다.

    왜 한 곳인가 — 앞쪽 스텝과 `image_steps` 가 **각각 산식을 적으면** 한쪽만
    고쳐진다. 그러면 팩을 바꿔도 바깥 이미지 스텝이 stale 이 안 돼
    **옛 참조가 영구 봉인**된다(`image_steps` 주석에 그 사고가 적혀 있다).

    접는 것:

    - **거친 종류 선택 팩** — 지문·스키마·좁힘 문안. 무엇을 고르는지를 지배한다
    - **검색·다운로드 계약** — `search_grounded_ref` 의 brief/질의 저작 팩
    - **라운드 계약** — 라운드 수·라운드당 후보 상한. 바뀌면 다른 실험이다
    - **계약 버전** — 이 모듈이 무엇을 뜻하는지

    ★안 접는 것: **어느 엔티티가 이 길을 타는가**(`generation_difficulty`).
    그것은 대상 집합을 정할 뿐 **한 대상의 참조 산출에 기여하지 않는다** —
    접으면 다른 대상의 난이도가 바뀌었다고 이미 뽑아 둔 참조가 무효가 된다.
    r   )coarse_type_pick)search_grounded_ref)resolve_effective    schemaprompt)kindversioncontent zutf-8    r   u   rounds 는 1..u)    의 **정수**여야 한다 (받은 값 ):N   )app.modules.pipeliner   r   app.modules.prompt_loaderr   hashlibsha256updatestrACQUISITION_CONTRACT_VERSIONencodePROMPT_PACK_VERSIONSYSTEM_STEMSCHEMA_STEMNARROW_STEMPROMPT_MODULEgetFileNotFoundErrorsearch_contract_shaREF_PACK_VERSIONtypeint
MAX_ROUNDS
ValueErrorPER_ROUND_CAP	hexdigest)r	   r
   roundsctpsgrr   hcvstemr   gotns               `/Users/manta/Documents/Projects/TheRoad-I1/backend/app/modules/pipeline/reference_acquisition.pyacquisition_contract_shar:      s   ( =?;AHHS-.5578HHW		2322B#//3??C  3??2x	#C$5$5t)-r;CHHS#)39r:AA'JK
 	
! D& HHS$$+s++--3VX7HHW F|3a6&CS^^&CS^^, -!*A'( 	( 	AHHs!C%%&aC%%%&((.2;;="= ! 	 HHSM	s   .AG;;HHselectedno_match_after_retry	retryableTreference_unavailabletupleKNOWN_RAW_STATUSESTERMINAL_RAW_STATUSES
unverifiedverifiedrejectedKNOWN_FIDELITYz1.202609020700c                    t        | xs i j                  d      xs i j                  d      xs d      }|t        v r|S t        S )u   이 줄의 **고증 축**. ★없으면 `unverified` — 기본이 「아직 아니다」다.

    ★모르는 값은 `unverified` 로 접는다. 「모르는 것」이 통과가 되면 안 된다.
    grounding_fidelitystater   )r   r'   rE   FIDELITY_UNVERIFIEDrowr7   s     r9   fidelity_ofrL      sD    
 	r34:??HNB
OC'3@-@@r   c                    t        | xs i j                  d      xs d      }|s+t        t        | xs i j                  d      xs d            }|t        k(  S )u  하류가 **참조로 써도 되나**. ★HITL 0 — 자동 선택(`outcome == selected`) **하나**면 된다.
    (아래 옛 문단은 2026-09-02 의 「두 축」 계약 기록이다 — 2026-09-03 사용자 재지시로 뒤집혔다.)

    ★★★`selected` 만 보면 안 된다 (Codex BLOCK 2026-09-02): 그것은 coarse
    심판이 「그 종류의 사진」이라고 한 것일 뿐이다. 고증이 확인되지 않은 것을
    참조로 붙이면, 사람이 못 본 사진이 그림의 근거가 된다.

    ★확인이 안 됐다고 **파이프라인을 막지 않는다** — 참조 **없이** 내려간다
    (`reference_unavailable` 과 같은 대접). HITL 0 이 이 판의 계약이다.

    ★어느 칸을 보나: 소비자가 보는 것은 **접은 값**(`outcome`)이다. 그것이
    없는 줄이면 raw `status` 를 접어서 본다 — 두 벌로 적지 않는다.
    (실측 2026-09-02: sidecar 투영 줄은 `outcome` 만 들고 있어 `status` 만
    보던 판이 **verified 인 줄까지 안 붙였다**.)
    outcomer   status)r   r'   acquisition_outcomeSTATUS_SELECTEDrJ   s     r9   usable_as_referencerR      sQ      sybooi(.B
/C!#sybooh&?&E2"FG /!!r   c                $    t        |       t        v S )uK   그 줄이 **끝났나**. ★「없다」와 「못 봤다」를 가른다.)r   rA   rO   s    r9   is_terminalrU      s    v;///r   c                     y)u/  이 대상을 하류가 **막아야 하는가** — ★**아니다**.

    ★사람 대기를 만들지 않는다 (사용자 확정 2026-08-31). 못 구한 것은
    `reference_unavailable` 로 남기고 **참조 없이 자동으로** 내려간다.

    ★★이 함수는 **늘 False** 다. 남겨 두는 까닭은 호출부가 이미 이것을
    묻고 있고, 지우면 그 자리들이 각자 판단하게 되기 때문이다. 「막을지」를
    묻는 자리는 여기 하나여야 나중에 정책이 또 바뀌어도 한 곳만 고친다.
    F rT   s    r9   downstream_blockedrX      s     r   c                ,    | t         k(  rt         S t        S )u  하류에 넘길 **처지**. ★사람이 볼 상태를 production 에 안 만든다.

        selected               참조를 쓴다
        reference_unavailable  참조 없이 간다 (못 구했다 · 다 못 봤다)

    ★`no_match_after_retry` 와 `retryable` 을 **둘 다** unavailable 로 접는다.
    둘의 차이는 **기록에 그대로 남지만**, 하류는 어느 쪽이든 참조 없이 간다.
    )rQ   STATUS_UNAVAILABLErT   s    r9   rP   rP      s      &8O %#%r    outdoor_structure_form_referencec                      e Zd ZdZy)FrontCheckpointMissingud   사는 모드인데 중앙 CP 가 없다 — 의존이 안 돈 것이지 legacy 주행이 아니다.N)__name__
__module____qualname____doc__rW   r   r9   r]   r]      s    nr   r]   c               X    ddl m}  ||       r|st        d| d      t        S t        S )u\  이 주행에서 **누가 참조를 사는가**.

    ★★앞뒤가 각각 사면 **같은 것을 두 번 산다.** 그래서 소유자를 한 곳으로
    못박고, 소유자가 아닌 자리는 **네트워크를 0회** 쓴다.

    이관 중에는 갈래가 둘이다 (Codex):

    - v2 이고 **앞쪽 산출이 있으면** → 앞쪽이 소유자. 야외 스텝은 그것을
      **읽어서 기존 CP 모양으로 투영만** 한다
    - 그 밖에는 야외 스텝이 그대로 산다 (**명시적 legacy fallback**).
      ★이 fallback 이 남아 있는 동안은 「이관 완료」라고 쓰지 않는다

    ★`front_checkpoint_exists` 를 **명시로 받는다.** 「v2 면 앞쪽이 있겠지」로
    유추하면, 앞쪽이 아직 안 돈 주행에서 야외가 조용히 아무것도 못 사고
    순수 T2I 로 내려간다.
    r   )buys_referencezgrounding_mode=u    는 중앙(reference_acquisition)이 참조를 사는 모드인데 앞쪽 CP 가 없다 — 의존 스텝이 안 돌았다. 야외 스텝은 legacy 로 사지 않는다(이중 구매 금지))app.core.grounding_moderc   r]   OWNER_FRONTOWNER_OUTDOOR)modefront_checkpoint_existsrc   s      r9   acquisition_ownerri      sD    ( 7d& )!$ *u uv v r   c                >    | |k7  rddl m}  |dd| d|dd      y	)
u   소유자가 아닌 자리에서 사려 하면 **선다**.

    ★조용히 지나가면 이중 구매가 되고, 그건 「몇 번 샀나」를 통째로 거짓말로
    만든다. 늦게 죽는 것보다 여기서 드러나는 편이 낫다.
    r   )AppErrorz#reference_acquisition.not_the_owneru"   이 주행의 참조 소유자는 u    인데 uK    가 사려 한다 — 앞뒤가 각각 사면 같은 것을 두 번 산다i  )codemessagestatus_codeN)app.core.errorsrk   )ownerwhererk   s      r9   assert_not_buyingrr     s@     ~,69%(5) T^ ^	
 	
 r   )r	   Optional[str]r
   rs   r1   r,   returnr   )rK   Dict[str, Any]rt   r   )rK   ru   rt   bool)rO   r   rt   rv   )rO   r   rt   r   )rg   r   rh   rv   rt   r   )rp   r   rq   r   rt   None)'ra   
__future__r   r   loggingtypingr   r   r   	getLoggerr^   loggerr    	STEP_NAMEr:   rQ   STATUS_NO_MATCHSTATUS_RETRYABLEALLOW_MISSING_REFERENCErZ   r@   __annotations__rA   rI   FIDELITY_VERIFIEDFIDELITY_REJECTEDrE   FIDELITY_CONTRACT_VERSIONrL   rR   rU   rX   rP   re   rf   RuntimeErrorr]   ri   rr   rW   r   r9   <module>r      s(   #   & &			8	$  #	 AE:>G*7G%(G-0GV ( $   - 
 -o-/AC E C !0A u A #   ,.?*, , - A":0


%" &2o\ oD
r   