
    3j6#                    ,   U d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZmZmZ dZded	<   d
Zded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<    G d de      Z	 	 	 	 d dZe G d d             Z	 	 	 	 d dZg dZy)!u  anu_v3.profile_dispatch_planning_adapter — §3.4: profile decision →
DEFAULT dispatch *planning* 입력 어댑터 (task-2553+52 / Track 3).

목표 (회장 §3.4):
  default profile resolver(`anu_v3.default_profile_resolver`)의 decision
  output(`decision.v1`)을 기본 dispatch **planning** 경로가 그대로 소비할
  수 있는 평면 입력으로 변환한다.

설계 invariant (§2 / §5 / §6):
  - 신규 별도 additive 모듈. resolver·engine·+38·+39·frozen anchor·
    durable v1 무수정. **import 결합 0** — anu_v3 import 전무, 순수
    stdlib only (resolver decision = 파일레벨 contract 로만 소비).
  - planning 입력 derive 만 — 실 dispatch / PR / merge / branch 실행 0.
    ``DISPATCH_LIFECYCLE_EFFECT == "none"``, ``plan_only == True``
    (hard-pinned). 어떤 입력에서도 write/merge/PR 자동확정 0.
  - resolver status != RESOLVED (REFUSED/CONFLICT/HOLD) → fail-closed:
    plan_admissible=False (planner 가 자동 진행 못 하도록 안전 신호).
  - decision schema marker mismatch / 부재 / 파싱 실패 = fail-closed
    (PLAN_UNAVAILABLE — 예외를 planner 가 진행 신호로 오인 불가).
  - 모든 메서드 = read-only derive/propose. 부작용 0 (파일 I/O 0).
    )annotationsN)	dataclass)Path)AnyDictFinalListMappingz(anu_v3.profile_dispatch_planning_adapterz
Final[str]ADAPTER_MODULEztask-2553+52.Track3.v1ADAPTER_VERSIONz+anu_v3.profile_dispatch_planning_adapter.v1ADAPTER_SCHEMAz+anu_v3.default_profile_resolver.decision.v1ACCEPTED_DECISION_SCHEMARESOLVED	_RESOLVEDnoneDISPATCH_LIFECYCLE_EFFECTPLAN_INPUT_OKPLAN_OKPLAN_FAIL_CLOSEDPLAN_DECISION_UNAVAILABLEPLAN_UNAVAILABLEc                  $     e Zd ZdZd fdZ xZS )#ProfileDispatchPlanningAdapterErroruF   resolver decision 소비 실패. ``self.code`` = 사유 (fail-closed).c                L    t         |   d| d|        || _        || _        y )N[z] )super__init__codemessage)selfr   r   	__class__s      ?/home/jay/workspace/anu_v3/profile_dispatch_planning_adapter.pyr   z,ProfileDispatchPlanningAdapterError.__init__1   s+    1TF"WI./	    )r   strr   r$   returnNone)__name__
__module____qualname____doc__r   __classcell__)r!   s   @r"   r   r   .   s    P r#   r   c           	     *   t        | t              rt        |       }n4t        |       }	 |j	                  d      }	 t        j                  |      }t        |t              s"t        d	d
t        |      j                         |j                  d      t        k7  r&t        ddt        d|j                  d      d      |S # t
        $ r}t        dd| d|       |d}~ww xY w# t        j                  $ r}t        dd| d|       |d}~ww xY w)u7  default resolver decision(`decision.v1`)을 read-only 소비.

    source = 파일 경로 또는 이미 로드된 dict (resolver 모듈 import·호출 0
    — 파일레벨 contract 만). schema marker mismatch / 부재 / 파싱 실패 =
    fail-closed (ProfileDispatchPlanningAdapterError, code 보존).
    zutf-8)encodingdecision_source_unreadableu'   resolver decision 부재/읽기 실패 z: Ndecision_source_unparsableu%   resolver decision JSON 파싱 실패 decision_not_objectu+   resolver decision 최상위 object 아님: schemadecision_schema_mismatchz,resolver decision schema mismatch: expected z, got u2    (resolver 부재/버전 mismatch — fail-closed))
isinstancer
   dictr   	read_textOSErrorr   jsonloadsJSONDecodeErrortyper'   getr   )sourceobjprawes        r"   load_resolver_decisionrA   7   s<    &'"<L	++w+/C	**S/C c4 1!9$s):L:L9MN
 	
 wwx441&:'*&1B0E F@A
 	
 J1  	5,9!BqcB 	 ## 	5,7s"QC@ 	s.   C C' 	C$CC$'D:DDc                  F    e Zd ZU dZded<   d
ddZddZddZddZddZ	y	)ProfileDispatchPlanningAdapteru   resolver decision → dispatch planning 평면 입력 (read-only derive).

    plan_only / DISPATCH_LIFECYCLE_EFFECT 는 입력과 무관하게 hard-pinned —
    어떤 경로에서도 실 dispatch/PR/merge/branch 자동확정 0.Dict[str, Any]decisionc                :    | j                   j                  ||      S N)rE   r;   )r    kdefaults      r"   _gz!ProfileDispatchPlanningAdapter._gj   s    }}  G,,r#   c                8    t        | j                  dd            S )Nstatus )r$   rJ   )r    s    r"   rL   z%ProfileDispatchPlanningAdapter.statusm   s    4778R())r#   c                z    | j                   j                  d      xs i }t        |t              rt	        |      S i S )Nboundary_expansion)rE   r;   r3   r
   r4   )r    bes     r"   _bez"ProfileDispatchPlanningAdapter._bep   s4    ]]34:%b'2tBx::r#   c                    | j                         j                  |      xs g D cg c]  }t        |       c}S c c}w rG   )rQ   r;   r$   )r    keyxs      r"   _listz$ProfileDispatchPlanningAdapter._listt   s.    !%!4!:<1A<<<s   ;c                .   | j                         }|t        k(  }i dt        dt        dt        dt
        d|rt        nt        d|dt        | j                  dd            d	t        | j                  d	d
            dt        | j                  dd
            d| j                  dd      dt        | j                  dd
            d|d| j                  d      ddd| j                  d      d| j                  d      d| j                  d      | j                  d      | j                         j                  d      | j                         j                  d      | j                  dd      | j                  dd      t        dddddddS )u3  기본 dispatch planning 경로가 그대로 소비할 평면 입력.

        resolver RESOLVED 일 때만 plan_admissible=True. REFUSED/CONFLICT/
        HOLD = fail-closed plan_admissible=False (planner 자동 진행 차단).
        실 dispatch/PR/merge/branch = plan_only hard-pinned (자동확정 0).adapter_schemaadapter_moduleadapter_versionconsumed_decision_schemasignalplan_admissibledefault_pathFgoal_idrM   	goal_typeresolved_profile_nameN
profile_idresolver_statusgate_condition_namesgate_semanticsu)   AND — ALL conditions must hold for PASShold_trigger_conditionsallowed_actionsforbidden_actionsexplicit_boundarycompletion_packet_meta_refevidence_meta_refrefusal_coderefusal_reasonTur   planning 입력 derive 만; 실 dispatch/PR/merge/branch 자동확정 0 (hard-pinned, 모든 입력에서 불변).)rh   ri   rj   rk   rl   dispatch_lifecycle_effect	plan_onlywrite_authoritymerge_authoritypr_branch_authorityauto_dispatchplan_only_invariant)rL   r   r   r   r   r   r   r   boolrJ   r$   rU   rQ   r;   r   )r    st
admissibles      r"   to_dispatch_planning_inputz9ProfileDispatchPlanningAdapter.to_dispatch_planning_inputw   s    [[]9_
"
n"
n"
 "
 '(@	"

 g1A"
 z"
 D!?@"
 s4779b12"
 TWW["56"
 $TWW-Dd%K"
 #dgglB78"
 r"
 #DJJ/E$F"
 I"
 &tzz2K'L"
  tzz*;<!"
"  ,?!@#"
$ "&,?!@*.((*..9U*V!%0C!D GGND9"gg&6=)B$$#("=?"
 "	
r#   N)rM   )rH   r$   rI   r   r%   r   )r%   r$   )r%   rD   )rS   r$   r%   z	List[str])
r'   r(   r)   r*   __annotations__rJ   rL   rQ   rU   rw    r#   r"   rC   rC   a   s)    K
 -*;=*
r#   rC   c                B   	 t        |       }t        |      j                         S # t        $ ro}i dt        dt        dt        dt
        dt        ddddd	d
d|j                  d|j                  dt        ddddddddddddddicY d}~S d}~ww xY w)u   default resolver → dispatch planning 입력 단일 callable entrypoint.

    resolver 부재/mismatch 는 fail-closed safe 입력으로 변환 (예외를
    planner 가 진행 신호로 오인하지 않도록 PLAN_DECISION_UNAVAILABLE).rW   rX   rY   rZ   r[   r\   Fr]   rb   UNAVAILABLErk   rl   rm   rn   Tro   rp   rq   rr   fail_closedrs   u>   fail-closed 경로에서도 plan_only / 자동확정 0 불변.N)rA   r   r   r   r   r   r   r   r   r   rC   rw   )r<   rE   r@   s      r"   adapt_for_dispatch_planningr}      s#   
)&10 *(3NNPP/ / 

n
n
 
 '(@	

 &
 u
 E
 }
 AFF
 aii
 ()B
 
 u
 u
 "5
  U!
" 4#
$ "P'
 	

s   & 	BA$BBB)r   r   r   r   r   r   r   r   r   rC   rA   r}   )r<   z 'str | Path | Mapping[str, Any]'r%   rD   )r*   
__future__r   r7   dataclassesr   pathlibr   typingr   r   r   r	   r
   r   rx   r   r   r   r   r   r   r   r   
ValueErrorr   rA   rC   r}   __all__ry   r#   r"   <module>r      s   * #  !  2 2G
 G6 6J
 J (U * T"	: " )/ : .% %1 * 1: * :* ',''T ?
 ?
 ?
D Q, Q QFr#   