+
    lHàjP"  ã                   ó²   € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
Ht ^ RIHt ]	'       d   ^ RIHt ]P                   ! R4      t ! R R4      tR# )	zQProcess-tree termination and post-kill survivor verification for ProcessRegistry.N)Úsuppress)ÚTYPE_CHECKINGÚListÚOptional)Úwindows_hide_flags)ÚProcessSessionztools.process_registryc                   ó¤   a € ] tR t^t o Rt]V 3R lR l4       t]RV 3R lR ll4       t]V 3R lR l4       t	R	t
V 3R
 lR ltV 3R lR ltRtV tR# )ÚProcessTerminationMixinz•The subclass supplies ``_host_pid_is_ours``, ``_is_host_pid_alive``,
``_detached_host_fate`` and ``_daemon_term_grace_seconds``. See ProcessRegistry.c                ó    <€ V ^8„  d   QhRS[ /# )é   Úreturn)Úbool)ÚformatÚ__classdict__s   "€ÚG/home/ubuntu/.hermes/hermes-agent/tools/process_registry_termination.pyÚ__annotate__Ú$ProcessTerminationMixin.__annotate__   s   ø€ ÷ ñ ™Tñ ó    c                óš   €  ^ RI pV P                  4       ;'       d    V P                  4       VP                  8g  #   \         d     R# i ; i)zSTrue if a psutil.Process is running and not a zombie (already dead, just unreaped).NF)ÚpsutilÚ
is_runningÚstatusÚSTATUS_ZOMBIEÚ	Exception)Úprocr   s   & r   Ú_proc_aliveÚ#ProcessTerminationMixin._proc_alive   sB   € ð	ÛØ—?‘?Ó$×NÐN¨¯©«¸&×:NÑ:NÑ)NÐNøÜô 	Úð	ús   ‚; �; »A
Á	A
Nc                ó:   <€ V ^8„  d   QhRS[ RS[S[ ,          RR/# )r   ÚpidÚexpected_startr   N)Úintr   )r   r   s   "€r   r   r   !   s1   ø€ ÷ ayñ ay¡cð ay¹8ÁC½=ð ayÐTXñ ayr   c                ó¶  a aaa€ ^ RI Hp Ve1   S P                  SV4      '       g   \        P	                  RS4       R# V3R lpV'       dG    \
        P                  ! RR\        S4      RR.R	R	R
R^
\        4       \
        P                  RR7	       R# ^ RIpVP                  VP                  \        3p VP!                  S4      p TP%                  R	R7      p\'        T4      ;_uu_ 4        TP)                  4        RRR4       S P+                  4       oR T T3R llp	T	! T.4       S^ 8:  d   TM*T U
u. uF  p
S P-                  T
4      '       g   K  T
NK   	  up
pT F/  p
\'        T4      ;_uu_ 4        T
P)                  4        RRR4       K1  	  T.TOpS^ 8:  d   R# T	! T4       \'        T4      ;_uu_ 4        S P-                  T4      '       dG   T U
u0 uF  qªP.                  kK  	  up
oTP1                  T3R lTP%                  R	R7       4       4       RRR4       T Fg  p
\'        T4      ;_uu_ 4        S P-                  T
4      '       d2   T
P3                  4        \        P5                  RT
P.                  S4       RRR4       Ki  	  R#   \        \
        P                  \        3 d    T! 4         R# i ; i  TP                   d     R# \        \"        3 d    T! 4         R# i ; i  T d    . p EL"i ; i  + '       g   i     EL; iu up
i   + '       g   i     EKÌ  ; iu up
i   + '       g   i     EL#; i  + '       g   i     EK6  ; i)uo  Terminate a host-visible PID and its descendants.
``expected_start`` (kernel start time at spawn) is re-validated first: a mismatch
or dead PID means the number was recycled onto a stranger and we refuse to touch
it â€” a leaked orphan beats tree-killing someone's browser. POSIX: snapshot descendants,
SIGTERM the parent alone so it can perform an orderly shutdown, then clean up snapshot
descendants that survive its grace window. Survivors are SIGKILLed after a second
``terminal.daemon_term_grace_seconds`` window. Windows:
``taskkill /T /F`` (psutil's stale PPID links miss orphans there); ``os.kill``
is the fallback.)Ú_IS_WINDOWSNuf   Refusing to terminate host pid %d: start-time mismatch â€” PID was recycled onto an unrelated process.c                  óÎ   <€ \        \        \        \        4      ;_uu_ 4        \        P
                  ! S \        P                  4       R R R 4       R #   + '       g   i     R # ; i©N)r   ÚOSErrorÚProcessLookupErrorÚPermissionErrorÚosÚkillÚsignalÚSIGTERM©r   s   €r   Ú_sigterm_quietlyÚEProcessTerminationMixin._terminate_host_pid.<locals>._sigterm_quietly3   s5   ø€ Üœ'Ô#5´×GÕGÜ—’˜œVŸ^™^Ô,÷ H×G×GÒGús   £&AÁA$	Útaskkillz/PIDz/Tz/FTzutf-8ÚreplaceF)Úcapture_outputÚtextÚencodingÚerrorsÚtimeoutÚcreationflagsÚstdinÚcheck©Ú	recursivec                ó   € V ^8„  d   QhRR/# )r   r   N© )r   s   "r   r   ÚAProcessTerminationMixin._terminate_host_pid.<locals>.__annotate__W   s   € ÷ 	!ñ 	! tñ 	!r   c                 ó:  <€ S^ 8:  d   R# \         P                  ! 4       S,           p\         P                  ! 4       V8  d[   \        ;QJ d    V3R lV  4       F  '       g   K   RM	  RM! V3R lV  4       4      '       d   \         P                  ! R4       Kr  R# R# )é    Nc              3   óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir$   )r   )Ú.0ÚpÚclss   & €r   Ú	<genexpr>ÚVProcessTerminationMixin._terminate_host_pid.<locals>._wait_for_exit.<locals>.<genexpr>[   s   øé € Ð5ZÑRYÈQ°c·o±oÀa×6HÐ6HÓRYùs   ƒ!TFçš™™™™™©?)ÚtimeÚ	monotonicÚanyÚsleep)ÚtargetsÚdeadlinerC   Úgraces   & €€r   Ú_wait_for_exitÚCProcessTerminationMixin._terminate_host_pid.<locals>._wait_for_exitW   sd   ø€ Ø˜ŒzÙÜ—~’~Ó'¨%Õ/ˆHÜ—.’.Ó" XÔ-·#³#Ô5ZÑRYÓ5Z·#·#²#Ô5ZÑRYÓ5Z×2ZÒ2ZÜ—
’
˜4Ö ñ 3[Ñ-r   c              3   óL   <"  € T F  qP                   S9  g   K  Vx € K  	  R # 5ir$   r,   )rA   rB   Úknowns   & €r   rD   Ú>ProcessTerminationMixin._terminate_host_pid.<locals>.<genexpr>}   s   øé € Ð`Ñ*I QÏUÉUÐZ_ÑM_ŸqšqÓ*Iùs   ƒ$š
$zDEscalated to SIGKILL for pid %d (ignored SIGTERM within %.1fs grace))Útools.process_registryr"   Ú_host_pid_is_oursÚloggerÚwarningÚ
subprocessÚrunÚstrr   ÚDEVNULLÚFileNotFoundErrorÚTimeoutExpiredr%   r   ÚNoSuchProcessÚAccessDeniedÚProcessr'   Úchildrenr   Ú	terminateÚ_daemon_term_grace_secondsr   r   Úextendr)   Úinfo)rC   r   r   r"   r-   r   ÚgoneÚparentÚdescendantsrN   r   Ú	remainingrK   rM   rQ   s   ff&          @@r   Ú_terminate_host_pidÚ+ProcessTerminationMixin._terminate_host_pid    sÃ  û€ õ 	7àÒ%¨c×.CÑ.CÀCÈ×.XÒ.XÜ�N‰Nð>Ø?BôDñ õ	-÷ ð#Ü—’Ø ¬¨S«°4¸Ð>ÈtÐZ^Ø$¨YÀÔRdÓRfÜ$×,Ñ,°Eõ;ñ ÛØ×$Ñ$ f×&9Ñ&9¼7ÐCˆð	Ø—^‘^ CÓ(ˆFð	Ø Ÿ/™/°D˜/Ó9ˆKô �d�^�^Ø×ÑÔ÷ ð ×.Ñ.Ó0ˆ÷	!ñ 	!ñ 	˜�xÔ ð $)¨A¤:‘KÙ(ó4
Ù(�T¨C¯O©O¸D×,A�DˆD™[ñ4
ˆ	ó ˆDÜ˜$—•Ø—‘Ô ÷  ‘ñ ð Ð&˜IÐ&ˆð �AŒ:ÙÙ�wÔô
 �d�^�^Ø�‰˜v×&Ò&Ù.5Ó6©g dŸœ©gÑ6�Ø—‘Ô`¨&¯/©/ÀD¨/Ô*IÓ`Ô`÷ ó ˆDÜ˜$—•Ø—?‘? 4×(Ò(Ø—I‘I”KÜ—K‘KÐ fÐhl×hpÑhpÐrwÔx÷  ‘ó øôE &¤z×'@Ñ'@Ä'ÐJô #Ù Õ"Ùð#ûð ×#Ñ#ô 	ÚÜœÐ)ô 	ÙÔÚð	ûð ô 	Ø‹Kð	ú÷ �^ˆ^üò"4
÷  —‘üò* 7÷ �^ˆ^ú÷
  —‘ús’   ÁAJ Â5J= ÃK/ Ã,K?Ä5LÅLÅ4LÆ:L2ÇL-Ç*.L2È8A	MÊ'J:Ê9J:Ê=K,ËK,Ë K,Ë+K,Ë/	K<Ë;K<Ë?L	ÌL*Ì-L2Ì2M	ÍMc                ó6   <€ V ^8„  d   QhRS[ RS[S[ ,          /# )r   r   r   )r    Úlist)r   r   s   "€r   r   r   …   s#   ø€ ÷ Sñ S™sð S¡t©C¥yñ Sr   c                ó   €  ^ RI pVP                  V 4      P                  RR7      pT Uu. uF,  p\        P                  T4      '       g   K   TP                  NK.  	  up#   \         d    \        P                  RT RR7       . u # i ; iu upi )zHPIDs of living non-zombie descendants of host PID ``pid`` (best-effort).NTr9   z$Could not list descendants of pid %s)Úexc_info)	r   r_   r`   r   rU   Údebugr	   r   r   )r   r   r`   Úcs   &   r   Ú_live_descendantsÚ)ProcessTerminationMixin._live_descendants„   s   € ð	ÛØ—~‘~ cÓ*×3Ñ3¸dÐ3ÓCˆHñ  (ÓR™x˜!Ô+B×+NÑ+NÈq×+Q”�—”™xÑRÐRøô ô 	Ü�L‰LÐ?ÀÈtˆLÔTØŠIð	üò Ss   ‚%A  «BÁBÁ %BÂBg      ð?c                ó4   <€ V ^8„  d   QhRRRS[ S[,          /# ©r   Úsessionr   r   ©rl   r    )r   r   s   "€r   r   r   •   s    ø€ ÷ ñ Ð,<ð ÁÁcÅñ r   c                óê   € \         P                  ! 4       V P                  ,           p V P                  V4      pV'       d   \         P                  ! 4       V8¼  d   V# \         P                  ! R4       KN  )uV  Host PIDs still alive once the kill signals have had time to land (#115490).

Fail-closed: anything unverifiable counts as a survivor, so a kill
that leaves a live tree can never write a killed receipt. Sandbox
(env) sessions have no host-visible tree and are unverifiable by
design â€” they return no survivors, preserving existing behavior.rF   )rG   rH   Ú_KILL_SETTLE_SECONDSÚ_probe_survivorsrJ   )Úselfru   rL   Ú	survivorss   &&  r   Ú_post_kill_survivorsÚ,ProcessTerminationMixin._post_kill_survivors•   sQ   € ô —>’>Ó# d×&?Ñ&?Õ?ˆØØ×-Ñ-¨gÓ6ˆIß¤§¢Ó 0°HÔ <Ø Ð Ü�JŠJ�tÖr   c                ó4   <€ V ^8„  d   QhRRRS[ S[,          /# rt   rv   )r   r   s   "€r   r   r   £   s    ø€ ÷ 1ñ 1Ð(8ð 1¹TÁ#½Yñ 1r   c                óz  a€ . o\        VR R4      pVeL    VP                  4       RJ pV'       d1   SP                  \        VRR4      ;'       g    VP                  4       \        VRR4      pVe>    \        VP                  4       4      pV'       d   SP                  VP                  4       VP                  R8X  dž   VP                  '       dŒ   V P                  VP                  VP                  4      R8X  da   VP                  S9  d   SP                  VP                  4       SP                  V3R lV P                  VP                  4       4       4       S Uu. uF  qf'       g   K  VNK  	  up#   \         d    Rp EL_i ; i  \         d     T P                  TP                  4      p EL)i ; iu upi )ÚprocessNTr   Ú_ptyÚhostÚrunningc              3   ó:   <"  € T F  pVS9  g   K  Vx € K  	  R # 5ir$   r<   )rA   r   r{   s   & €r   rD   Ú;ProcessTerminationMixin._probe_survivors.<locals>.<genexpr>¹   s"   øé € ð !-Ù#F˜CØ )Ñ+÷ ’CÓ#Fùs   ƒ	‘
)ÚgetattrÚpollr   Úappendr   r   ÚisaliveÚ_is_host_pid_aliveÚ	pid_scopeÚ_detached_host_fateÚhost_start_timerc   rq   )rz   ru   r   Ú
root_aliveÚptyÚ	pty_aliver   r{   s   &&     @r   ry   Ú(ProcessTerminationMixin._probe_survivors£   sr  ø€ Ø!ˆ	Ü�w 	¨4Ó0ˆØÒð"Ø!ŸY™Y›[¨DÐ0�
÷ Ø× Ñ ¤¨¨u°dÓ!;×!JÐ!J¸w¿{¹{ÔKÜ�g˜v tÓ,ˆØŠ?ðAÜ  §¡£Ó/�	÷ Ø× Ñ  §¡Ô-Ø×Ñ Ô&¨7¯;¯;¨;Ø×'Ñ'¨¯©°W×5LÑ5LÓMÐQZÔZØ—;‘; iÔ/Ø×$Ñ$ W§[¡[Ô1Ø× Ñ ô !-Ø#'×#9Ñ#9¸'¿+¹+Ô#Fó!-ô -ñ  )Ó0™y˜«C—�™yÑ0Ð0øô- ô "Ø!“
ð"ûô ô AØ ×3Ñ3°G·K±KÓ@“	ðAüò 1s/   –E7 Á2F Å 	F8Å.F8Å7FÆFÆ&F5Æ4F5r<   r$   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ústaticmethodr   Úclassmethodri   rq   rx   r|   ry   Ú__static_attributes__Ú__classdictcell__)r   s   @r   r	   r	      sq   ø‡ € ñXð ÷ó ðð ÷ayñ ayó ðayðF ÷Só ðSð Ð÷ð ÷1ö 1r   r	   )r–   Úloggingr(   r*   rW   rG   Ú
contextlibr   Útypingr   r   r   Úhermes_cli._subprocess_compatr   rS   r   Ú	getLoggerrU   r	   r<   r   r   Ú<module>r       sF   ðÙ Wã Û 	Û Û Û Ý ß 0Ñ 0å <çÝ5à	×	Ò	Ð3Ó	4€÷l1ó l1r   