
    0}j	&                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m	Z	 ddl
mZ  ed      Zedz  dz  Zg d	Zdd
ZdZ G d dej"                        ZddZedk(  r e e             y)u  task-2945 — 봇 spawn(기동) 지연 실측 harness.

task-2942 가 dispatch 반환 직전 spawn 검증을 결선했으나, 총 대기 25초
(cron offset 10 + marker 예산 15)가 **실측 근거 없이** 정해졌다. 본 harness 는
더미 dispatch 를 반복 발사해 `dispatch() 호출 시각 ~ spawn-confirmed marker
생성 시각` 의 실제 분포를 수집한다.

측정 전용. 대상 코드(dispatch/spawn_verification)는 일절 수정하지 않는다.

관측 앵커
  t0        : dispatch() 호출 직전 (wall clock)
  t_ret     : dispatch() 반환 (verify 가 블로킹한 만큼 포함)
  t_marker  : watcher 스레드가 marker 파일을 **최초로 목격**한 시각
              (dispatch 가 25초에 포기해도 watcher 는 계속 관측하므로
               '진짜 지연' 과 '오판' 을 동시에 얻는다)

usage:
    python3 scripts/measure/task2945_spawn_latency.py --probes 8 --grace 240
    )annotationsN)datetime)Pathz/home/jay/workspacememoryevents)z	dev3-teamz	dev4-teamz	dev5-teamz	dev7-teamz	dev8-teamc                 >   i } t        d      j                         D ]o  }|j                  j                         s	 t	        j
                  t        |dz              }d|v sEt        |j                        | t        |      j                  <   q | S # t        $ r Y w xY w)u|  현재 살아있는 봇 세션을 {team_dir_name: pid} 로 반환.

    ★ 파일럿에서 드러난 교란변수: 봇이 이미 세션을 점유 중이면 cokacdir 스케줄러가
    두 번째 세션을 띄우지 않아 스케줄이 무기한 pending 된다(= marker 영원히 없음).
    따라서 각 probe 의 t0 시점 점유 상태를 반드시 함께 기록한다.
    z/proccwdz/workspace/teams/dev)	r   iterdirnameisdigitosreadlinkstr	Exceptionint)outprocr	   s      =/home/jay/workspace/scripts/measure/task2945_spawn_latency.pylive_team_sessionsr   (   s     CW%%' 1yy  "	++c$,/0C "S("%dii.CS	1 J	  		s   !B	BBu  [task-2945 실측용 더미 태스크 — 코드 변경 없음]

목적: 봇 기동 지연 측정. **마커만 만들고 즉시 종료**하는 것이 전부입니다.

## 해야 할 일 (이것만)
프롬프트 최상단의 spawn 확인 마커 생성 명령을 **첫 명령으로 1회 실행**한 뒤,
아무것도 하지 말고 **즉시 세션을 종료**하세요.

## 하지 말 것 (전부 생략)
- task-timer start/end 호출 금지
- 보고서/이벤트 파일 작성 금지
- finish-task 실행 금지
- 콜백(ANU callback) 발사 금지
- 코드 읽기/수정/커밋/PR 금지
- 추가 조사·질문 금지

마커 생성 직후 "마커 생성 완료" 한 줄만 답하고 종료하면 됩니다.
c                  F     e Zd ZdZdd fdZd	dZd	dZd	dZd
dZ xZ	S )MarkerWatcheruQ   events 디렉토리를 고빈도 폴링해 marker 최초 목격 시각을 기록.c                    t         |   d       || _        || _        t	        j
                         | _        i | _        t               | _	        y )NT)daemon)
super__init__
events_dirinterval	threadingEvent_stopseensetbaseline)selfr   r   	__class__s      r   r   zMarkerWatcher.__init__R   s?    %$ __&
%'	"%%    c                |    | j                   j                  d      D ch c]  }t        |       c}| _        y c c}w )N*.spawn-confirmed-*.json)r   globr   r#   )r$   ps     r   snapshot_baselinezMarkerWatcher.snapshot_baselineZ   s+    )-)=)=>X)YZAQZZs   9c           	     ,   | j                   j                         sDt        j                         }	 | j                  j	                  d      D ]  }t        |      }|| j                  v s|| j                  v r+|j                  j                  d      d   }d }	 t        j                  |j                  d            }|||||j                         j                  d| j                  |<   t!        d|j                   dt#        j$                  |      d	d
        	 | j                   j'                  | j(                         | j                   j                         sCy y # t        $ r Y w xY w# t        $ r}t!        d| d
       Y d }~pd }~ww xY w)Nr(   z.spawn-confirmed-r   utf-8encoding)
first_seentask_idpathpayloadmtimeu       [watch] marker 목격: z @ z%H:%M:%S.%fTflushu#       [watch] 폴링 예외(무시): )r    is_settimer   r)   r   r#   r!   r   splitjsonloads	read_textr   statst_mtimeprintr   fromtimestampwaitr   )r$   nowr*   spr1   r3   excs          r   runzMarkerWatcher.run]   sc   **##%))+CO--.HI &AQBT]]*bDIIo ffll+>?BG"G"&**Q[['[-J"K '*#* "#*!"!2!2%DIIbM 7xs8CYCYZ]C^_jBkl $&#&* JJOODMM*1 **##%% %   O;C5ANNOs=   A&E0 %E!=A E0 !	E-*E0 ,E--E0 0	F9FFc                8    | j                   j                          y )N)r    r"   )r$   s    r   stopzMarkerWatcher.stopx   s    

r&   c                Z    | j                   j                         D ]  }|d   |k(  s|c S  y )Nr1   )r!   values)r$   r1   recs      r   findzMarkerWatcher.find{   s4    99##% 	C9~(
	 r&   )g?)r   r   r   float)returnNone)r1   r   rM   zdict | None)
__name__
__module____qualname____doc__r   r+   rE   rG   rK   __classcell__)r%   s   @r   r   r   O   s     [([+6r&   r   c                 Z   t        j                         } | j                  dt        d       | j                  dt        dd       | j                  dt        d	       | j                  d
t	        t
        dz  dz  dz               | j                         }t        j                  j                  dt	        t
                     t        j                  t	        t
                     dd l}t        t              j                          j!                          t#        dt%        j&                         dd       t#        d|xr t)        ddg      j+                          d       g }t-        |j.                        D ]  }t0        |t%        t0              z     }d|j2                  |z    }t5               }|j7                  dd      |v }t#        d|dz    d|j.                   d| d| d t9        j:                         d!d"| d#| d       |rt#        d$d       t=        j<                         d%z   }	t=        j<                         |	k  re|j7                  dd      t5               v rIt=        j>                  d&       t=        j<                         |	k  r|j7                  dd      t5               v rIt5               }|j7                  dd      |v }t=        j<                         }
	 |j                  |t@        |d'd(ddd)*      }t=        j<                         }|dz   |||
t9        jF                  |
      jI                         |||tK        ||
z
  d-      tM        |tN              r|jQ                  d.      n
t	        |      tM        |tN              r|jQ                  d/      nd tM        |tN              r)|jS                         D ci c]  \  }}|d0vs|| c}}nd d1}|jU                  |       t#        d2|d.    d3|d/    d4|d5    d6d        t#        d7|jV                   d8d       t=        j<                         |jV                  z   }t=        j<                         |k  rOtY        fd9|D              rt#        d:d       n-t=        j>                  d       t=        j<                         |k  rOj[                          |D ]  }j]                  |d;         }|rz|d<   |d=<   t9        jF                  |d<         jI                         |d><   |d?   |d@<   tK        |d<   |dA   z
  d-      |dB<   tK        |d?   |dA   z
  d-      |dC<   |dD   |dE<   |dF   |dG<   d |d=<   d |dB<    t_        |j`                        }|jb                  je                  ddH       |jg                  dIdJK      5 }|D ]+  }|ji                  tk        jl                  |d)L      dMz          - 	 d d d        t#        dN| d       |D cg c]  }|jQ                  dB      |dB    }}t#        dOt%        |       dt%        |       dP       |r4to        |      }t#        dQ|d    dR|t%        |      d&z      dS|dT           y# tB        $ r}d+tE        |      d,}Y d }~d }~ww xY wc c}}w # 1 sw Y   xY wc c}w )UNz--probes   )typedefaultz--grace   u(   마지막 dispatch 후 추가 관측 초)rV   rW   helpz
--start-idi z--outr   reportsztask-2945-raw.jsonl)rW   r   u*   [harness] watcher 시작 (baseline marker u   건)Tr5   z[harness] spawn_verify_enabled=zdispatch.spawn_verificationx)fromlistztask-z-team z
[probe    /z] u    → z  (z%H:%M:%Sz) occupied=z live=uB       [skip-wait] 대상 봇 점유 중 — 최대 90s 해제 대기Z      normalcodingF)team_id	task_descr1   level	task_typeforceallow_no_scoperefresh_mapharness_exception)statusmessage   rl   spawn_verification)prompt)prober1   teamt0t0_isotarget_bot_occupied_at_t0live_sessions_at_t0t_retdispatch_elapsedrl   ro   
raw_resultu       dispatch 반환: status=z	 verdict=z	 elapsed=rx   su*   
[harness] 전 probe 발사 완료. grace u   s 추가 관측...c              3  F   K   | ]  }j                  |d            yw)r1   N)rK   ).0rwatchers     r   	<genexpr>zmain.<locals>.<genexpr>   s     ;aw||AiL);s   !u9   [harness] 전 probe marker 확보 — grace 조기 종료r1   r0   t_markert_marker_isor4   marker_mtimers   latency_from_calllatency_mtime_from_callr3   marker_payloadr2   marker_path)parentsexist_okwr-   r.   )ensure_ascii
u   
[harness] raw 기록: u   [harness] marker 확보 u   건z[harness] min=z med=z max=)8argparseArgumentParseradd_argumentr   r   	WORKSPACE
parse_argssysr2   insertr   chdirdispatchr   
EVENTS_DIRr+   startr?   lenr#   
__import__
is_enabledrangeprobesBOT_ROTATIONstart_idr   replacer   rB   r8   sleep
DUMMY_DESCr   reprr@   	isoformatround
isinstancedictgetitemsappendgraceallrG   rK   r   r   parentmkdiropenwriter:   dumpssorted)apargsdrecordsirr   r1   	occupancy	self_busy_dlrs   resultrD   t1kvrJ   deadlinemr   fr}   latlat_sr~   s                           @r   mainr      s;   		 	 	"BOOJS!O4OOIC;eOfOOLsEO:OOGSX)=	)ILa)a%bOc==?DHHOOAs9~&HHS^J'GMMO	6s7;K;K7L6MT
RZ^_	+A,x*=Zfiej2k2v2v2x+y
z G4;; .AAL 112$--!+,-&(	LL"-:		!A#a}BwiuTF C,,.*+i[ykSZ^	`V^bc))+"C))+#Wb(AEWEY(Y

1 ))+#Wb(AEWEY(Y*,IWb1Y>IYY[	KZZ$"#!   	F YY[U,,R0::<)2#, %b2gq 1.8.Ffjj*CPVKFPQWY]F^&**-A"Bdh&$' -3LLNSDAqa{>R1a4S-1
 	s,S]O9SI]E^D_ `/014;?	A[.A` 
7

|CU
V^bcyy{TZZ'H
))+
 ;7;;MUYZ

1	 ))+
 
 LLN ,LLY(oC
O"*"8"8<"I"S"S"UC"#G*C',Q|_s4y-H!'LC#$-21W:D	3I1-MC)*$%iLC !!"6C"C
O'+C#$, txx.CJJTD1	#	( @A 	@CGGDJJs7$>?	@@ 
$SE
*$7+2
]aaee<O6P6\1 !
]C
]	$SXJaG~S
AB
suQxjeCJM.B-C5rTUs  	K 3S	JF	K T@@ @
 ^s<   'Y1ZZ(1Z6Z(Z(1	Z:ZZZ%__main__)rM   zdict[str, int])rM   r   )rR   
__future__r   r   r:   r   r   r   r8   r   pathlibr   r   r   r   r   r   Threadr   r   rO   
SystemExit r&   r   <module>r      s   & #   	 
    &'	!H,
 Q&
(0I$$ 0fgT z
TV
 r&   