
    j                        d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	m
Z
  G d dee      Z ed	       G d
 d             ZddZddZ	 	 	 	 	 	 ddZddZddddd	 	 	 	 	 	 	 	 	 	 	 ddZy)u  Closeout Grade Auto-Classifier — task-2643 Track D 산출물 10.

회장 verbatim doctrine: **사람이 수동 선언한 closeout grade 는 authoritative 아님.**
batch coordinator 가 changed_files / evidence / dry-run / rollback 으로 자동 산정한다.

4 enum (spec §5.2):
- `DOCUMENTED_ONLY` — feedback md / event json / spec md 만 (실 enforcement 0)
- `REGRESSION_GUARDED` — regression test 추가 (정적 검사 수준)
- `RUNTIME_GUARDED` — staged hook draft + dry-run report (실 enforcement 준비)
- `HARNESS_ENFORCED` — live settings.json 적용 + harness deny 실 작동

입력:
- changed_files: list[str] — PR 안에서 수정된 file path
- evidence_files: list[str] — 박제 파일 / fixture 존재 path (memory/events, tests/fixtures/...)
- dry_run_report: dict | None — Track A dry-run report 내용 (PASS/FAIL 단언)
- rollback_plan_present: bool
- live_settings_applied: bool — ~/.claude/settings.json 에 hook 실 등록 여부
    )annotations)	dataclassfield)Enum)AnyIterablec                      e Zd ZdZdZdZdZy)CloseoutGradeDOCUMENTED_ONLYREGRESSION_GUARDEDRUNTIME_GUARDEDHARNESS_ENFORCEDN)__name__
__module____qualname__r   r   r   r        U/home/jay/workspace/.worktrees/task-2643-dev6/utils/closeout_grade_auto_classifier.pyr
   r
      s    'O-'O)r   r
   T)frozenc                  >    e Zd ZU ded<   ded<    ee      Zded<   y)	GradeDecisionr
   grade	list[str]	rationale)default_factoryzdict[str, Any]signalsN)r   r   r   __annotations__r   dictr   r   r   r   r   r   "   s    #D9G^9r   r   c                &    t        d | D              S )Nc              3  d   K   | ](  }|j                  d       xr |j                  d       * yw)ztests/regression/.pyN
startswithendswith.0ps     r   	<genexpr>z(_has_regression_tests.<locals>.<genexpr>/   s+     ^1q||/0FQZZ5FF^   .0any)changed_filess    r   _has_regression_testsr-   .   s    ^P]^^^r   c                V    t        d | D              }t        d | D              }|xr |S )u\   staged hook draft = hooks/*.py 생성 + memory/specs/staged_settings_template_*.json 동반.c              3  d   K   | ](  }|j                  d       xr |j                  d       * yw)zhooks/r!   Nr"   r%   s     r   r(   z)_has_staged_hook_draft.<locals>.<genexpr>4   s*     WA1<<)?ajj.??Wr)   c              3  d   K   | ](  }|j                  d       xr |j                  d       * yw)z&memory/specs/staged_settings_template_.jsonNr"   r%   s     r   r(   z)_has_staged_hook_draft.<locals>.<genexpr>5   s3       	
=>V1::gCVVr)   r*   )r,   has_hookhas_templates      r   _has_staged_hook_draftr4   2   s6    WWWH  L $$r   c                    t        d | D              }|syt        |t              sy|j                  d      xs i }|j                  dd      dk\  xr |j                  dd      dk\  S )uQ   dry-run report = events JSON 존재 + report 본문이 deny/allow summary 포함.c              3  p   K   | ].  }|j                  d       xr |j                  d      xr d|v  0 yw)memory/events/r1   dry_runNr"   r%   s     r   r(   z&_has_dry_run_report.<locals>.<genexpr>@   s=       	
%&Q1::g+>Q9PQ>Qs   46Fcase_summary
deny_countr      allow_count)r+   
isinstancer   get)r,   dry_run_reporthas_event_filesummarys       r   _has_dry_run_reportrB   <   sq       N nd+  06BG;;|Q'1,S]A1NRS1SSr   c                    dd| D cg c]  }|j                         s| }}|syt        fd|D              S c c}w )uB   모든 변경 파일이 doc/spec/event/feedback 류만 인 경우.)zmemory/specs/r7   zmemory/feedback_zdocs/z	CLAUDE.mdz	MEMORY.md)z.mdFc              3  n   K   | ]+  t        fd D              xs j                         - yw)c              3  @   K   | ]  }j                  |        y w)N)r#   )r&   prefr'   s     r   r(   z,_doc_only_paths.<locals>.<genexpr>.<genexpr>[   s     94ALL9s   N)r+   r$   )r&   r'   doc_suffixesdocs_prefixess    @r   r(   z"_doc_only_paths.<locals>.<genexpr>Z   s5       	9=99UQZZ=UUs   15)stripall)r,   r'   relevantrG   rH   s      @@r   _doc_only_pathsrL   L   sQ    M L(6aAGGI6H6    7s   ??NF)evidence_filesr?   rollback_plan_presentlive_settings_appliedc           
        t        |       }t        |xs g       }g }t        |      t        |      t        |      t	        ||      ||t        |      t        |      d}|r,|j                  d       t        t        j                  ||      S |d   rI|d   rD|rB|j                  d       |d   r|j                  d       t        t        j                  ||      S |d   r,|j                  d       t        t        j                  ||      S |d	   s|s.|r,|j                  d
       t        t        j                  ||      S |j                  d       t        t        j                  ||      S )u  closeout grade 자동 산정.

    우선순위 (highest → lowest):
    1. HARNESS_ENFORCED — live_settings_applied=True
    2. RUNTIME_GUARDED — staged hook draft + dry-run report PASS + rollback plan
    3. REGRESSION_GUARDED — regression tests 추가 (RUNTIME signal 없음)
    4. DOCUMENTED_ONLY — doc/spec/event/feedback only

    signal 누락 시 lower grade 로 fallback (예: hook 있는데 template 없으면 → REGRESSION_GUARDED).
    )changed_file_counthas_regressionhas_staged_hookhas_dry_run_reportrN   rO   doc_only_pathsevidence_file_countu3   live_settings_applied=True → live hook 실 작동rS   rT   u>   staged hook draft + dry-run report PASS + rollback plan 완비rR   u?   regression tests 추가 (정적 검사 + runtime 준비 합산)uH   regression tests 추가 (RUNTIME signal 미달 → 정적 검사 수준)rU   u#   doc/spec/event/feedback only 변경uK   RUNTIME/REGRESSION signal 없음 → 보수적으로 DOCUMENTED_ONLY 분류)listlenr-   r4   rB   rL   appendr   r
   r   r   r   r   )	r,   rM   r?   rN   rO   cfefr   r   s	            r   classify_closeout_grader\   e   s_   $ 
m	B	n"	#BI!"g/31"51"nE!6!6)"-"2w	G NO];;YPP 	!"()!YZ#$^_]::IwOO cd]==y'RR >?]::IwOO bc66	7KKr   )r,   Iterable[str]returnbool)r,   r]   r?   dict[str, Any] | Noner^   r_   )r,   r   rM   zlist[str] | Noner?   r`   rN   r_   rO   r_   r^   r   )__doc__
__future__r   dataclassesr   r   enumr   typingr   r   strr
   r   r-   r4   rB   rL   r\   r   r   r   <module>rg      s   & # (   *C * $: : :_%T T2GT	T 8 (,,0"'"'8L8L %8L *	8L
  8L  8L 8Lr   