
    i'                     B   d Z ddlZddlZddlmZmZ dZdZdZddhZd	Z	d
e
eef   fdZded
efdZdeded
e
eef   fdZded
efdZedk(  rRddlZddlZ eej,                        dkD  rej,                  d   ndZ ee      Z e ej4                  edd             yy)u   
data_integrity.py - task-timers.json 교차검증 verifier
task-timers.json의 task 상태와 .done 파일을 교차 대조
stale 체크: running 상태가 2시간 이상이면 WARNING
    N)datetimetimezonez+/home/jay/workspace/memory/task-timers.jsonz!/home/jay/workspace/memory/events   	completeddonerunningreturnc                     t         j                  j                  t              si dt         fS 	 t	        t        dd      5 } t        j                  |       }ddd       dfS # 1 sw Y   xY w# t
        j                  $ r}i d| fcY d}~S d}~wt        $ r i dt         fcY S t        $ r}i d	| fcY d}~S d}~ww xY w)
u2   task-timers.json 로드. (data, error_msg) 반환.ztask-timers.json not found: rzutf-8)encodingN z&JSON parse error in task-timers.json: zPermission denied: z#OS error reading task-timers.json: )
ospathexistsTASK_TIMERS_PATHopenjsonloadJSONDecodeErrorPermissionErrorOSError)fdataes      A/home/jay/workspace/teams/dev1/qc/verifiers.bak/data_integrity.py_load_task_timersr      s    77>>*+12B1CDDD	="C': 	 a99Q<D	 Rx	  	   @;A3??? <()9(:;;; =8<<<=sM   A0 A$A0 $A-)A0 0CB	CC(C0B<6C<Ctask_idc                      t         j                  j                  t              sy	 t        j                  t              }t         fd|D              S # t        $ r Y yw xY w)uD   events/ 디렉토리에 task_id의 .done 파일이 있는지 확인.Fc              3   L   K   | ]  }|j                        xr d |v   yw)z.doneN)
startswith).0r   r   s     r   	<genexpr>z!_has_done_file.<locals>.<genexpr>(   s&     Ka1<<(9W\9Ks   !$)r   r   isdir
EVENTS_DIRlistdiranyr   )r   entriess   ` r   _has_done_filer(   "   sL    77==$**Z(K7KKK s   ,A 	A A 	task_infoc                    | j                  dd      }|t        k7  ry| j                  dd      }|sdd| dfS 	 t        j                  |      }|j                  t        j
                         }n#t        j
                  t        j                        }||z
  j                         d	z  }|t        k\  rdd| d
|ddt         dfS y# t        $ r}dd| d| d| fcY d}~S d}~ww xY w)ux   
    running 상태인 태스크가 2시간 이상 경과했는지 확인.
    (is_warning, detail_message) 반환.
    statusr   )Fr   
start_timeT	WARNING [z%]: running but no start_time recordedNi  z]: running for z.1fzh (threshold: u   h) — possibly stalez]: cannot parse start_time 'z': )getRUNNING_STATUSr   fromisoformattzinfonowr   utctotal_secondsSTALE_THRESHOLD_HOURS
ValueError)r)   r   r+   start_time_strr,   r2   elapsed_hoursr   s           r   _check_staler9   -   s   
 ]]8R(F]]<4Ny	)NOOO]++N;
$,,.C,,x||,Cz)88:TA11G9OM#3F G455JL   ]y	)EnEUUXYZX[\\\]s   B
C 	C&C!C&!C&c                    | sddgdS g }d}d}t               \  }}|rd|gdS |j                  di       }t        |t              sddt	        |      j
                   dgdS | |vr
dd	|  d
gdS ||    }|j                  dd      }|j                  d|  d| d       t        |       }	|j                  d|	rdnd d|         |t        v r|	s|j                  d|  d| d       d}nk|	r$|t        k(  r|j                  d|  d| d       d}nE|t        v r|	r|j                  d|  d| d       n"|t        vr|	s|j                  d|  d| d       t        ||       \  }
}|
r|j                  |       d}d|v rBd|v r>|j                  d|d    d |j                  dd!       d"|j                  d#d$       d       |rd}n|rd%}nd&}||dS )'u   
    task-timers.json에서 task_id의 상태를 확인하고
    .done 파일과 교차 검증합니다.

    Args:
        task_id: 검증할 task ID

    Returns:
        {"status": "PASS"|"FAIL"|"WARN"|"SKIP", "details": [...]}
    SKIPzNo task_id specified)r+   detailsFFAILtasksz3task-timers.json: 'tasks' field is not a dict (got )ztask 'z' not found in task-timers.jsonr+   unknownztask-timers.json: [z
] status=''zevents/.done file: FOUNDz	NOT FOUNDz for zFAIL [z]: status='z' but no .done file in events/Tr-   z!]: .done file exists but status='zOK [z ' and .done file both consistentu   ' — task not yet completedr,   end_timez
timeline: u    → zN/Az (duration_humanr   WARNPASS)r   r.   
isinstancedicttype__name__appendr(   COMPLETED_STATUSESr/   r9   )r   r<   has_failurehas_warningr   load_errr>   r)   r+   done_existsis_stale	stale_msgfinal_statuss                r   verifyrT   O   sk     .D-EFFGKK '(ND( hZ88HHWb!EeT"MdSXkNbNbMccdef
 	
 e 	)HIJ
 	

 gI]]8Y/FNN(	F81EF !)KNN
g+FeG9U
 ##KWI[0NO	
  
>1y A&K	
  
%	%+gYk&9YZ[	)	)+gYk&9UVW 'y':Hiy! y Z9%<<01y}}ZQV7W6X Y.34A7	

 	"w77    __main__   ztask-4.4F)ensure_asciiindent)__doc__r   r   r   r   r   r$   r5   rL   r/   tuplerH   strr   boolr(   r9   rT   rJ   sys_jsonlenargvtidresultprintdumps rU   r   <module>rg      s   
  	 '@ 0
 !6* =5s+ ="C D ]D ]3 ]5s3C ]DX8C X8D X8v zSXX*#((1+
CC[F	+%++f5
;< rU   