
    jW3                    b   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mZm	Z	 ddl
mZ 	 ddlmZmZmZmZ dZd	Zd
ZdddddZdZd#dZddddddddedddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d$dZd%dZefd&dZ	 	 	 	 	 	 	 	 	 	 	 	 d'dZ d(dZ!d)dZ"	 d*	 	 	 	 	 	 	 d+dZ#efd,dZ$d-d.d Z%d/d0d!Z&e'd"k(  r e( e&             y# e$ r] ej$                  j'                  dej$                  j)                  ej$                  j+                  e                   ddlmZmZmZmZ Y w xY w)1uY  failure_envelope_writer.py — task-2712 FAILURE_CALLBACK_BEFORE_EXIT_GUARD.

Failure callback envelope 박제 + exactly-one-terminal-marker rule + fallback
chain (stderr emit / syslog journal).

회장 verbatim doctrine (task-2712 §4 / §3.2): 봇이 9 failure terminal state
중 어떤 state 로 종료되든 exit 전에 disk terminal marker 1개를 박제한다.
.done 은 SUCCESS 전용. envelope 은 UTF-8 ≤ 3900 bytes hard.

본 모듈은 §3.2.1 6 marker path · §3.2.4 marker count verification · §4.1 11
mandatory field · §4.2 byte limit · §4.3 fallback rule 을 1:1 mirror 한다.
    )annotationsN)datetimetimezone)Optional   )ANU_KEYUNCLASSIFIED_TERMINAL_STATEclassify_terminal_stateis_terminal_state)task_idteambotsessionphase	exit_codefailure_kindartifact_pathscritical7_matchterminal_statechair_authorization_idi<  zMCHAIR-AUTH-TASK-2712-FAILURE-CALLBACK-BEFORE-EXIT-GUARD-IMPLEMENTATION-260530.failure-envelope.json.failure-handoff-marker.json.supervisor-crash-marker.json.done)failure_envelopefailure_handoffsupervisor_crashdonefailure_callback_2712c                 f    t        j                  t        j                        j	                  d      S )Nz%Y-%m-%dT%H:%M:%SZ)r   nowr   utcstrftime     \/home/jay/workspace/.worktrees/task-2721-dev1/scripts/harness/v36/failure_envelope_writer.py_now_isor'   I   s!    <<%../CDDr%   	dev4-teamvishnu F"failure_callback_before_exit_guard)r   r   r   r   r   r   r   r   r   registration_moderesidual_pidsummaryc               @   i d| d|d|d|xs  t         j                  j                  dd      d|dt        |      d	|d
t	        |xs g       dt        |	      d|d|
dddt        dt        ddd|dt               }|t        |      |d<   |r||d<   |S )uD   §4.1 11 mandatory field + 4 collector strict field envelope 생성.r   r   r   r   COKACDIR_SESSION_IDr*   r   r   r   r   r   r   r   collector_roleANUcollector_key	owner_keyself_key_usedFr,   recorded_atr-   r.   )osenvirongetintlistboolr   r'   )r   r   r   r   r   r   r   r   r   r   r   r,   r-   r.   envelopes                  r&   build_enveloper>   M   s&   $7 	s 	7Gbjjnn-BBG	
 	 	S^ 	 	$~34 	40 	. 	!"8 	% 	 	W  	!" 	.#$ 	xz%H( #&|#4 %Or%   c                `    t        t        j                  | d      j                  d            S )NFensure_asciiutf-8)lenjsondumpsencode)objs    r&   	_utf8_lenrH   z   s#    tzz#E299'BCCr%   c                   t        |       |k  r| S t        |       }d|v r7d|d<   t        |      |k  r|S |j                  dd       t        |      |k  r|S t        |j	                  dd            dkD  r|d   dd |d<   t        |      |k  r|S t        |j	                  dg             dkD  rFt        |      |kD  r8|d   dd |d<   t        |j	                  dg             dkD  rt        |      |kD  r8|S )	u   §4.2 / §4.3: UTF-8 ≤ limit bytes. 초과 시 summary 축소 → 제거 →
    artifact_paths 만 유지하며 mandatory field 는 보존한다.r.   r*   Nr       r   r   )rH   dictpoprC   r9   )r=   limitenvs      r&   enforce_byte_limitrP   ~   s    e#
x.CCIS>U"J	4 S>U"J
377>2&'",!.1#26NS>U"J
cgg&+
,q
0Ys^e5K #$4 5cr : cgg&+
,q
0Ys^e5KJr%   c           
     `    d|  d| d| d| d| 
}t        |t        j                  d       |S )u@   §4.3.1 stderr 1-line emit (envelope-write fail fallback). fd=2.zFAILURE_CALLBACK_2712 task_id= terminal_state= exit_code= failure_kind=z phase=T)fileflush)printsysstderr)r   r   r   r   r   lines         r&   emit_stderr_liner[      sL    
 )	1A.AQ RK~l^75'	K 	 
$SZZt,Kr%   c                    	 t        j                  ddt        ddd|  d| d| d| gd	d
       y# t        $ r Y y	w xY w)uD   §4.3.2 syslog journal last-resort. logger -t failure_callback_2712.logger-tz-pzuser.warningztask_id=rR   rS   rT   F   )checktimeoutT)
subprocessrun
SYSLOG_TAG	Exception)r   r   r   r   s       r&   emit_syslogrf      sl    7)#3N3C D&K~l^E 	
  s   .1 	==c                   g }t         d   t         d   t         d   t         d   fD ]W  }t        j                  j                  ||  |       }t        j                  j	                  |      sG|j                  |       Y |S )uD   task_id 의 현존 terminal marker 경로 목록 (4 terminal class).r   r   r   r   )MARKER_SUFFIXr7   pathjoinexistsappend)r   
events_dirfoundsuffixps        r&   _existing_terminal_markersrq      s|    Ef()'(()	  GGLLy%9:77>>!LLO Lr%   c                   t        j                  |d       | d   }t        ||      }|rd|dS t        |       } t        j                  |t        d         }t         j                  j                  || |       }	 t        |dd	      5 }t        j                  | |d
d       ddd       d|t        |       |dS # 1 sw Y   xY w# t        t        f$ r t        |t        | j                  dd      | j                  dd      | j                  dd            }d
}		 t         j                  j                  || d      }
t        |
dd	      5 }|j!                  |dz          ddd       n# 1 sw Y   nxY wd}	n# t"        $ r Y nw xY wt%        |t        | j                  dd      | j                  dd            }|	s|rd||dcY S d|dcY S w xY w)u[  terminal marker JSON 박제. exactly-one-terminal-marker rule 적용.

    이미 terminal marker 가 존재하면 (success .done 포함) skip 하여 multi-fire
    를 방지한다 (§3.2 idempotent). write IO 실패 시 stderr 1-line + syslog
    fallback 으로 강등한다 (§4.3).

    return: {"status": ..., "path": ..., ...}
      - WRITTEN              : terminal marker 신규 박제
      - SKIPPED_ALREADY_TERMINAL : 이미 terminal marker 존재 (no-op)
      - FALLBACK_STDERR      : envelope-write fail → stderr emit
      - FALLBACK_STDERR_SYSLOG_FAIL : stderr+syslog 모두 fail
    T)exist_okr   SKIPPED_ALREADY_TERMINAL)statusexistingr   wrB   )encodingF   )rA   indentNWRITTEN)ru   ri   bytesmarker_typer   rK   r   disk_full_or_io_errorr   r*   .stderr-emit.loga
FALLBACK_STDERR)ru   stderr_linesyslogFALLBACK_STDERR_SYSLOG_FAIL)ru   r   )r7   makedirsrq   rP   rh   r9   ri   rj   openrD   dumprH   OSErrorIOErrorr[   r	   writere   rf   )r=   rm   r}   r   rv   ro   ri   frZ   	wrote_loglog_pathlf	syslog_oks                r&   write_enveloper      s   " KK
T*y!G)':>H4(KK!(+H{M:L,MNF77<<
wix$89D#N$g. 	A!IIha@	A  x(&	
 	
	A 	A W N'LLb)LL)@ALL"%
 		ww||J7);K0LMHhg6 &"%& & &I 		'LLb)LL,	
	 	/PYZZ7MM5Nsm   =C	 B=%C	 =CC	 	AG1E<E-$	E<-E6	2	E<;G<	FGF?G	GGc                    	 t        j                  dd|dddgddd      }| |j                  xs d	v S # t        $ r Y y
w xY w)uA   journalctl 로 syslog journal 항목 존재 확인 (best-effort).
journalctlr^   z
--no-pagerz-n200Tr_   )capture_outputtextra   r*   F)rb   rc   stdoutre   )r   tagouts      r&   _syslog_journal_has_entryr     sV    	nn4lD%@	
 3::+,, s   03 	??c                   dfd} ||  d       ||  d       ||  d       ||  d      g}t        |      }t        j                  j                  |  d      }t        j                  j	                  |      xr" t        j                  j                  |      dkD  }|xs t        | t              }|dk(  r|rd	d
dS dddS |dk\  rd|dS d|dS )u   §3.2.4 marker count verification. 4 enum 반환:
    OK / ZERO_FIRE / ZERO_FIRE_BUT_FALLBACK_RECOVERABLE / MULTI_FIRE_VIOLATION
    c                ~    t         j                  j                  t         j                  j                  |             S N)r7   ri   rk   rj   )rp   rm   s    r&   path_existsz7verify_exactly_one_terminal_marker.<locals>.path_exists  s%    ww~~bggll:q9::r%   r   r   r   r   r   r   )r   "ZERO_FIRE_BUT_FALLBACK_RECOVERABLET)ru   fallback_evidence	ZERO_FIREFry   MULTI_FIRE_VIOLATIONOK)rp   strreturnr<   )sumr7   ri   rj   rk   getsizer   rd   )r   rm   r   terminal_markersterminal_count
stderr_logstderr_evidencefallback_evidence_presents    `      r&   "verify_exactly_one_terminal_markerr     s   
; 	wiu%&wi567wi;<=wi<=>	 )*NjWI5E*FGJggnnZ0TRWW__Z5PST5TO / !3LZ4 $>%)  &EBB,!:
 	
 1JKKr%   c                   t        j                  d      }|j                  dd       |j                  dd       |j                  dt        d	       |j                  d
d       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dd       |j                  dt        d 	       |j                  dt        j
                  j                  dd             |j                  |       }|j                  }t        |      st        |j                  |      }|j                  j                  d      D cg c]  }|j                         s| }}t        |j                   ||j"                  |j$                  |j&                  |j(                  |j                  |j*                  ||j,                  |j.                        }t1        ||j2                  |j4                        }t7        t9        j:                  |d !             y"c c}w )#Nz!task-2712 failure envelope writer)descriptionz	--task-idT)requiredz--terminal-statez--exit-coder   )typedefaultz--failure-kindr*   )r   z--phasez--teamr(   z--botr)   z	--sessionz--marker-typer   z--artifact-pathsz--critical7
store_true)actionz--residual-pidz--events-dir FAILURE_CALLBACK_2712_EVENTS_DIRz!/home/jay/workspace/memory/events,)	r   r   r   r   r   r   r   r   r-   )r}   Fr@   r   )argparseArgumentParseradd_argumentr:   r7   r8   r9   
parse_argsr   r   r
   r   r   splitstripr>   r   r   r   r   r   r   	critical7r-   r   rm   r}   rW   rD   rE   )argvapargsr   rp   	artifactsr=   results           r&   _mainr   :  s   		 	 -P	QBOOK$O/OO&O6OOMQO7OO$bO1OOIrO*OOHkO2OOGXO.OOKO,OOO-?O@OO&O3OOM,O7OO$3O=OO

.0S
   ==D((N^,0P //55c:HqaggiHIHYYHHjj..&& &&H Hdoo4CSCSTF	$**V%
01# Is   I 'I __main__)r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r:   r   r   r   zOptional[list]r   r<   r   r   r,   r   r-   zOptional[int]r.   r   r   rL   )rG   rL   r   r:   )r=   rL   rN   r:   r   rL   )r   r   r   r   r   r:   r   r   r   r   r   r   )
r   r   r   r   r   r:   r   r   r   r<   )r   r   rm   r   r   r;   )r   )r=   rL   rm   r   r}   r   r   rL   )r   r   r   r   r   r<   )zmemory/events)r   r   rm   r   r   rL   r   )r   r:   ))__doc__
__future__r   r   rD   r7   rb   rX   r   r   typingr   terminal_state_classifierr   r	   r
   r   re   ri   insertdirnameabspath__file__MANDATORY_FIELDS
BYTE_LIMITCHAIR_AUTHORIZATION_IDrh   rd   r'   r>   rH   rP   r[   rf   rq   r   r   r   r   __name__
SystemExitr$   r%   r&   <module>r      s,   #   	  
 '     
 T  157	 %
E %)!"8A"&*** 	*
 
* * * * * #* *  * *  * *  
!*ZD 5? 2		"%	25	EH	QT		*$ *=N=N=N =N 
	=N@ 8B !LJ,^ z
UW
 S
  HHOOArwwrwwx'@AB s   C AD.-D.