+
    jHà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t^ RIt^ RIt^ RIHtHt ^ RIHt ^ RIHt ^ RIHt ]P.                  ! ]4      tR´tRtRtR	tR
tRtRt Rt!Rt"^€t#^t$Rµt%^t&Rt'R R lt(R R lt)R R lt*R¶R R llt+R R lt,R t-R R lt.R R lt/R¶R R  llt0R! R" lt1/ t2R#]3R$&   R% R& lt4R¶R' R( llt5]! R)R*7       ! R+ R,4      4       t6R- R. lt7R/ R0 lt8R¶R1 R2 llt9R¶R3 R4 llt:R5 R6 lt;R7 R8 lt<R9 R: lt=R; R< lt>R= R> lt?R? R@ lt@]! R)R*7       ! RA RB4      4       tARCtBRDtC]Pˆ                  ! RE]PŠ                  4      tF]Pˆ                  ! RF]PŠ                  4      tG]Pˆ                  ! RG]PŠ                  4      tH]Pˆ                  ! RH]PŠ                  4      tI]Pˆ                  ! RI]PŠ                  4      tJ]! R)R*7       ! RJ RK4      4       tKRL RM ltLRNR/RO RP lltMR¶RQ RR lltNR¶RS RT lltORU RV ltPRW RX ltQRY RZ ltRR[tSR\ R] ltTR^ R_ ltUR`tVRatW ! Rb Rc]X4      tY]P´                  ! 4       t[Rd Re lt\Rf Rg lt]Rh Ri lt^Rj Rk lt_]Rl]W/Rm Rn ll4       t`Ro Rp ltaRq Rr ltbRsRRtR/Ru Rv lltcR¶Rw Rx lltdR¶Ry Rz llteR{ R| ltfRsgR}]3R~&   . thR]3R€&   R� R‚ ltiR·Rƒ R„ lltj]%^3R… R† lltkR‡ Rˆ ltlR‰ RŠ ltmR‹ RŒ ltnR� RŽ ltoR� R� ltpR‘tqR’ R“ ltrR” R• ltsR– R— lttR¶R˜ R™ lltuRš R› ltv^twRœ R� ltxRž RŸ ltyR  R¡ ltzR¢ R£ lt{R¶R¤ R¥ llt|R¶R¦ R§ llt}R¶R¨ R© llt~Rª R« ltR¬ R­ lt€/ t�R®]3R¯&    ! R° R±4      t‚R² R³ ltƒR# )¸uÌ  Cross-process mutual exclusion for in-flight Hermes updates.

Two artifacts, one authority each:

* The update marker ``<root hermes home>/.hermes-update-in-progress`` (contract C1, format v2)
  is shared with the Tauri updater (``UpdateMarkerGuard`` in
  ``apps/bootstrap-installer/src-tauri/src/update.rs``), the Electron gate
  (``electron/update-marker.ts``) and the Desktop hand-off scripts. Body::

      <pid>\n<started_at>\nct:<owner creation time, 3 decimals>\n[delegate:<pid> ct:<ct>\n]

  An owner is live while its pid is alive and its creation time still matches: never by age
  (the 20-minute ceiling only ages out v1 markers, which carry no creation time).
* The checkout lock ``<git common dir>/hermes-update.lock`` (``<install root>/.hermes-update.lock``
  for a ZIP install with no ``.git``) â€” a kernel lock (flock / msvcrt) that ``hermes update``
  holds for its whole process tree, so two updates of one checkout started from different
  homes exclude each other and a killed updater whose completion child still runs keeps the
  checkout locked until that child exits. In the git dir it is never a worktree file: no
  ``git status``/autostash sees it, whatever the checked-out tree's ``.gitignore`` says.
)ÚannotationsN)ÚcontextmanagerÚsuppress)Ú	dataclass)ÚPath)ÚS_ISREGg       @g{®Gázt?g      ð?g      @z.hermes-update-in-progressz.hermes-update.lockzhermes-update.lockÚHERMES_UPDATE_HANDOFF_PIDl     }*{Gíc               ó   € V ^8„  d   QhRR/# ©é   Úreturnr   © )Úformats   "Ú;/home/ubuntu/.hermes/hermes-agent/hermes_cli/update_lock.pyÚ__annotate__r   Z   s   € ÷ 3ñ 3˜Dñ 3ó    c                 ón  €  ^ RI Hp  T ! 4       \        ,          #   \         d�    \        \        P
                  P                  R4      ;'       g    \        P                  ! 4       R,          4      pTP                  P                  R8X  d   TP                  P                  MTpT\        ,          u # i ; i)a(  Path of the shared update marker: always the profile-tree ROOT home.

A sticky or ``-p`` profile re-homes ``HERMES_HOME`` to ``<root>/profiles/<p>``; the Desktop,
the hand-off scripts and the Tauri updater all look at the root, so a profile-scoped marker
would be one the other owners never see.
)Úget_default_hermes_rootÚHERMES_HOMEz.hermesÚprofiles)Úhermes_constantsr   ÚImportErrorr   ÚosÚenvironÚgetÚhomeÚparentÚnameÚMARKER_NAME)r   r   Úroots      r   Úupdate_marker_pathr    Z   s‚   € ð"Ý<ñ
 #Ó$¤{Õ2Ð2øô	 ô "Ü”B—J‘J—N‘N =Ó1×LÐL´T·Y²Y³[À9Õ5LÓMˆØ%)§[¡[×%5Ñ%5¸Ô%Cˆt�{‰{×!Ò!ÈˆØ”kÕ!Ò!ð"ús   ‚ š5B4ÁA!B4Â3B4c               ó   € V ^8„  d   QhRR/# r
   r   )r   s   "r   r   r   j   s   € ÷ /ñ /˜tñ /r   c                 ó^   € \        \        4      P                  4       P                  ^,          # ©é   )r   Ú__file__ÚresolveÚparentsr   r   r   Ú_default_install_rootr(   j   s    € Ü”‹>×!Ñ!Ó#×+Ñ+¨AÕ.Ð.r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   úPath | Noner   )r   s   "r   r   r   n   s   € ÷ *ñ *˜$ð * ;ñ *r   c                ó.  € V R,          p VP                  4       '       d   TpMtVP                  4       '       d]   VP                  RR7      P                  4       pVP	                  R4      '       g   R# W\        R4      R P                  4       ,          pMR# VR,          pVP                  4       '       d'   W$P                  RR7      P                  4       ,          p\        \        P                  P                  T4      4      #   \         d     R# i ; i)a  The repository's common git dir, read from disk (no git process: -I -S children).

``.git`` is the dir itself, or a ``gitdir: <path>`` file (linked worktree, submodule) whose
target may name the shared dir in ``commondir``. ``None`` when ``root`` is no checkout.
z.gitz	utf-8-sig)Úencodingzgitdir:NÚ	commondir)Úis_dirÚis_fileÚ	read_textÚstripÚ
startswithÚlenÚOSErrorr   r   ÚpathÚnormpath)r   ÚdotÚgitdirÚtextÚcommons   &    r   Ú_git_common_dirr;   n   sÝ   € ð ��-€CðØ�:‰:�<Š<Ø‰FØ�[‰[�]Š]Ø—=‘=¨+�=Ó6×<Ñ<Ó>ˆDØ—?‘? 9×-Ò-ÙØ¤ Y£ Ð1×7Ñ7Ó9Õ9‰FáØ˜+Õ%ˆØ�>‰>×ÒØ×.Ñ.¸Ð.ÓD×JÑJÓLÕLˆFô ”—‘× Ñ  Ó(Ó)Ð)øô ô Úðús-   ‹D ¡D º6D Á3#D ÂD Â7&D ÄDÄDc               ó    € V ^8„  d   QhRRRR/# )r   Úinstall_rootúPath | str | Noner   r   r   )r   s   "r   r   r   ‡   s   € ÷ \ñ \Ð%6ð \À$ñ \r   c                óŽ   € \        T ;'       g    \        4       4      p\        V4      pVf   V\        ,          # V\        ,          # ©N)r   r(   r;   ÚCHECKOUT_LOCK_NAMEÚGIT_CHECKOUT_LOCK_NAME)r=   r   r:   s   &  r   Úcheckout_lock_pathrC   ‡   s=   € Ü�×7Ð7Ô 5Ó 7Ó8€DÜ˜TÓ"€FØ(.ªˆ4Ô$Õ$Ð[¸FÔE[Õ<[Ð[r   c               ó    € V ^8„  d   QhRRRR/# ©r   ÚpidÚintr   Úboolr   )r   s   "r   r   r   �   s   € ÷ 	ñ 	�Cð 	˜Dñ 	r   c                ó�   € V ^ 8:  d   R#  ^ RI Hp V! V 4      #   \         d"   p\        P	                  RY4        Rp?R# Rp?ii ; i)zQUse the dependency-free, Windows-safe, zombie-aware probe before PM is available.F)Ú_pid_is_runningzCould not probe pid %s: %sN)Úhermes_cli._early_recoveryrJ   Ú	ExceptionÚloggerÚdebug)rF   rJ   Úexcs   &  r   Ú
_pid_aliverP   �   sA   € à
ˆa„xÙðÝ>Ù˜sÓ#Ð#øÜô Ü�‰Ð1°3Ô<Ýûðús   ‹ ™A¤A Á Ac                 ó  € ^ RI p ^ RI Hp V P                  RRR7      pVP                  VP                  VP                  .VP
                  n        VP                  VP
                  n        VP                  .V P                  VP                  4      .^,          ,           VP                  n        VP                  VP                  n        VP                  .VP                  n        VP                  VP                  n        V# ©é    N©ÚwintypesÚkernel32T©Úuse_last_error)ÚctypesrU   ÚWinDLLÚDWORDÚBOOLÚOpenProcessÚargtypesÚHANDLEÚrestypeÚPOINTERÚFILETIMEÚGetProcessTimesÚCloseHandle)rY   rU   rV   s      r   Ú_windows_kernel32re   œ   s½   € ÛÝà�}‰}˜Z¸ˆ}Ó=€HØ%-§^¡^°X·]±]ÀHÇNÁNÐ$S€H×ÑÔ!Ø#+§?¡?€H×ÑÔ Ø)1¯©Ð(9¸V¿^¹^ÈH×L]ÑL]Ó=^Ð<_ÐbcÕ<cÕ(c€H×ÑÔ%Ø'/§}¡}€H×ÑÔ$Ø%-§_¡_Ð$5€H×ÑÔ!Ø#+§=¡=€H×ÑÔ Ø€Or   c               ó    € V ^8„  d   QhRRRR/# ©r   rF   rG   r   ú
int | Noner   )r   s   "r   r   r   ª   s   € ÷ %ñ % #ð %¨*ñ %r   c                óâ  a€ ^ RI o^ RI Hp \        4       pVP                  RRV 4      pV'       g   R#  \	        ^4       Uu. uF  qAP                  4       NK  	  ppVP                  ! V.V3R lV 4       O5!  '       g    VP                  V4       R# V^ ,          P                  ^ ,          V^ ,          P                  ,          VP                  V4       # u upi   TP                  T4       i ; i)zHGetProcessTimes creation FILETIME (100 ns ticks since 1601) or ``None``.NrT   i   Fc              3  óF   <"  € T F  pSP                  V4      x € K  	  R # 5ir@   )Úbyref)Ú.0ÚtrY   s   & €r   Ú	<genexpr>Ú+_windows_create_filetime.<locals>.<genexpr>µ   s   øé € Ð1QÉ5Àa°&·,±,¸q·/°/Ë5ùs   ƒ!)
rY   rU   re   r]   Úrangerb   rc   rd   ÚdwHighDateTimeÚdwLowDateTime)rF   rU   rV   ÚhandleÚ_ÚtimesrY   s   &     @r   Ú_windows_create_filetimerv   ª   sÆ   ø€ ãÝä Ó"€HØ×!Ñ! &¨%°Ó5€FßÙð%Ü.3°A¬hÓ7©h¨×"Ñ"Ö$©hˆÐ7Ø×'Ò'¨ÐRÔ1QÉ5Ó1Q×RÒRØð 	×Ñ˜VÖ$ð �a•×'Ñ'¨2Õ-°°qµ×1GÑ1GÕGà×Ñ˜VÕ$ùò 8øð
 	×Ñ˜VÕ$ús#   ´C ÁCÁ&C Â1C ÃC ÃC.c               ó    € V ^8„  d   QhRRRR/# )r   rF   rG   r   úfloat | Noner   )r   s   "r   r   r   ¼   s   € ÷ ñ ˜Sð  \ñ r   c                ó®  €  \         P                  R8X  d&   \        V 4      pVf   R# V\        ,
          R,          # \        P
                  P                  R4      '       d¾   \        RV  R2R4      ;_uu_ 4       pVP                  4       pRRR4       \        XVP                  R4      ^,           R P                  4       ^,          4      p\        R	R4      ;_uu_ 4       p\        R
 V 4       4      pRRR4       XV\        P                  ! R4      ,          ,           # \        P                  ! RRRR\!        V 4      .RRRR^\        P"                  R\        P$                  P'                  R4      ;'       g    RRRRR/RR7	      P(                  P+                  4       pV'       g   R# \-        \.        P0                  ! \2        P4                  ! RP7                  VP                  4       4      R4      4      4      #   + '       g   i     ELx; i  + '       g   i     EL$; i  \8        \:        \<        \>        \        P@                  \B        3 d     R# i ; i)u1  Creation time in unix seconds without psutil (``-I -S`` children, early recovery).

Same clock psutil reports: Linux ``starttime / CLK_TCK + btime``, macOS the kernel start
time (``ps -o lstart=`` in UTC, second resolution â€” inside the 2 s tolerance), Windows the
``GetProcessTimes`` creation FILETIME.
Úwin32Ng    ÐcAú/procú/proc/ú/statÚrbó   )z
/proc/statc              3  ó’   "  € T F=  qP                  R 4      '       g   K  \        VP                  4       ^,          4      x € K?  	  R# 5i)s   btime N)r2   rG   Úsplit)rl   Úlines   & r   rn   Ú&_stdlib_create_time.<locals>.<genexpr>Ì   s/   é € Ð_¹b°dÇOÁOÐT]×D^Ô1œS §¡£¨a¥×1Ð1»bùs
   ‚AŸ(AÚ
SC_CLK_TCKÚpsú-ozlstart=ú-pTúutf-8ÚreplaceÚPATHz/bin:/usr/binÚLC_ALLÚCÚTZÚUTC0F)Úcapture_outputr9   r,   ÚerrorsÚtimeoutÚstdinÚenvÚcheckÚ z%a %b %d %H:%M:%S %Y)"ÚsysÚplatformrv   Ú_FILETIME_UNIX_EPOCHr   r5   ÚisdirÚopenÚreadrG   Úrindexr�   ÚnextÚsysconfÚ
subprocessÚrunÚstrÚDEVNULLr   r   Ústdoutr1   ÚfloatÚcalendarÚtimegmÚtimeÚstrptimeÚjoinr4   Ú
ValueErrorÚ
IndexErrorÚStopIterationÚSubprocessErrorÚAttributeError)rF   ÚticksÚfhÚstatÚstart_ticksÚbtimeÚouts   &      r   Ú_stdlib_create_timerµ   ¼   sÀ  € ðÜ�<‰<˜7Ô"Ü,¨SÓ1ˆEØ š=�4ÐR¨uÔ7KÕ/KÈsÕ.RÐRÜ�7‰7�=‰=˜×!Ò!Ü˜˜s˜e 5Ð)¨4×0Ô0°BØ—w‘w“y�÷ 1ä˜d 4§;¡;¨tÓ#4°qÕ#8Ð#9Ð:×@Ñ@ÓBÀ2ÕFÓGˆKÜ�l D×)Ô)¨RÜÑ_¹bÓ_Ó_�÷ *à˜;¬¯ª°LÓ)AÕAÕAÐAä�nŠnØ�4˜ D¬#¨c«(Ð3ÀDÈtØ Y¸Ä×ASÑASØœŸ™Ÿ™¨Ó/×BÐB°?ÀHÈcÐSWÐY_Ð`Øô	
÷
 ‰&—‘“ð 	÷ ÙÜ”X—_’_¤T§]¢]°3·8±8¸C¿I¹I»KÓ3HÐJ`Ó%aÓbÓcÐc÷ 1×0Ð0ú÷ *×)Ð)ûô ”Z¤¬]¼J×<VÑ<VÔXfÐgô Úðúsf   ‚%H! ¨H! ¼$H! Á!H! Á9G9Â
AH! ÃHÃ2+H! ÄAH! Å8-H! Æ(AH! Ç9H
	È	H! ÈH	È	H! È!/IÉIc               ó    € V ^8„  d   QhRRRR/# )r   rF   rh   r   rx   r   )r   s   "r   r   r   Ü   s   € ÷ +ñ +˜Zð +°<ñ +r   c                ó  € V f   \         P                  ! 4       MT p ^ RIp \        TP                  T4      P                  4       4      #   \         d    \	        T4      u # i ; i  \         d    \	        T4      u # i ; i)uB  Creation time of ``pid`` (default: this process) in unix seconds, or ``None``.

psutil when importable â€” the value ``process_identity._process_create_time`` records â€”
else the stdlib probe of the same kernel clock, so a marker written by either is
comparable by the other within :data:`CREATE_TIME_TOLERANCE_SECONDS`.
N)	r   ÚgetpidÚpsutilr   rµ   r¤   ÚProcessÚcreate_timerL   )rF   Útargetr¹   s   &  r   Úprocess_create_timer½   Ü   sv   € ð  šKŒR�YŠYŒ[¨S€Fð+Ûð+Ü�V—^‘^ FÓ+×7Ñ7Ó9Ó:Ð:øô ô +Ü" 6Ó*Ò*ð+ûô ô +Ü" 6Ó*Ò*ð+ús"   �A
 ¢'A& Á
A#Á"A#Á&A?Á>A?c               ó   € V ^8„  d   QhRR/# ©r   r   rx   r   )r   s   "r   r   r   î   s   € ÷ ñ ˜,ñ r   c                 óÊ   € \         P                  ! 4       p \        P                  R4      V 8w  d!   \        P	                  V \        V 4      R7       \        P                  R4      # )zQThis process's creation time (cached per pid: a forked child is another process).rF   ©rF   ÚctrÂ   )r   r¸   Ú_OWN_CTr   Úupdater½   ©rF   s    r   Ú_own_create_timerÆ   î   sC   € ä
�)Š)‹+€CÜ‡{�{�5Ó˜SÔ Ü�‰˜3Ô#6°sÓ#;ˆÔ<Ü�;‰;�tÓÐr   ÚdictrÃ   c               ó   € V ^8„  d   QhRR/# r¿   r   )r   s   "r   r   r   ù   s   € ÷ 4ñ 4˜ñ 4r   c                ó"  € V e   \        V \        \        34      '       d   V f   R# \        V 4      # \        P	                  \        V 4      P                  4       P                  R4      4      pV'       d   \        VP                  ^ 4      4      # R# )zVA recorded creation time as a float: a number, ``"ct:<s>"`` / ``"<s>"`` text, or None.Núct:)	Ú
isinstancerG   r¤   Ú	_CT_VALUEÚ	fullmatchr¡   r1   ÚremoveprefixÚgroup)ÚrecordedÚmatchs   & r   Ú_as_ctrÒ   ù   sn   € àÒœ: h´´e°×=Ò=ØÒ'ˆtÐ<¬U°8«_Ð<Ü×Ñ¤ H£× 3Ñ 3Ó 5× BÑ BÀ5Ó IÓJ€Eß$)Œ5�—‘˜Q“Ó Ð3¨tÐ3r   c               ó    € V ^8„  d   QhRRRR/# )r   rF   rG   r   úbool | Noner   )r   s   "r   r   r     s   € ÷ Añ A˜#ð A°Kñ Ar   c                ó†   €  \        V 4      p \        T \	        T4      \        4       4      #   \        \        3 d     R# i ; i)uÁ  THE one incarnation rule (A7 rule 4) for every Python identity reader (marker, pause record).

An identity is (pid, creation time). ``True``: that process is running. ``False``: no such
process, a different incarnation of the pid, or a claim naming OUR pid that is not us â€” our
own pid is ours only within :data:`_OWN_CREATE_TIME_EPSILON` of our creation time, and a
claim without a creation time naming our pid is a previous incarnation (a fresh pid
namespace hands a killed update's pid to the next launch) â€” unless our own creation time is
unreadable: then we write no-ct claims ourselves, so a no-ct claim is ours and a ct one is
not (``marker.rs`` agrees). ``None``: alive but unprovable â€” no creation time recorded, or
the live one unreadable (Windows denies elevated/other-user pids); each caller applies its
own bound (the marker: the v1 age ceiling, :func:`_identity_live`).

``recorded_ct`` is a float or the marker spelling ``"ct:<seconds>"``.
F)rG   Ú	TypeErrorrª   Ú_incarnationrÒ   Ú_real_world)rF   Úrecorded_cts   &&r   Úincarnation_liverÚ     sA   € ðÜ�#‹hˆô ˜œV KÓ0´+³-Ó@Ð@øô ”zÐ"ô Úðús   ‚+ «A ¿A T)Úfrozenc                  óN   € ] tR tRt$ RtR]R&   R]R&   R]R&   R	]R
&   R	]R&   RtR# )Ú_Worldi  z�What a marker verdict depends on besides the bytes: us, the clock, the process table.
Production uses :func:`_real_world`; the shared corpus injects a table.rG   rF   rx   rÂ   r¤   ÚnowÚobjectÚaliveÚct_ofr   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r   r   r   rÝ   rÝ     s$   ‡ ñOð 
ƒHØÓØ	ƒJØƒMØ‡Mr   rÝ   c               ó   € V ^8„  d   QhRR/# )r   r   rÝ   r   )r   s   "r   r   r   #  s   € ÷ añ a�Vñ ar   c                 óŒ   € \        \        P                  ! 4       \        4       \        P                  ! 4       \
        \        4      # r@   )rÝ   r   r¸   rÆ   r§   rP   r½   r   r   r   rØ   rØ   #  s&   € Ü”"—)’)“+Ô/Ó1´4·9²9³;Ä
ÔL_Ó`Ð`r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rF   rG   rÐ   rx   ÚwrÝ   r   rÔ   r   )r   s   "r   r   r   '  s.   € ÷ _ñ _�cð _ \ð _°fð _Àñ _r   c                óÔ  € V ^ 8:  d   R# WP                   8X  dƒ   VP                  f   VRJ # Vf   R# \        VP                  V,
          4      \        8:  d   R# VP	                  4       ;'       d,    ^ VP                  V,
          u;8*  ;'       d
    \
        8  # u # VP                  V 4      '       g   R# Vf   RMVP                  V 4      pVf   R# \        W1,
          4      \        8*  # )z-:func:`incarnation_live` against world ``w``.FNT)	rF   rÂ   ÚabsÚ_OWN_CREATE_TIME_EPSILONÚ
is_integerÚ_WHOLE_SECOND_CTrà   rá   ÚCREATE_TIME_TOLERANCE_SECONDS)rF   rÐ   rì   Úactuals   &&& r   r×   r×   '  s¿   € à
ˆa„xÙØ
�e‰e„|Ø�4‰4Š<Ø˜tÐ#Ð#ØÒÙÜˆq�t‰t�h�ÓÔ#;Ô;ÙØ×"Ñ"Ó$×PÐP¨¨a¯d©d°X­o×)PÔ)PÔ@PÑ)PÐPÑ)PÐPØ�7‰7�3�<Š<ÙØÒ%‰T¨1¯7©7°3«<€FØ’>ˆ4Ð^¤s¨6Õ+<Ó'=ÔA^Ñ'^Ð^r   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   rF   rG   r»   rx   Úager¤   Úworldú_World | Noner   rH   r   )r   s   "r   r   r   9  s7   € ÷ Pñ P˜ð P¨,ð P¸Uð PÈ=ð PÐdhñ Pr   c                ó\   € \        YT;'       g    \        4       4      pVf
   V\        8*  # T# )zýC1 rule 3 + A1 + A7 rule 4 for one (pid, ct) identity of a marker ``age`` seconds old:
:func:`incarnation_live`, where an unprovable identity (a v1 marker, or a creation time we
cannot read) may be a reused pid, so only the legacy age ceiling bounds it.)r×   rØ   ÚUPDATE_MARKER_MAX_AGE_SECONDS)rF   r»   rõ   rö   Úverdicts   &&&& r   Ú_identity_liverû   9  s/   € ô ˜3¨U×-CÐ-C´k³mÓD€GØ3:²?ˆ3Ô/Ñ/ÐOÈÐOr   c               ó    € V ^8„  d   QhRRRR/# )r   rF   rh   r   r¡   r   )r   s   "r   r   r   A  s   € ÷ 0ñ 0˜
ð 0¨cñ 0r   c                ó0   € \        V 4      pVf   R# RVR 2# )NÚ rÊ   z.3f)r½   rÁ   s   & r   Ú_identity_linerÿ   A  s#   € Ü	˜SÓ	!€BØ’ˆ2Ð/ 3 r¨# h Ð/r   c               ó   € V ^8„  d   QhRR/# )r   r   rh   r   )r   s   "r   r   r   I  s   € ÷ $ñ $�jñ $r   c                 ó´   €  \        \        P                  P                  \        R4      P                  4       4      p T ^ 8”  d   T # R#   \         d     R# i ; i)z¢Pid of the orchestrating updater that spawned us (:data:`HANDOFF_PID_ENV`); malformed
values count as absent so a broken handoff falls back to the normal refusal.rþ   N)rG   r   r   r   ÚHANDOFF_PID_ENVr1   rª   rÅ   s    r   Ú_handoff_pidr  I  sP   € ðÜ”"—*‘*—.‘.¤°"Ó5×;Ñ;Ó=Ó>ˆð ˜”'ˆ3Ð#˜tÐ#øô ô Úðús   ‚;A ÁAÁAc               ó    € V ^8„  d   QhRRRR/# rg   r   )r   s   "r   r   r   S  s   € ÷ -ñ -˜Sð - Zñ -r   c                óÖ  a
a€ ^ RI o
^ RI Ho  ! V
V3R lRS
P                  4      p\        4       pSP                  SP                  .VP
                  n        SP                  VP
                  n        VP                  VP                  3 F6  pSP                  S
P                  V4      .Vn        SP                  Vn        K8  	  VP                  ^^ 4      pV'       d!   VS
P                  R4      P                  8X  d   R# Rp V! 4       pS
P                  V4      Vn        VP                  VS
P#                  V4      4      pV'       dK   VP$                  V 8X  d   \'        VP(                  4      pM#VP                  VS
P#                  V4      4      pKR  VP+                  V4       V'       g   R# \-        V4      \-        V 4      r˜Ve   V	e	   W‰8”  d   R# V#   TP+                  T4       i ; i)zåThe parent of ``pid`` from a Toolhelp32 process snapshot (stdlib ctypes).

Windows keeps a dead parent's pid in the snapshot and reuses pids, so, like
psutil, a "parent" created after the child is a recycled pid, not our parent.
NrT   c                  óB  <€ ] tR tRtR ZP                  3R ZP                  3R ZP                  3R Z P
                  3R ZP                  3R ZP                  3R ZP                  3R	 Z P                  3R
 ZP                  3R Z P                  R,          3.
tRt	R# )Ú,_windows_parent_pid.<locals>.PROCESSENTRY32Wi\  ÚdwSizeÚcntUsageÚth32ProcessIDÚth32DefaultHeapIDÚth32ModuleIDÚ
cntThreadsÚth32ParentProcessIDÚpcPriClassBaseÚdwFlagsÚ	szExeFilei  r   N)
râ   rã   rä   rå   r[   Úc_size_tÚc_longÚc_wcharÚ_fields_rè   ©rY   rU   s   €€r   ÚPROCESSENTRY32Wr  \  s„   ø† à‘x—~‘~Ð&¨±X·^±^Ð(DØ™hŸn™nÐ-Ð0CÁVÇ_Á_Ð/UØ™XŸ^™^Ð,¨|¹X¿^¹^Ð.LØ"¡H§N¡NÐ3Ð6FÉÏÉÐ5VØ™Ÿ™Ð'¨+±v·~±~ÈÕ7KÐ)Lð
Œr   r  éÿÿÿÿ)rY   rU   Ú	Structurere   r[   ÚCreateToolhelp32Snapshotr^   r_   r`   ÚProcess32FirstWÚProcess32NextWra   r\   Úc_void_pÚvalueÚsizeofr  rk   r
  rG   r  rd   rv   )rF   r  rV   ÚwalkÚsnapshotr   ÚentryÚfoundÚparent_createdÚchild_createdrY   rU   s   &         @@r   Ú_windows_parent_pidr&  S  s–  ù€ ó Ý÷
ð 
˜&×*Ñ*ô 
ô !Ó"€HØ2:·.±.À(Ç.Á.Ð1Q€H×%Ñ%Ô.Ø08·±€H×%Ñ%Ô-Ø×)Ñ)¨8×+BÑ+BÓCˆØ!Ÿ™¨&¯.©.¸Ó*IÐJˆŒØ—}‘}ˆŽñ Dð ×0Ñ0°°aÓ8€Hß�x 6§?¡?°2Ó#6×#<Ñ#<Ô<ÙØ€Fð
'ÙÓ!ˆØ—}‘} _Ó5ˆŒØ×(Ñ(¨°6·<±<ÀÓ3FÓGˆßØ×"Ñ" cÔ)Ü˜U×6Ñ6Ó7�ØØ×+Ñ+¨H°f·l±lÀ5Ó6IÓJŠEà×Ñ˜XÔ&ßÙÜ$<¸VÓ$DÔF^Ð_bÓFc�MØÒ! mÒ&?ÀNÔDbÙØ€Møð 	×Ñ˜XÕ&ús   ÄAG Å	A
G ÇG(c               ó    € V ^8„  d   QhRRRR/# rg   r   )r   s   "r   r   r   ƒ  s   € ÷ !ñ !˜Cð ! Jñ !r   c                ó*  € \         P                  R8X  d    \        V 4      #  \        P                  P                  R4      '       d3   \        RV  R2R4      ;_uu_ 4       pVP                  4       pRRR4       Mr\        P                  ! RRR	R
\        V 4      .RRRRR^\        P                  R7      P                  p\!        VP#                  4       ;'       g    R4      pV^ 8”  d   V# R#  \!        XVP'                  R4      ^,           R P)                  4       ^,          4      #   \        \        \
        3 d     R# i ; i  + '       g   i     Lg; i  \        \
        \        P$                  3 d     R# i ; i  \
        \*        3 d     R# i ; i)u´  The parent of ``pid`` without psutil, or ``None`` when unresolvable.

The update-takeover child is spawned ``-I -S -B`` (hermes_cli/_old_updater.py) so
psutil cannot import there â€” and that grandchild is exactly the process that most
needs the two-hop ancestry walk to adopt the orchestrator's marker. /proc serves
Linux; macOS keeps /proc absent, so shell out to ps once per hop; Windows has
neither, so ask the Toolhelp32 snapshot.
rz   Nr{   r|   r}   r~   r…   r†   zppid=r‡   Trˆ   r‰   )r�   r9   r,   r�   r”   r‘   r’   r   r  )r–   r—   r&  r4   r®   rª   r   r5   r™   rš   r›   rŸ   r    r¡   r¢   r£   rG   r1   r­   rœ   r�   r«   )rF   r°   r±   r´   r  s   &    r   Ú_stdlib_parent_pidr)  ƒ  sb  € ô ‡|�|�wÔð	Ü& sÓ+Ð+ðÜ�7‰7�=‰=˜×!Ò!Ü˜˜s˜e 5Ð)¨4×0Ô0°BØ—w‘w“y�÷ 1Ð0ô —.’.Ø�t˜W d¬C°«HÐ5Ø#¨$¸ÈÐZ^ÐhiÜ ×(Ñ(ô÷ ‰fð	 ô
 ˜Ÿ	™	›×)Ð) rÓ*ˆEØ! AœI�5Ð/¨4Ð/ð
Ü�4˜Ÿ™ DÓ)¨AÕ-Ð.Ð/×5Ñ5Ó7¸Õ:Ó;Ð;øô' œ¬Ð4ô 	Úð	ú÷ 1×0ûô ”Z¤×!;Ñ!;Ð<ô Úðûô œ
Ð#ô Úðúsk   —
D& £$E ÁE Á EÁ1E Á:AE ÃE Ã*E Ã-8E= Ä&E Ä?E ÅE	ÅE ÅE Å E:Å9E:Å=FÆFc               ó    € V ^8„  d   QhRRRR/# rE   r   )r   s   "r   r   r   §  s   € ÷ Añ A˜#ð A $ñ Ar   c                óÆ  € V ^ 8:  d   R# V \         P                  ! 4       8X  d   R#  ^ RIpVP                  4       pVP                  0p\        \        4       F_  pVP                  4       pVf    R# VP                  V 8X  d    R# VP                  V9   d    R# VP                  VP                  4       TpKa  	  \        P                  RV \        4       R#   \         dU    \         P                  ! 4       p\        ^ 4       F,  p\        T4      pTf     R# YP8X  d     R# YV8X  d     R# TpK.  	   R# \         d"   p\        P                  RY4        Rp?R# Rp?ii ; i)uø  True when ``pid`` is a live ancestor of this process.

The orchestrating updater spawns ``hermes update`` as a (grand)child, so a live marker
owned by one of our ancestors can only be the claim we are already running under â€” an
unrelated concurrent updater is never in our parent chain. This heals the fleet of staged
``hermes-setup`` binaries that predate the HANDOFF_PID_ENV export and can never send it.

The chain is walked one link at a time and each ancestor is tested as it is
discovered. ``psutil.Process.parents()`` cannot be used here: it builds the
whole chain up to the lowest pid *before* returning, and its per-link
``parent()`` tolerates only ``NoSuchProcess``. So any process we may not
inspect anywhere above us raises ``AccessDenied`` and discards the
ancestors already collected â€” including the orchestrator one link down.
That is not exotic: under firejail with ``ptrace_scope=1``, and in hardened
containers, ``/proc/1`` is unreadable, so the GUI update deadlocked against
its own parent on every attempt. Walking incrementally means a failure
*above* the match can no longer hide it.

Never includes our own pid, and any failure encountered before a match
counts as "not an ancestor": an unprovable ancestry must fall back to the
normal refusal.
FTNz:Gave up walking process ancestry for pid %s after %s linksz.Could not walk process ancestry for pid %s: %s)r   Úgetppidr¹   rº   rF   rp   Ú_MAX_ANCESTRY_DEPTHr   ÚaddrM   rN   r   r¸   r)  rL   )rF   r¹   ÚprocÚseenrt   r   ÚchildrO   s   &       r   Ú_is_ancestor_pidr2  §  s!  € ð. ˆa„xÙØ
Œb�jŠj‹lÔÙð&Ûà�~‰~ÓˆØ—‘ˆzˆÜÔ*Ö+ˆAØ—[‘[“]ˆFØŠ~ÚØ�z‰z˜SÔ ÚØ�z‰z˜TÔ!ò Ø�H‰H�V—Z‘ZÔ ØŠDñ ,ô 	�‰ØHØÜô	
ñ
 øÜô ä—	’	“ˆÜ�r–ˆAÜ'¨Ó.ˆFØŠ~ÛØŒ}ÛØŒÛØŠEñ ò Üô Ü�‰ÐEÀsÔPÝûðúsH   §AC Á1C ÂC Â<C Ã>E ÄE Ä"E Ä,E Ä5E Ä>E Ä?EÅE c               ó    € V ^8„  d   QhRRRR/# )r   Úcmdlinez	list[str]r   rH   r   )r   s   "r   r   r   ë  s   € ÷ nñ n˜ið n¨Dñ nr   c                ór   € ^ RI Hp ^ RIHp RP	                  V 4      pV! V4      ;'       g    V! V4      R9   # )z°A long-lived Hermes host (``gateway run`` / ``serve`` / ``dashboard``), by the canonical
command-line matchers (profile flags, ``hermes_cli/main.py`` paths, inline bootstraps).)Úlooks_like_gateway_command_line)Ú_hermes_holder_subcommandr•   )ÚserveÚ	dashboard)Úgateway.statusr6  Úhermes_cli.update_cmd_windowsr7  r©   )r4  r6  r7  r‚   s   &   r   Ú_is_runtime_hostr<  ë  s7   € õ ?ÝGØ�8‰8�GÓ€DÙ*¨4Ó0×mÐmÑ4MÈdÓ4SÐWmÑ4mÐmr   c               ó    € V ^8„  d   QhRRRR/# )r   Ú
holder_pidrG   r   rH   r   )r   s   "r   r   r   ô  s   € ÷ ñ  Cð ¨Dñ r   c                óè  €  ^ RI p TP                  4       P                  4       p\	        \
        4       F}  pTe   TP                  T 8X  d    R# \        TP                  4      ;_uu_ 4        \        TP                  4       4      '       d    RRR4        R#  RRR4       TP                  4       pK  	  R#   \         d     R# i ; i  + '       g   i     L8; i  TP                   d     R# i ; i)u˜  True when a Hermes gateway/serve/dashboard sits between us and *holder_pid* (or anywhere
above us when the holder is not reached).

Such a host is relaunched BY an update and outlives its stages; a ``hermes update`` its agent
or ``/update`` starts is an independent update that must not run under the first one's claim
(cli Â§7 V9). Unreadable command lines count as not-a-host (the legacy adoption stands).
NFT)r¹   r   rº   r   rp   r-  rF   r   ÚErrorr<  r4  )r>  r¹   r/  rt   s   &   r   Ú_runtime_host_belowrA  ô  sÀ   € ðÛð
Ø�~‰~Ó×&Ñ&Ó(ˆÜÔ*Ö+ˆAØŠ|˜tŸx™x¨:Ô5ÚÜ˜&Ÿ,™,×'Õ'Ü# D§L¡L£N×3Ò3Ø÷ (Ò'Ø3÷ (ð —;‘;“=ŠDñ ,ñ øô ô Úðú÷ (×'ûð �<‰<ô ÚðúsG   ‚B7 ‡AC ÁC Á,!C	Â	C ÂC Â7CÃCÃ	CÃC ÃC1Ã0C1c                  óL   € ] tR tRt$ RtR]R&   R]R&   RtR]R	&   R
tR]R&   RtR# )ÚUpdateHolderi  u%  A confirmed-live update holding the lock, or the reason a claim was refused.

``held``: the marker's identities are dead but the checkout kernel lock is still held (a
killed updater's completion/build child or git still runs) â€” the update is NOT over; the
hand-off scripts' ``held`` verdict.rG   rF   r¤   Úage_secondsNú
str | NoneÚreasonFrH   Úheldr   )	râ   rã   rä   rå   ræ   rç   rF  rG  rè   r   r   r   rC  rC    s(   ‡ ñ+ð 
ƒHØÓØ€FˆJÓØ€Dˆ$×r   rC  l   ÿÿ l   ÿÿÿÿ z[0-9]+z[0-9]+(?:\.[0-9]+)?zct:([0-9]+(?:\.[0-9]+)?)z*delegate:([0-9]+) ct:([0-9]+(?:\.[0-9]+)?)zrun:([A-Za-z0-9._-]{1,128})c                  ó  € ] tR tRt$ R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   RtR]R&   RtR]R&   RtR]R&   R#tR]R&   ]	R R l4       t
]	R R l4       tR$R R lltR$R R lltR$R R lltR$R R  lltR! R" ltR#tR# )%Ú_Markeri(  ÚbytesÚrawrG   rF   rh   Ú
started_atrx   r»   Údelegate_pidÚdelegate_create_timeFrH   Ú	in_flightNrE  Úct_textÚdelegate_ct_textztuple[str, ...]Úrunsc               ó   € V ^8„  d   QhRR/# )r   r   rJ  r   )r   s   "r   r   Ú_Marker.__annotate__6  s   € ÷ @ñ @�eñ @r   c                óf   € RP                  V P                  P                  RR7      R,          4      # )uF   Lines 1â€“3 exactly as written (what a delegate keeps byte-identical).r   T)Úkeepends:Né   N)r©   rK  Ú
splitlines©Úselfs   &r   ÚbaseÚ_Marker.base5  s*   € ð �x‰x˜Ÿ™×+Ñ+°TÐ+Ó:¸2Õ>Ó?Ð?r   c               ó   € V ^8„  d   QhRR/# )r   r   rE  r   )r   s   "r   r   rT  ;  s   € ÷ 3ñ 3�Zñ 3r   c                	óP   € V P                   '       d   V P                   ^ ,          # R# ©rS   N)rR  rY  s   &r   r    Ú_Marker.run:  s   € à#ŸyŸy˜yˆt�y‰y˜�|Ð2¨dÐ2r   c               ó    € V ^8„  d   QhRRRR/# )r   rö   r÷   r   r¤   r   )r   s   "r   r   rT  >  s   € ÷ Vñ V˜ð V°%ñ Vr   c                	ó¢   € Vf   \         P                   ! 4       MVP                  pV P                  e   W P                  ,
          # \        R4      # )NÚinf)r§   rÞ   rL  r¤   )rZ  rö   rÞ   s   && r   rõ   Ú_Marker.age>  s6   € Ø"š]Œd�iŠiŒk°·	±	ˆØ(,¯©Ò(Cˆs—_‘_Õ$ÐUÌÈuËÐUr   c               ó    € V ^8„  d   QhRRRR/# ©r   rö   r÷   r   rH   r   )r   s   "r   r   rT  B  s   € ÷ Sñ S ð S¸ñ Sr   c                	ó�   € V P                   R J;'       d2    \        V P                  V P                  V P	                  V4      V4      # r@   )rL  rû   rF   r»   rõ   ©rZ  rö   s   &&r   Ú
owner_liveÚ_Marker.owner_liveB  s@   € Ø�‰ dÐ*÷ Sð SÜ˜tŸx™x¨×)9Ñ)9¸4¿8¹8ÀE»?ÈEÓRð	Sr   c               ó    € V ^8„  d   QhRRRR/# rf  r   )r   s   "r   r   rT  F  s   € ÷ eñ e =ð e¸Dñ er   c                	ó¼   € V P                   R J;'       dH    V P                  R J;'       d2    \        V P                   V P                  V P	                  V4      V4      # r@   )rM  rL  rû   rN  rõ   rh  s   &&r   Údelegate_liveÚ_Marker.delegate_liveF  s]   € Ø× Ñ ¨Ð,÷ eð e°·±ÈÐ1L÷ eð eÜ˜t×0Ñ0°$×2KÑ2KÈTÏXÉXÐV[Ë_Ð^cÓdð	er   c               ó    € V ^8„  d   QhRRRR/# )r   rö   r÷   r   rh   r   )r   s   "r   r   rT  J  s   € ÷ Hñ H˜mð H°zñ Hr   c                	óº   € V P                   '       d   ^ # V P                  V4      '       d   V P                  # V P                  V4      '       d   V P                  # R# r_  )rO  ri  rF   rm  rM  rh  s   &&r   Úlive_pidÚ_Marker.live_pidJ  sG   € Ø�>�>ˆ>ÙØ�?‰?˜5×!Ò!Ø—8‘8ˆOØ$(×$6Ñ$6°u×$=Ò$=ˆt× Ñ ÐGÀ4ÐGr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rF   rG   rP  rE  r   rJ  r   )r   s   "r   r   rT  Q  s&   € ÷ Nñ N˜Sð N¨:ð N¸%ñ Nr   c                ó¾   € V RV P                    R2V'       d   RV R2MR,           pVRP                  R V P                   4       4      ,           P                  4       # )zVA rewritten claim (A7 rule 5): ``pid`` owns it from ``started_at`` on; run lines kept.Ú
rÊ   rþ   c              3  ó.   "  € T F  pR V R2x € K  	  R# 5i©zrun:ru  Nr   ©rl   r    s   & r   rn   Ú$_Marker.canonical.<locals>.<genexpr>T  s   é € ÐC¹°#  c U¨"�~»ùó   ‚)rL  r©   rR  Úencode)rZ  rF   rP  Úbodys   &&& r   Ú	canonicalÚ_Marker.canonicalQ  sS   € à��b˜Ÿ™Ð)¨Ð,ÇW°#°g°Y¸bÑ0AÐRTÕUˆØ�r—w‘wÑC¸¿ºÓCÓCÕC×KÑKÓMÐMr   r   r@   )râ   rã   rä   rå   rç   rO  rP  rQ  rR  Úpropertyr[  r    rõ   ri  rm  rq  r}  rè   r   r   r   rI  rI  (  s™   ‡ à	ƒJØ	ƒHØÓØÓØÓØ&Ó&Ø€IˆtÓØ€GˆZÓØ#'Ð�jÓ'Ø€Dˆ/Óàô@ó ð@ð ô3ó ð3÷V÷S÷e÷H÷Nñ Nr   rI  c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9   r¡   ÚlimitrG   r   rh   r   )r   s   "r   r   r   W  s!   € ÷ 
-ñ 
-�sð 
- 3ð 
-¨:ñ 
-r   c                óä   € \         P                  V 4      '       g   R# V P                  R4      ;'       g    Rp\        V4      \        \	        V4      4      8”  d   R# \        V4      pW18:  d   V# R# )u  ASCII digits whose value fits ``limit`` (u32 pid, u64 started_at â€” Rust's ``parse``), else
None. Leading zeros are fine; the significant digits are counted BEFORE ``int()``, which
refuses past 4300 digits â€” an oversized field is malformed, never an exception.NÚ0)Ú	_INT_LINErÍ   Úlstripr3   r¡   rG   )r9   r�  Úsignificantr  s   &&  r   Ú_bounded_intr‡  W  s_   € ô ×Ñ˜t×$Ò$ÙØ—+‘+˜cÓ"×)Ð) c€KÜ
ˆ;Óœ#œc %›j›/Ô)ÙÜ�Ó€EØ”Nˆ5Ð,¨Ð,r   Úmtimec               ó$   € V ^8„  d   QhRRRRRR/# )r   rK  rJ  rˆ  rx   r   rI  r   )r   s   "r   r   r   d  s!   € ÷ ñ �uð ¨ð Àñ r   c               ó¤  € V P                  RRR7      P                  R4      pVP                  R4       Uu. uF"  q3P                  R4      P	                  R4      NK$  	  ppVR.^\        V4      ,
          ,          ,          p\        V^ ,          \        4      pVe   \        V^,          \        4      MR	pVf   RMTp\        P                  V^,          4      pR
 \        \        P                  VR,          4       4       p\        R V 4       R4      w  rš\        ;QJ d3    . R \        \        P                  VR,          4       4       F  NK  	  5M,! R \        \        P                  VR,          4       4       4      pV '       * ;'       d0    VR	J;'       d$    \         P                   ! 4       V,
          \"        8  p\%        YYg'       d   \'        VP)                  ^4      4      MR	T
V	'       d   \'        V	P)                  ^4      4      MR	TV'       d   VP)                  ^4      MR	V	'       d   V	P)                  ^4      VR7
      # R	VR7
      # u upi )uÎ  Contract A2 + A7 rule 7, identical in every reader (Rust ``marker.rs``, Electron, the
hand-off scripts; ``tests/fixtures/update_marker_corpus.json``): BOM, CRLF and surrounding
spaces/tabs tolerated; line 1 pid (u32) and line 2 started_at (u64) are integers or the marker is
MALFORMED (dead: ``started_at`` None); a bad line 3 makes it v1; lines 4+ are tagged â€” the
first well-formed ``delegate:<pid> ct:<ct>`` and every ``run:<id>`` â€” anything else ignored.rˆ   r‰   )r�   u   ï»¿ru  Úz 	rþ   Nc              3  óv   "  € T F/  q'       g   K  V\        VP                  ^4      \        4      3x € K1  	  R# 5i©r$   N)r‡  rÏ   Ú_U32_MAX©rl   Úms   & r   rn   Ú _parse_marker.<locals>.<genexpr>q  s,   é € ÐpÑBj¸QÓnoÔ8�!”\ !§'¡'¨!£*¬hÓ7Õ8ÓBjùs   ‚	9�)9:rW  NNc              3  ó8   "  € T F  w  rVf   K  W3x € K  	  R # 5ir@   r   )rl   r�  Úds   &  r   rn   r‘  r  s   é € Ð"Q±i©d¨aÀ1¤6 A¥6³iùs   ‚�c              3  óV   "  € T F  q'       g   K  VP                  ^4      x € K!  	  R# 5ir�  )rÏ   r�  s   & r   rn   r‘  s  s    é € ÐNÑ%H ËA”�—‘˜—�Ó%Hùs   ‚	)�))
rK  rF   rL  r»   rM  rN  rO  rP  rQ  rR  r  )NN)ÚdecoderÎ   r�   Úremovesuffixr1   r3   r‡  rŽ  Ú_U64_MAXÚ_CT_LINErÍ   ÚmapÚ_DELEGATE_LINEr�   ÚtupleÚ	_RUN_LINEr§   ÚEMPTY_MARKER_GRACE_SECONDSrI  r¤   rÏ   )rK  rˆ  r9   r‚   ÚlinesrF   rL  rÂ   Ú	delegatesÚdelegaterM  rR  rO  s   &$           r   Ú_parse_markerr¡  d  sÏ  € ð �:‰:�g iˆ:Ó0×=Ñ=¸hÓG€DØ>B¿j¹jÈÔ>NÓOÑ>N°d×Ñ˜tÓ$×*Ñ*¨5Ö1Ñ>N€EÐOØ	ˆbˆT�Qœ˜U›•^Õ$Õ$€EÜ
�u˜Q•x¤Ó
*€CØ58²_”˜e A�h¬Ô1È$€JØ’‰" €CÜ	×	Ñ	˜E !�HÓ	%€BÙpÄ#Än×F^ÑF^Ð`eÐfhÕ`iÔBjÓp€IÜ!Ñ"Q±iÓ"QÐS_Ó`Ñ€HßŒ5ÑN¤S¬×)<Ñ)<¸eÀB½iÔ%HÓN�5‰5ÑN¤S¬×)<Ñ)<¸eÀB½iÔ%HÓNÓN€DØ”×bÐb˜E¨Ð-×bÐb´$·)²)³+ÀÕ2EÔHbÑ2b€IÜØ ZÖSU¼UÀ2Ç8Á8ÈAÃ;Ô=OÐ[_Ø!ß9AœU 8§>¡>°!Ó#4Ô5ÀtÐW`ß!�—‘˜” t×S[¸h¿n¹nÈQÓ>OØôð ð bfØôð ùò Ps   ¶(Ic               ó$   € V ^8„  d   QhRRRRRR/# )r   rK  rJ  rö   r÷   r   z"tuple[str, int | None, str | None]r   )r   s   "r   r   r   ~  s"   € ÷ ;ñ ;�eð ; Mð ;Ð=_ñ ;r   c                ó°  € T;'       g    \        4       p\        V 4      pVP                  f   R# VP                  V4      pVf   RRVP                  3# VP
                  VP
                  8H  ;'       d    VP                  V4      ;'       g3    VP                  VP
                  8H  ;'       d    VP                  V4      pV'       d   RMRWCP                  3# )uú   ``(verdict, owner, run)`` of marker bytes â€” the shared corpus' judge contract.

verdict: ``malformed`` | ``dead`` | ``ours`` (a live identity is this incarnation) | ``live``;
owner: the owner identity if live, else the delegate if live, else None.
NÚdeadÚoursÚlive)Ú	malformedNN)	rØ   r¡  rL  rq  r    rF   ri  rM  rm  )rK  rö   rì   ÚmarkerÚownerr¥  s   &&    r   Újudge_markerrª  ~  s¿   € ð 	×Ð”“€AÜ˜3Ó€FØ×ÑÒ Ø&Ð&Ø�O‰O˜AÓ€EØ‚}Ø�t˜VŸZ™ZÐ'Ð'Ø�J‰J˜!Ÿ%™%Ñ×8Ð8 F×$5Ñ$5°aÓ$8÷ Fð FØ×Ñ 1§5¡5Ñ(×DÐD¨V×-AÑ-AÀ!Ó-Dð 	ç‰F ¨·
±
Ð:Ð:r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rK  rJ  rö   r÷   r   ztuple[str, bytes | None]r   )r   s   "r   r   r   �  s"   € ÷ ñ ˜5ð ¨ð ÐBZñ r   c                ój  € T;'       g    \        4       p\        V 4      pVP                  f   R# VP                  VP                  8X  dv   VP	                  V4      '       d_   VP
                  RVP                  39  d@   VP                  V4      '       d)   RVP                  VP
                  VP                  4      3# R# VP
                  VP                  8X  dY   VP                  V4      '       dB   VP	                  V4      '       d)   RVP                  VP                  VP                  4      3# R# R# )uª  A7 rule 5: what releasing ``world``'s claim does to marker bytes ``raw``.

``("delete", None)`` | ``("rewrite", new bytes)`` | ``("keep", None)``. The owner (line 1â€“3
identity is our incarnation) deletes â€” regardless of delegate lines â€” unless a live delegate
other than us exists: then that delegate becomes the owner. A delegate (us) drops its line
while the owner lives, else deletes. Anything not naming us is kept.
NÚrewrite)ÚkeepN)ÚdeleteN)
rØ   r¡  rL  rF   ri  rM  rm  r}  rQ  rP  )rK  rö   rì   r¨  s   &&  r   Ú_release_decisionr°  �  sþ   € ð 	×Ð”“€AÜ˜3Ó€FØ×ÑÒ ØÐØ‡z�z�Q—U‘UÔ˜v×0Ñ0°×3Ò3Ø×Ñ t¨Q¯U©U mÔ3¸×8LÑ8LÈQ×8OÒ8OØ˜f×.Ñ.¨v×/BÑ/BÀF×D[ÑD[Ó\Ð\Ð\ØÐØ×Ñ˜aŸe™eÔ#¨×(<Ñ(<¸Q×(?Ò(?Ø×Ñ˜Q×ÒØ˜f×.Ñ.¨v¯z©z¸6¿>¹>ÓJÐJÐJØÐØÐr   c               ó    € V ^8„  d   QhRRRR/# )r   r5   r   r   zbytes | Noner   )r   s   "r   r   r   §  s   € ÷ ñ �dð ˜|ñ r   c                óH   €  V P                  4       #   \         d     R # i ; ir@   )Ú
read_bytesr4   ©r5   s   &r   Ú_read_bytesrµ  §  s&   € ðØ�‰Ó Ð øÜô Úðús   ‚ ’! !c               ó    € V ^8„  d   QhRRRR/# )r   r5   r   r   z_Marker | Noner   )r   s   "r   r   r   ®  s   € ÷ +ñ +�tð + ñ +r   c                óê   € \        V 4      pVf   R # R pV'       g;   \        \        4      ;_uu_ 4        V P                  4       P                  pR R R 4       \        WR7      #   + '       g   i     L; i)N)rˆ  )rµ  r   r4   r±   Úst_mtimer¡  )r5   rK  rˆ  s   &  r   Ú_read_markerr¹  ®  sQ   € Ü
�dÓ
€CØ
‚{ÙØ€EßÜ”g×ÕØ—I‘I“K×(Ñ(ˆE÷ ä˜Ô*Ð*÷ ×ús   ³A"Á"A2	c               ó    € V ^8„  d   QhRRRR/# ©r   r5   r   r   r   )r   s   "r   r   r   ¹  s   € ÷ Sñ S�tð S ñ Sr   c           	     ó˜   € V P                  V P                   R \        P                  ! 4        R \        P
                  ! ^4       R24      # )Ú.ú.tmp)Ú	with_namer   r   r¸   ÚsecretsÚ	token_hexr´  s   &r   Ú_tmp_siblingrÂ  ¹  s:   € Ø�>‰>˜TŸY™Y˜K q¬¯ª«¨°Q´w×7HÒ7HÈÓ7KÐ6LÈDÐQÓRÐRr   g      N@c               ó$   € V ^8„  d   QhRRRRRR/# )r   r©  rh   r"  r   r   rH   r   )r   s   "r   r   r   Â  s&   € ÷ Kñ K˜Jð K¨tð K¸ñ Kr   c                óØ   € V f   R# V \         P                  ! 4       8w  d   \        V 4      '       * # \        P                  ! 4       VP	                  4       P
                  ,
          \        8„  # )NT)r   r¸   rP   r§   r±   r¸  ÚOWN_PID_TMP_STALE_SECONDS)r©  r"  s   &&r   Ú_tmp_writer_gonerÆ  Â  sI   € Ø‚}ÙØ”—	’	“ÔÜ˜eÓ$Ô$Ð$Ü�9Š9‹;˜Ÿ™›×.Ñ.Õ.Ô1JÑJÐJr   c               ó    € V ^8„  d   QhRRRR/# ©r   r5   r   r   ÚNoner   )r   s   "r   r   r   Ê  s   € ÷ #ñ # 4ð #¨Dñ #r   c                óŽ  € V P                    R2p\        \        4      ;_uu_ 4        V P                  P	                  4        FÏ  pVP                   pV\        V4      R P                  R^4      ^ ,          pVP                  V4      '       d3   VP                  R4      '       d   \        P                  V4      '       g   K  \        \        4      ;_uu_ 4        \        \        V\        4      V4      '       d   VP                  4        RRR4       KÑ  	  RRR4       R#   + '       g   i     Kî  ; i  + '       g   i     R# ; i)z Reclaim ``<marker>.<pid>[.<token>].tmp`` files whose writer died between write and
publish (contract m10): the pid is the first component after the marker name.r½  Nr¾  )r   r   r4   r   Úiterdirr3   r�   r2   Úendswithr„  rÍ   rÆ  r‡  rŽ  Úunlink)r5   Úprefixr"  r   r©  s   &    r   Ú_sweep_dead_tmp_siblingsrÏ  Ê  sá   € ð —	‘	ˆ{˜!ˆ_€FÜ	”'×	Õ	Ø—[‘[×(Ñ(Ö*ˆEØ—:‘:ˆDØœ˜V›˜Ð&×,Ñ,¨S°!Ó4°QÕ7ˆEØ—O‘O F×+Ò+°·±¸f×0EÒ0EÌ)×J]ÑJ]Ð^c×JdÒJdÙÜœ'×"Õ"Ü#¤L°¼Ó$AÀ5×IÒIØ—L‘L”N÷ #Ñ"ñ +÷ 
Ñ	÷ #×"Ð"ú÷ 
×	Ð	ús0   §A<D3Â$D3Â?D3Ã1DÄ	D3ÄD0Ä*	D3Ä3E	z.lockg      $@c                  ó   € ] tR tRtRtRtR# )Ú
MarkerBusyià  zJThe marker mutex stayed held past :data:`MUTEX_WAIT_SECONDS`: report busy.r   N)râ   rã   rä   rå   ræ   rè   r   r   r   rÑ  rÑ  à  s   † ÝTr   rÑ  c               ó    € V ^8„  d   QhRRRR/# r»  r   )r   s   "r   r   r   ç  s   € ÷ 4ñ 4˜Dð 4 Tñ 4r   c                óN   € V P                  V P                  \        ,           4      # )z�``<marker>.lock``: the sidecar every marker MUTATION holds a kernel lock on. Never deleted
(deleting it would split the lock across two inodes).)r¿  r   ÚMUTEX_SUFFIXr´  s   &r   Úmarker_mutex_pathrÕ  ç  s   € ð �>‰>˜$Ÿ)™)¤lÕ2Ó3Ð3r   c               ó   € V ^8„  d   QhRR/# )r   r5   r   r   )r   s   "r   r   r   í  s   € ÷ !ñ ! $ñ !r   c           
     óF  € ^ RI p^ RI Hp VP                  RRR7      pVP                  VP                  VP                  VP
                  VP                  VP                  VP                  .VP                  n        VP                  VP                  n	        VP                  R4      P                  pR FZ  w  rVVP                  \        V 4      V^ RV^€R4      pV'       d   Wt8w  d   Vu # VP                  4       pV^ 8X  d    R# V^8w  g   KZ   M	  VP                  X4      h)z¯The Windows sidecar mutex: the file opened with NO sharing (``FileShare.None`` in the
PowerShell scripts, ``share_mode(0)`` in marker.rs). ``None`` = someone else has it open.NrT   rV   TrW   r  ))l        é   )l        rW  )rY   rU   rZ   ÚLPCWSTRr[   r  r_   ÚCreateFileWr^   r`   r  r¡   Úget_last_errorÚWinError)	r5   rY   rU   rV   ÚinvalidÚaccessÚdispositionrs   Úerrors	   &        r   Ú_windows_open_exclusiverá  í  só   € ó Ýà�}‰}˜Z¸ˆ}Ó=€HØ%-×%5Ñ%5°x·~±~ÀxÇ~Á~ÐW]×WfÑWfØ%-§^¡^°X·^±^ÀXÇ_Á_ð%V€H×ÑÔ!à#+§?¡?€H×ÑÔ Ø�o‰o˜bÓ!×'Ñ'€GÛAÑˆØ×%Ñ%¤c¨$£i°¸¸DÀ+ÈtÐUYÓZˆß�fÔ'ØŠMØ×%Ñ%Ó'ˆØ�BŒ;ÚØ�AŽ:Ùñ  Bð �/‰/˜%Ó
 Ð r   c               ó   € V ^8„  d   QhRR/# ©r   r   rÉ  r   )r   s   "r   r   r     s   € ÷ 2ñ 2˜dñ 2r   c                óN   € ^ RI pVP                  R4      P                  V 4       R# )rS   NrV   )rY   rZ   rd   )rs   rY   s   & r   Ú_windows_closerå    s   € Ûà
‡M�M�*Ó×)Ñ)¨&Ö1r   c               ó    € V ^8„  d   QhRRRR/# ©r   r5   r   Úwaitr¤   r   )r   s   "r   r   r   
  s   € ÷ ñ ˜ð  Uñ r   c                óD  € \         P                  ! 4       V,           p\        P                  R 8X  dS    \	        V 4      pVe   V# \         P                  ! 4       V8¼  d   \        V  R24      h\         P                  ! R4       KR  ^ RIp \        P                  ! V \        P                  \        P                  ,          R4      p   VP                  WTP                  VP                   ,          4       V#   \         d)    \        P                  ! T \        P                  4      p Lci ; i  \"         dD    \         P                  ! 4       T8¼  d   \        T  R24      Rh\         P                  ! R4        K³  i ; i  \$         d    \        P&                  ! T4       h i ; i)rz   Nz is held by another updateç{®Gáz”?é¤  )r§   Ú	monotonicr–   r—   rá  rÑ  ÚsleepÚfcntlr   rš   ÚO_RDWRÚO_CREATÚPermissionErrorÚO_RDONLYÚflockÚLOCK_EXÚLOCK_NBÚBlockingIOErrorÚBaseExceptionÚclose)r5   rè  Údeadliners   rî  Úfds   &&    r   Ú_mutex_acquirerû  
  s:  € Ü�~Š~Ó $Õ&€HÜ
‡|�|�wÔØÜ,¨TÓ2ˆFØÒ!Ø�Ü�~Š~Ó 8Ô+Ü  D 6Ð)CÐ!DÓEÐEÜ�JŠJ�tÖÛð(Ü�WŠW�Tœ2Ÿ9™9¤r§z¡zÕ1°5Ó9ˆðØð!Ø—‘˜B§¡°·±Õ =Ô>Ø�	øô ô (Ü�WŠW�Tœ2Ÿ;™;Ó'Šð(ûô #ô !Ü—>’>Ó# xÔ/Ü$¨ vÐ-GÐ%HÓIÈtÐSÜ—
’
˜4× ð!ûô ô Ü
�Š�ŒØðús=   Â	;C5 ÃE< Ã-D+ Ã50D(Ä'D(Ä+A
E9Å5E< Å8E9Å9E< Å<#Frè  c               ó    € V ^8„  d   QhRRRR/# rç  r   )r   s   "r   r   r   )  s   € ÷ ñ �tð  eñ r   c             #  ó¤  "  € \        \        V 4      4      p\        \        RR4      pVf   / ;p\        n        VP                  V4      '       d0   W2;;,          ^,          uu&    Rx € W2;;,          ^,          uu&   R# \        \        V4      V4      p^W2&    Rx € VP                  VR4       \        P                  R8X  d   \        V4       R# \        P                  ! V4       R#   Y2;;,          ^,          uu&   i ; i  TP                  TR4       \        P                  R8X  d   \        T4       i \        P                  ! T4       i ; i5i)u  Hold the kernel lock on ``<marker>.lock`` (A7 rule 1): read â†’ judge â†’ mutate of the marker
at ``path`` happens entirely inside. Re-entrant per thread; the kernel releases it if we die.
Raises :class:`MarkerBusy` after ``wait`` seconds, ``OSError`` when it cannot be opened.ÚkeysNrz   )r¡   rÕ  ÚgetattrÚ_MUTEX_HELDrþ  r   rû  r   Úpopr–   r—   rå  r   rø  )r5   rè  ÚkeyrG  rs   s   &$   r   Úmarker_mutexr  (  sñ   é € ô
 Ô Ó%Ó
&€CÜ”; ¨Ó-€DØ‚|Ø"$Ð$ˆŒ{ÔØ‡x�x�‡}‚}Ø�	�Q�‹	ð	Ûà�I˜�N‹IÙÜœD ›I tÓ,€FØ€D�IðÛà�‰��dÔÜ�<‰<˜7Ô"Ü˜6Ö"ä�HŠH�VÖøð �I˜�NŒIûð 	�‰��dÔÜ�<‰<˜7Ô"Ü˜6Õ"ä�HŠH�VÕüs>   ‚AEÁEÁ%C) Á)/EÂD ÂAEÃ)C?Ã?EÄAEÅEc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r5   r   ÚexpectedrJ  Únewr   rH   r   )r   s   "r   r   r   D  s(   € ÷ ñ ˜Dð ¨Eð ¸ð À$ñ r   c                óØ  € \        V 4      ;_uu_ 4        \        V 4      V8w  d    RRR4       R# \        V 4      p \        VR4      ;_uu_ 4       pVP	                  V4       VP                  4        \        P                  ! VP                  4       4       RRR4       \        P                  ! W04        \        \        4      ;_uu_ 4        VP                  4        RRR4       RRR4       R#   + '       g   i     La; i  + '       g   i     L-; i  \         dn   p\        P                  RY4        Rp?\        \        4      ;_uu_ 4        TP                  4        RRR4       M  + '       g   i     M; iRRR4       R# Rp?ii ; i  \        \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; i; i  + '       g   i     R# ; i)zrAtomically replace ``path`` (tmp + ``os.replace``) only while it still holds ``expected``,
under the marker mutex.NFÚwbTz&Could not rewrite update marker %s: %s)r  rµ  rÂ  rš   ÚwriteÚflushr   ÚfsyncÚfilenor‰   r   r4   rÍ  rM   rN   )r5   r  r  Útmpr°   rO   s   &&&   r   Ú_compare_and_swapr  D  s4  € ô 
�d×	Õ	Ü�tÓ Ô(Ø÷ 
Ñ	ô ˜4Ó ˆð	Ü�c˜4—” BØ—‘˜”Ø—‘”
Ü—’˜Ÿ™›Ô%÷ !ô �JŠJ�sÔ!Øô
 œ'×"Õ"Ø—
‘
”÷ #÷ 
Ñ	÷
 !—ú÷ #×"ûô	 ô 	Ü�L‰LÐAÀ4ÔMÛäœ'×"Õ"Ø—
‘
”÷ #×"×"Ð"ú÷ 
Ñ	ûð	ûô œ'×"Õ"Ø—
‘
”÷ #×"×"Ð"ý÷ 
×	Ð	ús¬   ”G°G¼DÁAC/	ÂDÂ5GÃD	ÃGÃ/C?Ã:DÄDÄGÄFÄ FÄ6FÄ:GÅE+	Å"	GÅ+E;Å6GÆFÆFÆGÆ(GÆ9	GÇGÇGÇGÇG)	c               ó    € V ^8„  d   QhRRRR/# )r   r¨  rI  r   z	list[int]r   )r   s   "r   r   r   Z  s   € ÷ 
ñ 
˜7ð 
 yñ 
r   c                óø   € V P                   '       d   ^ .# . pV P                  4       '       d   VP                  V P                  4       V P	                  4       '       d   VP                  V P
                  4       V# )z©Live identities behind a marker: the owner, then the delegate (``[0]`` for a claim
still being written). A claim naming our own pid counts only at our exact incarnation.)rO  ri  ÚappendrF   rm  rM  )r¨  Úpartnerss   & r   Ú_live_partnersr  Z  sa   € ð ××ÐØˆsˆ
Ø€HØ×Ñ×ÒØ�‰˜Ÿ
™
Ô#Ø×Ñ×ÒØ�‰˜×+Ñ+Ô,Ø€Or   r5   r=   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r5   r*   r=   r>   r   úUpdateHolder | Noner   )r   s   "r   r   r   g  s#   € ÷ !ñ !˜kð !Ð@Qð !Ð]pñ !r   c           	     ó   € T ;'       g    \        4       p \        ^4       F©  p\        V4      pVf    R# VP                  4       pVe-   \	        YTP
                  e   VP                  4       MRR7      u # \        W!4      pVR8X  d9   \	        ^ RVP
                  e   \        VP                  4       R4      MRR7      u # VR8w  g   K¨   R# 	   R#   \         d"   p\        P                  RY'4        Rp?R# Rp?ii ; i)	u°  Return the live update holding the marker, or ``None``.

Absent, unreadable, malformed and dead-owner all mean "no live update" â€” unless the
checkout kernel lock of ``install_root`` (default: this checkout) is held: then a killed
updater's tree (its completion, build or git) still runs, the marker is kept, and the
answer is a ``held`` holder (R6; ``marker.sh``/``marker.ps1`` answer ``held`` too). Otherwise
a dead marker is reclaimed â€” judged again and removed inside the marker mutex, so a claim
published after our first read is never the one deleted. Never raises: a marker that cannot
be judged at all also reads as ``None``. That fails open on the MARKER only; the checkout
kernel lock is the guard, and every caller that acts on ``None`` still consults it
(``update_in_progress`` ORs :func:`checkout_lock_held`; ``UpdateLock.acquire`` /
``acquire_checkout`` take it), so a live update is never joined or raced through this answer.
Nç        ©rF   rD  rG  T©rF   rG  rD  r¦  z$Could not judge update marker %s: %s)r    rp   r¹  rq  rC  rL  rõ   Ú_reclaim_deadÚmaxrL   rM   rN   )r5   r=   r¨  Ú_attemptÚparsedr¦  rú   rO   s   $$      r   Úread_live_updater  g  sï   € ð ×)Ð)Ô'Ó)€FðJô ˜ažˆHÜ! &Ó)ˆFØŠ~ÚØ—?‘?Ó$ˆDØÒÜ#¨×J[ÑJ[ÒJg¸&¿*¹*¼,ÐmpÔqÒqÜ# FÓ9ˆGØ˜&Ô Ü#¨°ØJP×J[ÑJ[ÒJg´°F·J±J³LÀ#Ô0FÐmpôrò rà˜&Ö Øñ ò !ñ øô ô JÜ�‰Ð;¸V×IÐIÙûðJús5   –C ¶?C Á6A	C Ã C Ã	C ÃC ÃC=ÃC8Ã8C=c               ó$   € V ^8„  d   QhRRRRRR/# )r   r5   r   r=   r>   r   r¡   r   )r   s   "r   r   r   ‹  s"   € ÷ ñ ˜ð Ð,=ð Èñ r   c           	     óô  €  \        V 4      ;_uu_ 4        \        V 4      pVf    RRR4       R# VP                  4       e    RRR4       R# \        V4      '       d    RRR4       R# \	        \
        4      ;_uu_ 4        V P                  4        RRR4        RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i  \         d"   p\        P                  RY4        Rp?R# Rp?ii ; i)zªRemove a dead marker under the mutex: ``reclaimed`` | ``held`` (dead, but the checkout lock
is held, so it is kept) | ``live`` (a claim appeared) | ``absent`` | ``busy``.NÚabsentr¦  rG  Ú	reclaimedz1Left update marker %s for its current mutator: %sÚbusy)
r  r¹  rq  Úcheckout_lock_heldr   ÚFileNotFoundErrorrÍ  r4   rM   rN   )r5   r=   ÚcurrentrO   s   &&  r   r  r  ‹  s¿   € ðÜ˜$×ÕÜ" 4Ó(ˆGØŠØ÷  Ñð ×ÑÓ!Ò-Ø÷  Ñô " ,×/Ò/Ø÷  Ñô Ô+×,Õ,Ø—‘”÷ -à÷  Ñ÷ -×,ú÷  ×Ðûô ô Ü�‰ÐHÈ$ÔTÝûðúsn   ‚C •B7¦C °B7ÁC ÁB7ÁC Á)B7Â B$	Â	B7ÂC Â$B4Â/B7Â7C	ÃC ÃC ÃC7ÃC2Ã2C7c               ó    € V ^8„  d   QhRRRR/# )r   r   r*   r   zlist[UpdateHolder]r   )r   s   "r   r   r   Ÿ  s   € ÷ ñ  ð Ð7Iñ r   c           
     óÄ  € V f   \        4       P                  MT p . p\        \        4      ;_uu_ 4        V R,          P	                  4        Ft  p\        V\        ,          4      pVe   VP                  '       d   K1  VP                  4       pV'       g   KK  VP                  \        WCP                  4       R7      4       Kv  	  RRR4       V#   + '       g   i     T# ; i)aÄ  Live claims in pre-root-marker ``<root>/profiles/<p>/.hermes-update-in-progress`` files (R11).

Before the marker moved to the profile-tree root, an update under a named profile claimed
its PROFILE home and never took the checkout lock. During the transition such an update can
still be running: honor it (v1 rules: pid alive, within the legacy age ceiling, never our own
previous incarnation). Read-only: an old updater reclaims its own dead markers.
Nr   r  )r    r   r   r4   rË  r¹  r   rO  rq  r  rC  rõ   )r   ÚclaimsÚprofiler¨  r¦  s   &    r   Úlegacy_profile_claimsr+  Ÿ  s§   € ð +/ª,ÔÓ×&Ò&¸D€DØ€FÜ	”'×	Õ	Ø˜zÕ)×2Ñ2Ö4ˆGÜ! '¬KÕ"7Ó8ˆFØŠ~ ×!1×!1Ð!1ÙØ—?‘?Ó$ˆDß‰tØ—‘œl¨tÇÁÃÔNÖOñ 5÷ 
ð €M÷ 
Ö	ð €Mús   ´ACÁ;CÂ-CÃC	c               ó    € V ^8„  d   QhRRRR/# )r   Úholderr  r   r¡   r   )r   s   "r   r   r   ´  s   € ÷ ñ Ð/ð °Cñ r   c                ór  € V e#   V P                   '       d   RV P                    R2# \        \        \        V f   ^ MV P                  ^ 4      4      ^<4      w  rV'       d	   V RV R2MV R2pV '       d"   V P
                  '       d   RV P
                   2MRpV e   V P                  '       d   RpRV R	V R
2# )z?One-line, user-facing explanation of who holds the update lock.u-   âœ— Cannot lock this install for the update: a4  .

  Updating without the lock could let two updates corrupt the install, or run
  under a Desktop app, gateway or installer that cannot see it. Make that path
  writable (fix its owner or permissions, or remount a read-only filesystem
  read-write), or run `hermes update` as the user that owns the install.zm Úsz
, process rþ   zD; its owner exited but a process it started still holds the checkoutu6   âœ— Another Hermes update is already running (started z agoz¼).

  Running two at once would corrupt the install. Wait for it to finish
  (watch `hermes logs`), or close the Desktop/dashboard window that
  started it, then run `hermes update` again.)rF  ÚdivmodrG   r  rD  rF   rG  )r-  ÚminutesÚsecondsÚelapsedÚwhos   &    r   Údescribe_holderr5  ´  sÀ   € àÒ˜fŸmŸm˜mà;¸F¿M¹M¸?ð KWð Wð	
ô œc¤#¨6ª>¡a¸v×?QÑ?QÐSTÓ"UÓVÐXZÓ[Ñ€Gß*1��	˜˜G˜9 AÑ&¸'¸À!°}€Gß'-°&·*·*°*ˆJ�v—z‘z�lÑ
#À"€CØÒ˜fŸkŸk˜kØTˆà
@ÀÀ	ÈÈcÈUð S8ð 	8ðr   zdict | NoneÚ_HELDÚlistÚ_JOBSc               ó    € V ^8„  d   QhRRRR/# )r   rú  rG   r   rH   r   )r   s   "r   r   r   Ö  s   € ÷ ñ �#ð ˜$ñ r   c                ó€  € \         P                  R 8X  df   \        V \        4      '       g   R# \        V \        ^,           \        4      '       g   \        V 4       R# \        V \        ^,           \        4       R# ^ RIp VP                  WP                  VP                  ,          4       R#   \         d     R# i ; i)rz   FTN)r–   r—   Ú_lock_bytesÚ_WINDOWS_LOCK_OFFSETÚ_LEASE_SLOTSÚ_unlockrî  ró  rô  rõ  rö  )rú  rî  s   & r   Ú	_try_lockr?  Ö  s�   € Ü
‡|�|�wÔÜ˜2Ô3×4Ò4ÙÜ˜2Ô3°aÕ7¼×FÒFÜ�BŒKÙÜ�Ô(¨1Õ,¬lÔ;ÙÛðØ�‰�BŸ™¨¯©Õ5Ô6ñ øô ô Úðús   Â ,B. Â.B=Â<B=c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rú  rG   ÚoffsetÚcountr   rH   r   )r   s   "r   r   r   è  s(   € ÷ 	ñ 	�Cð 	 ð 	¨Sð 	¸ñ 	r   c                ó¶   € ^ RI p\        P                  ! W\        P                  4        VP	                  WP
                  V4       R#   \         d     R# i ; i)zSWindows: lock ``count`` bytes at ``offset`` without waiting (fails if any is held).NFT)Úmsvcrtr   ÚlseekÚSEEK_SETÚlockingÚLK_NBLCKr4   ©rú  rA  rB  rD  s   &&& r   r;  r;  è  sG   € ãä‡H‚HˆRœŸ™Ô%ðØ�‰�rŸ?™?¨EÔ2ñ øô ô Úðús   «A	 Á	AÁAc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rú  rG   rA  rB  r   rÉ  r   )r   s   "r   r   r   ô  s(   € ÷ 7ñ 7�ð 7˜Sð 7Àð 7ÈDñ 7r   c                ó&  € \         P                  R 8X  dh   ^ RIp\        \        4      ;_uu_ 4        \
        P                  ! W\
        P                  4       VP                  WP                  V4       RRR4       R# R#   + '       g   i     R# ; i)rz   N)
r–   r—   rD  r   r4   r   rE  rF  rG  ÚLK_UNLCKrI  s   &&& r   r>  r>  ô  sY   € Ü
‡|�|�wÔÛä”g×ÕÜ�HŠH�R¤§¡Ô-Ø�N‰N˜2Ÿ™°Ô6÷ Ññ ÷ ×Ðús   ±AA?Á?B	c               ó    € V ^8„  d   QhRRRR/# )r   rú  rG   r   rh   r   )r   s   "r   r   r   ý  s   € ÷ ñ �Cð ˜Jñ r   c                ó˜   € \        \        ^,           \        ^,           \        ,           4       F  p\        W4      '       g   K  Vu # 	  R# )z¦Windows: lock a free lease byte (R5b) on ``fd``; its offset, or None when all are held
(the tree's other joiners hold them: this one still runs inside their custody).N)rp   r<  r=  r;  )rú  rA  s   & r   Ú_take_leaserO  ý  s<   € ô Ô,¨qÕ0Ô2FÈÕ2JÌ\Õ2YÖZˆÜ�r×"Ô"ØŠMñ [ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   r5   r   r   rh   r   )r   s   "r   r   r     s   € ÷ ñ ˜Tð  jñ r   c                óÚ  € \         P                  R8X  d   R#  \        P                  ! V 4      p\        P                  P                  R4      '       d   RMRp\        P                  ! V4       Uu. uF%  q3P                  4       '       g   K  \        V4      NK'  	  pp^ RI
pT F›  p \        P                  ! T4      '       g   K"  \        P                  ! T4      pTP                  TP                  3TP                  TP                  38w  d   Km  TP                  YeP                   TP"                  ,          4       Tu # 	  R# u upi   \         d     R# i ; i  \         d     KÆ  i ; i)zRAn fd this process inherited that holds the lock on ``path`` (POSIX ``pass_fds``).rz   Nz/proc/self/fdz/dev/fd)r–   r—   r   r±   r5   r™   ÚlistdirÚisdigitrG   r4   rî  Úget_inheritableÚfstatÚst_devÚst_inoró  rô  rõ  )r5   r¼   Úfd_dirr   Ú
candidatesrî  rú  Ústs   &       r   Ú_inherited_lock_fdr[    s  € ä
‡|�|�wÔÙðÜ—’˜“ˆÜ$&§G¡G§M¡M°/×$BÒ$B‘È	ˆÜ,.¯JªJ°vÔ,>ÓQÑ,> DÇ,Á,Ç.”i”c˜$–iÑ,>ˆ
ÐQó ãˆð	ô ×%Ò% b×)Ò)ÙÜ—’˜"“ˆBØ—	‘	˜2Ÿ9™9Ð%¨&¯-©-¸¿¹Ð)GÔGÙð �K‰K˜ŸM™M¨E¯M©MÕ9Ô:ØŠIñ ñ  ùò+ RøÜô Úðûô$ ô 	Úð	úsN   ™:E	 ÁE	 Á0EÂEÂE	 Â'EÃA	EÄ-EÅE	 Å	EÅEÅE*Å)E*c               ó   € V ^8„  d   QhRR/# )r   r   rC  r   )r   s   "r   r   r   %  s   € ÷ 	Añ 	A ñ 	Ar   c                óR  € \        V 4      ;'       g    Rp\        V4      pVP                  '       d   VP                  4       MRpVP                  ^ 8”  d3   \        VP                  VP                  4      RJ d   \        ^ VRR7      # \        \        VP                  ^ 4      VR7      # )a   Who holds the checkout lock, from its holder record. A recorded updater that is gone (its
incarnation is dead) while the lock stays held means a process it started holds it: that is
the ``held`` holder, never the dead pid (the marker reader's wording, R6).r   r  FT)rF   rD  rG  r  )	rµ  r¡  rL  rõ   rF   rÚ   r»   rC  r  )Ú
fd_or_pathrK  r  rõ   s   &   r   Ú_lock_holderr_  %  sƒ   € ô �jÓ
!×
(Ð
( S€CÜ˜3Ó€FØ ×+×+Ð+ˆ&�*‰*Œ,°€CØ‡z�z�A„~Ô*¨6¯:©:°v×7IÑ7IÓJÈeÓSÜ ¨s¸Ô>Ð>ÜœC §
¡
¨AÓ.¸CÔ@Ð@r   c               ó    € V ^8„  d   QhRRRR/# )r   r5   r   r   ztuple[int | None, object]r   )r   s   "r   r   r   1  s   € ÷ /ñ /˜$ð /Ð#<ñ /r   c                ó  € \        \        R^ 4      \        \        R^ 4      ,          p \        P                  ! V \        P                  \        P                  ,          V,          R4      R3#   \
         d   pTp Rp?M3Rp?i\         d#   pRTP                  ;'       g    T3u Rp?# Rp?ii ; i \        P                  ! T \        P                  T,          4      R3#   \         d    RTP                  ;'       g    T3u # i ; i)u  ``(fd, True)`` read-write; ``(fd, False)`` read-only for an existing lock file we may not
write (left root-owned by a ``sudo hermes update``: the kernel lock works on a read-only fd,
contract A5; POSIX only â€” a Windows owner needs its record); ``(None, reason)`` when neither opens.ÚO_BINARYÚ
O_NOFOLLOWrë  TNF)	rÿ  r   rš   rï  rð  rñ  r4   Ústrerrorrò  )r5   ÚbinaryrO   Údenieds   &   r   Ú_open_lock_filerg  1  sÎ   € ô
 ”R˜ QÓ'¬'´"°lÀAÓ*FÕF€Fð)Ü�wŠw�tœRŸY™Y¬¯©Õ3°fÕ<¸eÓDÀdÐJÐJøÜô Ø�ûÜô )Ø�S—\‘\×(Ð( SÐ(Õ(ûð)úð/Ü�wŠw�tœRŸ[™[¨6Õ1Ó2°EÐ9Ð9øÜô /Ø�V—_‘_×.Ð.¨Ð.Ò.ð/úsH   ©AA- Á-B/Á8A?Á?B/ÂB/ÂB*Â$B/Â*B/Â3-C! Ã!DÄ DÄDc               ó    € V ^8„  d   QhRRRR/# )r   r=   r   r   r  r   )r   s   "r   r   r   C  s   € ÷ 9ñ 9 Dð 9Ð-@ñ 9r   c                óö  € \        V 4      p\        e7   \        R,          \        V4      8X  d   \        R;;,          ^,          uu&   R# \        V4      pVe   R\        V4      RVRRR^/sR# \	        V4      w  r4Vf   \        ^ RV RV R	2R
7      # \        P                  ! V4      p\        VP                  4      '       d   VP                  ^8w  d(   \        P                  ! V4       \        ^ RV R2R
7      #  \        W14      '       g–   \        V4      '       dd   \        V4      p\        V4      '       d9   R\        V4      RRRRR^RVf   RMW63/sVf   \        P                  ! V4       R# Ve   \        W64       \        P                  ! V4       \!        V4      # VRJdH   \"        P$                  R8X  d3   \        V4       \        P                  ! V4       \        ^ RV R2R
7      # VRJ d¤   \        P&                  ! 4        R\)        \*        P*                  ! 4       4       R\-        4        R2P/                  4       p\        P0                  ! V^ \        P2                  4       \        P4                  ! V^ 4       \        P6                  ! W74       R\        T4      RTRRR^/sR#   \8         d@   p\        T4       \        P                  ! T4       \        ^ RT RT R2R
7      u Rp?# Rp?ii ; i)zTTake (or join, when inherited) the checkout lock; the refusal holder, else ``None``.Nr5   Údepthrú  ÚownedFr  ú is not writable (zV); the update locks the checkout there, in its git directory, which git must write too©rF   rD  rF  z- is not a regular single-link file; delete itÚleaseTrz   z/ is read-only; delete it or fix its permissionsru  z could not be locked (Ú))rC   r6  r¡   r[  rg  rC  r   rU  r   Úst_modeÚst_nlinkrø  Ú_lock_with_contention_waitÚ_held_by_our_windows_ancestorrO  r>  r_  r–   r—   r¸   rG   r§   rÿ   r{  rE  rF  Ú	ftruncater	  r4   )	r=   r5   Ú	inheritedrú  Úwritabler#  rn  ÚrecordrO   s	   &        r   Ú_acquire_checkoutrx  C  s•  € ô ˜lÓ+€DÜÒœU 6�]¬c°$«iÔ7Üˆg�˜!Õ‹ÙÜ" 4Ó(€IØÒØœ˜T› D¨)°W¸eÀWÈaÐPˆÙÜ" 4Ó(�L€BØ	‚zÜ ¨s¸d¸VÐCUÐV^ÐU_ð `gð <gô hð 	hä�HŠH�R‹L€EÜ�5—=‘=×!Ò! U§^¡^°qÔ%8ô 	�Š�ŒÜ ¨s¸d¸VÐCpÐ;qÔrÐrð"bÜ)¨"×3Ò3Ü,¨T×2Ò2ô
 $ B›�Ü0°×6Ò6Ø#¤S¨£Y°°d¸GÀUÈGÐUVØ$¨eªm¡dÀ"ÀðN�Eà’}ÜŸš œÙØÒ$Ü˜BÔ&Ü�HŠH�RŒLÜ Ó%Ð%Ø˜4Ó¤C§L¡L°GÔ$;ô �BŒKÜ�HŠH�RŒLÜ A°3Ø*.¨Ð/^Ð'_ôað aà�tÓÜŸ	š	›�} B¤s¬4¯9ª9«;Ó'7Ð&8¸¼>Ó;KÐ:LÈBÐO×VÑVÓXˆFÜ�HŠH�R˜œBŸK™KÔ(Ü�LŠL˜˜QÔÜ�HŠH�RÔ ð
 ”S˜“Y  b¨'°4¸À!ÐD€EÙøô ô bÜ�ŒÜ
�Š�ŒÜ ¨s¸d¸VÐCYÐZ]ÐY^Ð^_Ð;`ÔaÕaûðbús3   Ã=A4J. Å3/J. Æ#AJ. Ç0B)J. Ê.K8Ê94K3Ë-K8Ë3K8g      @c               ó$   € V ^8„  d   QhRRRRRR/# )r   rú  rG   r5   r   r   rH   r   )r   s   "r   r   r   …  s!   € ÷ 
ñ 
 3ð 
¨dð 
°tñ 
r   c                ó  € \        V 4      '       d   R # \        V4      '       d   R# \        P                  ! 4       \        ,           p\        P                  ! 4       V8  d,   \        P
                  ! R4       \        V 4      '       g   KC  R # R# )TFrê  )r?  rs  r§   rì  Ú CHECKOUT_CONTENTION_WAIT_SECONDSrí  )rú  r5   rù  s   && r   rr  rr  …  sX   € Ü�‡}‚}ÙÜ$ T×*Ò*ÙÜ�~Š~ÓÔ"BÕB€HÜ
�.Š.Ó
˜XÔ
%Ü�
Š
�4ÔÜ�R�=Œ=ÙÙr   c               ó    € V ^8„  d   QhRRRR/# )r   r5   r   r   rH   r   )r   s   "r   r   r   ’  s   € ÷ eñ e¨ð e°ñ er   c                óR  € \         P                  R8w  d   R# \        \        V 4      ;'       g    R4      pVP                  e%   VP
                  \        P                  ! 4       8X  d   R# \        VP
                  VP                  4      RJ ;'       d    \        VP
                  4      # )z›Windows: the checkout lock's holder record names a LIVE incarnation of one of our
ancestors (the ``hermes update`` whose completion/build children we are).rz   Fr   T)r–   r—   r¡  rµ  rL  rF   r   r¸   rÚ   r»   r2  )r5   rw  s   & r   rs  rs  ’  s{   € ô ‡|�|�wÔÙÜœ; tÓ,×3Ð3°Ó4€FØ×ÑÒ  F§J¡J´"·)²)³+Ô$=ÙÜ˜FŸJ™J¨×(:Ñ(:Ó;¸tÐC×dÐdÔHXÐY_×YcÑYcÓHdÐdr   c               ó   € V ^8„  d   QhRR/# rã  r   )r   s   "r   r   r   �  s   € ÷ !ñ !˜4ñ !r   c                 óZ  € \         f   R # \         R;;,          ^,          uu&   \         R,          ^ 8”  d   R # \         R up s V P                  R4      '       dM   V R,          w  r\        W4       \        \        4      ;_uu_ 4        \
        P                  ! V4       R R R 4       V R,          '       dR   \        V R,          4       \        \        4      ;_uu_ 4        \
        P                  ! V R,          4       R R R 4       R # R #   + '       g   i     Lr; i  + '       g   i     R # ; i)Nrj  rn  rk  rú  )r6  r   r>  r   r4   r   rø  )rG  Úlease_fdrA  s      r   Ú_release_checkoutr�  �  sÅ   € ä‚}ÙÜ	ˆ'‡N�aÕƒNÜˆW…~˜ÔÙÜ˜€K€Dˆ%Ø‡x�x�×ÒØ �=ÑˆÜ�Ô!Ü”g×ÕÜ�HŠH�XÔ÷ àˆG‡}„}ô 	��T•
ÔÜ”g×ÕÜ�HŠH�T˜$•ZÔ ÷ Ññ	 ÷ ×ú÷ ×Ðús   ÂDÃDÄD	ÄD*	c               ó    € V ^8„  d   QhRRRR/# )r   r=   r>   r   ztuple[int, ...]r   )r   s   "r   r   r   ²  s   € ÷ 'ñ 'Ð$5ð 'Àñ 'r   c                ó¸   € \         P                  R8X  d   R# \        e    \        R,          f   R# \        R,          3# \        \	        V 4      4      pVf   R# V3# )z¢Fds a child of the update tree must inherit (``subprocess`` ``pass_fds``) so the
checkout stays locked while it runs, even after its parent is killed. POSIX only.rz   rú  r   )r–   r—   r6  r[  rC   )r=   rú  s   & r   Úcheckout_lock_fdsr„  ²  sV   € ô ‡|�|�wÔØˆ	ÜÒÜ˜4•[Ò(ˆrÐ<¬u°T­{¨nÐ<Ü	Ô.¨|Ó<Ó	=€BØ’ˆ2Ð& " Ð&r   c               ó   € V ^8„  d   QhRR/# )r   r   rÇ   r   )r   s   "r   r   r   ½  s   € ÷ (ñ (˜dñ (r   c                 ó~   € \         P                  R8X  g   \        e   \        R,          f   / # R\        R,          3/# )af  ``subprocess`` kwargs that keep a checkout MUTATOR (git, the Node source build) in the
update tree's custody (R2): POSIX children inherit the held lock fd, so the checkout stays
locked until the last of them exits even if this process is killed. ``{}`` when this process
holds no checkout lock, and on Windows (bind the Popen with bind_child_to_update_tree).rz   rú  Úpass_fds)r–   r—   r6  r   r   r   Úcustody_spawn_kwargsrˆ  ½  s3   € ô
 ‡|�|�wÔ¤%¢-´5¸µ;Ò3FØˆ	Øœ˜t�˜Ð'Ð'r   c               ó    € V ^8„  d   QhRRRR/# )r   r/  úsubprocess.Popenr   zOSError | Noner   )r   s   "r   r   r   Ê  s   € ÷ ñ Ð$4ð ¸ñ r   c                óÂ   € \         P                  R8w  d   R#  \        V 4       R#   \         d.   p\        P                  RT P                  T4       Tu Rp?# Rp?ii ; i)a  Windows: put an update-tree child in a kill-on-close job owned by this process, so the
child (and everything it spawns) dies when the lock owner dies and frees the lock.

Create ``proc`` with :data:`CREATE_SUSPENDED` and resume it after the bind
(:func:`resume_suspended_child`): it runs no instruction before, so nothing it starts can
escape the job. The job allows breakaway: a process the tree starts
with ``CREATE_BREAKAWAY_FROM_JOB`` (the gateways an update restarts or resumes,
``gateway_windows._spawn_detached``) leaves it and outlives the update; every other
descendant stays bound. Not ``SILENT_BREAKAWAY_OK``, which would let every descendant escape.

POSIX children inherit the lock fd instead (:func:`checkout_lock_fds`). Returns ``None`` when
bound, else the refusal (logged): the caller runs post-commit work, which must not fail over
a weaker lock, so it records the refusal and runs the child, which joins the lock holding its
own lease byte (R5b): the checkout stays busy until it exits, even after the owner's death.
rz   Nz6Could not bind update child %s to the update's job: %s)r–   r—   Ú_bind_to_kill_on_close_jobr4   rM   ÚwarningrF   )r/  rO   s   & r   Úbind_child_to_update_treerŽ  Ê  sU   € ô  ‡|�|�wÔÙðÜ" 4Ô(ñ øô ô Ü�‰ÐOÐQU×QYÑQYÐ[^Ô_Ø�
ûðús   ™& ¦A±"AÁAÁAc               ó    € V ^8„  d   QhRRRR/# ©r   r/  rŠ  r   rÉ  r   )r   s   "r   r   r   ä  s   € ÷ 
Cñ 
CÐ!1ð 
C°dñ 
Cr   c                ó@  € ^ RI pVP                  R4      pVP                  .VP                  n        VP
                  VP                  n        VP                  \        V P                  4      4      ^ 8w  d)   V P                  4        \        RV P                   24      hR# )z~Windows: resume a :data:`CREATE_SUSPENDED` child (a no-op for a running one). A failed
resume kills it and raises ``OSError``.NÚntdllzcould not resume update child )rY   rZ   r  ÚNtResumeProcessr^   r  r`   rG   Ú_handleÚkillr4   rF   )r/  rY   r’  s   &  r   Úresume_suspended_childr–  ä  s}   € ó à�M‰M˜'Ó"€EØ&,§o¡oÐ%6€E×ÑÔ"Ø$*§M¡M€E×ÑÔ!Ø×ÑœS §¡Ó.Ó/°1Ô4Ø�	‰	ŒÜÐ6°t·x±x°jÐAÓBÐBñ 5r   c               ó    € V ^8„  d   QhRRRR/# r�  r   )r   s   "r   r   r   ñ  s   € ÷ 7ñ 7Ð%5ð 7¸$ñ 7r   c                óh  € ^ RI p^ RI Hp VP                  RRR7      pVP                  VP                  .VP                  n        VP                  VP                  n        VP	                  \        4       \        V P                  4      4      '       g    VP                  VP                  4       4      hR# rR   )rY   rU   rZ   r_   ÚAssignProcessToJobObjectr^   r\   r`   Úupdate_tree_jobrG   r”  rÜ  rÛ  )r/  rY   rU   rV   s   &   r   rŒ  rŒ  ñ  s„   € ÛÝà�}‰}˜Z¸ˆ}Ó=€HØ2:·/±/À8Ç?Á?Ð1S€H×%Ñ%Ô.Ø08·±€H×%Ñ%Ô-Ø×,Ñ,¬_Ó->ÄÀDÇLÁLÓ@Q×RÒRØ�o‰o˜f×3Ñ3Ó5Ó6Ð6ñ Sr   c               ó   € V ^8„  d   QhRR/# )r   r   rG   r   )r   s   "r   r   r   ü  s   € ÷ %ñ %˜ñ %r   c                 óè  aaa€ \         '       d   \         ^ ,          # ^ RIo^ RIHo  ! VV3R lRSP                  4      o ! VV3R lRSP                  4      p SP	                  RRR	7      pSP
                  SP                  .VP                  n        SP                  VP                  n
        SP                  SP                  SP
                  SP                  .VP                  n        SP                  VP                  n
        SP                  .VP                  n        VP                  RR4      pV'       g    SP!                  SP#                  4       4      hV ! 4       pR
VP$                  n        VP                  V^	SP)                  V4      SP+                  V4      4      '       g3   SP#                  4       pVP                  V4       SP!                  V4      h\         P-                  V4       V# )z¨Windows: this process's kill-on-close job for the update tree (created once, never
closed: the handle closes when this process dies, killing every process still in it).NrT   c            
      ó  <€ ] tR tRtR Z P                  3R Z P                  3R ZP
                  3R Z P                  3R Z P                  3R ZP
                  3R Z P                  3R	 ZP
                  3R
 ZP
                  3.	tRtR# )Úupdate_tree_job.<locals>._Basici  ÚPerProcessUserTimeLimitÚPerJobUserTimeLimitÚ
LimitFlagsÚMinimumWorkingSetSizeÚMaximumWorkingSetSizeÚActiveProcessLimitÚAffinityÚPriorityClassÚSchedulingClassr   N)	râ   rã   rä   rå   Úc_int64r[   r  r  rè   r  s   €€r   Ú_Basicrž    s{   ø† Ø.±·±Ð?ÐBWÑY_×YgÑYgÐAhØ!¡8§>¡>Ð2Ð5LÉfÏoÉoÐ4^Ø,©f¯o©oÐ>ÐAUÑW_×WeÑWeÐ@fØ¡§¡Ð1°OÁXÇ^Á^Ð3TØ&©¯©Ð7ð	9Œr   r©  c                  ó¾   <€ ] tR tRtR Z 3R ZP                  ^,          3R ZP
                  3R ZP
                  3R ZP
                  3R ZP
                  3.tRtR	# )
Ú"update_tree_job.<locals>._Extendedi  ÚBasicLimitInformationÚIoInfoÚProcessMemoryLimitÚJobMemoryLimitÚPeakProcessMemoryUsedÚPeakJobMemoryUsedr   N)râ   rã   rä   rå   Úc_ulonglongr  r  rè   )r©  rY   s   €€r   Ú	_Extendedr«    s\   ø† Ø,©fÐ5¸Á&×BTÑBTÐWXÕBXÐ7YØ)©6¯?©?Ð;Ð>NÑPV×P_ÑP_Ð=`Ø,©f¯o©oÐ>ÐATÑV\×VeÑVeÐ@fðhŒr   r³  rV   TrW   i (  )r8  rY   rU   r  rZ   r  rÙ  ÚCreateJobObjectWr^   r_   r`   Úc_intr[   ÚSetInformationJobObjectr\   rd   rÜ  rÛ  r¬  r¡  rk   r  r  )r³  rV   ÚjobÚlimitsrà  r©  rY   rU   s        @@@r   rš  rš  ü  s‰  ú€ ÷ ƒuÜ�Q�xˆÛÝ÷9ð 9�×!Ñ!ô 9÷hð h�F×$Ñ$ô hð
 �}‰}˜Z¸ˆ}Ó=€HØ*0¯/©/¸8×;KÑ;KÐ)L€H×ÑÔ&Ø(0¯©€H×ÑÔ%Ø19·±À&Ç,Á,ÐPV×P_ÑP_Ðai×aoÑaoÐ0p€H×$Ñ$Ô-Ø/7¯}©}€H×$Ñ$Ô,Ø%-§_¡_Ð$5€H×ÑÔ!Ø
×
#Ñ
# D¨$Ó
/€CßØ�o‰o˜f×3Ñ3Ó5Ó6Ð6Ù‹[€Fà.=€F× Ñ Ô+Ø×+Ñ+¨C°°F·L±LÀÓ4HÈ&Ï-É-ÐX^ÓJ_×`Ò`Ø×%Ñ%Ó'ˆØ×Ñ˜SÔ!Ø�o‰o˜eÓ$Ð$Ü	‡L�L�ÔØ€Jr   c               ó    € V ^8„  d   QhRRRR/# ©r   r=   r>   r   rH   r   )r   s   "r   r   r   $  s   € ÷ wñ wÐ&7ð wÀ4ñ wr   c                óÈ   € \         RJ;'       dT    \        P                  P                  \         R,          4      \        P                  P                  \	        V 4      4      8H  # )zUTrue when this process holds (or joined) the checkout lock: it IS the running update.Nr5   )r6  r   r5   ÚrealpathrC   ©r=   s   &r   Úholds_checkout_lockr¾  $  sC   € ä˜Ð×vÐv¤§¡×!1Ñ!1´%¸µ-Ó!@ÄBÇGÁG×DTÑDTÔUgÐhtÓUuÓDvÑ!vÐvr   c               ó    € V ^8„  d   QhRRRR/# rº  r   )r   s   "r   r   r   )  s   € ÷ gñ gÐ%6ð gÀ$ñ gr   c                óD   € \        V R7      RJ;'       g    \        V 4      # )zNTrue while an update owns this install: a LIVE marker or a held checkout lock.r½  N)r  r$  r½  s   &r   Úupdate_in_progressrÁ  )  s!   € ä¨Ô6¸dÐB×fÐfÔFXÐYeÓFfÐfr   c               ó    € V ^8„  d   QhRRRR/# rº  r   )r   s   "r   r   r   .  s   € ÷ ñ Ð%6ð À$ñ r   c           	     ó  € \        V 4      '       d   R# \        V 4      p \        P                  ! V\        P                  \        \        R^ 4      ,          4      p \        T4      '       g    \        P                  ! T4       R# \        T4        \        P                  ! T4       R#   \         d     R# \         d     R# i ; i  \         d     \        P                  ! T4       R# i ; i  \        P                  ! T4       i ; i)aÙ  True while some process (this one included) holds the checkout kernel lock.

A probe takes the lock for the microseconds of one try and drops it (closing the fd), the
way ``marker.sh::checkout_lock_held`` does; an updater acquiring at that instant waits
:data:`CHECKOUT_CONTENTION_WAIT_SECONDS` instead of failing (R6/D17).

Only a missing lock file is free. One that exists but cannot be opened answers held, the same
verdict ``marker.sh`` / ``marker.ps1`` and the Desktop probes give, so no reader admits a
launch the others would park. A lock call that fails outright (ENOLCK on NFS without lockd,
EOPNOTSUPP on some SMB shares) means nothing can hold it: free, so the interrupted-pull repair
runs unguarded there as designed.Trb  F)r¾  rC   r   rš   rò  rÿ  r%  r4   r?  rø  r>  )r=   r5   rú  s   &  r   r$  r$  .  sÅ   € ô ˜<×(Ò(ÙÜ˜lÓ+€DðÜ�WŠW�Tœ2Ÿ;™;¬´°ZÀÓ)CÕCÓDˆð
Ü˜�}Š}Øô 	�Š�Žô 	�ŒØô 	�Š�Žøô ô ÚÜô Úðûô ô Øä
�Š�Žðûô 	�Š��úsG    ;B* ÁC	 ÂC	 Â*CÂ8CÃCÃCÃ	C.ÃC1 Ã-C.Ã.C1 Ã1D	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r5   r   r|  rJ  r   rH   r   )r   s   "r   r   r   Q  s!   € ÷ )ñ )˜Tð )¨ð )°4ñ )r   c           
     óž  € \        V 4      p \        VR4      ;_uu_ 4       pVP                  V4       VP                  4        \        P
                  ! VP                  4       4       RRR4        \        P                  ! W 4        \        \        4      ;_uu_ 4        VP                  4        RRR4       R#   + '       g   i     LZ; i  + '       g   i     R# ; i  \         dI     \        \        4      ;_uu_ 4        TP                  4        RRR4       R#   + '       g   i     R# ; i\         d!   p\        P                  RT4        Rp?MRp?ii ; i \        \        4      ;_uu_ 4        TP                  4        RRR4       M[  + '       g   i     MK; i  \        \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; i; i \        P                  ! T \        P                  \        P                  ,          \        P                   ,          \#        \        R^ 4      ,          R4      pM  \         d     R# i ; i\        P$                  ! T4      p \        P                  ! YQ4      \'        T4      8w  d   \        \(        P*                  RT  24      h\        P
                  ! T4       Mâ  \,         dÕ    \        P.                  ! T4       \        \        4      ;_uu_ 4        \1        T 4      ;_uu_ 4        \        P2                  ! T 4      pTP4                  TP6                  3TP4                  TP6                  38X  d   T P                  4        RRR4       M  + '       g   i     M; iRRR4       h   + '       g   i     h ; ii ; i\        P.                  ! T4       R# )	a_  Contract A3: publish ``body`` at ``path`` only if nothing is there, never as an empty
file a reader could judge dead. Write a private tmp sibling, then hard-link it into place
(fails if the marker exists); a filesystem without hard links falls back to an exclusive
create (readers grant a young empty marker EMPTY_MARKER_GRACE_SECONDS). False = taken.ÚxbNTFzANo hard link for the update marker (%s); exclusive create insteadrb  rë  zshort write publishing )rÂ  rš   r	  r
  r   r  r  Úlinkr   r4   rÍ  ÚFileExistsErrorrM   rN   ÚO_WRONLYrð  ÚO_EXCLrÿ  rU  r3   ÚerrnoÚENOSPCr÷  rø  r  r±   rV  rW  )r5   r|  r  r°   rO   rú  ÚmaderÞ   s   &&      r   Ú_publish_exclusiverÎ  Q  sj  € ô
 �tÓ
€CðÜ�#�t�_Œ_ Ø�H‰H�TŒNØ�H‰HŒJÜ�HŠH�R—Y‘Y“[Ô!÷ ð	cÜ�GŠG�CÔØô ”g×ÕØ�J‰JŒL÷ Ñ÷ �_ú÷ ×Ðûô ô 	Øô ”g×ÕØ�J‰JŒL÷ ××Òúô ô 	cÜ�L‰LÐ\Ð^a×bÑbûð	cúØbä”g×ÕØ�J‰JŒL÷ ××ÐûŒX”g×ÕØ�J‰JŒL÷ ××ÐýðÜ�WŠW�Tœ2Ÿ;™;¬¯©Õ3´b·i±iÕ?Ä'Ì"ÈjÐZ[ÓB\Õ\Ð^cÓd‰øÜô Úðúä�8Š8�B‹<€DðÜ�8Š8�BÓ¤ T£Ô*Üœ%Ÿ,™,Ð*AÀ$ÀÐ(HÓIÐIÜ
�Š��øÜô 	ô 	�Š�ŒÜ”g×Õ¤¨T× 2Õ 2Ü—'’'˜$“-ˆCØ—
‘
˜CŸJ™JÐ'¨D¯K©K¸¿¹Ð+EÔEØ—‘”÷ !3× 2× 2Ð 2ú×ð 	÷	 Öð 	úð	úô ‡H‚HˆR„LÙsæ   �F$ ¡AB9Á'F$ Á0C  ÂCÂ9C		ÃF$ ÃC	Ã EÃ+F$ ÄDÄD/	Ä2EÄ;EÄ<EÅF$ ÅEÅF$ Å7FÆF!	Æ$G)Æ<G	Ç	G)ÇG&Ç!G)Ç-A&I ÉI#É"I#É=AK Ë8N4ÌN Ì!ANÍ;	N ÎNÎN Î	N4Î N0Î+	N4c               ó$   € V ^8„  d   QhRRRRRR/# )r   r5   r   rO   r4   r   r¡   r   )r   s   "r   r   r   }  s&   € ÷ Cñ C˜Tð C¨ð C°Cñ Cr   c                ó   € V  RV R2# )zUWhy an unwritable marker location refuses the update, not just that it is unwritable.rl  zj); the update records itself there so the Desktop app, gateways, installers and other updaters wait for itr   )r5   rO   s   &&r   Ú_marker_unwritablerÑ  }  s    € àˆfÐ& s eð ,Bð Bð Cr   zdict[str, int]Ú_CLAIMSc                  ó¸   € ] tR tRtRtRRRRR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4       tR R ltR R ltR R ltR R ltR R ltRtR# )Ú
UpdateLockiˆ  uÌ  Context manager owning the shared update marker (and, with ``install_root``, the
checkout lock) for this process.

``acquired`` is True when we wrote the marker; adopting a live partner's claim (hand-off
pid, ancestor, or an outer claim of this same process) succeeds with ``acquired`` False.
``acquire`` returns False (and sets ``holder``) when another live update owns either lock
or the lock cannot be created at all â€” never "proceed unlocked".

``install_root`` names the checkout whose kernel lock guards the claim (default: this
checkout). With ``checkout_first`` (the default, when ``install_root`` is given) ``acquire``
takes that lock before the marker. ``checkout_first=False`` claims the marker alone â€” a
launch that may run under a live update's claim (venv_sync) and takes the checkout lock later,
only for its own mutation. Either way a dead marker over a checkout lock held by another
process tree is refused as ``held`` and kept, never reclaimed (R6).
r5   Nr=   Úcheckout_firstTc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r5   r*   r=   r>   rÕ  rH   r   rÉ  r   )r   s   "r   r   ÚUpdateLock.__annotate__™  s+   € ÷ ñ  ð ÐBSð Ø!%ðØ15ñr   c               	ó¨   € T;'       g    \        4       V n        Vf   R M
\        V4      V n        W0n        RV n        R V n        RV n        RV n        R # )NF)	r    r5   r   r=   rÕ  Úacquiredr-  Ú_claimedÚ	_checkout)rZ  r5   r=   rÕ  s   &$$$r   Ú__init__ÚUpdateLock.__init__™  sK   € à×0Ð0Ô.Ó0ˆŒ	Ø$0Ò$8™D¼dÀ<Ó>PˆÔØ,ÔØˆŒØ+/ˆŒØˆŒØˆŽr   c               ó   € V ^8„  d   QhRR/# ©r   r   rH   r   )r   s   "r   r   r×  £  s   € ÷ ñ ˜ñ r   c                	ó¢  € V P                   e6   V P                  '       d$   V P                  V P                   4      '       g   R#  V P                  4       pT'       g   T P                  4        R# \        T P                  4      p\        P                  T^ 4      ^,           \        T&   RT n
        R#   \         d    T P                  4        h i ; i)NFT)r=   rÕ  Úacquire_checkoutÚ_claim_markerr÷  Ú_drop_checkoutr¡   r5   rÒ  r   rÚ  )rZ  Úokr  s   &  r   ÚacquireÚUpdateLock.acquire£  sª   € Ø×ÑÒ(¨T×-@×-@Ð-@Ø×-Ñ-¨d×.?Ñ.?×@Ò@Ùð	Ø×#Ñ#Ó%ˆB÷ Ø×ÑÔ!ÙÜ�$—)‘)‹nˆÜ—{‘{ 3¨Ó*¨QÕ.Œ�‰ØˆŒÙøô ô 	Ø×ÑÔ!Øð	ús   ÁB1 Â1Cc               ó    € V ^8„  d   QhRRRR/# )r   r=   z
Path | strr   rH   r   )r   s   "r   r   r×  ´  s   € ÷ 
ñ 
¨Zð 
¸Dñ 
r   c                ó|   € V P                   '       d   R# \        \        V4      4      pVe	   W n        R# RV n         R# )u©   Take (or join) the checkout lock â€” ACQUIRE custody, never sample it (R2): a caller
that will mutate the checkout under a marker it adopted or claimed calls this first.TF)rÛ  rx  r   r-  )rZ  r=   Úrefuseds   && r   rá  ÚUpdateLock.acquire_checkout´  s7   € ð �>�>ˆ>ÙÜ#¤D¨Ó$6Ó7ˆØÒØ!ŒKÙØˆŒÙr   c               ó   € V ^8„  d   QhRR/# rß  r   )r   s   "r   r   r×  À  s   € ÷ 0ñ 0˜tñ 0r   c                	ó\  €  V P                   P                  P                  R R R7       \        T P                   4       \        P                  \        T P                   4      4      fj   \        T P                   P                  4       Uu. uF(  pT P                  TP                  4      '       d   K&  TNK*  	  ppT'       d   T^ ,          T n        R# \        P                  ! 4        R\!        \"        P"                  ! 4       4       R\%        4        R2P'                  4       p \)        ^4       EFi  p\+        T P                   T4      '       d   R T n         R # \/        T P                   4      ;_uu_ 4        \1        T P                   4      pTf    RRR4       Kl  \3        T4      '       d   T P5                  T4      uuRRR4       u # T P7                  4       '       dH   \	        ^ R TP8                  e   \;        TP=                  4       R4      MRR7      T n         RRR4        R# \?        \@        4      ;_uu_ 4        T P                   PC                  4        RRR4       \+        T P                   T4      '       d   R T n         RRR4        R #  RRR4       EKl  	  \G        T P                   T PH                  R	7      ;'       g    \	        ^ RR7      T n        R#   \         d=   p\	        ^ R\        T P                   P                  T4      R7      T n         Rp?R# Rp?ii ; iu upi   + '       g   i     LÙ; i  + '       g   i     EK  ; i  \D         d    \	        ^ RR7      T n         R# \         d3   p\	        ^ R\        T P                   T4      R7      T n         Rp?R# Rp?ii ; i)
T)r'   Úexist_okr  rm  NFru  r  r  )r5   r=   )%r5   r   Úmkdirr4   rC  rÑ  r-  rÏ  rÒ  r   r¡   r+  Ú_is_partnerrF   r   r¸   rG   r§   rÿ   r{  rp   rÎ  rÙ  r  r¹  r  Ú_adopt_or_refuseÚ_checkout_held_elsewhererL  r  rõ   r   r%  rÍ  rÑ  r  r=   )rZ  rO   ÚclaimÚlegacyr|  r  Úexistings   &      r   râ  ÚUpdateLock._claim_markerÀ  sÉ  € ð	Ø�I‰I×Ñ×"Ñ"¨4¸$Ð"Ô?ô 	! §¡Ô+Ü�;‰;”s˜4Ÿ9™9“~Ó&Ò.Ü)>¸t¿y¹y×?OÑ?OÔ)Pó :Ñ)P Ø!×-Ñ-¨e¯i©i×8÷ �eÑ)PˆFð :çØ$ Q�i�”ÙÜ—)’)“+�˜b¤¤T§Y¢Y£[Ó!1Ð 2°"´^Ó5EÐ4FÀbÐI×PÑPÓRˆð	Ü! !ŸH�ä% d§i¡i°×6Ò6Ø$(�D”MÚÜ! $§)¡)×,Õ,Ü+¨D¯I©IÓ6�HØÒ'Ø ÷ -Ñ,ô & h×/Ò/Ø#×4Ñ4°XÓ>÷ -Ô,ð ×4Ñ4×6Ò6ô '3Ø !¨ØDL×DWÑDWÒDc¬¨H¯L©L«N¸CÔ(@Ðilô'n˜œð  %÷ -Ò,ô "Ô"3×4Õ4ØŸ	™	×(Ñ(Ô*÷ 5ä)¨$¯)©)°T×:Ò:Ø(,˜œØ#÷' -Ò,ð" ;÷# -Ò,ñ %ô> '¨D¯I©IÀD×DUÑDUÔV÷ 4ð 4Ü ¨sÔ3ð 	Œáøô[ ô 	Ü&¨1¸#ÔFXÐY]×YbÑYb×YiÑYiÐknÓFoÔpˆDŒKÝûð	üò
:÷6 5×4ú÷ -×,Ñ,ûô( ô 	Ü&¨1¸#Ô>ˆDŒKÚÜô 	Ü&¨1¸#ÔFXÐY]×YbÑYbÐdgÓFhÔiˆDŒKÝûð	ús­   ‚'K Â	#L"Â1L"Ä"3M ÅM Å4L:Æ
M Æ!L:Æ:M ÇL:Ç<L:È	M È$L:È;L'É,L:Ê	M ÊM ËLË#1LÌLÌ'L7Ì2L:Ì:MÍ
M ÍN+Í/N+Í8N+Í9'N&Î&N+c               ó   € V ^8„  d   QhRR/# rß  r   )r   s   "r   r   r×  ò  s   € ÷ 	Zñ 	Z¨$ñ 	Zr   c                óò   € V P                   '       d   R# \        V P                  4      p\        e   \        R,          \	        V4      8X  d   R# \        V P                  4      ;'       d    \        V4      RJ # )u¢   The checkout lock is held, and not by this process's own update tree (our hold, or
a lock fd inherited from the update that spawned us â€” that tree may reclaim).FNr5   )rÛ  rC   r=   r6  r¡   r$  r[  )rZ  r5   s   & r   rñ  Ú#UpdateLock._checkout_held_elsewhereò  s]   € ð �>�>ˆ>ÙÜ! $×"3Ñ"3Ó4ˆÜÒ¤ v¥´#°d³)Ô!;Ùä! $×"3Ñ"3Ó4×YÐYÔ9KÈDÓ9QÐUYÐ9YÐYr   c               ó    € V ^8„  d   QhRRRR/# rE   r   )r   s   "r   r   r×  þ  s   € ÷ `ñ `˜ð ` ñ `r   c                	ó–   € V \         P                  ! 4       8H  ;'       g+    T ;'       d!    V \        4       8H  ;'       g    \        V 4      # r@   )r   r¸   r  r2  rÅ   s   &r   rï  ÚUpdateLock._is_partnerý  s9   € à”b—i’i“kÑ!×_Ð_ c×&^Ð&^¨s´l³nÑ/D×/]Ð/]ÔHXÐY\ÓH]Ð_r   c               ó    € V ^8„  d   QhRRRR/# )r   rô  rI  r   rH   r   )r   s   "r   r   r×    s   € ÷ ñ ¨ð °Tñ r   c                ó<  a € \        V4      p\        ;QJ d    V 3R lV 4       F  '       g   K   RM	  RM! V 3R lV 4       4      '       g>   \        V^ ,          VP                  '       d   VP	                  4       MRR7      S n        R# \        4       p\        P                  ! 4       V9  dï   VP                  V9  dÞ   VP                  eÐ   V'       dÈ   VP                  P                  R4      '       d   VP                  MVP                  R,           pVR\        P                  ! 4        RV R	2P                  4       ,           R
P                  R VP                   4       4      P                  4       ,           p\!        S P"                  VP$                  V4       R# )zpC1 rule 4: a LIVE claim by us, an ancestor or the hand-off partner is run under.
Called inside the marker mutex.c              3  ó¶   <"  € T FN  pSP                  V4      ;'       d1    V\        P                  ! 4       8H  ;'       g    \        V4      '       * x € KP  	  R # 5ir@   )rï  r   r¸   rA  )rl   ÚprZ  s   & €r   rn   Ú.UpdateLock._adopt_or_refuse.<locals>.<genexpr>  sG   øé € ÐnÑemÐ`a�4×#Ñ# AÓ&×[Ð[¨A´·²³Ñ,<×,ZÐ,ZÔDWÐXYÓDZÔ@ZÔ[Óemùs   ƒA AÁ ATFr  r  ó   
z	delegate:r•   ru  rþ   c              3  ó.   "  € T F  pR V R2x € K  	  R# 5irw  r   rx  s   & r   rn   r     s   é € ÐB±M¨S˜D   R�.³Mùrz  )r  ÚanyrC  rL  rõ   r-  rÿ   r   r¸   rM  r»   r[  rÌ  r{  r©   rR  r  r5   rK  )rZ  rô  r  Úownr[  Ú	delegateds   f&    r   rð  ÚUpdateLock._adopt_or_refuse  s  ø€ ô " (Ó+ˆß‹sÔnÑemÓn�s�sŠsÔnÑemÓn×nÒnÜ&¨8°A­;ÐV^×Vi×ViÐViÀHÇLÁLÄNÐorÔsˆDŒKÙÜÓˆÜ�9Š9‹;˜hÔ&¨8×+@Ñ+@ÈÔ+PØ×(Ñ(Ò4¿ð %-§M¡M×$:Ñ$:¸5×$AÒ$A�8—=’=ÀxÇ}Á}ÐW\ÕG\ˆDØ ¬2¯9ª9«;¨-°q¸¸¸RÐ@×GÑGÓIÕIØ—'‘'ÑB°H·M²MÓBÓB×IÑIÓKõLˆIä˜dŸi™i¨¯©°yÔAÙr   c               ó   € V ^8„  d   QhRR/# rã  r   )r   s   "r   r   r×    s   € ÷  ñ   ñ  r   c                	óP   € V P                   '       d   R V n         \        4        R# R# )FN)rÛ  r�  rY  s   &r   rã  ÚUpdateLock._drop_checkout  s   € Ø�>�>ˆ>Ø"ˆDŒNÜÖñ r   c               ó   € V ^8„  d   QhRR/# rã  r   )r   s   "r   r   r×    s   € ÷ "ñ "˜ñ "r   c                ó  €  V P                   '       dw   \        V P                  4      p\        P	                  V^4      ^,
          \        V&   \        V,          ^ 8:  d,   \        P                  VR4       \        V P                  4       R;T n
        T n         T P                  4        R#   \         d,   p\        P                  RT P                  T4        Rp?LQRp?ii ; i  R;T n
        T n         T P                  4        i ; i)um  Give back our part of the claim (A7 rule 5), decided under the marker mutex by
identity, not by the bytes we once wrote: whatever names this incarnation â€” as owner, or
as a delegate someone else wrote in (the hand-off script names its child) â€” is released;
a live delegate inherits an owner's claim. Only the outermost claim of a process
releases. Never raises.Nz&Could not release update marker %s: %sF)rÚ  r¡   r5   rÒ  r   r  Ú_release_markerr4   rM   rN   rÙ  rã  )rZ  r  rO   s   &  r   ÚreleaseÚUpdateLock.release  sÁ   € ð	"Ø�}�}ˆ}Ü˜$Ÿ)™)“n�Ü&Ÿ{™{¨3°Ó2°QÕ6”˜‘Ü˜3•< 1Ô$Ü—K‘K  TÔ*Ü# D§I¡IÔ.ð -2Ð1ˆDŒM˜DœMØ×ÑÖ!øô	 ô 	SÜ�L‰LÐAÀ4Ç9Á9Èc×RÑRûð	Sûð -2Ð1ˆDŒM˜DœMØ×ÑÕ!ús*   ‚BB* Â*C Â5!CÃC# ÃC Ã C# Ã# Dc               ó   € V ^8„  d   QhRR/# )r   r   rÔ  r   )r   s   "r   r   r×  +  s   € ÷ ñ ˜:ñ r   c                	ó&   € V P                  4        V # r@   )rå  rY  s   &r   Ú	__enter__ÚUpdateLock.__enter__+  s   € Ø�‰ŒØˆr   c               ó   € V ^8„  d   QhRR/# rã  r   )r   s   "r   r   r×  /  s   € ÷ ñ  ñ r   c                	ó&   € V P                  4        R # r@   )r  )rZ  Ú_excs   &*r   Ú__exit__ÚUpdateLock.__exit__/  s   € Ø�‰Žr   )rÛ  rÚ  rÙ  rÕ  r-  r=   r5   )râ   rã   rä   rå   ræ   rÜ  rå  rá  râ  rñ  Ústaticmethodrï  rð  rã  r  r  r  rè   r   r   r   rÔ  rÔ  ˆ  sm   † ñð ¨dð ÐVZð Ø(,÷õõ"
õ0õd	Zð ô`ó ð`õõ$ õ
"õ&÷ñ r   rÔ  c               ó    € V ^8„  d   QhRRRR/# rÈ  r   )r   s   "r   r   r   3  s   € ÷ 
.ñ 
.˜$ð 
. 4ñ 
.r   c           	     óp  € \        V 4      ;_uu_ 4        \        V 4      pVf    R R R 4       R # \        V4      w  r#VR8X  d2   \        \        4      ;_uu_ 4        V P                  4        R R R 4       MVR8X  d   \        WV4       R R R 4       R #   + '       g   i     L; i  + '       g   i     R # ; i)Nr¯  r­  )r  rµ  r°  r   r%  rÍ  r  )r5   rK  Úactionr  s   &   r   r  r  3  s‰   € Ü	�d×	Õ	Ü˜$ÓˆØŠ;Ø÷ 
Ñ	ô (¨Ó,‰ˆØ�XÔÜÔ+×,Õ,Ø—‘”÷ -Ð,à�yÔ Ü˜d¨Ô-÷ 
Ñ	÷ -×,ú÷ 
×	Ð	ús(   ”B$¯+B$ÁB	Á+B$ÂB!ÂB$Â$B5	i°  i   r@   r#   )„Ú__conditional_annotations__ræ   Ú
__future__r   r¥   rË  Úloggingr   ÚrerÀ  rŸ   r–   Ú	threadingr§   Ú
contextlibr   r   Údataclassesr   Úpathlibr   r±   r   Ú	getLoggerrâ   rM   rù   rò   rï   rñ   r�  r   rA   rB   r  r-  ÚUPDATE_EXIT_CONCURRENTr<  r=  r˜   r    r(   r;   rC   rP   re   rv   rµ   r½   rÆ   rÃ   rç   rÒ   rÚ   rÝ   rØ   r×   rû   rÿ   r  r&  r)  r2  r<  rA  rC  rŽ  r—  ÚcompileÚASCIIr„  rÌ   r˜  rš  rœ  rI  r‡  r¡  rª  r°  rµ  r¹  rÂ  rÅ  rÆ  rÏ  rÔ  ÚMUTEX_WAIT_SECONDSr4   rÑ  Úlocalr   rÕ  rá  rå  rû  r  r  r  r  r  r+  r5  r6  r8  r?  r;  r>  rO  r[  r_  rg  rx  r{  rr  rs  r�  r„  rˆ  ÚCREATE_SUSPENDEDrŽ  r–  rŒ  rš  r¾  rÁ  r$  rÎ  rÑ  rÒ  rÔ  r  )r  s   @r   Ú<module>r+     sŽ  øðôõ* #ã Û Û Û 	Û 	Û Û Û 
Û Û ß /Ý !Ý Ý à	×	Ò	˜8Ó	$€ð !(Ð ð !$Ð ð !Ð ð Ð ð !Ð à*€Ø*Ð Ø-Ð ð .€ð
 Ð ð
 Ð ð Ð ð
 €à)Ð õ3õ /õ*÷2\õ	òõ%õ$÷@+õ$ð €ˆÓ õ4÷Añ, �$Ô÷ð ó ðõaõ_÷$P÷0õ$õ-õ`!õHAõHnõñ: �$Ô÷
ð 
ó ð
ð €Ø€Ø�JŠJ�y "§(¡(Ó+€	Ø�JŠJÐ-¨r¯x©xÓ8€	Ø�:Š:Ð1°2·8±8Ó<€Ø—’ÐIÈ2Ï8É8ÓT€Ø�JŠJÐ5°r·x±xÓ@€	ñ �$Ô÷+Nð +Nó ð+Nõ\
-ð°t÷ ÷4;÷$õ.õ+õSð !Ð õKõ#ð" €àÐ ôU�ô Uð �oŠoÓ€õ4õ!õ.2õð< ðÐ.@ö ó ðõ6õ,
ð!¨Dð !ÐTX÷ !÷H÷(õ*ð< €€{Ó Ø€€tÓ õ÷$	ð $8Àa÷ 7õõõ>	Aõ/õ$9ð~ $'Ð  õ
õeõ!÷*'õ(ð Ð õõ4
Cõ7õ%÷Pw÷
g÷
õF)õXCð €ˆÓ ÷hñ h÷V
.r   