+
    lHàjè ã                   ó`  a € R^ ty0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI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 ^ RIHt ^ RIHtHtHtHt ^ RIHtHtHt ^ RIH t  ^ RI!H"t"H#t#H$t$H%t%H&t&H't'H(t(H)t)H*t* ^ R	I+H,t,H-t-H.t. ^ R
I/H0t0 ^ RI1H2t2H3t3H4t4H5t5H6t6H7t7 ]Pp                  ! ]94      t:. R_Ot;Rs<] ^ k ]t=Rt>Rt?]P€                  ! R4      tAR R ltBR R ltC]4tD]P€                  ! R4      tER R ltF]0tGR R ltHR`R R lltIR R ltJR R ltKRRR RR!R/R" R# lltLR$ R% ltMR& R' ltNR( R) ltOR*RaR+RR,]
P                   ]Q3/R- R. lltRR/ R0 ltSR1 R2 ltTR3 R4 ltU. RbOtVR5tWR6tXR7 R8 ltYRctZR9 R: lt[Rdt\Ret]. RfOt^]_! 4       t`] ^k ]PÂ                  ! 4       tbRgtcR;R<.tdRhR> R? llteR@ RA ltfRB RC ltgRsh] ^k Rsi] ^k RD RE ltjRFR=/RG RH lltkRI RJ ltlRK RL ltmRitnRM RN ltoRO RP ltp]P€                  ! RQ4      tqRjtrRR RS ltsRT RU lttRV RW ltuRX RY ltvRZ R[ ltw ! R\ R]]4      txR# )kzçDocker execution environment for sandboxed command execution.

Security hardened (cap-drop ALL, no-new-privileges, PID limits), configurable
resource limits (CPU, memory, disk), and optional filesystem persistence via
bind mounts.
N)ÚPath)ÚOptional)Úget_hermes_home)ÚBaseEnvironmentÚEnvironmentConnectionErrorÚ_SHELL_ENV_NAME_REÚget_sandbox_dir)Ú_host_path_keyÚ_is_windows_drive_pathÚcwd_follows_host_mount)Ú_popen_bash)	Ú_EGRESS_LABEL_KEYÚ_critical_egress_env_namesÚ_egress_enforce_on_dockerÚ_egress_proxy_args_for_dockerÚ_egress_reuse_fingerprintÚcheck_docker_env_collisionsÚcheck_extra_args_collisionsÚcheck_forward_env_collisionsÚmerge_egress_env)Úhand_back_sandbox_filesÚreclaim_sandbox_filesÚstrip_sandbox_privileges)Úsanitize_task_id_for_path)Ú	bash_argvÚclient_env_withÚload_hermes_env_varsÚprepend_unsetÚresolve_passthrough_envÚrun_capturezhermes-environmentzhermes-workspacez:ws:([0-9a-f]{16})$c                ój   € V ^8„  d   QhR\         \        ,          R,          R\         \        ,          /# )é   Úforward_envNÚreturn©ÚlistÚstr)Úformats   "Ú>/home/ubuntu/.hermes/hermes-agent/tools/environments/docker.pyÚ__annotate__r)   <   s'   € ÷ ñ ¬d´3­i¸$Õ.>ð Ä4ÌÅ9ñ ó    c                óX  € . pT ;'       g    .  F—  p\        V\        4      '       g   \        P                  RV4       K1  VP	                  4       pV'       g   KK  \
        P                  V4      '       g   \        P                  RV4       K~  W19  g   K†  VP                  V4       K™  	  V# )z?Return a deduplicated list of valid environment variable names.z0Ignoring non-string docker_forward_env entry: %rz-Ignoring invalid docker_forward_env entry: %r)Ú
isinstancer&   ÚloggerÚwarningÚstripÚ_ENV_VAR_NAME_REÚmatchÚappend)r"   Ú
normalizedÚitemÚkeys   &   r(   Ú_normalize_forward_env_namesr6   <   sˆ   € à€JØ×!Ð!˜rÒ!ˆÜ˜$¤×$Ò$Ü�N‰NÐMÈtÔTÙØ�j‰j‹lˆßÙÜ×%Ñ% c×*Ò*Ü�N‰NÐJÈDÖQØÖ"Ø×Ñ˜cÖ"ñ "ð Ðr*   c                ó`   € V ^8„  d   QhR\         R,          R\         \        \        3,          /# )r!   ÚenvNr#   ©Údictr&   )r'   s   "r(   r)   r)   M   s&   € ÷ ñ œT D�[ð ¬T´#´s°(­^ñ r*   c                ó¦  € V '       g   / # \        V \        4      '       g,   \        P                  R\	        V 4      P
                  4       / # / pV P                  4        Fï  w  r#\        V\        4      '       d*   \        P                  VP                  4       4      '       g   \        P                  RV4       K\  \        V\        \        \        \        34      '       g;   \        P                  RVP                  4       \	        V4      P
                  4       K¼  \        V\        4      '       d   TM
\        V4      WP                  4       &   Kñ  	  V# )zTValidate a docker_env dict to {str: str}; scalars are coerced, other values dropped.zdocker_env is not a dict: %sz#Ignoring invalid docker_env key: %rz/Ignoring non-string docker_env value for %r: %s)r,   r:   r-   r.   ÚtypeÚ__name__Úitemsr&   r0   r1   r/   ÚintÚfloatÚbool)r8   r3   r5   Úvalues   &   r(   Ú_normalize_env_dictrC   M   sç   € çØˆ	Ü�cœ4× Ò Ü�‰Ð5´t¸C³y×7IÑ7IÔJØˆ	Ø!#€JØ—i‘i–k‰
ˆÜ˜#œs×#Ò#Ô+;×+AÑ+AÀ#Ç)Á)Ã+×+NÒ+NÜ�N‰NÐ@À#ÔFÙÜ˜%¤#¤s¬E´4Ð!8×9Ò9Ü�N‰NÐLÈcÏiÉiËkÔ[_Ð`eÓ[f×[oÑ[oÔpÙÜ+5°e¼S×+AÒ+A¡%ÄsÈ5Ãzˆ
—9‘9“;Óñ "ð Ðr*   z[^A-Za-z0-9_.-]c                ó0   € V ^8„  d   QhR\         R\         /# )r!   rB   r#   ©r&   )r'   s   "r(   r)   r)   i   s   € ÷ @ñ @¤ð @¬ñ @r*   c                ó�   € \        V \        4      '       d	   V '       g   R# \        P                  RV 4      R,          ;'       g    R# )zXLossy coercion into a Docker label-safe form; empty/invalid input becomes ``"unknown"``.ÚunknownÚ_:Né?   N)r,   r&   Ú_LABEL_VALUE_OK_REÚsub)rB   s   &r(   Ú_sanitize_label_valuerL   i   s4   € ä�eœS×!Ò!¯ÙÜ×!Ñ! # uÓ-¨cÕ2×?Ð?°iÐ?r*   c                ó$   € V ^8„  d   QhR\         /# ©r!   r#   rE   )r'   s   "r(   r)   r)   u   s   € ÷ ñ ¤#ñ r*   c                 óV   €  ^ RI Hp  V ! 4       ;'       g    R#   \         d     R# i ; i)z°Active Hermes profile name, or ``"default"`` on any error. Resolved at container-create
time so a container stays tagged with its creator even if the process switches profiles.©Úget_active_profile_nameÚdefault)Úhermes_cli.profilesrQ   Ú	ExceptionrP   s    r(   Ú_get_active_profile_namerU   u   s-   € ðÝ?Ù&Ó(×5Ð5¨IÐ5øÜô Úðús   ‚ – ™(§(c                ó0   € V ^8„  d   QhR\         R\         /# )r!   Ú
shared_keyr#   rE   )r'   s   "r(   r)   r)      s   € ÷ @ñ @¤Cð @´ñ @r*   c                óÚ   € V '       g   \        \        4       4      # \        P                  ! V P	                  R4      4      P                  4       R,          p\        V 4      R,           RV 2# )aQ  Profile label used for container reuse and orphan reaping. Profiles are isolated by default; an
explicit shared key lets trusted profiles share one Docker identity. Label sanitization is lossy
and reuse is label-keyed, so a digest of the raw key disambiguates colliding keys. Plain profile
names keep their historical un-suffixed labels.úutf-8ºNé   N:Né2   NÚ-)rL   rU   ÚhashlibÚsha256ÚencodeÚ	hexdigest)rW   Údigests   & r(   Ú_container_identityrc      sY   € ÷
 Ü$Ô%=Ó%?Ó@Ð@Ü�^Š^˜J×-Ñ-¨gÓ6Ó7×AÑAÓCÀCÕH€FÜ# JÓ/°Õ4Ð5°Q°v°hÐ?Ð?r*   c                ó0   € V ^8„  d   QhR\         R\        /# )r!   Úspecr#   ©r&   rA   )r'   s   "r(   r)   r)   Š   s   € ÷ ñ ¤#ð ¬$ñ r*   c                óJ  € V R9   g   RV 9  d   R# \        V 4      pVe
   V^ ,          MV P                  R^4      ^ ,          p\        V4      '       d   R#  \        P                  P                  \        P                  ! 4       4      p\        P                  P                  \        P                  P                  \        P                  P                  V4      4      4      pWC8H  ;'       g'    VP                  V\        P                  ,           4      #   \         d     R# i ; i)uø  True when *spec* is a ``host:container[:mode]`` mount whose host source is a
per-process tempdir (a ``mkdtemp`` under the system temp), so its path is random
per process and must not be hashed into the reuse label.

The known source is the symlink-safe skills copy from
``credential_files._safe_skills_path``: any symlink under ``skills/`` makes it a
fresh ``mkdtemp`` per process. Stable host paths â€” including a symlink-free
skills dir, which mounts directly â€” never sit under the process tempdir.
Ú:F)ú-vz--mount)Ú_split_volume_specÚsplitr
   ÚosÚpathÚrealpathÚtempfileÚ
gettempdirÚabspathÚ
expanduserÚ
startswithÚsepÚOSError)re   ÚparsedÚsourceÚ	temp_rootÚ
source_abss   &    r(   Ú_is_volatile_mount_specrz   Š   s×   € ð Ð Ô  C¨t¤OÙÜ Ó%€FØ Ò,ˆV�AŽY°$·*±*¸SÀ!Ó2DÀQÕ2G€FÜ˜f×%Ò%ÙðÜ—G‘G×$Ñ$¤X×%8Ò%8Ó%:Ó;ˆ	Ü—W‘W×%Ñ%¤b§g¡g§o¡o´b·g±g×6HÑ6HÈÓ6PÓ&QÓRˆ
ØÑ&×SÐS¨*×*?Ñ*?À	ÌBÏFÉFÕ@RÓ*SÐSøÜô Úðús   ÁBD Ã,&D ÄD"Ä!D"c                ó^   € V ^8„  d   QhR\         R\        \         ,          R\         R\         /# )r!   ÚimageÚ
mount_argsÚhermes_homer#   ©r&   r%   )r'   s   "r(   r)   r)   ¢   s4   € ÷ Dñ D¬Sð D¼dÄ3½ið DÔVYð DÔ^añ Dr*   c                óì  € \         P                  P                  \         P                  P                  \         P                  P	                  V4      4      4      pV Uu. uF2  p\        V4      '       d   RVP                  R^4      ^,           2MTNK4  	  pp\        P                  ! RV RVRV/RR
R7      p\        P                  ! VP                  R4      4      P                  4       R	,          # u upi )a�  Hash immutable configuration so reuse cannot silently attach to stale mounts.

Hash requested values rather than exposing profile paths and volume sources in labels.
Keep mount order: later arguments can override earlier mount destinations.
Per-process tempdir-sourced mounts (the symlink-safe skills copy) have their volatile
host path replaced by a stable placeholder: the path is random per process, so hashing
it made the label differ across processes and cross-process container reuse never
matched for users with any symlink under ``skills/``. The container path stays in the
hash, so moving where that mount lands still forces a fresh container.
z<volatile-tempdir-mount>:rh   r|   r}   r~   T)Ú	sort_keysÚ
separatorsrY   :Né   N)Ú,rh   )rl   rm   Únormcaserq   rr   rz   rk   ÚjsonÚdumpsr^   r_   r`   ra   )r|   r}   r~   Únormalized_homere   Úcanonical_mountsÚpayloads   $$$    r(   Ú_reuse_environment_fingerprintr‹   ¢   sØ   € ô —g‘g×&Ñ&¤r§w¡w§¡´r·w±w×7IÑ7IÈ+Ó7VÓ'WÓX€Oñ ó ñ ˆDô $ D×)Ò)ð % T§Z¡Z°°QÓ%7¸Õ%:Ð$;Ñ	<Ø/3ò
4áð ð  ô �jŠjØ	�%˜Ð'7¸ÈÐXØ :ô/€Gô �>Š>˜'Ÿ.™.¨Ó1Ó2×<Ñ<Ó>¸sÕCÐCùò s   Á8C1Úmax_age_secondsiX  Úprofile_filterÚ
docker_exec                ód   € V ^8„  d   QhR\         R\        R,          R\        R,          R\         /# )r!   rŒ   r�   NrŽ   r#   )r?   r&   )r'   s   "r(   r)   r)   ¸   s6   € ÷ -ñ -Üð-Ü36¸µ:ð-ÜRUÐX\ÕR\ð-äñ-r*   c                óN  € T;'       g    \        4       ;'       g    Rp. ROpV'       d    VP                  RR\        V4       2.4       \        VRR.VORNRN^RR	R
7      pVf   ^ # \        P                  P                  \        P                  4      p^ pR VP                  P                  4        4        Fé  p\        W84      p	V	f   K  Wi,
          P                  4       p
W 8  d   K2  \        W84       \        W84      '       d   KP  \        VRV.^RVR,          3R7      pVf   Kp  VP                  ^ 8X  d3   V^,          p\        P                  RVR,          \!        V
4      4       K³  \        P#                  RVR,          VP$                  P'                  4       4       Kë  	  V# )a®  Remove stale hermes-tagged containers left behind by prior processes (SIGKILL/OOM
exits that bypass atexit). Only ``status=exited`` containers (running ones may belong
to a sibling process), only the caller's profile, and only if ``FinishedAt`` is older
than *max_age_seconds* (a just-exited sibling may be about to reuse its container).
Best-effort and idempotent: failures log at debug and the count removed so far is returned.
Údockerú--filterúlabel=hermes-profile=Úpsú-aú--formatz{{.ID}}z"orphan reaper docker ps failed: %sz'orphan reaper docker ps returned %d: %s©ÚtimeoutÚfailÚnonzeroc              3   óp   "  € T F,  qP                  4       '       g   K  VP                  4       x € K.  	  R # 5i©N©r/   ©Ú.0Úlns   & r(   Ú	<genexpr>Ú)reap_orphan_containers.<locals>.<genexpr>Ï   s"   é € ÐOÑ%@˜rÇHÁHÇJ”
�—‘—
�
Ó%@ùs   ‚6ž6Úrmz%orphan reaper docker rm %s failed: %srZ   ©r˜   r™   Ú	fail_argsz2Reaped orphan container %s (exited %d seconds ago)zdocker rm %s failed: %s)r’   úlabel=hermes-agent=1r’   zstatus=exited)Úfind_dockerÚextendrL   Ú_docker_queryÚdatetimeÚnowÚUTCÚstdoutÚ
splitlinesÚ_container_finished_atÚtotal_secondsr   Ú_is_idle_workspace_containerÚ
returncoder-   Úinfor?   ÚdebugÚstderrr/   )rŒ   r�   rŽ   r‘   ÚfiltersÚlistingr«   ÚremovedÚcidÚfinished_atÚageÚresults   $$$         r(   Úreap_orphan_containersr½   ¸   sˆ  € ð ×4Ð4œ;›=×4Ð4¨H€FÚO€GßØ�‰˜
Ð&;Ô<QÐR`Ó<aÐ;bÐ$cÐdÔeäØ	��tÐ=˜gÐ= zÐ=°9Ð=ÀrØ1Ð;dôf€Gð ‚Ùô ×
Ñ
×
Ñ
¤§¡Ó
-€CØ€GÙO W§^¡^×%>Ñ%>Ô%@ÖOˆÜ,¨VÓ9ˆØÒÙØÕ ×/Ñ/Ó1ˆØÔ ÙÜ  Ô-Ü'¨×4Ò4Ùô Ø�T˜3Ð¨Ð2YÐfiÐjmÕfnÐepôrˆàŠ>ÙØ×Ñ Ô!Ø�q�LˆGÜ�K‰KÐLÈcÐRUÍhÔX[Ð\_ÓX`Öaä�L‰LÐ2°C¸µH¸f¿m¹m×>QÑ>QÓ>SÖTñ+ Pð, €Nr*   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r!   rŽ   Úcontainer_idr#   rf   )r'   s   "r(   r)   r)   è   s&   € ÷ Lñ L¬Sð LÄð LÌñ Lr*   c                óÚ   € \        V RRR\         R2V.^
RVR,          3R7      pVe   VP                  ^ 8w  d   R	# \        P                  ! R
VP
                  P                  4       4      RJ# )aÊ  A persistent per-workspace container (task key ``<base>:ws:<digest>``, stamped with the
``hermes-workspace=<digest>`` label at create time) that the idle reaper STOPPED on purpose
(``DockerEnvironment.stop_idle``): it is that workspace's sandbox, restarted on next use, not an
orphan. Reads the dedicated label, never the 63-char-truncated ``hermes-task-id``, whose
``_ws_<digest>`` suffix a long profile name cuts. Unknown (inspect failed) reads as not one.Úinspectr–   z{{index .Config.Labels "z"}}ú*orphan reaper docker inspect %s failed: %srZ   r¤   NFz[0-9a-f]{16})r©   Ú_WORKSPACE_LABEL_KEYr²   ÚreÚ	fullmatchr­   r/   )rŽ   r¿   r¼   s   && r(   r±   r±   è   sw   € ô Ø	�Y 
Ð.HÔI]ÐH^Ð^cÐ,dÐfrÐsØÐEÐR^Ð_bÕRcÐQeôg€Fð ‚~˜×*Ñ*¨aÔ/ÙÜ�<Š<˜¨¯©×)<Ñ)<Ó)>Ó?ÀtÐKÐKr*   c                ó0   € V ^8„  d   QhR\         R\         /# )r!   rŽ   r¿   rE   )r'   s   "r(   r)   r)   ö   s   € ÷ ñ ¤sð ¼#ñ r*   c                óÜ  € \        V RRRV.^
RVR,          3R7      pVe   VP                  ^ 8w  d   R# VP                  P                  4       pV'       d   VP	                  R4      '       d   R# \
        P                  ! R	R
V4      P                  RR4      p \        P                  P                  V4      #   \         d*   p\        P                  RY1R,          T4        Rp?R# Rp?ii ; i)z¤``docker inspect`` FinishedAt as an aware datetime; ``None`` (= don't reap) when
missing/unparseable or Docker's never-finished zero value ``0001-01-01T00:00:00Z``.rÁ   r–   z{{.State.FinishedAt}}rÂ   rZ   r¤   Nz
0001-01-01z(\.\d{6})\d+z\1ÚZz+00:00z(could not parse FinishedAt %r for %s: %s)r©   r²   r­   r/   rs   rÄ   rK   Úreplacerª   ÚfromisoformatÚ
ValueErrorr-   r´   )rŽ   r¿   r¼   ÚrawÚes   &&   r(   r¯   r¯   ö   sÒ   € ô Ø	�Y 
Ð,CÀ\ÐRÐ\^Ø9ÀlÐSVÕFWÐEYô[€Fð ‚~˜×*Ñ*¨aÔ/ÙØ
�-‰-×
Ñ
Ó
€Cß�#—.‘. ×.Ò.Ùä
�&Š&� %¨Ó
-×
5Ñ
5°c¸8Ó
D€CðÜ× Ñ ×.Ñ.¨sÓ3Ð3øÜô Ü�‰Ð?ÀÐSVÕFWÐYZÔ[Ýûðús   ÂB7 Â7C+ÃC&Ã&C+c                ó0   € V ^8„  d   QhR\         R\        /# )r!   rm   r#   rf   )r'   s   "r(   r)   r)   
  s   € ÷ =ñ =œð =¤ñ =r*   c                 óš   € \         P                  P                  V 4      ;'       d&    \         P                  ! V \         P                  4      # rœ   )rl   rm   ÚisfileÚaccessÚX_OK)rm   s   &r(   Ú_is_executablerÓ   
  s,   € Ü�7‰7�>‰>˜$Ó×<Ð<¤B§I¢I¨d´B·G±GÓ$<Ð<r*   r¥   rš   Ú	exc_typesc                ó„   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        R,          R\        /# )r!   Úargvr˜   r™   r¥   rš   NrÔ   )r%   r&   r@   Útuple)r'   s   "r(   r)   r)     sF   € ÷ ñ Ü
Œs�)ðÜ!&ðÜ.1ðÜ>CðÜSVÐY]ÕS]ðäñr*   c               ó(  €  \        WR7      pTeR   TP                  ^ 8w  dA   \        P                  ! T.TOTP                  NTP                  P                  4       N5!   R# T#   T d&   p\        P                  ! T.TOTN5!    Rp?R# Rp?ii ; i)zäBest-effort ``run_capture`` for probes: logs *fail* (``*fail_args, exc``) at debug and
returns ``None`` when the CLI raises; with *nonzero* set, a nonzero exit also logs
(``*fail_args, returncode, stderr``) and returns ``None``.©r˜   N)r   r-   r´   r²   rµ   r/   )rÖ   r˜   r™   r¥   rš   rÔ   r¼   rÍ   s   &$$$$$  r(   r©   r©     s‡   € ðÜ˜TÔ3ˆð Ò˜v×0Ñ0°AÔ5Ü�Š�WÐS˜yÐS¨&×*;Ñ*;ÐS¸V¿]¹]×=PÑ=PÓ=RÔSÙØ€Møð ô Ü�Š�TÐ)˜IÐ) qÔ)Ýûðús   ‚A% Á%BÁ,BÂBc                ó:   € V ^8„  d   QhR\         \        ,          /# rN   ©r   r&   )r'   s   "r(   r)   r)      s   € ÷ ñ ”Xœc•]ñ r*   c                 óØ  € \         e   \         # \        P                  ! R4      p V '       d+   \        V 4      '       d   \        P                  RV 4       T pM‰\        P                  ! R4      ;p'       d   Mj\        P                  ! R4      ;p'       d   \        P                  RV4       M5\        R \         4       R4      ;p'       d   \        P                  RV4       V'       d   Vs V# )	zªLocate the docker/podman CLI (cached): ``HERMES_DOCKER_BINARY`` override, ``docker``
on PATH, ``podman`` on PATH, then macOS Docker Desktop locations; ``None`` if absent.NÚHERMES_DOCKER_BINARYz'Using HERMES_DOCKER_BINARY override: %sr‘   Úpodmanz%Using podman as container runtime: %sc              3   óL   "  € T F  p\        V4      '       g   K  Vx € K  	  R # 5irœ   )rÓ   )rŸ   Úps   & r(   r¡   Úfind_docker.<locals>.<genexpr>/  s   é € ÐMÑ#7˜a¼>È!×;LŸšÓ#7ùs   ‚$š
$z%Found docker at non-PATH location: %s)
Ú_docker_executablerl   ÚgetenvrÓ   r-   r³   ÚshutilÚwhichÚnextÚ_DOCKER_SEARCH_PATHS)ÚoverrideÚfounds     r(   r§   r§      s°   € ô Ò%Ü!Ð!ä�yŠyÐ/Ó0€Hß”N 8×,Ò,Ü�‰Ð=¸xÔHØ‰Ü—,’,˜xÓ(Ð	(ˆÖ	(ØÜ—,’,˜xÓ(Ð	(ˆÖ	(Ü�‰Ð;¸UÕCÜÑMÕ#7ÓMÈtÓTÐ	TˆÖ	TÜ�‰Ð;¸UÔCßØ"ÐØ€Lr*   c                ó0   € V ^8„  d   QhR\         R\         /# ©r!   Ú
executabler#   rE   )r'   s   "r(   r)   r)   6  s   € ÷ Vñ V¤Cð V¬Cñ Vr*   c                ón   € R\         P                  P                  V 4      P                  4       9   d   R# R# )z�User-facing runtime name (``"Podman"`` / ``"Docker"``) for the CLI at *executable*, so
diagnostics and pickers name the runtime actually in use.rÞ   ÚPodmanÚDocker)rl   rm   ÚbasenameÚlower©rì   s   &r(   Údocker_runtime_nameró   6  s.   € ð  ¤2§7¡7×#3Ñ#3°JÓ#?×#EÑ#EÓ#GÔGˆ8ÐUÈXÐUr*   c                ó0   € V ^8„  d   QhR\         R\         /# rë   rE   )r'   s   "r(   r)   r)   <  s   € ÷ 2ñ 2¬#ð 2´#ñ 2r*   c                ó*   € \        V 4      R8w  d   R# R# )z¨How to bring the runtime at *executable* back up, for a "not reachable" message. Docker has
a daemon to start; Podman is daemonless (outside Linux it runs inside a VM).rî   zstart Docker and retryz$run `podman machine start` and retry)ró   rò   s   &r(   Údocker_runtime_start_hintrö   <  s   € ô ˜:Ó&¨(Ô2Ù'Ù1r*   Ú2048Ú1gc                ó0   € V ^8„  d   QhR\         R\        /# ©r!   Ú
extra_argsr#   )r%   rA   )r'   s   "r(   r)   r)   h  s   € ÷ %ñ %¬ð %´$ñ %r*   c                ó’   € \         ;QJ d&    R T ;'       g    .  4       F  '       g   K   R# 	  R# ! R T ;'       g    .  4       4      # )zUTrue when docker_extra_args already set ``--shm-size`` (then our default is skipped).c              3   óŽ   "  € T F;  p\        V\        4      ;'       d    VR 8H  ;'       g    VP                  R4      x € K=  	  R# 5i)ú
--shm-sizez--shm-size=N)r,   r&   rs   )rŸ   Úas   & r(   r¡   Ú+_extra_args_set_shm_size.<locals>.<genexpr>j  s?   é € ð %á"ˆAô 	�1”cÓ×QÐQ  \Ñ 1× PÐ P°Q·\±\À-Ó5PÔQÛ"ùs   ‚AžA«ATF)Úany)rû   s   &r(   Ú_extra_args_set_shm_sizer  h  sS   € ç‹3ñ %à×"Ð" Ð"ó%�3Œ3ð %Š3ð %ˆ3ñ %à×"Ð" Ð"ó%ó %ð %r*   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# rú   )r%   r   r&   )r'   s   "r(   r)   r)   r  s   € ÷ ñ ¬ð ´(¼3µ-ñ r*   c                óŠ  € T ;'       g    .  Uu. uF  p\        V\        4      '       g   K  VNK  	  pp\        V4       F{  w  r4\         Fl  pWE8X  d-   V^,           \	        V4      8  d   W#^,           ,          MRu u # VP                  V R24      '       g   KQ  VP                  R^4      ^,          u u # 	  K}  	  R# u upi )aS  Network mode requested by ``docker_extra_args`` (``--network none`` / ``--network=none`` /
``--net``), or None when the operator set no network flag. Docker rejects a repeated
``--network`` outright (exit 125), so the implicit ``docker_network: false`` flag and an
operator-supplied one must be reconciled before the command line is built.Ú Ú=N)r,   r&   Ú	enumerateÚ_NETWORK_FLAGSÚlenrs   rk   )rû   rÿ   ÚargsÚiÚargÚflags   &     r(   Ú_extra_args_network_moder  r  s¢   € ð
 #×(Ð( bÐ(Ó@Ñ(�!¬Z¸¼3×-?�AˆAÑ(€DÐ@Ü˜D–/‰ˆß"ˆDØŒ{Ø&'¨!¥e¬c°$«iÔ&7�t �E–{¸RÔ?Ø�~‰~   a˜j×)Ô)Ø—y‘y  aÓ(¨Õ+Ô+ó	 #ñ "ñ ùò As
   �C ¬C z--security-optzno-new-privilegesFc          	      ó^   € V ^8„  d   QhR\         R\         R\         R\        \        ,          /# )r!   Úrun_as_host_userÚrun_execÚsnap_compatr#   ©rA   r%   r&   )r'   s   "r(   r)   r)   –  s6   € ÷ Iñ I¬4ð I¼4ð IÔVZð IÔgkÔloÕgpñ Ir*   c                óä   € \        \        4      V'       d   . M\        \        4      ,           pT\        V'       d   \        M\        4      ,          pV '       d   V# V\        \
        4      ,           # )a  Security/cap/tmpfs args for the privilege mode; ``run_exec`` mounts /run exec for s6 images.
``snap_compat`` drops no-new-privileges: snap-packaged Docker's AppArmor profile turns it into
"exec: operation not permitted" for every process in the container (#9730, LP#1908448).)r%   Ú_BASE_SECURITY_ARGSÚ_NO_NEW_PRIVILEGES_ARGSÚ_RUN_TMPFS_EXECÚ_RUN_TMPFS_NOEXECÚ_PRIVDROP_CAP_ARGS)r  r  r  r
  s   &&& r(   Ú_build_security_argsr  –  sJ   € ô Ô#Ó$¯k©¼tÔD[Ó?\Õ]€DØŒD§H•Ô2CÓDÕD€Dß#ˆ4ÐH¨´Ô5GÓ0HÕ)HÐHr*   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r!   rŽ   r|   r#   rf   )r'   s   "r(   r)   r)   Ÿ  s!   € ÷ >ñ >¬Cð >¼ð >Äñ >r*   c           	     óî  € \        V RRVRR.^RV3R\        P                  \        3R7      pVe%   VP                  ;'       g    RP                  4       MRpV'       d   VR	8X  d   R
#  \        P                  ! V4      p\        T\        4      '       d   T.p\        T\        4      '       d	   T'       g   R
# \        T^ ,          4      P                  4       \        9   #   \        \        3 d     R
# i ; i)záTrue if ``image``'s entrypoint is the s6-overlay ``/init`` (own PID 1: incompatible
with ``--init`` and a noexec /run). Any inspection failure, including an image not yet
pulled, returns False and keeps the hardened defaults.r|   rÁ   r–   z{{json .Config.Entrypoint}}z/Docker: could not inspect entrypoint for %s: %sz4Docker: image inspect for %s returned %d (stderr=%s))r˜   r™   r¥   rš   rÔ   r  ÚnullF)r©   Ú
subprocessÚSubprocessErrorru   r­   r/   r†   ÚloadsrË   Ú	TypeErrorr,   r&   r%   Ú_S6_INIT_ENTRYPOINTS)rŽ   r|   r¼   rÌ   Ú
entrypoints   &&   r(   Ú_image_uses_init_entrypointr$  Ÿ  sÚ   € ô Ø	�W˜i¨°
Ð<YÐZÐdfØ>È5È(ØFÜ×-Ñ-¬wÐ7ô	9€Fð
 ,2Ò+=ˆ6�=‰=×Ð˜B×
%Ñ
%Ô
'À2€Cß�#˜”-ÙðÜ—Z’Z “_ˆ
ô �*œc×"Ò"Ø �\ˆ
Ü�j¤$×'Ò'¯zÙÜˆz˜!�}Ó×#Ñ#Ó%Ô)=Ñ=Ð=øô œ	Ð"ô Úðús   Á)C ÃC4Ã3C4c                ó:   € V ^8„  d   QhR\         \        ,          /# rN   rÛ   )r'   s   "r(   r)   r)   ¶  s   € ÷ 
ñ 
¤¬#¥ñ 
r*   c                 ó¢   € \        \        RR4      p \        \        RR4      pV e   Vf   R#  V ! 4        RV! 4        2#   \         d     R# i ; i)zª``<uid>:<gid>`` of the host user, or ``None`` without POSIX ids. Uses os.getuid/getgid
directly (not pwd/getpass) so nameless UIDs inside sandboxed launchers never raise.ÚgetuidNÚgetgidrh   )Úgetattrrl   rT   )Úget_uidÚget_gids     r(   Ú_resolve_host_user_specr,  ¶  sX   € ô ”b˜( DÓ)€GÜ”b˜( DÓ)€GØ‚˜'š/ÙðÙ“)�˜A™g›i˜[Ð)Ð)øÜô Úðús   ®? ¿AÁAc                ó0   € V ^8„  d   QhR\         R\        /# )r!   r|   r#   rf   )r'   s   "r(   r)   r)   Ç  s   € ÷ *ñ *¤Cð *¬Dñ *r*   c                ó  € \         e   \         # \        4       pV'       d	   V '       g   R#  \        VRRRRRRR	R
V RR.^<R7      pTP                  ^ 8X  d   Rs R# TP                  ;'       g    RP                  4       pRTP                  4       9  d+   \        P                  RTP                  TR,          4       R# Rs \        P                  RTR,          4       R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)a  Probe once per process whether ``--cpus``/``--memory``/``--pids-limit`` work here, via a
throwaway ``sleep 0`` container from *image* (no extra pull). Without delegated cgroup
controllers (unprivileged LXCs, rootless) these flags fail every start with exit 126;
the result is host-wide, so it is cached. Only DEFINITIVE answers are cached: a probe
that could not run (auto-pull past the timeout, daemon cold-start, manifest/pull error)
says nothing about cgroup support, so it degrades this spawn and is retried on the next.NFÚrunz--rmú--cpusz0.5ú--memoryÚ64mú--pids-limitÚ32ÚsleepÚ0rÙ   zbCgroup limit probe failed; containers run without CPU/memory/PID limits until a probe succeeds: %sTr  Úcgroupz‹Cgroup limit probe could not determine support (docker exited %d: %s). Containers run without CPU/memory/PID limits until a probe succeeds.:Niô  NzóCgroup resource limits (--cpus/--memory/--pids-limit) not available in this environment. Containers will run without CPU, memory or PID limits. To enable, delegate the cpu, memory and pids cgroup controllers to this container. Probe stderr: %s)
Ú_cgroup_limits_okr§   r   rT   r-   r.   r²   rµ   r/   rñ   )r|   rŽ   r¼   rÍ   rµ   s   &    r(   Ú_cgroup_limits_availabler9  Ç  s	  € ô Ò$Ü Ð ä“€JßŸUÙðÜØ˜ ¨°%¸ÀUÈNÐ\`Ø�G˜Sð"àôˆð ×Ñ˜AÔØ ÐÙØ�m‰m×!Ð!˜r×(Ñ(Ó*€FØ�v—|‘|“~Ô%ä�‰ðSà×Ñ˜v d�|ô	-ñ ØÐÜ
‡N�Nð	Qð 	ˆt�ôñ øô- ô Ü�‰ð JØKLô	Nåûðús   ¬C ÃD
Ã)DÄD
Úexc_infoc                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r!   Úlog_msgÚerrorÚhintr:  rf   )r'   s   "r(   r)   r)   ô  s)   € ÷ >ñ >¤ð >¼ð >Ä3ð >ÔRVñ >r*   c                óN   € \         P                  ! V .VO5R V/  \        WR7      # )r:  )Ú
retry_hint)r-   r=  r   )r<  r=  r>  r:  Úlog_argss   &$$$*r(   Ú_docker_unavailablerB  ô  s#   € Ü
‡L‚L�Ð7˜8Ò7¨hÒ7Ü% eÔ=Ð=r*   c                ó   € V ^8„  d   QhRR/# ©r!   r#   N© )r'   s   "r(   r)   r)   ù  s   € ÷ "Gñ "G $ñ "Gr*   c            	     ó¶  € \        4       p V '       g   \        RRRR7      h \        V R.^R7      pTP                  ^ 8w  d3   \        RYP                  TP                  P                  4       RRR7      hR#   \         d    \        RT RR	R
R7      h\        P
                   d    \        RT RRRR7      h\         d    \        P                  RRR7       h i ; i)zXFail fast with an ``EnvironmentConnectionError`` when the docker CLI/daemon is unusable.z–Docker backend selected but no docker executable was found in PATH or known install locations. Install Docker Desktop and ensure the CLI is available.z|Docker executable not found in PATH or known install locations. Install Docker and ensure the 'docker' command is available.zZInstall Docker (or fix PATH) and retry, or run `hermes setup terminal` to switch to Local.)r=  r>  ÚversionrÙ   zVDocker backend selected but the resolved docker executable '%s' could not be executed.TzHDocker executable could not be executed. Check your Docker installation.z)Repair the Docker installation and retry.)r:  r=  r>  zYDocker backend selected but '%s version' timed out. The Docker daemon may not be running.zHDocker daemon is not responding. Ensure Docker is running and try again.uˆ   Start Docker (e.g. `systemctl start docker` or launch Docker Desktop), then retry â€” or run `hermes setup terminal` to switch to Local.z4Unexpected error while checking Docker availability.)r:  zIDocker backend selected but '%s version' failed (exit code %d, stderr=%s)zXDocker command is available but 'docker version' failed. Check your Docker installation.uu   Start Docker, or add your user to the docker group, then retry â€” or run `hermes setup terminal` to switch to Local.N)r§   rB  r   ÚFileNotFoundErrorr  ÚTimeoutExpiredrT   r-   r=  r²   rµ   r/   )rŽ   r¼   s     r(   Ú_ensure_docker_availablerJ  ù  s  € ä“€JßÜ!ðbðQàmôoð 	oðÜ˜j¨)Ð4¸aÔ@ˆð" ×Ñ˜AÔÜ!ØWØ×)Ñ)¨6¯=©=×+>Ñ+>Ó+@ØlðFô	Gð 	Gñ øô! ô >Ü!ØdØ Ø\Ø<ô	>ð 	>ô
 ×$Ñ$ô GÜ!ØgØ Ø\ðFô	Gð 	Gô ô Ü�‰ÐKÐVZˆÔ[Øðús   ¢A6 Á6-CÂ$CÂ>Cc                ó:   € V ^8„  d   QhR\         \        ,          /# rN   r$   )r'   s   "r(   r)   r)     s   € ÷ Añ A¤$¤s¥)ñ Ar*   c                ó\   € \        V 4       UUu. uF  pRV3 F  q"NK  	  K  	  upp# u uppi )z£``-e KEY`` flags (no values): the docker CLI resolves values from its own env,
so secrets live in owner-readable /proc/*/environ instead of world-readable cmdline.z-e)Úsorted)Únamesr5   r  s   &  r(   Ú_name_only_env_argsrO    s,   € ô " %œ=Ô@™=�C°T¸3³K¨SŠC±K‰C™=Ò@Ð@ùÓ@s   �(c                ó:   € V ^8„  d   QhR\         \        ,          /# rN   r$   )r'   s   "r(   r)   r)   +  s   € ÷ ñ ¤D¬¥Iñ r*   c            	     óš  € . p  ^ RI Hp \         EF  w  r#p\        W4      ! 4        Fì  p\	        VR,          4      pV'       d4   VP                  4       '       d   RMVP                  4       '       d   RMRpMVP                  4       '       d   RMRpV'       d/   \        P                  RVP                  4       ^ ,          Wv4       K   V P                  RVR,           RVR	,           R
2.4       \        P                  RWER,          VR	,          4       Kî  	  EK
  	  V #   \         d"   p\        P                  RT4        Rp?T # Rp?ii ; i)a1  ``-v host:container:ro`` args for credential files, skill dirs and cache dirs. Read-only so the
container can authenticate/read but never modify host state. Missing or wrong-kind sources are
skipped with a warning (Docker-in-Docker auto-creates a missing file source as a directory,
which would exit 125).NÚ	host_pathz=source is a directory (likely Docker-in-Docker auto-creation)zsource not foundzsource is not a directoryu$   Docker: skipping %s mount â€” %s: %sri   rh   Úcontainer_pathz:rozDocker: mounting %s %s -> %sz1Docker: could not load credential file mounts: %s)Útools.credential_filesÚcredential_filesÚ_RO_MOUNT_SOURCESr)  r   Úis_dirÚis_filer-   r.   rk   r¨   r³   rT   r´   )	r
  ÚcfÚgetterÚexpects_fileÚnounÚentryÚsrcÚproblemrÍ   s	            r(   Ú_readonly_skill_mount_argsr`  +  s!  € ð
 €DðMÝ+ß*;Ð*;Ñ&ˆF $Ü  Ô,Ö.�Ü˜5 Õ-Ó.�ßØbe×blÑbl×bnÒbnÑ^Ø,/¯K©K¯MªM¡DÐ?Qñ ð '*§j¡j§l¢l™dÐ8S�GßÜ—N‘NÐ#IÈ4Ï:É:Ë<ÐXYÍ?Ð\cÔiÙØ—‘˜T e¨KÕ&8Ð%9¸¸5ÐAQÕ;RÐ:SÐSVÐ#WÐXÔYÜ—‘Ð:¸DÈÕBTÐV[Ð\lÕVmÖnô /ñ +<ð €Køô ô MÜ�‰ÐHÈ!×LÐLØ€KûðMús1   „AD ÁD Á2D ÂD ÂBD ÄE
Ä)EÅE
c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r!   r  r#   r  )r'   s   "r(   r)   r)   E  s   € ÷ ñ ¤dð ¬t´C­yñ r*   c                ó”   € V '       g   . # \        4       pVe   \        P                  RV4       RV.# \        P                  R4       . # )uµ   ``--user uid:gid`` so bind-mount writes are owned by the host user, not root. Without
POSIX ids fall back to the full cap set â€” the image's init may still need to drop privileges.z)Docker: running container as host user %sz--userzƒdocker_run_as_host_user is enabled but this platform does not expose POSIX uid/gid; container will start as its image default user.)r,  r-   r³   r.   )r  Ú	user_specs   & r(   Ú_host_user_argsrd  E  sN   € ÷ Øˆ	Ü'Ó)€IØÒÜ�‰Ð?ÀÔKØ˜)Ð$Ð$Ü
‡N�Nð	TôUð €Ir*   z/^(?P<host>.+):(?P<container>/[^:]+)(?::[^:]*)?$c                ó`   € V ^8„  d   QhR\         R\        \         \         3,          R,          /# )r!   re   r#   N)r&   r×   )r'   s   "r(   r)   r)   Y  s'   € ÷ 9ñ 9œSð 9¤U¬3´¨8¥_°tÕ%;ñ 9r*   c                óÐ   € \        V \        4      '       g   R# \        P                  V P	                  4       4      pV'       g   R# VP                  R4      VP                  R4      3# )uY   ``host:container[:mode]`` â†’ ``(host, container)``. Drive-letter hosts keep their colon.NÚhostÚ	container)r,   r&   Ú_VOLUME_SPEC_REr1   r/   Úgroup)re   r1   s   & r(   rj   rj   Y  sK   € ä�dœC× Ò ÙÜ×!Ñ! $§*¡*£,Ó/€EßÙØ�;‰;�vÓ §¡¨KÓ 8Ð8Ð8r*   c                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# )r!   Úvolume_argsÚmountr#   )r%   r&   rA   )r'   s   "r(   r)   r)   c  s%   € ÷ ñ ¬¬S­	ð ¼#ð Ä$ñ r*   c                 óÌ   € VP                  R 4      ;'       g    R pV  FB  p\        V4      pV'       g   K  V^,          P                  R 4      ;'       g    R V8X  g   KA   R# 	  R# )Ú/TF)Úrstriprj   )rl  rm  Útargetr  rv   s   &&   r(   Ú_container_mount_takenrr  c  sW   € Ø�\‰\˜#Ó×%Ð% #€FÛˆÜ# CÓ(ˆß‰6�v˜a•y×'Ñ'¨Ó,×3Ð3°¸Ö>Úñ ñ r*   c                ó`   € V ^8„  d   QhR\         \        ,          R\        R\        R,          /# )r!   rl  Úhost_cwd_absr#   Nr$   )r'   s   "r(   r)   r)   l  s)   € ÷ 	ñ 	¤d¬3¥ið 	¼sð 	ÄsÈTÅzñ 	r*   c                ó°   € \        V4      pV'       g   R# V  F:  p\        V4      pV'       g   K  \        V^ ,          4      V8X  g   K1  V^,          u # 	  R# )zHContainer path if a user volume already bind-mounts this host directory.N)r	   rj   )rl  rt  Úwantr  rv   s   &&   r(   Ú_existing_host_mountrw  l  sJ   € ä˜,Ó'€DßÙÛˆÜ# CÓ(ˆß‰6”n V¨A¥YÓ/°4Ö7Ø˜!•9Òñ ñ r*   c                óF   € V ^8„  d   QhR\         \        ,          R\        /# )r!   rl  r#   r$   )r'   s   "r(   r)   r)   x  s   € ÷ )ñ )¤d¬3¥ið )´Cñ )r*   c                 ó`   € \          F  p\        W4      '       d   K  Vu # 	  \         R,          # )é   éÿÿÿÿ)Ú_HOST_CWD_FALLBACK_MOUNTSrr  )rl  Ú	candidates   & r(   Ú_free_host_cwd_mountr~  x  s*   € ß.ˆ	Ü% k×=Ô=ØÒñ /ô % RÕ(Ð(r*   c                ó0   € V ^8„  d   QhR\         R\         /# )r!   Úhost_cwdr#   rE   )r'   s   "r(   r)   r)     s   € ÷ %ñ %œCð %¤Cñ %r*   c                óÎ   € \         P                  P                  V 4      p\        V4      '       d   \         P                  R8w  d   V# \         P                  P                  V4      # )zTAbsolute host path. A Windows drive path is not prefixed with the POSIX process cwd.Únt)rl   rm   rr   r
   Únamerq   )r€  Úexpandeds   & r(   Ú_abs_host_cwdr…    sC   € ä�w‰w×!Ñ! (Ó+€HÜ˜h×'Ò'¬B¯G©G°t¬OØˆÜ�7‰7�?‰?˜8Ó$Ð$r*   c                   óž  a a€ ] tR tRt oRtRtRtV3R lR ltR^<^ ^ ^ RRR	R	R	RR	RRR	R]R
RR3V3R lV 3R lllt	V3R lR lt
V3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR  ltV3R! lR" ltV3R# lR$ ltR%RR&^xR'R	/V3R( lR) lltRFtV3R* lR+ ltV3R, lR- ltRGV3R. lV 3R/ lllt]V3R0 lR1 l4       tV3R2 lR3 ltV3R4 lR5 ltV3R6 lR7 ltV3R8 lR9 lt R:R/V3R; lR< llt!V3R= lR> lt"V3R? lR@ lt#]RHV3RA lRB ll4       t$RIV3RC lRD llt%REt&Vt'V ;t(# )JÚDockerEnvironmenti‡  uý   Hardened Docker container execution (caps dropped, no-new-privileges, PID limits,
size-limited tmpfs). The container is the security boundary â€” its filesystem stays
writable so agents can install packages. Persistence bind-mounts /workspace and /root.Tc                ó4   <€ V ^8„  d   QhRS[ S[R3,          /# ©r!   r#   .)r×   r&   )r'   Ú__classdict__s   "€r(   r)   ÚDockerEnvironment.__annotate__�  s   ø€ ÷ (ñ (¹eÁCÈÀH½oñ (r*   c                ó,   € \        V P                  4      # )z@Keep explicit docker_forward_env values out of shared snapshots.)r×   Ú_forward_env©Úselfs   &r(   Ú,_additional_profile_scoped_passthrough_namesÚ>DockerEnvironment._additional_profile_scoped_passthrough_names�  s   € ä�T×&Ñ&Ó'Ð'r*   ú/rootFrR   Nr  c          *      óð   <€ V ^8„  d   QhRS[ RS[ RS[RS[RS[RS[RS[RS[ R	S[R
,          RS[S[ ,          R
,          RS[R
,          RS[RS[S[ ,          RS[RS[RS[R
,          RS[RS[ RS[ RS[RS[/# )r!   r|   Úcwdr˜   ÚcpuÚmemoryÚdiskÚpersistent_filesystemÚtask_idÚvolumesNr"   r8   Únetworkr€  Úauto_mount_cwdr  rû   Úpersist_across_processesÚshm_sizeÚshared_container_keyr  Úimage_pinned)r&   r?   r@   rA   r%   r:   r   )r'   rŠ  s   "€r(   r)   r‹  “  s  ø€ ÷ ñ áðñ ðñ ð	ñ
 ðñ ðñ ðñ  $ðñ ðñ ˜•ðñ ™#•Y Õ%ðñ �D�[ðñ ðñ ™3•-ðñ ðñ  ð!ñ" ˜4•Kð#ñ$ #'ð%ñ& ð'ñ( "ð)ñ* ð+ñ, ñ-r*   c           	     óî  <€ VR 8X  d   Rp\         S'V `  W#R7       Wpn        VV n        RV n        W€n        \        V
4      V n        \        V4      V n	        RV n
        RV n        / V n        RV n        RV n        . V n        \         P#                  RV	4       V	e/   \%        V	\&        4      '       g   \         P)                  RV	4       . p	\+        4        V P-                  WWVVVV4      pV P/                  W�Wè4      w  pp\1        V RR4      pV'       d3   \3        VV4      '       d!   \         P#                  RVV4       TpVV n        VP7                  \9        4       4       V P;                  V4      w  pppppVP7                  V4       \=        V4      p\?        4       ;'       g    R	V n         \C        V P@                  V4      p V '       d   \         P#                  R
V4       \E        T;'       d    \G        V4      V VR7      p!VV n$        V'       d   \         P)                  R4       \         P#                  RV4       V!V,           V,           V,           V,           V,           V,           V,           p"\         P#                  RV"4       \K        V4      p#\M        V4      p$RRRV$RV#\N        V/V n(        \R        PU                  T;'       g    R4      ;p%'       d#   V%PW                  ^4      V PP                  \X        &   V'       g5   \[        V. VOVO\]        \_        4       4      R7      V PP                  \`        &   Wn1        VV n2        V V n3        V"V n4        T;'       d    V Pk                  V$V#VV4      p&V&'       g   V Pm                  V4      V n        M \o        V P@                  V P                  4       \q        V P@                  V P                  V P                  4       V Ps                  4       V n:        V Pw                  4        R# )Ú~r’  )r”  r˜   FNzDockerEnvironment volumes: %sz'docker_volumes config is not a list: %rÚhost_cwd_mountzDContainer cwd follows configured host workspace at %s (requested %s)r‘   ug   Docker: image %s uses /init (s6-overlay) as entrypoint â€” skipping --init and mounting /run with exec.)r  r  z]docker_snap_compat: running without --init and no-new-privileges (snap Docker under AppArmor)zDocker volume_args: %szDocker run_args: %szhermes-agentÚ1úhermes-task-idúhermes-profiler  )r|   r}   r~   rE  )<ÚsuperÚ__init__Ú_persistentÚ_persist_across_processesÚ_session_scopedÚ_task_idr6   r�  rC   Ú_envÚ_init_unset_passthrough_namesÚ_container_idÚ_init_env_valuesÚ_workspace_dirÚ	_home_dirÚ_sandbox_mountsr-   r³   r,   r%   r.   rJ  Ú_resource_argsÚ_mount_argsr)  r   r”  r¨   r`  Ú_egress_and_env_argsrd  r§   Ú_docker_exer$  r  rA   Ú_snap_compatrc   rL   r   Ú_labelsÚ_WORKSPACE_TASK_REÚsearchrj  rÃ   r‹   r&   r   Ú_ENVIRONMENT_LABEL_KEYÚ_imageÚ_image_pinnedÚ_image_uses_s6_initÚ_all_run_argsÚ_attach_existing_containerÚ_docker_runr   r   Ú_build_init_env_argsÚ_init_env_argsÚinit_session)(r�  r|   r”  r˜   r•  r–  r—  r˜  r™  rš  r"   r8   r›  r€  rœ  r  rû   r�  rž  rŸ  r  r   Úresource_argsrl  Úwritable_argsrm  Úegress_labelÚegress_volume_argsÚegress_host_argsÚenv_argsÚvalidated_extraÚ	user_argsÚimage_uses_s6_initÚsecurity_argsÚall_run_argsÚprofile_nameÚ
task_labelÚ	workspaceÚreusedÚ	__class__s(   &&&&&&&&&&&&&&&&&&&&&&                 €r(   r¨  ÚDockerEnvironment.__init__“  s¢  ø€ ð. �#Œ:ØˆCÜ‰Ñ˜SÐÔ2Ø0ÔØ)AˆÔ&ð  %ˆÔØŒÜ8¸ÓEˆÔÜ'¨Ó,ˆŒ	Ø>@ˆÔ*Ø,0ˆÔØ02ˆÔØ-1ˆÔØ(,ˆŒà68ˆÔÜ�‰Ð3°WÔ=ØÒ¤z°'¼4×'@Ò'@Ü�N‰NÐDÀgÔNØˆGä Ô"à×+Ñ+¨E¸ÀgÈxÐYcÓdˆØ%)×%5Ñ%5°gÈÓ%aÑ"ˆ�]Ü˜Ð.°Ó5ˆßÔ+¨C°×7Ò7Ü�K‰KØVØ�sôð ˆCØˆDŒHØ×ÑÔ5Ó7Ô8à×%Ñ% jÓ1ñ 	VˆÐ(Ð*:¸HÀoà×ÑÐ-Ô.Ü#Ð$4Ó5ˆ	ô '›=×4Ð4¨HˆÔô 9¸×9IÑ9IÈ5ÓQÐßÜ�K‰Kð?àôô -Ø×0Ð0¤ i£Ð;MÐ[fôhˆà'ˆÔßÜ�N‰NØoôqô 	�‰Ð,¨kÔ:ð ˜IÕ%¨Õ5¸ÕEØõØ!,õ-Ø/7õ8Ø:IõJð 	ô 	�‰Ð)¨<Ô8ô +Ð+?Ó@ˆÜ*¨7Ó3ˆ
à˜CØ˜jØ˜lÜ˜|ð	-ˆŒô
 +×1Ñ1°'·-°-¸RÓ@Ð@ˆ9Ö@Ø1:·±ÀÓ1CˆD�L‰LÔ-Ñ.÷ $Ü3QØÐ(F¨-Ð(F¸+Ð(FÜ¤Ó 1Ó2ô44ˆD�L‰LÔ/Ñ0ð ŒØ)ˆÔØ#5ˆÔ Ø)ˆÔà)÷ =ð =¨d×.MÑ.MØ˜ l°Gó/=ˆçØ!%×!1Ñ!1°#Ó!6ˆDÕä$ T×%5Ñ%5°t×7IÑ7IÔJÜ˜d×.Ñ.°×0BÑ0BÀD×DXÑDXÔYð #×7Ñ7Ó9ˆÔØ×ÑÖr*   c                ó‚   <€ V ^8„  d   QhRS[ S[S[S[,          S[S[,          S[S[,          S[S[,          3,          /# rN   )r×   r&   r%   )r'   rŠ  s   "€r(   r)   r‹    s=   ø€ ÷ tñ t±%¹¹TÁ#½YÉÉSÍ	ÑSWÑX[ÕS\Ñ^bÑcfÕ^gÐ8gÕ2hñ tr*   c                ó  € \        4       w  r#p\        W#V4      pV'       d   \        4       MRp\        V4      pV'       d-   \	        V P
                  Wv4       \        V P                  W64       \        V P                  W64      p\        V4      V n
        . p	T;'       g    .  FB  p
\        V
\        4      '       g   \        P                  RV
4       K1  V	P                  V
4       KD  	  V'       d   \!        W—V4       WRV\#        V4      V	3# )a  Egress credential-injection proxy plumbing (CA mount + HTTPS_PROXY/CA-bundle env so
outbound traffic routes through the host-side proxy and the sandbox receives proxy tokens
instead of real API keys), merged with docker_env into name-only ``-e`` args, plus the
validated docker_extra_args. Returns ``(egress_label, volume_args, host_args, env_args,
validated_extra)``; sets ``self._run_env_values`` (injected into the docker-client
subprocess env at run time and reused verbatim by container-recreation recovery).Tz/Ignoring non-string docker_extra_args entry: %r)r   r   r   r   r   r�  r   r­  r   r:   Ú_run_env_valuesr,   r&   r-   r.   r2   r   rO  )r�  rû   rÉ  Úegress_env_overridesrÊ  rÈ  Úenforce_egressÚcritical_egress_namesÚ
merged_envrÌ  r  s   &&         r(   r¶  Ú&DockerEnvironment._egress_and_env_args  sî   € ô FcÓEdÑBÐÐ2BÜ0Ð1CÐ[kÓlˆß8LÔ2Ô4ÐRVˆÜ :Ð;OÓ PÐßÜ(¨×):Ñ):Ð<QÔbÜ'¨¯	©	Ð3GÔXä% d§i¡iÐ1EÓVˆ
Ü# JÓ/ˆÔàˆØ×$Ð$ "Ò$ˆCÜ˜c¤3×'Ò'Ü—‘ÐPÐRUÔVÙØ×"Ñ" 3Ö'ñ	 %÷
  Ü'¨ÐP^Ô_ØÐ1AÔCVÐWaÓCbÐdsÐsÐsr*   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# rN   r$   )r'   rŠ  s   "€r(   r)   r‹  1  s   ø€ ÷ "ñ "ÑY]Ñ^aÕYbñ "r*   c                óÆ  € . p\        V4      '       dX   V^ 8”  d   VP                  R\        V4      .4       V^ 8”  d   VP                  RV R2.4       VP                  R\        .4       \        T;'       g    R4      P	                  4       p	V	'       d,   V	R8w  d%   \        V4      '       g   VP                  RV	.4       V^ 8”  dY   \        P                  R8w  dD   V P                  4       '       d   VP                  R	R
V R2.4       M\        P                  R4       V'       g:   \        V4      p
V
f   VP                  R4       V# V
R8w  d   \        RV
: R24      hV# )zKcgroup-gated CPU/memory/pids limits, shm size, disk quota and network mode.r0  r1  Úmr3  r  r6  rþ   Údarwinú--storage-optzsize=z�Docker storage driver does not support per-container disk limits (requires overlay2 on XFS with pquota). Container will run without disk quota.z--network=noneÚnonez`terminal.docker_network is false (air-gapped) but terminal.docker_extra_args requests --network=zj. Remove the --network entry from docker_extra_args, or set docker_network: true to opt into that network.)r9  r¨   r&   Ú_DEFAULT_PIDS_LIMITr/   r  ÚsysÚplatformÚ_storage_opt_supportedr-   r.   r  r2   ÚRuntimeError)r�  r|   r•  r–  r—  r›  rž  rû   r
  ÚshmÚextra_networks   &&&&&&&&   r(   r´  Ú DockerEnvironment._resource_args1  sM  € àˆÜ# E×*Ò*Ø�QŒwØ—‘˜X¤s¨3£xÐ0Ô1Ø˜ŒzØ—‘˜Z¨F¨8°1¨Ð6Ô7Ø�K‰K˜Ô)<Ð=Ô>ô �(—.�.˜bÓ!×'Ñ'Ó)ˆß�3˜#”:Ô&>¸z×&JÒ&JØ�K‰K˜ sÐ+Ô,Ø�!Œ8œŸ™¨Ô0Ø×*Ñ*×,Ò,Ø—‘˜_°°d°V¸1¨oÐ>Õ?ä—‘ðeôf÷ Ü4°ZÓ@ˆMØÒ$Ø—‘Ð,Ô-ð ˆð  &Ô(ô #ð*Ø*7Ñ):ð ;_ð`óað að
 ˆr*   c                óV   <€ V ^8„  d   QhRS[ S[S[,          S[S[,          3,          /# rN   )r×   r%   r&   )r'   rŠ  s   "€r(   r)   r‹  U  s-   ø€ ÷ L*ñ L*ÉÉtÑTWÍyÑZ^Ñ_bÕZcÐOcÕIdñ L*r*   c                ó  € . pT;'       g    .  F}  p\        V\        4      '       g   \        P                  RV4       K1  VP	                  4       pV'       g   KK  RV9  d   \        P                  RV4       Kj  VP                  RV.4       K  	  \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      pV'       d   \        V4      MRp\        T;'       g    R4      ;'       g    \        V4      p	\        V4      ;'       d     \        P                  P                  V4      p
T
;'       d    T;'       g    T	pV'       g	   V	'       d'   V'       d   V
'       g   \        P                  R	V4       V'       d   \        WX4      MR
pV'       d   W€n        WÀn        R
pM:V'       d#   V'       g   RM
\#        V4      pW€n        WÐn        MR
V n        R
V n        R
pVR8H  pV'       * ;'       d    V'       * p. pV P$                  '       dþ   \'        4       R,          \)        V4      ,          p\        VR,          4      V n        \        P,                  ! V P*                  RR7       V P*                  R3.V n        V'       da   \        VR,          4      V n        \        P,                  ! V P0                  RR7       V P.                  P3                  V P0                  R34       V P.                   F  w  ppVRV RV 2.,          pK  	  M TV'       d   RR.M. ,          pV. RO,          pV'       d&   \        P5                  RWØ4       RV RV 2.VOpVV3# V'       d   V'       g   \        P                  R4       VV3# )uP  ``(volume_args, writable_args)`` for user volumes, host cwd and /workspace,/root.

Persistent mode bind-mounts from TERMINAL_SANDBOX_DIR (default ~/.hermes/sandboxes/).
A configured host working directory is bound even when another volume already
claims ``/workspace``: at ``/workspace`` when that path is free, otherwise at
a second mount. ``host_cwd`` / ``host_cwd_mount`` tell tools which container
path is that directory. A Windows drive path is bound whenever it exists on
the host â€” it can never be a path inside the Linux container, and the check
is the drive shape, not a username.
z'Docker volume entry is not a string: %rrh   z*Docker volume '%s' missing colon, skippingri   c              3   ó,   "  € T F
  pR V9   x € K  	  R# 5i)z:/workspaceNrE  )rŸ   Úvs   & r(   r¡   Ú0DockerEnvironment._mount_args.<locals>.<genexpr>l  s   é € Ð*SÁ{À!¨=¸AÖ+=Ã{ùs   ‚TFr  z@Skipping docker cwd mount: host_cwd is not a valid directory: %sNz
/workspacer‘   Úhome)Úexist_okr’  rÓ  ú--tmpfsz/workspace:rw,exec,size=10gz&Mounting configured host cwd to %s: %szDSkipping docker cwd mount: /workspace already mounted by user config)rô  z/home:rw,exec,size=1grô  z/root:rw,exec,size=1g)r,   r&   r-   r.   r/   r¨   r  r…  r
   rA   rl   rm   Úisdirr´   rw  r€  r£  r~  r©  r   Ú_sandbox_dir_namer²  Úmakedirsr³  r±  r2   r³   )r�  rš  r€  rœ  r™  rl  ÚvolÚworkspace_explicitly_mountedrt  Úwindows_cwdÚhost_dir_existsÚshould_bindÚexisting_mountÚbind_targetÚbind_at_workspaceÚmount_workspacerÇ  ÚsandboxÚhost_dirrS  s   &&&&&               r(   rµ  ÚDockerEnvironment._mount_argsU  sâ  € ð "$ˆØ—M�M˜r’MˆCÜ˜c¤3×'Ò'Ü—‘ÐHÈ#ÔNÙØ—)‘)“+ˆCßÙØ˜#Œ~Ü—‘ÐKÈSÔQÙØ×Ñ  c˜{Ö+ñ "÷ (+£sÑ*SÁ{Ó*S§s§s¢sÑ*SÁ{Ó*SÓ'SÐ$ç2:”} XÔ.ÀˆÜ,¨X¯^¨^¸Ó<×dÐdÔ@VÐWcÓ@dˆÜ˜|Ó,×LÐL´·±·±¸|Ó1LˆØ%×IÐI¨>×+HÐ+H¸[ˆßŸk¯xÇÜ�L‰LÐ[Ð]eÔfçLWÔ-¨kÔHÐ]aˆßð )ŒMØ"0ÔØ‰Kßç$@‘Ü)¨+Ó6ð ð )ŒMØ"-Õà ˆDŒMØ"&ˆDÔØˆKà'¨<Ñ7ÐØ/Ô/×TÐTÐ8TÔ4Tˆà#%ˆØ××Ðô &Ó'¨(Õ2Ô5FÀwÓ5OÕOˆGÜ  ¨6Õ!1Ó2ˆDŒNÜ�KŠK˜Ÿ™°Õ6Ø%)§^¡^°WÐ$=Ð#>ˆDÔ ßÜ&)¨'°KÕ*?Ó&@�Ô#Ü—’˜D×/Ñ/¸$Õ?Ø×$Ñ$×+Ñ+¨T×-@Ñ-@À,Ð,OÔPØ,0×,@Ô,@Ñ(�˜.Ø $¨8¨*°A°nÐ5EÐ(FÐ!GÕG’ò -Að Ï?˜iÐ)FÑGÐ`bÕbˆMØÒeÕeˆMçÜ�K‰KÐ@À+Ô\Ø L >°°;°-Ð!@ÐOÀ;ÐOˆKð ˜MÐ)Ð)÷ *·.Ü�L‰LÐ_Ô`Ø˜MÐ)Ð)r*   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r!   r›  r#   ©rA   )r'   rŠ  s   "€r(   r)   r‹  £  s!   ø€ ÷ Fñ FÑZ^ð FÑcgñ Fr*   c           	     óÐ  € V P                  WV4      pVf   R# Vw  rgV P                  V4      pVeß   W€P                  8w  dÏ   V P                  '       g6   \        P                  RVR,          W€P                  V P                  W4       M‡V P                  4       '       g+   \        P                  RVR,          W€P                  W4       MG\        P                  RVR,          W€P                  W4        \        V P                  RRV.^R	7       R# V'       g`   V P                  V4      p
V
R8w  dH   \        P                  RVR,          T
;'       g    RW4        \        V P                  RRV.^R	7       R# VR8w  d6   V P                  V4      pVe!   \        P                  RVR,          W{4       R# W`n        \        P                  RVR,          WV4       R#   \        P                  \        3 d*   p	\        P                  R
TR,          T	4        Rp	?	R# Rp	?	ii ; i  \        P                  \        3 d*   p	\        P                  R
TR,          T	4        Rp	?	R# Rp	?	ii ; i)a‰  Attach to a prior process's labeled container ("ONE long-lived container shared
across sessions"; opt out via ``docker_persist_across_processes: false``).
Network guard is lockdown-only: a bridge container under ``docker_network: false``
is removed and recreated, but a ``none`` container under default config is kept so
``--network=none`` in extra args doesn't churn containers every startup.NFu  Existing container %s runs image %s; the default docker_image is now %s. Keeping the existing sandbox â€” approve the switch with `hermes config set terminal.docker_image %s` (files in /root and /workspace carry over) or pin the current image to stop this notice (task=%s, profile=%s).rZ   už   Existing container %s runs image %s; docker_image is %s but that image could not be pulled â€” keeping the current sandbox until it can (task=%s, profile=%s).ut   Existing container %s runs image %s but docker_image is %s â€” removing it and starting fresh (task=%s, profile=%s).r£   ú-frÙ   z,Failed to remove mismatched container %s: %srä  uœ   Existing container %s has NetworkMode=%s but docker_network=false requests an air-gapped container â€” removing it and starting fresh (task=%s, profile=%s).rG   Úrunningu[   Failed to start existing container %s (state=%s): %s â€” falling back to a fresh container.z:Reusing container %s (task=%s, profile=%s, prior state=%s)T)Ú_find_reusable_containerÚ_container_imager½  r¾  r-   r.   Ú_image_available_locallyr   r·  r  rI  ru   Ú_container_network_modeÚ_start_containerr¯  r³   )r�  rÒ  rÑ  rÈ  r›  Úexistingr¿   ÚstateÚactual_imagerÍ   Úactual_modeÚerrs   &&&&&       r(   rÁ  Ú,DockerEnvironment._attach_existing_container£  sG  € ð ×0Ñ0°È<ÓXˆØÒÙØ&Ñˆð ×,Ñ,¨\Ó:ˆØÒ#¨¿¹Ô(CØ×%×%Ð%Ü—‘ðOð ! Õ% |·[±[À$Ç+Á+Èzõið ×2Ñ2×4Ò4ô
 —‘ðaà  Õ% |·[±[À*õ\ô
 —‘ð<à  Õ% |·[±[À*ô\ðiÜ ×!1Ñ!1°4¸¸|Ð LÐVXÕYñ ßØ×6Ñ6°|ÓDˆKØ˜fÔ$Ü—‘ðZð ! Õ% {×'?Ð'?°iÀô	[ð
iÜ ×!1Ñ!1°4¸¸|Ð LÐVXÕYñ à�IÔØ×'Ñ'¨Ó5ˆCØŠÜ—‘ð@à  Õ% uô3ñ Ø)ÔÜ�‰ØHØ˜Õ˜z¸ô	@ñ øô; #×1Ñ1´7Ð;ô iÜ—N‘NÐ#QÐS_Ð`cÕSdÐfg×hÐhÙûðiûô #×1Ñ1´7Ð;ô iÜ—N‘NÐ#QÐS_Ð`cÕSdÐfg×hÐhÙûðiús0   Ã3G ÅH! ÇHÇ5HÈHÈ!I%È<I É I%c                ó    <€ V ^8„  d   QhRS[ /# rN   r  )r'   rŠ  s   "€r(   r)   r‹  ë  s   ø€ ÷ ñ ©$ñ r*   c                ór  €  \        V P                  RRV P                  RR.^R7      pVP                  ^ 8X  d   R# \        V P                  RV P                  .RR7      pVP                  ^ 8H  #   \        P
                  \        3 d-   p\        P                  R	T P                  T4        R
p?R# R
p?ii ; i)z¾True once ``self._image`` is in the local image store, pulling it when it is not. Called BEFORE a
container replacement removes anything: a pull that fails must leave the old sandbox intact.r|   rÁ   r–   z{{.Id}}rÙ   TÚpulli„  zDocker: could not pull %s: %sNF)	r   r·  r½  r²   r  r  ru   r-   r.   )r�  Úprober  rÍ   s   &   r(   r  Ú*DockerEnvironment._image_available_locallyë  s    € ð		Ü ×!1Ñ!1°7¸IÀtÇ{Á{ÐT^Ð`iÐ jØ(*ô,ˆEà×Ñ 1Ô$ÙÜ × 0Ñ 0°&¸$¿+¹+ÐFÐPSÔTˆDØ—?‘? aÑ'Ð'øÜ×*Ñ*¬GÐ4ô 	Ü�N‰NÐ:¸D¿K¹KÈÔKÝûð	ús   ‚8A/ ¼2A/ Á/B6Â
!B1Â1B6c                ó4   <€ V ^8„  d   QhRS[ RS[R,          /# )r!   r¿   r#   N)r&   rT   )r'   rŠ  s   "€r(   r)   r‹  ù  s    ø€ ÷ ñ ©Sð ±YÀÕ5Eñ r*   c                ó¦   €  \        V P                  RV.^RR7       R#   \        P                  \        P                  3 d   pTu Rp?# Rp?ii ; i)zM``docker start`` a stopped container; returns the failure instead of raising.ÚstartT)r˜   ÚcheckN)r   r·  r  ÚCalledProcessErrorrI  )r�  r¿   rÍ   s   && r(   r  Ú"DockerEnvironment._start_containerù  sJ   € ð	Ü˜×)Ñ)¨7°LÐAÈ2ÐUYÕZÙøÜ×-Ñ-¬z×/HÑ/HÐIô 	Ø�Hûð	ús   ‚ Ÿ%AÁAÁAÁAc                ó<   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          /# )r!   rƒ  Úworkdirr#   r   )r'   rŠ  s   "€r(   r)   r‹    s&   ø€ ÷ !ñ !¡ð !©sð !±t¹Cµyñ !r*   c           	     óH  € V P                   P                  4        UUUu. uF  w  r4RV RV 23 F  qUNK  	  K  	  ppppV P                  RR.V P                  '       g   V P                  '       d   . MR.ORNVNVORNVNV P
                  OV P                  NRNR	N# u upppi )
z«``docker run -d`` argv for a fresh ``sleep infinity`` container (idle reaper handles
lifetime). s6-overlay images already provide PID 1, so ``--init`` is skipped for them.z--labelr  r/  z-dz--initz--namez-wr5  Úinfinity)r¹  r>   r·  r¿  r¸  rÀ  r½  )r�  rƒ  r   Úkrð  r  Ú
label_argss   &&&    r(   Ú_run_commandÚDockerEnvironment._run_command  sî   € ð '+§l¡l×&8Ñ&8Ô&:Õ^Ñ&:™d˜aÀyÐUVÐTWÐWXÐYZÐX[ÐR\ÓF]¸s’cÑF]‘cÑ&:ˆ
Ò^ð
 ×Ñ˜e Tð	!ð
 ×,×,Ð,°×0A×0AÐ0A‰bÈÀzð!ð ð!ð ð!ð ð!ð ð!ð ð!ð ×Ñð!ð �K‰Kð!ð ð!ð  ð!ð 	!ùô _s   ŸBc                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r!   r”  r#   rE   )r'   rŠ  s   "€r(   r)   r‹    s   ø€ ÷ ñ ™sð ¡sñ r*   c           	     óz  € R\         P                  ! 4       P                  R,           2pV P                  W!4      p\        P                  RRP                  V4      4        \        V^xRV P                  V P                  4      R7      pTP"                  P%                  4       p\        P'                  RY&R,          4       T#   \        P                  \        P                  3 dT   p\        P                  RY%4       \        P                  ! T P                  RR	T.R^
\        P                   R
R7       h Rp?ii ; i)zÎStart a fresh container and return its id. A failed ``docker run`` (exit 125, timeout
mid-pull) can leave a "Created" orphan the exited-only reaper never catches, so it is
removed by name before re-raising.úhermes-ºNé   NzStarting container: %sÚ T©r˜   r  r8   z<docker run failed for %s, cleaning up orphaned container: %sr£   r  F©Úcapture_outputr˜   Ústdinr  NzStarted container %s (%s)rZ   )ÚuuidÚuuid4Úhexr%  r-   r´   Újoinr   Ú_docker_client_envrÙ  r  r  rI  r.   r/  r·  ÚDEVNULLr­   r/   r³   )r�  r”  Úcontainer_nameÚrun_cmdr¼   rÍ   r¿   s   &&     r(   rÂ  ÚDockerEnvironment._docker_run  s
  € ð #¤4§:¢:£<×#3Ñ#3°BÕ#7Ð"8Ð9ˆØ×#Ñ# NÓ8ˆÜ�‰Ð-¨s¯x©x¸Ó/@ÔAð		Ü Ø ¨DØ×+Ñ+¨D×,@Ñ,@ÓAôCˆFð —}‘}×*Ñ*Ó,ˆÜ�‰Ð/°ÈcÕARÔSØÐøô ×-Ñ-¬z×/HÑ/HÐIô 	Ü�N‰NÐYÐ[iÔmÜ�NŠNØ×!Ñ! 4¨¨~Ð>Ø#¨R´z×7IÑ7IÐQVõXð ûð	ús   Á!(C Ã%D:Ã'AD5Ä5D:c                ó`   <€ V ^8„  d   QhRS[ S[S[3,          RS[ S[S[3,          R,          /# )r!   Úvaluesr#   Nr9   )r'   rŠ  s   "€r(   r)   r‹  (  s0   ø€ ÷ 	'ñ 	'©©c±3¨h­ð 	'¹DÁÁcÀ½NÈTÕ<Qñ 	'r*   c                ó   € \        V4      # )að  Env for the docker-client subprocess carrying forwarded values (pairs with name-only
``-e KEY`` flags to keep secrets out of cmdline); ``None`` = inherit when empty.

Name-only ``-e KEY`` flags make the docker CLI read each value from its own process environment,
keeping secrets out of the client's world-readable ``/proc/<pid>/cmdline`` (issue #96268). Values
live in ``/proc/<pid>/environ`` instead, which is owner/root-only. Returns ``None`` (inherit as
before) when there is nothing to add.
)r   )r�  r;  s   &&r(   r5  Ú$DockerEnvironment._docker_client_env(  s   € ô ˜vÓ&Ð&r*   c                ó0   <€ V ^8„  d   QhRS[ S[,          /# rN   r$   )r'   rŠ  s   "€r(   r)   r‹  3  s   ø€ ÷ -ñ -¡d©3¥iñ -r*   c                óä   € V P                  4       w  r/ V P                  CVCpV F  pVP                  VR4       K  	  \        \	        V4      4      V n        \        V4      V n        \        V4      # )u]  Name-only ``-e`` args for init_session so ``export -p`` captures docker_env
plus the current profile's forwarded values (values travel via the client env).

The VALUES intentionally do not appear in the argv â€” they are passed via the docker client
subprocess env (see _docker_client_env and issue #96268); the flags here are name-only ``-e KEY``.
N)	Ú_resolve_passthrough_envr­  Úpopr×   rM  r®  r:   r°  rO  )r�  Úpassthrough_envÚunset_namesÚexec_envrƒ  s   &    r(   rÃ  Ú&DockerEnvironment._build_init_env_args3  si   € ð (,×'DÑ'DÓ'FÑ$ˆØ3�d—i‘iÐ3 ?Ð3ˆÛˆDØ�L‰L˜˜tÖ$ñ  ä-2´6¸+Ó3FÓ-GˆÔ*Ü $ X£ˆÔÜ" 8Ó,Ð,r*   c                ó\   <€ V ^8„  d   QhRS[ S[S[S[3,          S[S[,          3,          /# rN   )r×   r:   r&   Úset)r'   rŠ  s   "€r(   r)   r‹  B  s-   ø€ ÷ cñ c©%±±S¹#°XµÁÁCÅÐ0HÕ*Iñ cr*   c                ó8   € \        V P                  \        R7      # )zbSee ``remote_common.resolve_passthrough_env``; explicit docker_forward_env bypasses the blocklist.)Úhermes_env_loader)r   r�  Ú_load_hermes_env_varsrŽ  s   &r(   r@  Ú*DockerEnvironment._resolve_passthrough_envB  s   € ä& t×'8Ñ'8ÔLaÔbÐbr*   c                ót   <€ V ^8„  d   QhRS[ S[S[,          S[ S[R3,          S[S[S[3,          3,          /# r‰  )r×   r%   r&   r:   )r'   rŠ  s   "€r(   r)   r‹  F  s=   ø€ ÷ gñ g±U¹4Á½9ÁeÉCÐQTÈHÅoÑW[Ñ\_ÑadÐ\dÕWeÐ;eÕ5fñ gr*   c                óx   € V P                  4       w  r\        V4      \        \        V4      4      \	        V4      3# )z‰Runtime name-only forwarding args, names absent from scope, and the values
to inject into the docker client subprocess env.

See #96268.
)r@  rO  r×   rM  r:   )r�  rB  rC  s   &  r(   Ú#_build_runtime_env_args_with_unsetsÚ5DockerEnvironment._build_runtime_env_args_with_unsetsF  s8   € ð (,×'DÑ'DÓ'FÑ$ˆÜ" ?Ó3´U¼6À+Ó;NÓ5OÔQUÐVeÓQfÐfÐfr*   Úloginr˜   Ú
stdin_datac          
      óZ   <€ V ^8„  d   QhRS[ RS[RS[RS[ R,          RS[P                  /# )r!   Ú
cmd_stringrP  r˜   rQ  Nr#   )r&   rA   r?   r  ÚPopen)r'   rŠ  s   "€r(   r)   r‹  O  sD   ø€ ÷ xñ x¡Cð x±4ð xÙðxá! D�jðxá4>×4DÑ4Dñxr*   c               ó&  € V P                   '       g   Q R4       hV P                  R.pVe   VP                  R4       Rp/ pV'       d@   VP                  V P                  4       \        \        V R/ 4      4      p\        V RR4      pM6V P                  '       d%   V P                  4       w  r†pVP                  V4       WPP                   .\        \        W4      V4      O,          pV P                  V4      p	V	e   \        WTV	R7      # \        WT4      # )zÒSpawn bash inside the container. Init seeds the snapshot; profile-scoped passthrough
values are re-injected on every command because one container can be shared by
multiple routed profiles in a gateway process.zContainer not startedÚexecz-ir°  r®  )r8   rE  )r¯  r·  r2   r¨   rÄ  r:   r)  Ú_profile_scoped_passthroughrN  r   r   r5  r   )
r�  rS  rP  r˜   rQ  ÚcmdrC  Ú
env_valuesÚruntime_argsÚ
client_envs
   &&$$$     r(   Ú	_run_bashÚDockerEnvironment._run_bashO  sþ   € ð ×!×!Ð!Ð:Ð#:Ó:Ð!Ø×Ñ Ð(ˆØÒ!Ø�J‰J�tÔð (*ˆØ%'ˆ
ßØ�J‰J�t×*Ñ*Ô+Üœg dÐ,>ÀÓCÓDˆJÜ! $Ð(GÈÓL‰KØ×-×-Ð-Ø48×4\Ñ4\Ó4^Ñ1ˆL zØ�J‰J�|Ô$Ø×"Ñ"Ð^¤Y¬}¸ZÓ/UÐW\Ó%]Ð^Õ^ˆà×,Ñ,¨ZÓ8ˆ
Ø?IÒ?UŒ{˜3°
Ô;ÐwÔ[fÐgjÓ[wÐwr*   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r!   Úoutputr#   rf   )r'   rŠ  s   "€r(   r)   r‹  o  s   ø€ ÷ Eñ E©ð E±ñ Er*   c                ó    a€ \         ;QJ d)    V3R  lV P                   4       F  '       g   K   R# 	  R# ! V3R  lV P                   4       4      # )c              3   ó,   <"  € T F	  qS9   x € K  	  R # 5irœ   rE  )rŸ   rà   r_  s   & €r(   r¡   Ú7DockerEnvironment._is_container_gone.<locals>.<genexpr>p  s   øé € ÐDÑ(C 1˜–;Ó(Cùs   ƒTF)r  Ú_NO_CONTAINER_PATTERNS)r�  r_  s   &fr(   Ú_is_container_goneÚ$DockerEnvironment._is_container_goneo  s8   ø€ ß‹sÔD¨×(CÒ(CÓD�sŒsÐDŠsÐDˆsÔD¨×(CÒ(CÓDÓDÐDr*   c                ó    <€ V ^8„  d   QhRS[ /# rN   r  )r'   rŠ  s   "€r(   r)   r‹  r  s   ø€ ÷ .ñ .¡Tñ .r*   c                óØ  € \         P                  RV P                  ;'       g    RR,          4       RV n        V P                  V P                  P                  RR4      V P                  P                  RR4      V P                  P                  \        R4      4      pVe‡   Vw  r#VR8X  d%   W n        \         P                  R	VR,          4       MWV P                  V4      ;pf%   W n        \         P                  R
VR,          4       M\         P                  RVR,          V4       V P                  '       gÛ   V P                  '       g   \         P                  R4       R#  R\        P                  ! 4       P                  R,           2p\        V P                  WPP                   4      ^xRV P#                  V P$                  4      R7      pVP&                  P)                  4       V n        \         P                  RWPP                  R,          4        RV n        V P5                  4        \         P                  RT P                  ;'       g    RR,          4       T P9                  4        R#   \*        P,                  \*        P.                  \0        3 d"   p\         P                  RT4        Rp?R# Rp?ii ; i  \6         d"   p\         P                  RT4        Rp?R# Rp?ii ; i)zßRecreate a container removed out-of-band: label-based reuse first (another process
may have recreated it), else a fresh one from the saved image/run-args. False when
recovery fails so the caller surfaces the original error.u7   Container %s appears to be gone â€” attempting recoveryr  rZ   Nr¥  r¦  Úoffr  z&Recovery: reusing running container %sz Recovery: restarted container %sz*Recovery: failed to start container %s: %sz8Recovery: no saved image name, cannot recreate containerFr)  r*  Tr-  z)Recovery: created fresh container %s (%s)z,Recovery: failed to create new container: %sz2Recovery: init_session failed in new container: %su(   Recovery successful â€” new container %s)r-   r.   r¯  r	  r¹  Úgetr   r³   r  r½  r=  r1  r2  r3  r   r%  r”  r5  rÙ  r­   r/   r  r  rI  ru   Ú_snapshot_readyrÅ  rT   Ú_mark_recreated)r�  r  r¹   r  r  Únew_namer¼   rÍ   s   &       r(   Ú_recreate_containerÚ%DockerEnvironment._recreate_containerr  sM  € ô 	�‰ÐPÐSW×SeÑSe×SkÐSkÐikÐmpÕRqÔrØ!ˆÔà×0Ñ0Ø�L‰L×ÑÐ-¨rÓ2Ø�L‰L×ÑÐ-¨rÓ2Ø�L‰L×ÑÔ.°Ó6ó8ˆð ÒØ!‰JˆCØ˜	Ô!Ø%(Ô"Ü—‘ÐDÀcÈ#ÅhÕOØ×.Ñ.¨sÓ3Ð3�#Ò<Ø%(Ô"Ü—‘Ð>ÀÀCÅÕIä—‘ÐKÈSÐQTÍXÐWZÔ[à×!×!Ð!Ø—;—;�;Ü—‘ÐWÔXÙð	Ø$¤T§Z¢Z£\×%5Ñ%5°bÕ%9Ð$:Ð;�Ü$Ø×%Ñ% h·±Ó9À3ÈdØ×/Ñ/°×0DÑ0DÓEôG�ð &,§]¡]×%8Ñ%8Ó%:�Ô"Ü—‘ÐGÈ×SeÑSeÐfiÕSjÔkð
	Ø#(ˆDÔ Ø×ÑÔô
 	�‰Ð>À×ASÑAS×AYÐAYÐWYÐ[^Õ@_Ô`Ø×ÑÔÙøô ×1Ñ1´:×3LÑ3LÌgÐVô Ü—‘ÐKÈQÔOÝûðûô ô 	Ü�L‰LÐMÈqÔQÝûð	ús1   Å$B0I/ ÈJ= É/*J:ÊJ5Ê5J:Ê=K)ËK$Ë$K)c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r!   Úcommandr”  r#   )r&   r:   )r'   rŠ  s   "€r(   r)   r‹  ¢  s"   ø€ ÷ 
ñ 
™sð 
©ð 
Áñ 
r*   c                ó  <€ \         SV `  ! W3/ VB pVP                  R^ 4      ^ 8w  da   V P                  VP                  RR4      4      '       d:   V P                  '       d(   V P                  4       '       d   \         SV `  ! W3/ VB pV# )zˆExecute a command; if the container was removed out-of-band (idle reaper,
docker prune, OOM, daemon restart) recreate it and retry once.r²   r_  r  )r§  Úexecuteri  rd  rª  rm  )r�  rp  r”  Úkwargsr¼   rÕ  s   &&&, €r(   rr  ÚDockerEnvironment.execute¢  sz   ø€ ô ‘’ Ñ8°Ñ8ˆà�J‰J�| QÓ'¨1Ô,Ø×'Ñ'¨¯
©
°8¸RÓ(@×AÒAØ×.×.Ð.Ø×(Ñ(×*Ò*Ü‘W’_ WÑ<°VÑ<ˆFØˆr*   c                ó    <€ V ^8„  d   QhRS[ /# rN   r  )r'   rŠ  s   "€r(   r)   r‹  ¯  s   ø€ ÷ (ñ (¡Dñ (r*   c                 óÔ  € \         e   \         #  \        4       ;'       g    Rp \        V RRR.^
R7      pVP                  ^ 8w  d   R# VP                  P                  4       P                  4       R8w  d   Rs R# \        V RR	R
R.^R7      pVP                  ^ 8X  dh   Rs VP                  P                  4       '       dE   \        P                  ! V RVP                  P                  4       .R^\        P                  RR7       M+RVP                  ;'       g    RP                  4       9   d   Rs \        P                  R\         4       \         ;'       g    R#   \         d     R# i ; i)a  Whether ``--storage-opt size=`` works (only overlay2 on XFS with pquota; ext4 errors out).
Only definitive answers are cached: a probe that could not run (daemon cold-start,
hello-world pull timeout) says nothing about pquota support and is retried next spawn.r‘   r³   r–   z{{.Driver}}rÙ   FÚoverlay2Úcreaterã  zsize=1mzhello-worldTr£   r.  Ústorager  z Docker --storage-opt support: %s)Ú_storage_opt_okr§   r   r²   r­   r/   rñ   r  r/  r6  rµ   rT   r-   r´   )r‘   r¼   r  s      r(   rè  Ú(DockerEnvironment._storage_opt_supported®  s8  € ô Ò&Ü"Ð"ð	Ü “]×.Ð. hˆFÜ  &¨&°*¸mÐ!LÐVXÔYˆFØ× Ñ  AÔ%ÙØ�}‰}×"Ñ"Ó$×*Ñ*Ó,°
Ô:Ø"'�Ùä ¨°?ÀIÈ}Ð ]ÐgiÔjˆEØ×Ñ 1Ô$Ø"&�Ø—<‘<×%Ñ%×'Ò'Ü—N’N F¨D°%·,±,×2DÑ2DÓ2FÐ#GØ26ÀÌ×I[ÑI[Ðchõjøà˜uŸ|™|×1Ð1¨r×8Ñ8Ó:Ô:Ø"'�ô 	�‰Ð7¼ÔIÜ×'Ð' %Ð'øô ô 	Úð	ús6   �E ¡%E Á/E Á9AE Â>AE ÄE ÄE ÅE'Å&E'c                ó6   <€ V ^8„  d   QhRS[ RS[S[ ,          /# ©r!   r¿   r#   ©r&   r   )r'   rŠ  s   "€r(   r)   r‹  Í  s#   ø€ ÷ Oñ O©Sð O±X¹cµ]ñ Or*   c                ó’   € \        V P                  RRRV.^
RRR7      pVe%   VP                  P                  4       ;'       g    R# R# )zûThe image reference a container was created from (``Config.Image``: the tag as given
to ``docker run``, so it compares directly with ``docker_image``), or ``None`` when
inspection fails (callers then keep the container: a failed probe must not churn).rÁ   r–   z{{.Config.Image}}zdocker inspect Image failed: %sz$docker inspect Image returned %d: %sr—   N©r©   r·  r­   r/   ©r�  r¿   r¼   s   && r(   r
  Ú"DockerEnvironment._container_imageÍ  sT   € ô Ø×Ñ˜y¨*Ð6IÈ<ÐXÐbdØ2Ð<bôdˆð 39Ò2D�—‘×#Ñ#Ó%×-Ð-¨ÐNÈ$ÐNr*   c                ó6   <€ V ^8„  d   QhRS[ RS[S[ ,          /# r}  r~  )r'   rŠ  s   "€r(   r)   r‹  Ö  s#   ø€ ÷ Oñ O±Cð O¹HÁS½Mñ Or*   c                ó’   € \        V P                  RRRV.^
RRR7      pVe%   VP                  P                  4       ;'       g    R# R# )z¥``HostConfig.NetworkMode`` of a container, or ``None`` when inspection fails (callers
treat ``None`` as a mismatch under lockdown, so a failed inspect fails closed).rÁ   r–   z{{.HostConfig.NetworkMode}}z%docker inspect NetworkMode failed: %sz*docker inspect NetworkMode returned %d: %sr—   Nr€  r�  s   && r(   r  Ú)DockerEnvironment._container_network_modeÖ  sU   € ô Ø×Ñ˜y¨*Ð6SÐUaÐbÐlnØ8ÐBnôpˆð 39Ò2D�—‘×#Ñ#Ó%×-Ð-¨ÐNÈ$ÐNr*   c                óX   <€ V ^8„  d   QhRS[ RS[ RS[ RS[S[S[ S[ 3,          ,          /# )r!   rÒ  Úprofile_labelrÈ  r#   )r&   r   r×   )r'   rŠ  s   "€r(   r)   r‹  Þ  s?   ø€ ÷ " ñ " Ùð" Ù.1ð" ÙADð" ÙIQÑRWÑX[Ñ]`ÐX`ÕRaÕIbñ" r*   c                óP  € RRRRV 2RRV 2RR\          RV 2.pV P                  P                  \        4      ;p'       d   VP	                  RR\         RV 2.4       \        V P                  RR.VOR	NR
N^
RRR7      pVf   R# R;rxR VP                  P                  4        4        Fm  p	V	P                  R^4      p
\        V
4      ^8w  d   K'  V
^ ,          V
^,          P                  4       P                  4       rËVf   W¼3pVR8X  g   Kd  Ve   Kj  W¼3pKo  	  T;'       g    T# )uR  ``(container_id, state)`` of an existing container labeled for this task/profile/
egress posture and immutable environment, or ``None`` on miss or any failure.
Explicit shared keys opt out of the environment filter. The egress posture is a label
FILTER for every posture, "off" included: a container built with egress on must not be
reused after ``hermes egress disable`` (baked-in proxy env and CA mounts), and every
container this class creates carries the label. The ``{{.Label "key"}}`` template
function is Docker-only â€” podman ps exits 125 on it â€” so the probe never uses it (#99213).r’   r¦   zlabel=hermes-task-id=r“   zlabel=r  r”   r•   r–   z{{.ID}}	{{.State}}u;   docker ps probe failed: %s â€” will start a fresh containeru@   docker ps probe returned %d: %s â€” will start a fresh containerr—   Nc              3   óT   "  € T F  qP                  4       '       g   K  Vx € K   	  R # 5irœ   r�   rž   s   & r(   r¡   Ú=DockerEnvironment._find_reusable_container.<locals>.<genexpr>÷  s   é € ÐIÑ :˜"¿h¹h¿j—2’2Ó :ùs   ‚(ž
(Ú	r  )r   r¹  ri  r¼  r¨   r©   r·  r­   r®   rk   r	  r/   rñ   )r�  rÒ  r‡  rÈ  r¶   Úenvironment_labelr¼   r  Úfirstr    Úpartsr¹   r  s   &&&&         r(   r	  Ú*DockerEnvironment._find_reusable_containerÞ  sQ  € ð Ð.ØÐ/°
¨|Ð<ØÐ/°¨Ð?Ø˜&Ô!2Ð 3°1°\°NÐCð	Eˆð
 !%§¡× 0Ñ 0Ô1GÓ HÐHÐÖHØ�N‰N˜J¨&Ô1GÐ0HÈÐJ[ÐI\Ð(]Ð^Ô_ÜØ×Ñ˜t TÐW¨GÐW°ZÐWÐAVÐWÐacØNØVôXˆð Š>Ùð ÐˆÙI §¡× 8Ñ 8Ô :ÖIˆBØ—H‘H˜T 1Ó%ˆEÜ�5‹z˜QŒÙØ˜q� 5¨¥8§>¡>Ó#3×#9Ñ#9Ó#;�ØŠ}Ø˜�Ø˜	Ö! g¤oØ˜,’ñ Jð ×Ð˜%Ðr*   c                ó   <€ V ^8„  d   QhRR/# rD  rE  )r'   rŠ  s   "€r(   r)   r‹    s   ø€ ÷ 5ñ 5 4ñ 5r*   c                óˆ   € V P                   V P                  3 F%  pV'       g   K  \        P                  ! VR R7       K'  	  R# )T)Úignore_errorsN)r±  r²  rä   Úrmtree)r�  Úds   & r(   Ú_remove_bind_dirsÚ#DockerEnvironment._remove_bind_dirs  s.   € Ø×%Ñ% t§~¡~Ó6ˆAß‰qÜ—’˜a¨t×4ó 7r*   Úforce_removec                ó    <€ V ^8„  d   QhRS[ /# )r!   r—  r  )r'   rŠ  s   "€r(   r)   r‹    s   ø€ ÷ 3%ñ 3%¡tñ 3%r*   c               óÚ  aaaa€ V P                   oS'       g%   V P                  '       g   V P                  4        R# V P                  oSR,          o\	        \        V R. 4      4      oV'       g3   V P                  '       d!   RV n         V P                  VV3R lS4       R# R VVVV3R llpV P                  VS4       RV n         V P                  '       g   V P                  4        R# R# )u7  Tear down per persist mode. Persist mode (default) leaves the container RUNNING â€”
stopping it on every exit would kill background processes and add a ``docker start``
delay per session; reclamation is ``reap_orphan_containers()`` at next startup.
``persist_across_processes=False`` or ``force_remove=True`` (explicit-teardown hook,
unused so far) does ``docker stop`` + ``docker rm -f`` on a daemon thread that the
atexit hook joins via ``wait_for_cleanup`` so the work completes before exit.

Cleanup runs on a daemon thread with bounded ``subprocess.run`` calls (not the racy ``Popen(... &)``
pattern from before PR #33645). The atexit hook in ``tools/terminal_tool.py`` waits up to 15s for
the thread to finish before the interpreter exits, so ``docker stop`` / ``docker rm`` actually
completes when we do trigger it.
NrZ   r³  c                  ó   <€ \        SS 4      # rœ   )r   )r¿   rŽ   s   €€r(   Ú<lambda>Ú+DockerEnvironment.cleanup.<locals>.<lambda>%  s   ø€ Ô)AÀ*ÈlÔ)[r*   c                ó   € V ^8„  d   QhRR/# rD  rE  )r'   s   "r(   r)   Ú/DockerEnvironment.cleanup.<locals>.__annotate__(  s   € ÷ 
	8ñ 
	8˜Tñ 
	8r*   c            	      óV  <€ . R	OR3RR.R33 FW  w  rV ^ ,          R8X  d   S'       d   \        SSS4        \        P                  ! S.V OSNR^\        P                  RR7       KY  	  R#   \        P                  \
        3 d#   p\        P                  TST4        Rp?K•  Rp?ii ; i)
Ústopz%docker stop %s timed out / failed: %sr£   r  zdocker rm -f %s failed: %sTFr.  N)r   ú-tÚ10)r   r  r/  r6  rI  ru   r-   r.   )rÖ   Úfail_msgrÍ   r¿   rŽ   Úlog_idÚsandbox_mountss      €€€€r(   Ú_do_cleanupÚ.DockerEnvironment.cleanup.<locals>._do_cleanup(  s¤   ø€ Ú$8Ð:aÐ#bØ%)¨4 LÐ2NÐ#Oó#Q‘�à˜•7˜d”?§~Ü+¨J¸ÀnÔUð8Ü—N’NØ#Ð9 dÐ9¨LÐ9Ø'+°R¼z×?QÑ?QÐY^÷`ó#Qøô #×1Ñ1´7Ð;ô 8Ü—N‘N 8¨V°Q×7Ò7ûð8ús   ·.A+Á+B(ÂB#Â#B()r¯  r©  r•  r·  r%   r)  rª  Ú_start_teardown)r�  r—  r¦  r¿   rŽ   r¤  r¥  s   &$ @@@@r(   ÚcleanupÚDockerEnvironment.cleanup  sÉ   û€ ð ×)Ñ)ˆßà×#×#Ð#Ø×&Ñ&Ô(Ùð ×%Ñ%ˆ
Ø˜cÕ"ˆÜœg dÐ,=¸rÓBÓCˆç × >× >Ð >ð "&ˆDÔà× Ñ Õ![Ð]cÔdÙ÷
	8ó 
	8ð 	×Ñ˜[¨&Ô1Ø!ˆÔð ××ÐØ×"Ñ"Ö$ñ  r*   c                ó   <€ V ^8„  d   QhRR/# rD  rE  )r'   rŠ  s   "€r(   r)   r‹  <  s   ø€ ÷ "ñ "˜4ñ "r*   c                ó¬   aaa€ V P                   oS'       g   R# V P                  SR,          uooR VVV3R llpV P                  VS4       RV n         R# )aI  Idle reclaim of a per-workspace persistent container (#140665): ``docker stop``, never
``rm``. Its writable layer and ``/root`` sandbox stay, and the next use in that workspace
re-attaches through :meth:`_attach_existing_container`, which ``docker start``s a stopped
container. Without this, persistent mode left one RUNNING container per workspace a user
ever opened (each with its own ``container_memory``) until the process exited. Like a
persist-mode cleanup, the host user may touch what it left before it is reattached, so its
sandbox privileges are stripped once it has stopped.NrZ   c                ó   € V ^8„  d   QhRR/# rD  rE  )r'   s   "r(   r)   Ú1DockerEnvironment.stop_idle.<locals>.__annotate__I  s   € ÷ 	?ñ 	?˜$ñ 	?r*   c                  óü   <€  \         P                  ! SR RRS.R^\         P                  RR7       \        SS4       R#   \         P                  \        3 d"   p \
        P                  RST 4        Rp ? LERp ? ii ; i)r   r¡  r¢  TFr.  z*docker stop %s (idle workspace) failed: %sN)r  r/  r6  rI  ru   r-   r.   r   )rÍ   r¿   rŽ   r¤  s    €€€r(   Ú_do_stopÚ-DockerEnvironment.stop_idle.<locals>._do_stopI  ss   ø€ ðXÜ—’ 
¨F°D¸$ÀÐMÐ^bØ')´×1CÑ1CÈ5õRô % Z°Ö>øô ×-Ñ-¬wÐ7ô XÜ—‘ÐKÈVÐUV×WÑWûðXús   ƒ.? ¿A;ÁA6Á6A;)r¯  r·  r¨  )r�  r°  r¿   rŽ   r¤  s   & @@@r(   Ú	stop_idleÚDockerEnvironment.stop_idle<  sQ   ú€ ð ×)Ñ)ˆßÙØ!×-Ñ-¨|¸CÕ/@Ðˆ
�F÷	?ò 	?ð 	×Ñ˜X vÔ.Ø!ˆÖr*   c                ó$   <€ V ^8„  d   QhRS[ RR/# )r!   r¤  r#   NrE   )r'   rŠ  s   "€r(   r)   r‹  T  s   ø€ ÷ !ñ !©Cð !°Dñ !r*   c                óè   € \         P                  ! VRRV 2R7      p\        ;_uu_ 4        \        P	                  V4       RRR4       VP                  4        W0n        R#   + '       g   i     L(; i)z5Run *work* on a daemon thread the atexit drain joins.Tzhermes-cleanup-)rq  Údaemonrƒ  N)Ú	threadingÚThreadÚ_TEARDOWN_LOCKÚ_TEARDOWN_THREADSÚaddr  Ú_cleanup_thread)r�  Úworkr¤  Úts   &&& r(   r¨  Ú!DockerEnvironment._start_teardownT  sL   € ä×Ò D°¸oÈfÈXÐ<VÔWˆßŽ^Ü×!Ñ! !Ô$÷ à	�‰Œ	Ø Ö÷ �^ús   «A!Á!A1	c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r!   r˜   r#   ©r@   rA   )r'   rŠ  s   "€r(   r)   r‹  ]  s   ø€ ÷ /ñ /©ð /¹ñ /r*   c           	     óÌ  € \         P                  ! 4       V ,           p \        ;_uu_ 4        \        P	                  \         Uu0 uF  q"P                  4       '       d   K  VkK  	  up4       \        \        4      pRRR4       X'       g   R# V\         P                  ! 4       ,
          pV^ 8:  d   R# V^ ,          P                  VR7       K±  u upi   + '       g   i     L_; i)uQ  Join every in-flight teardown worker, including those of envs the idle reaper already
popped out of the active registry (their handles are otherwise unreachable at exit, so
``docker rm`` died with the interpreter and left a stopped container behind â€” #86317).
Re-snapshots each pass: the reaper may start a worker while the drain runs.TNFrÙ   )ÚtimeÚ	monotonicr¹  rº  Údifference_updateÚis_aliver%   r4  )r˜   Údeadliner¾  ÚpendingÚ	remainings   &    r(   Úwait_for_all_teardownsÚ(DockerEnvironment.wait_for_all_teardowns\  s›   € ô —>’>Ó# gÕ-ˆØß–Ü!×3Ñ3Õ@QÓ4fÑ@Q¸1×YcÑYc×Ye·Q°QÑ@QÑ4fÔgÜÔ0Ó1�÷  ÷ ÙØ ¤4§>¢>Ó#3Õ3ˆIØ˜AŒ~ÙØ�A�J�O‰O IˆOÖ.ùò 5g÷  —ús#   ¬CÁCÁ CÁ&CÃCÃC#	c                ó&   <€ V ^8„  d   QhRS[ RS[/# rÁ  rÂ  )r'   rŠ  s   "€r(   r)   r‹  n  s   ø€ ÷ %ñ %©ð %¹ñ %r*   c                ó¢   € \        V RR4      pVe   VP                  4       '       g   R# VP                  VR7       VP                  4       '       * # )z~Block up to *timeout* seconds for the cleanup thread (atexit hook). True if it
finished or none was started, False on timeout.r¼  NTrÙ   )r)  rÇ  r4  )r�  r˜   Úthreads   && r(   Úwait_for_cleanupÚ"DockerEnvironment.wait_for_cleanupn  sE   € ô ˜Ð0°$Ó7ˆØŠ> §¡×!2Ò!2ÙØ�‰˜GˆÔ$Ø—?‘?Ó$Ô$Ð$r*   )rÀ  r¼  r¯  r·  r­  r�  r²  r½  r¾  r¿  rÄ  r°  r®  r¹  rª  r©  rÙ  r³  r«  r¸  rj  r¬  r±  r”  r€  r£  )zNo such containerzis not runningzno such container©r  )g      .@)g      >@))r=   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú"_passwordless_sudo_probe_supportedrW  r�  Ú_DEFAULT_SHM_SIZEr¨  r¶  r´  rµ  rÁ  r  r  r%  rÂ  r5  rÃ  r@  rN  r\  rc  rd  rm  rr  Ústaticmethodrè  r
  r  r	  r•  r©  r²  r¨  rË  rÐ  Ú__static_attributes__Ú__classdictcell__Ú__classcell__)rÕ  rŠ  s   @@r(   r‡  r‡  ‡  sÒ  ù‡ € ñ^ð *.Ð&Ø"&Ð÷(ð (ð ØØØØØ&+Ø Ø#Ø(,ØØØ"&Ø$Ø!&Ø"&Ø)-Ø)Ø$&Ø!Ø"÷-õ ÷Dtð t÷8"ð "÷HL*ð L*÷\Fð F÷Pð ÷ð ÷!ð !÷"ð ÷,	'ð 	'÷-ð -÷cð c÷gð gðx¸%ð xØ!$ðxà+/÷xò xð< ZÐ÷Eð E÷.ð .÷`
õ 
ð ÷(ó ð(÷<Oð O÷Oð O÷" ð " ÷H5ð 5ð
3%¨e÷ 3%ò 3%÷j"ð "÷0!ð !ð ÷/ñ /ó ð/÷"%÷ %ò %r*   r‡  c                ó$  € V ^8„  d   Qh/ ^ \         9   d   \        \        ,          ;R&   ^\         9   d   \        \        P
                  ,          ;R&   ^\         9   d   \        \        ,          ;R&   ^\         9   d   \        \        ,          ;R&   # )r!   râ   rº  rz  r8  )Ú__conditional_annotations__r   r&   rG  r·  r¸  rA   )r'   s   "r(   r)   r)      ss   € ÷ ñ ÷b )Ò (”HœS•MÑ (ñc÷X 1Ò 0”3”y×'Ñ'Õ(Ñ 0ñY÷D 'Ò &”œ$•Ñ &ñE÷F )Ò (”8œD•>Ñ (òGr*   )z/usr/local/bin/dockerz/opt/homebrew/bin/dockerz6/Applications/Docker.app/Contents/Resources/bin/dockerrÒ  rE  )z
--cap-dropÚALLú	--cap-addÚDAC_OVERRIDErà  ÚCHOWNrà  ÚFOWNERrô  z/tmp:rw,nosuid,size=512mrô  z#/var/tmp:rw,noexec,nosuid,size=256m)z	--networkz--net)rô  z/run:rw,noexec,nosuid,size=64m)rô  z/run:rw,exec,nosuid,size=64m)rà  ÚSETUIDrà  ÚSETGID)z/initz&/package/admin/s6-overlay/command/init)FF))Úget_credential_file_mountsTÚ
credential)Úget_skills_directory_mountFz
skills dir)Úget_cache_directory_mountsFz	cache dir)z	/host-cwdz/host-cwd-2z/host-cwd-3)zrÞ  rÖ  rª   r^   r†   Úloggingrl   rÄ   Úshlexrä   r  ræ  ro   r·  rÄ  r1  Úpathlibr   Útypingr   Úhermes_constantsr   Útools.environments.baser   r   r   r   Útools.terminal_tool_configr	   r
   r   Útools.environments.base_outputr   Ú tools.environments.docker_egressr   r   r   r   r   r   r   r   r   Ú#tools.environments.docker_ownershipr   r   r   Útools.environments.path_utilsr   Ú tools.environments.remote_commonr   r   r   r   r   r   Ú	getLoggerr=   r-   rç   râ   r0   r¼  rÃ   Úcompilerº  r6   rC   rJ  rJ   rL   rö  rU   rc   rz   r‹   r½   r±   r¯   rÓ   rI  ru   r©   r§   ró   rö   r  rå  rØ  r  r  r  r  r  r  rG  rº  ÚLockr¹  r"  r  r  r$  r,  rz  r8  r9  rB  rJ  rO  rV  r`  rd  ri  r|  rj   rr  rw  r~  r…  r‡  r)   )rÞ  s   @r(   Ú<module>rù     sv  øðöó Û Û Û Û 	Û 	Û Û Û Û 
Û Û Û Û Ý Ý å ,ß tÓ t÷ñ õ 7÷÷ õ ÷
Nñ Nå C÷k÷ kð 
×	Ò	˜8Ó	$€òÐ ð %)Ð Ó (Ø%Ð Ø-Ð ð *Ð Ø—Z’ZÐ 6Ó7Ð õõ"ð( -Ð ð
 —Z’ZÐ 2Ó3Ð õ@ð .Ð õ÷@õõ0Dð,-Ø!ð-Ø@Dð-Ø_c÷-õ`Lõõ(=ðØFHðØ`dðà"×1Ñ1°7Ð;÷õ$õ,Võ2ò6Ð ð Ð ð Ð õ%ð (€õð" @Ð Ø;€ò
 DÐ ñ ,/«5Ð Ó 0Ø—’Ó!€àJÐ ð ,Ð-@ÐAÐ ÷Iõ>õ.
ð #'€Ó &Ø$(Ð Ó (õ*ðZ>ÐY^÷ >õ
"GõJAð8Ð õõ4ð —*’*ÐOÓP€àGÐ õ9õõ	õ)õ%ôn%˜ö n%r*   