+
    „WÝj,  ã                  ó¬   € R t ^ RIHt ^ RIt^ RIHt ^ RIHtHt Rt	R R lt
RR R	 lltRR
 R lltRR]	 2RR/R R lltR R ltRRRR/R R lltR# )a»  Refusals that keep ``hermes gateway`` lifecycle verbs off gateways they must not take down.

Two rules, one per failure that took a production gateway down:

* **Foreign service definition.** A systemd unit / launchd plist pins the ``HERMES_HOME`` its gateway
  runs on. A lifecycle verb (start/stop/restart/uninstall) on a definition pinning ANOTHER home acts on
  another install's gateway: a ``HOME=<scratch>`` probe resolved the bare ``hermes-gateway`` name and ran
  ``systemctl --user stop`` on the account's real unit. Install/refresh already refused to WRITE such a
  definition (``gateway_service_owner``); the same module now refuses to OPERATE one:
  ``refuse_foreign_systemd_unit`` (salvaged from #141908, checked before any home sync) and
  ``refuse_foreign_launchd_plist``.
* **Live sessions.** ``gateway stop``/``restart`` name the turns, cron jobs or background delegations the
  gateway is running and ask y/N before interrupting them; ``-y``/``--yes`` (alias ``--interrupt``)
  skips the question, and with no terminal to ask on they refuse. The in-band restart
  drains turns, but its stop still interrupts every async delegation (``interrupt_all``), and a stop
  ends the sessions outright.
)ÚannotationsN)ÚPath)ÚAnyÚOptionalz--yesc               ó    € V ^8„  d   QhRRRR/# )é   Úhomer   ÚreturnúOptional[dict[str, Any]]© )Úformats   "ÚWC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\gateway_lifecycle_guards.pyÚ__annotate__r      s   € ÷ 	Cñ 	C ð 	CÐ)Añ 	Có    c                ó  € ^ RI HpHpHpHp V! V R,          4      pV'       d   V! V4      '       g   V! V4      '       g   R# VP                  R4      pRV! VP                  R4      4      R\        V\        4      '       d   V/# . /# )z]``active_agents`` from a fresh ``gateway_state.json`` whose writer is alive (older gateways).)Úparse_active_agentsÚread_runtime_statusÚruntime_status_is_staleÚruntime_status_pid_is_livezgateway_state.jsonNÚactive_workÚactive_agents)Úgateway.statusr   r   r   r   ÚgetÚ
isinstanceÚlist)r   r   r   r   r   ÚrecordÚworks   &      r   Ú_live_work_from_stater      sƒ   € ç|Ó|á  Ð(<Õ!<Ó=€FßÑ,¨V×4Ò4Ñ<VÐW]×<^Ò<^ÙØ�:‰:�mÓ$€DØÑ0°·±¸OÓ1LÓMØ¤:¨d´D×#9Ò#9˜4ðCð CØ?AðCð Cr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   ÚprofileúOptional[str]r	   r
   r   )r   s   "r   r   r   (   s"   € ÷ 	<ñ 	<�Dð 	< =ð 	<Ð<Tñ 	<r   c                óà   € ^ RI Hp T! T RV'       d   RV/MRR7      p\        V\        4      '       d(   \        VP	                  R4      \
        4      '       d   V# V'       d   R# \        V 4      # )a&  What the gateway serving ``home`` is running now: ``{"active_agents", "active_work"}``, or None
when no gateway answers. The control socket answers live; the state file covers older gateways.
``profile`` narrows the answer to one served profile's work (the state file cannot, so it is skipped).)Úquery_gateway_controlzactive-workr   N)Úparamsr   )Úgateway.control_socketr"   r   Údictr   r   r   )r   r   r"   Úanswers   &&  r   Ú	live_workr'   (   sZ   € õ =á" 4¨×W^À	È7Ñ?SÐdhÔi€FÜ�&œ$×Ò¤J¨v¯z©z¸-Ó/HÌ$×$OÒ$OØˆßˆ4Ð;Ô 5°dÓ ;Ð;r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚsystemÚboolr	   ú
list[Path]r   )r   s   "r   r   r   4   s   € ÷ ñ ˜Tð ¨jñ r   c                óÒ  € ^ RI HpHp VP                  4       .pVP	                  4       '       df   VP                  V 4      '       dO   VP                  R4      f<   VP                  VP                  RR7      R4      ;pV9  d   VP                  ^ V4       VP                  4       pVe?   \        VP                  4      V9  d%   VP                  \        VP                  4      4       V# )au  Homes whose gateway a stop/restart from here takes down, in order: the system unit's pinned home
(``sudo`` strips HERMES_HOME, so this process sees root's), this home's own gateway (a ``--force``
standalone one included), then the live host owner that serves it. Only READS the unit: a foreign
unit is skipped here and refused by the systemd verb before it adopts any home.)ÚgatewayÚgateway_service_ownerT)r)   )Ú
hermes_clir-   r.   Úget_hermes_homeÚsupports_systemd_servicesÚ_select_systemd_scopeÚforeign_systemd_unit_homeÚservice_home_for_unitÚget_systemd_unit_pathÚinsertÚ_host_multiplexer_for_all_verbr   r   Úappend)r)   Úgwr.   ÚhomesÚ	unit_homeÚowners   &     r   Ú_candidate_homesr=   4   sÂ   € ÷
 @à×ÑÓ!Ð"€EØ
×$Ñ$×&Ò&¨2×+CÑ+CÀF×+KÒ+KØ%×?Ñ?ÀÓEÒMØ3×IÑIÈ"×JbÑJbÐjnÐJbÓJoÐquÓvÐv�Øôà�‰�Q˜	Ô"Ø×-Ñ-Ó/€EØÒœT %§*¡*Ó-°UÔ:Ø�‰”T˜%Ÿ*™*Ó%Ô&Ø€Lr   Ú	flag_hintzhermes gateway {verb} r   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   ÚverbÚstrr:   r+   r>   r   r    r	   ú	list[str]r   )r   s   "r   r   r   G   s1   € ÷ ñ ˜ð  Jð ¸cð Ø(ðØ4=ñr   c               óR   € V F   p\        WC4      pVf   K  \        WWR4      u # 	  . # )zcRefusal text for ``verb`` while the first answering gateway among ``homes`` has live work, else [].)r'   Ú_work_lines)r@   r:   r>   r   r   r   s   &&$$  r   Úrefusal_linesrE   G   s2   € ó ˆÜ˜Ó'ˆØÔÜ˜t¨4Ó;Ò;ñ ð €Ir   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   r@   rA   r   r   r   zdict[str, Any]r>   r	   rB   r   )r   s   "r   r   r   Q   s0   € ÷ ñ �cð  ð ¨^ð Èð ÐPYñ r   c           	     ó   € ^ RI Hp VP                  R4      ;'       g    .  Uu. uF  p\        V\        4      '       g   K  VNK  	  pp\        \        V4      \        VP                  R4      ;'       g    ^ 4      4      pV'       g   . # RV  RV R2.pY† Uu. uF  pRV! WQ4       2NK  	  up,          pV'       g   VP                  RV R24       VR	R
VP                  V R7       RV R2.,          pV# u upi u upi )é    )Údescribe_active_work_unitr   r   úRefusing to z the gateway: z& live session(s) would be interrupted.u     â€¢ z6 active agent run(s) (this gateway does not name them)z2  Let them finish, or interrupt them deliberately:z    )r@   z   # interrupts z live session(s))
Ú"hermes_cli.update_cmd_drain_reportrI   r   r   r%   ÚmaxÚlenÚintr8   r   )	r@   r   r   r>   rI   ÚuÚunitsÚcountÚliness	   &&&&     r   rD   rD   Q   s  € ÝLàŸ™ Ó/×5Ð5°2Ð5ÓMÑ5�1¼ÀAÄt×9L�QˆQÑ5€EÐMÜ”�E“
œC §¡¨Ó 9× >Ð >¸QÓ?Ó@€EßØˆ	Ø˜D˜6 °¨wÐ6\Ð]Ð^€EØ	ÀUÓKÁUÀ�Ñ0°Ó9Ð:Ó;ÁUÑKÕK€EßØ�‰�v˜e˜WÐ$ZÐ[Ô\Ø	ÐBØ�Y×%Ñ%¨4Ð%Ó0Ð1Ð1AÀ%ÀÐHXÐYð[õ [€Eà€Lùò Nùò
 Ls   ¤C6ÁC6ÂC;Ú	host_homec               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r@   rA   rS   zOptional[Path]r   r    r	   ÚNoner   )r   s   "r   r   r   a   s*   € ÷  ñ   Sð  ¸nð  Ð^kð  Ðw{ñ  r   c          
     ó¤  € V'       d&   RV R\          2p\        V \        V4      .W4R7      pM \        V \        \	        VRR4      4      4      pV'       g   R# ^ RIHpHp \	        VRR4      '       dA   V! V^ ,          P                  R	V  R
2RV  R24      4       V^R  F  p\        V4       K  	  R# \        P                  P                  4       '       dº   \        P                  P                  4       '       d–   ^ RIHp	 V! V^ ,          P                  R	V  R
2V P!                  4        R
24      4       V^R  F  p\        V4       K  	  V	! RV  R2RR7      '       d   R# \        RV R8X  d   RMR R24       \        P"                  ! ^4       V! V^ ,          4       VR,           F  p\        V4       K  	  \        P"                  ! ^4       R# )zÜExit 1 naming the live work unless ``--interrupt`` was passed; with it, say what is interrupted.
``host_home``/``profile``: a served profile's stop/restart unserves only that profile in the host,
so only its work counts.z
hermes -p z gateway {verb} )r   r>   r)   FN)Úprint_errorÚprint_warningÚ	interruptrJ   z the gatewayz--yes: z	 proceeds)Úprompt_yes_nozInterrupt them and z the gateway?)Údefaultz!  Cancelled: the gateway was not ÚstopÚstoppedÚ	restartedÚ.:é   NNéþÿÿÿ)ÚINTERRUPT_FLAGrE   r   r=   ÚgetattrÚhermes_cli.gatewayrW   rX   ÚreplaceÚprintÚsysÚstdinÚisattyÚstdoutÚhermes_cli.cli_outputrZ   Ú
capitalizeÚexit)
r@   ÚargsrS   r   ÚhintrR   rW   rX   ÚlinerZ   s
   &&$$      r   Úrefuse_while_sessions_liverq   a   sŒ  € ÷ Ø˜G˜9Ð$6´~Ð6FÐGˆä˜d¤T¨)£_Ð$5¸wÔW‰ä˜dÔ$4´W¸TÀ8ÈUÓ5SÓ$TÓUˆßÙß=äˆt�[ %×(Ò(Ù�e˜A•h×&Ñ&¨°d°V¸<Ð'HÈGÐTXÐSYÐYbÐJcÓdÔeØ˜!˜B“KˆDÜ�$ŽKñ  áÜ
‡y�y×Ñ×ÒœcŸj™j×/Ñ/×1Ò1Ý7á�e˜A•h×&Ñ&¨°d°V¸<Ð'HÈTÏ_É_ÓM^ÐL_Ð_kÐJlÓmÔnØ˜!˜B“KˆDÜ�$ŽKñ  áÐ.¨t¨f°MÐBÈE×RÓRÙÜÐ1¸tÀv¼~±)ÐS^Ð1_Ð_`ÐaÔbÜ�Š�ŒÙ��a•ÔØ�b—	�	ˆÜˆdŽñ ä‡H‚HˆQ†Kr   )N)F)Ú__doc__Ú
__future__r   rg   Úpathlibr   Útypingr   r   rb   r   r'   r=   rE   rD   rq   r   r   r   Ú<module>rv      si   ðñõ$ #ã 
Ý ß  à€õ	C÷	<÷ð&ÐF^Ð_mÐ^nÐDoð Ø+/÷õð  Ètð  Ðnr÷  ñ  r   