
    3ja                       U d Z ddlmZ ddlmZmZ ddlmZ ddl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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<   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+<   d,Z*ded-<   d.Z+ded/<   d0Z,ded1<    G d2 d3e-      Z.e G d4 d5             Z/dGd6Z0eed7	 	 	 	 	 dHd8Z1dId9Z2e G d: d;             Z3e d<d<d=d=d>	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dJd?Z4	 	 	 	 	 	 dKd@Z5eeeedA	 	 	 	 	 	 	 	 	 	 	 dLdBZ6eeeedA	 	 	 	 	 	 	 	 	 	 	 dMdCZ7eeeedA	 	 	 	 	 	 	 	 	 	 	 dMdDZ8dNdEZ9g dFZ:y=)Ou
  anu_v3.default_profile_resolver — TRACK 3: policy profile engine →
DEFAULT dispatch-planning 경로 연결 (task-2553+52).

회장 3-track 배치 Track 3. goal_type `policy_profile_default_dispatch_adoption`.

목표 (회장 verbatim §1):
  policy profile engine 을 **기본 dispatch planning 경로** 에 연결한다.
  기본 경로에서 **goal_type + boundary 만으로 profile 선택** 가능해야 한다.

기존 +38 `dispatch_profile_selection` 과의 차이:
  +38 seam 은 chair 가 ``policy_profile.name`` 을 **명시 공급** 해야 했다.
  본 Track 은 그 한 칸을 없앤다 — chair 는 default 경로에서 ``goal_type``
  + ``boundary`` 만 준다. 본 resolver 가 ``goal_type → policy_profile``
  mapping(`memory/policy_profiles/goal_type_profile_mapping.json`)을 단일
  결정 테이블로 조회해 profile 이름을 산출하고, C1 engine 정본 API
  (parse_goal_request → resolve_policy)를 **read-only 소비** 하여
  gate / HOLD / allowed / forbidden / evidence / completion-packet 을
  자동 산출한다 (§8 회장이 풀어쓰지 않아도 ANU 가 engine+guard 로 자동산출).

본 모듈 한정 책임 (순수, 부작용 0 — 파일 write 0, network 0, git 0,
GitHub API 0, 실 dispatch/PR/merge/branch 실행 0):
  1. default profile resolver (§3.1)
  2. goal_type → policy_profile mapping 로더·조회 (§3.2)
  3. boundary → gate/HOLD/forbidden expansion 표면화 (§3.3 — engine 산출
     read-only 표면화)
  6. missing / unknown profile fail-closed (§3.6 — 추측·날조 0)
  7. profile conflict fail-closed (§3.7)
  8. selected profile evidence JSON 산출 (§3.8)

설계 invariant (§5 / §6 / §10):
  - 신규 별도 모듈 (strict-additive). engine·+38·+39·frozen anchor·기존
    profile/mapping/anchor import-only read-only / mutation 0.
  - engine = `anu_v3.policy_profile_engine` 정본 API 만 호출
    (parse_goal_request@187 → resolve_policy@561, PolicyEngineError,
    validate_against_meta, load_meta_schema). engine 내부 재구현·mutation 0.
  - resolver 는 profile 을 **선택만** 한다 — 실행하지 않는다.
    ``DISPATCH_LIFECYCLE_EFFECT == "none"``. 실 운영 in-place 채택은 별도.
  - missing / unknown / conflict = **fail-closed** (자동 적용 0,
    profile 미바인딩, 예외 dispatch 비전파). 추측·날조 0.
  - profile engine 이 write/merge 권한을 요구하면 본 모듈은 그것을 절대
    수행하지 않고 fail-closed (§7 공통 HOLD 대상 — 회장 보고).
  - 외부 의존성 0 (engine 과 동일 — offline 100%).
    )annotations)	dataclassfield)Path)AnyFinalMappingSequence)	PROFILE_JSON_DIR_DEFAULTPROFILE_SCHEMA_DIR_DEFAULTSCHEMA_DIR_DEFAULTPolicyEngineErrorPolicyResolutionload_meta_schemaparse_goal_requestresolve_policyvalidate_against_metazanu_v3.default_profile_resolverz
Final[str]RESOLVER_MODULEztask-2553+52.Track3.v1RESOLVER_VERSIONz+anu_v3.default_profile_resolver.decision.v1RESOLUTION_SCHEMA_IDz<anu_v3.default_profile_resolver.selected_profile_evidence.v1EVIDENCE_SCHEMA_IDz5memory/policy_profiles/goal_type_profile_mapping.jsonMAPPING_PATH_DEFAULTz%goal_type_profile_mapping.schema.jsonMAPPING_SCHEMA_NAMEnoneDISPATCH_LIFECYCLE_EFFECTRESOLVEDSTATUS_RESOLVEDDEFAULT_RESOLUTION_REFUSEDSTATUS_REFUSEDPROFILE_CONFLICTSTATUS_CONFLICTHOLD_FOR_CHAIRSTATUS_HOLDdefault_request_not_mappingREFUSAL_REQUEST_NOT_MAPPINGgoal_type_missingREFUSAL_GOAL_TYPE_MISSINGgoal_type_not_mappedREFUSAL_GOAL_TYPE_NOT_MAPPEDmapping_load_failREFUSAL_MAPPING_LOAD_FAILmapping_schema_failREFUSAL_MAPPING_SCHEMA_FAILmapping_entry_invalidREFUSAL_MAPPING_ENTRY_INVALIDexplicit_profile_conflictCONFLICT_EXPLICIT_PROFILEambiguous_mapping_conflictCONFLICT_AMBIGUOUS_MAPPING!engine_allowed_forbidden_conflictCONFLICT_ENGINE_ALLOW_FORBIDengine_hold_for_chairREFUSAL_ENGINE_HOLDc                  $     e Zd ZdZd fdZ xZS )DefaultProfileResolverErroru   resolver 정규화/조회 실패. dispatch lifecycle 로 전파하지 않고
    내부에서 fail-closed 결정(REFUSED/CONFLICT)으로 변환된다.c                L    t         |   d| d|        || _        || _        y )N[z] )super__init__codemessage)selfr>   r?   	__class__s      6/home/jay/workspace/anu_v3/default_profile_resolver.pyr=   z$DefaultProfileResolverError.__init__a   s+    1TF"WI./	    )r>   strr?   rD   returnNone)__name__
__module____qualname____doc__r=   __classcell__)rA   s   @rB   r9   r9   ]   s    M rC   r9   c                  b    e Zd ZU dZded<   ded<   ded<    ee      Zded<   d	Zd
ed<   ddZ	y	)DefaultDispatchRequestu@  기본 dispatch planning 경로 입력. policy_profile.name 은 chair 가
    주지 않는다 — resolver 가 goal_type 으로 산출한다.

    ``explicit_policy_profile_name`` 은 선택적 — chair 가 굳이 명시했는데
    mapping 산출과 다르면 **profile conflict fail-closed** (§3.7) 검출용.
    rD   goal_idgoal_statement	goal_type)default_factoryz	list[str]boundaryN
str | Noneexplicit_policy_profile_namec                x    | j                   | j                  | j                  t        | j                        d|idS )u   resolver 가 산출한 profile_name 을 채워 C1 engine 정본 입력
        (goal_request_2553plus33.schema.json) 형태로 변환.name)rN   rO   rP   rR   policy_profile)rN   rO   rP   listrR   )r@   profile_names     rB   to_goal_requestz&DefaultDispatchRequest.to_goal_requesty   s9     ||"11T]]+%|4
 	
rC   )rY   rD   rE   dict[str, Any])
rG   rH   rI   rJ   __annotations__r   rX   rR   rT   rZ    rC   rB   rM   rM   j   s8     LN5Hi5/3 *3	
rC   rM   c                   t        | t              s&t        t        dt	        |       j
                         | j                  d      }|r t        |t              r|j                         st        t        d      | j                  d      xs i }t        |t              r|j                  d      nd}t        t        | j                  dd            t        | j                  d	d            |j                         | j                  d
      xs g D cg c]  }t        |       c}t        |t              r%|j                         r|j                               S d      S c c}w )u   dispatch 가 넘긴 raw dict → DefaultDispatchRequest (fail-closed).

    형태 불량은 DefaultProfileResolverError 로 raise 하되 entrypoint 가
    REFUSED 안전 거부로 흡수한다 (dispatch 무파괴).
    u   default request dict 아님: rP   uO   default 경로 필수 입력 goal_type 누락/무효 (추측 0 — fail-closed)rW   rV   NrN    rO   rR   )rN   rO   rP   rR   rT   )
isinstancer	   r9   r%   typerG   getrD   stripr'   rM   )rawgtppexplicitbs        rB   build_default_requestri      s'    c7#)'+DI,>,>+?@
 	
 
	BZC(
)%]
 	
 
!	"	(bB!+B!8rvvf~dH!CGGIr*+377#3R89((*#&77:#6#<">Q#a&> *8S 9hnn>NHNN  UY  ?s   E!mapping_path
schema_dirc                   ddl }t        |       }	 |j                  d      }	 |j                  |      }t        |t              st	        t
        d|       	 t        t        |	      }t        ||      }|rt	        t        dj                  |            t        |j!                  d      t              r|d   st	        t        d      |S # t        $ r}t	        t
        d| d|       |d}~ww xY w# |j                  $ r}t	        t
        d| d|       |d}~ww xY w# t        $ r}t	        t        d
|       |d}~ww xY w)u^  goal_type → policy_profile mapping 을 read-only 로딩·검증.

    engine 의 offline draft-07 subset validator(validate_against_meta)로
    `goal_type_profile_mapping.schema.json` 검증. 파일 부재/파싱 실패/
    schema 불일치 = fail-closed (DefaultProfileResolverError, code 보존).
    mutation 0 (mapping 파일 read-only).
    r   Nzutf-8)encodingu   mapping 부재/읽기 실패 z: u   mapping JSON 파싱 실패 u   mapping 최상위 dict 아님 rl   u#   mapping meta-schema 로드 실패: z; mappingsu)   mapping.mappings 비어있음/dict 아님)jsonr   	read_textOSErrorr9   r+   loadsJSONDecodeErrorr`   dictr   r   r   r-   r   joinrb   )	rk   rl   rq   prd   eobjmetaerrss	            rB   load_goal_type_mappingr}      sm    \Akk7k+
jjo
 c4 )%)Gs'K
 	
 3
K
 !d+D)'4
 	
 cggj)40J)')T
 	
 J;  )%)FqcA3'O
	  )%)DQCr!'M
	  )'+Nqc)R
	sF   C C5 D# 	C2C--C25D DD #	E,E  Ec           	        | j                  d      xs i }||vrt        t        d|d      ||   }t        |t        t
        f      rt        t        d|d      t        |t              s)t        t        d|dt        |      j                         |j                  d      }|r t        |t              r|j                         st        t        d|d      |j                         S )uY  단일 결정 테이블 조회. goal_type → policy_profile 이름 (deterministic).

    - goal_type 미등재         → REFUSAL_GOAL_TYPE_NOT_MAPPED (unknown,
      추측 0 fail-closed §3.6)
    - entry 형태 불량          → REFUSAL_MAPPING_ENTRY_INVALID
    - entry 가 다중 후보(list) → CONFLICT_AMBIGUOUS_MAPPING (§3.7)
    rp   z
goal_type uQ    가 default mapping 에 없음 — UNKNOWN, 추측·날조 0 (fail-closed §3.6)uB    다중 후보(비결정) — profile conflict fail-closed (§3.7)u    entry 가 object 아님: rW   u/    entry 에 policy_profile(string) 누락/무효)rb   r9   r)   r`   rX   tupler3   r	   r/   ra   rG   rD   rc   )mappingrP   entriesentryrV   s        rB   resolve_profile_namer      s    kk*%+G)( &3 4
 	

 IE%$')& &" #
 	

 eW%))%?U@T@T?UV
 	
 99%&Dz$,DJJL))%TU
 	
 ::<rC   c                      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Zd	ed<   dZd	ed<   eZded<   dZ	ded<   e
Zded<   eZded<   dZded<   ddZddZddZy)DefaultProfileResolutionu   default 경로 산출 — dispatch planning / batch coordinator 가 그대로
    소비할 profile resolution binding (fail-closed 4-상태).rD   statusboolprofile_bound
auto_applyrN   rP   rS   resolved_profile_name
profile_idprofile_versionmapping_sourcer[   boundary_expansionNrefusal_coderefusal_reasondispatch_lifecycle_effectTdefault_pathresolverresolver_versiondict[str, Any] | Noneengine_decisionc                   i dt         d| j                  d| j                  d| j                  d| j                  d| j
                  d| j                  d| j                  d	| j                  d
| j                  d| j                  d| j                  d| j                  d| j                  d| j                  d| j                  d| j                   d| j"                  iS )Nschemar   r   r   r   r   r   r   rN   rP   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   rN   rP   r   r   r   r   r   r   r   r   r@   s    rB   to_decision_dictz)DefaultProfileResolution.to_decision_dict  s;   
*

  5 5
 dkk	

 T//
 $//
 D--
 ()G)G
 t||
 
 $T%?%?
 $//
 t33
 d11
 !$"9"9
  D--!
" d11#
$ t33%
 	
rC   c                   t         | j                  | j                  | j                  | j                  t        | j                  j                  dg             dd| j                  | j                  | j                  | j                  | j                  | j                  d| j                  d| j                  | j                  t        k7  | j                   | j"                  dS )u   §3.8 — selected profile evidence JSON.

        goal_type + boundary → profile 선택이 default 경로에서 engine
        read-only 소비로 이뤄졌음을 입증하는 평면 증거.explicit_boundaryF)rP   rR   "chair_supplied_policy_profile_name)r   r   r   r   r   r   uv   anu_v3.policy_profile_engine.parse_goal_request -> resolve_policy (정본 API, engine import-only, mutation 0, byte-0))r   r   r   r   selection_inputselectedr   engine_consumed_read_onlyr   fail_closedr   r   )r   r   r   r   rP   rX   r   rb   r   r   r   r   r   r   r   r   r   r   r   s    rB   to_selected_profile_evidencez5DefaultProfileResolution.to_selected_profile_evidence+  s     ) $ 5 5 --!^^ !8!8!<!<=PRT!UV6;  ++)-)C)C"oo#'#7#7!%!3!3"oo #11G #'"9"9;;/9 --"115
 	
rC   c                   | j                   }| j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  t        |j                  dg             t        |j                  dg             t        |j                  dg             t        |j                  dg             |j                  d      |j                  d      | j                  dS )u   dispatch planning adapter 소비용 평면 binding (RESOLVED 시에만
        의미; 그 외 빈 contract — 자동 적용 0).gate_condition_nameshold_trigger_conditionsallowed_actionsforbidden_actionscompletion_packet_meta_refevidence_meta_ref)r   r   r   r   rN   rP   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   rN   rP   r   r   rX   rb   r   )r@   bes     rB   planning_bindingz)DefaultProfileResolution.planning_bindingM  s     $$kk!//// --||%)%?%?//$(0F)K$L'+BFF3Lb,Q'R#BFF+<b$AB!%bff-@"&E!F*,&&1M*N!#(;!<)-)G)G
 	
rC   )rE   r[   )rG   rH   rI   rJ   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   r]   rC   rB   r   r      s    D KLN%%O&&#L*#!%NJ%%>s>L$#Hc#,c,-1O*1
, 
D
rC   r   r_   N)r   rN   rP   r   r   c               6    t        |dd|||ddddg i| ||      S )uX   fail-closed 안전 거부 — profile 미바인딩·자동 적용 0, dispatch 무파괴.Fr_   Nr   r   r   r   rN   rP   r   r   r   r   r   r   r   r   )r   )r>   reasonr   rN   rP   r   r   s          rB   _refusedr   d  s=     $3/4' rC   c           
         | j                         }t        |j                        t        |d         t        |d         t        |d         t        |d         |d   |d   t        | j                        dS )u   §3.3 — boundary → gate/HOLD/forbidden expansion 표면화.

    engine 이 boundary[] + profile 로 산출한 gate/HOLD/allowed/forbidden 을
    그대로 표면화 (engine read-only). resolver 가 재구현하지 않는다.
    r   r   r   r   r   r   )r   r   r   r   r   r   r   resolved_boundary)to_coordinator_bindingrX   rR   rv   )resrequestbindings      rB   #_boundary_expansion_from_resolutionr   |  s     ((*G!'"2"23 $W-C%D E#'0I(J#K(9 :;!'*=">?&-.J&K$%89!#,,/	 	rC   rk   profile_json_dirprofile_schema_dirrl   c                  	 t        ||      }t        || j                        }t        |      }	| j                  rZ| j                  |k7  rKt        t        d| j                  d|d| j                  dt        | j                  | j                  |      S | j                  |      }
	 t        |
|	       t!        |
|||
      }t%        ||       }|j'                         }|j(                  dk(  rr|j*                  xs d}d|v xs d|v }t-        |rt        nt.        dd|j                  |j                  ||j0                  |j2                  |	||rt4        nt6        ||      S t-        t8        dd|j                  |j                  ||j0                  |j2                  |	||      S # t        $ ra}|j                  t
        k(  rt        nt        }t        |j                  |j                  || j                  | j                        cY d}~S d}~ww xY w# t"        $ rB}t        |j                  |j                  | j                  | j                  |      cY d}~S d}~ww xY w)u  **DEFAULT dispatch-planning resolver entrypoint** (§3.1).

    goal_type + boundary 만으로 profile 을 자동 선택·로딩한다.
      1. goal_type → policy_profile mapping 조회 (§3.2, 단일 결정 테이블)
      2. explicit profile 명시 충돌 검출 → PROFILE_CONFLICT (§3.7)
      3. C1 engine 정본 API read-only 소비: parse_goal_request →
         resolve_policy (engine byte-0, mutation 0)
      4. boundary → gate/HOLD/forbidden expansion 표면화 (§3.3)
      5. missing/unknown/conflict = fail-closed (§3.6/§3.7 — 추측·날조 0)

    profile 부재 / schema mismatch / engine HOLD 는 예외를 dispatch 로
    전파하지 않고 fail-closed 결정으로 변환 (dispatch lifecycle 무파괴).
    rj   )r   rN   rP   Nu   chair 명시 profile u    ≠ default mapping 산출 z (goal_type u*   ) — profile conflict fail-closed (§3.7))r   rN   rP   r   ro   )r   r   rl   )rN   rP   r   r"   zengine HOLD_FOR_CHAIRu   충돌u   모순Fr   T)r   r   r   rN   rP   r   r   r   r   r   r   )r}   r   rP   r9   r>   r3   r!   r   r   r?   rN   rD   rT   r1   rZ   r   r   r   r   r   r   hold_reasonr   r#   r   r   r5   r7   r   )r   rk   r   r   rl   r   rY   ry   r   r   goal_requestr   r   decisionr   is_conflicts                   rB   resolve_default_profiler     sM   ,

(%*
 ,GW5F5FG &N 	,,00L@%#G$H$H#K L&&2%5\  ##MO #OOw/@/@".
 	
 **<8L
<J?-1!	
 
-S'	:B##%H
zz%% ;$;&(>H,>'&1?{KKmm".~~//)!0;,AT!$
 	
$ $--*>>++%  I ' 
$%FF.H$HnFFAIIfOOw/@/@
 	

D  
FFAIIOOw/@/@".
 	

s<   #F# (H #	H,AHHH	I7IIIc                   	 t        |       }t        |||||      j                         S # t        $ r8}t        |j                  |j                        j                         cY d}~S d}~ww xY w)u   파일레벨 contract entrypoint — raw dict → decision dict.

    기본 dispatch planning 경로가 단일 호출로 소비할 결선점. 요청 정규화
    실패도 fail-closed 안전 거부로 흡수한다 (예외 dispatch 비전파).
    Nr   )ri   r9   r   r>   r?   r   r   raw_requestrk   r   r   rl   reqry   s          rB   run_default_profile_resolutionr     sj    >#K0 #!)-  ' >		*;;==>   + 	A,-A'!A,'A,c                   	 t        |       }t        |||||      j                         S # t        $ r8}t        |j                  |j                        j                         cY d}~S d}~ww xY w)uI   §3.8 — raw dict → selected profile evidence JSON (예외 비전파).Nr   )ri   r9   r   r>   r?   r   r   r   s          rB   run_selected_profile_evidencer     sm    J#K0 #!)- #"$% ' J		*GGIIJr   c                2    | D cg c]  }|d   	 c}S c c}w )uA   fixture case[].request 목록 추출 (regression/dry-run 공용).r   r]   )casescs     rB   default_requests_from_fixturer   /  s    "'(QAiL(((s   )r   r   r   r   r   r   r   r   r   r!   r#   r%   r'   r)   r+   r-   r/   r1   r3   r5   r7   r9   rM   r   ri   r}   r   r   r   r   r   )rd   r   rE   rM   )rk   
str | Pathrl   r   rE   r[   )r   zMapping[str, Any]rP   rD   rE   rD   )r>   rD   r   rD   r   rD   rN   rD   rP   rD   r   rS   r   r   rE   r   )r   r   r   rM   rE   r[   )r   rM   rk   r   r   r   r   r   rl   r   rE   r   )r   r   rk   r   r   r   r   r   rl   r   rE   r[   )r   zSequence[Mapping[str, Any]]rE   z	list[Any]);rJ   
__future__r   dataclassesr   r   pathlibr   typingr   r   r	   r
   anu_v3.policy_profile_enginer   r   r   r   r   r   r   r   r   r   r\   r   r   r   r   r   r   r   r   r!   r#   r%   r'   r)   r+   r-   r/   r1   r3   r5   r7   
ValueErrorr9   rM   ri   r}   r   r   r   r   r   r   r   r   __all__r]   rC   rB   <module>r      s  *V # (  0 0
 
 
 @ ?7 * 7#P j P!_ J _ $[ j Z"I Z I )/ : . ) (9
 90 0*Z * +H Z G(; : ;+A j A(; : ;*? Z ?,C z C(C : C)E J E+N j N"9 Z 9*  
 
 
4F  4/.. . 	.b!N b
 b
 b
L .<(,-1	
'*"% & +	
 0	$:0  4#;%?/k#k k !	k
 #k k kb  4#;%?/  !	
 #  :  4#;%?/%% % !	%
 #% % %,)
 rC   