
    3jm                    R   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	 ddl
mZmZmZmZmZ ddlmZ ddl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<   e de!de"di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)e d*Z)ded+<    G d, d-e*      Z+ G d. d/e,      Z-dAd0Z.e G d1 d2             Z/dBd3Z0dBd4Z1dCd5Z2	 	 	 	 dDd6Z3dEd7Z4dFdGd8Z5dFdHd9Z6dAd:Z7e G d; d<             Z8dId=Z9dJd>Z:dKd?Z;g d@Z<y)Lu  anu_v3.profile_adoption_planner — STEP 2 profile engine operational
adoption 준비 planner (task-2553+42).

회장 3단계 지시 Step 2 (회장 GO, 코드/파일 자동화 — 문서-only 아님):
  +38 seam(`anu_v3.dispatch_profile_selection`) · +39 binding seam
  (`anu_v3.coordinator_profile_binding`) · C1 engine
  (`anu_v3.policy_profile_engine`) 를 **read-only 소비**하여, profile engine
  을 실 운영 dispatch selection / batch coordinator 경로에 연결할 때 touch
  될 live touchpoint 를 기계가독 enumeration 하고, adoption plan
  (expected_files allowlist 후보 · conflict set · risk tier(LOW/MED/HIGH))
  + read-only adoption dry-run(실 in-place adoption 0) 을 산출한다.

9-R.1 (본문 우선 — 2-layer 분리):
  - Layer A (deliverable module 경계): 본 모듈·dry-run 은 callback/collector
    **소스 경로를 읽거나 수정하지 않으며**, adoption 을 **실제 적용하지
    않는다**(plan + simulate only). seam/engine/coordinator/frozen anchor
    **byte-0**. module side-effect 0 (순수 — decision 경계 밖 I/O 는
    명시 hard-guarded helper 1개 `emit_adoption_plan` 한정).
  - Layer B (executor lifecycle): §8 normal completion callback 은 executor
    프로세스 종료 신호로 본 모듈의 책임 밖이다 (본 모듈은 cron 을 등록/
    제거/조작하지 않는다).

설계 invariant (§3 / §5 / 9-R.1):
  - 신규 별도 additive 모듈. engine·+38·+39·frozen
    `parallel_batch_coordinator.py`·callback frozen anchor·durable v1·
    +22~+41 원본 무수정.
  - +38/+39/C1 은 **import-only read-only 소비** (정본 module attribute
    introspection 만 — engine resolve_policy 를 live profile dir 에 대해
    실행하지 않는다; mutation 0, 파일 write 0, network 0, git 0, PR 0,
    merge 0, cron 0).
  - adoption 은 **계획·시뮬레이션만**. 실 in-place 연결 실행 0 — 실
    채택은 본 task 후 별도 회장 GO.
  - closeout/merge/auto-confirm 자동확정 0 (hard-pinned False).
  - 모든 decision-logic 메서드 = derive / propose / read only. 파일 I/O 는
    decision 경계 밖의 명시 hard-guarded helper 1개(`emit_adoption_plan`)
    한정.
  - 외부 의존성 0 (stdlib only — offline 100%).
    )annotationsN)	dataclassfield)Path)AnyDictFinalListMappingzanu_v3.profile_adoption_plannerz
Final[str]PLANNER_MODULEztask-2553+42.Step2.v1PLANNER_VERSIONz0anu_v3.profile_adoption_planner.adoption_plan.v1PLAN_SCHEMAz*anu_v3.profile_adoption_planner.dry_run.v1DRY_RUN_SCHEMAnoneADOPTION_LIFECYCLE_EFFECTz
Final[int]DRY_RUN_APPLIED_COUNTLOWRISK_LOWMEDRISK_MEDHIGH	RISK_HIGH      zFinal[Dict[str, int]]_RISK_ORDER)z"anu_v3/profile_adoption_planner.pyz)schemas/profile_adoption_plan.schema.jsonz<tests/regression/test_profile_adoption_planner_2553plus42.pyzmemory/fixtures/task-2553+42.*z(memory/events/task-2553+42.decision.jsonz&memory/events/task-2553+42.result.jsonz-memory/events/task-2553+42.adoption-plan.jsonzmemory/reports/task-2553+42.mdzFinal[tuple[str, ...]]EXPECTED_FILES_ALLOWLIST)zanu_v3/policy_profile_engine.pyz$anu_v3/dispatch_profile_selection.pyz%anu_v3/coordinator_profile_binding.py$anu_v3/parallel_batch_coordinator.py+utils/anu_delegation_completion_callback.py#task-2553.parallel-batch-state.jsonFROZEN_ANCHORS)r   z$anu_v3/executor_callback_contract.pyCALLBACK_COLLECTOR_PATHSr   _FROZEN_DURABLE_V1z.adoption-plan.json_DELIVERABLE_SUFFIXz"plan_schema": ""_DELIVERABLE_MARKERc                  $     e Zd ZdZd fdZ xZS )ProfileAdoptionPlannerErroruJ   planner 산출 실패. ``self.code`` = 실패 사유 코드 (fail-closed).c                L    t         |   d| d|        || _        || _        y )N[z] )super__init__codemessage)selfr,   r-   	__class__s      6/home/jay/workspace/anu_v3/profile_adoption_planner.pyr+   z$ProfileAdoptionPlannerError.__init__l   s+    1TF"WI./	    )r,   strr-   r2   returnNone)__name__
__module____qualname____doc__r+   __classcell__)r/   s   @r0   r'   r'   i   s    T r1   r'   c                      e Zd ZdZy)FrozenWriteRefusedu   frozen / git-tracked / 무관 untracked 파일 write 거부. plan
    deliverable 은 별도 NEW untracked 경로여야 한다 (§4/§5).N)r5   r6   r7   r8    r1   r0   r;   r;   r   s    Kr1   r;   c            	        t         j                  t         j                  dddgddt        j                  t        j
                  t        j                  ddgt        j                  t        j                  t        j                  t        j                  gdt        j                  t        j                  t        j                  t        j                  d	d
gdddS )uT  +38 seam · +39 binding seam · C1 engine 의 정본 contract 를
    **read-only attribute introspection** 으로 소비한다.

    engine resolve_policy 를 live profile dir 에 대해 실행하지 않는다 —
    module attribute 만 읽는다 (mutation 0, side-effect 0). 반환은 순수
    dict (engine/seam 객체 노출 0).
    z(anu_v3.policy_profile_engine.decision.v1parse_goal_requestresolve_policyuD   pure — GitHub API 0, token 0, 파일 write 0 (docstring invariant))moduleversiondecision_schemaprimary_apiside_effect_contractselect_profile_for_dispatchrun_dispatch_profile_selection)r@   rA   selection_schemaentrypointslifecycle_effectfail_closed_statusconsume_for_coordinatorload_profile_decisionuR   closeout/merge/auto_confirm hard-pinned False (coordinator=판단보조 소비만))r@   rA   binding_schemaaccepted_decision_schemarH   auto_confirm_invariant)enginedispatch_seamcoordinator_binding_seam)_ppeENGINE_MODULEENGINE_VERSION_dpsSEAM_MODULESEAM_VERSIONSELECTION_SCHEMA_IDDISPATCH_LIFECYCLE_EFFECTSTATUS_SELECTEDSTATUS_REFUSEDSTATUS_HOLD_cpbBINDING_MODULEBINDING_VERSIONBINDING_SCHEMAACCEPTED_DECISION_SCHEMAr<   r1   r0   introspect_seamsrc   z   s     ((**I02BC(	
 &&(( $ 8 8-0 !% > >$$##  #
  ))++"11(,(E(E57NO7
%
5% %r1   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ed<   ded<   ddZy)AdoptionTouchpointuJ   실사용 연결 시 touch 될 live 경로 1건의 기계가독 기술자.r2   touchpoint_idtrackseam_moduleseam_entrypointconsumesz	List[str]live_target_candidatesadoption_kindboolin_place_edit_requiredtouches_frozen_anchortouches_callback_collector	risk_tier	rationalec                "   | j                   | j                  | j                  | j                  | j                  t        | j                        | j                  | j                  | j                  | j                  | j                  | j                  dS )Nrf   rg   rh   ri   rj   rk   rl   rn   ro   rp   rq   rr   )rf   rg   rh   ri   rj   listrk   rl   rn   ro   rp   rq   rr   )r.   s    r0   to_dictzAdoptionTouchpoint.to_dict   su    !//ZZ++#33&*4+F+F&G!//&*&A&A%)%?%?*.*I*I
 	
r1   Nr3   Dict[str, Any])r5   r6   r7   r8   __annotations__rv   r<   r1   r0   re   re      sN    TJM%%   $$NN
r1   re   c                    | t         v S N)r    paths    r0   
_is_frozenr~      s    >!!r1   c                    | t         v S r{   )r!   r|   s    r0   _is_callback_collectorr      s    +++r1   c                   | d   }| d   }| d   }g }g d}|j                  t        dd|d   d|d    d	|d
dt        d |D              t        d |D              t        d             d}d}|j                  t        dd|d   d|d    d||gddt	        |      dt
        d| d| d             |j                  t        dd|d   ddg d dddt        d!             |S )"uS  seam introspection → 실사용 연결 touchpoint enumeration.

    실사용 grep 결과(현재 어떤 live dispatch/coordinator 도 seam 을 호출하지
    않음 — 실 adoption 미수행)를 전제로, adoption 시 touch 될 live 경로를
    derive 한다. live target 후보는 **문자열로만 기술**(읽기·수정 0).
    rQ   rR   rP   )zdispatch/core.pyzdispatch/prompt.pyz!anu_v3/active_dispatch_scanner.pyzTA.dispatch_selection_wireAr@   rF   z% (parse_goal_request, resolve_policy)u~   live dispatch 경로가 seam file-level contract 를 호출하도록 in-place wire (seam byte-0 — live 측만 추가 호출)Tc              3  2   K   | ]  }t        |        y wr{   )r~   .0ps     r0   	<genexpr>z(enumerate_touchpoints.<locals>.<genexpr>   s     %Hjm%H   c              3  2   K   | ]  }t        |        y wr{   )r   r   s     r0   r   z(enumerate_touchpoints.<locals>.<genexpr>   s      +./&q)+r   u   seam DISPATCH_LIFECYCLE_EFFECT=='none' (선택만, 실행 0) — live 측 tracked dispatch 코드에 1 call-site 추가 필요 (가역, frozen 무접촉). 실 적용은 별도 회장 GO.rt   r   z#anu_v3/generic_batch_coordinator.pyzTB.coordinator_binding_consumeBrK   rN   z) (engine decision.v1 file-level contract)ux   batch coordinator 가 engine decision.v1 을 binding seam 통해 read-only 소비 (closeout/merge 자동확정 0 불변)Fu   후보 ug    는 frozen anchor(byte-0) — 그 경로 in-place adoption 은 §5/§6 위반(CONFLICT). 안전 route=uG    (non-frozen, MED)로 한정해야 함. 실 적용은 별도 회장 GO.zTE.engine_decision_emitC1u4   resolve_policy → PolicyResolution.to_decision_dictu+   (none — engine 은 decision.v1 생산측)un   engine 은 이미 decision.v1 contract 를 노출 — adoption 시 engine in-place edit 불요 (byte-0 유지)u\   engine 정본 API 가 이미 완비 — additive contract, adoption 시 engine 무변 (LOW).)appendre   anyr   r~   r   r   )introspectiondscbengtps
ta_targets	tb_frozentb_safes           r0   enumerate_touchpointsr      ss    
	'B	1	2B

!C$&CJ
 JJ68<H&KL#-L $("%%HZ%H"H'* +3=+ ( N%	
6 7I3GJJ:85012 3' ' %.w#7Q $(",Y"7',) %GGNi PYY'	
8 JJ3HRB#%> $)"'',4!	
, Jr1   c           	        g }g }| D ]j  }|j                   D ]Y  }t        |      r |j                  |j                  |ddd       t	        |      s:|j                  |j                  |ddd       [ l g ||D ch c]  }|d   |d   f }}||t        t              t        t              t        |      dS c c}w )	uG  frozen anchor / callback-collector 와 충돌하는 adoption 후보 식별.

    conflict = frozen anchor 를 in-place touch 하거나 callback/collector
    경로를 건드리는 live target 후보 (그 route 는 §5/§6 위반 — 안전 route
    로 한정 필요). fail-closed: 충돌 후보를 누락 없이 등재.
    u1   frozen anchor byte-0 — in-place adoption 금지u9   non-frozen 안전 route 로 한정 (frozen 경로 배제))rf   	candidatereasonrequired_mitigationu+   callback/collector 경로 — §5 무접촉u   해당 route 전면 배제rf   r   )frozen_anchor_conflictscallback_collector_conflictsfrozen_anchorscallback_collector_pathsconflict_count)	rk   r~   r   rf   r   ru   r    r!   len)touchpointsfrozen_conflictscallback_conflictstpcandcdistinct_routess          r0   classify_conflictsr   ?  s     .0/1 -- 	D$ '')+)9)9%)"UW	 &d+")))+)9)9%)"O/K		6 :#9&89 
?	Q{^,O 
 $4(:~.$()A$Bo. 	s   =B;c                <    | st         S t        d | D        d       S )u@   touchpoint 중 최고 risk tier (fail-closed — 최악 우선).c              3  4   K   | ]  }|j                     y wr{   )rq   )r   r   s     r0   r   z$overall_risk_tier.<locals>.<genexpr>u  s     ,",s   c                D    t         j                  | t         t                 S r{   )r   getr   )rs    r0   <lambda>z#overall_risk_tier.<locals>.<lambda>v  s    kooaY)?@ r1   )key)r   max)r   s    r0   overall_risk_tierr   p  s"    ,,@ r1   c                   | t        |       n	t               }t        |      }t        |      }t	        |      }i dt
        dt        dt        dddddt        d	d
d|d|D cg c]  }|j                          c}dt        t              d|d||D ci c]  }|j                  |j                   c}t        t        t         gddt        t"              ddddddS c c}w c c}w )u   expected_files allowlist 후보 · conflict set · risk tier 를 담은
    기계가독 adoption plan. 실 adoption 0 (plan only).plan_schemaplanner_moduleplanner_versiontasktask-2553+42stepu5   Step 2 — profile engine operational adoption 준비adoption_lifecycle_effectreal_in_place_adoption_countr   seam_introspectionr   expected_files_allowlistconflictrisk)overall_tierper_touchpointtiersbyte0_anchorscallback_collector_untouchedTrO   uT   closeout/merge/auto_confirm 자동확정 0 (hard-pinned False, 모든 입력 불변)real_adoption_gateu]   실 in-place adoption 은 본 task 후 별도 회장 GO — 본 산출은 plan + dry-run only)dictrc   r   r   r   r   r   r   r   rv   ru   r   rf   rq   r   r   r   r    )r   intror   	conflictsoverallr   s         r0   build_adoption_planr   }  s_    $1#<DBRBTE

&C"3'I$G{. 	? 		
 	G 	$%> 	' 	e 	s3

3 	#D)A$B 	I 	#9<35  ",,. )4
& 	n-'( 	')* 	!$-2 	"5  4
s   'C'C,
c           	        | t        |       n	t               }g }g }g }g }|d   D ]  }|d   s|j                  |d   ddd       "|d   D cg c]  }|t        vr
|t        vr| }}|d   D cg c]  }|t        v s| }	}|d   D cg c]  }|t        v r| }
}|	D ]  }|j                  |d   |dd	        |
D ]  }|j                  |d   |d
d	        |s|j                  |d   dddd       |j                  |d   d|d    d| dddd       |j                  |d   dd        i dt
        dt        dt        dddddt        ddddd dd!dd"dd#dd$|d%|d&|d'|d(d)S c c}w c c}w c c}w )*u   실 in-place 연결을 **시뮬레이션만** — 예상 diff·conflict·rollback
    지점을 산출하되 적용 0 (write/merge/cron/PR 0, callback/collector 무접촉).
    r   rn   rf   u&   NONE (additive contract 이미 완비)F)rf   changeappliedrk   u*   BLOCKED (frozen byte-0 — dry-run 거부))rf   r   decisionu>   BLOCKED (callback/collector — §5 무접촉, dry-run 거부)uf   NO_SAFE_ROUTE — 모든 후보가 frozen/callback-collector (chair routing 필요, 시뮬레이트 0)u   (none — safe route 부재))rf   r   expected_hunkr   u   +1 call-site → ri   u    (safe route 후보: )uI   live 측 단일 호출 추가 (seam byte-0; live 코드만 가역 추가)u   추가된 single call-site 제거 (git revert of live edit) — seam/engine/coordinator 무변이므로 rollback 은 live 1-hunk 한정)rf   rollbackdry_run_schemar   r   r   r   modeREAD_ONLY_SIMULATIONapplied_countwritesr   mergescron_opspr_opscallback_collector_touchedfrozen_anchor_touchedsimulated_diffsblocked_frozen_routesblocked_callback_routesrollback_pointsside_effectu2   none (simulation only — 실 in-place adoption 0))	r   r   r   r    r!   r   r   r   r   )planr   r   r   blockedblocked_callbackr   r   safe_targetsfrozen_targetscallback_targetsftcts                r0   dry_run_adoptionr     s    &T
,?,AA,.O,.O$&G-/ N
*+""%'%8F$  01
&14L+L 
 
 23
qN7JA
 

 01
,, 
 

 ! 	BNN%'%8!# L	 # 	B##%'%8!# `	  ""%'%8D &D$
 !#O!4'+<(='> ?++7.; ` 
	
 	!#O!4^	
MN
`.. 	? 		
 	& 	. 	! 	! 	A 	! 	%e 	  	? 	  	"#3  	?!" 	K# M



s   E:0E?>E?Fc                 >    t               } t        |       }dd| |dddS )uN   plan + dry-run 을 단일 호출로 산출 (순수 — write/merge/cron/PR 0).z)anu_v3.profile_adoption_planner.bundle.v1r   FT)schemar   adoption_plandry_runreal_in_place_adoptionr   )r   r   )r   drys     r0   run_adoption_plannerr     s0     D
4
 C="'(, r1   c                  *    e Zd ZU  ee      Zded<   y)AdoptionPlannerFixture)default_factoryzList[Dict[str, Any]]casesN)r5   r6   r7   r   ru   r   ry   r<   r1   r0   r   r   *  s    "'"=E=r1   r   c                    t        j                  t        |       j                  d            }t	        t        |j                  dg                   S )Nutf-8encodingr   )r   )jsonloadsr   	read_textr   ru   r   )fixture_pathdatas     r0   load_planner_fixturer   /  s>    ::d<(22G2DED!TXXgr-B(CDDr1   c                ^   	 t        j                  ddt        | j                        ddgdd      }|j                  dk7  ry|j
                  j                         }t        j                  dd|d	d
t        | j                               gdd      }|j                  dk(  S # t        $ r Y yw xY w)Ngitz-Cz	rev-parsez--show-toplevelT)capture_outputtextr   Fzls-filesz--error-unmatch)	
subprocessrunr2   parent
returncodestdoutstripresolve	Exception)r   topreporcs       r0   _is_git_trackedr  7  s    nnD#ahh-6GH

 >>Qzz!^^D$
,=s199;?OP

 }}!! s   ?B  AB   	B,+B,c                   t        |      }t        D ch c]  }t        |      j                   }}|j                  t        k(  s|j                  |v rt	        d| d      t
        D ch c]  }t        |      j                   }}	 t        |j                               j                  dd      |j                  |v st        fdt
        D              rt	        d| d      t        |      rt	        d| d	      |j                         rK|j                  j                  t              }|s	 t        |j!                  d
      v }|st	        d| d      |j$                  j'                  dd       |j)                  t+        j,                  | dd      dz   d
       |S c c}w c c}w # t        $ r t        |      j                  dd      Y &w xY w# t        t"        f$ r d}Y w xY w)u  NEW untracked adoption-plan 파일 write. decision component 아님 —
    runner/ANU 가 수행하는 명시 I/O (9-R.1 경계 밖, Layer A 의 module
    side-effect 아님).

    Hard write-guard (§4/§5 — +39 가드 미러, 무관 파일 절대 clobber 0):
      * chair durable v1 name              -> REFUSE (byte-0 immutable)
      * frozen anchor basename             -> REFUSE (byte-0)
      * git-tracked path                   -> REFUSE (tracked HEAD invariant)
      * untracked & non-existent           -> ALLOW  (NEW deliverable)
      * untracked & existing sanctioned    -> ALLOW  (idempotent re-emit)
      * untracked & existing non-deliver.  -> REFUSE (무관 파일 보호)
    z'refusing to write frozen/byte-0 anchor u    (§5)\/c              3  @   K   | ]  }j                  |        y wr{   )endswith)r   r   _rels     r0   r   z%emit_adoption_plan.<locals>.<genexpr>f  s      $a$s   u0   refusing to write/read callback·collector path u:    (§5 무접촉, 9-R.1 Layer A — read 도달 전 차단)z#refusing to write git-tracked path uA    (§5 tracked HEAD invariant — only NEW untracked deliverables)r   r   Fz9refusing to overwrite existing untracked non-deliverable z[ (only a NEW untracked path or this planner's own adoption-plan deliverable may be written)T)parentsexist_okr   )ensure_asciiindent
)r   r    namer"   r;   r!   r2   r  replaceOSErrorr   r  existsr  r#   r%   r   UnicodeDecodeErrorr  mkdir
write_textr   dumps)	r   out_pathoutafrozen_namesr   	_cc_names
sanctionedr  s	           @r0   emit_adoption_planr'  K  s    x.C*89QDGLL9L9
xx%%\)A 5cU&A
 	
 (@@!a@I@+3;;=!))$4 xx9 $":$ ! !>se DH H
 	
 s 1# 7= =
 	
 zz|XX&&':;
#0CMM$ 5B 5 

 $K% <= 
 JJTD1NN

4eA6=   J[ : A  +3xc*+* /0 #"
#s/   F(+F-
)F2 4G 2$GGG10G1)r   r   r   r   r   r   r   r   r   r   r    r!   r'   r;   re   r   rc   r   r   r   r   r   r   r   r'  rw   )r}   r2   r3   rm   )r   Mapping[str, Any]r3   List[AdoptionTouchpoint])r   r)  r3   rx   )r   r)  r3   r2   r{   )r   Mapping[str, Any] | Noner3   rx   )r   r*  r3   rx   )r   'str | Path'r3   r   )r   r   r3   rm   )r   r(  r!  r+  r3   r   )=r8   
__future__r   r   r  dataclassesr   r   pathlibr   typingr   r   r	   r
   r   "anu_v3.coordinator_profile_bindingcoordinator_profile_bindingr^   !anu_v3.dispatch_profile_selectiondispatch_profile_selectionrV   anu_v3.policy_profile_enginepolicy_profile_enginerS   r   ry   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r%   
ValueErrorr'   RuntimeErrorr;   rc   re   r~   r   r   r   r   r   r   r   r   r   r  r'  __all__r<   r1   r0   <module>r9     s  %L #   (  2 2 1 0 +>
 >5 5LZ LI
 I )/ : .$% z % * * 	: &.8Q	1%M" M	4 0 	*& 4 0  "G J F"7 Z 7$4[M"C Z C* K K-f 
 
 
B",bP.)..b$Tld" > > >E(;|r1   