+
    jHàj-|  ã                  ó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Ht ^ RIHtHtHt ]R;,          t]P$                  ! R	4      t^ûtR
 R lt] ! R R]4      4       tR R ltR R lt ! R R4      t ! R R]4      t ! R R]4      t ! R R]4      tR R lt]! R4      tRtR R lt R  R! lt!R" R# lt"R$ R% lt#R&t$R'^R(R)/R* R+ llt%R,t&R,t'R- R. lt(R/ R0 lt) ! R1 R2]*4      t+ ! R3 R4]+4      t, ! R5 R6]+4      t- ! R7 R84      t.R]R]R]R]./t/R9]0R:&   R# )<zIAbstract service manager interface + systemd/launchd/Windows/s6 backends.)ÚannotationsN)ÚPath)ÚLiteralÚProtocolÚruntime_checkableÚsystemdÚlaunchdÚwindowsÚs6z^[a-z0-9][a-z0-9_-]*$c               ó    € V ^8„  d   QhRRRR/# ©é   ÚnameÚstrÚreturnÚNone© )Úformats   "Ú?/home/ubuntu/.hermes/hermes-agent/hermes_cli/service_manager.pyÚ__annotate__r      s   € ÷ Wñ W ð W¨ñ Wó    c                óæ   € V '       g   \        R4      h\        V 4      \        8”  d    \        R\        V 4       R\         R24      h\        P	                  V 4      '       g   \        RV : 24      hR# )zFRaise ValueError unless ``name`` is a filesystem/s6-safe profile name.zprofile name must not be emptyzprofile name too long (z > Ú)z1profile name must match [a-z0-9][a-z0-9_-]*, got N)Ú
ValueErrorÚlenÚ_MAX_PROFILE_LENÚ_VALID_PROFILE_REÚmatch©r   s   &r   Úvalidate_profile_namer      si   € çÜÐ9Ó:Ð:Ü
ˆ4ƒyÔ#Ô#ÜÐ2´3°t³9°+¸SÔAQÐ@RÐRSÐTÓUÐUÜ×"Ñ" 4×(Ò(ÜÐLÈTÉHÐUÓVÐVñ )r   c                  ó’   € ] tR t^ t$ RtR]R&   R R ltR R ltR R	 ltR
 R lt	R R lt
RRRR/R R lltR R ltR R ltRtR# )ÚServiceManageruÖ   Init-system-specific service operations.

Lifecycle methods exist on every backend. Runtime registration (register/unregister/
list_profile_gateways) is s6-only â€” check ``supports_runtime_registration()`` first.
ÚServiceManagerKindÚkindc               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   ÚServiceManager.__annotate__*   s   € ×+Ñ+˜#Ð+ $Ñ+r   c                	ó   € R # ©Nr   ©Úselfr   s   &&r   ÚstartÚServiceManager.start*   s   € ©r   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r%   +   s   € ×*Ñ*˜Ð* Ñ*r   c                	ó   € R # r'   r   r(   s   &&r   ÚstopÚServiceManager.stop+   s   € ¡sr   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r%   ,   s   € ×-Ñ-˜CÐ- DÑ-r   c                	ó   € R # r'   r   r(   s   &&r   ÚrestartÚServiceManager.restart,   s   € ©#r   c               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r   Úboolr   )r   s   "r   r   r%   -   s   € ×0Ñ0˜sÐ0 tÑ0r   c                	ó   € R # r'   r   r(   s   &&r   Ú
is_runningÚServiceManager.is_running-   s   € ©Sr   c               ó   € V ^8„  d   QhRR/# ©r   r   r6   r   )r   s   "r   r   r%   /   s   € ×8Ñ8¨tÑ8r   c                	ó   € R # r'   r   ©r)   s   &r   Úsupports_runtime_registrationÚ,ServiceManager.supports_runtime_registration/   s   € ±Sr   Ú	extra_envNÚ	start_nowTc               ó(   € V ^8„  d   QhRRRRRRRR/# ©	r   Úprofiler   r@   zdict[str, str] | NonerA   r6   r   r   r   )r   s   "r   r   r%   0   s,   € ÷ ñ ØðØ*?ðØSWðà	ñr   c               	ó   € R # r'   r   ©r)   rD   r@   rA   s   &&$$r   Úregister_profile_gatewayÚ'ServiceManager.register_profile_gateway0   s   € ár   c               ó    € V ^8„  d   QhRRRR/# ©r   rD   r   r   r   r   )r   s   "r   r   r%   3   s   € ×CÑC°#ÐC¸$ÑCr   c                	ó   € R # r'   r   ©r)   rD   s   &&r   Úunregister_profile_gatewayÚ)ServiceManager.unregister_profile_gateway3   s   € Ár   c               ó   € V ^8„  d   QhRR/# ©r   r   z	list[str]r   )r   s   "r   r   r%   4   s   € ×5Ñ5 yÑ5r   c                	ó   € R # r'   r   r=   s   &r   Úlist_profile_gatewaysÚ$ServiceManager.list_profile_gateways4   s   € ±#r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r*   r.   r2   r8   r>   rG   rM   rR   Ú__static_attributes__r   r   r   r!   r!       s?   ‡ ñð Óå+Ý*Ý-Ý0å8ðØBFðØZ^÷õ Dß5Ñ5r   r!   c               ó   € V ^8„  d   QhRR/# )r   r   r"   r   )r   s   "r   r   r   7   s   € ÷ ñ Ð 2ñ r   c                 ó˜   € ^ RI Hp HpHp \	        4       '       d   R# V! 4       '       d   R# V ! 4       '       d   R# V! 4       '       d   R# R# )uL  Return "s6" (s6-svscan is PID 1), "windows", "launchd", "systemd" (working bus) or "none".

This function does NOT replace ``supports_systemd_services()`` â€”
host call sites continue to use that. It exists for new backend-
agnostic code (profile create/delete hooks, the s6 dispatch path
in ``hermes gateway start/stop/restart``).
©Úis_macosÚ
is_windowsÚsupports_systemd_servicesr
   r	   r   r   Únone)Úhermes_cli.gatewayr^   r_   r`   Ú_s6_runningr]   s      r   Údetect_service_managerrd   7   s:   € ÷ SÑRô
 ‡}‚}ÙÙ‡|‚|ÙÙ‡z‚zÙÙ ×"Ò"ÙÙr   c               ó   € V ^8„  d   QhRR/# r;   r   )r   s   "r   r   r   Q   s   € ÷ Dñ D�Tñ Dr   c                 óÆ   €  \        R4      P                  RR7      P                  4       p T R8H  ;'       d    \        R4      P	                  4       #   \         d     R# i ; i)uB  True when s6-svscan is PID 1 in this container.

Must work for the unprivileged hermes user too: ``/proc/1/exe`` is unreadable for other UIDs
(``resolve()`` silently yields the literal ``exe``), which made runtime registration inert in
production. Probe the world-readable ``/proc/1/comm`` AND ``/run/s6/basedir`` â€” either alone
can false-positive.

The obvious probe â€” ``Path('/proc/1/exe').resolve()`` â€” only works as root: for any other UID, the
symlink at ``/proc/1/exe`` is unreadable and ``resolve()`` silently returns the path unchanged, so the
resolved name is the literal ``"exe"`` and detection always fails. Since every Hermes runtime call
inside the container drops to hermes via ``s6-setuidgid``, that silent failure made the entire
service-manager runtime-registration path inert in production (PR #30136 review).
z/proc/1/commúutf-8©ÚencodingFz	s6-svscanz/run/s6/basedir)r   Ú	read_textÚstripÚOSErrorÚis_dir)Úcomms    r   rc   rc   Q   s`   € ðÜ�NÓ#×-Ñ-°wÐ-Ó?×EÑEÓGˆð �;Ñ×CÐC¤4Ð(9Ó#:×#AÑ#AÓ#CÐCøô ô Úðús   ‚)A ÁA ÁA c                  ó¼   € ] tR t^nt$ RtR]R&   R]R&   RtR]R&   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tRRRR/R R lltR R ltR R ltRtR# ) Ú_HostServiceManagerzå``start``/``stop``/``restart`` resolve to ``<_fn_prefix><op>`` on ``hermes_cli.<_backend>``
at call time (lazy import; tests monkeypatch the submodule or its functions). Runtime
registration is unsupported on every host backend.
r"   r#   r   Ú_backendÚ Ú
_fn_prefixc                	óx   € ^ RI p^ RIpVP                  RV P                   24       \	        W P                  4      # )é    Nzhermes_cli.)Ú	importlibÚ
hermes_cliÚimport_modulerq   Úgetattr)r)   rv   rw   s   &  r   Ú_backend_moduleÚ#_HostServiceManager._backend_modulex   s0   € ÛÛØ×Ñ +¨d¯m©m¨_Ð =Ô>Ü�z§=¡=Ó1Ð1r   c               ó    € V ^8„  d   QhRRRR/# )r   Úopr   r   r   r   )r   s   "r   r   Ú _HostServiceManager.__annotate__~   s   € ÷ Dñ D˜ð D ñ Dr   c                	ó`   € \        V P                  4       V P                   V 24      ! 4        R # r'   )ry   rz   rs   )r)   r}   s   &&r   Ú_callÚ_HostServiceManager._call~   s&   € Ü�×$Ñ$Ó&¨4¯?©?Ð*;¸B¸4Ð(@ÔAÖCr   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r~   �   s   € ÷ ñ ˜#ð  $ñ r   c                	ó(   € V P                  R 4       R# )r*   N©r€   r(   s   &&r   r*   Ú_HostServiceManager.start�   s   € Ø�
‰
�7Ör   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r~   „   s   € ÷ ñ ˜ð  ñ r   c                	ó(   € V P                  R 4       R# )r.   Nr„   r(   s   &&r   r.   Ú_HostServiceManager.stop„   s   € Ø�
‰
�6Ör   c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r~   ‡   s   € ÷ ñ ˜Cð  Dñ r   c                	ó(   € V P                  R 4       R# )r2   Nr„   r(   s   &&r   r2   Ú_HostServiceManager.restart‡   s   € Ø�
‰
�9Ör   c               ó   € V ^8„  d   QhRR/# r;   r   )r   s   "r   r   r~   Š   s   € ÷ ñ ¨tñ r   c                	ó   € R # )Fr   r=   s   &r   r>   Ú1_HostServiceManager.supports_runtime_registrationŠ   s   € Ùr   c               ó    € V ^8„  d   QhRRRR/# )r   Úverbr   r   ÚNotImplementedErrorr   )r   s   "r   r   r~   �   s   € ÷ 
ñ 
 ð 
Ð)<ñ 
r   c                	óJ   € \        \        V 4      P                   R V R24      # )z* does not support runtime profile gateway z (container-only feature))r‘   ÚtyperT   )r)   r�   s   &&r   Ú_unsupportedÚ _HostServiceManager._unsupported�   s,   € Ü"Ü�D‹z×"Ñ"Ð#Ð#MÈdÈVÐSlÐmó
ð 	
r   r@   NrA   Tc               ó(   € V ^8„  d   QhRRRRRRRR/# rC   r   )r   s   "r   r   r~   ’   s,   € ÷ 0ñ 0Øð0Ø*?ð0ØSWð0à	ñ0r   c               	ó$   € V P                  R 4      h)Úregistration©r”   rF   s   &&$$r   rG   Ú,_HostServiceManager.register_profile_gateway’   s   € ð ×Ñ Ó/Ð/r   c               ó    € V ^8„  d   QhRRRR/# rJ   r   )r   s   "r   r   r~   —   s   € ÷ 2ñ 2°#ð 2¸$ñ 2r   c                	ó$   € V P                  R 4      h)Úunregistrationr™   rL   s   &&r   rM   Ú._HostServiceManager.unregister_profile_gateway—   s   € Ø×ÑÐ 0Ó1Ð1r   c               ó   € V ^8„  d   QhRR/# rP   r   )r   s   "r   r   r~   š   s   € ÷ ñ  yñ r   c                	ó   € . # r'   r   r=   s   &r   rR   Ú)_HostServiceManager.list_profile_gatewaysš   s   € Øˆ	r   r   )rT   rU   rV   rW   rX   rY   rs   rz   r€   r*   r.   r2   r>   r”   rG   rM   rR   rZ   r   r   r   rp   rp   n   sf   ‡ ñð
 ÓØƒMØ€J�Óò2õDõõõõõ
ð
0ØBFð0ØZ^÷0õ
2÷ñ r   rp   c                  ó>   € ] tR t^žt$ RtRtR]R&   RtRtR R lt	R	t
R
# )ÚSystemdServiceManagerz²Wraps the ``systemd_*`` functions in hermes_cli.gateway (host call sites still use those
directly; this exists for backend-agnostic code such as the profile create/delete hooks).r   r"   r#   ÚgatewayÚsystemd_c               ó    € V ^8„  d   QhRRRR/# r5   r   )r   s   "r   r   Ú"SystemdServiceManager.__annotate__¦   s   € ÷ ñ ˜sð  tñ r   c                	óF   € V P                  4       P                  4       w  r#V# r'   )rz   Ú_probe_systemd_service_running)r)   r   Ú_Úrunnings   &&  r   r8   Ú SystemdServiceManager.is_running¦   s    € Ø×)Ñ)Ó+×JÑJÓL‰
ˆØˆr   r   N©rT   rU   rV   rW   rX   r#   rY   rq   rs   r8   rZ   r   r   r   r£   r£   ž   s)   ‡ ñað  )€DÐ
Ó(Ø€HØ€J÷ñ r   r£   c                  ó>   € ] tR t^«t$ RtRtR]R&   RtRtR R lt	R	t
R
# )ÚLaunchdServiceManagerz8Wraps the ``launchd_*`` functions in hermes_cli.gateway.r   r"   r#   r¤   Úlaunchd_c               ó    € V ^8„  d   QhRRRR/# r5   r   )r   s   "r   r   Ú"LaunchdServiceManager.__annotate__²   s   € ÷ Gñ G˜sð G tñ Gr   c                	ó>   € V P                  4       P                  4       # r'   )rz   Ú_probe_launchd_service_runningr(   s   &&r   r8   Ú LaunchdServiceManager.is_running²   s   € Ø×#Ñ#Ó%×DÑDÓFÐFr   r   Nr­   r   r   r   r¯   r¯   «   s&   ‡ ÙBà(€DÐ
Ó(Ø€HØ€J÷Gñ Gr   r¯   c                  óZ   € ] tR t^¶t$ RtRtR]R&   RtRRRR	R
R	RR/R R lltR R lt	Rt
R	# )ÚWindowsServiceManageru   Wraps ``hermes_cli.gateway_windows`` (Scheduled Task / Startup-folder fallback).

Not a true init service but the lifecycle protocol is the same. ``install`` takes
Windows-specific kwargs passed straight through â€” non-Windows callers must never call it.
r	   r"   r#   Úgateway_windowsÚforceFrA   NÚstart_on_loginÚelevated_handoffc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r¹   r6   rA   zbool | Nonerº   r»   r   r   r   )r   s   "r   r   Ú"WindowsServiceManager.__annotate__À   s>   € ÷ 

ñ 

ð ð

ð ð	

ð
 $ð

ð ð

ð 
ñ

r   c               	óH   € V P                  4       P                  WW4R 7       R# ))r¹   rA   rº   r»   N)rz   Úinstall)r)   r¹   rA   rº   r»   s   &$$$$r   r¿   ÚWindowsServiceManager.installÀ   s%   € ð 	×ÑÓ×&Ñ&Ø¸^ð 	'ö 	
r   c               ó    € V ^8„  d   QhRRRR/# r5   r   )r   s   "r   r   r½   Ì   s   € ÷ )ñ )˜sð ) tñ )r   c                	óz   € ^ RI Hp V P                  4       P                  4       '       g   R# \	        V! 4       4      # )ru   )Úfind_gateway_pidsF)rb   rÃ   rz   Úis_installedr6   )r)   r   rÃ   s   && r   r8   Ú WindowsServiceManager.is_runningÌ   s/   € Ý8Ø×#Ñ#Ó%×2Ñ2×4Ò4ÙÜÑ%Ó'Ó(Ð(r   r   )rT   rU   rV   rW   rX   r#   rY   rq   r¿   r8   rZ   r   r   r   r·   r·   ¶   sP   ‡ ñð  )€DÐ
Ó(Ø €Hð

ð ð

ð "&ð	

ð
 '+ð

ð "'÷

÷)ñ )r   r·   c               ó   € V ^8„  d   QhRR/# )r   r   r!   r   )r   s   "r   r   r   Ó   s   € ÷ ñ ˜^ñ r   c                 óh   € \         P                  \        4       4      p V f   \        R4      hV ! 4       # )z?Return the ServiceManager instance for the current environment.z%no supported service manager detected)Ú_MANAGER_CLASSESÚgetrd   ÚRuntimeError)Úclss    r   Úget_service_managerrÌ   Ó   s.   € ä
×
Ñ
Ô5Ó7Ó
8€CØ
‚{ÜÐBÓCÐCÙ‹5€Lr   z/run/serviceúgateway-c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r   )r   s   "r   r   r   ç   s   € ÷ 0ñ 0 ð 0¨ñ 0r   c                ó,   € V P                  \        4      # )zPStrip the ``gateway-`` prefix back off (matches what the user typed via ``-p``).)ÚremoveprefixÚS6_SERVICE_PREFIXr   s   &r   Ú_profile_from_servicerÒ   ç   s   € à×ÑÔ.Ó/Ð/r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   r   r   )r   s   "r   r   r   ì   s   € ÷ Iñ I¨3ð I°4ñ Ir   c                ó  € \        V 4      p\        V4       \        \        P                  P                  RR4      4      pVP                  P                  R8X  d   VP                  P                  MTpVR8X  d   V# VR,          V,          # )a5  Resolve ``gateway-<profile>`` to its persistent profile directory.

s6 lifecycle commands may run from any active profile (``gateway stop --all``), so never write
the caller's HERMES_HOME blindly: derive the shared profile root and map the suffix to the root
default profile or ``<root>/profiles/<profile>``.
ÚHERMES_HOMEz	/opt/dataÚprofilesÚdefault)rÒ   r   r   ÚosÚenvironrÉ   Úparentr   )r   rD   Úhermes_homeÚroots   &   r   Ú _profile_dir_for_gateway_servicerÝ   ì   sr   € ô $ DÓ)€GÜ˜'Ô"Ü”r—z‘z—~‘~ m°[ÓAÓB€KØ(3×(:Ñ(:×(?Ñ(?À:Ô(Mˆ;×Ñ×$Ò$ÐS^€DØ˜iÔ'ˆ4ÐH¨T°JÕ->ÀÕ-HÐHr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Údesired_stater   r   r   )r   s   "r   r   r   ú   s!   € ÷ ñ  sð ¸3ð À4ñ r   c                óˆ  € \        V 4      pVR,          p VP                  4       '       g   R#  VP                  4       '       d'   \        P                  ! VP	                  RR7      4      M/ p\        V\        4      '       g   / pYR&   \        \        P                  ! 4       4      TR&   TP                  TP                  R,           4      pTP                  \        P                  ! TRR7      R	,           R
R7       TP                  T4       R#   \        \        P                  3 d    / p L©i ; i  \         d     R# i ; i)a  Persist the operator's start/stop intent (``desired_state``) next to the gateway's volatile
``gateway_state`` so boot reconciliation can restore s6 want-up/down after pod recreation.
Best-effort: a failed write must not block immediate s6 lifecycle control.
zgateway_state.jsonNz	utf-8-sigrh   rß   Ú
updated_atú.tmp)Ú
separatorsÚ
rg   )Ú,Ú:)rÝ   ÚexistsÚjsonÚloadsrj   Ú
isinstanceÚdictrl   ÚJSONDecodeErrorÚintÚtimeÚwith_suffixÚsuffixÚ
write_textÚdumpsÚreplace)r   rß   Úprofile_dirÚ
state_fileÚdataÚtmps   &&    r   Ú_write_gateway_desired_staterø   ú   s  € ô
 3°4Ó8€KØÐ3Õ3€JðØ×!Ñ!×#Ò#Ùð	ØMW×M^ÑM^×M`ÒM`”4—:’:˜j×2Ñ2¸KÐ2ÓHÔIÐfhˆDÜ˜d¤D×)Ò)Ø�ð !.ˆ_ÑÜ ¤§¢£Ó-ˆˆ\ÑØ×$Ñ$ Z×%6Ñ%6¸Õ%?Ó@ˆØ�‰”t—z’z $°:Ô>ÀÕEÐPWˆÔXØ�‰�JÖøô œ×-Ñ-Ð.ô 	ØŠDð	ûô ô Úðús<   –D2 ¯D ÁA D ÂBD2 ÄD/Ä,D2 Ä.D/Ä/D2 Ä2EÅ Ec               ó$   € V ^8„  d   QhRRRRRR/# )r   Úmgrr!   rD   r   r   r6   r   )r   s   "r   r   r     s"   € ÷ ñ ¨~ð Èð ÐPTñ r   c                ó�   € \        \         V 24      pVR,          P                  4       '       g   R# V P                  VRR7       R# )u­  Register a ``down`` s6 slot for a profile whose directory exists but was never registered.

`hermes profile create` can only register a slot when it runs inside the container; created
from the host against a bind-mounted home, the directory lands where the container reads it
but no ``/run/service/gateway-<name>`` exists, and the boot reconciler only notices on the
next container restart. Returns False without touching anything unless the directory carries
``SOUL.md`` â€” the reconciler's own "real profile" marker â€” so a mistyped ``-p`` name cannot
mint a phantom slot. ``start_now=False``: the caller's ordinary ``start`` stays the single
owner of the ``desired_state`` write.
zSOUL.mdF)rA   T)rÝ   rÑ   rç   rG   )rú   rD   rô   s   && r   Ú%register_unregistered_profile_gatewayrü     sF   € ô 3Ô6GÐ5HÈÈ	Ð3RÓS€KØ˜)Õ#×+Ñ+×-Ò-ÙØ× Ñ  °EÐ Ô:Ùr   z/commandÚtimeoutÚcheckFc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úcmdr   Úargsrý   Úfloatrþ   r6   r   )r   s   "r   r   r   ,  s(   € ÷ ñ �ð ˜Sð ¨5ð ¸Tñ r   c          
     óT   € \         P                  ! \         RV  2.VOVRRRRVR7      # )zJRun an s6 binary by absolute path with the shared capture/decode settings.Ú/Trg   ró   )rþ   Úcapture_outputÚtextri   Úerrorsrý   )Ú
subprocessÚrunÚ_S6_BIN_DIR)r   rý   rþ   r  s   &$$*r   Ú_s6_runr  ,  s7   € ä�>Š>Üˆ=˜˜#˜Ð	Ð' $Ð'Ø D¨t¸gÈiØôð r   i'  c               ó    € V ^8„  d   QhRRRR/# )r   Úpathr   r   r   r   )r   s   "r   r   r   ;  s   € ÷ ñ ˜ð  ñ r   c                ól   €  \         P                  ! V \        \        4       R #   \         d     R # i ; ir'   )rØ   ÚchownÚ_HERMES_UIDÚ_HERMES_GIDÚPermissionError)r  s   &r   Ú_chown_hermesr  ;  s+   € ðÜ
�Š�”{¤KÖ0øÜô ò 	ðús   ‚ $ ¤3²3c               ó    € V ^8„  d   QhRRRR/# )r   Úsvc_dirr   r   r   r   )r   s   "r   r   r   D  s   € ÷ ,ñ , dð ,¨tñ ,r   c                óˆ   a€ R R loR V3R llpV! V 4       V R,          pVP                  4       '       d   V! V4       R# R# )u±  Pre-create hermes-owned ``supervise/`` and top-level ``event/`` inside a service directory.

s6-supervise (root) creates ``event/``/``supervise/`` 0700 and the control FIFO 0600, so the
hermes user gets EACCES on every ``s6-svc``/``s6-svstat``. s6 treats EEXIST as success and skips
its chown/chmod fix-up, so seeding before ``s6-svscanctl -a`` makes s6-supervise inherit our
ownership. ``log/`` gets the same skeleton (its own supervise instance) or unregister teardown
EACCESes on the logger. Idempotent: existing entries (possibly live FIFOs) are left untouched.

The PR #30136 review surfaced this as a real product gap: the entire S6ServiceManager lifecycle
(``register/start/stop/unregister _profile_gateway``) was inert in production because every operation is
dispatched as the hermes user.
Reference --------- Discussed at length on the skarnet `skaware` mailing list in 2020
(`<http://skarnet.org/lists/skaware/1424.html>`_); see also just-containers/s6-overlay#130. The
pre-creation pattern was historically called out as forward-compatibility-fragile, but the EEXIST
handling in s6-supervise has been stable since 2015 â€” it's the same pattern ``s6-svperms`` and
``fix-attrs.d`` rely on.
c               ó$   € V ^8„  d   QhRRRRRR/# )r   r  r   Úmoderí   r   r   r   )r   s   "r   r   Ú._seed_supervise_skeleton.<locals>.__annotate__W  s!   € ÷ ñ ˜4ð  sð ¨tñ r   c                ó”   € V P                  4       '       d   R # V P                  RRR7       V P                  V4       \        V 4       R # )NF)ÚparentsÚexist_ok)rç   ÚmkdirÚchmodr  )r  r  s   &&r   Ú_mkdir_ownedÚ._seed_supervise_skeleton.<locals>._mkdir_ownedW  s4   € Ø�;‰;�=Š=ÙØ�
‰
˜5¨5ˆ
Ô1Ø�
‰
�4ÔÜ�dÖr   c               ó    € V ^8„  d   QhRRRR/# )r   rÜ   r   r   r   r   )r   s   "r   r   r  ^  s   € ÷ #ñ #�Dð #˜Tñ #r   c                ó  <€ S! V R ,          R4       V R,          pS! VR4       S! VR ,          R4       VR,          pVP                  4       '       g6   \        P                  ! VR4       VP                  R4       \	        V4       R# R# )ÚeventiØ  Ú	superviseéí  Úcontroli°  N)rç   rØ   Úmkfifor  r  )rÜ   r$  r&  r  s   &  €r   Ú_seedÚ'_seed_supervise_skeleton.<locals>._seed^  st   ø€ á�T˜G•^ VÔ,Ø˜;Õ&ˆ	Ù�Y Ô&Ù�Y Õ(¨&Ô1ð ˜iÕ'ˆØ�~‰~×ÒÜ�IŠI�g˜uÔ%Ø�M‰M˜%Ô Ü˜'Ö"ñ  r   ÚlogN)rm   )r  r(  Úlog_dirr  s   &  @r   Ú_seed_supervise_skeletonr,  D  s=   ø€ õ&÷#ð #ñ 
ˆ'„NØ˜�o€GØ‡~�~×ÒÙˆgŽñ r   c                  ó:   a € ] tR tRtRtRR/R V 3R llltRtV ;t# )ÚS6Erroris  z˜Base for S6ServiceManager lifecycle failures; carries the slot name so the CLI can render an
actionable message instead of a raw ``CalledProcessError``.ÚserviceNc               ó$   € V ^8„  d   QhRRRRRR/# )r   Úmessager   r/  z
str | Noner   r   r   )r   s   "r   r   ÚS6Error.__annotate__w  s!   € ÷ ñ  ð °ð Àtñ r   c               	ó2   <€ \         SV `  V4       W n        R # r'   )ÚsuperÚ__init__r/  )r)   r1  r/  Ú	__class__s   &&$€r   r5  ÚS6Error.__init__w  s   ø€ Ü‰Ñ˜Ô!ØŽr   ©r/  ©rT   rU   rV   rW   rX   r5  rZ   Ú__classcell__©r6  s   @r   r.  r.  s  s   ø† ñCð¸d÷ ÷ ð r   r.  c                  ó2   a € ] tR tRtRtR V 3R lltRtV ;t# )ÚGatewayNotRegisteredErrori|  zuA lifecycle method targeted a missing slot. ``profile`` is unprefixed so callers can phrase
"no such gateway 'typo'".c               ó    € V ^8„  d   QhRRRR/# rJ   r   )r   s   "r   r   Ú&GatewayNotRegisteredError.__annotate__€  s   € ÷ 
ñ 
 ð 
¨ñ 
r   c                	óL   <€ Wn         \        SV `	  R V: RV R2RV 2R7       R# )zno such gateway z*: register it with `hermes profile create z9` first, or pass an existing profile name via `-p <name>`rÍ   r8  N)rD   r4  r5  )r)   rD   r6  s   &&€r   r5  Ú"GatewayNotRegisteredError.__init__€  sA   ø€ ØŒÜ‰ÑØ˜w™kð *&Ø&- Yð /7ð7ð ˜w˜iÐ(ð	 	ö 	
r   )rD   r9  r;  s   @r   r=  r=  |  s   ø† ñ!÷
ö 
r   r=  c                  ó2   a € ] tR tRtRtR V 3R lltRtV ;t# )ÚS6CommandErroriŠ  z‘An s6 command failed for a reason other than a missing slot (EACCES on the control FIFO,
unexpected non-zero exit); carries the command's stderr.c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	r   r/  r   ÚactionÚ
returncoderí   Ústderrr   r   r   )r   s   "r   r   ÚS6CommandError.__annotate__Ž  s0   € ÷ 3ñ 3 3ð 3°ð 3Àð 3Ècð 3ÐVZñ 3r   c               	óÆ   <€ W n         W0n        W@n        R V RV: RV R2pVP                  4       '       d   VRVP                  4        2,          p\        SV `  WQR7       R# )zs6-svc z on z failed (rc=r   z: r8  N)rE  rF  rG  rk   r4  r5  )r)   r/  rE  rF  rG  r1  r6  s   &$$$$ €r   r5  ÚS6CommandError.__init__Ž  s_   ø€ ØŒØ$ŒØŒØ˜F˜8 4¨¡{°,¸z¸lÈ!ÐLˆØ�<‰<�>Š>Ø˜˜FŸL™L›NÐ+Ð,Õ,ˆGÜ‰Ñ˜ÐÖ2r   )rE  rF  rG  r9  r;  s   @r   rC  rC  Š  s   ø† ñ@÷3ö 3r   rC  c                  ó  € ] tR tRt$ RtRtR]R&   ]3R R lltR R	 lt	]
R
 R l4       t]
R R l4       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 R ltR R ltR R ltR R!R"R#/R$ R% lltR& R' ltR( R) ltR*tR!# )+ÚS6ServiceManageri˜  z­Per-profile gateway supervision via s6-overlay, for runtime-registered services under
``S6_DYNAMIC_SCANDIR`` only (static services are managed by s6-rc at image-build time).r
   r"   r#   c               ó    € V ^8„  d   QhRRRR/# )r   Úscandirr   r   r   r   )r   s   "r   r   ÚS6ServiceManager.__annotate__ž  s   € ÷ ñ  ð ¸dñ r   c                	ó   € Wn         R # r'   ©rN  )r)   rN  s   &&r   r5  ÚS6ServiceManager.__init__ž  s   € ØŽr   c               ó    € V ^8„  d   QhRRRR/# )r   rD   r   r   r   r   )r   s   "r   r   rO  ¡  s   € ÷ >ñ > Cð >¨Dñ >r   c                	óN   € \        V4       V P                  \         V 2,          # r'   )r   rN  rÑ   rL   s   &&r   Ú_service_dirÚS6ServiceManager._service_dir¡  s$   € Ü˜gÔ&Ø�|‰|Ô!2Ð 3°G°9Ð=Õ=Ð=r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rD   r   r@   zdict[str, str]r   r   )r   s   "r   r   rO  ¦  s!   € ÷ 4'ñ 4' Cð 4'°Nð 4'Àsñ 4'r   c           	     ó°  € . ROp\        VP                  4       4       F0  w  r4VP                  RV R\        P                  ! V4       24       K2  	  VP                  R4       VP                  R4       V R8X  d   RpMR\        P                  ! V 4       R2pVP                  R	V 24       VP                  R
V 24       RP                  V4      R,           # )uQ  Run script for a profile-gateway s6 service.

Sources HERMES_HOME via with-contenv (run time, not baked in), resets ``HOME`` before the
privilege drop so root's HOME does not leak, activates the venv, drops to hermes.
``profile == "default"`` emits NO ``-p`` flag: it is the sentinel for the root HERMES_HOME
profile and ``-p default`` would look up ``profiles/default/``. Port comes from the
profile's own env (``API_SERVER_PORT``, default 8642); two profiles that both leave it
unset collide.

Port selection: the gateway binds the port resolved by ``gateway/config.py`` from the profile's own
environment â€” ``API_SERVER_PORT`` (or ``platforms.api_server.extra.port`` in that profile's
``config.yaml``), defaulting to 8642. There is no ``[gateway] port`` key and no Python-side
allocator: because each supervised profile gateway loads its own ``HERMES_HOME``, two profiles that
both leave the port unset will both try to bind 8642 â€” give each profile a distinct
``API_SERVER_PORT`` in its ``.env``. Previously this method took a ``port`` parameter that was
passed in but never substituted into the rendered script (carried for "API parity" with a
deterministic SHA-256 allocator in ``hermes_cli.profiles._allocate_gateway_port``). PR #30136 review
item I5 retired both the allocator and the parameter because they were dead code through the entire
stack.
zexport Ú=z#export HERMES_S6_SUPERVISED_CHILD=1z export HERMES_SUPERVISED_CHILD=1r×   zhermes gateway run --replacez
hermes -p z gateway run --replacez[ "$(id -u)" = 0 ] || exec zexec s6-setuidgid hermes rä   )z#!/command/with-contenv shz# shellcheck shell=shzset -ezexport HOME=/opt/datazcd /opt/data)ÚsortedÚitemsÚappendÚshlexÚquoteÚjoin)rD   r@   ÚlinesÚkÚvÚgateway_cmds   &&    r   Ú_render_run_scriptÚ#S6ServiceManager._render_run_script¥  sÇ   € ò,
ˆô ˜9Ÿ?™?Ó,Ö-‰DˆAØ�L‰L˜7 1 # Q¤u§{¢{°1£~Ð&6Ð7Ö8ñ .ð
 	�‰Ð:Ô;ð 	�‰Ð7Ô8ð �iÔØ8‰Kà&¤u§{¢{°7Ó';Ð&<Ð<RÐSˆKà�‰Ð2°;°-Ð@ÔAØ�‰Ð0°°Ð>Ô?Ø�y‰y˜Ó $Õ&Ð&r   c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   rO  Ý  s   € ÷ 
ñ 
 3ñ 
r   c                 ó$   € ^ RI Hp  T pRV RV R2# )u¬  Finish script: exit 78 (EX_CONFIG, fatal config) and clean exit 0 (intentional stop â€”
restarting would turn every normal exit into a reconnect storm) both map to 125 so s6 stops
restarting; only other non-zero exits let s6 restart normally.

When the gateway exits with EX_CONFIG (78) â€” a fatal configuration error such as a token collision
or no messaging platforms â€” we tell s6-supervise to stop restarting by exiting 125 (permanent
failure). A clean exit 0 is an intentional stop, not a crash: restarting after it turns any normal
gateway exit into a reconnect loop (the ashriel-discord storm in #76435 â€” 1,000+ connections and a
provider token reset). See #51228, #76435.
)ÚGATEWAY_FATAL_CONFIG_EXIT_CODEz^#!/command/with-contenv sh
# shellcheck shell=sh
# $1 = exit code from the run script.
# Exit u~    (EX_CONFIG) = fatal config error â€” don't restart.
# Exit 0 (clean stop) = intentional stop â€” don't restart.
if [ "$1" = "zE" ]; then
  exit 125
fi
if [ "$1" = "0" ]; then
  exit 125
fi
exit 0
)Úgateway.restartrh  )rh  Úcodes     r   Ú_render_finish_scriptÚ&S6ServiceManager._render_finish_scriptÜ  s2   € õ 	CØ-ˆðð �Vð à ˜6ð "ðð	
r   c               ó    € V ^8„  d   QhRRRR/# )r   rD   r   r   r   )r   s   "r   r   rO  ú  s   € ÷ 
ñ 
 ð 
¨ñ 
r   c                ó:   € \         P                  ! V 4      pRV R2# )zÔlog/run script. s6-log directives apply per line in order; ``T`` (timestamp) is
non-sticky and only prefixes lines for the next action directive, so it sits between
``1`` and the log dir rather than before ``1``.zs#!/command/with-contenv sh
# shellcheck shell=sh
: "${HERMES_HOME:=/opt/data}"
log_dir="$HERMES_HOME/logs/gateways/a$  "
if [ "$(id -u)" = 0 ]; then
  s6-setuidgid hermes mkdir -p "$log_dir"
  s6-setuidgid hermes rm -f "$log_dir/lock"
else
  mkdir -p "$log_dir"
  rm -f "$log_dir/lock"
fi
[ "$(id -u)" = 0 ] || exec s6-log 1 n10 s1000000 T "$log_dir"
exec s6-setuidgid hermes s6-log 1 n10 s1000000 T "$log_dir"
)r]  r^  )rD   Úprofs   & r   Ú_render_log_runÚ S6ServiceManager._render_log_runù  s/   € ô
 �{Š{˜7Ó#ˆð3ð 48°&ð 9LðMð	
r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úaction_flagr   Úaction_labelr   r   r   r   )r   s   "r   r   rO    s(   € ÷ ñ  Cð °sð À#ð È$ñ r   c                óF  € V P                   V,          pVP                  4       '       g   \        \        V4      4      h \	        RV\        V4      RR7       R#   \        P                   d3   p\        Y2TP                  TP                  ;'       g    RR7      ThRp?ii ; i)z£``s6-svc <action_flag>``; a missing service dir raises ``GatewayNotRegisteredError``
(instead of s6-svc's opaque failure) and any other failure ``S6CommandError``.ús6-svcT)rþ   rr   )r/  rE  rF  rG  N)rN  rm   r=  rÒ   r  r   r  ÚCalledProcessErrorrC  rF  rG  )r)   rs  rt  r   Úservice_dirÚexcs   &&&&  r   Ú_run_svcÚS6ServiceManager._run_svc  s‹   € ð —l‘l TÕ)ˆØ×!Ñ!×#Ò#Ü+Ô,AÀ$Ó,GÓHÐHð	Ü�H˜k¬3¨{Ó+;À4×HøÜ×,Ñ,ô 	Ü Ø¸c¿n¹nÐUX×U_ÑU_×UeÐUeÐceôàðûð	ús   ¿A ÁB Á.-BÂB c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   rO  $  s   € ÷ 6ñ 6˜#ð 6 $ñ 6r   c                	óD   € V P                  R RV4       \        VR4       R# )z-ur*   r«   N©rz  rø   r(   s   &&r   r*   ÚS6ServiceManager.start$  s   € Ø�‰�d˜G TÔ*Ü$ T¨9Ö5r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úfieldsr   zlist[str] | Noner   )r   s   "r   r   rO  (  s"   € ÷ 
>ñ 
> 3ð 
>°ð 
>Ð9Iñ 
>r   c           	     ó  € \        RRRP                  V4      \        V P                  V,          4      4      pVP                  ^ 8w  d   R# VP
                  P                  4       p\        V4      \        V4      8X  d   V# R# )a	  ``s6-svstat -o <fields>`` values for ``name``, or None on a nonzero rc or a count mismatch.

Never parse the human status line: s6 2.15 prints ``up (pid N pgid N) Ss``, which the old
``(pid N)`` regex never matched, so the planned-stop marker was silently skipped.
z	s6-svstatz-orå   N)r  r_  r   rN  rF  ÚstdoutÚsplitr   )r)   r   r�  ÚresultÚvaluess   &&*  r   Ú_svstat_fieldsÚS6ServiceManager._svstat_fields(  si   € ô ˜ d¨C¯H©H°VÓ,<¼cÀ$Ç,Á,ÐQUÕBUÓ>VÓWˆØ×Ñ Ô!ÙØ—‘×$Ñ$Ó&ˆÜ˜V›¬¨F«Ô3ˆvÐ=¸Ð=r   c               ó    € V ^8„  d   QhRRRR/# )r   r   r   r   z
int | Noner   )r   s   "r   r   rO  4  s   € ÷ (ñ ( Cð (¨Jñ (r   c                óÄ   €  V P                  VR4      pV'       d   \        V^ ,          4      M^ pT^ 8”  d   T# R#   \        \        P                  \
        3 d     R# i ; i)zbPID of the supervised gateway per ``s6-svstat -o pid`` (``-1`` when down), or None on any
failure.ÚpidN)r‡  rí   rl   r  ÚSubprocessErrorr   )r)   r   r†  r‹  s   &&  r   Ú_supervised_pidÚ S6ServiceManager._supervised_pid4  s^   € ð	Ø×(Ñ(¨¨uÓ5ˆFß$*”#�f˜Q•i”.°ˆCð ˜A”gˆsÐ' 4Ð'øô œ×3Ñ3´ZÐ@ô 	Úð	ús   ‚; œ; » AÁAc               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   rO  >  s   € ÷ 6ñ 6˜ð 6 ñ 6r   c                ó®   € V P                  V4      pVe    ^ RIHp V! V4       V P	                  RRV4       \        VR4       R#   \         d     L.i ; i)zÁ``s6-svc -d``, after writing a planned-stop marker for the supervised PID so the gateway's
shutdown handler classifies this SIGTERM as operator-initiated and persists
``gateway_state=stopped``.N)Úwrite_planned_stop_markerú-dr.   Ústopped)r�  Úgateway.statusr‘  Ú	Exceptionrz  rø   )r)   r   r‹  r‘  s   &&  r   r.   ÚS6ServiceManager.stop>  sY   € ð ×"Ñ" 4Ó(ˆØŠ?ðÝDÙ)¨#Ô.ð 	�‰�d˜F DÔ)Ü$ T¨9Ö5øô ô Ùðús   —A ÁAÁAc               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   rO  L  s   € ÷ 6ñ 6˜Cð 6 Dñ 6r   c                óD   € V P                  RRV4       \        VR4       R# )z``s6-svc -t`` (SIGTERM).ú-tr2   r«   Nr~  r(   s   &&r   r2   ÚS6ServiceManager.restartL  s   € à�‰�d˜I tÔ,Ü$ T¨9Ö5r   c               ó    € V ^8„  d   QhRRRR/# r5   r   )r   s   "r   r   rO  Q  s   € ÷ "ñ "˜sð " tñ "r   c                	ó2   € V P                  VR 4      pVR.8H  # )ÚupÚtrue)r‡  )r)   r   r†  s   && r   r8   ÚS6ServiceManager.is_runningQ  s!   € Ø×$Ñ$ T¨4Ó0ˆØ˜&˜Ñ!Ð!r   c               ó   € V ^8„  d   QhRR/# r;   r   )r   s   "r   r   rO  W  s   € ÷ ñ ¨tñ r   c                	ó   € R # )Tr   r=   s   &r   r>   Ú.S6ServiceManager.supports_runtime_registrationW  s   € Ùr   r@   NrA   Tc               ó(   € V ^8„  d   QhRRRRRRRR/# rC   r   )r   s   "r   r   rO  Z  s2   € ÷ /Yñ /YØð/YØ*?ð/YØSWð/Yà	ñ/Yr   c               óD  € V P                  V4      pVP                  4       '       d   \        RV: RV 24      hVP                  RVP                  ,           R,           4      pVP                  4       '       d   \
        P                  ! VRR7       VP                  RR7       R R	 lp VR
,          P                  RRR7       T! VR,          T P                  Y;'       g    / 4      4       V! VR,          V P                  4       4       VR,          P                  4        V! VR,          R,          V P                  V4      4       \        V4       V'       g   VR,          P                  4        VP                  V4       \!        RR\#        T P$                  4      4      pTP&                  ^ 8w  dE   \
        P                  ! TRR7       \)        RTP*                  ;'       g    TP,                   24      hR#   \         d    \
        P                  ! TRR7       h i ; i)a,  Create the s6 service directory and ``s6-svscanctl -a`` so it is picked up immediately.

``start_now=False`` writes a ``down`` marker so the service stays stopped until an explicit
``gateway start``. Raises ValueError on an invalid name or existing directory, RuntimeError
if ``s6-svscanctl`` fails.
zprofile gateway z already registered at Ú.râ   T©Úignore_errors)r  c               ó$   € V ^8„  d   QhRRRRRR/# )r   r  r   r  r   r   r   r   )r   s   "r   r   Ú?S6ServiceManager.register_profile_gateway.<locals>.__annotate__q  s!   € ÷ 	ñ 	 ð 	¨Cð 	°Dñ 	r   c                óN   € V P                  VR R7       V P                  R4       R# )rg   rh   r%  N)rñ   r  )r  r  s   &&r   Ú_write_scriptÚ@S6ServiceManager.register_profile_gateway.<locals>._write_scriptq  s   € Ø�O‰O˜D¨7ˆOÔ3Ø�J‰J�uÖr   r“   zlongrun
rg   rh   r	  Úfinishr*  Údownús6-svscanctlz-azs6-svscanctl failed: N)rU  rç   r   Ú	with_namer   ÚshutilÚrmtreer  rñ   rd  rk  rp  r,  ÚtouchÚrenamer•  r  r   rN  rF  rÊ   rG  rƒ  )r)   rD   r@   rA   r  Útmp_dirr«  r…  s   &&$$    r   rG   Ú)S6ServiceManager.register_profile_gatewayZ  s¸  € ð ×#Ñ# GÓ,ˆØ�>‰>×ÒÜÐ/°©{Ð:QÐRYÐQZÐ[Ó\Ð\ð ×#Ñ# C¨'¯,©,Õ$6¸Õ$?Ó@ˆØ�>‰>×ÒÜ�MŠM˜'°Õ6Ø�‰˜dˆÔ#õ	ð	Ø�vÕ×)Ñ)¨+ÀÐ)ÔHÙ˜' E�/¨4×+BÑ+BÀ7ÏOÈOÐY[Ó+\Ô]Ù˜' HÕ,¨d×.HÑ.HÓ.JÔKØ�u�_×#Ñ#Ô%Ù˜' E�/¨EÕ1°4×3GÑ3GÈÓ3PÔQô % WÔ-çØ˜6Õ!×(Ñ(Ô*Ø�N‰N˜7Ô#ô ˜¨¬s°4·<±<Ó/@ÓAˆØ×Ñ Ô!ä�MŠM˜'°Õ6ÜÐ!6°v·}±}×7UÐ7UÈÏÉÐ6VÐWÓXÐXñ "øô	 ô 	Ü�MŠM˜'°Õ6Øð	ús   Â*7G: Ã"B!G: Ç:%Hc               ó    € V ^8„  d   QhRRRR/# rJ   r   )r   s   "r   r   rO  ‹  s   € ÷ 3ñ 3°#ð 3¸$ñ 3r   c           	     óT  € V P                  V4      pVP                  4       '       g   R# \        RR\        V4      4       \        RRRR\        V4      ^R7       \        R	R
\        V P                  4      4       \
        P                  ! R4       \        P                  ! VRR7       R# )aÆ  Stop the profile gateway (best effort, wait for down) and remove its directory.
Idempotent: absent services are a no-op.

``s6-svscanctl -an`` fires BEFORE ``rmtree`` so s6-svscan reaps the supervise child and
releases its handles on ``supervise/lock``/``status``/``death_tally``; those files are
root-owned but the parent ``supervise/`` is hermes-owned (see ``_seed_supervise_skeleton``)
and POSIX only needs write+execute on the parent to remove them.
Nrv  r’  z	s6-svwaitz-Dr™  Ú10000)rý   r¯  z-angš™™™™™É?Tr¦  )	rU  rç   r  r   rN  rî   Úsleepr±  r²  )r)   rD   r  s   && r   rM   Ú+S6ServiceManager.unregister_profile_gateway‹  sz   € ð ×#Ñ# GÓ,ˆØ�~‰~×ÒÙÜ�˜$¤ G£Ô-Ü�˜T 4¨´#°g³,ÈÕKÜ� ¤s¨4¯<©<Ó'8Ô9ô 	�
Š
�3ŒÜ�Š�g¨T×2r   c               ó   € V ^8„  d   QhRR/# rP   r   )r   s   "r   r   rO  Ÿ  s   € ÷ 

ñ 

 yñ 

r   c                óœ  € V P                   P                  4       '       g   . # V P                   P                  4        Uu. uF�  pVP                  P	                  R4      '       d   K&  VP                  4       '       g   K>  VP                  P	                  \        4      '       g   Ke  VP                  \        \        4      R NKƒ  	  up# u upi )z;Profile names of all currently-registered gateway services.r¥  N)rN  rç   Úiterdirr   Ú
startswithrm   rÑ   r   )r)   Úentrys   & r   rR   Ú&S6ServiceManager.list_profile_gatewaysŸ  sž   € à�|‰|×"Ñ"×$Ò$ØˆIð Ÿ™×-Ñ-Ô/ó
á/�Ø—:‘:×(Ñ(¨×-ô 0ð —‘—ô 0ð —
‘
×%Ñ%Ô&7×8ô	 0ˆE�J‰J”sÔ,Ó-Ð.Ó/Ù/ñ
ð 	
ùò 
s   ¿#C	Á'C	Á?"C	Â& C	rQ  )rT   rU   rV   rW   rX   r#   rY   ÚS6_DYNAMIC_SCANDIRr5  rU  Ústaticmethodrd  rk  rp  rz  r*   r‡  r�  r.   r2   r8   r>   rG   rM   rR   rZ   r   r   r   rL  rL  ˜  s¯   ‡ ñ_ð  $€DÐ
Ó#à'9÷ õ>ð ô4'ó ð4'ðl ô
ó ð
ð8 ô
ó ð
õ:õ6õ
>õ(õ6õ6õ
"õð/YØBFð/YØZ^÷/Yõb3÷(

ñ 

r   rL  zdict[str, type]rÈ   )r   r   r	   r
   ra   )1Ú__conditional_annotations__rX   Ú
__future__r   rè   rØ   Úrer]  r±  r  rî   Úpathlibr   Útypingr   r   r   r"   Úcompiler   r   r   r!   rd   rc   rp   r£   r¯   r·   rÌ   rÂ  rÑ   rÒ   rÝ   rø   rü   r
  r  r  r  r  r,  rÊ   r.  r=  rC  rL  rÈ   rY   )rÄ  s   @r   Ú<module>rÊ     sf  øðÜ OÝ "ã Û 	Û 	Û Û Û Û Ý ß 7Ñ 7àÐJÕKÐ ð —J’JÐ7Ó8Ð ØÐ õWð ô6�Xó 6ó ð6õ,õ4D÷:-ñ -ô`
Ð/ô 
ôGÐ/ô Gô)Ð/ô )õ:ñ  ˜.Ó)Ð ØÐ õ0õ
Iõõ2ð, €ð°1ð ÀE÷ ð €Ø€õõ,ô^ˆlô ô
 ô 
ô3�Wô 3÷Q
ñ Q
ðj Ð$ØÐ$ØÐ$ØÐ
ð	%Ð �/õ r   