+
    jHàj/,  ã                  óà   € R t ^ RIHt ^ RIt^ RIHtHt ^ RIHtH	t	H
t
Ht ]P                  ! ]4      tR tR tRR R ll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tR R ltR# )zPNamed-profile lifecycle inside the host gateway, never a service-manager action.)ÚannotationsN)Úget_hermes_homeÚget_default_hermes_root)Úparked_marker_pathÚprofile_is_parkedÚprofile_is_standaloneÚprofiles_to_servec                ó–   € \        V \        4      ;'       d3    V P                  V4      V8H  ;'       d    V P                  R 4      '       * # )Úerror©Ú
isinstanceÚdictÚget)ÚanswerÚkeyÚnames   &&&ÚI/home/ubuntu/.hermes/hermes-agent/hermes_cli/gateway_profile_lifecycle.pyÚack_confirmedr      s9   € Ü�fœdÓ#×[Ð[¨¯
©
°3«¸4Ñ(?×[Ð[ÈÏ
É
ÐSZÓH[ÔD[Ð[ó    c                óh   € \        V \        4      '       d   V P                  R 4      ;'       g    R# R# )r
   zhost operation is still pendingz"host control socket did not answerr   )r   s   &r   Úack_failurer      s*   € Ü�&œ$×ÒØ�z‰z˜'Ó"×GÐGÐ&GÐGÙ/r   c               ó    € V ^8„  d   QhRRRR/# )é   Úpidú
int | NoneÚreturnÚNone© )Úformats   "r   Ú__annotate__r      s   € ÷ 	ñ 	˜:ð 	°ñ 	r   c                ór   €  ^ RI HpHp V f
   V! RR7      p V e   V! V 4       R# R#   \         d     R# i ; i)zPBest-effort planned-stop marker for ``pid`` (default: the recorded gateway PID).)Úget_running_pidÚwrite_planned_stop_markerNF)Úcleanup_stale)Úgateway.statusr!   r"   Ú	Exception)r   r!   r"   s   &  r   Úmark_planned_stopr&      s=   € ðßMØŠ;Ù!°Ô6ˆCØŠ?Ù% cÖ*ñ øäô Úðús   ‚!' §6µ6c                óV   € ^ RI Hp T! V e   V P                  4      # \        4       4      # )uÅ  Home a ``--all`` verb acts as: the live host owner's, else the default root.

``--all`` names the ONE host gateway, whichever profile invoked the CLI â€” but the active home
decides the service name, the Windows task/launcher and the detached child's ``--profile``, so
with the host DOWN ``-p X gateway start|restart --all`` re-launched X's own gateway, which the
named-profile guard then refused (exit 78): the host stayed down after a Desktop update.
)Ú	_home_env)Úhermes_cli.gateway_migrater(   Úhomer   )Úownerr(   s   & r   Úhost_scope_for_all_verbr,   #   s'   € õ 5Ù 5Ò#4�U—Z‘ZÓTÐTÔ:QÓ:SÓTÐTr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚcommandÚstrr   Úboolr   )r   s   "r   r   r   /   s   € ÷ Eñ E˜sð E¨Tñ Er   c                ó¦  € ^ RI Hp ^ RIHpHp VP                  4       pV'       d.   VR8X  g'   \        VRR4      '       g   \        VRR4      '       d   R# \        4       p\        V4      '       d   R# \        V4      pV R8X  d*   \        V4      '       d   VP                  4       '       g   Rp V R8X  d·   \        V4      '       g   R# VP                  4        VP                  4       pVf   ^ R	IHp	 V	! 4       f   R# Ve   VP                   M	\#        4       p
V! W¥4      p\%        VR
V4      '       d   \'        RV R24       R# \'        RV R\)        V4       R24       \'        R4       R# VP                  4       '       d   R# VP+                  4       pVf   VP-                  4       '       g   R# Ve   VP                   M	\#        4       p
^ RIHp V! WW¥R7       V R8X  dh   VP3                  4        V! W¥4      p\%        VRV4      '       d   \'        RV RV R24       R# \'        RV R\)        V4       R24       \'        R4       R# V! W¥4      p\%        VRV4      '       g   \'        RV R\)        V4       R24       R# V! W¥4      p\%        VR
V4      '       d   \'        RV R24       R# \'        RV R\)        V4       R24       \'        R4       R# )zQTrue when a named-profile command was handled (including an unconfirmed request).©Úgateway)Úrequest_unserve_profileÚrequest_serve_profile_hotÚdefaultÚallFÚforceÚrestartÚstart)Úlive_default_gateway_pidÚservedú	Profile 'z' served by the host gateway.z+' unparked, but serving was not confirmed: Ú.zGThe host retries on its next rescan (within 30s). Check gateway status.T)Úrefuse_while_sessions_live)Ú	host_homeÚprofileÚstopÚunservedzE' parked; its bots and cron are stopped. Start again with: hermes -p z gateway startz0' parked, but immediate stop was not confirmed: z2The host drops it on its next rescan (within 30s).z' restart was not confirmed: z ' restarted by the host gateway.z*' stopped, but serving was not confirmed: )Ú
hermes_clir3   Úgateway.control_socketr4   r5   Ú_current_profile_nameÚgetattrr   r   r   r   Úfind_gateway_pidsÚunlinkÚ_host_multiplexer_for_all_verbÚ#hermes_cli.gateway_multiplex_servedr;   r*   r   r   Úprintr   Ú_served_by_another_host_gatewayÚ+named_profile_served_by_running_multiplexerÚ#hermes_cli.gateway_lifecycle_guardsr?   Útouch)r.   ÚargsÚgwr4   r5   r   r*   Úmarkerr+   r;   r@   r   r?   s   &&           r   Úprofile_lifecyclerT   /   s¯  € å(ßYà×#Ñ#Ó%€Dß�4˜9Ô$¬°°e¸U×(CÒ(CÄwÈtÐU\Ð^c×GdÒGdÙÜÓ€DÜ˜T×"Ò"ñ Ü Ó%€FØ�)ÔÔ 1°$× 7Ò 7À×@TÑ@T×@VÒ@Vð ˆØ�'ÔÜ  ×&Ò&ÙØ�‰ŒØ×1Ñ1Ó3ˆØŠ=ÝTÙ'Ó)Ò1ÙØ"'Ò"3�E—J’JÔ9PÓ9Rˆ	Ù*¨9Ó;ˆÜ˜ ¨4×0Ò0Ü�I˜d˜VÐ#@ÐAÔBñ ô �I˜d˜VÐ#NÌ{Ð[aÓObÐNcÐcdÐeÔfÜÐ[Ô\Ùð 
×Ñ×ÒÙØ×.Ñ.Ó0€EØ‚}˜R×KÑK×MÒMÙØ#Ò/�—
’
Ô5LÓ5N€IåNÙ˜w¸	ÕPØ�&Ôà�‰ŒÙ(¨Ó9ˆÜ˜ ¨T×2Ò2Ü�I˜d˜Vð $1Ø15°°nðFô Gñ
 ô �I˜d˜VÐ#SÔT_Ð`fÓTgÐShÐhiÐjÔkÜÐFÔGÙá$ YÓ5€FÜ˜ ¨T×2Ò2Ü�	˜$˜Ð<¼[ÈÓ=PÐ<QÐQRÐSÔTÙÙ& yÓ7€FÜ�V˜X t×,Ò,Ü�	˜$˜Ð?Ð@ÔAñ ô 	�	˜$˜ÐIÌ+ÐV\ÓJ]ÐI^Ð^_Ð`ÔaÜÐWÔXÙr   c               ó   € V ^8„  d   QhRR/# )r   r   r0   r   )r   s   "r   r   r   w   s   € ÷ ñ ˜Tñ r   c                 ó  € ^ RI Hp  V P                  4       pV'       d5   VR8w  d.   \        \	        4       4      '       d   \        RV RV R24       R# V'       d   VR8X  d›   \        RRR7       UUu. uF#  w  r#VR8w  g   K  \        V4      '       g   K!  VNK%  	  pppV'       dW   V P                  4       pVe(   \        RR	P                  VP                  4       24       V F  p\        RV RV R24       K  	  R
# u uppi )zDA parked satellite is still installed, but is not a running gateway.r2   r6   r=   z': parked (hermes -p z gateway start)T)Úinclude_parkedzServed profiles: z, F)
rD   r3   rF   r   r   rL   r   Úhost_multiplexer_servingÚjoinÚprofiles)rR   r   rA   r*   Úparkedr+   s         r   Úprint_parked_statusr\   w   sð   € å(Ø×#Ñ#Ó%€Dß�˜	Ô!Ô&7¼Ó8I×&JÒ&JÜ�	˜$˜Ð4°T°F¸/ÐJÔKÙß�4˜9Ô$Ü/@ÀÐVZÕ/[ô GÑ/[™m˜gØ 	Ñ)ô Ü.?À×.E÷ �'Ñ/[ˆñ GçØ×/Ñ/Ó1ˆEØÒ ÜÐ)¨$¯)©)°E·N±NÓ*CÐ)DÐEÔFÛ!�Ü˜	 ' Ð*?À¸yÈÐXÖYñ "áùóGs   Á2C>ÂC>ÂC>c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   Š   s   € ÷ ñ ˜:ñ r   c                 óÌ   € ^ RI Hp Hp  V ! 4       pVe   \        W!! 4       4      '       g   R# V ! 4       V8X  d   V# R#   \         d    \
        P                  RRR7        R# i ; i)au  This profile's own gateway pid, only on positive, fresh ownership evidence; else None.

A served profile's runtime record carries the host multiplexer's pid (#141133), so the recorded
pid alone never authorizes a stop. Every ``find_gateway_pids()`` caller (stop, uninstall's kill,
``service_manager.is_running``, cron readiness, Windows start polls) reads it through here.
)r!   Ú_get_process_hermes_homeNz)Could not prove gateway process ownershipT©Úexc_info)r$   r!   r_   Ú_pid_owned_by_homer%   ÚloggerÚdebug)r!   r_   r   s      r   Úowned_gateway_pidre   Š   sf   € ÷ Ið	ÙÓˆØŠ;Ô0°Ð6NÓ6P×QÒQÙá%Ó'¨3Ô.ˆsÐ8°DÐ8øÜô ä�‰Ð@È4ˆÔPÚðús   Š!= ­= »= ½"A#Á"A#c               ó    € V ^8„  d   QhRRRR/# ©r   r   Úintr   r0   r   )r   s   "r   r   r   Ÿ   s   € ÷ Nñ N˜Cð N¨$ñ Nr   c                ó>  € ^ RI HpHp ^ RIHp ^ RIHp VP                  VP                  4      pVRJ;'       d)    VP                  V 8H  ;'       d    VP                  V4      pV'       d!   V! VP                  V4      V4      '       g   R# \        W4      '       d   R# V'       d[   VP                  4        VP                  4       pVe7   VP                  V 8X  d&   VP                  '       d   V! VP                   V4      # V! V RR7      p	V	RJ;'       d	    V! W‘4      # )a  Ownership ladder, cheapest proof first; the control socket is dialled only for the host's pid.

``gateway status`` asks once per profile and every served profile's record names the host, so the
host record (a file read plus an incarnation check) settles those without a dial.
)Úhost_attachÚhost_rendezvous)Ú_same_hermes_home)Ú_hermes_home_for_pidNFT)Úrequire_launch_identity)r3   rj   rk   r$   rl   Úhermes_cli.dashboard_procsrm   Úread_recordÚROLE_GATEWAYr   Úrecord_names_live_ownerÚrecord_homeÚ_launch_record_ownsÚinvalidate_host_gateway_cacheÚhost_gatewayÚserved_knownr*   )
r   r*   rj   Úhrrl   rm   ÚrecordÚis_hostr+   Úprocess_homes
   &&        r   rb   rb   Ÿ   sé   € ÷ ;Ý0Ý?à�^‰^˜BŸO™OÓ,€FØ˜DÐ ×]Ð] V§Z¡Z°3Ñ%6×]Ð]¸2×;UÑ;UÐV\Ó;]€GßÑ(¨×)@Ñ)@ÀÓ)HÈ$×OÒOÙÜ˜3×%Ò%ÙßØ×1Ñ1Ô3Ø×(Ñ(Ó*ˆàÒ §¡¨cÔ!1°e×6H×6HÐ6HÙ$ U§Z¡Z°Ó6Ð6Ù'¨ÀTÔJ€LØ˜tÐ#×MÐMÑ(9¸,Ó(MÐMr   c               ó    € V ^8„  d   QhRRRR/# rg   r   )r   s   "r   r   r   ¹   s   € ÷ [ñ [˜Sð [¨4ñ [r   c                ó\  € ^ RI HpHpHpHpHp V! 4       ;'       g    / pVP                  R4      VP                  R4      r˜VP                  R4      V8H  ;'       dR    V! V4      V 8H  ;'       d?    VRJ;'       d3    Wƒ! V 4      8H  ;'       d!    \        V	\        4      ;'       d	    V! W‘4      # )a‘  ``<home>/gateway.pid`` names *pid*'s exact incarnation as launched from *home*.

A gateway writes that file once, about its own launch home (the host never writes one into a
served profile), so it pins the profile resolved at launch: a ``gateway run --force`` that relied
on the sticky ``active_profile`` stays stoppable after the sticky choice changes, which argv and
environment alone cannot prove.
)Ú_GATEWAY_KINDÚ_get_process_start_timeÚ_pid_from_recordÚ_read_pid_recordrl   Ú
start_timeÚhermes_homeÚkindN)	r$   r~   r   r€   r�   rl   r   r   r/   )
r   r*   r~   r   r€   r�   rl   ry   ÚstartedÚrecorded_homes
   &&        r   rt   rt   ¹   sÂ   € ÷gõ gñ Ó×%Ð% 2€FØ#ŸZ™Z¨Ó5°v·z±zÀ-Ó7Pˆ]Ø�J‰J�vÓ -Ñ/÷ Zð ZÑ4DÀVÓ4LÐPSÑ4S÷ Zð ZØ˜tÐ#÷Zð ZØ(/Ð3JÈ3Ó3OÑ(O÷Zð Zä˜=¬#Ó.÷Zð Zá3DÀ]Ó3Yð[r   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r   Ë   s   € ÷ ñ  Tñ r   c                 ó2  € ^ RI Hp  ^ RIHp  V ! 4       RJ ;'       d    VP	                  4       '       * pV'       d   \        R4       R# VP                  R	4       \        4        \        ^4      h  \
         d    \        P                  RRR7       Rp Lai ; i)
zFDo not report absence when a live PID was refused or the probe failed.©r!   r2   Nz,Could not confirm gateway absence after stopTr`   Fu'   âœ— No gateway running for this profilezkGateway stop was not confirmed; a gateway may still be running. Check gateway status and process ownership.)r$   r!   rD   r3   rH   r%   rc   rd   rL   Úprint_errorÚ_print_host_hintÚ
SystemExit)r!   rR   Úabsents      r   Úreport_profile_stop_failurer�   Ë   s‰   € å.Ý(ðÙ Ó" dÐ*×IÐI°2×3GÑ3GÓ3IÔ/Iˆ÷ ÜÐ7Ô8ÙØ‡N�Nð Aô BäÔÜ
�Q‹-Ðøô ô Ü�‰ÐCÈdˆÔSØŠðús   ŽA/ žA/ Á/$BÂBc               ó   € V ^8„  d   QhRR/# rˆ   r   )r   s   "r   r   r   Þ   s   € ÷ [ñ [˜$ñ [r   c                 ó  € ^ RI Hp  ^ RIHp  V! 4       V P	                  V P
                  4      r2Te+   Te%   TP                  T8X  d   \        RT R24       R# R# R# R#   \         d    \        P                  RRR7        R# i ; i)	zPName the refused pid when it is the host gateway serving this profile (#141133).)rk   rŠ   z0Could not read the host record for the stop hintTr`   Nz  PID z� is the host gateway serving this profile; stopping it would take every served profile offline. Stop the host instead: hermes gateway stop --all)r3   rk   r$   r!   rp   rq   r%   rc   rd   r   rL   )rx   r!   r   ry   s       r   rŒ   rŒ   Þ   s‡   € å-Ý.ðÙ%Ó'¨¯©¸¿¹Ó)HˆVð ‚˜6Ò-°&·*±*ÀÔ2CÜ��s�eð Yð Zö 	[ñ 3DÑ-�øô ô Ü�‰ÐGÐRVˆÔWÚðús   Ž!A Á"BÂB)N)Ú__doc__Ú
__future__r   ÚloggingÚhermes_constantsr   r   Úhermes_cli.profilesr   r   r   r   Ú	getLoggerÚ__name__rc   r   r   r&   r,   rT   r\   re   rb   rt   r�   rŒ   r   r   r   Ú<module>r™      sg   ðÙ VÝ "ã ç Eß oÓ oð 
×	Ò	˜8Ó	$€ò\ò0÷	ò	UõEõPõ&õ*Nõ4[õ$÷&[r   