+
    jHàjçO  ã                   ó*  € R t ^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	H
t
 ^ RIHt ^ RIHt ^ RIHtHt ^ RIHtHt R	 tR
 tR t ! R R]4      t ! R R]4      tR tR tR tR tR tR tR!t R t!R t"R t#R t$R"R lt%R t&R t'R t(RR/R  lt)R# )#zMRestore only private, profile-bound local policy into the existing authority.N)ÚPath)ÚPlatform)ÚSessionEntryÚSessionSource)Ú
SessionRef)Úlocal_identity)ÚPOLICY_PREFIXÚlocal_receipt)ÚRuntimeStoreErrorÚlist_session_admissionsc                óØ   € V P                   p\        VRR4      pVe   VP                  V 4      MRpVf   VP                  # \        VRR4      pVf	   / ;qAn        VP                  V/ 4      # )a  The adapter map a LOCAL session of *authority* lives in: ``runner.adapters`` for the launch
profile, ``runner._profile_adapters[name]`` for a served secondary (its routed home, so
``_adapter_for_source`` / ``_adapters_for_profile`` resolve the right transport).Úsession_authoritiesNÚ_profile_adapters)ÚrunnerÚgetattrÚprofile_nameÚadaptersr   Ú
setdefault)Ú	authorityr   ÚregistryÚnameÚprofile_adapterss   &    ÚC/home/ubuntu/.hermes/hermes-agent/gateway/session_local_recovery.pyÚlocal_adapter_mapr      sy   € ð ×Ñ€FÜ�vÐ4°dÓ;€HØ/7Ò/Cˆ8× Ñ  Ô+È€DØ‚|Ø�‰ÐÜ˜vÐ':¸DÓAÐØÒØ68Ð8ÐÔ3Ø×&Ñ& t¨RÓ0Ð0ó    c                ó®   € \        \        P                  WRR7      p\        V P                  RR4      pVe   VP                  V 4      MRpVe   WSn        V# )a  LOCAL SessionSource for a session owned by *authority*. A served secondary's local sessions
carry its profile so ``build_session_key`` namespaces them (``agent:<name>:local:...``) and the
SessionStore writes their rows to that profile's ``state.db``, not the launch store.Údm)ÚplatformÚchat_idÚuser_idÚ	chat_typer   N)r   r   ÚLOCALr   r   r   Úprofile)r   r   r   Úsourcer   r   s   &&&   r   Úlocal_sourcer$      sS   € ô ¤H§N¡N¸GÐ`dÔe€FÜ�y×'Ñ'Ð)>ÀÓE€HØ/7Ò/Cˆ8× Ñ  Ô+È€DØÒØŒØ€Mr   c                ó€  € ^ RI pVP                  V P                  4      p\        V \        4      '       d   V P
                  M\        V 4      P                   RV  2pV'       d+   RVR,          P                   RVR,          P                   2MRpV P                  e   R\        V P                  4       2MRpV V V 2# )zê``<reason or error> at <function>:<line>``: where a receipt check raised, and why, followed
through every chained ``__cause__`` (``restore_policy`` and ``local_receipt`` wrap the check
that failed into a bare ``storage_unavailable``).Nz: z at Ú:Ú z, caused by éÿÿÿÿ)Ú	tracebackÚ
extract_tbÚ__traceback__Ú
isinstancer
   ÚreasonÚtypeÚ__name__r   ÚlinenoÚ	__cause__Ú_refused_check)Úexcr)   ÚframesÚcauseÚwhereÚchaineds   &     r   r2   r2   *   s­   € ó Ø×!Ñ! #×"3Ñ"3Ó4€FÜ$ SÔ*;×<Ò<ˆC�JŠJÄTÈ#ÃY×EWÑEWÐDXÐXZÐ[^ÐZ_ÐB`€Eß<Bˆd�6˜"•:—?‘?Ð# 1 V¨B¥Z×%6Ñ%6Ð$7Ñ8È€EØ@CÇÁÒ@Y�œ^¨C¯M©MÓ:Ð;Ñ<Ð_a€GØˆW�U�G˜G˜9Ð%Ð%r   c                   ó   € ] tR t^6tRtRtR# )Ú_ReceiptRefusedzRA refused receipt ``restore_local_session`` already logged with its failing check.© N©r/   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r:   r   r   r9   r9   6   s   † Ý\r   r9   c                   ó   € ] tR t^:tRtRtR# )Ú_CatchUpPendingzVThe receipt's compression catch-up is committing in a worker; this restore is refused.r:   Nr;   r:   r   r   rB   rB   :   s   † Ý`r   rB   c                óx  € ^ RI HpHp V P                  P	                  4       ;_uu_ 4       pV! WR4      f   VuuRRR4       #  RRR4       ^ RIHpHp V! 4       '       d   V! WV4       \        R4      hV! V P                  V P                  WR7       \        V P                  V4      #   + '       g   i     Ln; i)a¿  *receipt*, after recording compression steps an older build published past its tip (#140060).

The catch-up writes, so it never runs on the owner loop: a contended writer there would stall every
profile the loop serves. The async restore paths commit it in a worker first
(``session_local_adoption``); a sync restore on the loop that still finds it hands it to a tracked
worker, which publishes the session once it commits, and refuses this read.
)Úadopt_untracked_compressionÚadoptable_compressionN)Úon_owner_loopÚschedule_adoptionÚstorage_unavailable)ÚepochÚ
session_idÚexpected)Úhermes_state_local_lineagerD   rE   ÚdbÚ	_read_ctxÚgateway.session_local_adoptionrF   rG   rB   rI   r	   )r   ÚsidÚreceiptrD   rE   ÚconnrF   rG   s   &&&     r   Ú_with_untracked_compressionrS   >   s�   € ÷ ^Ø	�‰×	Ñ	×	!Ô	! TÙ  Ó/Ò7Ø÷ 
"Ò	!Ø7÷ 
"÷ PÙ‡‚Ù˜)¨'Ô2ÜÐ3Ó4Ð4Ù 	§¡°I·O±OÐPSÕfÜ˜Ÿ™ sÓ+Ð+÷ 
"×	!ús   «B)Â)B9	c                ó6  € VR,          V8w  d   \        R4      h\        P                  ! VR,          4      pRVR,          R,          9  d   VP                  VP                  n        VP
                  V8w  g.   VP                  P                  4       VP                  4       8w  d   \        R4      hV P                  P                  VP                  4      pVe6   VR,          VR,          VR	,          3W2P                  VP                  38w  d   \        R
4      hV# )zS*receipt*'s entry, once its route, origin and stored identity are this authority's.Úroutezroute mismatchÚentryr"   Úoriginzentry mismatchÚsession_keyr   r   zstored identity mismatch)Ú
ValueErrorr   Ú	from_dictr"   rW   rX   Úto_dictrM   Úget_sessionrJ   r   r   )r   rQ   r#   rU   rV   Úrows   &&&&  r   Ú_checked_entryr^   R   sç   € àˆwÕ˜5Ô ÜÐ)Ó*Ð*Ü×"Ò" 7¨7Õ#3Ó4€Eð ˜ Õ(¨Õ2Ô2Ø%Ÿ~™~ˆ�‰ÔØ×Ñ˜UÔ"Ø�|‰|×#Ñ#Ó%¨¯©Ó)9Ô9ÜÐ)Ó*Ð*Ø
�,‰,×
"Ñ
" 5×#3Ñ#3Ó
4€CØ
‚{�s˜=Õ)¨3¨y­>¸3¸y½>ÐJÈu×VdÑVdÐfl×ftÑftÐNuÔuÜÐ3Ó4Ð4Ø€Lr   c           	     ó¤  € \        V P                  V4      pVR,          V P                  8w  d   \        R4      hRV9   d
   VR,          M!\	        VR,          VR,          VR,          4      pVR,          V8w  g   W8w  d   \        R4      h\        WVR,          4      pV P                  P                  P                  V4      pW$V\        WWE4      3# )zY*sid*'s stored receipt with its LOCAL source, route and entry, once all are this owner's.Ú
profile_idÚprofile_mismatchÚlegacy_session_idÚprincipal_idÚ
request_idrJ   zidentity mismatch)r	   rM   r`   r
   r   rY   r$   r   Úsession_storeÚ_generate_session_keyr^   )r   rP   rQ   r   r#   rU   s   &&    r   Úowned_receiptrg   e   sÀ   € ä˜IŸL™L¨#Ó.€GØˆ|Õ 	× 4Ñ 4Ô4ÜÐ 2Ó3Ð3Ø/BÀgÔ/MˆwÐ*Ö+Ü˜g lÕ3°W¸^Õ5LÈgÐVbÕNcÓdð àˆ|Õ Ô# s¤~ÜÐ,Ó-Ð-Ü˜)¨g°nÕ.EÓF€FØ×Ñ×*Ñ*×@Ñ@ÀÓH€EØ˜E¤>°)ÀfÓ#TÐTÐTr   c           	     ó†  € V'       d   W!P                  RVR,          .4      9   d   R# V P                  P                  4       ;_uu_ 4       pVP                  RW"W"34      P	                  4       pRRR4       Xe   R# \
        P                  ! \        4      P                  RVR,          V4       R#   + '       g   i     LJ; i)a™  *session_id* is a replacement the SessionStore's stale-route self-heal minted on this local
route before #140642: outside the receipt's lineage, never admitted, no transcript. The receipt
is the route's truth, so restoring it drops that entry instead of refusing the conversation
forever (``admission_conflict`` on every resume). Anything with history or ledger rows still
refuses: it is not provably a stray.ÚlineagerJ   FzîSELECT 1 FROM messages WHERE session_id=? UNION ALL SELECT 1 FROM session_admissions WHERE target_session_id=? UNION ALL SELECT 1 FROM worker_executions WHERE session_id=? UNION ALL SELECT 1 FROM sessions WHERE parent_session_id=? LIMIT 1NzbLocal route for %s named an empty replacement %s outside its lineage; restoring the receipt targetT)	ÚgetrM   rN   ÚexecuteÚfetchoneÚloggingÚ	getLoggerr/   Úwarning)r   rQ   rJ   rR   Úbusys   &&&  r   Ú_stray_route_targetrq   s   s¦   € ÷ ˜§{¡{°9¸wÀ|Õ?TÐ>UÓ'VÔVÙØ	�‰×	Ñ	×	!Ô	! TØ�|‰|ðQð  ZÐ<ó	>÷ ?G¹h»jð	 	÷ 
"ð ÒÙÜ×Ò”hÓ×'Ñ'ØlØ�Õ˜zô+ñ ÷ 
"×	!ús   Á#B0Â0C 	c                 óZ  € ^ RI Hp ^ RIHp ^ RIHp  \        W4      w  rVrxVP                  V P                  P                  r©\        WV4      pV! VR,          4      pWµJd   T\        WWg4      r…TP                  p^ RIHp V P                  P!                  4       ;_uu_ 4       pV! Wõ4       RRR4       \C        T 4      pTPE                  \F        PH                  4      pTf   T! T 4      pTT\F        PH                  &   \7        TT4      '       d   TPJ                  T Jd   \9        R
4      hT PL                  PE                  T4      pTfæ   T
PN                  ;_uu_ 4        T
PQ                  4        T
PR                  PE                  T4      pTe;   TP                  T8w  d*   \U        YTP                  4      '       g   \9        R4      hRpTe   TPV                  Tn+        Yhn,        YŠPR                  T&   RRR4       TTPZ                  T	&   T! Yg4      T PL                  T&   TP]                  T4       MûTP_                  TP`                  4      '       dN   TP`                  Pc                  4       TPc                  4       8w  g!   TPZ                  PE                  T	4      T8w  d   \9        R	4      hT
PN                  ;_uu_ 4        T
Pe                  T4      pTe?   TP                  TPE                  RT.4      9  d(   \U        YTP                  4      '       g   \9        R4      hTTn        RRR4       \g        T Ph                  T4      #   + '       g   i     ELœ; i  \"         d    h \$        \&        \(        \*        3 d‰   p\,        P.                  ! \0        4      P3                  RT\5        T4      4       \7        T\8        4      '       d.   \;        TP<                  TP>                  TP@                  R7      Th\;        R	4      ThRp?ii ; i  + '       g   i     EL; i  + '       g   i     EL ; i)é    )ÚLiveSession)ÚLocalSessionAdapter)Úrestore_policyÚpolicy)Úvalidate_local_lineageNz$Local session %s receipt refused: %s)ÚfieldÚdetailrH   Úruntime_drainingÚadmission_conflictri   )5Úgateway.session_authorityrt   Úgateway.session_localru   Úgateway.session_policyrv   rg   r   r   re   rS   r^   rJ   rL   rx   rM   rN   rB   ÚKeyErrorÚ	TypeErrorrY   ÚAttributeErrorrm   rn   r/   ro   r2   r,   r
   r9   r-   ry   rz   r   rj   r   r!   r   ÚsessionsÚ_lockÚ_ensure_loaded_lockedÚ_entriesrq   ÚyolorW   ÚpoliciesÚregister_sourceÚauthorize_sourcer#   r[   Ú_entry_lockedr   r`   )r   rP   rt   ru   rv   rQ   r#   rU   rV   r   ÚstoreÚadoptedrw   Útargetrx   rR   r3   r   ÚadapterÚliveÚcurrents   &&                   r   Úrestore_local_sessionr’   ‰   sG  € Ý5Ý9Ý5ð>ä(5°iÓ(EÑ%ˆ˜ØŸ™¨×)9Ñ)9×)GÑ)G�Ü-¨i¸gÓFˆÙ ¨Õ 1Ó2ˆØÓ!Ø$¤n°YÈÓ&W�UØ×!Ñ!ˆÝEØ�\‰\×#Ñ#×%Ô%¨Ù" 4Ô1÷ &ô ! Ó+€HØ�l‰lœ8Ÿ>™>Ó*€GØ‚Ù% iÓ0ˆØ#*ˆ”—‘Ñ Ü�gÐ2×3Ò3°w×7HÑ7HÐPYÓ7YÜÐ 2Ó3Ð3Ø×Ñ×!Ñ! #Ó&€DØ‚|Ø�[�[‹[Ø×'Ñ'Ô)Ø—n‘n×(Ñ(¨Ó/ˆGØÒ" w×'9Ñ'9¸VÔ'CÜ*¨9¸w×?QÑ?Q×RÒRÜ+Ð,@ÓAÐAØ�ð Ò"Ø$Ÿ\™\�”
Ø!ŒLØ$)�N‰N˜5Ñ!÷ ð %+ˆ×Ñ˜Ñ!Ù"-¨fÓ"<ˆ	×Ñ˜3ÑØ×Ñ Õ'Ø×&Ñ& t§{¡{×3Ò3Ø�[‰[× Ñ Ó" f§n¡nÓ&6Ô6Ø×Ñ×!Ñ! 'Ó*¨fÔ4ÜÐ 5Ó6Ð6à�[�[‹[Ø×)Ñ)¨%Ó0ˆGØŠ 7×#5Ñ#5¸W¿[¹[ÈÐUXÐTYÓ=ZÔ#ZÜ+>¸yÐSZ×SeÑSe×+fÒ+fÜ'Ð(<Ó=Ð=Ø!'ˆGÔ÷ ô �i×*Ñ*¨CÓ0Ð0÷_ &×%Ð%ûäô ØÜ”i¤¬^Ð<ô >ä×Òœ(Ó#×+Ñ+Ð,RÐTWÔYgÐhkÓYlÔmÜ�cÔ,×-Ò-Ü! #§*¡*°C·I±IÀcÇjÁjÔQÐWZÐZÜÐ3Ó4¸#Ð=ûð>ú÷ �[ˆ[ú÷, �[ˆ[úsW   ”BM Â$	M Â-M ÅBPÊ<A&PÍ M	ÍM ÍM Í$PÍ9PÍ:BO=Ï=PÐP	ÐP*	c                óR  € V P                   VP                  ,          pVP                  em   VP                  P                  \        P
                  8X  dD   \        WP                  4       \        V P                  VP                  4      R,          R,          # V P                  V4      # )zYThe current physical transcript of logical *ref* (a local receipt's entry, else the tip).rV   rJ   )
rƒ   rJ   r#   r   r   r!   r’   r	   rM   Úphysical_target)r   Úrefr�   s   && r   Útranscript_targetr–   É   sq   € à×Ñ˜cŸn™nÕ-€DØ‡{�{Ò 4§;¡;×#7Ñ#7¼8¿>¹>Ô#IÜ˜i¯©Ô8Ü˜YŸ\™\¨3¯>©>Ó:¸7ÕCÀLÕQÐQØ×$Ñ$ SÓ)Ð)r   c           
     óü   € ^ RI Hp V P                  VRR7      pV Uu0 uF  qDR,          kK  	  pp V P                  V4       \	        Y0P                  TRRRR7      4      w  rgYVT3# u upi   T d	    T. R3u # i ; i)a²  ``(live row ids, display rows, truncated)`` of physical *target*, the live ids read first
(``local_history``'s fence). The display rows are the compression lineage as main's resume and the
REST transcript show it: every live row, and the newest compaction-archived rows that fit what the
live rows leave of ``RESUME_HISTORY_BYTES`` (``truncated`` when older ones were left out). A lineage
over the resume cap shows only the live rows.)ÚSessionResumeTooLargeErrorT©Úinclude_row_idsÚ_row_idF)Úinclude_ancestorsÚinclude_compactedrš   )Úhermes_stater˜   Úget_messages_as_conversationÚassert_resume_safeÚ_fit_archive)rM   rŽ   r˜   Ú	live_rowsr]   r�   ÚkeptÚ	truncateds   &&      r   Údisplay_rowsr¥   Ù   s¡   € õ 8Ø×/Ñ/°ÈÐ/ÓM€IÙ&/Ó0¡i˜s�	�NˆN¡i€DÐ0ðØ
×Ñ˜fÔ%ô # 9×.MÑ.MØ $¸$ÐPTð /Nó /Vó W�O€Dà�yÐ Ð ùò 1øð &ô Ø�R˜ˆÒðús   žA'²A, Á,A;Á:A;c           	     ót  € V  Uu0 uF  q"R,          kK  	  pp. \        R V  4       4      Rrep\        V4       Fk  pVR,          V9  dJ   V\        \        P                  ! V\
        R7      4      ,          pT;'       g
    V\        8„  pV'       d   KZ  VP                  V4       Km  	  VRRR1,          V3# u upi )zš``(display rows kept, truncated)``: every live row of *display*, and its newest archived rows that fit
what *live_rows* leave of ``RESUME_HISTORY_BYTES``.r›   c              3   ól   "  € T F*  p\        \        P                  ! V\        R 7      4      x € K,  	  R# 5i)©ÚdefaultN)ÚlenÚjsonÚdumpsÚstr©Ú.0r]   s   & r   Ú	<genexpr>Ú_fit_archive.<locals>.<genexpr>ï   s%   é € Ð#[ÑQZÈ#¤C¬¯
ª
°3ÄÔ(D×$EÐ$EÓQZùs   ‚24Fr¨   Nr(   )ÚsumÚreversedrª   r«   r¬   r­   ÚRESUME_HISTORY_BYTESÚappend)r¢   Údisplayr]   r�   r£   Úusedr¤   s   &&     r   r¡   r¡   ë   s¨   € ñ '0Ó0¡i˜s�	�NˆN¡i€DÐ0Ø¤Ñ#[ÑQZÓ#[Ó [Ð]b�	€DÜ˜Ö ˆØˆy�> Ô%Ø”CœŸ
š
 3´Ô4Ó5Õ5ˆDØ!×@Ð@ TÔ,@Ñ%@ˆIßÙØ�‰�CÖñ !ð ‘�"��:�yÐ Ð ùò 1s   …B5c              ƒ  ó„   "  € \        W4      pT\        P                  ! \        V P                  V4      G Rj  x€L
 3#  L5i)za``local_history``'s lineage read, off the owner loop; the locked part re-reads only the live tip.N)r–   ÚasyncioÚ	to_threadr¥   rM   )r   r•   rŽ   s   && r   Úprepare_historyr»   ú   s3   é € ä˜yÓ.€FØœ×*Ò*¬<¸¿¹ÀvÓN×NÐNÐNÑNùs   ‚6A ¸>¹A c                óà  € V Uu0 uF  q"R,          kK  	  pp. . ^ repV  FE  pVR,          V9   d   VP                  V4       . V^,           reK.  VP                  / VCRR/C4       KG  	  V  Uu0 uF  q"R,          kK  	  upV,          p. ^ r˜\        VR R7       FB  pVR,          V9   d!   VP                  WI,          4       V	^,          p	VP                  V4       KD  	  W…,           # u upi u upi )aý  The live rows in stored (``row_id``) order, each archived display row placed before the live
row it preceded in display order.

Display deduplication keeps a carried message at its FIRST copy's position, so after a rotated
compression the copied tail sits before the new summary. Clients take the live rows of a resume
as the transcript (the CLI's ``conversation_history``, ``/undo``'s prefix, rollback, ACP replay),
so the live subsequence must be the stored one; archived rows only anchor between live rows.r›   ÚarchivedTc                 ó   € V R ,          # )r›   r:   )Úrs   &r   Ú<lambda>Ú-_merge_live_in_stored_order.<locals>.<lambda>  s   € ¨!¨I®,r   )Úkey)rµ   ÚsortedÚextend)
r¶   r�   r]   r‘   ÚgroupsÚpendingÚshownÚ	shown_idsÚrowsÚseens
   &&        r   Ú_merge_live_in_stored_orderrË      sè   € ñ *.Ó.© #�9�~ˆ~©€GÐ.Ø  Q�U€FÛˆØˆy�>˜WÔ$Ø�M‰M˜'Ô"Ø ¨¥’Uà�N‰NÐ4˜cÐ4 :¨tÑ4Ö5ñ ñ ,3Ó3©7 C�Y—�©7Ñ3°gÕ=€IØ�Qˆ$Ü�dÑ 6×7ˆØˆy�>˜YÔ&Ø�K‰K˜�Ô%Ø�A�IˆDØ�‰�CÖñ	 8ð
 �>Ðùò /ùò 4s   …C&Á,C+c                ó€  € V P                   p\        W4      pVe   V^ ,          V8X  d
   V^,          M
\        W44      w  rVpVP                  VRR7      pV U	u0 uF  q™R,          kK  	  p
p	WZ8:  g#   \        W44      w  rVpVP                  VRR7      pM'W¥,
          '       d   \	        W†4      w  rkT;'       g    Tp\        Wh4       U	UUu. uF=  p	/ V	P                  4        UUu/ uF  w  rÍVR8w  g   K  WÍbK  	  uppCRV	R,          /CNK?  	  ppp	pV'       d   V'       d   RV^ ,          R&   V# u up	i u uppi u uppp	i )aP  Display history of logical *ref*: every stored row the user saw, in display order.

A row outside the current physical transcript's active set (summarized away by a compression)
carries ``archived: true``: it is shown, never live, so no undo, retry or rewind may target it.
The rows without it are exactly the live transcript's, so a client choosing among live rows sees
what it saw before. That includes a micro-compaction merge (``display_metadata.model_only``): its
originals are the archived rows renderers show, so renderers skip the merge itself.

Each row carries its durable ``messages.id`` as ``row_id`` (the ``TranscriptMessage`` field
Desktop hydration and the legacy ``session.history`` already use): a ``session.mutate`` rewind
addresses its ``target_message_id`` by it, so a snapshot without it leaves no way to undo/retry.
*prepared* (``prepare_history``) is kept while every row it read as live still is; a rewind or
compaction since then re-reads the lineage here. When the byte budget left older archived rows out
(``display_rows``), the first row carries ``archived_truncated: true``.
Tr™   r›   Úrow_idÚarchived_truncated)rM   r–   r¥   rŸ   r¡   rË   Úitems)r   r•   ÚpreparedrM   rŽ   Ú	read_liver¶   r¤   r�   r]   Úlive_idsÚcutÚkÚvrÉ   s   &&&            r   Úlocal_historyrÖ     s=  € ð  
�‰€BÜ˜yÓ.€FØ4<Ò4HÈXÐVWÍ[Ð\bÔMb X¨a¦[Ü*6°rÓ*Bñ "€I˜	à×*Ñ*¨6À4Ð*ÓH€DÙ*.Ó/©$ 3�I—�©$€HÐ/ØÔ Ü(4°RÓ(@Ñ%ˆ	˜IØ×.Ñ.¨vÀtÐ.ÓL‰Ø	×	Ô	ä# DÓ2‰ˆØ×$Ð$ ˆ	ä2°7ÔAõCÙA�ð [ §¡¤Ô?¡™˜°°Y±”�’¡Ò?ÐZÀÈ3ÈyÍ>ÔZÙAð 	ò Cç—TØ(,ˆˆQ�Ð$Ñ%Ø€Kùò 0ùó @ùô Cs$   ÁD.Ã	D9Ã"D3Ã2D3Ã8D9Ä3D9c                óÈ  € V P                   P                  VP                  4      pVe8   VP                  e*   VP                  P                  \
        P                  8w  d   R# \        V P                  VP                  4      R,          R,          pV P                  P                  V4      pVe3   VP                  R4      e   V P                  P                  V4       R# R# R# )u
  The first admitted turn makes a finalized local session live again (#85303).

Mounting (``session.resume``) is a read and leaves ``ended_at``/``end_reason`` alone; the drain
calls this after the turn's local preflight, before execution routes it. A TUI shutdown / WS
disconnect / idle eviction stamps ``end_reason`` on the physical row. ``SessionStore`` reads any
stamped row as a stale route (#54878) and, since those reasons are not recoverable, answers the
turn with a FRESH session â€” the client keeps waiting on an id that never emits again. The classic
surfaces clear the stamp on the first real turn (tui_gateway ``_reopen_if_finalized``); the
authority must too. Only the lineage tip is reopened: a
compression parent or reset predecessor is never the physical target.
NrV   rJ   Ú
end_reason)rƒ   rj   rJ   r#   r   r   r!   r	   rM   r\   Úreopen_session)r   r•   r�   rŽ   r]   s   &&   r   Úreopen_local_sessionrÚ   >  s¢   € ð ×Ñ×!Ñ! #§.¡.Ó1€DØ‚|�t—{‘{Ò*¨d¯k©k×.BÑ.BÄhÇnÁnÔ.TÙÜ˜9Ÿ<™<¨¯©Ó8¸ÕAÀ,ÕO€FØ
�,‰,×
"Ñ
" 6Ó
*€CØ
‚˜3Ÿ7™7 <Ó0Ò<Ø�‰×#Ñ# FÖ+ñ =�r   c                 ó  € ^ RI Hp \        VP                  Y#TVP                  VP
                  VP                  Ve   TMVP                  RR7	      pV P                  VP                  4      p\        V RR4      ;'       g    / pVe>   VP                  \        VP                  4      P                  4       V P                  4      MV P                  p	V! WyVP                  VP!                  4       R7       W`P"                  VP                  &   V# )rs   )Úreset_local_targetNT)rW   r   r    Údisplay_nameÚis_fresh_resetÚ_local_authority_epochs)rI   Úparent_session_idrV   )rL   rÜ   r   rX   rW   r   r    rÝ   Ú_db_for_keyr   rj   r   Údb_pathÚresolveÚ_local_authority_epochrJ   r[   r†   )
rŒ   Ú	old_entryrJ   ÚnowrÝ   rÜ   rV   rM   ÚepochsrI   s
   &&&&&     r   Úreset_local_sessionrè   S  sç   € Ý=Ü˜×.Ñ.°
ÀØ×Ñ¨)×*<Ñ*<È	×H[ÑH[Ø%1Ò%=‘\À9×CYÑCYØô€Eð 
×	Ñ	˜9×0Ñ0Ó	1€BÜ�UÐ5°tÓ<×BÐBÀ€FØTVÒTbˆF�J‰J”t˜BŸJ™JÓ'×/Ñ/Ó1°5×3OÑ3OÔPÐhm÷  iEñ  iE€EÙ�rØ)2×)=Ñ)=ÀUÇ]Á]Ã_õVà,1‡N�N�9×(Ñ(Ñ)Ø€Lr   c           	      ó  € V P                   P                  4       ;_uu_ 4       pVP                  R \        R,           34       Uu. uF  q"^ ,          \	        \        4      R NK  	  upuuRRR4       # u upi   + '       g   i     R# ; i)z+SELECT key FROM state_meta WHERE key LIKE ?Ú%N)rM   rN   rk   r   rª   )r   rR   r]   s   &  r   Úlocal_receipt_idsrë   b  sw   € Ø	�‰×	Ñ	×	!Ô	! TØ7;·|±|Ø9¼MÈCÕ<OÐ;Qô8Só Tñ 8S°�A•”sœ=Ó)Ð*Ó+ñ 8Sñ T÷ 
"Ò	!ùòT÷ 
"×	!Ð	!ús   £!A7Á!A2Á%A7Á2A7Á7B	ÚscheduleFc          	      óv  € \        V 4       F‡  p \        W4      p\        V P                  VR 7      pV'       dZ   V'       dP   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       g   V P                  V4       Kƒ  K…  K‡  K‰  	  V'       d¹   ^ RIHpHp ^ RIHp V! V 4       Fœ  pV P                  \'        V P(                  V4      4       \        ;QJ d1    R \        V P                  VR 7       4       F  '       g   K   RM&	  RM"! R \        V P                  VR 7       4       4      '       g   KŽ  V! W! W4      4       Kž  	  R# R#   \        \        3 d     EKb  \         dA   p\        P                  ! \        4      P                  RY%P                  4        Rp?EK§  Rp?ii ; i)	)rJ   c              3   ó8   "  € T F  qR ,          R8H  x € K  	  R# 5i©ÚstatusÚunknownNr:   r®   s   & r   r°   Ú)recover_local_sessions.<locals>.<genexpr>m  s   é € Ð/^ÑV]Ès°HµÀÖ0JÓV]ùó   ‚TFzLocal session %s paused: %sN)Úrearm_persisted_closesÚsettle_viewer_close)Útrack_mutationc              3   ó8   "  € T F  qR ,          R8H  x € K  	  R# 5irï   r:   r®   s   & r   r°   rò   y  s   é € ÐoÑ9n°#�x•= IÖ-Ó9nùró   )rë   r’   r   rM   ÚanyÚ	_scheduler9   rB   r
   rm   rn   r/   ro   r-   Úgateway.session_viewer_closerô   rõ   Úgateway.session_runtime_workersrö   r   r`   )	r   rì   rP   r•   rÆ   r3   rô   rõ   rö   s	   &$       r   Úrecover_local_sessionsrü   h  sD  € Ü  Ö+ˆð	`Ü'¨	Ó7ˆCÜ-¨i¯l©lÀsÔKˆGßŸG¯C«CÑ/^ÑV]Ó/^¯C¯CªCÑ/^ÑV]Ó/^×,^Ò,^Ø×#Ñ# CÖ(ñ -_™G‰xñ	 ,÷ ç\ÝBÙ)¨)Ö4ˆCØ×Ñ¤
¨9×+?Ñ+?ÀÓ EÔFß‹sÑoÔ9PÐQZ×Q]ÑQ]ÐjmÕ9nÓo�s�sŠsÑoÔ9PÐQZ×Q]ÑQ]ÐjmÕ9nÓo×oÔoá˜yÐ*=¸iÓ*MÖNó	 5ñ	 øô	  ¤Ð1ô 	ÛÜ ô 	`Ü×ÒœhÓ'×/Ñ/Ð0MÈs×T^ÑT^×_Ó_ûð	`ús;   �1EÁ
EÁEÁ!EÁ<EÅF8Å.F8Å7F8Å84F3Æ3F8i  0 )N)*r?   r¹   r«   rm   Úpathlibr   Úgateway.configr   Úgateway.sessionr   r   Úgateway.session_contractr   Úhermes_state_keysr   Úhermes_state_localr   r	   Úhermes_state_runtimer
   r   r   r$   r2   r9   rB   rS   r^   rg   rq   r’   r–   r´   r¥   r¡   r»   rË   rÖ   rÚ   rè   rë   rü   r:   r   r   Ú<module>r     s´   ðÙ SÛ Û Û Ý å #ß 7Ý /Ý ,ß ;ß Kò1ò	ò	&ô]Ð'ô ]ôaÐ'ô aò,ò(ò&Uòò,=1ò@*ð 'Ð ò!ò$!òOòô4!òH,ò*òTðO°%ö Or   