
    i#                     l   d 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	 ddl
Z
dZ e	d      Z e	d      Z e	d	      Z e	d
      Zde	defdZde	defdZdedefdZde	dededefdZdededefdZdedefdZdedefdZdedededefdZdededededed e	de	fd!Zd" Zed#k(  r e        yy)$u  
주간 배치 학습 분석 스크립트 v1

사용법:
    python3 learning-analyzer.py --week 2026-04-07

옵션:
    --week          ISO 날짜 (월요일 기준, 해당 주 월~일 7일 분석) [필수]
    --audit-trail   audit-trail.jsonl 경로 오버라이드 (테스트용)
    --output-dir    출력 디렉토리 오버라이드 (테스트용)
    --whitelist     화이트리스트 YAML 경로 오버라이드 (테스트용)
    --thresholds    임계값 YAML 경로 오버라이드 (테스트용)

v1 한계:
    - 에러 유사도 분석 미지원 (v2 예정)
    - task_id 없는 레코드 제외 (old schema)
    - bot==anu 세션 제외
    N)date	timedeltafnmatch)Pathz/home/jay/workspace/z1/home/jay/workspace/memory/logs/audit-trail.jsonlz$/home/jay/workspace/memory/learningsz2/home/jay/workspace/config/learning-whitelist.yamlz3/home/jay/workspace/config/learning-thresholds.yamlpathreturnc                 $   	 t        | d      5 }t        j                  |      }d d d        t        j	                  d      xs g       t        |j	                  d      xs g       dS # 1 sw Y   FxY w# t        $ r t               g dcY S w xY w)Nutf-8encodingfilespatterns)r   r   )openyaml	safe_loadsetgetlist	Exceptionr   fdatas      J/home/jay/workspace/.worktrees/task-2116-dev1/scripts/learning-analyzer.pyload_whitelistr   $   s    0$) 	%Q>>!$D	% '*0b1TXXj17R8
 	
	% 	%  0B//0s(   A6 A*AA6 *A3/A6 6BBc                    	 t        | d      5 }t        j                  |      }d d d        t        j	                  dd            t        |j	                  dd            dS # 1 sw Y   @xY w# t        $ r dddcY S w xY w)Nr   r   min_task_count   min_task_ratiog333333?)r   r   )r   r   r   intr   floatr   r   s      r   load_thresholdsr"   0   s    <$) 	%Q>>!$D	% "$((+;Q"?@#DHH-=s$CD
 	
	% 	%  <"#s;;<s'   A0 A$>A0 $A-)A0 0B B
file_fieldc                 `    | r'| j                  t              r| t        t              d  S | xs dS )N )
startswithWORKSPACE_ROOTlen)r#   s    r   _normalize_pathr)   <   s0    j++N;#n-/00    
week_startweek_endc                    g }|j                         }|j                         }	 t        | d      5 }|D ]  }|j                         }|s	 t        j                  |      }|j                  dd      }	|	sA|	d d }
||
cxk  r|k  sn T|j                  dd      }|si|j                  d      r{|j                  dd      }|d	k(  r|j                  d
d      }|r|dk(  rt        |      }|j                  ||d        	 d d d        |S # t        j
                  $ r Y w xY w# 1 sw Y   |S xY w# t        $ r Y |S w xY w)Nr   r   tsr%   
   filez/tmp/botanutask_idunknown)r0   r3   )	isoformatr   stripjsonloadsJSONDecodeErrorr   r&   r)   appendr   )r   r+   r,   recordsweek_start_strweek_end_strr   linerecr.   ts_date	file_pathr1   r3   rel_paths                  r   parse_audit_trailrC   B   sj   G))+N%%'L#$)  	GQ Gzz|**T*C WWT2&Sb'&'@L@GGFB/	 ''0ggeR(%<'')R0'Y"6*95WEF?G 	GF N9 ++  	GF N  NsS   D3 D&D B"D&D3 D# D&"D##D&&D0+D3 0D3 3	E ?E rB   	whitelistc                 V    | |d   v rd|  S |d   D ]  }t        | |      sd| c S  y)Nr   zfiles: r   z
patterns: r%   r   )rB   rD   patterns      r   _is_whitelistedrG   m   sL    9W%%
##Z( *8W%y))* r*   c                 T    t        |       j                  j                         }|dv ryy)N)z.yamlz.jsonz.tomlconfig_hotspotrefactor_candidate)r   suffixlower)rB   rK   s     r   _classify_typerM   v   s)    (^""((*F,,r*   
task_countc                     | dk\  ryy)N   highmedium )rN   s    r   _classify_priorityrT   }   s    Qr*   r;   
thresholdsc                 :   i }| D ]<  }t        |d         }|j                  |t                     j                  |d          > t	        | D ch c]  }|d   	 c}      }g }g }|d   }	|d   }
|j                         D ]  \  }}t        ||      }|r|j                  ||dd       *t	        |      }|dkD  r||z  nd}||	k\  sG||
k\  sM|j                  |||t        |      t        |      t        |      |d	        |j                  d
        ||fS c c}w )Nr0   r3   r   r   skipped_whitelist)r0   rulestatusr   g        )r0   rN   
task_ratiotask_idstypeprioritytotal_tasksc                     | d    | d   fS )NrN   r0   rS   )xs    r   <lambda>z"compute_hotspots.<locals>.<lambda>   s    !L/!11V9 = r*   )key)r)   
setdefaultr   addr(   itemsrG   r:   sortedrM   rT   sort)r;   rD   rU   
file_tasksr?   r   r^   hotspotswhitelisted	min_count	min_ratiorB   r[   wl_rulerN   rZ   s                   r   compute_hotspotsrn      sE   !#J <CK(a'++C	N;< 9#s9~9:KHK+,I+,I(..0 (!(I6'M`ab]
3>?j;.
"zY'>OO$",", &x 0*84 2: >#.
, MM=M>[  ? :s   Dri   rj   r^   
output_dirc           
         |t        d      z
  }g }|j                  d| d|        |j                  d       |j                  d       |j                  d       |j                  dt        |        d       |j                  d       t        | d      D ]  \  }}	t	        |	d	   d
z  d      }
dj                  |	d         }d}|j                  d| d|	d    d       |j                  d|	d           |j                  d|
 d|	d    d|	d    d       |j                  d|        |j                  d|	d           |j                  d|        |j                  d|	d           |j                  d       |j                  d        |j                  d t        |       d       |j                  d       |D ]  }|j                  d!|d    d"|d#           ! |s|j                  d$       |j                  d       |j                  d%       |j                  d&| d|        |j                  d'|        |j                  d(t        |               |j                  d)t        |              |j                  d       |j                  d*d*+       |d,| d-z  }|j                  d.j                  |      d/0       |S )1N   daysu   # 주간 학습 리포트: z ~ r%   u<   > 학습 기능 v1 — 에러 유사도 미지원(v2 예정)u   ## 핫스팟 파일 (u   건)rZ   d   z, r[   u=   리팩토링 검토 필요 — 같은 파일을 반복 수정z### z. `r0   `u   - **수정 task 수**: rN   u   - **수정 비율**: z% (/r^   z tasks)u   - **수정 task 목록**: z- **type**: r\   z- **action**: z- **priority**: r]   z- **status**: pendingu   ## 화이트리스트 제외 (z- `u   ` — rX   u   (없음)u	   ## 요약u   - 분석 기간: u   - 총 task 수: u   - 핫스팟 파일 수: u   - 화이트리스트 제외: T)parentsexist_okzweekly-z.md
r   r   )r   r:   r(   	enumerateroundjoinmkdir
write_text)ri   rj   r+   r,   r^   ro   week_end_displaylinesidxhs	ratio_pct	task_listactionwloutput_paths                  r   generate_reportr      s     )"33E	LL.zl#>N=OPQ	LL	LLOP	LL	LL(Xt<=	LLXq) R"\*S0!4	IIbn-	PtC5BvJ<q12.r,/?.@AB,YKs2l;K:LAbQ^N_M``ghi1)=>|BvJ<01~fX./':'789,.R 
LL1#k2B1C4HI	LL ;s2f:,fRZL9:;Z 	LL	LL	LL$ZL4D3EFG	LL#K=12	LL+CM?;<	LL0[1A0BCD	LLTD1C88K499U+g>r*   c            
      z   t        j                  d      } | j                  ddd       | j                  dd d	       | j                  d
d d	       | j                  dd d	       | j                  dd d	       | j                         }	 t	        j
                  |j                        }t        d      z   }|j                  rt        |j                        nt        }|j                   rt        |j                         nt"        }|j$                  rt        |j$                        nt&        }|j(                  rt        |j(                        nt*        }t-        |      }t/        |      }	t1        |||      }
t3        |
D ch c]  }|d   	 c}      }t5        |
||	      \  }}t7        ||||||      }t        d|        t        d| dt3        |       dt3        |       d       y # t        $ rA t        d|j                   t        j                         t        j                  d       Y w xY wc c}w )Nu   주간 배치 학습 분석)descriptionz--weekTu%   분석 주 시작일 (ISO, 월요일))requiredhelpz--audit-trailu(   audit-trail.jsonl 경로 오버라이드)defaultr   z--output-diru#   출력 디렉토리 오버라이드z--whitelistu'   화이트리스트 YAML 오버라이드z--thresholdsu   임계값 YAML 오버라이드u;   ERROR: --week 값이 유효한 ISO 날짜가 아닙니다: )r0   rq      rr   r3   u   리포트 생성 완료: u   총 task 수: u   , 핫스팟: u    건, 화이트리스트 제외: u   건)argparseArgumentParseradd_argument
parse_argsr   fromisoformatweek
ValueErrorprintsysstderrexitr   audit_trailr   DEFAULT_AUDIT_TRAILro   DEFAULT_OUTPUT_DIRrD   DEFAULT_WHITELISTrU   DEFAULT_THRESHOLDSr   r"   rC   r(   rn   r   )parserargsr+   r,   
audit_pathro   whitelist_paththresholds_pathrD   rU   r;   r?   r^   ri   rj   result_paths                   r   mainr      s   $$1NOF
46]^
<fg
;`a
t:cd
;[\D''		2

 I1--H+/+;+;d&&'ATJ*.//doo&?QJ-1^^T$..)ARN/3d4??+DVO~.I 1J
JAG9#s9~9:K,WiLHk!(KX{\fgK	%k]
34	N;-}S]OCcdghsdtcuux
yz-  KDII;W^a^h^hi :s   G+ H8+AH54H5__main__) __doc__r   r7   r   datetimer   r   r   pathlibr   r   r'   r   r   r   r   dictr   r"   strr)   r   rC   rG   rM   r    rT   tuplern   r   r   __name__rS   r*   r   <module>r      sv  &   
 $   'NO @A MN OP 	0 	0$ 	0	<$ 	<4 	<  (D (d (d (t (Vc d s  S  S  3 3 %!d %!t %! %!% %!P111 1 	1
 1 1 
1h!{H zF r*   