
    IjU                    z   U d Z ddlmZ ddlZddlZddl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 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<    eh d      Zded<   dddd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#dAd0Z$dd1dBd2Z%dCd3Z&	 	 	 	 	 	 	 	 	 	 	 	 dDd4Z'eee e!ed5	 	 	 	 	 	 	 	 	 	 	 	 	 dEd6Z(d7eeee e!eed8d9dd:d;	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dFd<Z)dGd=Z*	 	 	 	 	 	 dHd>Z+dIdJd?Z,e-d@k(  r e. e,             y)Kuo  anu_v3.pre_authorized_evidence_bundle_builder — task-2553+1 F1-solo evidence
bundle 을 **실 git / scan 증거에서 기계 생성** (task-2553+6 §7.1, 9-R.2).

회장 §3.1 11항목은 개념 요약. 머신 계약 권위 = task-2553+5 deriver 의
``REQUIRED_EVIDENCE_KINDS`` 19개 + evidence object 5-key
(``kind,source,observed_value,collected_ts,derivation_rule_id``) +
``schemas/pre_authorized_evidence_bundle.schema.json`` (9-R.2 권위).

본 모듈 한정 책임 (self-assert 0, fail-closed):
  - 실 git **read-only** 명령 (rev-parse / merge-base / rev-list / show /
    diff --name-only) 으로 머신 사실 수집. **GitHub mutation / push / merge /
    gh subprocess 0** (read-only allowlist 정적 강제).
  - GO-ready packet 의 boolean 주장은 **비권위** — 식별자만 차용, gate
    관련 모든 값은 git/scan/spec-parse 로 독립 산출 (9-R.3).
  - task-2553+6 §5 single-authority 6 effective-diff 파일
    (#2 = ``test_owner_trigger_2553_plus1_high_fix.py``, D-SPEC-EXACTNESS)
    을 expected_files / scope 로 사용.
  - 출력 = evidence bundle 스키마(``anu_v3.pre_authorized_evidence_bundle.v1``)
    통과 필수. 미정렬/누락/모호 → deriver 가 gate 도달 전 auto-HOLD.
  - 9-R.8 ``_provenance`` 미리보기 stamp 부착 (canonical sha256 = 실 번들
    재해시, ``_provenance`` 제외 — deriver/binding 동일 함수 재검증).

one-way: deriver 의 **public** API 만 사용 (``canonical_evidence_sha256`` /
``REQUIRED_EVIDENCE_KINDS``). private helper 복제·import 금지 (9-R.6).
git read-only 수집은 builder 책임 — deriver/gate/binding 은 subprocess 0 불변.
    )annotationsN)datetimetimezone)Path)AnyFinalMappingSequence)REQUIRED_EVIDENCE_KINDScanonical_evidence_sha256z-anu_v3.pre_authorized_evidence_bundle_builderz
Final[str]BUILDER_MODULE1.0.0BUILDER_VERSIONz(anu_v3.pre_authorized_evidence_bundle.v1EVIDENCE_BUNDLE_SCHEMA_NAMEz&anu_v3.pre_authorized_contract_deriverDERIVER_MODULE_NAMEkindsourceobserved_valuecollected_tsderivation_rule_idzFinal[tuple[str, ...]]_EVIDENCE_OBJECT_KEYS>   cat-filediffshowrev-list	rev-parse
merge-basezFinal[frozenset[str]]_GIT_READONLY_ALLOWLIST)zAKIA[0-9A-Z]{16}z"-----BEGIN [A-Z ]*PRIVATE KEY-----z$(?i)\bpassword\s*=\s*['\"][^'\"]{6,}z,(?i)\bclient_secret\s*[=:]\s*['\"][^'\"]{8,})zghp_[A-Za-z0-9]{30,}zgithub_pat_[A-Za-z0-9_]{30,}z(?i)\bOWNER_PAT\b\s*=z(?i)\bGH_OWNER_TOKEN\b)z0(?i)\brequests\.(get|post|put|patch|delete)\s*\(z4(?i)\bhttpx\.(get|post|put|patch|delete|Client)\s*\(z#(?i)\burllib\.request\.urlopen\s*\(z(?i)api\.github\.com)z(?i)\bgit\s+push\bz (?i)\bgh\s+pr\s+(create|merge)\bz4(?i)\bsubprocess\.[A-Za-z_]+\(\s*\[?['\"]?(git|gh)\b)z(?i)\blimited_real_write\bz(?i)\bheld_real_write_track\bz(?i)\bREAL_WRITE_TRACK\bcredential_scanowner_pat_scanactual_api_scanreal_write_scanlimited_real_write_scanz!Final[dict[str, tuple[str, ...]]]_SCAN_PATTERNS)zanu_v2/owner_trigger_pat.pyz:tests/regression/test_owner_trigger_2553_plus1_high_fix.pyzmemory/reports/task-2553+1.mdz%memory/events/task-2553+1.result.jsonz*memory/events/task-2553+1.red-evidence.logz,memory/events/task-2553+1.green-evidence.logTASK_2553P1_EFFECTIVE_DIFF_6)z$anu_v3/pre_authorized_action_gate.pyz)anu_v3/pre_authorized_contract_deriver.pyz)anu_v3/pre_authorized_executor_binding.pyz2schemas/pre_authorized_action_contract.schema.jsonz2schemas/pre_authorized_action_decision.schema.json2schemas/pre_authorized_evidence_bundle.schema.jsonz3tests/regression/test_pre_authorized_action_gate.pyz;tests/regression/test_pre_authorized_contract_derivation.pyz8tests/regression/test_pre_authorized_executor_binding.pyz+utils/anu_delegation_completion_callback.pyzXmemory/fixtures/task-2553+1.duplicate-callback-ignored.collector-regression-fixture.jsonzLtests/regression/test_completion_callback_dup_ignored_realworld_2553plus1.pyzdispatch.pyzscripts/finish-task.shztask-timer.py#TASK_2553P6_FORBIDDEN_WRITE_TARGETSf   z
Final[int]SOURCE_PR_NUMBERztask/task-2553-dev5SOURCE_BRANCH(bd5ad74f5d443b354319fc8b3cb006816b8a9025RECORDED_SOURCE_HEAD(7346df8260803308df30a6d04ec32d66d4cdfa5bFRESH_BASE_SHAz%task/task-2553p1-f1-clean-replacementNEW_CLEAN_REPLACEMENT_BRANCHc                      e Zd ZdZy)BuilderErroruO   evidence 수집/조립 실패. fail-closed: 절대 부분 번들 방출 금지.N)__name__
__module____qualname____doc__     D/home/jay/workspace/anu_v3/pre_authorized_evidence_bundle_builder.pyr3   r3      s    Yr9   r3   c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftimer8   r9   r:   _now_utcr?      s!    <<%../CDDr9   defaultc          	        |r|d   t         vr&t        d|r|d   nddt        t                d      	 t        j                  ddt        |       g|ddd	d
      }|j                  dk7  rI||S t        ddj                  |       d|j                   d|j                  j                                |j                  j                         S # t        t        j                  f$ r#}||cY d}~S t        d|d    d|       |d}~ww xY w)u   git **read-only** 명령만 실행. 화이트리스트 외 subcommand → BuilderError.

    GitHub mutation / push / network 0. 실패 시 default(있으면) 또는 raise.
    r   u    git read-only allowlist 위반: z<empty>u
    (허용: )git-CT   F)capture_outputtexttimeoutcheckNzgit u	    실패:  z rc=z: )r   r3   sorted
subprocessrunstrOSErrorSubprocessError
returncodejoinstderrstripstdout)reporA   argsoutes        r:   _git_readonlyr[      s1   
 47"99.$tAwI.P Q678;
 	
@nnD#d)+d+
 ~~N388D>"$s~~&6b9I9I9K8LM
 	
 :: Z//0 @NT$q')A378a?@s#   (C D(D+D1DDc           
         g }t         |   D ]D  }t        j                  ||       D ])  }|j                  | d| d|j	                                 + F |S )uV   변경 자산 텍스트에서 forbidden 패턴 적극 탐지 (negative 적극 증명).:@)r&   refinditerappendstart)rH   r   hitspatms        r:   _scanrf      s_    Dd# 5S$' 	5AKK4&#a	{34	55 Kr9   c                v    | |t        |      ||dt        fdt        D              rt        d|        S )Nr   c              3  &   K   | ]  }|v 
 y wNr8   ).0kobjs     r:   	<genexpr>z_ev.<locals>.<genexpr>   s     
7A1C<
7s   u   evidence object 5-key 누락: )dictanyr   r3   )r   r   r   rule_idtsrl   s        @r:   _evrr      sI     ~.%C 
7!6
77;D6BCCJr9   source_branchrecorded_source_headfresh_base_sha
new_branchexpected_filesc                  t        |       }|dz  j                         st        d|       t        |d|d      }t        |ddd      }t	        j
                  ddt        |      d	d
|dgddd      j                  dk(  }	t        |dd| d| d      }
	 t        |
      }t        |dd|d      dk7  }|r^t        |dd| d| d      }|j                         D cg c]  }|j                         s| }}t        |d|d      }d|dd  d| }nt        |      }d}d}t        |d| dd      }t        D ci c]  }|t        ||       }}d|dd  d}||t        |	      |||||||d 
S # t        $ r d}Y w xY wc c}w c c}w )!u   실 git read-only 수집. clean replacement branch 미materialize 시
    effective_diff = 계획 6파일(dry-run plan, branch≠source 검증된 상태).z.gitu   git repo 아님: r    r@   zorigin/mainrD   rE   r   z--is-ancestorTrF   F)rG   rI   rJ   r   r   z--count..0z--verifyr   z--name-onlyzgit diff --name-only N   uu   PLANNED (clean replacement branch 미materialize — dry-run): task-2553+6 §5 single-authority 6-file effective diffr   z:anu_v2/owner_trigger_pat.pyz	git show u   :anu_v2/owner_trigger_pat.py | scan(forbidden-patterns); F1 = endpoint/args allowlist 강화, token transport 무관 (task-2553+1 §2))
recomputed_source_headcurrent_origin_main_shafresh_base_is_ancestorsource_branch_push_counteffective_fileshead_sha
diff_basisscan_results
scan_basisbranch_exists)r   existsr3   r[   rM   rN   rO   rR   int
ValueError
splitlinesrU   listr&   rf   bool)	repo_pathrt   ru   rv   rw   rx   rW   recomputed_headorigin_mainis_ancpush_count_rawr   r   diff_outfr   r   r   
asset_textrk   r   r   s                         r:   collect_real_git_factsr      sJ    	?D6M!!#.tf566#k="O  k="K 	D	  	
 *	 " #
 =/2N&#&~#6 
 	dKZL	   b-
 '/&9&9&;Iqwwy1II +z2
 $N2A$6#7r*F 	 ~.E 	 
  <=	J 6DDAuZ++DLD
(!,- .3 	4  #2#."&v,$<* $ & _  &#% & J2 Es$   E3 F4F>F	3F Fztask-2553+1PASS_WITH_RECOMMENDATIONSFT)task_idsource_pr_numberrt   ru   rv   rw   rx   forbidden_write_targetscodex_verdict
critical_7factsstampc                     t               }|t        ||||||      }|d   }|d   }t        dd| | | dd|      t        d	d
d||dd|      t        dd||dd|      t        dd| d| d||d   dd|      t        dd|dd  d| ||d   dd|      t        d d!|dd  d"||d#   |d$   d%d&|      t        d'd(d)t        |      id*|      t        d+|d,   ||d-   xs d.t        |d/         d0d1|      t        d2d3d4t        |      id5|      t        d6d7d8t	        |
      id9|      t        d:d;d<|	id=|      t        d>d?d@d@d@d@d@d@d@d@t        |      dA	dB|      t        dCdDdEdEdFdEdEdEdEdGdH|      t        dIdJdKd@dEd@d@d@d@d@d@d@d@d@d@d@dLidM|      dN}dOD ]6  }t        ||dEt        ||         dPdQ|j                  dRdS       |      ||<   8 t        D cg c]	  }||vs| }}|rt        dT|       t        | |dU}|rt        |      }|S c c}w )Vu2  실 git/scan 사실 → deriver 19-kind 정렬 evidence bundle (스키마 통과).

    self-assert 0: gate 관련 값은 git/scan/spec-parse 독립 산출.
    GO-ready packet boolean 은 hint-only(go_ready_packet_claims) 로만 기록 —
    deriver 가 독립 재계산, mismatch → HOLD (9-R.3).
    Nrs   r   r   task_identityuD   task md 파일명 + dispatch marker + go-ready packet (3-way 일치))go_ready_packet_task_idtask_md_filename_task_iddispatch_marker_task_idz9-R.2/task_id/3wayaction_method_markeruY   task-2553+1.md method 선언 (Option B clean replacement) + git(신규 branch ≠ source)clean_replacement_pr_open)methodrw   rt   z9-R.2/action_type/method+git	source_pru?   PR #102 source marker (identifier — packet authority allowed))numberbranchz9-R.2/source_pr/identifiersource_pr_preservationzgit rev-parse z vs recorded PR#z headr   )recorded_head_sharecomputed_head_shaz9-R.2/source_pr/git-rev-parsesame_branch_push_zerozgit rev-list --count r~   r{   r   )rt   r   z9-R.2/same_branch_push/rev-list
fresh_basez9git rev-parse origin/main + git merge-base --is-ancestor z origin/mainr   r   )recorded_base_shar   is_ancestorz%9-R.2/fresh_base/origin-main-ancestorrx   uV   task-2553+6 §5 single-authority 6-file effective diff (#2=high_fix, D-SPEC-EXACTNESS)filesz#9-R.2/expected_files/spec-authoritygit_effective_diffr   r   PLANNED_DRY_RUNr   )base_shar   r   z9-R.2/effective_diff/git-diffforbidden_path_scanuC   effective_diff_files ∩ forbidden_write_targets (task-2553+6 §13)r   z9-R.2/forbidden/intersectioncritical_7_markerz9task-2553+1 Critical-7 classification marker (structured)r   z9-R.2/critical_7/markercodex_verdict_markerz4task-2553+1 Codex post-result marker `verdict` fieldverdictz9-R.2/codex_verdict/markerscope_declarationu3   task-2553+1.md F1-only least-privilege scope 선언F)	requires_credentialrequires_owner_patrequires_actual_apirequires_real_writerequires_limited_real_writerequires_mergerequires_auto_closeoutrequires_dev_status_changedeclared_scope_filesz9-R.2/scope/task-mdcallback_policy_markeruD   callback (a) STANDARDIZED marker (collector-only/no-write 인코딩)Tcollector_only)normalfallback	authorityno_writeno_dev_reactivationno_dispatchno_closeoutz9-R.2/callback/marker+invariantgo_ready_packet_claimsuC   GO-ready packet self-asserted booleans (hint-only, 비권위 9-R.3)claimed_booleans)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_changez9-R.3/packet-hint-only)r   r   r   r   r   r   rx   r   r   r   r   r   r   r   r    )scannedrc   z9-R.2/negative/rf   rz   u   19-kind 미정렬 — 누락: )schemar   evidence)
r?   r   rr   r   r   replacer   r3   r   stamp_provenance)r   r   r   rt   ru   rv   rw   rx   r   r   r   r   r   rq   srr   r   	scan_kindrk   missingbundles                        r:   build_evidence_bundler   5  s   , 
B}&'!5)!)
 
~	B|$J R+2,3+2
 !

 !$". 6(!.
 +!
 M'=A(
 #&$]O+;<L;MUS%9',-E'F ,	#
 "%##$8!$<#=RO!.,12L,M .	"
 Gbq!",0 &4+01J+K$%=>
 4
 .d>*+1
 " ,*!*-B1Be$567
 ,

  #!Q&-D(EF* 
 !G4
+,%
 !$"B&(!
 !A',&+',',/4"'*/.3(,^(<
 "
" #&$R - '+## .#
 #&$Q"(-"&49"'270505+09>',&+%*).%" %+#
O^ H~ 
	 "d2i=&9:i//<=>

 2GQQh5FqGGG;G9EFF .F
 !&)M Hs   	HHc                    t        |       j                         D ci c]  \  }}|dk7  s|| }}}t        |      }t        |ddd|d<   |S c c}}w )u   9-R.8 ``_provenance`` 미리보기 stamp. canonical sha = 실 번들 재해시
    (``_provenance`` 제외 — deriver/binding 과 동일 ``canonical_evidence_sha256``)._provenanceTr   )
derived_byevidence_bundle_sha256recomputed_all_gate_booleansderiver_version)rn   itemsr   r   )r   rk   vrY   shas        r:   r   r     sb     !L..0
GDAqA4F1a4
GC
G
#C
(C)"%(,"	C J Hs
   AAc                <   	 ddl }t        j                  t        |      j                  d            }	 |j                  t        |       |       y# t        $ r}t        d      |d}~ww xY w# |j                  $ r}t        d|j                         |d}~ww xY w)uN   evidence bundle 스키마 정적 검증 (jsonschema). 실패 → BuilderError.r   Nu0   jsonschema 미설치 — 스키마 검증 불가utf-8encodingu"   evidence bundle 스키마 위반: )
jsonschemaImportErrorr3   jsonloadsr   	read_textvalidatern   ValidationErrormessage)r   schema_pathr   rZ   r   s        r:   validate_bundler   #  s    V ZZ[)33W3EFFTDL&1	  VMNTUUV
 %% T?		{KLRSSTs.   A A. 	A+A&&A+.B=BBc                N   ddl }|j                  d      }|j                  dd       |j                  dd	       |j                  d
d       |j                  |       }t	        |j
                        }t        |j
                        |j                  z  }|j                         rt        ||       t        j                  |dd      dz   }|j                  r?t        |j                        j                  |d       t        d|j                          yt        |       y)uQ   standalone: 실 git → fixture 방출 (auto-derive fixture, _provenance 포함).r   Nz&PRE_AUTHORIZED evidence bundle builder)descriptionz--repoz/home/jay/workspacer@   z--outrz   z--schemar(   )r      F)indentensure_ascii
r   r   u   evidence bundle → )argparseArgumentParseradd_argument
parse_argsr   rW   r   r   r   r   r   dumpsrY   
write_textprint)argvr  prX   r   r   rH   s          r:   mainr
  2  s    ,TUANN8%:N;NN7BN'NND   <<D"TYY7Ftyy/DKK/K,::fQU;dBDxxTXX!!$!9$TXXJ/0  	dr9   __main__)returnrO   )rW   r   rX   rO   rA   z
str | Noner  rO   )rH   rO   r   rO   r  z	list[str])r   rO   r   rO   r   Mapping[str, Any]rp   rO   rq   rO   r  dict[str, Any])r   
str | Pathrt   rO   ru   rO   rv   rO   rw   rO   rx   Sequence[str]r  r  )r   rO   r   r  r   r   rt   rO   ru   rO   rv   rO   rw   rO   rx   r  r   r  r   rO   r   r   r   zMapping[str, Any] | Noner   r   r  r  )r   r  r  r  )r   r  r   r  r  Noneri   )r  zSequence[str] | Noner  r   )/r7   
__future__r   r   r_   rM   r   r   pathlibr   typingr   r   r	   r
   &anu_v3.pre_authorized_contract_deriverr   r   r   __annotations__r   r   r   r   	frozensetr   r&   r'   r)   r+   r,   r.   r0   r1   	Exceptionr3   r?   r[   rf   rr   r   r   r   r   r
  r4   
SystemExitr8   r9   r:   <module>r     s  6 #  	  '  0 0
 M
 L% %*T Z T"J Z J1 -  2;G2 . 
 151 D8 4 ? #%; &  # * "1z 1#M j MG
 G+R j RZ9 ZE AE >
 & 	
 	 , ' 4(2$@ii i 	i
 i i "i i\ !,& 4(2$@-P4&*]] ] 	]
 ] ] ] ] "] +] ] ] $] ] ]@TT,6T	T4 z
TV
 r9   