+
    jHàjÒt  ã                  óÀ  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHtHtHtHtHtHtHtHtHtHtHt ^ RIHt ^ RIHt ]P<                  ! R	4      tRs R
]!R&   / t"R]!R&   Rs#R]!R&   Rs$R]!R&   Rs%R]!R&   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/R( R) llt/R* R+ lt0R, R- lt1R. R/ lt2R0 R1 lt3R2 R3 lt4R4 R5 lt5R6 R7 lt6R8 R9 lt7R: R; lt8R< R= lt9R>t:R?t;R@RRA^</RB RC llt<RD RE lt=RF RG lt>RH RI lt?RJ RK lt@RL RM ltARN RO ltBRP RQ ltCRR RS ltDRT RU ltERV RW ltFRX RY ltGRZ R[ ltHR# )\aÀ  The single commit point of a source ``hermes update``: everything the tree move needs armed first.

Before git (or the ZIP swap) writes the first file of the new code, three things are durable:

* the interrupted-pull marker (``.git/hermes-update-pull``) naming the commit git moves to, for EVERY
  tree move (branch switch, upstream fork pull, the pull itself) so a launch after any exit that left
  a torn tree puts the old one back (``_early_recovery.restore_interrupted_pull``);
* the source-completion tail (``venv_sync.arm_completion``) and the host fleet-restart obligation,
  so a kill after the move but before the completion child starts still leaves the tail owed to the
  next launch (``venv_sync.prepare_launch``) and the restart owed to the next ``hermes update``.

Failures before the move are no-ops: ``disarm_commit_obligations`` puts both obligations back the way
this run found them once the tree is verified at its pre-update commit again.
)ÚannotationsN)Úsuppress)ÚPath)ÚOptional)ÚRECOVERY_CLOSUREÚRECOVERY_CLOSURE_INITÚRECOVERY_CLOSURE_MANIFESTÚblob_idÚ_lock_identityÚinterrupted_pull_markerÚis_object_idÚrecovery_closure_dirÚrecovery_closure_verifiedÚrestore_interrupted_pullÚwrite_durable_text)Ú_record_stop)Úrun_gitzhermes_cli.update_cmdz%Optional[dict[Path, Optional[bytes]]]Ú_armed_snapshotzdict[Path, Optional[bytes]]Ú_armed_bytesz&Optional[tuple[list, tuple[str, str]]]Ú
_run_startzOptional[Path]Ú_obligation_rootÚ ÚstrÚ_ownerc               ó    € V ^8„  d   QhRRRR/# ©é   Úrootr   ÚreturnÚbool© )Úformats   "ÚA/home/ubuntu/.hermes/hermes-agent/hermes_cli/update_cmd_commit.pyÚ__annotate__r#   6   s   € ÷ 1ñ 1˜dð 1 tñ 1ó    c                ó:   € ^ RI Hp V! 4       P                  V 4      # )é    )Ú_m)Úhermes_cli.update_cmdr'   Ú_pytest_owns_live_checkout)r   r'   s   & r"   Ú_owns_live_checkoutr*   6   s   € Ý(á‹4×*Ñ*¨4Ó0Ð0r$   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   z
list[Path]r    )r!   s   "r"   r#   r#   <   s   € ÷ iñ i˜Dð i Zñ ir$   c                óP   € ^ RI Hp ^ RIHp ^ RIHp V! V 4      V! 4       V! 4       .# )r&   )Ú"_fleet_restart_pending_marker_path)Úhost_obligation_path)Úcompletion_pending_path)Úhermes_cli.update_cmd_fleetr-   Ú!hermes_cli.update_host_obligationr.   Úhermes_cli.venv_syncr/   )r   r-   r.   r/   s   &   r"   Ú_obligation_pathsr3   <   s%   € ÝNÝFÝ<á# DÓ)Ñ+MÓ+OÑQeÓQgÐhÐhr$   c               ó    € V ^8„  d   QhRRRR/# )r   Úpathr   r   zOptional[bytes]r    )r!   s   "r"   r#   r#   D   s   € ÷ ñ ˜ð  ñ r$   c                óH   €  V P                  4       #   \         d     R# i ; i)z\The record's bytes, None when absent. Any other read error raises: custody is never guessed.N)Ú
read_bytesÚFileNotFoundError)r5   s   &r"   Ú_read_or_noner9   D   s&   € ðØ�‰Ó Ð øÜô Úðús   ‚ ’! !c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úexpected_shar   r   ÚNoner    )r!   s   "r"   r#   r#   L   s&   € ÷ Qñ Q ð Q°Sð Q¸Tñ Qr$   c                ó~  € ^ RI p^ RIHp ^ RIHp \        V 4      p \        V 4      '       d   R# \        fZ   \        V 4       Uu/ uF  qU\        V4      bK  	  upsV  R\        P                  ! 4        RVP                  4       P                   2s V! V 4       T! T;'       g    R\        R7      p\        P!                  \         Uu/ uF  qU\        V4      bK  	  up4       V'       g   \#        R4      hR# u upi u upi   \        P!                  \         Uu/ uF  qU\        T4      bK  	  Mu upi up4       i ; i)aŒ  Owe the completion tail and the fleet restart for ``expected_sha`` BEFORE the tree moves.

Idempotent within a run (the first call snapshots what to restore on a no-op failure). An
unwritable install state, an unreadable record or a fleet restart neither store accepted
raises: nothing has moved yet, and moving without the obligation is exactly the
tail-never-runs state this exists to prevent.
N)Ú#_write_fleet_restart_pending_marker)Úarm_completionÚ|r   )r;   Úownerz7could not record the pending gateway-restart obligation)Úuuidr0   r>   r2   r?   r   r*   r   r3   r9   ÚosÚgetpidÚuuid4Úhexr   r   ÚupdateÚOSError)r   r;   rB   r>   r?   r5   Úoweds   &&     r"   Úarm_commit_obligationsrJ   L   s  € ó åOÝ3ä�‹:€DÜ˜4× Ò ÙÜÒÜARÐSWÔAXÓYÑAX¸¤¨tÓ!4Ò4ÑAXÑYˆØ�6˜œ2Ÿ9š9›;˜- q¨¯©«×)9Ñ)9Ð(:Ð;ˆðUÙ�tÔÙ2À×@RÐ@RÐPRÔZ`Ôaˆä×ÑÅ?ÓSÁ?¸4¤=°Ó#6Ò6Á?ÑSÔTßÜÐOÓPÐPñ ùò Zùò TøŒ×ÑÅ?ÓSÁ?¸4¤=°Ó#6Ò6Â?ùÔSÕTús*   ÁC8ÂD Â$D ÃC=ÄD<ÄD/Ä.D<c               ó   € V ^8„  d   QhRR/# ©r   r   r<   r    )r!   s   "r"   r#   r#   i   s   € ÷ 'ñ ' 4ñ 'r$   c                 ó^  € \         e`   \         w  p w  r\        e   \        \        4      MRpVe   \        W4      ^ ,          MRpVe   V'       d   WA8w  d   Ve   \	        W44       R# ^ RIHpHpHp \        Rups	\        \        4      p	\        P                  4        V! 4       p
T;'       g    / P                  4        FX  w  r¼ Wº8X  d   V! \        4       K  W¹9  g   \        V4      W›,          8w  d   K8  Vf   VP!                  RR7       KP  V! W¼4       KZ  	  R#   \"         d     Kl  i ; i)aÏ  Restore both obligations to what this run found: the tree never left its pre-update commit.

Off the commit this run STARTED from nothing is handed back: a failed later move (CP1 refused
or failed after the CP0 branch switch, the upstream fork ff after the origin pull) settles on a
commit that is already new code, so the obligations are owed for THAT head instead of the
failed move's target, which the checkout does not contain and no restart could discharge.
Nr   )r.   Úrelease_host_obligationÚreplace_bytesT©Ú
missing_ok)r   r   r   Úhead_and_branchÚ_owe_forr1   r.   rN   rO   r   Údictr   ÚclearÚitemsr   r9   ÚunlinkrH   )Úgit_cmdÚ
start_headÚ_branchr   Úheadr.   rN   rO   ÚsnapshotÚarmedÚhostr5   Údatas                r"   Údisarm_commit_obligationsr`   i   s  € ô ÒÜ)3Ñ&ˆÑ&�*Ü)9Ò)EŒtÔ$Ô%È4ˆØ48Ò4DŒ˜wÓ-¨aÖ0È"ˆØŠ<Ÿz¨TÔ-?ØÒÜ˜Ô$ÙßnÑnä /°Ð€HˆoÜ”Ó€EÜ×ÑÔÙÓ!€DØ—~�~ 2×,Ñ,Ö.‰
ˆð	ØŒ|ñ (¬Ô/ÙØÔ ¤M°$Ó$7¸5½;Ô$FÙØŠ|Ø—‘ t�Ö,ñ ˜dÖ)ó /øô ô 	Úð	ús$   ÃDÃDÃ7DÄDÄD,Ä+D,c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úpreú
str | Noner   r<   r    )r!   s   "r"   r#   r#   “   s!   € ÷ $ñ $˜ð $ Jð $°4ñ $r$   c                óD   € \        \        V 4      T;'       g    R4       R# )z«A failed move left a torn tree under its marker: the next launch's restore puts ``pre`` back,
so the obligations name ``pre``, never the target the checkout will not hold.r   N)rS   r   )r   rb   s   &&r"   Úowe_restore_ofre   “   s   € ô ŒT�$‹Z˜Ÿ˜ Ö#r$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úshar   r   r<   r    )r!   s   "r"   r#   r#   ™   s&   € ÷ 	Xñ 	X�4ð 	X˜cð 	X dñ 	Xr$   c                ó  € \         e   \        V4      '       g   R#  \        W4       R#   \         dS   p\        P                  RTR,          T4       \        RTR,           RT R2\        P                  R7        Rp?R# Rp?ii ; i)zWRe-arm what this run armed for ``sha``, the commit the checkout is (or is restored) on.Nz2Could not re-arm the update obligations for %s: %sºNé
   Nu>     âš  Could not record the restart this update still owes for z (z8); run `hermes gateway restart` once the update is done.)Úfile)	r   r   rJ   rH   ÚloggerÚwarningÚprintÚsysÚstderr)r   rg   Úexcs   && r"   rS   rS   ™   s„   € äÒ¤l°3×&7Ò&7ÙðXÜ˜tÖ)øÜô XÜ�‰ÐKÈSÐQTÍXÐWZÔ[ÜÐNÈsÐSVÍxÈjÐXZÐ[^ÐZ_ð `Fð FÜLOÏJÉJ÷	Xó 	XûðXús   �* ªBµABÂBc               ó$   € V ^8„  d   QhRRRRRR/# )r   rb   r   Útargetr   r    )r!   s   "r"   r#   r#   ¥   s!   € ÷ 5ñ 5˜3ð 5¨ð 5°ñ 5r$   c                ób   € \         e   \         ^,          ^ ,          MRpV'       d	   W8w  d   V # T# )ac  The commit a fast-forward ``pre`` -> ``target`` arms the obligations for.

A later move of this run (the upstream sync after the origin pull) owes ``pre``: the commit the
earlier move already owes, which every landing of a fast-forward contains, and the fleet
discharge holds the gateways to the checkout's actual HEAD whenever it contains the debt. Its
failure then needs no retarget write, which could itself fail and leave the debt naming a commit
the checkout never reached (review O4). The run's first move owes its ``target``: its failure
hands the obligations back whole (``disarm_commit_obligations``).
r   )r   )rb   rs   Ústarts   && r"   Údebt_sha_for_moverv   ¥   s*   € ô !+Ò 6ŒJ�q�M˜!Ö¸B€Eß˜CœLˆ3Ð4¨fÐ4r$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r;   r   r   rc   r    )r!   s   "r"   r#   r#   ³   s!   € ÷ ñ  Dð ¸ð È
ñ r$   c                óV  € ^ RI Hp V! 4       ;p'       d   V#  \        W4       \        W3/ VB  R#   \         dl   p\        4        \        e   \        Y4      ^ ,          MRpT'       d.   T\        ^,          ^ ,          8w  d   RT RTR,           2u Rp?# RT R2u Rp?# Rp?ii ; i)a[  Arm the obligations, then the tree-move marker (``arm_tree_move(**move)``): no marker, no move.

``None`` when both are durable; otherwise why not, with the obligations handed back
(``disarm_commit_obligations``), and the caller must stop before git writes a file.
Linux/macOS gateways are paused first: this is every route's first checkout move.
)Úpause_at_commit_pointNr   zcould not arm the update (z_); this step changed nothing, but an earlier step of this update already moved the checkout to ri   z); the checkout was not changed)Ú!hermes_cli.update_cmd_posix_pausery   rJ   Úarm_tree_moverH   r`   r   rR   )rX   r   r;   Úmovery   Úrefusedrq   r[   s   &&&,    r"   Úarm_commit_pointr~   ³   s±   € õ HÙ'Ó)Ð)€wÖ)Øˆð
QÜ˜tÔ2Ü�gÑ, tÒ,ñ øô ô QÜ!Ô#Ü4>Ò4JŒ˜wÓ-¨aÖ0ÐPRˆß�DœJ q�M¨!Õ,Ô,à0°°ð 6DØDHÈÅIÀ;ðPõ Qà+¨C¨5Ð0OÐPÕPûðQús,   ™2 ²B(½-B#Á+'B#ÂB(ÂB#ÂB(Â#B(Úrollbackc               ó0   € V ^8„  d   QhRRRRRRRRRRR	R/# )
r   r   r   rb   rc   rs   r   Ústashr   r   r    )r!   s   "r"   r#   r#   Ë   s8   € ÷ ñ  ð ¨zð À3ð Èzð Ø&ðØ26ñr$   c               óÊ  € \        V4      pRpV'       d[   \        V . RO\        V4      RRRR\        P                  ^<R7	      pVP
                  ^ 8X  d   VP                  P                  4       MRpV'       d<   \        \        \        P                  4      ;_uu_ 4        \        WV4       RRR4       \        TR\        P                  ! 4        RT;'       g    R R	T R
T;'       g    R R2	R\        VP                   R,          4       R2,           V'       d
   RV RV R2MR,           \#        V 4      ;p	'       d   RV	 R2MR,           4       V#   + '       g   i     L¯; i)ab  Write the interrupted-pull marker for one git tree move (pre -> target).

``rollback`` (``branch``/``detach``): a syntax rollback that moves HEAD and the index back to
``pre`` before any file; a kill before that step finds HEAD still on ``target`` and the restore
redoes it first, only while HEAD still names the ``ref`` recorded here (empty: detached).
r   Túutf-8Úreplace©ÚcwdÚcapture_outputÚtextÚencodingÚerrorsÚstdinÚtimeoutNzpid=z
pre=z
target=z
stash=Ú
zindex_lock=ú
index.lockz	rollback=z
ref=zgit=)zsymbolic-refú-qÚHEAD)r   r   r   Ú
subprocessÚDEVNULLÚ
returncodeÚstdoutÚstripr   rH   ÚSubprocessErrorÚpublish_recovery_closurer   rC   rD   r
   ÚparentÚ_absolute_git)
rX   r   rb   rs   r�   r   ÚmarkerÚrefÚnamedÚgits
   &&$$$$    r"   r{   r{   Ë   s?  € ô % TÓ*€FØ
€CßÜ˜Ò!?ÄSÈÃYÐ_cÐjnØ!(°Ä*×BTÑBTÐ^`ôbˆà&+×&6Ñ&6¸!Ô&;ˆe�l‰l× Ñ Ô"Àˆß
Ü”gœz×9Ñ9×:Õ:Ü$ W°CÔ8÷ ;ô
 �v ¤b§i¢i£k ]°&¸¿¸À¸À9ÈVÈHÐT\Ð]b×]hÐ]hÐfhÐ\iÐikÐlØ&¤~°f·m±mÀlÕ6RÓ'SÐ&TÐTVÐWõ XçAI˜I h Z¨v°c°U¸"Ñ=Èrõ Sô 5BÀ'Ó4JÐ-J¨SÖ-J˜D   R™.ÐQSõ Uô Vð €M÷ ;×:ús   ÂEÅE"	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rb   r   r   r    )r!   s   "r"   r#   r#   æ   s!   € ÷ 3ñ 3¨Dð 3°sð 3¸tñ 3r$   c           	     ób  a€ ^ RI p\        S4      '       g   \        RS: 24      h\        \	        V4      S4      p\        VS4      '       d   V# . \        V \        4      '       d   V .MT ORNp \        V RRRSR.\        O\        V4      R\        P                  ^xR	7      p/ pVP                  ^ 8X  d&   VP                  ;'       g    R
P                  R4      MR F_  pVP                  RR4      P!                  R4      w  r‰p
VP                  4       R,          R.8X  g   KF  VP                  4       ^,          Wj&   Ka  	  \"        R
/p\%        WS\        4      p\         FQ  p
W¦9  g(   WÊ,          e   \'        WÊ,          S4      Wj,          8w  d   \        V
 RSR,           24      hWÊ,          Wº&   KS  	  RP)                  V3R lVP+                  4        4       4      P-                  R4      pVP/                  RS R\0        P2                  ! 4        R24      pVP5                  VRR7        / VC\6        V/CP+                  4        F�  w  r¯Wê,          P8                  P;                  RRR7       \=        Wê,          R4      ;_uu_ 4       pVP?                  V4       VPA                  4        \0        PB                  ! VPE                  4       4       RRR4       K’  	  VR,          V3 F  p\G        V4       K  	  VP5                  VRR7       \0        PH                  ! Wä4       \G        VP8                  4       VP5                  VRR7       VP8                  PK                  4        F  pVV8w  g   K  VP5                  VRR7       K!  	  V#   + '       g   i     EKS  ; i  TP5                  TRR7       i ; i)a•  Copy the launch repair's modules, as committed at ``pre``, beside the marker (outside the tree).

The bytes come from the commit the repair restores, never from the working tree: a rollback move
starts from a broken tree, and a second move in one run starts from code this process never ran.
A manifest names each file's blob id; the launcher runs the closure only when every file hashes
to it (``recovery_closure_verified``) and rebuilds it from git's objects otherwise. Files and
directory are fsynced before the atomic rename, so a power loss during the move that follows
finds the whole closure or none. An older run's closure (another ``pre``) is dropped.
Nznot a commit id: z--no-replace-objectszls-treeú-zz--full-treez--T)r†   r‡   r‹   rŒ   r$   ó    rƒ   r„   Ú	:é   r   NÚblobz is not in ri   r   c              3  óL   <"  € T F  w  r\        VS4       R V R2x € K  	  R# 5i)Ú r�   N)r	   )Ú.0Úrelr_   rb   s   &  €r"   Ú	<genexpr>Ú+publish_recovery_closure.<locals>.<genexpr>  s(   øé € ÐVÉ¹9¸3œ' $¨Ó,Ð-¨Q¨s¨e°2Õ6Ëùs   ƒ!$Ú.z.staging)Úignore_errors)ÚparentsÚexist_okÚwbÚ
hermes_clir    )&Úshutilr   rH   r   r   r   Ú
isinstancer   r   r   r‘   r’   r“   r”   ÚsplitÚdecodeÚ	partitionr   Úread_target_filesr	   ÚjoinrV   ÚencodeÚ	with_namerC   rD   Úrmtreer   r˜   ÚmkdirÚopenÚwriteÚflushÚfsyncÚfilenoÚ
_fsync_dirr„   Úiterdir)rX   r   rb   r±   ÚdestÚlistedÚidsÚentryÚmetaÚ_r¨   ÚblobsÚshownÚmanifestÚstagingr_   ÚhandleÚ	directoryÚstales   &&f                r"   r—   r—   æ   s  ø€ ó ä˜×ÒÜÐ)¨#©Ð1Ó2Ð2Ü¤ T£
¨CÓ0€DÜ   s×+Ò+ØˆØ]œj¨´#×6Ò6�'‘¸GÐ]ÐF\Ð]€GÜ�W˜y¨$°¸sÀDÐ\ÔK[Ð\ÔbeÐfjÓbkØ$(´
×0BÑ0BÈCôQ€Fà
€CØ8>×8IÑ8IÈQÔ8N�&—-‘-×&Ð& 3×-Ñ-¨eÔ4ÐTVÒVˆØ—|‘| G¨YÓ7×AÑAÀ$ÓG‰ˆ�Ø�:‰:‹<˜Õ  Ö(Ø—z‘z“| A•ˆC‹Hñ Wô # CÐ(€EÜ˜g¨SÔ2BÓC€EßˆØŒ>˜U�ZÒ/´7¸5½:ÀsÓ3KÈsÍxÔ3WÜ˜S˜E ¨S°­X¨JÐ7Ó8Ð8Ø•Zˆ‹
ñ  ð �w‰wÔVÈÏÉÌÓVÓV×]Ñ]Ð^eÓf€HØ�n‰n˜q   Q¤r§y¢y£{ m°8Ð<Ó=€GØ
‡M�M�'¨€MÔ.ð3ØG˜EÐGÔ#<¸hÑG×MÑMÖO‰IˆCØ�]×"Ñ"×(Ñ(°ÀÐ(ÔEÜ�g•m T×*Ô*¨fØ—‘˜TÔ"Ø—‘”Ü—’˜Ÿ™›Ô)÷ +Ñ*ñ Pð " LÕ0°'Ó:ˆIÜ�yÖ!ñ ;à�‰�d¨$ˆÔ/Ü
�
Š
�7Ô!Ü�4—;‘;Ôà�‰�g¨TˆÔ2Ø—‘×$Ñ$Ö&ˆØ�DŽ=Ø�M‰M˜%¨tˆMÖ4ñ 'ð €K÷ +×*Ñ*ûð 	�‰�g¨TˆÕ2ús'   È)AN ÊANËA'N ÎNÎ
N ÎN.c               ó    € V ^8„  d   QhRRRR/# )r   rÎ   r   r   r<   r    )r!   s   "r"   r#   r#     s   € ÷ 	ñ 	˜$ð 	 4ñ 	r$   c                ó  € \         P                  R8X  d   R# \         P                  ! V \         P                  4      p \         P                  ! V4       \         P
                  ! V4       R#   \         P
                  ! T4       i ; i)znPOSIX: make a directory's entries durable. Windows opens no directory handle; NTFS journals
the rename itself.ÚntN)rC   Únamer¼   ÚO_RDONLYr¿   Úclose)rÎ   Úfds   & r"   rÁ   rÁ     sM   € ô 
‡w�w�$„ÙÜ	�Š�œBŸK™KÓ	(€BðÜ
�Š�Œä
�Š�ŽøŒ�Š��ús   ¾A, Á,Bc               ó   € V ^8„  d   QhRR/# )r   r   r   r    )r!   s   "r"   r#   r#   (  s   € ÷ 
3ñ 
3˜cñ 
3r$   c                óè   € ^ RI p\        V \        4      '       g   \        V 4      ;'       g    R.^ ,          MT pVP	                  V4      pV'       d    \
        P                  P                  V4      # R# )a5  The git this run moves the tree with, as an absolute path for the next launch's repair.

A Windows install's git is often PM's store copy, on PATH only inside the updater
(``expose_pm_git``); the repair cannot look it up through ``pm`` when the killed move tore a
module ``pm`` imports (``hermes_constants``).Nr�   r   )r±   r²   r   ÚlistÚwhichrC   r5   Úabspath)rX   r±   r[   Úfounds   &   r"   r™   r™   (  sU   € ó ä0:¸7ÄC×0HÒ0HŒD�‹M×$Ð$˜e˜W aÖ(Èg€DØ�L‰L˜Ó€Eß%*Œ2�7‰7�?‰?˜5Ó!Ð2°Ð2r$   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r   r   rb   r   rs   rc   r   ú	list[str]r    )r!   s   "r"   r#   r#   5  s.   € ÷ Qñ Q $ð Q¨Sð Q¸*ð QÈñ Qr$   c                ó  € V'       d   W28X  d   . # \        V RRRRRW#.\        V4      RRRR\        P                  ^xR	7	      pVP                  ^ 8X  d5   VP
                  P                  R
4       Uu. uF  qU'       g   K  VNK  	  up# . # u upi )z¸Paths ``target`` adds over ``pre``. A rollback's mixed reset un-tracks them and ``reset --hard``
never touches untracked files, so ``drop_added_files`` removes them by name afterwards.Údiffz--name-onlyr    z--no-renamesz--diff-filter=ATrƒ   r„   r…   Ú )r   r   r‘   r’   r“   r”   r³   )rX   r   rb   rs   ÚcpÚps   &&&&  r"   Úfiles_added_byrä   5  s†   € ÷ �V”]Øˆ	Ü	�˜6 =°$¸ÐHYÐ[^ÐgÜ ›I°dÀÐPWÐ`iÜ(×0Ñ0¸#ô
?€Bð 79·m±mÀqÔ6H�r—y‘y—‘ tÔ,Ó2Ñ,�!³�AˆAÑ,Ñ2ÐPÈbÐPùÒ2s   Á0	B	Á>B	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚaddedrÞ   r   r   r    )r!   s   "r"   r#   r#   @  s&   € ÷ Jñ J˜4ð J¨	ð J°dñ Jr$   c           
     ó*  a € \        S 4      o RpV F  p S V,          P                  RR7       K  	  \        V UUu0 uF3  p\        V4      P                   F  p\        V4      R8w  g   K  VkK  	  K5  	  uppR RR7       F  p S V,          P                  4        K  	  T;'       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    Rp Kè  i ; iu uppi   \         d     K�  i ; i)z³Every one is the move's own file: git refuses to move a checkout over an untracked file.

False when one of them is still there (the caller keeps the marker; the restore retries).TrP   Fr«   c                ó,   € \        V P                  4      # ©N)ÚlenÚparts)rã   s   &r"   Ú<lambda>Ú"drop_added_files.<locals>.<lambda>L  s   € ¤s¨1¯7©7¤|r$   )ÚkeyÚreversec              3  óp   <"  € T F+  p\         P                  P                  SV,          4      x € K-  	  R # 5iré   )rC   r5   Úlexists)r§   r¨   r   s   & €r"   r©   Ú#drop_added_files.<locals>.<genexpr>Q  s%   øé € ÐIÁ5¸CœBŸG™GŸO™O¨D°3­J×7Ð7Ã5ùs   ƒ36)r   rW   rH   Úsortedr­   r   ÚrmdirÚany)r   ræ   Úgoner¨   rã   r˜   s   f&    r"   Údrop_added_filesr÷   @  sï   ø€ ô �‹:€DØ€DÛˆð	Ø�C�Z×Ñ¨4ÐÖ0ñ ô
 ¡uÔY¡u ´d¸3³i×6GÔ6G°Ì3ÈqË6ÐUXÉ=Ÿ!˜!Ñ6G™!¡uÒYÙ3¸T÷Cˆð	Ø�F�]×!Ñ!Ö#ñCð ×IÐIŸ›ÔIÁ5ÓIŸŸšÔIÁ5ÓIÓIÔIÐIøô ô 	Ø‹Dð	üãYøô ô 	Úð	ús.   •C)¼*C=
Á+
C=
ÂDÃ)C:Ã9C:ÄDÄDc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rg   r   r   r   r    )r!   s   "r"   r#   r#   T  s&   € ÷ 
Dñ 
D ð 
D¨Cð 
D°Dñ 
Dr$   c                óŠ  a a€ R V V3R llpV! RRRR4      pVP                   ^ 8w  gY   VP                  P                  4       V8w  g:   \        \	        S4      4      P
                  R,          P                  4       '       d   R# V! R	R
RR4      pVP                   ^ 8H  ;'       d!    VP                  P                  R4      '       * # )zOHEAD is ``sha``, no ``index.lock`` is left and no tracked file differs from it.c               ó    € V ^8„  d   QhRRRR/# )r   Úargsr   r   zsubprocess.CompletedProcessr    )r!   s   "r"   r#   Ú#tree_whole_at.<locals>.__annotate__V  s   € ÷ Wñ W�3ð WÐ6ñ Wr$   c                 ó^   <€ \        S. V O\        S4      R R RR\        P                  ^xR7	      # )Trƒ   r„   r…   )r   r   r‘   r’   )rû   rX   r   s   *€€r"   ÚrunÚtree_whole_at.<locals>.runV  s6   ø€ Ü�w  $ ¬S°«YÀtÐRVÐahØ%.´j×6HÑ6HÐRUôWð 	Wr$   ú	rev-parser�   z--verifyr�   rŽ   FÚstatusz--porcelainr    z--untracked-files=norá   )r“   r”   r•   r   r   r˜   Úexists)rX   r   rg   rþ   r[   r  s   ff&   r"   Útree_whole_atr  T  s­   ù€ ÷Wñ Wñ ˆ{˜D *¨fÓ5€DØ‡�˜!Ô˜tŸ{™{×0Ñ0Ó2°cÔ9Ô>UÔVZÐ[_ÓV`Ó>a×>hÑ>hÐkwÕ>w×=Ñ=÷  >Bò  >BÙÙ�˜=¨$Ð0FÓG€FØ×Ñ Ñ!×CÐC¨&¯-©-×*=Ñ*=¸dÓ*CÔ&CÐCr$   c               ó    € V ^8„  d   QhRRRR/# r   r    )r!   s   "r"   r#   r#   a  s   € ÷ 
 ñ 
  $ð 
 ¨4ñ 
 r$   c                ó°   € \        \        V 4      4      pVP                  4       '       g   R# \        \        V 4      RR7       VP                  4       '       * # )a  Git exited without finishing a tree move: put back what it wrote, keep the marker if we can't.

True when the tree is verified whole again (at the pre-move commit, or at the target when git got
there anyway); False leaves the marker for the next launch's ``restore_interrupted_pull``.
FT)Úafter_failure)r   r   Úis_filer   )r   rš   s   & r"   Úsettle_failed_tree_mover  a  s@   € ô %¤T¨$£ZÓ0€FØ�>‰>×ÒÙÜœT $›Z°tÕ<Ø�~‰~ÓÔÐr$   c               ó    € V ^8„  d   QhRRRR/# )r   Ú	pyprojectúbytes | str | Noner   rc   r    )r!   s   "r"   r#   r#   n  s   € ÷ 3ñ 3Ð%7ð 3¸Jñ 3r$   c                ó  € V '       g   R# ^ RI p \        V \        4      '       d   V P                  R4      MT pVP	                  V4      R,          R,          p\        T\        4      '       d   T# R#   \
        \        \        3 d     R# i ; i)zKThe target's ``requires-python`` specifier, None when absent or unreadable.Nrƒ   Úprojectzrequires-python)	Útomllibr²   Úbytesr´   ÚloadsÚKeyErrorÚ	TypeErrorÚ
ValueErrorr   )r
  r  rˆ   Úspecs   &   r"   Ú_requires_python_specr  n  s{   € çÙÛðÜ,6°yÄ%×,HÒ,Hˆy×Ñ Ô(ÈiˆØ�}‰}˜TÓ" 9Õ-Ð.?Õ@ˆô ˜d¤C×(Ò(ˆ4Ð2¨dÐ2øô ”i¤Ð,ô Úðús   �AA2 Á2BÂBc               ó$   € V ^8„  d   QhRRRRRR/# )r   r  r   Úversionr   r   r    )r!   s   "r"   r#   r#   |  s!   € ÷ ñ �sð  Sð ¨Tñ r$   c                ó¬  € ^ RI p ^ RIHpHp  T! T 4      P                  TRR7      #   \         d“    TP                  RT 4      pTP                  RT4      pT'       * ;'       g]    \        T4      ;'       dJ    \        T^,          4      \        T^,          4      3\        T^,          4      \        T^,          4      38¬  u # i ; i  T d     R# i ; i)r&   N)ÚInvalidSpecifierÚSpecifierSetz>=\s*(\d+)\.(\d+)z(\d+)\.(\d+)T)Úprereleases)
ÚreÚpackaging.specifiersr  r  ÚImportErrorÚsearchÚmatchr   ÚintÚcontains)r  r  r  r  r  ÚfloorrÜ   s   &&     r"   Ú_spec_admitsr$  |  sÈ   € ÛðmßGð
Ù˜DÓ!×*Ñ*¨7ÀÐ*ÓEÐEøô ô mØ—	‘	Ð.°Ó5ˆØ—‘˜¨'Ó2ˆØŒy×lÐlœD ›K×lÐl¬S°°qµ«]¼CÀÀaÅ»MÐ,JÌsÐSXÐYZÕS[Ë}Ô^aÐbgÐhiÕbjÓ^kÐNlÑ,lÒlðmûð ô Úðús-   †( �C ¨<CÁ%CÁ8A
CÃCÃCÃCc               ó    € V ^8„  d   QhRRRR/# )r   r
  r  r   r   r    )r!   s   "r"   r#   r#   ‹  s   € ÷ 
Rñ 
RÐ%7ð 
R¸Dñ 
Rr$   c                ót   € ^ RI p\        V 4      pVRJ;'       d    \        W!P                  4       4      '       * # )af  True when a target's ``requires-python`` excludes the running interpreter.

Its startup modules may then use a newer Python's syntax that this interpreter's ``compile()``
cannot judge: ``startup_syntax_error`` asks an installed interpreter the target admits instead.
Unknown -> False: keep checking, so a real syntax error is never waved through on a guess.
N)Úplatformr  r$  Úpython_version)r
  r'  r  s   &  r"   Úrequires_other_pythonr)  ‹  s5   € ó ä  Ó+€DØ�tÐ×QÐQ¤L°×7NÑ7NÓ7PÓ$QÔ QÐQr$   z1import platform; print(platform.python_version())a6  import base64, json, sys
verdict = None
for rel, data in json.load(sys.stdin).items():
    try:
        compile(base64.b64decode(data), rel, 'exec', dont_inherit=True)
    except (SyntaxError, ValueError) as exc:
        verdict = [rel, f'{type(exc).__name__}: {exc}']
        break
print(json.dumps(verdict))
r‹   rŒ   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   ÚargvrÞ   r‹   r   rŒ   Úfloatr   rc   r    )r!   s   "r"   r#   r#   ¦  s(   € ÷ 	9ñ 	9�ið 	9¨3ð 	9¸eð 	9ÈZñ 	9r$   c               óÖ   € ^ RI Hp  \        P                  ! WRRRRW#! 4       RR7	      pTP                  ^ 8X  d   TP                  # R#   \        \        P
                  3 d     R# i ; i)z\Stdout of a read-only interpreter child (it never writes the checkout), None when it failed.)Úwindows_hide_flagsTrƒ   r„   F)Úinputr‡   rˆ   r‰   rŠ   rŒ   ÚcreationflagsÚcheckN)Úhermes_cli._subprocess_compatr.  r‘   rþ   rH   r–   r“   r”   )r+  r‹   rŒ   r.  Údones   &$$  r"   Ú_run_pythonr4  ¦  sk   € å@ðÜ�~Š~˜dÀÈ4ÐZaØ%.¸ÐOaÓOcÐkpôrˆð Ÿ/™/¨QÔ.ˆ4�;‰;Ð8°DÐ8øô ”Z×/Ñ/Ð0ô Úðús   ˆ"A	 Á	A(Á'A(c               ó    € V ^8„  d   QhRRRR/# )r   r  r   r   rc   r    )r!   s   "r"   r#   r#   ²  s   € ÷ ñ ˜3ð  :ñ r$   c                ó˜  € ^ RI Hp \        ^(\        P                  ^,          R	4       Uu. uF5  pV! RV 24      ;pP
                  '       g   K"  VP
                  ^ ,          NK7  	  upR,          pV FO  p\        VRR\        .^R7      ;'       g    RP                  4       pV'       g   K:  \        W4      '       g   KM  Vu # 	  R# u upi )
a  An installed ``python3.N`` the target's ``requires-python`` admits (newest first), or None
when this machine has none. No uv tier: Hermes never resolves the user's uv
(tests/test_managed_runtime_resolution.py), and a missing interpreter only means this one judges.)Úlocate_commandzpython3.:Né   Nú-Iú-c)rŒ   r   Néÿÿÿÿ)
Úhermes_platform.resolverr7  Úrangero   Úversion_infoÚcommandr4  Ú_PYTHON_VERSIONr•   r$  )r  r7  ÚminorÚresÚ
candidatesÚpythonr  s   &      r"   Ú_admitted_pythonrE  ²  s¹   € õ 8ä.3°B¼×8HÑ8HÈÕ8KÈRÔ.Pó JÑ.P UÙ+¨h°u°gÐ,>Ó?Ð?�c×HÕHô !�#—+‘+˜a—.�.Ñ.Pñ JØJLõN€JãˆÜ ¨¨d´OÐDÈbÔQ×WÐWÐUW×^Ñ^Ó`ˆß‰7”| D×2Ô2ØŠMñ ñ ùòJs   «CÁCc               ó    € V ^8„  d   QhRRRR/# )r   Úsourceszdict[str, bytes]r   útuple[str, str] | Noner    )r!   s   "r"   r#   r#   Á  s   € ÷ ñ Ð+ð Ð0Fñ r$   c                óÎ   € V P                  4        F  w  r \        W!R RR7       K  	  R#   \        \        3 d)   pT\	        T4      P
                   RT 23u Rp?u # Rp?ii ; i)ÚexecT)Údont_inheritz: N)rV   ÚcompileÚSyntaxErrorr  ÚtypeÚ__name__)rG  r¨   r_   rq   s   &   r"   Ú_compile_hererP  Á  sb   € Ø—]‘]–_‰	ˆð	7Ü�D˜v°D×9ñ %ñ
 øô œZÐ(ô 	7Øœ4 ›9×-Ñ-Ð.¨b°°Ð6Ð6×6ûð	7ús   —+«A$¼AÁA$ÁA$c               ó$   € V ^8„  d   QhRRRRRR/# )r   rG  údict[str, bytes | None]r
  zbytes | Noner   rH  r    )r!   s   "r"   r#   r#   Ê  s(   € ÷ !mñ !mÐ"9ð !mÀlð !mÐWmñ !mr$   c           
     ó®  € ^ RI p^ RIp^ RIpV P                  4        UUu/ uF  w  rVVf   K  WVbK  	  ppp\	        V4      pVe    \        W„P                  4       4      '       d   \        V4      # \        V4      ;p	'       dô   TP                  VP                  4        UUu/ uF%  w  rVWRP                  V4      P                  R4      bK'  	  upp4      p
\        V	RR\        .V
^xR7      p TP                  T;'       g    RP                  4       P!                  4       R,          4      pVf   R# \'        V\(        4      '       d2   \+        V4      ^8X  d"   \-        V^ ,          4      V^,           RV	 R	23# \        V4      pVf   R# V^ ,          V^,           R
VP                  4        RV RV R23# u uppi u uppi   \"        \$        3 d    Rp L«i ; i)a  ``(path, error)`` for the first startup file that does not compile, else None.

Judged by the interpreter that will run the target: this one when the target's
``requires-python`` admits it, else an installed interpreter it admits (review N15: a
conflict-marker scan is not a syntax check). With none installed, this interpreter still
judges: code it parses is code a newer Python parses, and a refusal names the Python to install
so the release can be judged by its own interpreter. ``None`` values (absent files) are skipped.
NÚasciir9  r:  )r‹   rŒ   r   Fz (judged by Ú)z
Judged by Python z: the target requires Python zM and no installed interpreter satisfies it. Install one (`uv python install 'zJ'`) and re-run `hermes update` so the release is judged by its own Python.r;  )Úbase64Újsonr'  rV   r  r$  r(  rP  rE  ÚdumpsÚ	b64encoder´   r4  Ú_COMPILE_ALLr  r•   Ú
splitlinesÚ
IndexErrorr  r²   rÙ   rê   r   )rG  r
  rV  rW  r'  r¨   r_   Úpresentr  rD  ÚpayloadÚoutÚverdictÚbrokens   &&            r"   Ústartup_syntax_errorrb  Ê  s¾  € ó ÛÛà*1¯-©-¬/ÔN©/™Y˜S¸TŒyˆsŠy©/€GÑNÜ  Ó+€DØ‚|”| D×*AÑ*AÓ*C×DÒDÜ˜WÓ%Ð%Ü! $Ó'Ð'€vÖ'Ø—*‘*Ð[b×[hÑ[hÔ[jÔkÑ[jÉiÈc˜c×#3Ñ#3°DÓ#9×#@Ñ#@ÀÓ#IÒIÑ[jÒkÓlˆÜ˜6 4¨¬|Ð<ÀGÐUXÔYˆð	Ø—j‘j #§) )¨×!2Ñ!2Ó!4×!?Ñ!?Ó!AÀ"Õ!EÓFˆGð Š?ÙÜ�gœt×$Ò$¬¨W«¸Ô):Ü�w˜q•z“? w¨q¥z l°,¸v¸hÀaÐ$HÐHÐHÜ˜7Ó#€FØ‚~ÙØ�!�9˜& �)˜Ð$7¸×8OÑ8OÓ8QÐ7RÐRoØ˜ð  Ø˜&Ð jðlð mð mùó% Oùó
 løô œJÐ'ô 	ØŠGð	ús(    F2­F2Â +F8
Ã*F> Ã>*F> Æ>GÇGc               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Ú
target_refr   r   rR  r    )r!   s   "r"   r#   r#   î  s"   € ÷ ñ  Tð °sð ÐI`ñ r$   c           	     ó¤  a€ \        \        P                  V4      4      p\        P                  V4      pRP                  V3R lV 4       4      P	                  R4      p\        V RR.\        V4      VR^xR7      pVP                  ^ 8X  d   VP                  ;'       g    RMR^ r˜V F¥  p
VP                  R	V	4      pV^ 8  d    V# W‰V P                  4       V^,           rœ\        V4      ^8X  g   KK  V^,          P                  4       '       g   Kj  \        V^,          4      pV^,          R
8X  d   W‰W�,            WZ&   W�^,           ,          p	K§  	  V# )z¦``{rel: bytes}`` of each path as committed at ``target_ref`` (None: absent there or unreadable),
in ONE ``git cat-file --batch`` instead of one ``git show`` per file.r   c              3  ó4   <"  € T F  pS R V R2x € K  	  R# 5i)Ú:r�   Nr    )r§   r¨   rd  s   & €r"   r©   Ú$read_target_files.<locals>.<genexpr>ó  s   øé € Ð?¹°#˜˜ A c U¨"Õ-»ùs   ƒrƒ   zcat-filez--batchT)r†   r/  r‡   rŒ   r$   ó   
s   blob)rÙ   rT   Úfromkeysr·   r¸   r   r   r“   r”   Úfindr³   rê   Úisdigitr!  )rX   r   rd  ÚrelpathsÚnamesrÜ   Úrequestrâ   r_  Úposr¨   ÚendÚheaderÚsizes   &&f&          r"   r¶   r¶   î  s!  ø€ ô ”—‘˜xÓ(Ó)€EÜ%)§]¡]°5Ó%9€EØ�g‰gÔ?¹Ó?Ó?×FÑFÀwÓO€GÜ	�˜: yÐ1´s¸4³yÈÐ`dÐnqÔ	r€BØ%'§]¡]°aÔ%7�—	‘	× Ð ˜Sø¸SÀ!ˆÛˆØ�h‰h�u˜cÓ"ˆØ�Œ7Øð €Lð ˜c�l×(Ñ(Ó*¨C°!­G�Üˆv‹;˜!Ö  q¥	× 1Ñ 1× 3Ô 3Ü�v˜a•y“>ˆDØ�a�y˜GÔ#Ø  S¥ZÐ0�‘
Ø˜!•8�OŠCñ ð €Lr$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rd  r   r   rH  r    )r!   s   "r"   r#   r#     s"   € ÷ 2ñ 2 tð 2¸ð 2ÐKañ 2r$   c                ó¬   €  \        WVR.VO4      pTP	                  RR4      p\        YE4      #   \        P                   d    \        R4        R# i ; i)aÉ  ``(path, error)`` for the first startup-critical file that does not compile at ``target_ref``.

Read from the object store, never written to the tree: this runs BEFORE HEAD moves, so a broken
release is refused with the install untouched (the post-pull rollback stays as the backstop).
``startup_syntax_error`` judges it under the interpreter the target admits. A file absent at the
target (or unreadable) is skipped: the post-pull guard has the last word.
úpyproject.tomluU     âš  Syntax preflight skipped (slow object fetch); the post-update check still runs.N)r¶   r‘   ÚTimeoutExpiredrn   Úpoprb  )rX   r   rd  rm  Úfilesr
  s   &&&&  r"   Útarget_syntax_errorrz    sb   € ðÜ! '°Ð>NÐ=ZÐQYÐ=ZÓ[ˆð —	‘	Ð*¨DÓ1€IÜ Ó1Ð1øô ×$Ñ$ô ô 	ÐeÔfÚð	ús   ‚/ ¯ AÁAc               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   rH  r    )r!   s   "r"   r#   r#     s   € ÷ 
bñ 
b˜Dð 
bÐ/Eñ 
br$   c                ól  € \        V 4      p / pV F:  p W,          P                  4       '       d   W,          P                  4       MRW#&   K<  	  V R,          p\        Y%P                  4       '       d   VP                  4       4      # R4      #   \         d   p\	        T4      RT 23u Rp?u # Rp?ii ; i)z\``startup_syntax_error`` for the files in the worktree at ``root`` (the post-move backstop).Nzcould not read: rv  )r   r  r7   rH   r   rb  )r   rm  rG  r¨   rq   r
  s   &&    r"   Útree_syntax_errorr}    s¥   € ä�‹:€DØ')€GÛˆð	6Ø9=½×8LÑ8L×8NÒ8N˜D�J×2Ñ2Ô4ÐTXˆG‹Lñ ð
 Ð'Õ'€IÜ ×CTÑCT×CVÒCV¨×)=Ñ)=Ó)?ÓaÐaÐ\`ÓaÐaøô ô 	6Ü�s“8Ð/°¨uÐ5Ð5×5ûð	6ús   ”6BÂB3ÂB.Â&B3Â.B3c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   ztuple[str, str]r    )r!   s   "r"   r#   r#   #  s   € ÷ Nñ N 4ð N¨Oñ Nr$   c                ó@   a a€ R  V V3R llpV! RR4      V! RRR4      3# )c               ó    € V ^8„  d   QhRRRR/# )r   rû   r   r   r    )r!   s   "r"   r#   Ú%head_and_branch.<locals>.__annotate__$  s   € ÷ ?ñ ?�3ð ?˜3ñ ?r$   c                 ó¸   <€ \        S. V O\        S4      R R RR\        P                  ^<R7	      pVP                  ^ 8X  d   VP
                  P                  4       # R# )Trƒ   r„   r…   r   )r   r   r‘   r’   r“   r”   r•   )rû   râ   rX   r   s   * €€r"   r_  Úhead_and_branch.<locals>.out$  sS   ø€ Ü�W˜g ˜g¬3¨t«9ÀTÐPTÐ_fÐoxÜ",×"4Ñ"4¸bôBˆà$&§M¡M°QÔ$6ˆr�y‰y�‰Ó Ð>¸BÐ>r$   r   r�   z--abbrev-refr    )rX   r   r_  s   ff r"   rR   rR   #  s*   ù€ ÷?ñ ?ñ
 ˆ{˜FÓ#¡S¨°nÀfÓ%MÐMÐMr$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ru   rH  r   r   r    )r!   s   "r"   r#   r#   ,  s"   € ÷ 	3ñ 	3 dð 	3Ð3Ið 	3Èdñ 	3r$   c                ó¨   € ^ RI Hp Ve   V^ ,          '       g   R# V! 4       f    \        V4      P                  4       '       d   R# \	        W4      V8H  # )z®True when the checkout is exactly where this run found it: same HEAD, same branch, no
autostash taken, no tree move armed. Only then may a failed git update fall back to ZIP.)Ú_unrestored_autostash_noticeF)Úhermes_cli.update_cmd_stashr†  r   r  rR   )rX   r   ru   r†  s   &&& r"   Úcheckout_untouchedrˆ  ,  sH   € õ Ià‚}˜E !ŸHœHÙÙ#Ó%Ò1Ô5LÈTÓ5R×5ZÑ5Z×5\Ò5\ÙÜ˜7Ó)¨UÑ2Ð2r$   c               ó   € V ^8„  d   QhRR/# rL   r    )r!   s   "r"   r#   r#   8  s   € ÷ ñ ˜dñ r$   c                 ó>   € Rs Rs\        P                  4        RsRsR# )a\  A new ``hermes update`` attempt owns nothing yet: no snapshot, no stake, no run start.

The state above is per attempt, not per process: a second update in one interpreter (a
long-lived caller) that inherited the first one's snapshot and owner would hand back the
first update's committed debt as its own undo when its move is refused (review O5).
r   N)r   r   r   rU   r   r   r    r$   r"   Úbegin_update_attemptr‹  8  s%   € ð €FØ€OÜ×ÑÔØ€JØÒr$   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r<   r    )r!   s   "r"   r#   r#   G  s   € ÷ "ñ " Dð "¨Tñ "r$   c                óH   € \        V 4      \        W4      3s\        V4      sR # ré   )rÙ   rR   r   r   r   )rX   r   s   &&r"   Úrecord_run_startrŽ  G  s   € ä�w“-¤°Ó!?Ð@€JÜ˜D“zÒr$   c               ó    € V ^8„  d   QhRRRR/# r   r    )r!   s   "r"   r#   r#   M  s   € ÷ Hñ H ð H¨$ñ Hr$   c                ón   € \         f   R# \        \         ^ ,          \        V 4      \         ^,          4      # )z]``checkout_untouched`` for this run; True before the checkout phase (nothing can have moved).T)r   rˆ  r   )r   s   &r"   Úrun_checkout_untouchedr‘  M  s&   € äÒÙÜœj¨�m¬T°$«Z¼ÀA½ÓGÐGr$   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   rd  r   r   rc   r    )r!   s   "r"   r#   r#   T  s!   € ÷ ñ  Tð °sð Èzñ r$   c                ód  € \        V4      p\        V4      '       g    ^ RIHp V! V4       \        WW#4      pVeA   Vw  rx\        R4       RV R2RP                  VP                  4       R,          4      ,           # R#   \         d     L_\
         d   p\        R4       RT 2u Rp?# Rp?ii ; i)	a  Why this update must not start, checked BEFORE the first tree move; ``None`` to proceed.

* a venv owned by another OS user (the completion child used to refuse only after the swap);
* a target whose startup-critical modules do not compile (rollback used to be the only guard).
)Úrefuse_foreign_owned_venvÚvenv_foreign_owneru   âœ— Nrz  u?   âœ— The update target has a syntax error in a critical file:
  z
    :Né   N)
r   r*   r2   r”  r  Ú	Exceptionr   rz  r·   r[  )	rX   r   rd  Úcritical_filesr”  rq   ra  r5   Úerrors	   &&&&     r"   Úpreflight_refusalrš  T  s´   € ô �‹:€DÜ˜t×$Ò$ð	 ÝFá% dÔ+ô ! °
ÓK€FØÒØ‰ˆÜÐ*Ô+ØRÐSWÐRXÐX^Ð_Ø—-‘- × 0Ñ 0Ó 2°2Õ 6Ó7õ8ð 	9áøô ô 	ÙÜô 	 ÜÐ-Ô.Ø˜#˜�<Õûð	 ús)   žA> Á>B/ÂB/ÂB/ÂB*Â$B/Â*B/)IÚ__conditional_annotations__Ú__doc__Ú
__future__r   ÚloggingrC   r‘   ro   Ú
contextlibr   Úpathlibr   Útypingr   Úhermes_cli._early_recoveryr   r   r   r	   r
   r   r   r   r   r   r   Úhermes_cli.update_cmd_commonr   Úhermes_cli.update_custodyr   Ú	getLoggerrl   r   Ú__annotations__r   r   r   r   r*   r3   r9   rJ   r`   re   rS   rv   r~   r{   r—   rÁ   r™   rä   r÷   r  r  r  r$  r)  r@  rZ  r4  rE  rP  rb  r¶   rz  r}  rR   rˆ  r‹  rŽ  r‘  rš  )r›  s   @r"   Ú<module>r§     sc  øðôõ #ã Û 	Û Û 
Ý Ý Ý ÷÷ ÷ ñ õ 6Ý -à	×	Ò	Ð2Ó	3€à9=€Ð6Ó =à,.€Ð)Ó .à59€
Ð2Ó 9Ø#'Ð �.Ó 'à€ˆÓ õ1õiõõQõ:'õT$õ	Xõ5õð0Ø)-÷õ63õl	õ
3õQõJõ(
Dõ
 õ3õõ
Rð F€ð#ð ð	9°ð 	9Àb÷ 	9õõõ!mõHõ*2õ&
bõNõ	3õõ"õH÷r$   