+
    jHàj…&  ã                  óÚ   € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 R R lt
R R ltR	 R
 ltR R lt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tR R ltR R ltR# )a„  Who may write a gateway service definition (systemd unit, launchd plist).

A service definition pins the ``HERMES_HOME`` its gateway runs with. Service names are derived from the
home (bare / profile name / path hash), and two homes can still resolve to the same name: a custom root's
``<root>/profiles/<name>`` takes the same ``hermes-gateway-<name>`` unit as ``~/.hermes/profiles/<name>``.
Every gateway boot refreshes "its" unit, so a scratch or E2E gateway started from such a home rewrote the
real install's unit to point at the scratch directory, and the real gateway failed on its next restart.

The rule: a definition that pins a home is written only by a process acting for that home. Uninstall
already refused a unit pinning another home (``_systemd_unit_belongs_to_current_home``); the writers now
refuse the same way. ``hermes gateway install --force-unit-path`` is the explicit repoint.
)ÚannotationsN)ÚPath)Ú
ExpatErrorc               ó    € V ^8„  d   QhRRRR/# )é   Údefinition_pathr   Úreturnú
str | None© )Úformats   "ÚE/home/ubuntu/.hermes/hermes-agent/hermes_cli/gateway_service_owner.pyÚ__annotate__r      s   € ÷ ;ñ ; ð ;¨*ñ ;ó    c                ó  € V P                   R8X  dµ    V P                  R4      ;_uu_ 4       p\        P                  ! V4      pRRR4       \        X\        4      '       d   TP                  R4      MRp\        T\        4      '       d   TP                  R4      MRpTe$   \        T4      P                  4       ;'       g    R# R# ^ RIHp VP                  V 4      #   + '       g   i     L¢; i  \        \
        \        3 d     R# i ; i)zZ``HERMES_HOME`` pinned by the systemd unit or launchd plist at *definition_path*, or None.z.plistÚrbNÚEnvironmentVariablesÚHERMES_HOME©Úgateway)ÚsuffixÚopenÚplistlibÚloadÚOSErrorÚ
ValueErrorr   Ú
isinstanceÚdictÚgetÚstrÚstripÚ
hermes_clir   Ú_hermes_home_pinned_by_unit)r   ÚfhÚdataÚenvÚvalueÚgws   &     r   Úpinned_homer'      sÐ   € à×Ñ Ô)ð	Ø ×%Ñ% d×+Ô+¨rÜ—}’} RÓ(�÷ ,ô 3=¸TÄ4×2HÒ2Hˆd�h‰hÐ-Ô.ÈdˆÜ*4°S¼$×*?Ò*?�—‘˜Ô&ÀTˆØ/4Ò/@”�E“
× Ñ Ó"×*Ð* dÐJÀdÐJÝ(Ø×)Ñ)¨/Ó:Ð:÷ ,×+ûäœ¤ZÐ0ô 	Úð	ús.   “C0 ¬CÁC0 ÃC-	Ã(C0 Ã-C0 Ã0D
Ä	D
c               ó    € V ^8„  d   QhRRRR/# )r   Úrawz
str | Pathr   zPath | Noner
   )r   s   "r   r   r   &   s   € ÷ ñ �*ð  ñ r   c                óŒ   €  \        V 4      P                  4       P                  4       #   \        \        \
        3 d     R # i ; i©N)r   Ú
expanduserÚresolver   ÚRuntimeErrorr   )r)   s   &r   Ú_resolver/   &   s<   € ðÜ�C‹y×#Ñ#Ó%×-Ñ-Ó/Ð/øÜ”\¤:Ð.ô Úðús   ‚&) ©AÁAc               ó$   € V ^8„  d   QhRRRRRR/# )r   Ú	unit_pathr   ÚsystemÚboolr   r
   )r   s   "r   r   r   -   s!   € ÷ ;ñ ; Tð ;°4ð ;¸Dñ ;r   c                óJ  € ^ RI Hp V'       g   VP                  4       # \        P                  P                  RR4      P                  4       '       gU   V P                  4       '       d   \        V 4      MRpV'       d   \        V4      P                  4       # VP                  4       # VP                  V 4      pV'       g   VP                  4       #  VP                  VR7      ^,          p\        TP                  T4      4      #   \         d    TP                  4       u # i ; i)aç  The ``HERMES_HOME`` this process acts for when it writes the systemd unit at *unit_path*.

User scope: its own home. System scope: an explicit ``HERMES_HOME`` remapped to the unit's ``User=``
account the way ``generate_systemd_unit`` pins it; with none (``sudo`` strips it, HOME=/root), the
unit's own pinned home, which is the only thing naming the install being operated on. Pure: it never
adopts the unit's home into ``os.environ``, so a check on this value compares caller and unit.
r   r   Ú N)Úrun_as_user)r    r   Úget_hermes_homeÚosÚenvironr   r   Úexistsr'   r   r,   Ú_read_systemd_user_from_unitÚ_system_service_identityr   Ú_hermes_home_for_target_user)r1   r2   r&   ÚpinnedÚuserÚhome_dirs   &&    r   Úservice_home_for_unitrA   -   së   € õ )çØ×!Ñ!Ó#Ð#Ü�:‰:�>‰>˜-¨Ó,×2Ñ2×4Ò4Ø+4×+;Ñ+;×+=Ò+=”˜YÔ'À4ˆß,2Œt�F‹|×&Ñ&Ó(ÐL¸×8JÑ8JÓ8LÐLØ×*Ñ*¨9Ó5€DßØ×!Ñ!Ó#Ð#ð$Ø×.Ñ.¸4Ð.Ó@ÀÕCˆô �×/Ñ/°Ó9Ó:Ð:øô ô $Ø×!Ñ!Ó#Ò#ð$ús   ÃD ÄD"Ä!D"c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r   r   ÚhomeÚactionr   r   r3   r
   )r   s   "r   r   r   F   s)   € ÷ ñ °ð ¸Dð È#ð ÐRVñ r   c                óæ   € V P                  4       '       g   R# \        V 4      pVe   \        V4      \        V4      8X  d   R# \        RV RV  RV RV R2	4       \        R4       \        R4       R	# )
zÊFalse (with guidance printed) when the existing definition pins a ``HERMES_HOME`` other than *home*.

A missing definition, or one that pins no home (hand-written, pre-pinning), belongs to nobody else.
Tu   âœ— Refusing to Ú z: it runs HERMES_HOME=ú#, but this process has HERMES_HOME=Ú.zU  That file is another install's gateway. Use that install, or pass --force-unit-pathzL  to `hermes gateway install` if you really mean to repoint it at this home.F)r:   r'   r/   Úprint)r   rC   rD   r)   s   &&& r   Údefinition_belongs_to_homerJ   F   s{   € ð
 ×!Ñ!×#Ò#ÙÜ
�oÓ
&€CØ
‚{”h˜s“m¤x°£~Ô5ÙÜ	Ð˜V˜H A oÐ%6Ð6LÈSÈEð R.Ø.2¨V°1ð6ô 7ä	Ð
aÔbÜ	Ð
XÔYÙr   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r   r1   r   r2   r3   rD   r   r6   r	   r   r
   )r   s   "r   r   r   W   s1   € ÷ ?ñ ? dð ?°Dð ?À#ð ?ÐT^ð ?Ðjnñ ?r   c                óà   € ^ RI Hp \        W4      pV'       d:   V'       d2    \        VP	                  VP                  V4      ^,          4      4      p\        WV4      #   \         d     Li ; i)zÀ``definition_belongs_to_home`` for the systemd unit at *unit_path*, judged against the home this
process would pin there (``run_as_user``'s for an explicit ``--system --run-as-user`` install).r   )r    r   rA   r   r=   r<   r   rJ   )r1   r2   rD   r6   r&   rC   s   &&&&  r   Úunit_belongs_to_callerrM   W   se   € õ )ä  Ó3€Dß—+ð	Ü˜×7Ñ7¸×8SÑ8SÐT_Ó8`ÐabÕ8cÓdÓeˆDô & i°vÓ>Ð>øô ô 	Ùð	ús   £0A ÁA-Á,A-c               ó    € V ^8„  d   QhRRRR/# )r   r2   r3   r   r	   r
   )r   s   "r   r   r   e   s   € ÷ ñ  dð ¨zñ r   c                ój  € ^ RI Hp VP                  VP                  V R7      4      pV'       g   R#  \	        V4      P                  4       P                  4       pVP                  4       P                  4       pY48X  d   R# ^ RI	H
p YE! 4       P                  4       8X  d   R# T#   \         d     R# i ; i)u¼  ``HERMES_HOME`` of the unit at this scope when it belongs to ANOTHER install, else None.

A throwaway ``HOME`` used to resolve the bare ``hermes-gateway`` name (its ``.hermes`` looked native) and
reach the account's real unit â€” user scope through the account-anchored unit dir, system scope
because system units are global. Naming now follows the account home, but two homes can still share
a name (a custom root's ``profiles/<name>``, a pre-pinning unit), so every systemd verb asks this.
``_sync_hermes_home_from_systemd_unit`` would adopt the unit's home and ``stop``/``restart`` would take
the live gateway down, so it must be evaluated BEFORE that sync.

Foreign means: the unit pins a home, it differs from this process's home, and this process's home
is not the account's own default root. The last clause keeps the ``sudo`` remap (#108674): root's
default home operating a unit that pins the invoking user's home is the operator, not a stranger.
r   )r2   N)Úaccount_default_hermes_home)r    r   r!   Úget_systemd_unit_pathr   r,   r-   r7   r   Úhermes_constantsrP   )r2   r&   Ú	unit_homeÚunitÚminerP   s   &     r   Úforeign_systemd_unit_homerV   e   s¡   € õ )Ø×.Ñ.¨r×/GÑ/GÈvÐ/GÓ/VÓW€IßÙðÜ�I‹×)Ñ)Ó+×3Ñ3Ó5ˆØ×!Ñ!Ó#×+Ñ+Ó-ˆð „|ÙÝ<ØÐ*Ó,×4Ñ4Ó6Ô6ÙØÐøô ô Úðús   ³AB# Â#B2Â1B2c               ó$   € V ^8„  d   QhRRRRRR/# )r   rD   r   r2   r3   r   ÚNoner
   )r   s   "r   r   r   „   s!   € ÷ ñ ¨ð °Tð ¸dñ r   c                óø   € ^ RI Hp \        V4      pVf   R# VP                  RV  RVP	                  4        RVP                  V4       RV RVP                  4        R24       \        P                  ! ^4       R# )	z^Exit non-zero instead of operating another install's unit (see ``foreign_systemd_unit_home``).r   NzRefusing to rF   z: that z unit runs HERMES_HOME=rG   zQ.
It belongs to another Hermes install. Run this from that install's HERMES_HOME.)	r    r   rV   Úprint_errorÚget_service_nameÚ_service_scope_labelr7   ÚsysÚexit)rD   r2   r&   rS   s   &&  r   Úrefuse_foreign_systemd_unitr_   „   s„   € å(Ü)¨&Ó1€IØÒÙØ‡N�NØ
�v�h˜a × 3Ñ 3Ó 5Ð6°g¸b×>UÑ>UÐV\Ó>]Ð=^ð _Ø �kÐ!DÀR×EWÑEWÓEYÐDZð [Zð	[ôô
 ‡H‚HˆQ†Kr   c               ó    € V ^8„  d   QhRRRR/# )r   Úverbr   r   rX   r
   )r   s   "r   r   r   ’   s   € ÷ ñ  sð ¨tñ r   c                ó    € ^ RI Hp \        VP                  4       VP	                  4       V 4      '       g   \
        P                  ! ^4       R# R# )zÅThe launchd half of ``refuse_foreign_systemd_unit``: exit 1 rather than start/stop/restart/remove a
LaunchAgent pinning another HERMES_HOME. (Windows task names derive from LOCALAPPDATA, not HOME.)r   N)r    r   rJ   Úget_launchd_plist_pathr7   r]   r^   )ra   r&   s   & r   Úrefuse_foreign_launchd_plistrd   ’   s:   € õ )Ü% b×&?Ñ&?Ó&AÀ2×CUÑCUÓCWÐY]×^Ò^Ü�Š�Žñ _r   c               ó    € V ^8„  d   QhRRRR/# ©r   Ú
definitionr   r   z	list[str]r
   )r   s   "r   r   r   š   s   € ÷ ñ ¨ð °ñ r   c                ó¨   € ^ RI pVP                  RV 4      pW!P                  RWP                  R7      ,          pW!P                  RV 4      ,          pV# )z»Every HERMES_HOME a gateway service definition sets: systemd ``Environment=``, launchd
``EnvironmentVariables``, the Windows ``gateway.cmd`` ``set`` line and the ``gateway.vbs`` env item.NzHERMES_HOME=([^"\r\n]+)z/<key>HERMES_HOME</key>\s*<string>(.*?)</string>©Úflagsz)Item\("HERMES_HOME"\)\s*=\s*"([^"\r\n]+)")ÚreÚfindallÚDOTALL)rg   rk   Úhomess   &  r   Úservice_definition_homesro   š   sM   € ó Ø�J‰JÐ1°:Ó>€EØ	�Z‰ZÐJÈJ×^gÑ^gˆZÓhÕh€EØ	�Z‰ZÐDÀjÓQÕQ€EØ€Lr   c               ó    € V ^8„  d   QhRRRR/# rf   r
   )r   s   "r   r   r   ¤   s   € ÷ &ñ &¨Sð &°Yñ &r   c                ó€   € ^ RI pVP                  RWP                  R7      p\        \        P                  V4      4      # )zÃThe scripts a definition starts, by their quoted absolute paths. The Windows Startup-folder
fallback and a Scheduled Task's action name no home: they start the home's ``gateway.vbs``, which does.Nz3"((?:[A-Za-z]:[\\/]|\\\\|/)[^"\r\n]*\.(?:vbs|cmd))"ri   )rk   rl   Ú
IGNORECASEÚlistr   Úfromkeys)rg   rk   Úfounds   &  r   Úservice_definition_launchersrv   ¤   s4   € ó Ø�J‰JÐMÈz×anÑanˆJÓo€EÜ”—‘˜eÓ$Ó%Ð%r   c               ó    € V ^8„  d   QhRRRR/# )r   rg   r   r   r	   r
   )r   s   "r   r   r   ¬   s   € ÷ ñ °ð ¸
ñ r   c                ó  a€ ^ RI p\        V 4      p\        VP                  4       4      P	                  4       \        R4      \        R4      \        R4      \        R4      0pV FŒ  p \        VP                  4       P                  R4      4      P	                  4       o\        ;QJ d    T3R lT 4       F  '       g   K   RM	  R	M! T3R lT 4       4      '       g   K|  TP                  4       u # 	  R#   \        \        3 d     K¦  i ; i)
zÂTemp-dir HERMES_HOME baked into a systemd unit / launchd plist, or None. A temp home means a
test/E2E harness generated it; installing it leaves the gateway "running" but deaf to every platform.Nz/tmpz/var/tmpz/private/tmpz/private/var/tmpÚ"c              3  ó\   <"  € T F!  pSV8H  ;'       g    VSP                   9   x € K#  	  R # 5ir+   )Úparents)Ú.0ÚrootÚresolveds   & €r   Ú	<genexpr>Ú2temp_home_in_service_definition.<locals>.<genexpr>º   s,   øé € ÐSÉ
Àˆx˜4Ñ×;Ð; 4¨8×+;Ñ+;Ñ#;Ô;Ë
ùs   ƒ,”,TF)	Útempfilero   r   Ú
gettempdirr-   r   r   r   Úany)rg   r�   Ú
candidatesÚ
temp_rootsr)   r~   s   &    @r   Útemp_home_in_service_definitionr†   ¬   sÒ   ø€ ó Ü)¨*Ó5€JäˆX× Ñ Ó"Ó#×+Ñ+Ó-ÜˆV‹”d˜:Ó&¬¨^Ó(<¼dÐCUÓ>Vð€Jó ˆð	Ü˜CŸI™I›K×-Ñ-¨cÓ2Ó3×;Ñ;Ó=ˆH÷ ‹3ÔSÉ
ÓS�3�3Š3ÔSÉ
ÓS×SÔSØ—9‘9“;Òñ ñ øô	 œÐ$ô 	Úð	ús   Á'6C5Ã5D
Ä	D
c               ó$   € V ^8„  d   QhRRRRRR/# )r   rg   r   Úkindr   r3   r
   )r   s   "r   r   r   ¿   s!   € ÷ 
ñ 
¨sð 
¸#ð 
À$ñ 
r   c                ób   € \        V 4      pVf   R# \        RV RV R24       \        R4       R# )zLRefuse (with guidance) when a service definition carries a temp HERMES_HOME.Fu"   âœ— Refusing to write the gateway z1: HERMES_HOME resolves to a temporary directory (z).zq  This usually means a test/E2E environment exported HERMES_HOME. Unset it (or run from a clean shell) and retry.T)r†   rI   )rg   rˆ   Ú	temp_homes   && r   Úrefuse_temp_home_service_writer‹   ¿   sC   € ä/°
Ó;€IØÒÙÜ	Ð.¨t¨fÐ4eÐfoÐepÐprÐ
sÔtÜ	ð	:ôñ r   r+   )Ú__doc__Ú
__future__r   r8   r   r]   Úpathlibr   Úxml.parsers.expatr   r'   r/   rA   rJ   rM   rV   r_   rd   ro   rv   r†   r‹   r
   r   r   Ú<module>r�      sZ   ðñõ #ã 	Û Û 
Ý Ý (õ;õõ;õ2÷"?õõ>õõõ&õ÷&
r   