
    3jԍ                       d Z ddlmZ ddlZddlZddl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mZmZ dZdZd	Z ee      j1                         Zd
ZdZdZeeefZdZdZdZ dZ!dZ" G d de#      Z$ G d de%      Z&d=dZ'h dh ddZ(ddhZ)d>dZ*e
 G d d             Z+e
 G d d              Z,d?d!Z-d@dAd#Z.g d$Z/g d%Z0dBd&Z1dCd'Z2dDd(Z3dDd)Z4dDd*Z5ee3ee4ee5iZ6	 d@	 	 	 	 	 dEd+Z7dFd,Z8dGd-Z9dHd.Z:d/d0	 	 	 	 	 	 	 dId1Z;d/d"d2	 	 	 	 	 	 	 	 	 dJd3Z<dKd4Z=d5efd6efd7effZ>dLd8Z?dMd9Z@dNdOd:ZAg d;ZBeCd<k(  r eD eA             y)Pu_  anu_v3.auto_remediation_planner — task-2612 Track C (plan-only).

회장 verbatim (task-2612 §1/§2): "Critical7이 아니면 ANU-Codex loop로 자동
remediation 하여 all-settled 까지 진행하는 구조를 구현한다(remediation plan
생성부)."

본 모듈은 batch HOLD 분류 결과를 입력받아 **새 task ID remediation spec
골격**(목표/필수/금지/expected_files/9-R)으로 변환하는 *생성기* 다. 세 유형:

  - ``GLOBAL_LEDGER_SHA_FALSE_POSITIVE`` (2604 유형) — 전역 ledger SHA
    하드핀이 sanctioned cross-track append 와 자가모순(false-positive)
    → track-scoped invariant 교정 plan.
  - ``STAGE_CLAIM_TEST_MISMATCH`` (2605 유형) — claimed real-entrypoint
    stage 가 실증되지 않음(부분 stage 만 real·regression range 절단)
    → spy/monkeypatch 실호출 증명 보강 plan (mock-only FAIL 강제).
  - ``COVERAGE_GAP`` (2609 유형) — mandated fixture 가 특정 standalone
    조건을 한 번도 exercise 하지 않아 verdict logic 미망라
    → coverage 보강 plan (fail-safe 방향 실증).

분류 규칙 (회장 §3/§6 verbatim): Critical7 또는 shared invariant 파손 →
``HOLD_FOR_CHAIR``. 그 외 non-Critical 은 ``AUTO_REMEDIATION_HOLD`` 로
자동 수렴(회장 개별 확인 대기 없음). Critical7 판정 자체는 TrackB
critical7_classifier 소관 — 본 planner 는 그 분류 결과(``is_critical7``)를
**입력으로만 소비**한다(중복 소유 0·DISJOINT 보존).

**plan only**: 본 모듈은 plan 골격 *생성* 만 수행한다. 실제 dispatch /
코드수정 / subprocess / cokacdir / cron / merge / PR / credential 표면을
import 하거나 호출하지 않는다(§2/§5). ``PLAN_ONLY`` / ``DISPATCH_PERFORMED``
불변식 + ``assert_plan_only`` 정적 가드로 강제한다.

비-문서 산출: 본 모듈은 실 entrypoint(``build_plan_from_adjudication`` /
``main`` CLI)를 갖는다. ``run_self_check`` 는 mock 0 으로 실제 2604/2605/
2609 adjudication 증거 파일을 read-only consume → 실 plan 을 생성·스키마
검증한다(mock-only 경로는 본질적으로 plan 을 못 만들어 FAIL).
    )annotationsN)	dataclassfield)Path)AnyDictListOptionalSequencecastzanu_v3.auto_remediation_plan.v1z)schemas/auto_remediation_plan.schema.jsonz/home/jay/workspace GLOBAL_LEDGER_SHA_FALSE_POSITIVESTAGE_CLAIM_TEST_MISMATCHCOVERAGE_GAPAUTO_REMEDIATION_HOLDHOLD_FOR_CHAIR)LOWMEDIUMHIGHCRITICALTFc                      e Zd ZdZy)PlanOnlyViolationu@   planner 가 dispatch/side-effect 표면을 건드리려 할 때.N__name__
__module____qualname____doc__     6/home/jay/workspace/anu_v3/auto_remediation_planner.pyr   r   O   s    Jr   r   c                      e Zd ZdZy)PathContainmentErroru2  입력 경로가 CANONICAL_WS_ROOT 하위 strict containment 를 벗어남.

    H1(``_read_json`` read-path)·H2(``expected_files`` module_rel/test_rel)
    공통 fail-closed 신호 — ``..`` traversal·임의 절대경로·symlink 이탈을
    거부한다(downstream out-of-scope 유도 차단).
    Nr   r   r   r   r!   r!   S   s    r   r!   c                    t        |       }|j                         r|nt        |z  }|j                         }|t        k(  st        |j                  vrt        d| d|       |S )u  입력 경로를 CANONICAL_WS_ROOT 기준 resolve 후 strict containment 검증.

    - 상대경로는 ``CANONICAL_WS_ROOT`` 기준 결합, 절대경로는 그대로 사용.
    - ``Path.resolve()`` 로 ``..`` 정규화 + symlink 실체화한 뒤,
      결과가 ``CANONICAL_WS_ROOT`` 의 진정한 하위(root 자기 자신 제외)인지
      검증한다. 이탈 시 ``PathContainmentError`` (fail-closed).
    z.path escapes CANONICAL_WS_ROOT (fail-closed):  -> )r   is_absoluteCANONICAL_WS_ROOTresolveparentsr!   )pathraw	candidateresolveds       r   _contained_resolvedr,   \   so     t*C(/@3/FI  "H$$(9AQAQ(Q"<hd8*&
 	
 Or   >   runcallPopen	getoutput
check_callcheck_outputgetstatusoutput>   execvpopenexecvpspawnvsystemposix_spawn)
subprocessosr8   r/   c                    t         rt        rt        d      t        t              j                  d      } t        j                  |       }t        j                  |      D ]  }t        |t        j                        s|j                  }t        |t        j                        ryt        |j                  t        j                        rU|j                  j                  |j                   }}|t"        j%                  |t'                     v st        d| d| d      t        |t        j                        s|j                  t(        v st        d|j                   d       y)u6  정적 자기검증: 본 소스에 dispatch/side-effect *실호출* 이 없음을 확인.

    문자열 리터럴/주석/docstring 의 토큰 언급은 허용하고, AST Call 노드
    (``subprocess.run(...)``, ``os.system(...)`` 등 실제 호출)만 탐지한다.
    위반 시 ``PlanOnlyViolation``.
    z-PLAN_ONLY/DISPATCH_PERFORMED invariant brokenutf-8)encodingz dispatch surface call detected: .z(...)N)	PLAN_ONLYDISPATCH_PERFORMEDr   r   __file__	read_textastparsewalk
isinstanceCallfunc	AttributevalueNameidattr_FORBIDDEN_ATTR_CALLSgetset_FORBIDDEN_BARE_CALLS)srctreenodefnmodrN   s         r   assert_plan_onlyrX      s    0 OPP
x.
"
"G
"
4C99S>D $)YYb#--(Z#((-KRWWC,00ce<<'6se1TF%H  CHH%"%%3H*H#2255'? r   c                      e Zd ZU dZded<   ded<   dZded<   dZded	<   dZded
<   dZded<    e	e
      Zded<    e	e      Zded<   ddZy)IssueClassificationu   batch HOLD 분류 결과(planner 입력).

    ``is_critical7`` 은 TrackB critical7_classifier 산출 — 본 planner 는
    소비만 한다. ``shared_invariant_broken`` 은 TrackA batch_hold_
    adjudicator 류 산출의 신호.
    strsource_task
issue_typer   severityFboolis_critical7shared_invariant_broken summary)default_factory	List[str]evidence_refsDict[str, object]detailc                    | j                   t        vr t        d| j                   dt         d      | j                  t        vrt        d| j                        y )Nzunknown issue_type z (expected one of )zunknown severity )r]   ISSUE_TYPES
ValueErrorr^   
SEVERITIESselfs    r   __post_init__z!IssueClassification.__post_init__   sc    ??+-%doo%8 9$$/=3  ==
*00ABCC +r   NreturnNone)r   r   r   r   __annotations__r^   r`   ra   rc   r   listrf   dictrh   rp   r   r   r   rZ   rZ      sb     OHcL$$)T)GS$T:M9: %d ;F;Dr   rZ   c                      e Zd ZU 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ed<   ded<   ddZy)RemediationPlanr[   schemaplan_idremediation_ofr]   dispositionr^   r_   r`   	plan_onlydispatch_performedshared_invariant_preservedhold_for_chairre   reasonssource_evidence_refsrg   spec_skeletonc                `   | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  t        | j                        t        | j                        | j                  dS )Nry   rz   r{   r]   r|   r^   r`   r}   r~   r   r   r   r   r   )ry   rz   r{   r]   r|   r^   r`   r}   r~   r   r   ru   r   r   r   rn   s    r   to_dictzRemediationPlan.to_dict   s    kk||"11//++ --"&"9"9*.*I*I"11DLL)$()B)B$C!//
 	
r   Nrr   rg   )r   r   r   rt   r   r   r   r   rx   rx      sV    KLOMO $$##$$
r   rx   c                J    | j                   s| j                  rt        S t        S )u   Critical7 또는 shared invariant 파손 → HOLD_FOR_CHAIR.
    그 외 non-Critical → AUTO_REMEDIATION_HOLD 자동 수렴 (회장 §6 verbatim).)r`   ra   DISPOSITION_CHAIRDISPOSITION_AUTO)issues    r   classify_dispositionr      s!     U::  r      c                0    |dk  rt        d      |  d| S )u   원 HOLD task ID → 새 remediation task ID 골격(plan 식별자).

    실제 dispatch 시 ANU 가 확정 — 여기서는 결정적 default 만 제시한다.
    r   zround_no must be >= 1-AR)rl   )r\   round_nos     r   next_plan_idr      s(    
 !|011]#hZ((r   )z+ANU-Codex lint = GO_READY (HIGH/CRITICAL 0)uj   실 entrypoint regression PASS · mock-only 경로는 반드시 FAIL (문서-only/mock-only 완료 금지)u>   expected_files allowlist 외 write 0 · 타 track 과 DISJOINTu`   shared invariant 보존 (기존 task-2553·task-2604 multitrack 산출물·frozen anchor byte-0)uG   git HEAD/branch 전후 EQUAL · PR/merge/branch/main write/credential 0uk   executor self-* (callback/collector/adjudication/dispatch) 0 · independent ANU collector 만 authoritative)uO   기존 산출물 변조 (task-2553·task-2604 multitrack·frozen anchor byte-0)uC   문서-only / mock-only 완료 (실 entrypoint + regression 필수)zEexecutor self-callback/self-collector/self-adjudication/self-dispatchu$   independent ANU authoritative 약화u-   fallback/dead-man/fixed-time 진행 트리거u'   PR/branch/main write·merge·credentialc                    | j                  d      r| j                  d      r| S t        |       j                  t              j                         S )u  H2 hardening: module_rel/test_rel 을 ``expected_files`` 유입 전 정규화.

    골격 placeholder(``<...>``)는 실경로가 아니므로 그대로 통과해 기존
    plan 골격(2604/2605/2609) 동작을 byte-0 보존한다. 실경로 형태는
    CANONICAL_WS_ROOT 하위 strict containment 로 정규화하며, ``..``
    traversal·절대경로 이탈·symlink 이탈 시 ``PathContainmentError``
    (fail-closed — downstream executor 의 out-of-scope 경로 유도 차단).
    <>)
startswithendswithr,   relative_tor%   as_posix)rels    r   _normalize_expected_relr     s@     ~~cs||C0
s#//0ABKKMMr   c                L    t        |      t        |      d|  dd|  dd|  dgS )Nzmemory/events/z.decision.jsonz.result.jsonzmemory/reports/z.md)r   )rz   
module_reltest_rels      r   _expected_filesr     s@    
+)
	0
	.
'#& r   c                   t        |j                  j                  dd            }t        |j                  j                  d|            }t        |j                  j                  d|            }| |  dd|j                   ddgd	d
dd| dgt	        t
              dgz   t        | ||      t	        t              dgz   dddS )uI   2604 유형: global ledger SHA false-positive → track-scoped invariant.target_testz<HOLD test/fixture>r   r   uE    — global ledger SHA false-positive 교정 (track-scoped invariant)/   단일 executor 1회 한정 · ANU key callbacku    의 전역 ledger SHA 하드핀(full-file hardpin)을 track-scoped invariant 로 교정하여 sanctioned cross-track append 와의 자가모순(false-positive)을 제거한다.uD   기능 로직은 무변경 — test-harness invariant 한정 교정.u   전역 SHA/full-file 하드핀 제거 → track-scoped invariant 로 대체: (a) 본 track row 의 shared ledger self-append 0, (b) pre-existing prefix byte 보존(변조 0), (c) append-only 성장만 허용(축소/재작성 = FAIL).u]   sanctioned/sibling +53/+54 durable-success append 는 무FAIL (false-positive 제거 실증).u   append-only 위반(shrink/rewrite/prefix-tamper/self-row)은 여전히 FAIL — isolated /tmp ledger self-proof 로 양방향 증명.u~   실 regression: 교정 전 FAIL(전역 하드핀이 sanctioned append 에서 collection-time FAIL) → 교정 후 PASS 재현.u4    외 기능 본문 byte-0 (s1..sN 동작 무변경).u3   기능 로직 변경(test-harness invariant 한정)ur   track-scoped invariant 3요소(self-append 0·prefix 보존·append-only) 정합 · 전역 하드핀 완전 제거Fgo_ready_criteriarelint_requiredtask_idtitleexecutor_hintgoalmust	forbiddenexpected_filesnine_rr[   rh   rP   r\   ru   _COMMON_FORBIDDENr   _COMMON_NINE_R)rz   r   targetr   r   s        r   _skeleton_2604r     s   !!-1FGHFU\\%%lF;<J5<<##J78H9 # #J  ! "V V S	
I.WGhJK
 +,@
AB)':xH!%n!5H"
  %
7# #r   c                   t        |j                  j                  dd            }|j                  j                  dd      }t        |j                  j                  dd            }t        |j                  j                  dd            }| |  d	| d
d|j                   d| d| dg| dd| d| ddd| ddgt	        t
              dgz   t        | ||      t	        t              | dgz   dddS )uL   2605 유형: stage claim/test mismatch → spy/monkeypatch 실호출 증명.claimed_stagestage9regression_rangezrange(1, N)r   z<entrypoint module>r   <regression test>u    — uE    claim/test mismatch 교정 (spy/monkeypatch 실호출 증명 보강)r   u    의 claimed real-entrypoint uK    가 실증되지 않은 mismatch 를 해소한다 — spy/monkeypatch 로 uK    실호출을 증명하고 regression range 를 전 stage 로 확장한다.u    의 실 entrypoint 호출을 spy/monkeypatch 로 포착 — 호출 횟수·인자·반환을 단언(claim 과 test 일치 실증).u   regression range 를 u$    → 전 stage 포함으로 확장 (u    누락 0).u   mock-only 테스트는 반드시 FAIL 하도록 가드: 실 호출이 spy 에 잡히지 않으면 assertion 실패(허위 PASS 차단).u9   기존 stage 1..N-1 regression 무회귀(0 regression) + u    additive 강화.uI   실 entrypoint 직접 호출(REAL) · 인접 PASS track 산출물 byte-0.u@   claim 만 수정하고 test 미보강(역방향 mismatch 은폐)um    실호출 spy/monkeypatch 단언 통과 · regression range 전 stage 망라 · mock-only 경로 FAIL 실증Fr   r   r   )rz   r   stagerngr   r   s         r   _skeleton_2605r   J  sX     (;<E
,,

-}
=CU\\%%l4IJKJ5<<##J0CDEH9E% )4 4J  !!>ug FUg 
 g U U#C5 )wk#PGg&(W

 +,M
NO)':xH!%n!5' I I"
  %
3! !r   c                
   |j                   j                  ddg      }t        |t              r|gn&t	        t
        |      D cg c]  }t        |       c}}t        |j                   j                  dd            }t        |j                   j                  dd            }| |  dd|j                   d	gd
t        |       dddddgt        t              dgz   t        | ||      t        t              dgz   dddS c c}w )u3   2609 유형: coverage gap → coverage 보강 plan.uncovered_conditionsz&<standalone condition never exercised>r   z<verdict module>r   r   uE    — coverage gap 보강 (미망라 standalone 조건 fixture 추가)r   u    의 verdict logic 미망라 coverage gap 을 보강한다 — mandated fixture 가 한 번도 exercise 하지 않은 standalone 조건을 격리 fixture 로 추가한다.uZ   미망라 조건마다 해당 조건만 false/standalone 으로 격리한 fixture 추가: r?   u   각 추가 fixture 가 실 entrypoint(judge/verdict 함수) 위에서 fail-safe 방향(보수적 HOLD/non-merge)으로 결정적 수렴함을 실증 — 위험 방향(auto-merge/PASS)으로 새지 않음.uf   기존 §-mandated regression 전부 무회귀(verdict + critical7 match 유지) + additive 보강만.u8   spec-mandated regression 누락 0 · invariant 약화 0.uS   실 entrypoint 직접 호출(REAL) · mock-only 는 coverage 미증명 으로 FAIL.u3   기존 mandated fixture 의 expected verdict 변조ux   미망라 조건 격리 fixture 전부 fail-safe 방향 실증 · 기존 mandated regression 무회귀 · coverage gap 0Fr   r   )
rh   rP   rG   r[   r   ru   r\   r   r   r   )rz   r   _ucx	uncoveredr   r   s          r   _skeleton_2609r   t  s:   ,,""	12C
 C%DsO+LqCF+L  U\\%%l4FGHJ5<<##J0CDEH9 7 7J  ! "D D
#I/q2M2F
 +,@
AB)':xH!%n!5I"
  %
3! !	 ,Ms   D c                n   t                t        |       }|t        k(  }t        | j                  |      }t
        | j                     } |||       }g }| j                  r|j                  d       | j                  r|j                  d       |s,|j                  d| j                   d| j                   d       |j                  d       t        t        || j                  | j                  || j                  | j                  t        t        | j                   ||t        | j                         |      S )u  IssueClassification → RemediationPlan (plan only, dispatch 0).

    fail-closed: HOLD_FOR_CHAIR 인 경우에도 spec 골격은 *생성*(회장 보고용)
    하되 disposition/hold_for_chair 로 명확히 표기한다. dispatch 는 결코
    수행하지 않는다.
    uF   Critical7 분류 → HOLD_FOR_CHAIR (회장 §6, 자동 수렴 금지)u7   shared invariant 파손 → HOLD_FOR_CHAIR (회장 §6)znon-Critical  (uW   ) → AUTO_REMEDIATION_HOLD 자동 수렴 (회장 §3/§6, 개별 확인 대기 없음)uP   plan only — 실제 dispatch/코드수정은 본 산출 아님 (회장 §2/§5)r   )rX   r   r   r   r\   	_BUILDERSr]   r`   appendra   r^   rx   PLAN_SCHEMAr@   rA   ru   rf   )r   r   r|   r   rz   builderskeletonr   s           r   build_remediation_planr     s-    &u-K $55N5,,h7G(()Gw&HGT	
 $$E	
 ENN+2e.>.>-? @ 	

 NNZ ((##''-','D'D#D%!%"5"56 r   c                    	 t        j                  d|        }|j	                  d      sd|v rt        d|      t        |      S # t        $ r}t        d|       |d}~ww xY w)u  열린 fd 가 *실제* 가리키는 커널-정규 경로를 ``/proc/self/fd`` 로 회수.

    ``os.readlink('/proc/self/fd/<fd>')`` 는 open 시점에 커널이 이미 모든
    구성요소(중간 디렉터리 symlink-swap 포함)를 해소한 실경로를 돌려준다 —
    파일시스템을 다시 walk 하지 않으므로 추가 TOCTOU 가 없다. ``/proc``
    미가용·삭제된 inode (`" (deleted)"` 접미) 등은 fail-closed 로 거부한다.
    z/proc/self/fd/z1cannot resolve opened fd realpath (fail-closed): Nz
 (deleted) z6opened fd realpath is unstable/deleted (fail-closed): )r;   readlinkOSErrorr!   r   r   )fdlinkexcs      r   _fd_realpathr     s    {{^B401
 }}\"fn"DTHM
 	
 :  "?uE
	s   A 	A%A  A%c                   t        j                  |       }	 t        j                  |      }t         j
                  j                  ||      s@t	        d|j                   d|j                   d|j                   d|j                   d	      t        j                  |j                        r(|j                  dkD  rt	        d|j                         yy# t        $ r}t	        d|       |d}~ww xY w)	u  H1h hardening (3차·additive defense-in-depth — hard-link 동일-inode 봉합).

    H1r 2차 방어(``O_NOFOLLOW`` + ``/proc/self/fd`` realpath + ``fstat``)는
    *경로* 기준 이탈만 차단한다. ``CANONICAL_WS_ROOT`` 내부 쓰기권한 공격자가
    동일 파일시스템·동일 uid 의 ws-밖 inode 에 대한 *hard link* 를 ws 내부에
    심으면 그 in-root pathname 은 정적·H1r 검증을 모두 통과하지만 열린 fd 는
    ws-밖 inode 를 가리킨다(race 없는 out-of-scope read). hard link 은 별도
    realpath 가 없으므로 inode 메타데이터로만 탐지 가능하다:

    - 열린 fd 의 ``os.fstat`` st_dev/st_ino 를 ``_contained_resolved()`` 가
      산출한 정적 경로의 ``os.lstat``(symlink 미추종) st_dev/st_ino 와
      ``os.path.samestat`` 동일성 대조 — 불일치 = check→open 사이 swap/우회
      → fail-closed (H1r realpath 검증과 직교한 additive 보강).
    - 정규파일이면서 ``st_nlink > 1`` 이면 해당 inode 가 ws-밖에서도 도달
      가능한 hard link 일 수 있다. 본 read-path 가 소비하는 정본
      JSON(schema·adjudication·plan)은 단일-link 정규파일이므로, 다중-link
      정규파일은 ws-내부 정합을 별도 보장할 수 없는 한 보수적으로
      fail-closed (out-of-scope hard-link inode read 차단).

    어떤 이탈도 ``PathContainmentError`` (fail-closed). 본 함수는 read-only
    inode 메타데이터만 조회하며 planner 산출 성격(plan 골격만)과 무관하다.
    z1cannot lstat static resolved path (fail-closed): NzIopened fd inode != static path inode (check->open swap fail-closed): fd=(,z
) static=(rj   r   u\   opened regular file has st_nlink>1 — possible out-of-scope hard link (fail-closed): nlink=)r;   fstatlstatr   r!   r(   samestatst_devst_inostatS_ISREGst_modest_nlink)r   r+   fstlstr   s        r   _assert_fd_inode_containedr     s    . ((2,Chhx 
 77C%"336::,a

| Lzzl!CJJ<q2
 	

 ||CKK S\\A%5"..1ll^=
 	
 &6   "?uE
	s   C 	C1C,,C1c                   t        |       }t        j                  t        j                  z  t	        t        dd      z  }	 t        j
                  ||      }	 t        |      }|t        k(  st        |j                  vrt        d| d|       t        j                  |      }t        j                  |j                         st        d	|       t#        ||       t        j$                  |d
dd      5 }d}|j'                         }d d d        |dk\  rt        j(                  |       	 t+        t,        t.        t0        f   t3        j4                              S # t        $ r1}t        d| d| dt        |      j                   d| d	      |d }~ww xY w# 1 sw Y   xY w# |dk\  rt        j(                  |       w w xY w)N	O_CLOEXECr   z,path open blocked (O_NOFOLLOW fail-closed): r#   r   : rj   z:opened fd escapes CANONICAL_WS_ROOT (TOCTOU fail-closed): z/opened fd is not a regular file (fail-closed): rr=   T)r>   closefd)r,   r;   O_RDONLY
O_NOFOLLOWgetattropenr   r!   typer   r   r%   r'   r   r   r   r   r   fdopenreadcloser   r   r[   r   jsonloads)	r(   r+   flagsr   r   realstfhtexts	            r   
_read_jsonr   "  s    #4(H KK"--''"k1*EEEWWXu%B$$(9(M&L($tf&  XXb\||BJJ'&A$J  	#2x0YYr3$? 	2B779D	 7HHRLS#X

4 011=  ":4($j49--.bQ8
 	0	 	 7HHRL s=    E BF$ 5FF$ 	F$,FFF!F$ $Gr   r^   c                  t        |       }t        |j                  d      xs; |j                  d      xs( |j                  d      xs |j                  d      xs d      }|j                  d      d   j                  d      d   j                  d	      d   }|j                  d
      xs |j                  d      xs i }t	        |t
              rt        t        t        t        f   |      ni }t        |j                  dd      xs d      }|dkD  }	|j                  di       }
t	        |
t
              rt        t        t        t        f   |
      ni }|j                  d      du }t        |j                  d      xs( |j                  d      xs |j                  d      xs d      }t        ||||	||dd | gt        t        t        t        f   |j                  di             xs i       S )u<  원 HOLD adjudication JSON 을 **read-only consume** 하여
    IssueClassification 을 추출한다. (기존 산출물 byte-0 — 읽기만.)

    is_critical7 은 본 adjudication 의 codex high/critical + Critical7
    표식에서 *보수적으로* 유도하되, 권위 분류는 TrackB 소관임을 명시.
    r{   r   schema_task	schema_idztask-unknown+r   r   r?   codex_adjudicationcodexcriticalindependent_anu_verificationgit_equal_before_afterFrc   high_findinghigh_resolutionrb   NiX  _planner_detailr\   r]   r^   r`   ra   rc   rf   rh   )r   r[   rP   splitrG   rv   r   r   r   intrZ   object)r(   r]   r^   dataraw_taskr\   
_codex_rawr   r   r`   _inv_rawinvshared_brokenrc   s                 r   extract_issue_from_adjudicationr  R  s    dD!" 	88I	88M"	 88K 	 H ..%a(..u5a8>>sCAFK./J488G3DJJ,6z4,HT#s(^Z(b 
 599Z+0q1Ha<Lxx6;H*4Xt*DT#s(^X&"  GG45>M		) 	99^$	99&'	 	G ! -fDf%txx0A2'FGM2	 	r   r^   r   c               8    t        | ||      }t        ||      S )u?   실 entrypoint: adjudication 증거 경로 → RemediationPlan.r   r   )r  r   )r(   r]   r^   r   r   s        r   build_plan_from_adjudicationr    s     ,D*xPE!%(;;r   c                   t        t              }	 ddl}|j                  |      }|j	                  t        t        |             D cg c]&  }t        |j                         d|j                   ( c}S c c}w # t        $ rL g }t        t        t           |j                  dg             D ]  }|| vs|j                  d|         |cY S w xY w)u   plan dict 를 schemas/auto_remediation_plan.schema.json 으로 검증.

    jsonschema 미가용 시 최소 required 키 검사로 fail-closed.
    r   Nr   requiredzmissing required key: )r   SCHEMA_PATH
jsonschemaDraft7Validatoriter_errorsr   r   ru   r(   messageImportErrorr	   r[   rP   r   )planry   r  	validatoreerrskeys          r   validate_planr    s    
 $F..v6	 **4T?;
 AFF|nBqyyk*
 	
 
  S	6::j"#=> 	<C$4SE:;	< s)   6A: +A52A: 5A: :9C4CCzAmemory/events/task-2604+1.independent-collector-adjudication.jsonzEmemory/events/task-2605+2.independent-anu-collector.adjudication.jsonz?memory/events/task-2609.independent-collector-adjudication.jsonc            
     n   t                g } d}t        D ]K  \  }}||d}	 t        ||      }|j                         }t	        |      }t        t        t        t        f   |d         }t        t        t        t        f   |j                  di             }	t        |j                  d            xrn t        |j                  d            xrR t        |j                  d            xr6 t        |j                  d            xr t        |	j                  d	            }
|j                  |d
   |d   |d   ||
| xr |
       |xr | xr |
}| j                  |       N d|t         t"        | dS # t        $ r7}|j                  dt        |      j                   d|        d}Y d}~_d}~ww xY w)u   실 2604/2605/2609 adjudication 을 read-only consume → 실 plan 생성·
    스키마 검증. mock 0 — 증거 파일이 없거나 실 entrypoint 가 plan 을
    못 만들면 FAIL (mock-only 경로 자동 FAIL).T)evidencer]   r   r   r   r   r   r   r   rz   r|   r   )rz   r|   r   schema_errorsstructural_okpassedFr   )r#  errorNz-anu_v3.auto_remediation_planner.self_check.v1)ry   
all_passedr}   r~   cases)rX   _SELF_CHECK_CASESr  r   r  r   r   r[   r   rP   r_   update	Exceptionr   r   r   r@   rA   )resultsokr   ityperecr  pdr  skr   r"  r   s               r   run_self_checkr0    s    ')G	B' 
U.1!G	/U;DB $Dd38nb&9:B$sCx."&&2*>?FRVVF^$ :(:,-:  012: $789  JJ9}-!"23"+ 2]   2D2]B 	s7: B0 	  	JJed3i.@.@-AC5+IJJB	s   D.E44	F4=-F//F4c                    t        j                  dd      } | j                  dd       | j                  dt        t              d	       | j                  d
dt        t
                     | j                  dt        dd       | j                  dd       | j                  ddd       | j                  ddd       | S )Nauto_remediation_planneruP   task-2612 Track C — auto remediation plan 생성기 (plan only · dispatch 0).)progdescriptionz--from-adjudicationu6   원 HOLD adjudication JSON 경로 (read-only consume).)helpz--issue-typeu   2604/2605/2609 유형.)choicesr5  z
--severityr   )defaultr6  z--roundr   r   )r   r7  destz--issue-jsonu4   IssueClassification dict JSON 경로(직접 입력).z--self-check
store_trueu1   실 2604/2605/2609 증거로 self-check (mock 0).)actionr5  z
--validateuB   생성 plan 을 스키마로 검증하고 결과를 함께 출력.)argparseArgumentParseradd_argumentru   rk   rm   r  )ps    r   _build_parserr?    s    '%	A
 NNE   NN[!%  
 NN<j9INJNN93
NCNNC   NN@  
 NNQ  
 Hr   c                D   t                t               j                  |       }|j                  r4t	               }t        t        j                  |dd             |d   rdS dS |j                  rt        |j                        }t        t        |d         t        |d         t        |j                  d	d
            t        |j                  dd            t        |j                  dd            t        |j                  dd            t        |j                  dg             t        |j                  di                   }t!        ||j"                        }nx|j$                  rD|j&                  r8t)        |j$                  |j&                  |j*                  |j"                        }n(t               j-                  t.        j0                         y|j3                         }|j4                  r|t7        |      d}t        t        j                  |dd             y)NF   )ensure_asciiindentr%  r   r   r\   r]   r^   r   r`   ra   rc   rb   rf   rh   r  r  r  )r  r!  )rX   r?  
parse_args
self_checkr0  printr   dumps
issue_jsonr   rZ   r[   rP   r_   ru   rv   r   r   from_adjudicationr]   r  r^   
print_helpsysstderrr   validater  )argvargsoutr)   r   r  r.  s          r   mainrQ    s   ?%%d+Ddjj5;<%q,1,)#C./3|,-V45cggne<=$(159% 	2./sww;<"-.
 &edmmD			DOO+""OO]]]]	
 	""3::.	B}}=+<=	$**ReA
67r   )r   r@   rA   %TYPE_GLOBAL_LEDGER_SHA_FALSE_POSITIVETYPE_STAGE_CLAIM_TEST_MISMATCHTYPE_COVERAGE_GAPrk   r   r   r   r!   rX   rZ   rx   r   r   r   r  r  r  r0  rQ  __main__)r(   r[   rr   r   rq   )r   rZ   rr   r[   )r   )r\   r[   r   r  rr   r[   )r   r[   rr   r[   )rz   r[   r   r[   r   r[   rr   re   )rz   r[   r   rZ   rr   rg   )r   rZ   r   r  rr   rx   )r   r  rr   r   )r   r  r+   r   rr   rs   )r(   r[   rr   zDict[str, Any])r(   r[   r]   r[   r^   r[   rr   rZ   )
r(   r[   r]   r[   r^   r[   r   r  rr   rx   )r  rg   rr   re   r   )rr   zargparse.ArgumentParser)N)rN  zOptional[Sequence[str]]rr   r  )Er   
__future__r   r;  rD   r   r;   r   rK  dataclassesr   r   pathlibr   typingr   r   r	   r
   r   r   r   r  CANONICAL_ROOTr&   r%   rR  rS  rT  rk   r   r   rm   r@   rA   RuntimeErrorr   rl   r!   r,   rO   rR   rX   rZ   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r'  r0  r?  rQ  __all__r   
SystemExitr   r   r   <module>r^     sa  "F #  
  	  
 (  < </9&
 (002  )K %!< "  *" + $ 2
 	 K K: * J  "7+ 8 D D D6  
  
  
H)
 N(V'T,` *>"N~	 1233*-33n*(
V-2b 4:/
//-0//f 4:1<
<<-0<EH<<2 	L-
 	P&
 	J  )ZD'T4 z
TV
 r   