
    3jI                       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mZ ddlZ e
e      j'                         j(                  j(                  Z ee      ej.                  vr"ej.                  j1                  d ee             	 ddlmZmZmZ dZd	Z d
Z!edz  dz  Z"e G d d             Z#e G d d             Z$ G d d      Z%ddd	 	 	 	 	 	 	 d8dZ&ddddddddddddddddd dd!dd"dd#dd$dd%dd&dd'dd(dd)d*d+d,dd-dd.d/d0dgZ'ed1fed1fed1fed1fe d2fe d2fe d2fe d2fed1fed1fe!d2fd3Z(d9d4Z)d:d;d5Z*g d6Z+e,d7k(  r e- e*             y# e$ r ddlmZmZmZ Y w xY w)<u  anu_v3.codex_high_classifier — Codex HIGH/HOLD batch 분류기 (task-2611 Track B).

회장 verbatim §1/§2: 병렬 작업 중 Codex HIGH/HOLD 가 발생해도 batch 전체
context 를 모아 Critical7 인지 non-critical remediation 인지 자동 분류한다.
Codex HIGH 를 security/scope/credential 계열과 coverage/test/claim mismatch
계열로 분류 — Critical7 = CHAIR_HOLD, 아니면 AUTO_REMEDIATION_HOLD 후보.

본 분류기 출력 = Track A ``anu_v3/batch_hold_adjudicator.py``(task-2610) 입력.
출력 schema = ``anu.codex_high_classification.v1``.

분류 우선순위 (deterministic, 회장 §3/§5 약화 금지):
  1) shared invariant 파손  -> CHAIR_HOLD
  2) Critical7 매치          -> CHAIR_HOLD
  3) remediation_family      -> AUTO_REMEDIATION_HOLD
  4) 그 외 HIGH/HOLD          -> AUTO_REMEDIATION_HOLD (high_unmatched, §3 자동수렴)

단일 진실원: ``config/codex_high_classification_rules.yaml`` +
``config/critical7_rules.yaml`` (anu_v3.critical7_classifier 재사용 — 규칙
중복 금지).

Layer A / NO-CRON: 순수 결정. ZERO cron / dispatch / subprocess / cokacdir /
파일쓰기. CLI ``--selftest`` 는 실 entrypoint regression (mock-only FAIL).
    )annotationsN)	dataclassfield)Path)AnyDictListOptionalSequence)
CHAIR_HOLDCritical7ResultCritical7Rulesetz anu.codex_high_classification.v1AUTO_REMEDIATION_HOLDGOconfigz$codex_high_classification_rules.yamlc                      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<    ee      Zded<   ddZy)FindingClassificationstr
finding_idseverityfamilyrouteboolis_critical7is_invariant_breakdict	critical7	List[str]matched_termsdefault_factoryreasonsc                    | j                   | j                  | j                  | j                  | j                  | j
                  | j                  t        | j                        t        | j                        d	S )N	r   r   r   r   r   r   r   r   r"   )
r   r   r   r   r   r   r   listr   r"   )selfs    3/home/jay/workspace/anu_v3/codex_high_classifier.pyto_jsonzFindingClassification.to_jsonI   s[    //kkZZ --"&"9"9!$"4"45DLL)

 
	
    Nreturnr   __name__
__module____qualname____annotations__r   r%   r"   r(    r)   r'   r   r   =   sA    OMKJOt4GY4
r)   r   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<    ee      Zded<   ddZy)BatchClassificationr   schemabatch_idinttotal_findingsin_scope_findingsr   any_critical7any_invariant_breakbatch_verdictr   critical7_rules_hitchair_hold_findingsremediation_candidateszList[FindingClassification]per_findingr    r"   c                   | j                   | j                  | j                  | j                  | j                  | j
                  | j                  t        | j                        t        | j                        t        | j                        | j                  D cg c]  }|j                          c}t        | j                        d| j                  | j                  t        k(  t        | j                        ddS c c}w )Nz4anu_v3/batch_hold_adjudicator.py (task-2610 Track A)consumerverdict
chair_holdauto_remediation_candidates)r4   r5   r7   r8   r9   r:   r;   r<   r=   r>   r?   r"   batch_hold_adjudicator_input)r4   r5   r7   r8   r9   r:   r;   r%   r<   r=   r>   r?   r(   r"   r   )r&   fs     r'   r(   zBatchClassification.to_jsonf   s    kk"11!%!7!7!//#'#;#;!//#'(@(@#A#'(@(@#A&*4+F+F&G151A1ABAAIIKBDLL) S--"00J>/3D4O4O/P	-
 	
 Cs   C<Nr*   r,   r1   r)   r'   r3   r3   W   sV    KM""""%%,,t4GY4
r)   r3   c                  ~    e Zd ZdZ	 d	 	 	 ddZe	 	 d	 	 	 	 	 dd       Zedd       ZddZ	ddZ
dd		 	 	 	 	 dd
Zy)CodexHighClassifieruJ   codex_high_classification_rules.yaml + critical7_rules.yaml 분류 엔진.Nc                   || _         |j                  d      | _        |j                  d      | _        |j                  dddg      D ch c]  }|j	                          c}| _        |j                  di       | _        |j                  di       xs i }|j                  dt              | _        |j                  d	d
      | _	        |xs t        j                         | _        y c c}w )Nr4   versionseverity_in_scopeHIGHCRITICALremediation_familiesdefault_when_high_unmatchedr   r   high_unmatched)rawgetr4   rK   upperrL   rO   r   default_routedefault_familyr   loadr   )r&   rulesr   sdflts        r'   __init__zCodexHighClassifier.__init__   s    
 ii)yy+$yy)<vz>RS"
AGGI"
 5:II"B5
! yy6;Ar!XXg/DE"hhx1AB"=&6&;&;&="
s   
C&c                    |rt        |      nt        }t        |dd      5 }t        j                  |      }d d d        t        j                  |      } | |      S # 1 sw Y   'xY w)Nrutf-8encoding)r   _DEFAULT_RULESopenyaml	safe_loadr   rW   )clspathcritical7_pathpfhrX   c7s          r'   rW   zCodexHighClassifier.load   s^     DJN!S7+ 	'rNN2&E	'"">25"~	' 	's   AA'c                    g }dD ]0  }| j                  |      }|s|j                  t        |             2 dj                  |      j	                         S )N)messagetexttitledetailactionsummaryz 
 )rS   appendr   joinlower)findingpartskeyvs       r'   	_haystackzCodexHighClassifier._haystack   sQ    N 	%CC ASV$	% {{5!''))r)   c                    | j                  |      }| j                  j                         D ]H  \  }}|xs i j                  dg       xs g D ]&  }|st	        |      j                         |v s"|c c S  J y )Nkeywords)ry   rO   itemsrS   r   rt   )r&   ru   hayfamspeckws         r'   _remediation_familyz'CodexHighClassifier._remediation_family   su    nnW%2288: 	ICzr&&z26<" #b'--/S0J	 r)   c                J   t        |j                  d      xs |j                  d      xs d      }t        |j                  dd            j                         }| j                  j	                  |      }|j
                  t        k(  rnt        |||j                  xs dt        |j                  |j                  |j                         t        |j                        t        |j                        	      S || j                  vr+t        ||dt         d	d	|j                         g d
| dg	      S | j#                  |      }|r+t        |||t$        d	d	|j                         g d| dg	      S t        ||| j&                  | j(                  d	d	|j                         g dg	      S )Nidr   unknownr   rM   r   r$   below_scopeFz	severity u    not in scope — not heldu    non-Critical remediation 계열=u3    -> AUTO_REMEDIATION_HOLD (회장 §3 자동수렴)u   Critical7 게이트 탈락 + remediation 계열 미매치 — non-Critical 자동수렴 (회장 §3, Critical7 기준 약화 아님))r   rS   rT   r   classifyrC   r   r   r   r   r   r(   r%   r   r"   rL   r   r   r   rV   rU   )r&   ru   fidr   rj   r~   s         r'   classify_findingz$CodexHighClassifier.classify_finding   s   '++d#Mw{{<'@MINw{{:v67==?"nn55g> ::#(!yy/K __#%#8#8**,"2#3#34RZZ(
 
 4111(!$"#(**, $XJ.HIJ
 
 &&w/(!+"#(**, 6se <F F   %&&$$$jjlY
 	
r)   batchr5   c                  |D cg c]  }| j                  |       }}|D cg c]  }|j                  dk7  s| }}|D cg c]  }|j                  t        k(  s| }}|D cg c]  }|j                  t        k(  s| }}t        d |D              }	t        d |D              }
t        |D ch c]T  }|j                  t        k(  r?|j                  j                  d      r$t        |j                  j                  d            V c}      }|rt        }t        |       d}n|rt        }t        |       d}nt        }d}t        t        |t        |      t        |      |	|
|t        |      |D cg c]  }|j                   c}|D cg c]  }|j                   c}||g      S c c}w c c}w c c}w c c}w c c}w c c}w c c}w )	Nr   c              3  4   K   | ]  }|j                     y wN)r   .0rh   s     r'   	<genexpr>z5CodexHighClassifier.classify_batch.<locals>.<genexpr>  s     1Q^^1   c              3  4   K   | ]  }|j                     y wr   )r   r   s     r'   r   z5CodexHighClassifier.classify_batch.<locals>.<genexpr>  s     8qa**8r   matched_rule_idu`    CHAIR_HOLD finding(s) — Critical7/invariant. 회장 보고. 자동수렴 금지 (회장 §6).u_    non-Critical HOLD — AUTO_REMEDIATION_HOLD 자동수렴 (Track C planner 입력, 회장 §3).u   in-scope HIGH/HOLD 0 — GO.)r4   r5   r7   r8   r9   r:   r;   r<   r=   r>   r?   r"   )r   r   r   r   r   anysortedr   rS   r   lenr   r3   BATCH_SCHEMAr%   r   )r&   findingsr5   rG   perrh   in_scopechairremedany_c7any_invc7_rulesrC   whys                 r'   classify_batchz"CodexHighClassifier.classify_batch   s    /7,
)*D!!!$,
 ,
  #@!ahh-&?A@@9q177j#899Dq177.C#CDD1S118C88
ww*$9J)K  123
   Gu:, C C  +Gu:, E E 
 G0C"s8!(m  '! $X7< =! =:?#@QALL#@E
 	
=,
 A9D
> !>#@s:   F.F3F3F8F8%F=>F=1AG7GGr   )rX   Dict[str, Any]r   zOptional[Critical7Ruleset])NN)rf   Optional[Path]rg   r   r+   z'CodexHighClassifier')ru   r   r+   r   )ru   r   r+   zOptional[str])ru   r   r+   r   )r   Sequence[Dict[str, Any]]r5   r   r+   r3   )r-   r.   r/   __doc__r[   classmethodrW   staticmethodry   r   r   r   r1   r)   r'   rI   rI   ~   s    T
 15>> .>&   $)-		 '	 
		 	 * *B
P  	1
*1
 	1

 
1
r)   rI   r   )r5   
classifierc               X    |xs t         j                         }|j                  | |      S )uD   batch Codex HIGH/HOLD 분류 (공개 entrypoint → Track A 입력).r   )rI   rW   r   )r   r5   r   clfs       r'   classify_codex_high_batchr   )  s.     
2+002Ch::r)   b-secrM   u7   SSRF in webhook fetcher — server-side request forgeryr   r   rl   b-credz3AWS secret AKIAABCDEFGH12345678 hardcoded in configb-scopez2out-of-scope write: touched another track artifactb-mergez#force push to main branch attemptedb-covu4   coverage regression — uncovered branch in new codeb-testz0failing test in regression suite, assertionerrorb-claimz8claim mismatch: result does not match, doc-only deliveryb-miscz5unexpected behavior in retry loop (no known category)b-path-structzunexpected write detectedz.git/config)r   r   rl   file
b-pat-barez(GitHub PAT with elevated privileges usedb-lowLOWzminor style nitTF)r   r   r   r   r   r   r   r   r   r   r   c                 j   t         j                         } g }| j                  t        d      }|j                  D ci c]  }|j
                  | }}t        j                         D ]  \  }\  }}|j                  |      }||j                  | d       1|j                  |k7  r#|j                  | d|j                   d|        |j                  |k7  ss|j                  | d|j                   d|         |j                  t        k7  r|j                  d|j                   d       | j                  t        D cg c]  }|d	   d
v s| c}d      }	|	j                  t        k7  r|j                  d|	j                   d       | j                  ddddgd      }
|
j                  t        k7  r|j                  d|
j                   d       | j                  ddddgd      }|j                  t        k7  s|j                   s,|j                  d|j                   d|j                    d       |j#                         }|j                  d      t$        k7  r*|j                  d|j                  d       dt$                |j                  di       }dD ]  }||vs|j                  d| d         t        j'                         D ch c]  }|d!   	 }}t)        |      d"k  r|j                  d#       d$t$        t+        t,        j/                  t0                    | j2                  t)        t              |j                  |j4                  |j6                  |j8                  ||sd%nd&d't$        d(}t;        t=        j>                  |d)d*+             |sd!S d,S c c}w c c}w c c}w )-Nselftestr   z: missing from outputz: route=z
 expected z: is_critical7=zbatch_verdict=u/    expected CHAIR_HOLD (Critical7 finding 존재)r   )r   r   r   z
remed-onlyzremed-only batch_verdict=z expected AUTO_REMEDIATION_HOLDxr   nitr   gozlow-only batch_verdict=z expected GOinvrM   z1executor self-callback detected; byte-0 violationzinvariant batch verdict=z any_invariant_break=z expected CHAIR_HOLD/Truer4   zschema_contract: output schema=rF   rA   z7schema_contract: batch_hold_adjudicator_input missing ''r      zWmock_only_guard: selftest must span >=3 distinct routes (constant classifier must fail)zanu_v3.codex_high_classifierPASSFAILT)moduler4   rX   rules_versionbatch_findingsr;   r<   r>   r=   failuresrC   mock_only_would_failtrack_a_input_schemaF   ensure_asciiindent   ) rI   rW   r   _SELFTEST_BATCHr?   r   _EXPECTr|   rS   rr   r   r   r;   r   r   r   r:   r(   r   valuesr   r   ra   relative_to_ROOTrK   r<   r>   r=   printjsondumps)r   r   r   rh   by_idr   	exp_routeexp_c7rG   
remed_onlygo_batchr   bjba_inkrx   distinct_routesresults                     r'   	_selftestr   a  s   

"
"
$CHDE&+&7&78Q\\1_8E8$+MMO   iIIcN9OOse#89:77iOO%xy
9+> >>V#OO%q~~&6jI j(U001 2) )	
 ###Qqqw2P'PQ $ J #88'
(@(@'A B- -	
 !!5	9:T " H #%h&<&<%=\J	

 

6H
J 	K  C
 J&c.E.E&s'8'8&9 :##&#:#:";;TV	
 
B	vvh<'-bffX.>-? @$~'	
 FF126EQ E>OOI!AN &-^^%56qt6O6
?a.	
 1^//67o.,,$88"'">">$88!)6v $ ,F 
$**V%
:;1#!# 90 	R` 7s   N&N+N+N0c                   t        j                  d      }|j                  ddd       |j                  dt        d d	       |j                  d
t        d       |j                  dt        d        |j                  dt        d        |j	                  | t        |       nd       }|j                  r
t               S |j                  r%t        |j                        j                  d      nt        j                  j                         }t        j                  |      }t!        |t
              r|n|g}t"        j%                  |j&                  rt        |j&                        nd |j(                  rt        |j(                        nd       }|j+                  ||j,                        }t/        t        j0                  |j3                         dd             y)Nz4Codex HIGH/HOLD batch classifier (task-2611 Track B))descriptionz
--selftest
store_trueu    실 entrypoint regression 실행)rp   helpz--inputu-   findings JSON 배열 파일 (없으면 stdin))typedefaultr   z
--batch-idr   )r   r   z--rulesz--critical7-rulesr^   r_   r   Fr   r   r   )argparseArgumentParseradd_argumentr   
parse_argsr%   r   r   inputr   	read_textsysstdinreadr   loads
isinstancerI   rW   rX   critical7_rulesr   r5   r   r   r(   )argvapargsrR   payloadr   r   r   s           r'   _mainr     su   		 	 J
B OOL;  =OOICH  JOOLsGO<OOICO6OO'c4O@==t'7dTBD}}{ jj 

%%w%7!iinn. jjoG$Wd3w'H

"
" JJTZZD&*&:&:T!!"C x$--@E	$**U]]_5
CDr)   )r   r   r   r   r   r3   rI   r   __main__)r   r   r5   r   r   zOptional[CodexHighClassifier]r+   r3   )r+   r6   r   )r   zOptional[Sequence[str]]r+   r6   ).r   
__future__r   r   r   r   dataclassesr   r   pathlibr   typingr   r   r	   r
   r   rc   __file__resolveparentr   r   rf   insertanu_v3.critical7_classifierr   r   r   ImportErrorcritical7_classifierr   r   r   ra   r   r3   rI   r   r   r   r   r   __all__r-   
SystemExitr1   r)   r'   <module>r     s^  . #   
 (  6 6 X ''..u:SXXHHOOAs5z"  2/ 	!$JJ 
 
 
2 #
 #
 #
Lh
 h
\ 04	;&; ; .	;
 ; IKEG&DF&57FHBD&JLGI
 +]DV:<!#1< $4 D!D!#U+$e,%u-$e, $'t$%[d$N:	 z
UW
 G   s   
E# #E54E5