
    j                        d Z ddlm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  ed       G d	 d
             Z G d d      Zy)u  anu_v3.active_dispatch_scanner — read-only active dispatch enumerator.

task-2553+31 ANU_RUNTIME_RECONCILE_CHECKPOINT leaf module
(구현목표 1·2 — active dispatch 목록 / dispatch log status 감지).

Two read-only sources:
  * normalized reconcile fixture (memory/fixtures/*.json) — primary input for
    deterministic regression
  * *.dispatch-fired.json event files (read/parse only) — live enumeration

NO-CRON / read-only invariant (§7/§9/§10): zero cron register/remove, zero
schedule mutation, zero write. cron-list / schedule_history are *read-only*
inputs when consulted; this module never cancels/removes/registers a cron.
    )annotationsN)	dataclassfield)Path)DictListOptionalT)frozenc                      e Zd ZU dZded<   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<   dZ	ded<    e
e      Zded<   edd       ZddZddZy	)DispatchRecordz:Read-only view of one dispatched track's 4-tuple + status.strtask_iddispatch_cron_iddispatch_status executorfallback_callback_cron_idNzOptional[str]!expected_normal_collector_cron_idnormal_collector_cron_idFboolby_design_no_normal_collector)default_factoryz	List[str]expected_artifactsc                L    t        | j                        j                         dv S )N)okfiredsuccess)r   r   lowerselfs    5/home/jay/workspace/anu_v3/active_dispatch_scanner.pydispatch_okzDispatchRecord.dispatch_ok&   s"    4''(..04NNN    c                |    | j                   | j                  | j                  xs | j                  | j                  dS )N)r   r   r   r   )r   r   r   r   r   r   s    r!   
four_tuplezDispatchRecord.four_tuple*   s<    || $ 5 5-- :99)-)G)G
 	
r#   c                    | j                   | j                  | j                  | j                  | j                  | j
                  | j                  | j                  t        | j                        d	S )N)	r   r   r   r"   r   r   r   r   r   )
r   r   r   r"   r   r   r   r   listr   r   s    r!   to_jsonzDispatchRecord.to_json5   s^    || $ 5 5#33++)-)G)G6622"&t'>'>"?
 	
r#   )returnr   )r)   zDict[str, Optional[str]])r)   zDict[str, object])__name__
__module____qualname____doc____annotations__r   r   r   r   r   r   r'   r   propertyr"   r%   r(    r#   r!   r   r      sz    DLHc%'s'7;%};.2m2*/!4/$)$$?	?O O	

r#   r   c                  F    e Zd ZdZ	 d	 	 	 ddZedd       Z	 d		 	 	 d
dZy)ActiveDispatchScannerz+Enumerate active dispatch tracks read-only.c                L    t        |      | _        | j                  |z  | _        y )N)r   	repo_root
events_dir)r    r4   events_subdirs      r!   __init__zActiveDispatchScanner.__init__H   s    i..=8r#   c                (   t        j                  t        |       j                  d            }t	        |t
              r|j                  d|      n|}g }|D ]  }|j                  t        |d   |j                  dd      |j                  dd      |j                  d	d      |j                  d
d      |j                  d      |j                  d      t        |j                  dd            t        |j                  dg             	              |S )zParse a normalized reconcile fixture (read-only).

        Accepts both the flat ``{"tracks": [...]}`` shape and a bare list.
        utf-8encodingtracksr   r   r   r   r   r   r   r   r   r   Fr   )	r   r   r   r   r   r   r   r   r   )jsonloadsr   	read_text
isinstancedictgetappendr   r   r'   )fixture_pathdocr<   outts        r!   from_fixturez"ActiveDispatchScanner.from_fixtureN   s     jjl+55w5GH+5c4+@3'c$& 	AJJiL%&UU+=r%B$%EE*;T$BUU:r2./ee3R/967ee;7=-.UU2.426=uE3G'+2B7(9	& 
r#   c                   g }| j                   j                         s|S t        | j                   j                  d            D ]  }	 t	        j
                  |j                  d            }|j                  dd      }|r|j                  |      sP|j                  di       xs i }|j                  di       xs i }|j                  di       xs i }|j                  t        ||j                  d	d      |j                  d
d      |j                  dd      |j                  d|j                  dd            |j                  d                    |S # t        t        f$ r Y (w xY w)zEnumerate *.dispatch-fired.json under events/ (read-only).

        Pure stat + json parse. No file is created or modified.
        z*.dispatch-fired.jsonr9   r:   r   r   dispatchcallback_policy_ar%   cron_idr   r   r   r   r   )r   r   r   r   r   r   )r5   is_dirsortedglobr=   r>   r?   OSError
ValueErrorrB   
startswithrC   r   )	r    task_id_prefixrF   prE   tidrJ   cbfts	            r!   scan_dispatch_firedz)ActiveDispatchScanner.scan_dispatch_firedm   sU    %'%%'J,,-DEF 	Ajjg!>? '')R(Ccnn^&Dwwz2.4"H,b17RBb)/RBJJ%-\\)R%@$'GG,=t$D%\\*b9.0ff3:B?/A 79ff274
	0 
+ Z( s   %EE,+E,N)zmemory/events)r4   r   r6   r   r)   None)rD   r   r)   List[DispatchRecord])r   )rS   r   r)   rZ   )r*   r+   r,   r-   r7   staticmethodrH   rX   r0   r#   r!   r2   r2   E   sM    5 '69 #9:>9  > %'"!"	"r#   r2   )r-   
__future__r   r=   dataclassesr   r   pathlibr   typingr   r   r	   r   r2   r0   r#   r!   <module>r`      sI    #  (  ' ' $)
 )
 )
XJ Jr#   