
    j                       d Z ddlmZ ddlZddlZddlZddlmZ dZdZ	dZ
dd	d
ddddZ eej                               ZddZdddZddZddZddZedk(  rddlZddlZ eej0                        dk\  re eej0                  d         Z e ej8                  e ee eej0                        dkD  rej0                  d   nd       ee      dd             yyy) u   terminal_state_classifier.py — task-2712 FAILURE_CALLBACK_BEFORE_EXIT_GUARD.

10 terminal state + 11 signal taxonomy 분류 + spawn verification.

회장 verbatim doctrine (task-2712 §3): 봇이 어떤 terminal state 로 종료되든 exit
전에 disk marker 박제가 가능하도록, exit_code / signal 을 10 terminal state 중
하나로 분류한다. CRASH_NO_EXIT_CODE 는 SIGKILL/OOM/kernel panic 등 정상 exit
code 가 없는 경우의 sentinel 이다.

본 모듈은 §3.1 / §3.1.1 / §5.2.1 의 locked spec 을 1:1 mirror 한다.
    )annotationsN)Optionalc119085addb0f8b7)
SUCCESSFAILUREBLOCKEDSCOPE_GUARD_FAILQC_FAILINFRA_DEFECTPERMISSION_FAILAPI_FAILCRITICAL_ESCALATIONCRASH_NO_EXIT_CODEUNCLASSIFIED_TERMINAL_STATESIGKILLSIGTERMSIGINTSIGSEGVSIGBUSOOM_OR_KERNEL_PANIC)iiiic                >    t         j                  t        |             S )u+  exit_code(음수 signal sentinel) → signal 이름. 비-signal 이면 None.

    §3.1.1 의 11 signal taxonomy 중 sentinel 매핑을 반환한다.
    container OOM-kill / kernel panic / docker stop cascade 는 모두 -1/-9/-15
    sentinel 로 수렴하므로 본 매핑으로 커버된다.
    )SIGNAL_TAXONOMYgetint)	exit_codes    ^/home/jay/workspace/.worktrees/task-2721-dev1/scripts/harness/v36/terminal_state_classifier.pyclassify_signalr   8   s     s9~..    c                P    t        |       }|dk(  ry|t        v ry|r
|t        v r|S y)u'  exit_code(+optional hint) → 10 terminal state 중 하나.

    규칙 (§3.1 / §5):
      - exit_code == 0  → SUCCESS
      - exit_code in {-1,-2,-7,-9,-11,-15} (signal sentinel) → CRASH_NO_EXIT_CODE
      - 그 외 비정상 exit_code → hint 가 valid terminal_state 면 hint, 아니면 FAILURE

    `hint` 는 inner-script hook 이 명시한 terminal_state (예: SCOPE_GUARD_FAIL,
    QC_FAIL) 를 그대로 보존하기 위한 통로다. `set -e` cascade / `trap EXIT`
    에서도 original terminal_state 를 보존한다 (§3.1.1).
    r   r   r   r   )r   _CRASH_SIGNAL_CODESTERMINAL_STATES)r   hintcodes      r   classify_terminal_stater&   B   s5     y>Dqy""#'r    c                (    | t         v xs	 | t        k(  S )uA   value 가 10 terminal state(또는 UNCLASSIFIED fallback) 인지.)r#   r   )values    r   is_terminal_stater)   X   s    O#Ku0K'KKr    c                    	 ddl }|j                  |       S # t        $ r Y nw xY w	 t        j                  | d       y# t
        $ r Y yt        $ r Y yt        $ r Y yw xY w)uQ   psutil 없이도 동작하는 pid 존재 확인 (psutil 있으면 우선 사용).r   NFT)psutil
pid_exists	ExceptionoskillProcessLookupErrorPermissionError)pidr+   s     r   _pid_existsr3   ]   sn      %% 
Q     s'    	##> 	A	AAAc                   d}t        t        j                  j                  d|            }d}d}t        j                  j                  ||  d      }||k  rLt        j                  |      r|t        t        |            ryt        j                  |       ||z  }||k  rL|duxr t        t        |            }	|	ryy	)
ur  §5.2.1 spawn verification.

    return: SPAWNED / DISPATCH_FALSE_OK / TIMEOUT_BOT_ALIVE_BUT_NO_MARKER

    spawn-confirmed marker 가 timeout 안에 나타나면 SPAWNED. timeout 후에도
    marker 없는데 child 가 살아있으면 TIMEOUT_BOT_ALIVE_BUT_NO_MARKER, child 도
    없으면 DISPATCH_FALSE_OK (등록은 OK 였지만 실제 spawn 0 인 false-OK).
       'FAILURE_CALLBACK_2712_SPAWN_TIMEOUT_SEC   r   z.spawn-confirmed-*.jsonNSPAWNEDTIMEOUT_BOT_ALIVE_BUT_NO_MARKERDISPATCH_FALSE_OK)
r   r.   environr   pathjoinglobr3   timesleep)
task_idexpected_bot_id	child_pid
events_dirDEFAULT_TIMEOUT_SECtimeout_secpollingelapsedpatternchild_alives
             r   _verify_bot_spawnrK   q   s     


@BUVK GGggll:'2I'JKG
K
99W KI$? 

77 K
 D(Ik#i..IK0r    __main__   r7   )r   terminal_statesignalF)ensure_ascii)r   r   returnOptional[str])N)r   r   r$   rR   rQ   str)r(   rS   rQ   bool)r2   r   rQ   rT   )Nzmemory/events)__doc__
__future__r   r>   r.   r?   typingr   ANU_KEYr#   r   r   	frozensetkeysr"   r   r&   r)   r3   rK   __name__jsonsyslenargvr   ecprintdumps r    r   <module>rd      s  
 #  	    < 
 			   4 4 67 /,L
(8 z
388}!DJJ!#&=3sxx=1+<CHHQK$' .b1 #		
 	 r    