+
    „WÝj·m  ã                  ó’  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHtHtHtHtHtHt ^ RIHt  ^ RItR R lt]P.                  ! ]4      t]P4                  R8H  t]! 0 R;m4      t]! R	R
04      t]! RR04      t]! 0 R<m4      t ]! RR04      t!R R lt"R R lt#R R lt$R R lt%R R lt&R R lt'R=t(R>t)R?t*R R lt+R R lt,R R  lt-R! R" lt.R# R$ lt/R% R& lt0R' R( lt1R) R* lt2^êt3^!t4]Pj                  R+ 4       t6R, R- lt7R. R/ lt8R0 R1 lt9R2R/R3 R4 llt:R5R6/R7 R8 llt;R9 R: lt<R#   ] d    Rt ELi ; i)@a  Process and descriptor authority for state.db structural maintenance.

This module owns the proof that no foreign process still holds the active or
an unlinked SQLite DB/WAL/SHM generation.  ``hermes_state`` supplies only the
SQLite connection factory needed by the final lock probe.
)ÚannotationsN)ÚPath)ÚCallableÚListÚOptionalÚSequenceÚSetÚTuple)Úis_sqlite_lock_errorc               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚstr© )Úformats   "ÚHC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_state_holders.pyÚ__annotate__r      s   € ÷ 9ñ 9 ñ 9ó    c                ó^   € \        V 4      P                  4       P                  4       R,           # )z·``file:`` URI for a ``mode=ro`` open. ``as_uri()`` percent-encodes ``?``/``#`` in the home
path; a raw ``f"file:{path}?mode=ro"`` truncates there and opens the wrong (empty) database.z?mode=ro)r   ÚresolveÚas_uri)Údb_paths   &r   Úread_only_db_urir      s%   € ô �‹=× Ñ Ó"×)Ñ)Ó+¨jÕ8Ð8r   Úwin32Úacp_adapterzhermes_cli.mainzhermes_cli/main.pyzrun_agent.pyz--check-hash-based-pycsz--jitc               ó    € V ^8„  d   QhRRRR/# )r   ÚpidÚintr   zOptional[list[str]]r   )r   s   "r   r   r   -   s   € ÷ ñ ˜ð Ð!4ñ r   c                óZ  €  \        RV  R2R4      ;_uu_ 4       pVP                  4       pRRR4       X'       g   R# VP                  RR4      P                  R4      pVR	,          R8X  d   VP	                  4        T;'       g    R#   + '       g   i     Le; i  \
         d     R# i ; i)
z8Read /proc/<pid>/cmdline without losing argv boundaries.ú/proc/z/cmdlineÚrbNzutf-8ÚreplaceÚ Ú éÿÿÿÿ)ÚopenÚreadÚdecodeÚsplitÚpopÚOSError)r   ÚhandleÚrawÚargvs   &   r   Ú_read_proc_argvr.   -   sŒ   € ð
Ü�F˜3˜%˜xÐ(¨$×/Ô/°6Ø—+‘+“-ˆC÷ 0çÙØ�z‰z˜' 9Ó-×3Ñ3°FÓ;ˆØ��8�rŒ>Ø�H‰HŒJØ�|ˆ|�tÐ÷ 0×/ûô ô Úðús3   ‚B šB«B ½AB ÂB ÂB	ÂB ÂB*Â)B*c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r   r   )r   s   "r   r   r   <   s   € ÷ 	 ñ 	 ˜Sð 	  Sñ 	 r   c                ó   € \        V 4      pVf8   \        e0    \        P                  ! V 4      P                  4       ;'       g    RpV'       dd   RP                  RP                  \        P                  P                  V^ ,          4      .VR,          O4      P                  4       4      R,          MRpRV  RV R2#   \         d    Rp L…i ; i)	zf``PID 123 (hermes gateway run)`` for operator-facing holder lists; /proc argv first, psutil elsewhere.NÚ ºé   NNºNéP   Nzcommand line unavailablezPID z (Ú))
r.   ÚpsutilÚProcessÚcmdlineÚ	ExceptionÚjoinÚosÚpathÚbasenamer(   )r   r-   Úwhos   &  r   Údescribe_holder_pidr@   <   s²   € ä˜3Ó€DØ‚|œÒ*ð	Ü—>’> #Ó&×.Ñ.Ó0×8Ð8°DˆD÷ VZˆ#�(‰(�3—8‘8œRŸW™W×-Ñ-¨d°1­gÓ6ÐB¸¸b½ÐBÓC×IÑIÓKÓ
LÈSÖ
QÐ_y€CØ�#��b˜˜˜QÐÐøô ô 	ØŠDð	ús   ™*B= ÁB= Â=CÃCc               ó    € V ^8„  d   QhRRRR/# )r   Úprogramr   r   Úboolr   )r   s   "r   r   r   H   s   € ÷ ñ ¨3ð °4ñ r   c                ól  € \         P                  P                  V 4      P                  4       P	                  R 4      pR Fq  pVP                  V4      '       g   K  V\        V4      R pV'       * ;'       g9    \        ;QJ d     R V 4       F  '       d   K   Ru # 	  Ru # ! R V 4       4      u # 	  R# )ú.exeNc              3  óZ   "  € T F!  qP                  4       ;'       g    VR 8H  x € K#  	  R# 5i)Ú.N)Úisdigit)Ú.0Úchars   & r   Ú	<genexpr>Ú0_looks_like_python_executable.<locals>.<genexpr>M   s#   é € Ð$VÉvÀt§\¡\£^×%BÐ%B°t¸s±{Ô%BËvùs   ‚+�+FT)ÚpythonÚpypy)r<   r=   r>   ÚlowerÚremovesuffixÚ
startswithÚlenÚall)rB   ÚnameÚprefixÚsuffixs   &   r   Ú_looks_like_python_executablerW   H   s‹   € Ü�7‰7×Ñ˜GÓ$×*Ñ*Ó,×9Ñ9¸&ÓA€DÛ$ˆØ�?‰?˜6×"Ô"Øœ#˜f›+˜-Ð(ˆFØ”:×VÐV§£Ñ$VÉvÓ$V§¤ÒV¢ÒV Ñ$VÉvÓ$VÓ!VÒVñ %ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   r-   úSequence[str]r   zOptional[tuple[str, str]]r   )r   s   "r   r   r   Q   s   € ÷ &ñ & =ð &Ð5Nñ &r   c                ó  € ^pV\        V 4      8  Edl   W,          pVR8X  d&   V^,          pV\        V 4      8  d   RW,          3# R# V\        9   d   V^,          pK[  VP                  R4      '       g   VP                  R4      '       d   V^,          pK”  VP                  R4      '       d   V^,          pK¶  VP                  R4      '       d¬   VR8w  d¥   VR,          p^ pRpV\        V4      8  ds   W4,          pW4^,           R pVR	8X  d   R# VR
8X  d2   V'       d   RV3# V^,          pV\        V 4      8  d   RW,          3# R# V\        9   d	   V'       * pMV^,          pK‚  Y'       d   ^M^,          pEKx  RV3# R# )zCReturn the Python module or script selected by interpreter options.z--ÚscriptNz--check-hash-based-pycs=z--jit=Ú-r2   FÚcÚmÚmodule)rR   Ú"_PYTHON_LONG_OPTIONS_WITH_OPERANDSrQ   Ú#_PYTHON_SHORT_OPTIONS_WITH_OPERANDS)r-   ÚindexÚargÚoptionsÚoption_indexÚconsumed_nextÚoptionÚattacheds   &       r   Ú_python_execution_targetri   Q   sm  € à€EØ
”#�d“)Õ
Ø�kˆØ�$Œ;Ø�Q�JˆEØ.3´c¸$³iÔ.?�H˜d�kÐ*ÐIÀTÐIØÔ4Ô4Ø�Q�JˆEÙØ�>‰>Ð4×5Ò5¸¿¹È×9QÒ9QØ�Q�JˆEÙØ�>‰>˜$×ÒØ�Q�JˆEÙØ�>‰>˜#×Ò 3¨#¤:Ø˜"•gˆGØˆLØ!ˆMØ¤ W£Ô-Ø Õ.�Ø"°!Õ#3Ð#5Ð6�Ø˜S”=ÙØ˜S”=ßØ'¨Ð1Ð1Ø˜Q•J�EØ6;¼cÀ$»iÔ6G˜H d¥kÐ2ÐQÈTÐQØÔ@Ô@Ø(0¤L�MØØ Õ!’Øž-‘Q¨QÕ.ˆEÚØ˜ˆ}ÐÙr   c               ó    € V ^8„  d   QhRRRR/# )r   r-   rY   r   rC   r   )r   s   "r   r   r   z   s   € ÷ ñ ˜]ð ¨tñ r   c                óì  a€ V '       g   R# \         P                  P                  V ^ ,          4      P                  4       P	                  R4      pV\
        9   d   R# \        V4      '       g   R# \        V 4      pVf   R# Vw  r4VP                  4       P                  RR4      oVR8X  d
   S\        9   # \        ;QJ d#    V3R l\         4       F  '       g   K   R# 	  R# ! V3R l\         4       4      # )zCReturn whether argv identifies a supported Hermes execution target.FrE   TÚ\Ú/r_   c              3  óf   <"  € T F&  pSV8H  ;'       g    SP                  R V 24      x € K(  	  R# 5i)rm   N)Úendswith)rI   r[   Ú
normalizeds   & €r   rK   Ú%_looks_like_hermes.<locals>.<genexpr>Š   s9   øé € ð á,ˆFð 	�fÑ×AÐA 
× 3Ñ 3°a¸°x°LÓ AÔAÛ,ùs   ƒ1”1)r<   r=   r>   rO   rP   Ú_HERMES_EXECUTABLESrW   ri   r!   Ú_HERMES_PYTHON_MODULESÚanyÚ_HERMES_PYTHON_SCRIPTS)r-   rB   ÚtargetÚkindÚvaluerp   s   &    @r   Ú_looks_like_hermesry   z   sÏ   ø€ çÙÜ�g‰g×Ñ˜t A�wÓ'×-Ñ-Ó/×<Ñ<¸VÓD€GØÔ%Ô%ÙÜ(¨×1Ò1ÙÜ% dÓ+€FØ‚~ÙØ�K€DØ—‘“×&Ñ& t¨SÓ1€JØˆxÔØÔ3Ñ3Ð3ß‹3ô å,ó�3Œ3ð Š3ð ˆ3ô å,óó ð r   c               ó    € V ^8„  d   QhRRRR/# )r   r=   r   r   r   )r   s   "r   r   r   �   s   € ÷ Nñ N ð N¨ñ Nr   c                ó˜   € \         P                  P                  \         P                  P                  V P	                  R4      4      4      # )zGNormalize a /proc fd target, stripping the Linux `` (deleted)`` suffix.ú
 (deleted))r<   r=   ÚnormcaseÚabspathrP   )r=   s   &r   Úcanonical_sqlite_pathr   �   s/   € ä�7‰7×ÑœBŸG™GŸO™O¨D×,=Ñ,=¸lÓ,KÓLÓMÐMr   c               ó    € V ^8„  d   QhRRRR/# )r   rx   r   r   r   )r   s   "r   r   r   š   s   € ÷ 5ñ 5�cð 5˜cñ 5r   c                óz   € \         P                  P                  \         P                  P                  V 4      4      # ©N)r<   r=   r}   Únormpath)rx   s   &r   Ú
_norm_pathr„   š   s&   € Ü�7‰7×ÑœBŸG™G×,Ñ,¨UÓ3Ó4Ð4r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r-   rY   Úflagsr   úOptional[str]r   )r   s   "r   r   r   ž   s!   € ÷ ñ ˜=ð °ð À=ñ r   c                óž  € Rp^ \        V 4      rCW48  d¹   W,          p\        V\        4      '       d�   WQ9   dL   V^,           V8  d>   \        W^,           ,          \        4      '       d   W^,           ,          pV^,          pKu  V F8  pVP                  VR,           4      '       g   K#  V\        V4      ^,           R p M	  V^,          pK¾  V# )z[Last ``--flag X`` / ``--flag=X`` value, token-exact (``--profile timothy`` is not ``tim``).NÚ=)rR   Ú
isinstancer   rQ   )r-   r†   rx   rb   ÚcountÚtokenÚflags   &&     r   Ú_argv_flag_valuerŽ   ž   s¬   € à€EØ”c˜$“iˆ5Ø
Œ-Ø•ˆÜ�eœS×!Ò!ØŒ~ %¨!¥)¨eÔ"3¼
À4ÐPQÍ	Å?ÔTW×8XÒ8XØ Q�Y��Ø˜•
�ÙÛ�Ø×#Ñ# D¨3¥J×/Ô/Ø!¤# d£)¨a¥- .Ð1�EÙñ ð 	��
ŠØ€Lr   c               ó    € V ^8„  d   QhRRRR/# )r   r-   rY   r   r‡   r   )r   s   "r   r   r   ±   s   € ÷ ñ ˜ð ¨=ñ r   c                óº   € \        \        V 4      4       FB  p\        V\        4      '       g   K  VP	                  R4      '       g   K4  V\        R4      R u # 	  R# )u]   ``HERMES_HOME=<path>`` env-style assignment on the argv (``env HERMES_HOME=â€¦ hermes â€¦``).zHERMES_HOME=N)ÚreversedÚlistrŠ   r   rQ   rR   )r-   rŒ   s   & r   Ú_argv_env_homer“   ±   sJ   € äœ$˜t›*Ö%ˆÜ�eœS×!Ô! e×&6Ñ&6°~×&FÔ&FØœ˜^Ó,Ð-Ð.Ò.ñ &ñ r   c               ó    € V ^8„  d   QhRRRR/# )r   Ú	this_homer   r   z#tuple[Optional[str], Optional[str]]r   )r   s   "r   r   r   ¹   s   € ÷ ñ  Sð Ð-Pñ r   c                óœ  €  ^ RI Hp V! V 4      pVeI   \        P                  P	                  \        VP                  P                  4      4      VP                  3# \        P                  P                  V 4      R8X  d"   \        P                  P	                  V 4      R3#  R#   \         d    \        P                  RT RR7        R# i ; i)u	  ``(<install root>, <our profile name>)`` for the home holding the store, else ``(None, None)``.

Derived with the canonical ``named_profile_home`` predicate, never a ``basename == "profiles"``
string test: an arbitrary ``<X>/profiles/<n>/`` tree is not a Hermes install, and promoting
``<X>`` to "ours" swallows an unrelated instance living under it â€” the literal two-instance
shape of #92401. The root store (``~/.hermes/state.db``) is its own root with no profile name,
so ANY named-profile selection contradicts it.
)Únamed_profile_homeNz.hermesz+Could not classify the install layout of %sT)Úexc_info)NN)Úhermes_constantsr—   r<   r=   r~   r   ÚparentrT   r>   r:   ÚloggerÚdebug)r•   r—   Úprofile_homes   &  r   Ú_store_install_layoutrž   ¹   s³   € ð	^Ý7á)¨)Ó4ˆØÒ#Ü—7‘7—?‘?¤3 |×':Ñ':×'AÑ'AÓ#BÓCÀ\×EVÑEVÐVÐVÜ�7‰7×Ñ˜IÓ&¨)Ô3Ü—7‘7—?‘? 9Ó-¨tÐ3Ð3ð 4ð Ðøô ô ^Ü�‰ÐBÀIÐX\ˆÕ]ØÐð^ús   ‚AB$ ÁAB$ Â$#CÃ
Cc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rp   r   Úinstall_rootr‡   Úour_profiler   rC   r   )r   s   "r   r   r   Ï   s0   € ÷ [ñ [ Sð [¸ð [ÐTað [Ðfjñ [r   c                óž  € Vf   R# \        \        P                  P                  VR4      4      \        P                  ,           pV P                  V4      '       g   R# V \        V4      R P                  \        P                  ^4      ^ ,          p\        V4      ;'       d,    YB'       d    \        P                  P                  V4      MR8g  # )z\True when the token is under ``<install root>/profiles/<name>`` for a name that is not ours.NFÚprofiles)
r„   r<   r=   r;   ÚseprQ   rR   r(   rC   r}   )rp   r    r¡   rU   rT   s   &&&  r   Ú_names_other_profiler¥   Ï   s’   € àÒÙÜœŸ™Ÿ™ \°:Ó>Ó?Ä"Ç&Á&ÕH€FØ× Ñ  ×(Ò(ÙØ”c˜&“k�lÐ#×)Ñ)¬"¯&©&°!Ó4°QÕ7€DÜ�‹:×ZÐZ˜$ÆK¤2§7¡7×#3Ñ#3°KÔ#@ÐUYÑZÐZr   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r-   rY   r•   r   r    r‡   r¡   r   r   )r   s   "r   r   r   Ú   s4   € ÷ ñ Ø
ðØ$'ðØ7DðØS`ðàñr   c                ó   € \        V \        4      ;'       g    \        V 4      pV'       d   \        V4      \        V4      8X  d   R# R# \        V \        4      pV'       d   Ve   WS8X  d   R# R# Ve
   VR8X  d   R# R# R# )aJ  ``"ours"``/``"other"``/``None`` from the process's OWN profile/home selection.

Under one process per host the shared binary path proves nothing about which home a process
serves; its ``--hermes-home``/``HERMES_HOME=``/``--profile``/``-p`` selection does. Same
token-exact parsers ``gateway/run.py::_argv_contradicts_home`` uses.
ÚoursÚotherNÚdefault)rŽ   Ú_HOME_FLAGSr“   r„   Ú_PROFILE_FLAGS)r-   r•   r    r¡   Ú
home_valueÚprofile_values   &&&&  r   Ú_argv_home_selectionr¯   Ú   s|   € ô " $¬Ó4×LÐL¼ÀtÓ8L€JßÜ# JÓ/´:¸iÓ3HÔHˆvÐUÈgÐUÜ$ T¬>Ó:€MßØÒ"Ø*Ô9�6ÐF¸wÐFà&Ò2°}È	Ô7QˆvÐ_ÐX_Ð_Ùr   c               ó    € V ^8„  d   QhRRRR/# )r   r-   rY   r   úlist[tuple[int, str]]r   )r   s   "r   r   r   ï   s   € ÷ ñ ˜Mð Ð.Cñ r   c                ó„  € . p\        V 4       F®  w  r#\        V\        4      '       g   K  VP                  R4      '       d   TpMUVP                  R4      '       d=   RV9   d6   VP	                  R^4      ^,          pVP                  R4      '       d   TMRpMRpVf   K’  VP                  V\        V4      34       K°  	  V# )zH``(argv index, normalized absolute path)`` for every path-bearing token.rm   r\   r‰   N)Ú	enumeraterŠ   r   rQ   r(   Úappendr„   )r-   Útokensrb   rŒ   Ú
path_tokenrx   s   &     r   Ú_argv_path_tokensr·   ï   sª   € à$&€FÜ! $ž‰ˆÜ˜%¤×%Ò%ÙØ×Ñ˜C× Ò Ø‰JØ×Ñ˜c×"Ò" s¨e¤|ð —K‘K  QÓ'¨Õ*ˆEØ"'×"2Ñ"2°3×"7Ò"7™¸T‰JàˆJØÔ!Ø�M‰M˜5¤*¨ZÓ"8Ð9Ö:ñ (ð €Mr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r-   rY   r   r   r   rC   r   )r   s   "r   r   r     s!   € ÷ :ñ : ]ð :¸Tð :Àdñ :r   c                óx  a€ \         P                  P                  \         P                  ! V4      4      p\         P                  P	                  V4      p\        V4      w  rE\        V4       Uu0 uF"  p\         P                  P                  V4      kK$  	  upo\         P                  P                  V4      pV'       d    \         P                  P                  V4      MRp\        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      '       d   R# \        WWE4      p
V
R8X  d   R# VRJpV
R8H  pV	 Fã  w  rÞ\        WäV4      '       d   RpK  Wç8X  g-   VP                  V\         P                  ,           4      '       d    R# Ve5   Wè8X  g-   VP                  V\         P                  ,           4      '       d   Kˆ  V^ 8X  d   V'       g   K™  RV9   gB   VP                  R4      '       g+   \         P                  P                  V4      \         9   g   Ká  RpKå  	  V# u upi )uU  Return whether argv proves the process belongs to a DIFFERENT instance.

``state.db`` lives at the HERMES_HOME root, so an absolute-path token
containing a ``/.hermes`` segment (or naming a ``state.db``/WAL/SHM under
some other parent) identifies that token's own Hermes home.  When at least
one such token exists AND no token references this instance's state.db,
its sidecars, or its home directory, the process provably works on a
different generation and must not be counted as an uninspectable holder
of ours (issue #92401: a second gateway under /home/demo/.hermes deferred
this instance's stale-FTS rebuild forever despite lsof proving zero open
handles).  Ambiguous argv without absolute-path tokens returns False and
keeps the fail-closed suspicion.

Evidence is ranked, because one host now runs ONE process for every profile:

1. A token naming our state.db or a sidecar exactly â€” definitive, ours.
2. The process's own ``--hermes-home``/``HERMES_HOME=``/``--profile``/``-p``
   selection â€” that is what decides which home a multiplexer serves.
3. Path tokens. A token under ``<install root>/profiles/<other>`` is another
   profile's store even though it sits under our root; a token that names only
   the SHARED install root is NEUTRAL (it is the same binary for every profile,
   so it can neither prove nor disprove a hold); ``argv[0]`` locates the INSTALL,
   not the home, so it is not other-home evidence for a store whose home is not
   part of an install layout (a custom ``HERMES_HOME`` is served BY the binary
   under ``~/.hermes`` â€” dismissing on it admits maintenance under a live writer).
Nc              3  ó2   <"  € T F  w  rVS9   x € K  	  R # 5ir‚   r   )rI   Ú_rp   Úsidecarss   &  €r   rK   Ú-_argv_scoped_to_other_home.<locals>.<genexpr>&  s   øé € Ð
C±{¡m aˆ:˜Ö!³{ùs   ƒTFr¨   r©   z/.hermes)r<   r=   r~   ÚfspathÚdirnamerž   Ú_sqlite_familyr}   r·   rt   r¯   r¥   rQ   r¤   ro   r>   Ú_STATE_DB_NAMES)r-   r   Údb_path_strr•   r    r¡   Ú	candidateÚthis_home_normÚ	root_normÚpath_tokensÚ	selectionÚargv0_locates_homeÚother_home_seenrb   rp   r¼   s   &&             @r   Ú_argv_scoped_to_other_homerÊ     s°  ø€ ô6 —'‘'—/‘/¤"§)¢)¨GÓ"4Ó5€KÜ—‘—‘ Ó,€IÜ 5°iÓ @Ñ€LÜ=KÈKÔ=XÓYÑ=X°	”—‘× Ñ  Ö+Ñ=XÑY€HÜ—W‘W×%Ñ% iÓ0€Nß2>”—‘× Ñ  Ô.ÀD€IÜ# DÓ)€Kç
ƒsÔ
C±{Ó
C‡s‡s‚sÔ
C±{Ó
C×CÒCÙÜ$ T°lÓP€IØ�FÔÙð &¨TÐ1ÐØ 7Ñ*€OÛ(ÑˆÜ 
¸+×FÒFØ"ˆOÙØÔ'¨:×+@Ñ+@ÀÔRT×RXÑRXÕAX×+YÒ+YÚØÒ ØÔ# z×'<Ñ'<¸YÌÏÉÕ=O×'PÒ'PáØ�AŒ:×0ÙØ˜Ô# z×':Ñ':¸:×'FÒ'FÌ"Ï'É'×JZÑJZÐ[eÓJfÔjyÖJyØ"ŠOñ )ð Ðùò9 Zs   Á.(H7c                 ó–  aa€ ^ RI p ^ RI Ho  ! V3R lRV P                  4      o ! VV3R lRV P                  4      pRV P                  SP                  4      SP                  SP
                  .RSP                  SP                  V P                  SP                  4      SP                  V P                  SP                  V P                  .R	SP                  V P                  SP                  4      V P                  SP                  4      V P                  V4      V P                  SP                  4      .R
SP                  ./pW3# )a:  Restart Manager ctypes metadata, built once on first scan.

Once, because ``ctypes.POINTER()`` on a freshly defined Structure pins it in
``ctypes._pointer_type_cache`` forever (a per-scan rebuild leaked a class set per call);
lazily, because POSIX processes import this module but never scan with Restart Manager.
N©Úwintypesc                  óT   <€ ] tR tRtR Z P                  3R Z P
                  3.tRtR# )Ú$_rm_ctypes.<locals>._RmUniqueProcessiO  r   Ústartedr   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__ÚDWORDÚFILETIMEÚ_fields_Ú__static_attributes__rÌ   s   €r   Ú_RmUniqueProcessrÏ   O  s!   ø† Ø™HŸN™NÐ+¨i¹×9JÑ9JÐ-KÐLŒr   rÙ   c                  óè   <€ ] tR tRtR Z 3R ZP                  R,          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# )Ú"_rm_ctypes.<locals>._RmProcessInfoiR  ÚprocessÚapp_nameé   Úservice_nameÚapp_typeÚ
app_statusÚts_session_idÚrestartabler   N)
rÑ   rÒ   rÓ   rÔ   ÚWCHARrÕ   ÚULONGÚBOOLr×   rØ   )rÙ   rÍ   s   €€r   Ú_RmProcessInforÛ   R  se   ø† àÑ(Ð)Ø™Ÿ™¨#Õ-Ð.Ø™XŸ^™^¨bÕ0Ð1Ø™Ÿ™Ð(Ø™8Ÿ>™>Ð*Ø™hŸn™nÐ-Ø™HŸM™MÐ*ð
Œr   rç   ÚRmStartSessionÚRmRegisterResourcesÚ	RmGetListÚRmEndSession)	ÚctypesrÍ   Ú	StructureÚPOINTERrÕ   ÚLPWSTRÚUINTÚLPCWSTRÚc_void_p)rì   rç   ÚargtypesrÙ   rÍ   s      @@r   Ú
_rm_ctypesrô   D  s  ù€ ó Ý÷M˜6×+Ñ+ô M÷	
ð 	
˜×)Ñ)ô 	
ð 	˜6Ÿ>™>¨(¯.©.Ó9¸8¿>¹>È8Ï?É?Ð[ØØ�N‰N˜HŸM™M¨6¯>©>¸(×:JÑ:JÓ+KØ�M‰M˜6Ÿ?™?¨H¯M©M¸6¿?¹?ð 
ð 	Ø�N‰N˜FŸN™N¨8¯=©=Ó9¸6¿>¹>È(Ï-É-Ó;XØ�N‰N˜>Ó*¨F¯N©N¸8¿>¹>Ó,Jð
ð 	˜Ÿ™Ð(ð€Hð Ð#Ð#r   c               ó    € V ^8„  d   QhRRRR/# )r   Úbaser   r   ztuple[str, str, str]r   )r   s   "r   r   r   l  s   € ÷ 0ñ 0˜ð 0Ð!5ñ 0r   c                ó&   € W R,           V R,           3# )zXThe main database file plus the ``-wal``/``-shm`` sidecars SQLite may hold alongside it.z-walz-shmr   )rö   s   &r   rÀ   rÀ   l  s   € à˜•- ¨¥Ð/Ð/r   c               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r   r±   r   )r   s   "r   r   r   q  s   € ÷ 5ñ 5¨dð 5Ð7Lñ 5r   c           
     óz  € ^ RI p^ RI Hp \        4       w  r4VP                  RRR7      pVP	                  4        F'  w  rg\        WV4      pWxn        VP                  Vn        K)  	  VP                  VP                  VP                  VP                  3w  ršr¼\        P                  P                  \        P                   ! V 4      4      p\#        V4       Uu. uF,  p\        P                  P%                  V4      '       g   K*  VNK.  	  ppV'       g   . # VP                  4       pVP'                  \(        4      pV	! VP+                  V4      ^ V4      pV'       d   \-        VR4      h VP.                  \1        V4      ,          ! V!  pV
! V\1        V4      V^ R^ R4      pV'       d   \-        VR4      hVP3                  4       VP                  4       pp\5        ^4       EF9  pVVP6                  ,          ! 4       pVP3                  VP6                  4      pT! TVP+                  V4      VP+                  V4      VP6                  '       d   TMRVP+                  V4      4      pV^ 8X  d˜   \        P8                  ! 4       p\5        VP6                  4       Uu. uFX  p\;        VV,          P<                  P>                  4      V8w  g   K0  \;        VV,          P<                  P>                  4      V3NKZ  	  upu V! V4       # V\@        8w  g   EK0  \-        VR4      h	  \C        R	4      hu upi u upi   T! T4       i ; i)
zUReturn foreign processes using state.db or a WAL sidecar via Windows Restart Manager.NrÌ   ÚrstrtmgrT)Úuse_last_errorzRmStartSession failedzRmRegisterResources failedzRmGetList failedz(Restart Manager holder set kept changing)"rì   rÍ   rô   ÚWinDLLÚitemsÚgetattrró   rÕ   Úrestyperè   ré   rê   rë   r<   r=   r~   r¾   rÀ   ÚexistsÚcreate_unicode_bufferÚ_RM_SESSION_KEY_LENÚbyrefr*   rñ   rR   rð   Úrangerx   Úgetpidr   rÜ   r   Ú_RM_ERROR_MORE_DATAÚRuntimeError)r   rì   rÍ   Úprocess_inforó   ÚapirT   ÚtypesÚfnÚstartÚregisterÚget_listÚendÚ
db_abspathr=   Ú	resourcesÚsessionÚkeyÚrcÚ	filenamesÚneededÚreasonsr»   Úappsr‹   Úown_pidrb   s   &                          r   Ú _windows_restart_manager_holdersr  q  s   € ãÝä'›\Ñ€Là
�-‰-˜
°4ˆ-Ó
8€CØ—~‘~Ö'‰ˆÜ�SÓˆØŒØ—^‘^ˆŽ
ñ (ð
 	×Ñ˜C×3Ñ3°S·]±]ÀC×DTÑDTð&Ñ"€E�Xô —‘—‘¤§¢¨7Ó!3Ó4€JÜ"0°Ô"<ÓUÑ"<˜$ÄÇÁÇÁÈt×@T—�Ñ"<€IÐUßØˆ	à�n‰nÓ€GØ
×
&Ñ
&Ô':Ó
;€CÙ	ˆv�|‰|˜GÓ$ a¨Ó	-€Bß	Ü�bÐ1Ó2Ð2ðØ×%Ñ%¬¨I«Ö6¸ÑCˆ	Ù�gœs 9›~¨y¸!¸TÀ1ÀdÓKˆßÜ˜"Ð:Ó;Ð;ð #Ÿ-™-›/¨8¯>©>Ó+;�ˆÜ�q—ˆAØ  6§<¡<Ö/Ó2ˆDØ—M‘M &§,¡,Ó/ˆEÙØ˜Ÿ™ fÓ-¨v¯|©|¸EÓ/BØŸŸ˜‘¨$°·±¸WÓ0EóˆBð �QŒwÜŸ)š)›+�ô "' u§{¡{Ô!3óá!3˜Ü˜4 �;×.Ñ.×2Ñ2Ó3°wÑ>ô ?”S˜˜e�×,Ñ,×0Ñ0Ó1°:Ó>Ù!3ññ ñ 	ˆG�ð	 Ô(×(Ü˜bÐ"4Ó5Ð5ñ ô  ÐEÓFÐFùòE Vùò6øñ 	ˆG�ús=   Ã'L&ÄL&Å'D-L0 Ê-L+Ë,L+Ë2L0 Ë?L0 ÌL0 Ì+L0 Ì0
L:c               ó    € V ^8„  d   QhRRRR/# rù   r   )r   s   "r   r   r   ©  s   € ÷ Kñ K dð KÐ/Dñ Kr   c           
     ó  € \         '       d    \        V 4      # \
        P                  P                  \
        P                  ! V 4      4      p\        V4       Uu0 uF  p\        V4      kK  	  pp. p\        4       pRp\        V4       FU  p \
        P                  ! V4      pTP%                  TP&                  TP(                  34       Y28X  g   KI  TP&                  pKW  	  \*        P,                  P/                  R4      '       Ed8    \
        P0                  ! 4       p	\
        P2                  ! R4       EF  p
V
P5                  4       '       g   K  \7        V
4      pW¹8X  d   K/  RV R	2p \
        P2                  ! V4      pT F²  pT RT 2p \
        P@                  ! T4      p\        T4      T9   p \
        P                  ! T4      pTP&                  TP(                  3T9   g=   T'       g   Km  TPC                  R4      '       g   K†  Tf   KŒ  TP&                  T8X  g   KŸ  TP#                  TT34       K´  	  EK  	  V# \D        f   R.#  \D        PF                  ! RR.4       F¸  pVPH                  p\7        VR,          4      pV\
        P0                  ! 4       8X  d   K=  VPK                  R4      ;'       g    R F\  p\M        VRR4      pV'       g   K  \        \
        P                  P                  V4      4      V9   g   KI  VP#                  VV34       K^  	  Kº  	  V#   \         d)   p\        P	                  RT4       RRT 23.u Rp?# Rp?ii ; iu upi   \         dU   pTP                  \        P                  \        P                   39  d   TP#                  RRT RT 234        Rp?EK-  Rp?ii ; i  \         de    \9        T4      pTeQ   \;        T4      '       d@   \=        Yà4      '       g/   R
P?                  T4      pTP#                  TRTR,           234        EKø  i ; i  \         d�   pTP                  \        P                  \        P                   39   d    Rp?EKï  \9        T4      pTe<   \;        T4      '       d+   \=        Yà4      '       g   TP#                  TRT RT 234        Rp?EK@  Rp?ii ; i  \         d¯   pTP                  \        P                  \        P                   39   d    Rp?EK‰  T'       d   TP#                  TRT RT 234       MJ\9        T4      pTe<   \;        T4      '       d+   \=        Yà4      '       g   TP#                  TRT RT 234        Rp?EKü  Rp?ii ; i  \         d8   p\        P	                  RT4       TP#                  RRT 234        Rp?T# Rp?ii ; i  \         d8   p\        P	                  RT4       TP#                  RRT 234        Rp?T# Rp?ii ; i)zòReturn foreign holders of the DB or one of its WAL sidecars.

A scan failure is represented as an unknown holder. Structural maintenance
must not assume quiescence when an old, unlinked SQLite generation may
still be open by another process.
zUCould not prove state.db has no Windows holders; deferring structural maintenance: %sz%Windows Restart Manager scan failed: Nzwatched-file stat failed: ú: Úlinuxz/procr   z/fdr1   zuninspectable holder: r4   rm   zuninspectable descriptor: r|   zUCould not prove state.db has no foreign holders; deferring structural maintenance: %szopen-file scan failed: r   Ú
open_filesr=   r#   r$   )r$   zopen-file scan unavailabler   )'Ú_IS_WINDOWSr  r:   r›   Úwarningr<   r=   Úrealpathr¾   rÀ   r   ÚsetÚstatr*   ÚerrnoÚENOENTÚESRCHr´   ÚaddÚst_devÚst_inoÚsysÚplatformrQ   r  ÚlistdirrH   r   r.   ry   rÊ   r;   Úreadlinkro   r7   Úprocess_iterÚinfoÚgetrÿ   )r   ÚexcrÂ   rÃ   ÚwatchedÚholdersÚwatched_idsÚdb_devÚstat_resultr  Úpid_strr   Úfd_dirÚfdsr-   r9   ÚfdÚfd_pathrv   Útarget_is_watchedÚfd_statrÜ   r1  Úopenedr=   s   &                        r   Úforeign_state_db_holdersrA  ©  sN  € ÷ ƒ{ð	IÜ3°GÓ<Ð<ô —'‘'×"Ñ"¤2§9¢9¨WÓ#5Ó6€KÜAOÐP[ÔA\Ó]ÑA\°IÔ$ YÖ/ÑA\€GÐ]Ø%'€GÜ(+«€KØ €FÜ# KÖ0ˆ	ð	ÜŸ'š' )Ó,ˆKð 	�‰˜×+Ñ+¨[×-?Ñ-?Ð@ÔAØÖ#Ø ×'Ñ'ŠFñ 1ô ‡|�|×Ñ˜w×'Ó'ðO	BÜ—i’i“kˆGÜŸ:š: g×.�Ø—‘×(Ò(ÙÜ˜'“l�Ø”>ÙØ! #  cÐ*�ðÜŸ*š* VÓ,�Có �BØ!' ¨¨"¨Ð.�Gð!Ü!#§¢¨WÓ!5˜ô" )>¸fÓ(EÈÑ(PÐ%ð!Ü"$§'¢'¨'Ó"2˜ð.  Ÿ™¨¯©Ð7¸;ÔFß)Ñ)Ø"ŸO™O¨L×9Ô9Ø"Ô.Ø#ŸN™N¨fÖ4àŸ™¨¨V }Ö5ôg ñ' /ð\ ˆä‚~Ø2Ð3Ð3ð>Ü×*Ò*¨E°<Ð+@ÖAˆGØ—<‘<ˆDÜ�d˜5•kÓ"ˆCØ”b—i’i“kÔ!ÙØŸ(™( <Ó0×6Ð6°BÒ6�Ü˜v v¨rÓ2�ß‘4Ô1´"·'±'×2BÑ2BÀ4Ó2HÓIÈWÖTØ—N‘N C¨ ;Ö/ó 7ñ Bð  €NøôC ô 	IÜ�N‰NØgØôð Ð@ÀÀÐFÐGÐHÕHûð	Iüò ^øô ô 	Ø�y‰y¤§¡¬u¯{©{Ð ;Ô;Ø—‘ØÐ5°i°[ÀÀ3À%ÐHÐIôö ûð	ûô, ô 	Ü*¨3Ó/�DàÒ(Ü.¨t×4Ò4Ü :¸4× IÒ Ià"%§(¡(¨4£.˜ØŸ™¨Ð/EÀgÈcÅlÀ^Ð-TÐ'UÔVÛð	ûô #ô !ØŸ9™9¬¯©´u·{±{Ð(CÔCÞ$Ü.¨sÓ3˜à Ò,Ü 2°4× 8Ò 8Ü$>¸t×$MÒ$Mà#ŸN™Nà$'Ø&@ÀÀ	ÈÈCÈ5Ð$Qð!"ôö !ûð!ûô& #ô !ØŸ9™9¬¯©´u·{±{Ð(CÔCÞ$ß,Ø#ŸN™NØ!$Ð(BÀ6À(È"ÈSÈEÐ&RÐ Sõô $3°3Ó#7˜Dà $Ò 0Ü$6°t×$<Ò$<Ü(BÀ4×(QÒ(Qà '§¡à(+Ø(DØ+1¨(°"°S°Eð);ð%&ô!"ö !ûð+!ûô: ô 	BÜ�N‰Nð7àôð
 �N‰N˜BÐ"9¸#¸Ð ?Ð@×AÐAØˆûð	Bûô* ô >Ü�‰ð3àô	
ð
 	�‰˜Ð5°c°UÐ;Ð<×=Ð=Ø€Nûð>ús1  Ž
L  ÁMÂMÄA V Å)N=Å?V ÆP/Æ"V Æ1S	Ç"V Ç.V ÈV ÈV È V É
A,W
 Ê7W
 Ë*W
 ÌW
 Ì MÌ+MÍMÍMÍN:Í&AN5Î5N:Î=A*P,Ð'V Ð+P,Ð,V Ð/SÐ:/SÑ)V Ñ0A
SÒ:V ÓSÓV Ó	VÓ/U=ÔV Ô
U=ÔA$U=Õ6V Õ=VÖV ÖWÖ,W×W×
X×,XØXÚexcludec               ó    € V ^8„  d   QhRRRR/# rù   r   )r   s   "r   r   r   7  s   € ÷ ñ Øðàñr   c               ót   € ^ RI Hp V! WR7       Uu. uF  p\        P                  ! 4       V3NK  	  up# u upi )a�  Return holders of ``db_path`` inside THIS process, other than *exclude*.

:func:`foreign_state_db_holders` skips ``os.getpid()`` by design, so it answers a
cross-PROCESS question only. Consumers that read "no holders" as "the store is quiet"
(auto-VACUUM admission) need this arm too: a VACUUM plus its TRUNCATE checkpoint retires
the generation a sibling SessionDB in this very process still holds.
)Úother_generations_for_path)rB  )Úhermes_state_registryrE  r<   r  )r   rB  rE  Údescriptions   &$  r   Úin_process_state_db_holdersrH  7  s?   € õ Añ 6°gÕOóáOˆKô 
�Š‹�kÓ"ÙOñð ùò s   ’ 5Ú
force_hintz--forcec               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r   r   Úcommandr   rI  r‡   r   r   )r   s   "r   r   r   I  s)   € ÷ "ñ " ð "°#ð "À=ð "Ðanñ "r   c               ó  € \        V 4      pV'       g   R# ^ RIHp ^ RIHp / p. pV F�  w  r‰V^ 8:  g   V	P                  R4      '       d   VP                  V	4       K6  VP                  V\        4       4      P                  \        V	P                  R4      4      P                  4       Kƒ  	  RV RV  R2.p
T
\        V4       Uu. uF2  pR	\        V4       R
RP                  \        Wh,          4      4       2NK4  	  up,          p
V'       d$   V
P                  RV^ ,          R,           R24       V! 4       pV
RRV R2.,          p
V'       d   V
P                  RV R24       V
P                  RV 24       RP                  V
4      # u upi )aÓ  Operator-facing refusal for structural maintenance (VACUUM, index rebuild, bulk delete) while another
process holds ``db_path`` or a WAL sidecar; ``None`` when the store is provably quiet.

Running ``hermes sessions optimize-storage`` underneath a fleet of live gateways put every agent into
the retired-WAL refusal until all writers were stopped (#110054). Same fail-closed scan doctor and
repair use: an incomplete scan refuses too, it never reads as an all-clear.
N)Úprofile_cli_selector)ÚSTORAGE_RECOVERY_DOCS_URLÚuninspectabler|   zRefusing `hermes sessions z`: another process is using rG   z  r  z, z>  cannot prove the database is quiet (holder scan incomplete: :Néx   Nr6   zŠRewriting the database under a live writer is how every agent ends up refusing turns with the retired state.db-wal error. Nothing is lost.zStop them first (`hermes z>gateway stop`, quit the Desktop app, pause cron), then re-run.zOverride with z if you accept the risk.zRecovery guide: Ú
)rA  r™   rM  Úhermes_state_errorsrN  rQ   r´   Ú
setdefaultr$  r)  r   rP   rT   Úsortedr@   r;   )r   rK  rI  r5  rM  rN  Úby_pidÚunknownr   rv   ÚlinesÚprofile_args   &$$         r   Úheld_store_refusalrY  I  s€  € ô ' wÓ/€GßÙÝ5Ý=à"$€FØ€GÛ‰ˆØ�!Œ8�v×(Ñ(¨×9Ò9Ø�N‰N˜6Ö"à×Ñ˜c¤3£5Ó)×-Ñ-¬d°6×3FÑ3FÀ|Ó3TÓ.U×.ZÑ.ZÖ[ñ	 ð
 *¨'¨Ð2NÈwÈiÐWXÐYÐZ€EØ	Ô[aÐbhÔ[iÓjÑ[iÐTW�Ô& sÓ+Ð,¨B¨t¯y©y¼ÀÅÓ9LÓ/MÐ.NÓOÑ[iÑjÕj€EßØ�‰ÐUÐV]Ð^_ÕV`ÐaeÕVfÐUgÐghÐiÔjÙ&Ó(€KØ	ð	7à
# K =Ð0nÐoðõ €E÷
 Ø�‰�~ j \Ð1IÐJÔKØ	‡L�LÐ#Ð$=Ð#>Ð?Ô@Ø�9‰9�UÓÐùò ks   Ã8F	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úconnect_repair_durablez!Callable[..., sqlite3.Connection]r   rC   r   )r   s   "r   r   r   n  s(   € ÷ $ñ $Øð$ð >ð$ð 
ñ	$r   c               óž  € \        V 4      '       d   R# Rp V! V RR7      pVP                  R4       VP                  R4       VP                  R4        Ve&    VP                  R4        VP                  4        R	# R	#   \         d     L"i ; i  \         d     R	# i ; i  \        P
                   da   p\        T4      u Rp?TeH    TP                  R4       M  \         d     Mi ; i TP                  4        #   \         d     # i ; i# Rp?i\        P                   dR     TeJ    TP                  R4       M  \         d     Mi ; i TP                  4        R	#   \         d     R	# i ; iR	# i ; i  TeH    TP                  R4       M  \         d     Mi ; i TP                  4        i   \         d     i i ; ii ; i)
aç  Return whether repair lacks proven exclusive ownership of ``db_path``.

ANY foreign process holding the DB or a sidecar is a live holder (#103339): the lock probe below
cannot see a DELETE-mode reader (SHARED only) and cannot run at all on a malformed file, and those
are exactly the states repair/VACUUM/checkpoint get invoked in. The holder scan is the authority and
fails closed on its own failures (unknown/uninspectable sentinels); the probe only adds a positive
lock signal on top.TNg        )ÚtimeoutzPRAGMA locking_mode=EXCLUSIVEzBEGIN IMMEDIATEÚROLLBACKzPRAGMA locking_mode=NORMALF)rA  Úexecuter:   ÚcloseÚsqlite3ÚOperationalErrorr
   ÚDatabaseError)r   r[  Úprober3  s   &$  r   Úlive_writer_holds_dbre  n  sÌ  € ô   ×(Ò(Ùà€EðÙ& w¸Ô<ˆØ�‰Ð5Ô6Ø�‰Ð'Ô(Ø�‰�jÔ!Øð ÒðØ—‘Ð:Ô;ðØ—‘–ñ øô ô Ùðûô ô Úðûô ×#Ñ#ô )Ü# CÓ(Ô(ð
 ÒðØ—‘Ð:Õ;øÜô ÙðúðØ—‘•øÜô Ùðúð ûô	 × Ñ ô ààÒðØ—‘Ð:Õ;øÜô ÙðúðØ—‘–øÜô Úðúñ ð	ûð ÒðØ—‘Ð:Õ;øÜô ÙðúðØ—‘•øÜô Ùðúð úsõ   —=B# ÁB  Á,B Â BÂBÂB ÂB Â#E<Â8
DÃE<ÃE? ÃCÃC,Ã+C,Ã0DÄDÄDÄE<Ä*E<Ä+E? Ä1E ÅEÅEÅE' Å'E6Å5E6Å;E<Å<E? Å?GÆFÆGÆF%Æ"GÆ$F%Æ%GÆ)F:Æ9GÆ:GÇGÇGÇG>   Úhermesú
hermes-acpúhermes-agent>   ÚQÚWÚX)z--hermes-home)z	--profilez-p)zstate.dbzstate.db-walzstate.db-shm)=Ú__doc__Ú
__future__r   r&  Ú	functoolsÚloggingr<   ra  r,  Úpathlibr   Útypingr   r   r   r   r   r	   rR  r
   r7   ÚImportErrorr   Ú	getLoggerrÑ   r›   r-  r!  Ú	frozensetrr   rs   ru   ra   r`   r.   r@   rW   ri   ry   r   r«   r¬   rÁ   r„   rŽ   r“   rž   r¥   r¯   r·   rÊ   r  r  Úcacherô   rÀ   r  rA  rH  rY  re  r   r   r   Ú<module>rv     sq  ðñõ #ã Û Û Û 	Û Û 
Ý ß A× Aå 4ðÛõ
9ð 
×	Ò	˜8Ó	$€à�l‰l˜gÑ%€ÙÒ HÓIÐ Ù" MÐ3DÐ#EÓFÐ Ù"Ð$8¸.Ð#IÓJÐ Ù&/²Ó&@Ð #Ù%.Ø Ð(ó&Ð "õ
õ	 õõ&õRõ,Nð
 !€Ø$€Ø>€õ5õõ&õõ,[õõ*õ(:ðz Ð ØÐ ð ‡�ñ$$ó ð$$õN0õ
5õpKð\Ø"÷ð$"ÐS\÷ "÷J$øðo ô ØƒFðús   ¾D9 Ä9	EÅE