+
    „WÝj’(  ã                  óž  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIHt ^ RIHt ]P                  ! ]4      tRtRt]R3]R3]R	3]R
33t/ tR]R&   ]
P6                  ! 4       tR R ltR R ltR R ltR+R R llt R R lt!R R lt"R R lt#R R lt$R R lt%R R  lt&R! R" lt'R# R$ lt(R% R& lt)R' R( lt*R) R* lt+R# ),a�  hermes.process.exit: how Hermes processes (and watchdog-killed turns) end.

A crash or SIGKILL cannot record itself. Each long-lived entrypoint drops a small marker under its
profile's store dir at start and restamps it on the way out (``clean``, ``crash`` + class from the
excepthook, ``watchdog`` from a hard-exit watchdog). The NEXT Hermes start in that profile reports
every marker whose owner is gone; one still ``running`` whose pid fails the canonical start-time
liveness check was killed. Reporting runs on a daemon thread so startup never waits on the Relay
runtime; a claimed-but-unreported marker (the reporter died mid-way) is reclaimed later.
)ÚannotationsN)ÚPath)ÚAnyÚprocess_markersz
.reportingÚmemory_errorÚimport_errorÚos_errorÚruntime_errorúdict[str, Any]Ú_STATEc               ó    € V ^8„  d   QhRRRR/# )é   ÚexczBaseException | NoneÚreturnÚstr© )Úformats   "ÚcC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\observability\shared_metrics_process.pyÚ__annotate__r   $   s   € ÷ ]ñ ]Ð)ð ]¨cñ ]ó    c                ó8   a € \        V 3R  l\         4       R4      # )c              3  óT   <"  € T F  w  r\        SV4      '       g   K  Vx € K  	  R # 5i)N)Ú
isinstance)Ú.0ÚkindÚlabelr   s   &  €r   Ú	<genexpr>Úcrash_class.<locals>.<genexpr>%   s   øé € ÐR©.™;˜4¼JÀsÈD×<Q—’«.ùs   ƒ(ž
(Úother)ÚnextÚ_CRASH_CLASSES)r   s   fr   Úcrash_classr!   $   s   ø€ ÜÔR­.ÓRÐT[Ó\Ð\r   c               ó    € V ^8„  d   QhRRRR/# )r   Úhomer   r   r   )r   s   "r   r   r   (   s   € ÷ Bñ B�dð B˜tñ Br   c                ó8   € V R ,          R,          \         ,          # )Ú	telemetryÚshared_metrics)ÚMARKER_DIRNAME)r#   s   &r   Úmarkers_dirr(   (   s   € Ø�+ÕÐ 0Õ0´>ÕAÐAr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úpathr   Úrecordr
   r   ÚNoner   )r   s   "r   r   r   ,   s!   € ÷ ñ ˜ð  nð ¸ñ r   c                ó¾   € V P                  R V P                   R24      pVP                  \        P                  ! V4      RR7       \
        P                  ! W 4       R# )Ú.z.tmpzutf-8©ÚencodingN)Ú	with_nameÚnameÚ
write_textÚjsonÚdumpsÚosÚreplace)r*   r+   Útmps   && r   Ú_write_markerr9   ,   sB   € Ø
�.‰.˜1˜TŸY™Y˜K tÐ,Ó
-€CØ‡N�N”4—:’:˜fÓ%°€NÔ8Ü‡J‚JˆsÖr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú	exit_kindr   Úcrashr   r,   r   )r   s   "r   r   r   2   s&   € ÷ Gñ G˜#ð G cð G°tñ Gr   c                ó’  €  \         ;_uu_ 4        \        P                  R4      p\        P                  R4      pVe   Ve   VP                  R4      R8w  d    RRR4       R# / VCRV RV/CpV\        R&   \        W24       RRR4       R#   + '       g   i     R# ; i  \         d    \
        P                  RRR	7        R# i ; i)
zWRestamp this process's marker with how it is ending. Never raises; no-op when unmarked.r+   r*   NÚstateÚrunningr!   zProcess exit marker not stampedT©Úexc_info)Ú_STATE_LOCKr   Úgetr9   Ú	ExceptionÚloggerÚdebug)r;   r<   r+   r*   s   &&  r   Ú
stamp_exitrG   2   s¥   € ð
GßŽ[Ü—Z‘Z Ó)ˆFÜ—:‘:˜fÓ%ˆDØŠ~ ¢°·±¸GÓ1DÈ	Ô1QØ÷	 ‰[ð
 J˜ÐI ¨°MÀ5ÑIˆFØ%ŒF�8ÑÜ˜$Ô'÷ �[�[Š[ûô ô GÜ�‰Ð6Àˆ×FðGús;   ‚B  �A
BÁB  Á$BÂB  ÂB	ÂB  ÂB  Â "CÃCc               ó    € V ^8„  d   QhRRRR/# )r   Úpreviousr   r   r   )r   s   "r   r   r   A   s   € ÷ ñ ˜#ð  #ñ r   c                ó   a € R  V 3R llpV# )c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   Úexc_typeztype[BaseException]r   ÚBaseExceptionÚtbr   r   r,   r   )r   s   "r   r   Ú!_excepthook.<locals>.__annotate__B   s)   € ÷ $ñ $Ð*ð $°ð $ÀCð $ÈDñ $r   c                ó|   <€ \        V \        \        34      '       g   \        R \	        V4      4       S! WV4       R# )r<   N)Ú
issubclassÚKeyboardInterruptÚ
SystemExitrG   r!   )rL   r   rN   rI   s   &&&€r   ÚhookÚ_excepthook.<locals>.hookB   s/   ø€ Ü˜(Ô%6¼
Ð$C×DÒDÜ�w¤¨CÓ 0Ô1Ù� Ö#r   r   )rI   rT   s   f r   Ú_excepthookrV   A   s   ø€ ÷$ð $ð
 €Kr   c               ó    € V ^8„  d   QhRRRR/# )r   r#   r   r   r,   r   )r   s   "r   r   r   J   s   € ÷ Rñ R ð R¨$ñ Rr   c                ó’   €  ^RI Hp ^RIHp V! V 4       V! V 4       R#   \         d    \
        P                  RRR7        R# i ; i)a  Collection is off: drop the files kept for a later start to count (parked update receipts,
installer receipts). Every opt-out answer calls this too, not only an opted-out start, so a
receipt never survives a "No" to be counted after a later opt-in. Never raises.)Úpurge_pending_installs)Úpurge_pending_updatesz*Pending shared-metrics receipts not purgedTr@   N)Úshared_metrics_install_runrY   Úshared_metrics_updaterZ   rD   rE   rF   )r#   rY   rZ   s   &  r   Úpurge_pending_receiptsr]   J   s@   € ðRÝFÝ@á˜dÔ#Ù˜tÖ$øÜô RÜ�‰ÐAÈDˆ×QðRús   ‚   "AÁAc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r,   r   )r   s   "r   r   r   X   s   € ÷ $Gñ $G˜ð $G ñ $Gr   c                ó´  €  ^ RI Hp ^RIHp ^RIHp ^RIHp \        '       d   R# V \        R&   V! 4       '       g_   V! 4       p\        V4       VR,          R,          V,          p\        V4      V! V4      V3 F  p\        P                  ! VR	R
7       K  	  R# ^ RIHp V! 4       p\        V4      pVP                  R	R	R7       \        P                   ! 4       p	Wp RV	 R2,          p
RV RV	RV! V	4      RR/p\"        ;_uu_ 4        \%        W«4       \        P'                  W«R7       RRR4       \)        \*        P,                  4      \*        n        \.        P0                  ! \2        R4       \4        P6                  ! \8        WZ3RR	R7      P;                  4        R#   + '       g   i     L|; i  \<         d    \>        PA                  RR	R7        R# i ; i)zWMark this process as a running ``kind`` and report dead predecessors. Once per process.©Úget_hermes_home)ÚONBOARDING_LATCH_DIRNAME)r(   )Ú_collection_onNr   r%   r&   T)Úignore_errors)Úget_process_start_time)ÚparentsÚexist_okÚ-ú.jsonÚpidÚ
start_timer>   r?   )r*   r+   Úcleanzhermes-exit-metrics)ÚtargetÚargsr2   ÚdaemonzProcess exit marker not startedr@   )!Úhermes_constantsra   Úshared_metrics_desktoprb   Úshared_metrics_setupr(   r\   rc   r   r]   ÚshutilÚrmtreeÚgateway.statusre   Úmkdirr6   ÚgetpidrB   r9   ÚupdaterV   ÚsysÚ
excepthookÚatexitÚregisterrG   Ú	threadingÚThreadÚ_report_dead_markersÚstartrD   rE   rF   )r   ra   rb   Úsetup_markers_dirrc   r#   ÚlatchesÚ	directoryre   rj   r*   r+   s   &           r   Úbegin_processr„   X   ss  € ð"GÝ4åDÝJÝ9ç‹6ÙØŒˆv‰Ù×ÒÙ"Ó$ˆDÜ" 4Ô(Ø˜[Õ(Ð+;Õ;Ð>VÕVˆGÜ)¨$Ó/Ñ1BÀ4Ó1HÈ'ÓR�	Ü—’˜i°t×<ñ SáÝ9áÓ ˆÜ Ó%ˆ	Ø�‰ ¨tˆÔ4Ü�iŠi‹kˆØ˜V 1 S E¨Ð/Õ/ˆØ˜$  s¨LÑ:PÐQTÓ:UÐW^Ð`iÐjˆßŽ[Ü˜$Ô'Ü�M‰M˜tˆMÔ3÷ ô %¤S§^¡^Ó4ŒŒÜ�Šœ
 GÔ,Ü×ÒÜ'¨t¨lÐAVÐ_cô	
ç
‰%Ž'÷ �[ûô ô GÜ�‰Ð6Àˆ×FðGús<   ‚#F1 ¨F1 ¾AF1 ÂA,F1 Ä"FÄ*A2F1 ÆF.	Æ)F1 Æ1"GÇGc               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r      s   € ÷ )ñ )˜cñ )r   c                 ó@   € \         P                  R 4      ;'       g    R# )r   r   )r   rC   r   r   r   Úcurrent_process_kindr‡      s   € Ü�:‰:�fÓ×(Ð( Ð(r   c               ó    € V ^8„  d   QhRRRR/# )r   r*   r   r   Úboolr   )r   s   "r   r   r   ƒ   s   € ÷ 8ñ 8˜ð 8 $ñ 8r   c                ó¬   € ^ RI Hp  \        V P                  P	                  R^4      R,          4      pT! RT/4      #   \
        \        3 d     R# i ; i)é    ©Úruntime_status_pid_is_liver.   Frj   éþÿÿÿ)ru   r�   Úintr2   ÚrsplitÚ
IndexErrorÚ
ValueError)r*   r�   Úclaimers   &  r   Ú_claimer_aliver”   ƒ   sU   € Ý9ðÜ�d—i‘i×&Ñ& s¨AÓ.¨rÕ2Ó3ˆñ & u¨gÐ&6Ó7Ð7øô œ
Ð#ô Úðús   ˆ,> ¾AÁAc               ó    € V ^8„  d   QhRRRR/# )r   r*   r   r   zPath | Noner   )r   s   "r   r   r   �   s   € ÷ ñ �ð ˜+ñ r   c                ó~  € ^ RI Hp V P                  P                  \        4      '       d   \        V 4      '       d   R# T pMRp \        P                  ! V P                  RR7      4      p\        T\        4      '       g   R# Tf'   TP                  R4      R8X  d   T! T4      '       d   R# T P                  T P                  P                  R4      ^ ,           R\         P"                  ! 4        \         24      p \         P$                  ! Y4       T#   \        \        3 d     R# i ; i  \         d     R# i ; i)	zURename a reportable marker so exactly one reporter owns it; None when not reportable.rŒ   Nú	utf-8-sigr/   r>   r?   ri   z.json.)ru   r�   r2   ÚendswithÚ
_REPORTINGr”   r4   ÚloadsÚ	read_textÚOSErrorr’   r   ÚdictrC   r1   Úsplitr6   rw   r7   )r*   r�   Úrecord_pathr+   Úclaimeds   &    r   Ú_claimr¡   �   s  € å9à‡y�y×Ñœ*×%Ò%Ü˜$×ÒÙØ‰àˆðÜ—’˜DŸN™N°K˜NÓ@ÓAˆô �fœd×#Ò#ÙØÒ˜vŸz™z¨'Ó2°iÔ?ÑD^Ð_e×DfÒDfÙØ�n‰n §	¡	§¡°Ó 8¸Õ ;Ð<¸FÄ2Ç9Â9Ã;À-ÔPZÈ|Ð\Ó]€GðÜ
�
Š
�4Ô!ð €Nøô ”ZÐ ô Úðûô ô Úðús$   Á&D Ã=D- ÄD*Ä)D*Ä-D<Ä;D<c               ó    € V ^8„  d   QhRRRR/# )r   r+   r
   r   zdict[str, str]r   )r   s   "r   r   r   §   s   € ÷ ñ  ð °>ñ r   c                óâ   € ^RI HpHpHp V P	                  R4      pVR8X  g   WB9  d   RMTpVR8X  d   V P	                  R4      MRpV P	                  R4      pRWa9   d   TMR	R
TRWs9   d   V/# R	/# )é   )ÚCRASH_CLASSESÚPROCESS_EXIT_KINDSÚPROCESS_KINDSr>   r?   Úkilledr<   r!   Únoner   r   r;   Úprocess_kind)Úshared_metrics_contractr¥   r¦   r§   rC   )r+   r¥   r¦   r§   r>   r;   r<   r   s   &       r   Úprocess_exit_fieldsr¬   §   s„   € ßYÑYà�J‰J�wÓ€EØ! YÔ.°%Ô2Q‘ÐW\€IØ)2°gÔ)=ˆF�J‰J�}Ô%À6€EØ�:‰:�fÓ€Dà Ô 6‘u¸GØ�YØ Ô 5˜ðð ð <Cðð r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r    r   ÚoriginalÚsavedr‰   r   r,   r   )r   s   "r   r   r   µ   s.   € ÷ Oñ O˜$ð O¨$ð O°tð OÀñ Or   c                ó¾   €  V'       d   V P                  RR7       R# \        P                  ! W4       R#   \         d    \        P                  RRR7        R# i ; i)zWDelete a claimed file once its row is saved; otherwise hand it back for the next start.T)Ú
missing_okz'Claimed shared-metrics file not settledr@   N)Úunlinkr6   r7   rœ   rE   rF   )r    r®   r¯   s   &&&r   Úsettle_claimr³   µ   sG   € ðOßØ�N‰N dˆNÖ+ä�JŠJ�wÖ)øÜô OÜ�‰Ð>Èˆ×NðOús   ‚6 Š6 ž6 ¶"AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r   r#   r   Úownr   r,   r   )r   s   "r   r   r   À   s!   € ÷ !*ñ !*˜tð !*¨$ð !*°4ñ !*r   c           	     ó  € ^ RI HpHp ^RIHp ^RIHp V! V 4      p \        \        V 4      P                  4       4       FÃ  pWq8X  g3   VP                  P                  R4      '       g   RVP                  9  d   K=  \        V4      pVf   KN   \        P                  ! VP                  RR7      4      p	\%        V	\&        4      '       d   VP(                  \+        V	4      3.M. p
\-        W‡V! V
4      \/        V
4      8H  4       KÅ  	  ^R	IHp ^R
IHp V! 4        V! V 4       ^RIHp V! V 4       V! V4       R#   \         \"        3 d    Rp	 Lši ; i  \<         d    \>        PA                  RRR7        LGi ; i  T! T4       i ; i)r‹   ©Úreset_hermes_home_overrideÚset_hermes_home_override©r«   )Ú
emit_savedr.   ri   Nr—   r/   )Úreport_abandoned_setups)Úreport_pending_updates)Úreport_pending_installsz!Dead process markers not reportedTr@   )!rp   r¸   r¹   Ú r«   Úshared_metrics_eventsr»   Úsortedr(   Úiterdirr2   Ú
startswithr¡   r4   rš   r›   rœ   r’   r   r�   ÚPROCESS_EXIT_MARKr¬   r³   Úlenrr   r¼   r\   r½   r[   r¾   rD   rE   rF   )r#   rµ   r¸   r¹   Úcontractr»   Útokenr*   r    r+   Úrowsr¼   r½   r¾   s   &&            r   r   r   À   sK  € ßUå5Ý1á$ TÓ*€Eð*Üœ; tÓ,×4Ñ4Ó6Ö7ˆDØŒ{˜dŸi™i×2Ñ2°3×7Ò7¸7È$Ï)É)Ô;SÙÜ˜T“lˆGØŠÙðÜŸš G×$5Ñ$5¸{Ð$5Ó$KÓL�ô S]Ð]cÔei×RjÒRj�X×/Ñ/Ô1DÀVÓ1LÐMÑNÐprˆDÜ˜©
°4Ó(8¼CÀ»IÑ(EÖFñ 8õ 	BÝAáÔ Ù Ô%åGá Ô%ñ
 	# 5Ö)øô# œZÐ(ô Ø’ðûô ô IÜ�‰Ð8À4ˆÖHðIûñ 	# 5Õ)úsO   žAE Á*$E Â&D:Â5A;E Ä:EÅE ÅEÅE Å"E8Å5E; Å7E8Å8E; Å;
Fc               ó    € V ^8„  d   QhRRRR/# ©r   Úagentr   r   r,   r   )r   s   "r   r   r   ä   s   € ÷ 	Cñ 	C�Cð 	C˜Dñ 	Cr   c                óž   €  ^ RI Hp \        V! 4       4      V n        RV n        R#   \
         d    \        P                  RRR7        R# i ; i)z•At turn entry (profile scope bound): the owning home for an off-thread watchdog abort, and
a fresh once-per-turn latch shared by both turn watchdogs.r`   FzTurn exit metrics not armedTr@   N)rp   ra   r   Ú_metrics_turn_homeÚ_metrics_watchdog_abort_countedrD   rE   rF   )rË   ra   s   & r   Úarm_turnrÏ   ä   sE   € ðCÝ4ä#&¡Ó'8Ó#9ˆÔ Ø05ˆÖ-øÜô CÜ�‰Ð2¸Tˆ×BðCús   ‚"& ¦"AÁAc               ó    € V ^8„  d   QhRRRR/# rÊ   r   )r   s   "r   r   r   ð   s   € ÷ Hñ H cð H¨dñ Hr   c                óH  €  \        V RR4      pV'       d   \        V RR4      '       d   R# RV n        ^ RIHpHp ^RIHp ^RIHp V! V4      p V! VP                  R 4       V! V4       R#   T! T4       i ; i  \         d    \        P                  R	RR
7        R# i ; i)z_One exit_kind=watchdog row per turn a watchdog killed, in the turn's own profile. Never raises.rÍ   NrÎ   Tr·   rº   )Ú_emitc                 ó"   € R RRRR\        4       /# )r!   r©   r;   Úwatchdogrª   )r‡   r   r   r   Ú<lambda>Ú,record_watchdog_turn_abort.<locals>.<lambda>ÿ   s   € Ø˜v {°JÀÔPdÓPfñ7r   z Watchdog turn abort not recordedr@   )ÚgetattrrÎ   rp   r¸   r¹   r¿   r«   rÀ   rÒ   rÄ   rD   rE   rF   )rË   r#   r¸   r¹   rÆ   rÒ   rÇ   s   &      r   Úrecord_watchdog_turn_abortrØ   ð   s–   € ðHÜ�uÐ2°DÓ9ˆç”w˜uÐ&GÈ×NÒNÙØ04ˆÔ-ßYå9Ý0á(¨Ó.ˆð	.Ù�(×,Ñ,ñ /ô ñ ' uÖ-øÑ& uÕ-ûÜô HÜ�‰Ð7À$ˆ×GðHús.   ‚(A; ¬#A; ÁA. Á$A; Á.
A8Á8A; Á;"B!Â B!)r©   ),Ú__conditional_annotations__Ú__doc__Ú
__future__r   r{   r4   Úloggingr6   rs   ry   r}   Úpathlibr   Útypingr   Ú	getLoggerÚ__name__rE   r'   r™   ÚMemoryErrorÚImportErrorrœ   ÚRuntimeErrorr    r   Ú__annotations__ÚLockrB   r!   r(   r9   rG   rV   r]   r„   r‡   r”   r¡   r¬   r³   r   rÏ   rØ   )rÙ   s   @r   Ú<module>ræ      sÙ   øðôõ #ã Û Û Û 	Û Û 
Û Ý Ý à	×	Ò	˜8Ó	$€à"€Ø€
ð �.Ð! K°Ð#@À7ÈJÐBWØ�?Ð#ð€ð €ˆÓ Ø�nŠnÓ€õ]õBõ÷GõõRõ$GõN)õ8õõ4õOõ!*õH	C÷Hr   