+
    jHàj^#  ã                  ób  € 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	H	t	H
t
Ht ^ RIHt ^ RIHt ]P                   ! ]4      tRtRt^@t]P,                  ! R4      t]! 0 Rm4      tR 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# )!aY  hermes.install.run: fresh installs through scripts/install.sh and scripts/install.ps1.

The installer runs before the user is asked about shared metrics and must never send anything, so a
full-ladder run only leaves ONE small local receipt (closed tokens plus two epoch timestamps) under
the profile's store dir. A later Hermes start that runs the process-exit reporter reads it:

- collection off: ``shared_metrics_process.begin_process`` (and every opt-out answer) deletes every
  receipt unreported, the same rule as parked update receipts;
- collection on, sending off: the row is recorded now (it stays on this machine);
- collection on, sending on: the row is recorded only on a day whose package the sender's consent
  gate can ever pass, i.e. a send consent window opened at or before today 00:00Z. On the opt-in day
  itself (setup asked during the install) the receipt waits for the first start on a later day;
- a receipt older than ``MAX_RECEIPT_AGE_SECONDS``, unparseable, or with any value outside the
  contract is deleted unreported (an old receipt would count under whatever version records it).
)ÚannotationsN)ÚdatetimeÚtimezoneÚUTC)ÚPath)ÚAnyÚpending_installsÚrecorded_installsz[0-9a-f]{32}c               ó    € V ^8„  d   QhRRRR/# )é   Úhomer   Úreturn© )Úformats   "ÚX/home/ubuntu/.hermes/hermes-agent/hermes_cli/observability/shared_metrics_install_run.pyÚ__annotate__r   +   s   € ÷ Cñ C˜tð C¨ñ Có    c                ó8   € V R ,          R,          \         ,          # ©Ú	telemetryÚshared_metrics)ÚPENDING_DIRNAME©r   s   &r   Úpending_installs_dirr   +   s   € Ø�+ÕÐ 0Õ0´?ÕBÐBr   c               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r   ÚNoner   )r   s   "r   r   r   /   s   € ÷ Bñ B ð B¨$ñ Br   c                óH   € \         P                  ! \        V 4      R R7       R# )T)Úignore_errorsN)ÚshutilÚrmtreer   r   s   &r   Úpurge_pending_installsr!   /   s   € Ü
‡M‚MÔ& tÓ,¸D×Ar   c               ó    € V ^8„  d   QhRRRR/# )r   Úvaluer   r   z
int | Noner   )r   s   "r   r   r   3   s   € ÷ cñ c�#ð c˜*ñ cr   c                óp   € \        V \        4      '       d    \        V \        4      '       g
   V ^ 8”  d   V # R# )é    N)Ú
isinstanceÚintÚbool)r#   s   &r   Ú_epochr)   3   s-   € Ü˜u¤c×*Ò*´:¸eÄT×3JÒ3JÈuÐWXÌyˆ5ÐbÐ^bÐbr   c               ó    € V ^8„  d   QhRRRR/# )r   Úreceiptr   r   zdict[str, str] | Noner   )r   s   "r   r   r   7   s   € ÷ ñ  ð Ð(=ñ r   c                ó~  € ^RI Hp \        V \        4      '       d   \	        V 4      \
        8w  d   R# \        V R,          \        4      '       d#   \        P                  V R,          4      '       g   R# \        V R,          4      \        V R,          4      r2Ve   Ve   W28  d   R# RVP                  W2,
          R,          4      RV R,          R	V R	,          R
V R
,          RV R,          /pVP                  VP                  V4      '       g   R# VR,          R8H  pWTR,          R8H  8w  g   WTR	,          R8H  8w  d   R# V# )zWhermes.install.run dims for one receipt, or None when anything is outside the contract.©Úshared_metrics_contractNÚidÚ
started_atÚfinished_atÚduration_bucketiè  Úfailed_stageÚfailure_classÚ	installerÚoutcomeÚsuccessÚnone)Ú r.   r&   ÚdictÚsetÚ_RECEIPT_KEYSÚstrÚ_RECEIPT_IDÚ	fullmatchr)   Úupdate_duration_bucketÚcounter_dimensions_are_validÚINSTALL_RUN_METRIC)r+   ÚcontractÚstartedÚfinishedÚfieldsÚ	succeededs   &     r   Úinstall_run_fieldsrH   7   s  € å5ä�gœt×$Ò$¬¨G«¼Ô(EÙÜ�g˜d•m¤S×)Ò)´×1FÑ1FÀwÈtÅ}×1UÒ1UÙÜ˜w |Õ4Ó5´v¸gÀmÕ>TÓ7UˆXØ‚˜(Ò*¨hÔ.@Ùà˜8×:Ñ:¸HÕ<NÐRVÕ;VÓWØ˜ Õ/Ø˜ Õ1Ø�W˜[Õ)Ø�7˜9Õ%ð€Fð ×0Ñ0°×1LÑ1LÈf×UÒUÙà�yÕ! YÑ.€IØ˜NÕ+¨vÑ5Ô6¸)ÈÕH_ÐciÑHiÔ:jÙØ€Mr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Ú
receipt_idr=   r   r   )r   s   "r   r   r   R   s&   € ÷ Qñ Q˜$ð Q¨Cð Q°Dñ Qr   c                óF   € V R ,          R,          \         ,          V,          # r   )ÚRECORDED_DIRNAME)r   rJ   s   &&r   Ú_recorded_latchrM   R   s   € Ø�+ÕÐ 0Õ0Ô3CÕCÀjÕPÐPr   c               ó    € V ^8„  d   QhRRRR/# )r   Úlatchr   r   r   r   )r   s   "r   r   r   V   s   € ÷ 	ñ 	˜$ð 	 4ñ 	r   c                ó  €  V P                   P                  RRR7       V P                  4        \        V P                   P	                  4       R RR7      \
        R  F  pVP                  RR7       K  	  R#   \         d     R# i ; i)z·Latch a receipt id AFTER its row is saved: a process that dies between the latch and the save
(a short-lived start whose reporter thread is cut off at exit) must not drop the install.T)ÚparentsÚexist_okc                ó6   € V P                  4       P                  # )N)ÚstatÚst_mtime)Úps   &r   Ú<lambda>Ú _mark_recorded.<locals>.<lambda>\   s   € À!Ç&Á&Ã(×BSÒBSr   )ÚkeyÚreverseN)Ú
missing_ok)ÚparentÚmkdirÚtouchÚsortedÚiterdirÚ_RECORDED_KEEPÚunlinkÚOSError)rO   Ústales   & r   Ú_mark_recordedre   V   ss   € ðØ�‰×Ñ 4°$ÐÔ7Ø�‰ŒÜ˜EŸL™L×0Ñ0Ó2Ñ8SÐ]aÔbÔcqÐcrÓsˆEØ�L‰L DˆLÖ)ó tøäô Úðús   ‚A4A8 Á8BÂBc               ó   € V ^8„  d   QhRR/# )r   r   r=   r   )r   s   "r   r   r   b   s   € ÷ \ñ \�cñ \r   c                 ó¶   € ^RI Hp Hp V ! \        P                  ! V! 4       P                  4       \        P                  P                  4       \        R7      4      # )z^Today's package ``period_start``, in the store's stamp format (``shared_metrics._isoformat``).©Ú
_isoformatÚ_utc_now)Útzinfo)	r   ri   rj   r   ÚcombineÚdateÚminÚtimer   rh   s     r   Ú_today_startrp   b   s6   € ç4á”h×&Ò&¡x£z§¡Ó'8¼(¿,¹,×:KÑ:KÓ:MÔVYÔZÓ[Ð[r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r(   r   )r   s   "r   r   r   i   s   € ÷ ñ ˜ð  ñ r   c                óð  € ^ RI Hp ^RIHp T! V! 4       ;'       g    / 4      pVP                  '       g   R# VP
                  '       g   R# ^RIHp V R,          R,          p V! VR,          VR	,          4      P                  4       ;_uu_ 4       pVP                  R
\        4       34      P                  4       pRRR4       VRJ#   + '       g   i     XRJ# ; i  \        P                   d     R# i ; i)ak  Whether a row recorded now lands in a package the user agreed to: collection on, and either
sending off (it stays local) or a send consent window opened at or before today 00:00Z. The
sender's ``CONSENT_GATE_SQL`` passes a day's package only when ``period_start >= opened_at``, so a
row recorded on the opt-in day itself would sit in a package that is never sent.)Úread_raw_config_readonly)Úresolve_send_configFT)ÚSharedMetricsStorer   r   zmetrics.sqlite3ÚoutboxzUSELECT 1 FROM send_consent_windows WHERE closed_at IS NULL AND opened_at <= ? LIMIT 1N)Úhermes_cli.configrs   Úshared_metrics_send_configrt   ÚenabledÚsendr   ru   Ú_connectionÚexecuterp   ÚfetchoneÚsqlite3ÚError)r   rs   rt   rz   ru   ÚrootÚ
connectionÚrows   &       r   Úconsented_dayrƒ   i   sÙ   € õ
 ;å?áÑ7Ó9×?Ð?¸RÓ@€DØ�<�<ˆ<ÙØ�9�9ˆ9ÙÝ2à�+ÕÐ 0Õ0€DðÙ Ð'8Õ 8¸$À½/ÓJ×VÑV×XÔXÐ\fØ×$Ñ$ØgÜ“Ð!ó÷ ‰h‹jð ÷ Yð �dˆ?Ð÷ YÖXð �dˆ?Ðûô �=‰=ô Úðús0   Á#-C Â*CÂ:C ÃC	ÃC ÃC ÃC5Ã4C5c               ó    € V ^8„  d   QhRRRR/# )r   Úpathr   r   zPath | Noner   )r   s   "r   r   r   …   s   € ÷ ñ ˜ð  +ñ r   c                ó`  € ^RI HpHp V P                  P	                  V4      '       d   V! V 4      '       d   R# V P                  V P                  P                  R4      ^ ,           R\        P                  ! 4        V 24      p \        P                  ! W4       V#   \         d     R# i ; i)z­Rename a receipt so exactly one reporter owns it. Unlike the process-marker claim it never
reads the file first: an unparseable receipt is claimed too, so it can be deleted.)Ú
_REPORTINGÚ_claimer_aliveNú.jsonz.json.)Úshared_metrics_processr‡   rˆ   ÚnameÚendswithÚ	with_nameÚsplitÚosÚgetpidÚreplacerc   )r…   r‡   rˆ   Úclaimeds   &   r   Ú_claim_receiptr“   …   s�   € ÷ Cà‡y�y×Ñ˜*×%Ò%©.¸×*>Ò*>ÙØ�n‰n §	¡	§¡°Ó 8¸Õ ;Ð<¸FÄ2Ç9Â9Ã;À-ÐPZÈ|Ð\Ó]€GðÜ
�
Š
�4Ô!ð €Nøô ô Úðús   ÂB ÂB-Â,B-c               ó    € V ^8„  d   QhRRRR/# )r   r+   r:   r   r(   r   )r   s   "r   r   r   ”   s   € ÷ Uñ U�Dð U˜Tñ Ur   c                ób   € ^RI Hp V! 4       P                  4       V R,          ,
          \        8„  # )é   )rj   r1   )r   rj   Ú	timestampÚMAX_RECEIPT_AGE_SECONDS)r+   rj   s   & r   Ú_staler™   ”   s(   € õ )á‹:×ÑÓ! G¨MÕ$:Õ:Ô=TÑTÐTr   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r   œ   s   € ÷ ,Mñ ,M $ð ,M¨4ñ ,Mr   c                óÚ  €  ^ RI Hp ^RIHp ^RIHp ^RIHp \        V 4      pVP                  4       '       g   R# VP                  4       '       g   R# \        V 4      p\        VP                  4       4       EF+  pVP                  P                  R4      '       g   RVP                  9  d   K8  \!        V4      pVf   KI   \"        P$                  ! VP'                  RR	7      4      p	\-        V	4      p
V
e(   \/        V	\0        4      '       d   \3        V	4      '       d   V! W‡R
4       K±  \5        W	R,          4      pVP7                  4       '       d   V! W‡R
4       Kä  V'       g   V! W‡R4       K÷  V! VP8                  V
3.4      ^8H  pV'       d   \;        V4       V! W‡V4       EK.  	  R#   \(        \*        3 d    Rp	 L×i ; i  \<         d    \>        PA                  RR
R7        R# i ; i)zVRecord each receipt once, on a consented day (see the module docstring). Never raises.)Úrelay_runtimer-   )Ú
emit_saved)Úsettle_claimNÚ.r‰   z	utf-8-sig)ÚencodingTr/   Fz%Pending install receipts not reported)Úexc_info)!Úagentrœ   r9   r.   Úshared_metrics_eventsr�   rŠ   rž   r   Úis_dirÚrelay_instrumentation_enabledrƒ   r_   r`   r‹   Ú
startswithr“   ÚjsonÚloadsÚ	read_textrc   Ú
ValueErrorrH   r&   r:   r™   rM   ÚexistsÚINSTALL_RUN_MARKre   Ú	ExceptionÚloggerÚdebug)r   rœ   rC   r�   rž   Ú	directoryÚ
reportabler…   r’   r+   rF   rO   Úsaveds   &            r   Úreport_pending_installsr³   œ   s”  € ð*MÝ'å9Ý5Ý8ä(¨Ó.ˆ	Ø×Ñ×!Ò!Ùð ×:Ñ:×<Ò<ÙÜ" 4Ó(ˆ
Ü˜9×,Ñ,Ó.×/ˆDØ�y‰y×#Ñ# C×(Ò(¨G¸4¿9¹9Ô,DÙÜ$ TÓ*ˆGØŠÙðÜŸ*š* W×%6Ñ%6ÀÐ%6Ó%LÓM�ô (¨Ó0ˆFØŠ~¤Z°¼×%>Ò%>Ä&ÈÇ/Â/Ù˜W¨DÔ1ÙÜ# D°$­-Ó8ˆEØ�|‰|�~Š~Ù˜W¨DÔ1ÙßÙ˜W¨EÔ2Ùá ×!:Ñ!:¸FÐ CÐDÓEÈÑJˆEßÜ˜uÔ%Ù˜¨×.ó3 0øô œZÐ(ô Ø’ðûô$ ô MÜ�‰Ð<Àtˆ×LðMúsN   ‚9G ½G ÁA-G Ã&F+Ã)A;G Å%*G ÆG Æ+GÆ>G Ç GÇG Ç"G*Ç)G*>   r/   r6   r5   r0   r1   r3   r4   i€:	 )&Ú__doc__Ú
__future__r   r§   Úloggingr�   Úrer   r~   r   r   r   Úpathlibr   Útypingr   Ú	getLoggerÚ__name__r®   r   rL   ra   Úcompiler>   Ú	frozensetr<   r˜   r   r!   r)   rH   rM   re   rp   rƒ   r“   r™   r³   r   r   r   Ú<module>r¾      s®   ðñõ  #ã Û Û 	Û 	Û Û ß ,Ñ ,Ý Ý à	×	Ò	˜8Ó	$€à$€ð 'Ð Ø€Ø�jŠj˜Ó)€ÙÒvÓw€ð %Ð õCõBõcõõ6Qõ	õ\õõ8õU÷,Mr   