
    >'jY                       U d Z ddlmZ ddlZddlZddlmZmZ ddlmZm	Z	m
Z
 ddl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d9dZd:dZd;dZd<d Zd=d!Zd>d"Zd?d#Zd:d$Z d:d%Z!d@d&Z"dAd'Z#dBd(Z$dCd)Z%dCd*Z&dCd+Z'dAd,Z(d:d-Z)	 	 	 	 	 	 	 	 dDd.Z*dEd/Z+	 	 	 	 	 	 	 	 dFd0Z,	 	 	 	 	 	 	 	 dGd1Z-dAd2Z.d3Z/ded4<   dHd5Z0d6d7	 	 	 	 	 	 	 	 	 	 	 	 	 dId8Z1y)Ju  anu_v3.pre_authorized_contract_deriver — PRE_AUTHORIZED contract auto-derivation (task-2553+5).

회장 §2/§12 verbatim 박제:
  GO-ready packet 을 사람이 손으로 contract 로 옮기지 않도록, **검증 가능한
  evidence** 에서 ``pre_authorized_action_contract`` 를 자동 생성한다. gate
  decision 이 ALLOW 일 때만 (별도 binding 모듈이) clean replacement PR open
  executor 로 연결한다.

본 모듈 한정 책임 (fail-closed, 순수 함수, 부작용 0):
  - evidence bundle (schemas/pre_authorized_evidence_bundle.schema.json) 소비
  - 9-R.2 normative derivation matrix 로 gate contract 전 field 기계 도출
  - self-assertion 차단: GO-ready packet 은 **식별자만 권위 (9-R.3)**.
    gate 관련 모든 boolean 은 독립 evidence(git/scan/marker)에서 재계산
  - evidence 부재/모호/추론불가 field → 자동 채움 금지 → HOLD_FOR_CHAIR
  - negative(안전) bool 은 scan 으로 false 를 적극 증명. 증명 불가 → HOLD
  - packet 주장 vs 독립 재계산 불일치 → HOLD + mismatch 기록 (9-R.3)
  - 9-R.8 provenance stamp 부착: 수동/위조 contract 는 stamp 위조 불가
    (evidence_bundle_sha256 = 실 evidence 번들 재해시 — binding 이 재검증)

one-way isolation: anu_v3 외부 import 금지. git/scan 은 evidence bundle 의
``observed_value`` 로 **사전 수집** — 본 deriver 는 subprocess/network 0,
순수하게 bundle 만 기계 변환한다 (gate 본체 무수정, deriver 출력 = gate 입력).
    )annotationsN)datetimetimezone)AnyFinalMapping)CONTRACT_SCHEMA_NAMEz&anu_v3.pre_authorized_contract_deriverz
Final[str]DERIVER_MODULEz1.0.0DERIVER_VERSIONz(anu_v3.pre_authorized_evidence_bundle.v1EVIDENCE_BUNDLE_SCHEMA_NAMEz,anu_v3.pre_authorized_contract_derivation.v1DERIVATION_SCHEMA_NAMEDERIVEDSTATUS_DERIVEDHOLD_FOR_CHAIRSTATUS_HOLD)task_identityaction_method_marker	source_prsource_pr_preservationsame_branch_push_zero
fresh_baseexpected_filesgit_effective_diffforbidden_path_scancritical_7_markercodex_verdict_markercredential_scanowner_pat_scanactual_api_scanreal_write_scanlimited_real_write_scanscope_declarationcallback_policy_markergo_ready_packet_claimszFinal[tuple[str, ...]]REQUIRED_EVIDENCE_KINDS)kindsourceobserved_valuecollected_tsderivation_rule_id_EVIDENCE_OBJECT_KEYSclean_replacement_pr_open_ACTION_CLEAN_REPLACEMENTc                  $     e Zd ZdZd fdZ xZS )_HolduJ   단일 field 도출 실패 → HOLD_FOR_CHAIR 사유. 호출자가 수집.c                2    t         |   |       || _        y N)super__init__reason)selfr4   	__class__s     =/home/jay/workspace/anu_v3/pre_authorized_contract_deriver.pyr3   z_Hold.__init__P   s         )r4   strreturnNone)__name__
__module____qualname____doc__r3   __classcell__)r6   s   @r7   r/   r/   M   s    T r8   r/   c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftime r8   r7   _now_utcrF   U   s!    <<%../CDDr8   c                   t        |       j                         D ci c]  \  }}|dk7  s|| }}}t        j                  |ddd      }t	        j
                  |j                  d            j                         S c c}}w )u  evidence bundle 의 결정적 sha256.

    ``_provenance`` 미리보기 블록은 해시 대상에서 제외 (fixture 가 stamp 를
    자기-포함할 수 있도록). deriver 와 binding 이 **동일 함수** 를 써서
    위조/치환된 번들을 검출한다 (9-R.8).
    _provenanceT),:F)	sort_keys
separatorsensure_asciizutf-8)dictitemsjsondumpshashlibsha256encode	hexdigest)bundlekvpayloadblobs        r7   canonical_evidence_sha256r[   Y   ss     !%V 2 2 4K1]8Jq!tKGK::4JUD >>$++g./99;;	 Ls
   A>A>c                    | j                  d      }t        |t              sy |j                  |      t        t              sy t        fdt        D              ry S )Nevidencec              3  &   K   | ]  }|v 
 y wr1   rE   ).0rW   objs     r7   	<genexpr>z _evidence_obj.<locals>.<genexpr>n   s     
7A1C<
7s   )get
isinstancer   anyr+   )rV   r&   evr`   s      @r7   _evidence_objrf   g   sO    	J	Bb'"
&&,Cc7#

7!6
77Jr8   c                    t        | |      }|t        d|       |d   }t        |t              st        d|       |S )Nu   evidence 부재: r(   u'   evidence observed_value 형식 오류: )rf   r/   rc   r   )rV   r&   r`   ovs       r7   	_observedri   s   sS    

%C
{'v.//		Bb'"=dVDEEIr8   c                8    || vrt        d| d| d      | |   S )N   evidence 모호: .u
    미기록)r/   )rh   keyr&   s      r7   _reqrn   }   s-    
"}'vQse:>??c7Nr8   c                J    t        | t              st        d| d| d      | S )Nrk   rl   u    가 bool 아님)rc   boolr/   )valuer&   rm   s      r7   _strict_boolrr      s-    eT"'vQse3CDEELr8   c                    t        | |      }t        t        |d|      |d      }|st        d| d      t        |d|      }t	        |t
        t        f      st        d| d      t        |      S )u   scan evidence 로 negative(false)를 **적극 증명**.

    scanned==true AND hits==[] → false (안전 증명).
    scanned!=true / hits 미기록 → 증명 불가 → HOLD.
    hits 비어있지 않음 → true (gate 가 HOLD 처리).
    scannedu   negative bool 증명불가: z.scanned=falsehitsu   .hits 형식 오류)ri   rr   rn   r/   rc   listtuplerp   )rV   r&   rh   rt   ru   s        r7   _prove_negativerx      s{     
64	 B4It4dIFG24&GHHFD!DdT5M*24&8KLMM:r8   c                    t        | d      }t        |dd      }t        |dd      }t        |dd      }t        |t              r|r||cxk(  r|k(  sn t	        d|d|d|      |S )Nr   go_ready_packet_task_idtask_md_filename_task_iddispatch_marker_task_idu&   task_id 3자 불일치/공백: packet=z md=z
 dispatch=ri   rn   rc   r9   r/   )rV   rh   abcs        r7   _derive_task_idr      s{    	6?	+BR*O<AR+_=AR*O<Aq#1a14QEaU*QER
 	
 Hr8   c                    t        | d      }t        |dd      }t        |dd      }t        |dd      }|t        k7  rt        d|      t	        |t
              r|st        d      ||k(  rt        d      t        S )Nr   method
new_branchsource_branchz!action_type UNDETERMINED: method=u.   action_type UNDETERMINED: new_branch 미기록uS   action_type UNDETERMINED: 신규 branch == source branch (clean replacement 아님))ri   rn   r-   r/   rc   r9   )rV   rh   r   r   r   s        r7   _derive_action_typer      s    	61	2B"h 67Fb,(>?J_.DEM**7zBCCz3'JDEE]")
 	
 %$r8   c                   t        | d      }t        | d      }t        |dd      }t        |dd      }t        |t              r|st	        d      ||k(  }|st	        d|d|      |j                  d      }|j                  d	      }t        |t              rt        |t              rt	        d
      t        |t              r|st	        d      |d||dS )Nr   r   recorded_head_sharecomputed_head_shau+   source_pr.head_sha 미기록 (preservation)u)   source PR 원본 변경 감지: recorded=z != recomputed=numberbranchu%   source_pr.number 부재/형식 오류u%   source_pr.branch 부재/형식 오류T)head_sha	preservedr   r   )ri   rn   rc   r9   r/   rb   intrp   )rV   identpresrecorded
recomputedr   numbrs           r7   _derive_source_prr      s    fk*EV56DD-/GHHd13KLJx%(ABBJ&I7| D'N,
 	

 ))H
C	8	Bc3:c4#8;<<b#b;<<	 r8   c                ~    t        | d      }t        |dd      }t        |t              r|dk  rt	        d      |dk7  S )Nr   source_branch_push_countr   u:   same_branch_push 증명불가: push_count 미기록/음수)ri   rn   rc   r   r/   )rV   rh   counts      r7   _derive_same_branch_pushr      sE    	62	3B/1HIEeS!UQYPQQA:r8   c                    t        | d      }t        |dd      }t        |dd      }t        t        |dd      dd      }t        |t              r|st        d      ||k7  s|st        d|d|d|       d	|fS )
Nr   recorded_base_shacurrent_origin_main_shais_ancestoru4   fresh_base 증명불가: recorded_base_sha 미기록u   fresh_base 미충족: base=z origin/main=z
 ancestor=T)ri   rn   rr   rc   r9   r/   )rV   rh   r   currentis_ancs        r7   _derive_fresh_baser      s    	6<	(BB+\:H20,?GR-|]F x%(JKK7&)(]7+ Nx!
 	
 >r8   c                    t        | d      }t        |dd      }t        |t        t        f      r|st        d      t        d |D              st        d      t        |      S )Nr   filesu6   expected_files 파싱불가 (task md §expected_files)c              3  D   K   | ]  }t        |t              xr |  y wr1   rc   r9   r_   fs     r7   ra   z)_derive_expected_files.<locals>.<genexpr>   s     7Az!S!'a'7s    u#   expected_files 항목 형식 오류ri   rn   rc   rv   rw   r/   allrV   rh   r   s      r7   _derive_expected_filesr      s^    	6+	,BW./EedE]+5LMM7779::;r8   c                    t        | d      }t        |dd      }t        |t        t        f      st        d      t        d |D              st        d      t        |      S )Nr   r   u,   effective_diff_files: git diff 산출 실패c              3  <   K   | ]  }t        |t                y wr1   r   r   s     r7   ra   z)_derive_effective_diff.<locals>.<genexpr>   s     1az!S!1s   u)   effective_diff_files 항목 형식 오류r   r   s      r7   _derive_effective_diffr      s\    	6/	0BW23EedE]+BCC1511?@@;r8   c                    t        | d      }t        |dd      }t        |t        t        f      st        d      |D cg c]  }t        |       c}S c c}w )Nr   forbidden_write_targetsu:   forbidden_path_scan: forbidden_write_targets 형식 오류)ri   rn   rc   rv   rw   r/   r9   )rV   rh   targetsts       r7   _derive_forbidden_targetsr      sQ    	60	1B202GHGge}-PQQ#$qCF$$$s   Ac                J    t        | d      }t        t        |dd      dd      S )Nr   
critical_7)ri   rr   rn   )rV   rh   s     r7   _derive_critical_7r     s/    	6.	/BR23 r8   c                r    t        | d      }t        |dd      }t        |t              r|st	        d      |S )Nr   verdictu5   codex_verdict marker.verdict 미기록 (prose 금지)r}   )rV   rh   r   s      r7   _derive_codex_verdictr     s;    	61	2B2y"89Ggs#7KLLNr8   c                n    t        | |      }t        | d      }t        t        ||d      d|      }|xs |S )uQ   negative bool: scan 0 hit AND scope 선언 none → false. 그 외 → true/HOLD.r"   )rx   ri   rr   rn   )rV   	scan_kind	scope_keyscan_hitscoperequiress         r7   _derive_scope_flagr     sG     vy1Hf12EUI23H
 xr8   c                   t        | d      }t        t        |dd      dd      }t        t        |dd      dd      }t        |dd      }t        t        |dd      dd      }t        t        |dd      dd      }t        t        |dd      dd      }t        t        |dd      dd      }|d	k7  rt        d
|d      |r|r|r|st        d      |r|st        d      dddS )Nr#   normalfallback	authorityno_writeno_dev_reactivationno_dispatchno_closeoutcollector_onlyu(   callback 광의권위 거부: authority=z != 'collector_only'uI   callback 광의권위 거부: write/재가동/dispatch/closeout 비차단u1   callback contract 누락: normal/fallback != trueT)r   r   ri   rr   rn   r/   )	rV   rh   r   r   r   r   no_reactr   r   s	            r7   _derive_callbackr   '  s5   	63	4BR34 F
 R56 H
 R&>?IR56 H
 R&(@A H
 R 89 K
 R 89 K $$6ymCWX
 	
 kkW
 	
 xGHH--r8   c                   t        | d      }|j                  d      }|!t        |t        t        f      st        d      t        |      }t        |      }|j                  |      sy|r|j                  t        |            syy)Nr"   declared_scope_filesu=   scope_declaration.declared_scope_files 형식 오류 (모호)TF)ri   rb   rc   rv   rw   r/   setissubset)rV   expected	effectiver   declaredeff_setexp_sets          r7   _derive_scope_expansionr   V  s}     f12Eyy/0HJx$$GSTT)nG(mGG$H.r8   c                l    t        | d      }t        t        ||d      d|      }|rt        | d      y)u   auto_closeout / dev_status_change — deriver 항상 false.

    evidence(scope)가 요구하면 설계상 HOLD (자동 채움 금지).
    r"   u8    요구 감지 → 설계상 HOLD (자동 채움 금지)Fr   )rV   r   labelr   r   s        r7   _derive_design_fixed_falser   g  sI     f12EUI23H
 ugUVWWr8   c                n    t        | d      }t        |dd      }t        |t              st	        d      |S )Nr"   requires_mergeu(   merge_required 모호 → 보수적 HOLD)ri   rn   rc   rp   r/   )rV   r   r   s      r7   _derive_merge_requiredr   y  s:    f12EE+-@AHh%>??Or8   )same_branch_pushr   effective_diff_contaminationr   credential_change_requiredowner_pat_touch_requiredactual_api_call_requiredreal_write_required!limited_real_write_entry_requiredscope_expansionmerge_requiredauto_closeoutdev_status_change_PACKET_CLAIMABLEc                    t               }t         t              st        d|dgi g       S  j	                  d      t
        k7  r;t        t         j	                  dd            |d j	                  d      gi g       S g i dt        idd<   dEfd} |d fdd	        |d
 fdd        |d fdd        |d fdd       i dF fd} |d|d       dv rd   d<    |d fdd        |d fdd       j	                  d      }j	                  d      }t        |t              rAt        |t              r1t        t        |            t        t        |            k7  d<   dd<   dG fd} |d |d!        |d" fd#d$        |d% fd&d'       d(D ]  \  }}}	}
 ||||	f fd)	|
        dF fd*} |d+|d,        |d- fd.d/        |d0 fd1d2        |d3 fd4d5        |d6 fd7d5       g }	 t         d8      }|j	                  d9      }t        |t              r<t        D ]3  }||v s|v s||   |   k7  s|j                  |||   |   d:       5 |r*j                  d=d>j!                  d? |D              z          t#               }r:t        t        j	                  d j	                  dd                  |||@      S t$        |dAt&        dBdC<   t(        t$        t&        |d   t*        g g |dDS # t        $ r(}j                  d;|j                          Y d<}~d<}~ww xY w)Hu  evidence bundle → derivation result. 부작용 0. trust boundary: bundle 신뢰 불가.

    반환:
      status == DERIVED → ``contract`` (9-R.8 ``_provenance`` stamp 포함, gate 입력)
      status == HOLD_FOR_CHAIR → ``contract`` 없음 + ``hold_reasons``
     u"   evidence bundle 이 Mapping 아님schematask_idu"   evidence bundle schema 불일치: zconst:CONTRACT_SCHEMA_NAMEc                    	  |       | <   || <   y # t         $ r*}j                  |  d|j                          Y d }~y d }~ww xY w)Nz: )r/   appendr4   )fieldfnrule_idecontract
field_provholds       r7   _tryzderive.<locals>._try  sK    	0 dHUO 'Ju 	0KK5'AHH:.//	0s    	A AAc                     t               S r1   )r   rV   s   r7   <lambda>zderive.<locals>.<lambda>  s    OF3 r8   z9-R.2/task_id/3wayaction_typec                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  s    #F+ r8   z9-R.2/action_type/method+gitr   c                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  s    !&) r8   z9-R.2/source_pr/git-rev-parser   c                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  s    (0 r8   z9-R.2/same_branch_push/reflogc                 .    t              \  } }|d<   | S )Nbase_sha)r   )rX   basebase_sha_holderrV   s     r7   _freshzderive.<locals>._fresh  s     $V,4&*
#r8   r   z%9-R.2/fresh_base/origin-main-ancestorr   r   c                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>      &v. r8   z9-R.2/expected_files/task-mdeffective_diff_filesc                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  r  r8   z9-R.2/effective_diff/git-diffr   z9-R.2/set-compare/deterministicc                     t              } j                  d      }t        |t              st	        d      t        t        |      t        |       z        S )Nr  u=   effective_diff_files 미도출 → forbidden 교집합 불가)r   rb   rc   rv   r/   sortedr   )r   effrV   r   s     r7   _forbidden_touchedz"derive.<locals>._forbidden_touched  sJ    +F3ll12#t$WXXc#hW-..r8   forbidden_paths_touchedz9-R.2/forbidden/intersectionr   c                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  s    "6* r8   z9-R.2/critical_7/markercodex_verdictc                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>  s    %f- r8   z9-R.2/codex_verdict/marker))r   r   requires_credentialz9-R.2/negative/credential)r   r   requires_owner_patz9-R.2/negative/owner_pat)r   r   requires_actual_apiz9-R.2/negative/actual_api)r   r    requires_real_writez9-R.2/negative/real_write)r   r!   requires_limited_real_writez!9-R.2/negative/limited_real_writec                    t        | |      S r1   )r   )skpkrV   s     r7   r   zderive.<locals>.<lambda>  s    0B62r0R r8   c                     j                  d      } j                  d      }t        | t              rt        |t              st        d      t	        | |      S )Nr   r  u-   scope_expansion: expected/effective 미도출)rb   rc   rv   r/   r   )expr  rV   r   s     r7   
_scope_expzderive.<locals>._scope_exp  sO    ll+,ll123%*S$*?GHH&vsC88r8   r   z9-R.2/scope_expansion/subsetcallbackc                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>'  s    -f5 r8   z9-R.2/callback/marker+invariantr   c                     t               S r1   )r   r   s   r7   r   zderive.<locals>.<lambda>*  r  r8   z9-R.2/merge/scoper   c                     t         dd      S )Nrequires_auto_closeoutr   r   r   s   r7   r   zderive.<locals>.<lambda>/  s    *,o
 r8   z9-R.2/design-fixed-falser   c                     t         dd      S )Nrequires_dev_status_changer   r  r   s   r7   r   zderive.<locals>.<lambda>6  s    *02E
 r8   r$   claimed_booleans)r   packet_claimindependent_derivationzgo_ready_packet_claims: NuF   packet-evidence mismatch (packet=비권위, 독립 재계산 우선): z, c              3  &   K   | ]	  }|d      yw)r   NrE   )r_   ms     r7   ra   zderive.<locals>.<genexpr>Q  s     7q'
7s   evidence_bundle_sha256T)
derived_byr'  recomputed_all_gate_booleansderiver_versionrH   r   deriver_moduler*  ts_utcr   statusr   hold_reasonsfield_provenancepacket_evidence_mismatchesr'  )r   r9   r   r9   r:   r;   )r:   rp   )r:   	list[str])rF   rc   r   _hold_resultrb   r   r9   r	   rv   r  r   ri   r   r   r/   r4   joinr[   r
   r   r   r   )rV   tsr   r  r   r   r	  r   r   r   ridr  
mismatches	claims_ovclaimedrW   r   
bundle_shar   r   r   r   s   `                 @@@@r7   deriver;    s    
Bfg&B%I$JBPRSSzz(::

9b)*1&**X2F1IJK
 	
 D!#J (*>?H7Jx0 	35IJ+&
 	)'
 	0' ')O
 	vFG_$.z:.&
 	.' ||,-H34I(D!jD&A39#i.3IVMN
 4
/0 6W
12/ 	!& 	*!
 	-$- $
(y)S@ 	 YR	
A$
L9 		J(FG57XY.
 		
 	# 		
 	# (*J;f&>?	-- 23gw'& 	<AMqzXa[0")))*07
:B1+	 Tii7J778	

 +62JY

9b(ABC#-
 	
 %",(,*	H] )(*I& &&(", 9  ;.qxxj9::;s*   :L L L L 	M#MMr   r&  c               t    t         t        t        || t        d t	        |      t        |      t	        |      |dS )Nr+  )r   r
   r   r   rv   rN   )r   r5  reasonsr   r7  r'  s         r7   r3  r3  w  s=     )(*W ,&*:&6"8 r8   )r:   r9   )rV   Mapping[str, Any]r:   r9   )rV   r>  r&   r9   r:   zMapping[str, Any] | None)rV   r>  r&   r9   r:   r>  )rh   r>  rm   r9   r&   r9   r:   r   )rq   r   r&   r9   rm   r9   r:   rp   )rV   r>  r&   r9   r:   rp   )rV   r>  r:   dict[str, Any])rV   r>  r:   rp   )rV   r>  r:   ztuple[bool, str])rV   r>  r:   r2  )rV   r>  r   r9   r   r9   r:   rp   )rV   r>  r:   zdict[str, bool])rV   r>  r   r2  r   r2  r:   rp   )rV   r>  r   r9   r   r9   r:   rp   )rV   r   r:   r?  )r   r9   r5  r9   r=  r2  r   zMapping[str, str]r7  zlist[dict[str, Any]]r'  r9   r:   r?  )2r?   
__future__r   rR   rP   r   r   typingr   r   r   !anu_v3.pre_authorized_action_gater	   r
   __annotations__r   r   r   r   r   r%   r+   r-   	Exceptionr/   rF   r[   rf   ri   rn   rr   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r;  r3  rE   r8   r7   <module>rE     s  0 #   ' & & BE
 E% %*T Z T%S 
 S&
 &*Z *3 / .1 -  )D : CI E<	"	%"8"%  *- := 	 ,.^)2?H	"*-69	$- ) "aV #%  "	
 %   r8   