§
    øžyj/f ã            	       óâ  — U d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZ ddlmZmZmZ ddlmZmZ  ej        e¦  «        Zg d¢Zdaee         ed<    ej        d	¦  «        Zd
Zde e         dz  de e         fd„Z!de"dz  de"eef         fd„Z#de"eef         fd„Z$ ej        d¦  «        Z%dedefd„Z&defd„Z'ddddœde(dedz  dedz  de(fd„Z)dedefd„Z*dee         fd„Z+g d¢Z,dZ-d Z.d!e de/fd"„Z0d#Z1d$Z2g d%¢Z3de4e e         e"eef         e e         f         fd&„Z5d'e e         d(e"eef         d)e e         defd*„Z6d>d,e/de/fd-„Z7d(e"eef         de8e         fd.„Z9d!e e         d/e8e         de e         fd0„Z:d?d2e/d3e/de e         fd4„Z;ded5ede/fd6„Z<dee         fd7„Z=da>ee/         ed8<   da?ee/         ed9<   d5ede/fd:„Z@d@d;„ZA G d<„ d=e¦  «        ZBdS )Azç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)ÚBaseEnvironmentÚEnvironmentConnectionErrorÚ_popen_bash)Ú_HERMES_PROVIDER_ENV_BLOCKLISTÚ_is_hermes_internal_secret)z/usr/local/bin/dockerz/opt/homebrew/bin/dockerz6/Applications/Docker.app/Contents/Resources/bin/dockerÚ_docker_executablez^[A-Za-z_][A-Za-z0-9_]*$zhermes-egressÚforward_envÚreturnc                 óŽ  — g }t          ¦   «         }| pg D ]¯}t          |t          ¦  «        st                               d|¦  «         Œ3|                     ¦   «         }|sŒJt                               |¦  «        st                               d|¦  «         Œ€||v rŒ…|                     |¦  «         | 	                    |¦  «         Œ°|S )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)
ÚsetÚ
isinstanceÚstrÚloggerÚwarningÚstripÚ_ENV_VAR_NAME_REÚmatchÚaddÚappend)r   Ú
normalizedÚseenÚitemÚkeys        ú?/home/ragecks/.hermes/hermes-agent/tools/environments/docker.pyÚ_normalize_forward_env_namesr   0   sÌ   € à€JÝ‘U”U€DàÐ!˜rð ð ˆÝ˜$¥Ñ$Ô$ð 	Ý�NŠNÐMÈtÑTÔTÐTØà�jŠj‰lŒlˆØð 	ØÝ×%Ò% cÑ*Ô*ð 	Ý�NŠNÐJÈDÑQÔQÐQØØ�$ˆ;ˆ;Øà�Š�‰ŒˆØ×Ò˜#ÑÔÐÐàÐó    Úenvc                 ó^  — | si S t          | t          ¦  «        st                               d| ¦  «         i S i }|                      ¦   «         D ]ß\  }}t          |t
          ¦  «        r,t                               |                     ¦   «         ¦  «        st                               d|¦  «         Œb|                     ¦   «         }t          |t
          ¦  «        sOt          |t          t          t          f¦  «        rt          |¦  «        }nt                               d||¦  «         ŒÚ|||<   Œà|S )z‡Validate and normalize a docker_env dict to {str: str}.

    Filters out entries with invalid variable names or non-string values.
    zdocker_env is not a dict: %rz#Ignoring invalid docker_env key: %rz/Ignoring non-string docker_env value for %r: %r)r   Údictr   r   Úitemsr   r   r   r   ÚintÚfloatÚbool)r   r   r   Úvalues       r   Ú_normalize_env_dictr'   I   s  € ð
 ð Øˆ	Ý�c�4Ñ Ô ð Ý�ŠÐ5°sÑ;Ô;Ð;Øˆ	à!#€JØ—i’i‘k”kð  ð  ‰
ˆˆUÝ˜#�sÑ#Ô#ð 	Õ+;×+AÒ+AÀ#Ç)Â)Á+Ä+Ñ+NÔ+Nð 	Ý�NŠNÐ@À#ÑFÔFÐFØØ�iŠi‰kŒkˆÝ˜%¥Ñ%Ô%ð 	õ ˜%¥#¥u­dÐ!3Ñ4Ô4ð Ý˜E™
œ
��å—’ÐPÐRUÐW\Ñ]Ô]Ð]ØØˆ
�3‰ˆàÐr   c                  óL   — 	 ddl m}   | ¦   «         pi S # t          $ r i cY S w xY w)zDLoad ~/.hermes/.env values without failing Docker command execution.r   ©Úload_env)Úhermes_cli.configr*   Ú	Exceptionr)   s    r   Ú_load_hermes_env_varsr-   g   sN   € ðØ.Ð.Ð.Ð.Ð.Ð.àˆx‰zŒzÐ˜RÐøÝð ð ð Øˆ	ˆ	ˆ	ðøøøs   ‚ ”#¢#z[^A-Za-z0-9_.-]r&   c                 ó†   — t          | t          ¦  «        r| sdS t                               d| ¦  «        }|dd…         pd}|S )u  Coerce *value* into a Docker label-safe form (alnum + ``_.-``, â‰¤63 chars).

    Empty or all-invalid inputs collapse to ``"unknown"`` so the resulting
    label is always queryable. Used at container-create time; never round-trip
    a sanitized value back into application logic.
    ÚunknownÚ_Né?   )r   r   Ú_LABEL_VALUE_OK_REÚsub)r&   Úcleaneds     r   Ú_sanitize_label_valuer5   w   sN   € õ �e�SÑ!Ô!ð ¨ð ØˆyÝ ×$Ò$ S¨%Ñ0Ô0€GØ�c�r�cŒlÐ'˜i€GØ€Nr   c                  óJ   — 	 ddl m}   | ¦   «         pdS # t          $ r Y dS w xY w)a   Return the active Hermes profile name, or ``"default"`` on any error.

    Resolved at container-create time so a single container is permanently
    tagged with the profile that created it. Profile switches inside the
    same process don't retroactively relabel running containers.
    r   ©Úget_active_profile_nameÚdefault)Úhermes_cli.profilesr8   r,   r7   s    r   Ú_get_active_profile_namer;   …   sO   € ðØ?Ð?Ð?Ð?Ð?Ð?à&Ð&Ñ(Ô(Ð5¨IÐ5øÝð ð ð Øˆyˆyðøøøs   ‚ ”
"¡"iX  )Úmax_age_secondsÚprofile_filterÚ
docker_exer<   r=   r>   c           
      óÜ  — |pt          ¦   «         pd}g d¢}|r'|                     ddt          |¦  «        › �g¦  «         	 t          j        |ddg|¢d‘d‘d	d	d
dddt          j        ¬¦  «        }n?# t          j        t          f$ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w|j
        dk    r:t           	                    d|j
        |j                             ¦   «         ¦  «         dS d„ |j                             ¦   «         D ¦   «         }|sdS ddl}|j                             |j        j        ¦  «        }	d}
|D �]"}t'          ||¦  «        }|€Œ|	|z
                       ¦   «         }|| k     rŒ4	 t          j        |dd|gd	d	d
ddt          j        ¬¦  «        }|j
        dk    r7|
dz  }
t                               d|dd…         t-          |¦  «        ¦  «         n;t           	                    d|dd…         |j                             ¦   «         ¦  «         ŒÜ# t          j        t          f$ r/}t           	                    d|dd…         |¦  «         Y d}~�Œd}~ww xY w|
S )u{  Remove stale hermes-tagged containers left behind by prior processes.

    Targets containers that match all of:

    * ``label=hermes-agent=1`` (created by this codebase)
    * ``status=exited`` (running containers are NEVER reaped â€” they may
      belong to a sibling Hermes process whose reuse path will pick them
      up; killing them would crash the sibling mid-command)
    * (optional) ``label=hermes-profile=<profile_filter>`` (sweep only the
      caller's profile by default; a hermes process in profile A must not
      tear down profile B's containers)
    * ``State.FinishedAt`` older than *max_age_seconds* ago (so a sibling
      process that just exited and is about to be replaced doesn't get
      its container yanked out from under it)

    Returns the number of containers removed. Best-effort: any failure
    (docker daemon unreachable, slow inspect, parse error) is logged at
    debug level and the function returns whatever it managed before the
    failure. Safe to call repeatedly; idempotent.

    Issue #20561 â€” this is the safety net for SIGKILL / OOM / crashed
    terminal exits that bypass the ``atexit`` cleanup hook. Without it,
    even with the cleanup-fix in the prior commit, a hard-killed Hermes
    process leaves its container behind permanently because there's no
    subsequent Hermes process scheduled to reuse that exact (task, profile)
    pair.
    Údocker)ú--filterúlabel=hermes-agent=1rA   zstatus=exitedrA   úlabel=hermes-profile=Úpsú-aú--formatz{{.ID}}Túutf-8Úreplaceé   F©Úcapture_outputÚtextÚencodingÚerrorsÚtimeoutÚcheckÚstdinz"orphan reaper docker ps failed: %sNr   z'orphan reaper docker ps returned %d: %sc                 ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S © ©r   ©Ú.0Úlns     r   ú
<listcomp>z*reap_orphan_containers.<locals>.<listcomp>Ê   s-   € ÐTÐTÐT BÈÏÊÉÌÐT�R—X’X‘Z”ZÐTÐTÐTr   Úrmú-fé   ©rK   rL   rM   rN   rO   rQ   é   z2Reaped orphan container %s (exited %d seconds ago)é   údocker rm -f %s failed: %sz%orphan reaper docker rm %s failed: %s)Úfind_dockerÚextendr5   Ú
subprocessÚrunÚDEVNULLÚTimeoutExpiredÚOSErrorr   ÚdebugÚ
returncodeÚstderrr   ÚstdoutÚ
splitlinesÚdatetimeÚnowÚtimezoneÚutcÚ_container_finished_atÚtotal_secondsÚinfor#   )r<   r=   r>   r@   ÚfiltersÚlistingÚeÚcandidate_idsrl   rm   ÚremovedÚcidÚfinished_atÚageÚresults                  r   Úreap_orphan_containersr|   ”   sô  € ðB Ð4�;™=œ=Ð4¨H€FØOÐOÐO€GØð fØ�Š˜
Ð$cÕ<QÐR`Ñ<aÔ<aÐ$cÐ$cÐdÑeÔeÐeðÝ”.Ø�T˜4ÐA 'ÐA¨:ÐA°yÐAØ d°WÀYÐXZÐbgÝÔ$ð
ñ 
ô 
ˆˆøõ
 Ô%¥wÐ/ð ð ð Ý�ŠÐ9¸1Ñ=Ô=Ð=Øˆqˆqˆqˆqˆqøøøøðøøøð Ô˜QÒÐÝ�ŠØ5ØÔ ¤× 4Ò 4Ñ 6Ô 6ñ	
ô 	
ð 	
ð ˆqàTÐT¨'¬.×*CÒ*CÑ*EÔ*EÐTÑTÔT€MØð Øˆqð
 €O€O€OØ
Ô
×
Ò
 Ô 1Ô 5Ñ
6Ô
6€CØ€GØð Oñ OˆÝ,¨V°SÑ9Ô9ˆØÐàØ�[Ñ ×/Ò/Ñ1Ô1ˆØ�Ò Ð Øð	OÝ”^Ø˜˜t SÐ)Ø#¨$¸ÈÐ\^Ý Ô(ðñ ô ˆFð
 Ô  AÒ%Ð%Ø˜1‘�Ý—’ØHØ˜˜˜”H�c #™hœhñô ð ð õ
 —’Ø0Ø˜˜˜”H˜fœm×1Ò1Ñ3Ô3ñô ð øøõ Ô)­7Ð3ð 	Oð 	Oð 	OÝ�LŠLÐ@À#ÀcÀrÀcÄ(ÈAÑNÔNÐNÐNÐNÐNÐNÑNøøøøð	Oøøøà€Ns1   Á/A1 Á1B-ÂB(Â(B-Å=B&H$È$I)È:$I$É$I)Úcontainer_idc           
      ó„  — 	 t          j        | ddd|gddddddt           j        ¬	¦  «        }nH# t           j        t          f$ r/}t
                               d
|dd…         |¦  «         Y d}~dS d}~ww xY w|j        dk    rdS |j         	                    ¦   «         }|r| 
                    d¦  «        rdS ddl}|                     dd|¦  «        }|                     dd¦  «        }	 ddl}|j                             |¦  «        S # t           $ r0}t
                               d||dd…         |¦  «         Y d}~dS d}~ww xY w)u@  Parse ``docker inspect`` FinishedAt for *container_id*.

    Returns a timezone-aware datetime, or ``None`` if the field is missing,
    unparseable, or the zero-value ``0001-01-01T00:00:00Z`` Docker emits
    for never-finished containers. ``None`` means "don't reap" â€” the caller
    leaves the container alone.
    ÚinspectrF   z{{.State.FinishedAt}}TrG   rH   é
   FrJ   z*orphan reaper docker inspect %s failed: %sNr^   r   z
0001-01-01z(\.\d{6})\d+z\1ÚZz+00:00z(could not parse FinishedAt %r for %s: %s)rb   rc   rd   re   rf   r   rg   rh   rj   r   Ú
startswithÚrer3   rH   rl   ÚfromisoformatÚ
ValueError)r>   r}   r{   ru   ÚrawÚ_rerl   s          r   rp   rp   ò   s’  € ðÝ”Ø˜ JÐ0GÈÐVØ d°WÀYÐXZÐbgÝÔ$ð
ñ 
ô 
ˆˆøõ
 Ô%¥wÐ/ð ð ð Ý�ŠÐAÀ<ÐPSÐQSÐPSÔCTÐVWÑXÔXÐXØˆtˆtˆtˆtˆtøøøøðøøøð Ô˜AÒÐØˆtØ
Œ-×
Ò
Ñ
Ô
€CØð �#—.’. Ñ.Ô.ð Øˆtð ÐÐÐØ
�'Š'�/ 5¨#Ñ
.Ô
.€CØ
�+Š+�c˜8Ñ
$Ô
$€CðØˆˆˆØÔ ×.Ò.¨sÑ3Ô3Ð3øÝð ð ð Ý�ŠÐ?ÀÀlÐSVÐTVÐSVÔFWÐYZÑ[Ô[Ð[Øˆtˆtˆtˆtˆtøøøøðøøøs-   ‚+. ®A3Á$A.Á.A3Ã'D Ä
D?Ä%D:Ä:D?c                  óx  — t           �t           S t          j        d¦  «        } | r]t          j                             | ¦  «        r>t          j        | t          j        ¦  «        r| a t                               d| ¦  «         | S t          j
        d¦  «        }|r|a |S t          j
        d¦  «        }|r|a t                               d|¦  «         |S t          D ]a}t          j                             |¦  «        r@t          j        |t          j        ¦  «        r!|a t                               d|¦  «         |c S ŒbdS )u‚  Locate the docker (or podman) CLI binary.

    Resolution order:
    1. ``HERMES_DOCKER_BINARY`` env var â€” explicit override (e.g. ``/usr/bin/podman``)
    2. ``docker`` on PATH via ``shutil.which``
    3. ``podman`` on PATH via ``shutil.which``
    4. Well-known macOS Docker Desktop install locations

    Returns the absolute path, or ``None`` if neither runtime can be found.
    NÚHERMES_DOCKER_BINARYz'Using HERMES_DOCKER_BINARY override: %sr@   Úpodmanz%Using podman as container runtime: %sz%Found docker at non-PATH location: %s)r
   ÚosÚgetenvÚpathÚisfileÚaccessÚX_OKr   rr   ÚshutilÚwhichÚ_DOCKER_SEARCH_PATHS)ÚoverrideÚfoundr�   s      r   r`   r`     s7  € õ Ð%Ý!Ð!õ ŒyÐ/Ñ0Ô0€HØð •B”G—N’N 8Ñ,Ô,ð µ´¸8ÅRÄWÑ1MÔ1Mð Ø%ÐÝ�ŠÐ=¸xÑHÔHÐHØˆõ ŒL˜Ñ"Ô"€EØð Ø"ÐØˆõ ŒL˜Ñ"Ô"€EØð Ø"ÐÝ�ŠÐ;¸UÑCÔCÐCØˆõ %ð ð ˆÝŒ7�>Š>˜$ÑÔð 	¥B¤I¨dµB´GÑ$<Ô$<ð 	Ø!%ÐÝ�KŠKÐ?ÀÑFÔFÐFØˆKˆKˆKøàˆ4r   )z
--cap-dropÚALLú	--cap-addÚDAC_OVERRIDEr—   ÚCHOWNr—   ÚFOWNERz--security-optzno-new-privilegesú--tmpfsz/tmp:rw,nosuid,size=512mr›   z#/var/tmp:rw,noexec,nosuid,size=256mÚ256Ú1gÚ
extra_argsc                 ó8   — t          d„ | pg D ¦   «         ¦  «        S )zÔTrue when user-supplied docker_extra_args already set ``--shm-size``.

    In that case we skip our default so the user's value is unambiguous
    (rather than relying on flag-ordering / last-wins behavior).
    c              3   óv   K  — | ]4}t          |t          ¦  «        o|d k    p|                     d¦  «        V — Œ5dS )ú
--shm-sizez--shm-size=N)r   r   r‚   )rV   Úas     r   ú	<genexpr>z+_extra_args_set_shm_size.<locals>.<genexpr>w  s[   è è € ð ð àõ 	�1•cÑÔÐQ  \Ò 1Ð P°Q·\²\À-Ñ5PÔ5Pðð ð ð ð ð r   )Úany)rž   s    r   Ú_extra_args_set_shm_sizer¥   q  s7   € õ ð ð àÐ" ðñ ô ñ ô ð r   )r›   z/run:rw,noexec,nosuid,size=64m)r›   z/run:rw,exec,nosuid,size=64m)r—   ÚSETUIDr—   ÚSETGIDc                  óÎ  — 	 ddl m}  ddlm} n7# t          $ r*}t
                               d|¦  «         g i g fcY d}~S d}~ww xY w | ¦   «         }|                     d¦  «        pi }|                     d¦  «        sg i g fS |                     ¦   «         }t          |                     dd	¦  «        ¦  «        }|j
        s3d
}|rt          |¦  «        ‚t
                               d|¦  «         g i g fS |j        r|j        s<d|j        › d�}|rt          |¦  «        ‚t
                               d|¦  «         g i g fS |j        �|j                             ¦   «         s<d|j        › d�}|rt          |¦  «        ‚t
                               d|¦  «         g i g fS |                     ¦   «         }|s3d}|rt          |¦  «        ‚t
                               d|¦  «         g i g fS d}	d|j        › d|	› d�g}
d|j        › �}d|j        dz   › �}||||dd|	|	|	|	dddœ}|D ]C}|j        ||j        <   |j        |d|j        › �<   t+          |dd¦  «        pdD ]}|j        ||<   ŒŒDddg}|
||fS ) u  Build the docker mount/env/host args needed to route a sandbox through
    the iron-proxy egress firewall.

    Returns ``(volume_args, env_overrides, host_args)``:

    * ``volume_args`` â€” read-only bind mount of the CA cert into the container
      (extends docker's ``-v`` argv list)
    * ``env_overrides`` â€” env vars to set on container creation: ``HTTPS_PROXY``,
      ``HTTP_PROXY``, ``NO_PROXY`` (loopback only), Python/Node/curl CA-bundle
      paths, and one ``HERMES_PROXY_TOKEN_<NAME>`` per minted mapping
    * ``host_args`` â€” extra ``--add-host`` flags so the container can reach the
      host-side proxy (Linux needs ``host.docker.internal:host-gateway``;
      Docker Desktop populates this automatically on macOS/Windows)

    Returns three empty containers when the proxy is disabled, not yet set up,
    or not currently running.  If ``proxy.enforce_on_docker`` is true and the
    proxy is enabled-but-not-running, raises ``RuntimeError`` so the docker
    backend refuses to start the sandbox.
    r   ©Úload_config©Ú
iron_proxyz%Egress proxy plumbing unavailable: %sNÚproxyÚenabledÚenforce_on_dockerTzvproxy.enabled is true but iron-proxy is not configured. Run `hermes egress setup` to mint tokens and write proxy.yaml.u:   %s â€” continuing without proxy (enforce_on_docker=false).z.iron-proxy is enabled but not running on port z&. Start it with `hermes egress start`.z!iron-proxy CA cert vanished from z0. Re-run `hermes egress setup` to regenerate it.z�iron-proxy is configured but mappings.json is empty or corrupt.  Re-run `hermes egress setup` to mint provider tokens before starting a sandbox.z#/etc/ssl/certs/hermes-egress-ca.crtú-vú:ú:rozhttp://host.docker.internal:r]   z127.0.0.1,localhost,::1Ú1ú--use-openssl-ca)ÚHTTPS_PROXYÚhttps_proxyÚ
HTTP_PROXYÚ
http_proxyÚNO_PROXYÚno_proxyÚREQUESTS_CA_BUNDLEÚSSL_CERT_FILEÚCURL_CA_BUNDLEÚNODE_EXTRA_CA_CERTSÚHERMES_EGRESS_PROXYÚ"_HERMES_EGRESS_NODE_OPTIONS_APPENDÚHERMES_PROXY_TOKEN_Úalias_env_namesrS   z
--add-hostz!host.docker.internal:host-gateway)r+   rª   Úagent.proxy_sourcesr¬   ÚImportErrorr   rg   ÚgetÚ
get_statusr%   Ú
configuredÚRuntimeErrorr   ÚpidÚ	listeningÚtunnel_portÚca_cert_pathÚexistsÚload_mappingsÚproxy_tokenÚreal_env_nameÚgetattr)rª   ÚipÚexcÚcfgÚ	proxy_cfgÚstatusÚenforceÚmsgÚmappingsÚcontainer_caÚvolume_argsÚ	proxy_urlÚplain_http_urlÚenv_overridesÚmÚaliasÚ	host_argss                    r   Ú_egress_proxy_args_for_dockerrâ   �  s†  € ð4Ø1Ð1Ð1Ð1Ð1Ð1Ø8Ð8Ð8Ð8Ð8Ð8Ð8øÝð ð ð Ý�ŠÐ<¸cÑBÔBÐBØ�B˜ˆ|ÐÐÐÐÐÐøøøøðøøøð ˆ+‰-Œ-€CØ—’˜Ñ Ô Ð& B€IØ�=Š=˜Ñ#Ô#ð Ø�B˜ˆ|Ðà�]Š]‰_Œ_€FÝ�9—=’=Ð!4°dÑ;Ô;Ñ<Ô<€GàÔð ðMð 	ð ð 	$Ý˜sÑ#Ô#Ð#Ý�ŠÐSÐUXÑYÔYÐYØ�B˜ˆ|ÐàŒJð ˜6Ô+ð ð3¸VÔ=Oð 3ð 3ð 3ð 	ð ð 	$Ý˜sÑ#Ô#Ð#Ý�ŠÐSÐUXÑYÔYÐYØ�B˜ˆ|ÐàÔÐ"¨&Ô*=×*DÒ*DÑ*FÔ*FÐ"ð=°Ô0Cð =ð =ð =ð 	ð ð 	$Ý˜sÑ#Ô#Ð#Ý�ŠÐSÐUXÑYÔYÐYØ�B˜ˆ|Ðð ×ÒÑ!Ô!€HØð 	ð0ð 	ð
 ð 	$Ý˜sÑ#Ô#Ð#Ý�ŠÐSÐUXÑYÔYÐYØ�B˜ˆ|Ðà8€LØ˜FÔ/ÐCÐC°,ÐCÐCÐCÐD€Kð D¨vÔ/AÐCÐC€IØL°FÔ4FÈÑ4JÐLÐL€Nð
 !Ø Ø$Ø$ð .Ø-ð +Ø%Ø&Ø+ð  #ð /AðK&%ð &%€Mð\ ð 1ð 1ˆØ)*¬ˆ�a”oÑ&ØABÄˆÐ=¨A¬OÐ=Ð=Ñ>Ý˜QÐ 1°2Ñ6Ô6Ð<¸"ð 	1ð 	1ˆEØ#$¤=ˆM˜%Ñ Ð ð	1ð )Ð*MÐN€Ià˜¨	Ð2Ð2s   ‚ �
A™>¸A¾ArÛ   rÞ   rá   c                 óÊ   — | s|s|sdS t          j        | ||dœdd¬¦  «        }t          j        |                     d¦  «        ¦  «                             ¦   «         dd…         S )	z@Stable Docker-label value for the egress posture of a container.Úoff)rÛ   rÞ   rá   T)Ú,r±   )Ú	sort_keysÚ
separatorsrG   Né   )ÚjsonÚdumpsÚhashlibÚsha256ÚencodeÚ	hexdigest)rÛ   rÞ   rá   Úpayloads       r   Ú_egress_reuse_fingerprintrð   .  sƒ   € ð ð ˜=ð ¨Ið ØˆuÝŒjà&Ø*Ø"ð	
ð 	
ð
 Øðñ ô €Gõ Œ>˜'Ÿ.š.¨Ñ1Ô1Ñ2Ô2×<Ò<Ñ>Ô>¸sÀ¸sÔCÐCr   Tr9   c                 óÜ   — 	 ddl m} t           |¦   «                              d¦  «        pi                      d| ¦  «        ¦  «        S # t          t
          f$ r | cY S t          $ r | cY S w xY w)z7Read proxy.enforce_on_docker with fail-safe defaulting.r   r©   r­   r¯   )r+   rª   r%   rÅ   rÄ   rf   r,   )r9   Ú	_load_cfgs     r   Ú_egress_enforce_on_dockerró   B  s“   € ðØ>Ð>Ð>Ð>Ð>Ð>å�Y�Y‘[”[—_’_ WÑ-Ô-Ð3°×8Ò8Ð9LÈgÑVÔVÑWÔWÐWøÝ�Ð!ð ð ð ØˆˆˆÝð ð ð Øˆˆˆðøøøs   ‚AA ÁA+ÁA+Á*A+c                 óL   — h d£}|                      d„ | D ¦   «         ¦  «         |S )zDEnv names that would weaken or bypass enforced egress if overridden.>   r¹   rº   r·   r¸   rµ   r¶   ÚNODE_OPTIONSr¼   r½   r»   r¾   c              3   ón   K  — | ]0}|                      d ¦  «        s|                      d¦  «        ¯,|V — Œ1dS )Ú_API_KEYÚ_TOKENN)Úendswith)rV   r   s     r   r£   z-_critical_egress_env_names.<locals>.<genexpr>V  s\   è è € ð ð ØØ�<Š<˜
Ñ#Ô#ðà'*§|¢|°HÑ'=Ô'=ðØðð ð ð ð ð r   )Úupdate)rÞ   Úcriticals     r   Ú_critical_egress_env_namesrü   N  sN   € ðð ð €Hð ‡O‚Oð ð Ø$ðñ ô ñ ô ð ð €Or   Úcritical_namesc                 óN  ‡— g }h d£}ddh}d}|t          | ¦  «        k     �ri| |         Š|dz   t          | ¦  «        k     r| |dz            nd}‰|v rW‰dk    r|                     ‰¦  «         n5|                     dd¦  «        d         }||v r|                     |¦  «         |d	z  }Œšt          ˆfd
„|D ¦   «         ¦  «        r{‰                     d¦  «        r|                     d¦  «         n„‰                     dd¦  «        d                              dd¦  «        d         }||v r|                     |¦  «         n4‰|v st          ˆfd„|D ¦   «         ¦  «        r|                     ‰¦  «         |dz  }|t          | ¦  «        k     �°it          t          |¦  «        ¦  «        S )zCReturn docker_extra_args entries that can override egress controls.>   ú--envú-eú
--env-filez	--networkz--netr   r]   Ú r  Ú=é   c              3   óH   •K  — | ]}‰                      |› d �¦  «        V — ŒdS ©r  N©r‚   ©rV   ÚflagÚargs     €r   r£   z0_extra_args_egress_collisions.<locals>.<genexpr>q  s5   øè è € Ð@Ð@¨dˆs�~Š~ ˜j˜j˜jÑ)Ô)Ð@Ð@Ð@Ð@Ð@Ð@r   z--env-file=c              3   óH   •K  — | ]}‰                      |› d �¦  «        V — ŒdS r  r  r  s     €r   r£   z0_extra_args_egress_collisions.<locals>.<genexpr>x  s5   øè è € Ð(^Ð(^È¨¯ª¸4¸
¸
¸
Ñ)CÔ)CÐ(^Ð(^Ð(^Ð(^Ð(^Ð(^r   )Úlenr   Úsplitr¤   r‚   Úsortedr   )	rž   rý   Ú
collisionsÚ	env_flagsÚnetwork_flagsÚiÚnxtÚnamer
  s	           @r   Ú_extra_args_egress_collisionsr  ]  sæ  ø€ ð €JØ-Ð-Ð-€IØ  'Ð*€MØ	€AØ
�c�*‰oŒoÒ
Ñ
Ø˜ŒmˆØ#$ q¡5­3¨z©?¬?Ò#:Ð#:ˆj˜˜Q™ÔÐÀˆØ�)ÐÐØ�lÒ"Ð"Ø×!Ò! #Ñ&Ô&Ð&Ð&à—y’y  aÑ(Ô(¨Ô+�Ø˜>Ð)Ð)Ø×%Ò% dÑ+Ô+Ð+Ø�‰FˆAØÝÐ@Ð@Ð@Ð@°iÐ@Ñ@Ô@Ñ@Ô@ð 	#Ø�~Š~˜mÑ,Ô,ð ,Ø×!Ò! ,Ñ/Ô/Ð/Ð/à—y’y  aÑ(Ô(¨Ô+×1Ò1°#°qÑ9Ô9¸!Ô<�Ø˜>Ð)Ð)Ø×%Ò% dÑ+Ô+Ð+øØ�MÐ!Ð!¥SÐ(^Ð(^Ð(^Ð(^ÐP]Ð(^Ñ(^Ô(^Ñ%^Ô%^Ð!Ø×Ò˜cÑ"Ô"Ð"Ø	ˆQ‰ˆð+ �c�*‰oŒoÒ
Ñ
õ, •#�j‘/”/Ñ"Ô"Ð"r   FÚrun_as_host_userÚrun_execc                 ó    — t          |rt          nt          ¦  «        }t          t          ¦  «        |z   }| r|S |t          t          ¦  «        z   S )aI  Return the security/cap/tmpfs args tailored to the privilege mode.

    ``run_exec`` mounts ``/run`` with ``exec`` instead of the hardened
    ``noexec`` default. This is required for s6-overlay images whose ``/init``
    entrypoint execs ``/run/s6/basedir/bin/init`` during startup; see
    ``_image_uses_init_entrypoint``.
    )ÚlistÚ_RUN_TMPFS_EXECÚ_RUN_TMPFS_NOEXECÚ_BASE_SECURITY_ARGSÚ_PRIVDROP_CAP_ARGS)r  r  Ú	run_tmpfsÚargss       r   Ú_build_security_argsr   ~  sO   € õ ¨ÐG•_�_Õ6GÑHÔH€IÝÕ#Ñ$Ô$ yÑ0€DØð ØˆØ•$Õ)Ñ*Ô*Ñ*Ð*r   Úimagec           	      óÆ  — 	 t          j        | dd|ddgdddddt           j        ¬	¦  «        }n@# t           j        t          f$ r'}t
                               d
||¦  «         Y d}~dS d}~ww xY w|j        dk    r;t
                               d||j        |j         	                    ¦   «         ¦  «         dS |j
        pd 	                    ¦   «         }|r|dk    rdS 	 t          j        |¦  «        }n# t          t          f$ r Y dS w xY wt          |t           ¦  «        r|g}t          |t"          ¦  «        r|sdS t!          |d         ¦  «         	                    ¦   «         }|dv S )añ  Return True if ``image``'s entrypoint is the s6-overlay ``/init``.

    Such images (e.g. anything built on ``s6-overlay``, including
    ``hermes-agent:latest``) already provide their own PID-1 init and execute
    ``/run/s6/basedir/bin/init`` during stage0 startup. They are incompatible
    with Docker's ``--init`` (two competing PID-1 inits) and with a ``noexec``
    ``/run`` mount. Detection is best-effort: on any inspection failure we
    return False and keep the hardened defaults.
    r!  r   rF   z{{json .Config.Entrypoint}}TrG   rH   rI   r\   z/Docker: could not inspect entrypoint for %s: %sNFr   z4Docker: image inspect for %s returned %d (stderr=%s)r  Únull)z/initz&/package/admin/s6-overlay/command/init)rb   rc   rd   ÚSubprocessErrorrf   r   rg   rh   ri   r   rj   ré   Úloadsr…   Ú	TypeErrorr   r   r  )r>   r!  r{   ru   r†   Ú
entrypointÚfirsts          r   Ú_image_uses_init_entrypointr)  �  s¥  € ðÝ”Ø˜ )¨UØÐ6ð8àØ °	ØÝÔ$ð
ñ 
ô 
ˆˆøõ Ô&­Ð0ð ð ð Ý�ŠÐFÈÈqÑQÔQÐQØˆuˆuˆuˆuˆuøøøøðøøøð Ô˜AÒÐõ 	�ŠØBØ�6Ô$ f¤m×&9Ò&9Ñ&;Ô&;ñ	
ô 	
ð 	
ð ˆuØŒ=Ð˜B×
%Ò
%Ñ
'Ô
'€CØð �#˜’-�-ØˆuðÝ”Z ‘_”_ˆ
ˆ
øÝ�	Ð"ð ð ð Øˆuˆuðøøøå�*�cÑ"Ô"ð "Ø �\ˆ
Ý�j¥$Ñ'Ô'ð ¨zð ØˆuÝ�
˜1”ÑÔ×$Ò$Ñ&Ô&€EØÐGÐGÐGs'   ‚+. ®A+ÁA&Á&A+ÃC/ Ã/DÄDc                  ó¸   — t          t          dd¦  «        } t          t          dd¦  «        }| �|€dS 	  | ¦   «         › d |¦   «         › �S # t          $ r Y dS w xY w)au  Return ``<uid>:<gid>`` for the current host user, or ``None`` on platforms
    where this is not meaningful (e.g. Windows without posix ids).

    We intentionally read ``os.getuid()``/``os.getgid()`` directly rather than
    going through ``getpass``/``pwd`` so this stays cheap and never raises on
    nameless UIDs (nss lookups can fail inside sandboxed launchers).
    ÚgetuidNÚgetgidr±   )rÑ   r‹   r,   )Úget_uidÚget_gids     r   Ú_resolve_host_user_specr/  º  s{   € õ •b˜( DÑ)Ô)€GÝ•b˜( DÑ)Ô)€GØ€˜'˜/ØˆtðØ�'‘)”)Ð)Ð)˜g˜g™iœiÐ)Ð)Ð)øÝð ð ð Øˆtˆtðøøøs   ´A Á
AÁAÚ_storage_opt_okÚ_cgroup_limits_okc                 óÂ  — t           �t           S t          ¦   «         }|r| sda dS 	 t          j        |ddddddd	d
| ddgdddddt          j        ¬¦  «        }|j        dk    a t           s<t                               d|j        pd 	                    ¦   «         dd…         ¦  «         n4# t          $ r'}da t                               d|¦  «         Y d}~nd}~ww xY wt           S )u/  Probe whether cgroup resource limits work in this environment.

    Tests ``--cpus``, ``--memory`` and ``--pids-limit`` together by spawning
    a throwaway container from *image* (the same sandbox image we are about
    to use for real, so no extra pull and no dependency on a public
    registry). The container runs ``sleep 0`` â€” sleep is guaranteed to be
    present because the sandbox itself uses ``sleep 2h`` as its long-lived
    entrypoint.

    On hosts where the corresponding cgroup controllers are not delegated
    to this process (typical inside unprivileged LXCs and some rootless
    setups) these flags cause every container start to fail with ``OCI
    runtime error`` / exit 126. The probe runs once per process and the
    result â€” which is host-wide, not image-specific â€” is cached.
    NFrc   z--rmú--cpusz0.5ú--memoryÚ64mú--pids-limitÚ32ÚsleepÚ0TrG   rH   é<   r\   r   zó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: %sr  iô  z8Cgroup limit probe failed; disabling resource limits: %s)r1  r`   rb   rc   rd   rh   r   r   ri   r   r,   )r!  r>   r{   ru   s       r   Ú_cgroup_limits_availabler;  Ð  s1  € õ" Ð$Ý Ð å‘”€JØð ˜Uð Ø!ÐØˆuðVÝ”Ø˜ Ø�u˜j¨%°ÀØ�G˜Sð"ð  Ø °	ØÝÔ$ð
ñ 
ô 
ˆð #Ô-°Ò2ÐÝ ð 	Ý�NŠNð#ð
 ”Ð$ "×+Ò+Ñ-Ô-¨d¨s¨dÔ3ñô ð øøõ ð Vð Vð VØ!ÐÝ�ŠÐQÐSTÑUÔUÐUÐUÐUÐUÐUÐUøøøøðVøøøõ Ðs   ¦A?B& Â&
CÂ0CÃCc            	      ó²  — t          ¦   «         } | s+t                               d¦  «         t          dd¬¦  «        ‚	 t	          j        | dgddddd	t          j        ¬
¦  «        }|j        dk    rJt                               d| |j        |j         	                    ¦   «         ¦  «         t          dd¬¦  «        ‚dS # t          $ r/ t                               d| d¬¦  «         t          dd¬¦  «        ‚t          j        $ r/ t                               d| d¬¦  «         t          dd¬¦  «        ‚t          $ r t                               dd¬¦  «         ‚ w xY w)zàBest-effort check that the docker CLI is available before use.

    Reuses ``find_docker()`` so this preflight stays consistent with the rest of
    the Docker backend, including known non-PATH Docker Desktop locations.
    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.zNInstall Docker (or fix PATH) and retry, or switch terminal.backend to 'local'.)Ú
retry_hintÚversionTrG   rH   é   r\   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.zaThe Docker daemon may be down or the current user lacks permission (docker group). Fix and retry.zVDocker backend selected but the resolved docker executable '%s' could not be executed.)Úexc_infozHDocker executable could not be executed. Check your Docker installation.z)Repair the Docker installation and retry.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.znStart the Docker daemon (e.g. `systemctl start docker` or launch Docker Desktop), then retry the same command.z4Unexpected error while checking Docker availability.N)r`   r   Úerrorr   rb   rc   rd   rh   ri   r   ÚFileNotFoundErrorre   r,   )r>   r{   s     r   Ú_ensure_docker_availablerC    sø  € õ ‘”€JØð 
Ý�Šð ñ	
ô 	
ð 	
õ
 )ðKð/ð	
ñ 
ô 
ð 	
ð7Ý”Ø˜Ð#ØØ °	ØÝÔ$ð
ñ 
ô 
ˆðN Ô Ò!Ð!Ý�LŠLð,àØÔ!Ø”×#Ò#Ñ%Ô%ñô ð õ -ð2ð@ð	ñ ô ð ð "Ð!øõA ð 

ð 

ð 

Ý�ŠðàØð	 	ñ 	
ô 	
ð 	
õ )ØVØBð
ñ 
ô 
ð 	
õ Ô$ð 
ð 
ð 
Ý�Šð4àØð	 	ñ 	
ô 	
ð 	
õ )ØVðGð
ñ 
ô 
ð 	
õ ð ð ð Ý�ŠØBØð 	ñ 	
ô 	
ð 	
ð 	ðøøøs   ½'B; Â;BEc            %       ó�  ‡ — e Zd ZdZdZdeedf         fd„Zdddddd	d
dddddd	d	ddefdedede	de
de	de	dedededee         dz  dedz  dedee         dededededef$ˆ fd„Zdee         fd„Zdeeef         fd „Zdeeeef         ee         f         fd!„Zdeee         eedf         f         fd"„Zdee         fd#„Zd	d$dd%œd&ed'ede	d(edz  dej        f
d)„Zd*Zd+edefd,„Zdefd-„Zd=d/ededefˆ fd0„Zedefd1„¦   «         Zd2edee         fd3„Zd4ed5ed6edeeeef                  fd7„Z d	d8œd9efd:„Z!d>de
defd<„Z"ˆ xZ#S )?ÚDockerEnvironmentuñ  Hardened Docker container execution with resource limits and persistence.

    Security: all capabilities dropped, no privilege escalation, PID limits,
    size-limited tmpfs for scratch dirs. The container itself is the security
    boundary â€” the filesystem inside is writable so agents can install packages
    (pip, npm, apt) as needed. Writable workspace via tmpfs or bind mounts.

    Persistence: when enabled, bind mounts preserve /workspace and /root
    across container restarts.
    Tr   .c                 ó*   — t          | j        ¦  «        S )z@Keep explicit docker_forward_env values out of shared snapshots.)ÚtupleÚ_forward_env©Úselfs    r   Ú,_additional_profile_scoped_passthrough_namesz>DockerEnvironment._additional_profile_scoped_passthrough_namesb  s   € å�TÔ&Ñ'Ô'Ð'r   ú/rootr:  r   Fr9   Nr!  ÚcwdrO   ÚcpuÚmemoryÚdiskÚpersistent_filesystemÚtask_idÚvolumesr   r   ÚnetworkÚhost_cwdÚauto_mount_cwdr  rž   Úpersist_across_processesÚshm_sizec           
      ó!  •‡ ‡Q‡R‡S‡T‡U— |dk    rd}t          ¦   «                              ||¬¦  «         |‰ _        |‰ _        d‰ _        |‰ _        t          |
¦  «        ‰ _        t          |¦  «        ‰ _	        d‰ _
        d ‰ _        i ‰ _        d‰ _        d‰ _        d‰ _        g ‰ _        t"                               d|	¦  «         |	�2t'          |	t(          ¦  «        st"                               d|	¦  «         g }	t-          ¦   «          g }|d	k    r3t/          |¦  «        r$|                     d
t3          |¦  «        g¦  «         |d	k    r)t/          |¦  «        r|                     d|› d�g¦  «         t/          |¦  «        r|                     dt4          g¦  «         t3          |pd¦  «                             ¦   «         }|r,|dk    r&t9          |¦  «        s|                     d|g¦  «         |d	k    rZt:          j        dk    rJ‰                      ¦   «         r|                     dd|› d�g¦  «         nt"                               d¦  «         |s|                      d¦  «         d	dl!m"} g }d}|	pg D ]‡}t'          |t2          ¦  «        st"                               d|¦  «         Œ3|                     ¦   «         }|sŒJd|v r|                     d|g¦  «         d|v rd}Œlt"                               d|¦  «         Œˆ|r<tF          j$         %                    tF          j$         &                    |¦  «        ¦  «        nd}|o0tO          |¦  «        o!tF          j$         (                    |¦  «        o| }|r<|r:tF          j$         (                    |¦  «        st"           )                    d|¦  «         d ‰ _*        d ‰ _+        g }‰ j        r· |¦   «         dz  |z  }t3          |dz  ¦  «        ‰ _+        tG          j,        ‰ j+        d¬¦  «         |                     d‰ j+        › d �g¦  «         |sS|sQt3          |d!z  ¦  «        ‰ _*        tG          j,        ‰ j*        d¬¦  «         |                     d‰ j*        › d�g¦  «         n2|s|s|                     d"d#g¦  «         |                     g d$¢¦  «         |r%t"                               d%|¦  «         d|› d�g|¢}n|rt"           )                    d&¦  «         	 d	d'l-m.}m/}m0}  |¦   «         D ]È} tc          | d(         ¦  «        }!|! 2                    ¦   «         rt"                               d)|!¦  «         ŒG|! 3                    ¦   «         st"                               d*|!¦  «         Œw|                     d| d(         › d| d+         › d,�g¦  «         t"                               d-| d(         | d+         ¦  «         ŒÉ |¦   «         D ]˜}"tc          |"d(         ¦  «        }!|! 2                    ¦   «         st"                               d.|!¦  «         ŒG|                     d|"d(         › d|"d+         › d,�g¦  «         t"                               d/|"d(         |"d+         ¦  «         Œ™ |¦   «         D ]˜}#tc          |#d(         ¦  «        }!|! 2                    ¦   «         st"                               d0|!¦  «         ŒG|                     d|#d(         › d|#d+         › d,�g¦  «         t"                               d1|#d(         |#d+         ¦  «         Œ™n2# th          $ r%}$t"           )                    d2|$¦  «         Y d }$~$nd }$~$ww xY wtk          ¦   «         \  }%ŠU}&tm          |%‰U|&¦  «        }'to          ¦   «         }(tq          ‰U¦  «        ŠR‰Ur^ts          ˆRfd3„‰ j        D ¦   «         ¦  «        })|)r<d4|)› d5|(rd6nd7› d8�}*|(rtu          |*› d9�¦  «        ‚t"                               d:|*¦  «         |                     |%¦  «         ‰U�rO	 d	d;l;m<}+  |+¦   «          =                    d<¦  «        pi },n]# t|          t~          f$ r i },Y nHth          $ r<}-	 d	d l@}.n# t|          $ r ‚ w xY wt"                               d=|-¦  «         i },Y d }-~-nd }-~-ww xY wtO          |, =                    d>d¦  «        ¦  «        }(h d?£}/tƒ          ¦   «         ŠS	 d	d@lBmC}0 dA„ |0 D                    ¦   «         D ¦   «         ŠSn# th          $ r Y nw xY w|/‰Sz  }1ts          ˆSˆUˆ fdB„|1D ¦   «         ¦  «        }2|2r<dC|2› d5|(rd6nd7› d8�}*|(rtu          |*› dD�¦  «        ‚t"                               dE|*¦  «         	 d	d;l;m<}3 tO           |3¦   «          =                    d<¦  «        pi  =                    d>d¦  «        ¦  «        }4n&# t|          t~          f$ r d}4Y nth          $ r d}4Y nw xY w|4r,‰Ur*t‹          ‰ j	        ¦  «        }5|5 F                    ‰U¦  «         n)t‹          ‰U¦  «        }5|5 F                    ‰ j	        ¦  «         |5 G                    dFd ¦  «        }6|6rã|5 =                    dGd¦  «        }7|7 H                    ¦   «         }8dHdIhŠQ|6                     ¦   «         ŠT‰T‰Qv r<ˆQˆTfdJ„|8D ¦   «         }9|9rt"                               dK|9‰T¦  «         ˆQˆTfdL„|8D ¦   «         }8‰T|8vr|8                      ‰T¦  «         dM I                    |8¦  «                             ¦   «         |5dG<   |5dG         s|5 G                    dGd ¦  «         g }:ts          |5¦  «        D ]$};|:                     dN|;› dO|5|;         › �g¦  «         Œ%g }<|rJt•          ¦   «         }=|=� dP|=g}<t"                               dQ|=¦  «         nt"                               dR¦  «         t—          ¦   «         pd‰ _L        t›          ‰ jL        |¦  «        }>|>rt"                               dS|¦  «         t�          |otO          |<¦  «        |>¬T¦  «        }?t"                               dU|¦  «         g }@|pg D ]H}At'          |At2          ¦  «        st"                               dV|A¦  «         Œ3|@                      |A¦  «         ŒI‰UrNtŸ          |@‰R¦  «        }B|Br<dW|B› d5|(rd6nd7› d8�}*|(rtu          |*› dX�¦  «        ‚t"                               dY|*¦  «         |?|<z   |z   |z   |&z   |z   |:z   |@z   }Ct"                               dZ|C¦  «         d[t¡          jQ        ¦   «         jR        d d\…         › �}Dt§          t©          ¦   «         ¦  «        }Et§          |¦  «        }Fd]d^d]d_|F› �d]d`|E› �d]tª          › dO|'› �g}G|‰ _        |D‰ _        |>‰ _        |C‰ _        dadbdc|Fdd|Etª          |'i‰ _        d}H|�rª‰  V                    |F|E|'¦  «        }I|I�Ê|I\  }J}Kd}Ld }M|s‰  W                    |J¦  «        }M|Mdek    }L|Lr¢t"                               df|Jd dg…         |Mpdh|F|E¦  «         	 t±          jY        ‰ jL        didj|Jgdddkdldmdt°          jZ        ¬n¦  «         nG# t°          j[        t~          f$ r.}$t"                               do|Jd dg…         |$¦  «         Y d }$~$nd }$~$ww xY wd }I|I�Å|I\  }J}K|J‰ _        |Kdpk    r„	 t±          jY        ‰ jL        dq|Jgdddkdldmdt°          jZ        ¬n¦  «         nT# t°          j\        t°          j[        f$ r6}$t"                               dr|Jd dg…         |K|$¦  «         d ‰ _        Y d }$~$nd }$~$ww xY w‰ j        r(t"                               ds|Jd dg…         |F|E|K¦  «         d}H|H�s-|>rg ndtg}N‰ jL        dudvg|N¢dw‘|D‘|G¢dx‘|‘|C¢|‘dy‘dz‘}Ot"           )                    d{dM I                    |O¦  «        ¦  «         	 t±          jY        |Odddkdld|dt°          jZ        ¬n¦  «        }Pnk# t°          j\        t°          j[        f$ rM}$t"                               d}|D|$¦  «         t±          jY        ‰ jL        didj|Dgdd~t°          jZ        ¬¦  «         ‚ d }$~$ww xY w|Pj]                             ¦   «         ‰ _        t"                               d€|D‰ j        d dg…         ¦  «         ‰  ^                    ¦   «         ‰ __        ‰  `                    ¦   «          d S )�NÚ~rL  )rM  rO   FrS   r  zDockerEnvironment volumes: %sz'docker_volumes config is not a list: %rr   r3  r4  rß   r6  r9  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)Úget_sandbox_dirz'Docker volume entry is not a string: %rr±   r°   z:/workspaceTz*Docker volume '%s' missing colon, skippingz@Skipping docker cwd mount: host_cwd is not a valid directory: %sr@   Úhome)Úexist_okz:/rootÚ	workspacer›   z/workspace:rw,exec,size=10g)r›   z/home:rw,exec,size=1gr›   z/root:rw,exec,size=1gz.Mounting configured host cwd to /workspace: %szDSkipping docker cwd mount: /workspace already mounted by user config)Úget_credential_file_mountsÚget_skills_directory_mountÚget_cache_directory_mountsÚ	host_pathug   Docker: skipping credential mount â€” source is a directory (likely Docker-in-Docker auto-creation): %su:   Docker: skipping credential mount â€” source not found: %sÚcontainer_pathr²   z$Docker: mounting credential %s -> %su?   Docker: skipping skills mount â€” source is not a directory: %sz$Docker: mounting skills dir %s -> %su>   Docker: skipping cache mount â€” source is not a directory: %sz#Docker: mounting cache dir %s -> %sz1Docker: could not load credential file mounts: %sc              3   ó$   •K  — | ]
}|‰v ¯|V — Œd S ©NrS   )rV   r   Ú_critical_egress_namess     €r   r£   z-DockerEnvironment.__init__.<locals>.<genexpr>P  s7   øè è € ð )ð )Ø°CÐ;QÐ4QÐ4Q�Ð4QÐ4QÐ4QÐ4Qð)ð )r   z@docker_forward_env would inject real egress-protected variables z; enforce_on_docker is r®   Údisabledú.zi  Remove these names from docker_forward_env or disable enforce_on_docker to opt out of egress isolation.zC%s  Explicit docker_forward_env values will override egress tokens.r©   r­   z:Could not read proxy config for egress collision check: %sr¯   >
   r¹   rº   r·   r¸   rµ   r¶   r¼   r½   r»   r¾   r«   c                 ó   — h | ]	}|j         ’Œ
S rS   )rÐ   )rV   rß   s     r   ú	<setcomp>z-DockerEnvironment.__init__.<locals>.<setcomp>˜  s'   € ð +ð +ð +Ø()�A”Oð+ð +ð +r   c              3   ó¢   •K  — | ]I}|‰j         v r>|‰vs‰j         |         ‰|         k    r#|‰v s|‰v r‰j         |         ‰|         k    ¯E|V — ŒJd S rg  )Ú_env)rV   ÚkÚ_critical_provider_keysÚegress_env_overridesrJ  s     €€€r   r£   z-DockerEnvironment.__init__.<locals>.<genexpr>ž  s‘   øè è € ð !ð !ØØ˜œ	�>�>àÐ1Ð1Ð1Ø”y ”|Ð';¸AÔ'>Ò>Ð>ð Ð0Ð0Ð0ØÐ1Ð1Ð1Ø œI aœLÐ,@ÀÔ,CÒCÐCð ð DÐCÐCÐCð!ð !r   z;docker_env in config.yaml overrides egress-proxy variables z`  Remove these keys from docker_env or disable enforce_on_docker to opt out of egress isolation.zX%s  Falling back to docker_env values; sandbox traffic will NOT route through the proxy.rÀ   rõ   r´   z--use-bundled-cac                 ó(   •— g | ]}|‰v ¯|‰k    ¯|‘ŒS rS   rS   ©rV   ÚtÚ_CA_MODE_FLAGSÚappend_tokens     €€r   rX   z.DockerEnvironment.__init__.<locals>.<listcomp>í  s/   ø€ ÐcÐcÐc ¸¸nÐ9LÐ9LÐQRÐVbÒQbÐQb˜1ÐQbÐQbÐQbr   zOverriding conflicting NODE_OPTIONS CA-mode flag(s) %s with egress-required %s to keep Node routed through the egress CA store.c                 ó(   •— g | ]}|‰vs|‰k    ¯|‘ŒS rS   rS   rs  s     €€r   rX   z.DockerEnvironment.__init__.<locals>.<listcomp>ô  s/   ø€ Ð"nÐ"nÐ"n¨ÀÈ.ÐAXÐAXÐ\]ÐamÒ\mÐ\m 1Ð\mÐ\mÐ\mr   Ú r   r  z--userz)Docker: running container as host user %szƒdocker_run_as_host_user is enabled but this platform does not expose POSIX uid/gid; container will start as its image default user.ug   Docker: image %s uses /init (s6-overlay) as entrypoint â€” skipping --init and mounting /run with exec.)r  zDocker volume_args: %sz/Ignoring non-string docker_extra_args entry: %rz7docker_extra_args would override egress-proxy controls zP  Remove these args or disable enforce_on_docker to opt out of egress isolation.z2%s  Extra Docker args may bypass egress isolation.zDocker run_args: %súhermes-é   ú--labelzhermes-agent=1zhermes-task-id=zhermes-profile=zhermes-agentr³   úhermes-task-idúhermes-profileÚnoneuœ   Existing container %s has NetworkMode=%s but docker_network=false requests an air-gapped container â€” removing it and starting fresh (task=%s, profile=%s).r^   r/   rY   rZ   rG   rH   r[   rJ   z,Failed to remove mismatched container %s: %sÚrunningÚstartu[   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)ú--initrc   ú-dú--nameú-wr8  ÚinfinityzStarting container: %séx   z<docker run failed for %s, cleaning up orphaned container: %sr€   ©rK   rO   rQ   zStarted container %s (%s))aÚsuperÚ__init__Ú_persistentÚ_persist_across_processesÚ_session_scopedÚ_task_idr   rH  r'   rn  Ú_init_unset_passthrough_namesÚ_container_idÚ_labelsÚ_imageÚ_container_nameÚ_image_uses_s6_initÚ_all_run_argsr   rr   r   r  r   rC  r;  ra   r   Ú_DEFAULT_PIDS_LIMITr   r¥   ÚsysÚplatformÚ_storage_opt_supportedr   Útools.environments.baser]  r‹   r�   ÚabspathÚ
expanduserr%   Úisdirrg   Ú_workspace_dirÚ	_home_dirÚmakedirsÚtools.credential_filesra  rb  rc  r   Úis_dirÚis_filer,   râ   rð   ró   rü   r  rÈ   r+   rª   rÅ   rÄ   rf   Úyamlr   rÃ   r¬   rÎ   r!   rú   Úpopr  Újoinr/  r`   Ú_docker_exer)  r   r  ÚuuidÚuuid4Úhexr5   r;   Ú_EGRESS_LABEL_KEYÚ_find_reusable_containerÚ_container_network_moderb   rc   rd   re   ÚCalledProcessErrorrj   Ú_build_init_env_argsÚ_init_env_argsÚinit_session)WrJ  r!  rM  rO   rN  rO  rP  rQ  rR  rS  r   r   rT  rU  rV  r  rž   rW  rX  Úresource_argsÚshmr]  rÛ   Úworkspace_explicitly_mountedÚvolÚhost_cwd_absÚbind_host_cwdÚwritable_argsÚsandboxra  rb  rc  Úmount_entryÚsrcÚskills_mountÚcache_mountru   Úegress_volume_argsÚegress_host_argsÚegress_labelÚ_enforce_egressÚ_forward_collisionsÚ_msgÚ_load_cfg_for_collisionÚ
_proxy_cfgÚ_er£  Ú_critical_proxy_controlÚ_ip_for_mappingsÚ	_criticalÚ_collisionsÚ_load_cfg_for_precedenceÚ_enforce_egress_mergeÚ
merged_envÚ_egress_node_appendÚexisting_nodeÚexisting_tokensÚdroppedÚenv_argsr   Ú	user_argsÚ	user_specÚimage_uses_s6_initÚsecurity_argsÚvalidated_extrar
  Ú_extra_collisionsÚall_run_argsÚcontainer_nameÚprofile_nameÚ
task_labelÚ
label_argsÚreusedÚexistingr}   ÚstateÚmode_mismatchÚactual_modeÚ	init_argsÚrun_cmdr{   ru  rh  rp  rv  rq  Ú	__class__sW   `                                                                                @@@@@€r   r‰  zDockerEnvironment.__init__f  s2  øøøøøøø€ ð* �#Š:ˆ:ØˆCÝ‰Œ×Ò˜S¨'ÐÑ2Ô2Ð2Ø0ˆÔØ)AˆÔ&ð  %ˆÔØˆŒÝ8¸ÑEÔEˆÔÝ'¨Ñ,Ô,ˆŒ	Ø>@ˆÔ*Ø,0ˆÔØ')ˆŒØˆŒØ$&ˆÔØ).ˆÔ Ø(*ˆÔÝ�ŠÐ3°WÑ=Ô=Ð=àÐ¥z°'½4Ñ'@Ô'@ÐÝ�NŠNÐDÀgÑNÔNÐNØˆGõ 	!Ñ"Ô"Ð"ð ˆØ�Š7ˆ7Õ/°Ñ6Ô6ˆ7Ø× Ò  (­C°©H¬HÐ!5Ñ6Ô6Ð6Ø�AŠ:ˆ:Õ2°5Ñ9Ô9ˆ:Ø× Ò  *°¨l¨l¨lÐ!;Ñ<Ô<Ð<Ý# EÑ*Ô*ð 	HØ× Ò  .Õ2EÐ!FÑGÔGÐGõ �(�.˜bÑ!Ô!×'Ò'Ñ)Ô)ˆØð 	6�3˜#’:�:Õ&>¸zÑ&JÔ&J�:Ø× Ò  ,°Ð!4Ñ5Ô5Ð5Ø�!Š8ˆ8�œ¨Ò0Ð0Ø×*Ò*Ñ,Ô,ð Ø×$Ò$ o°¸t°°°Ð%GÑHÔHÐHÐHå—’ðeñô ð ð ð 	3Ø× Ò Ð!1Ñ2Ô2Ð2ð
 	<Ð;Ð;Ð;Ð;Ð;ð ˆØ',Ð$Ø�M˜rð 	Rð 	RˆCÝ˜c¥3Ñ'Ô'ð Ý—’ÐHÈ#ÑNÔNÐNØØ—)’)‘+”+ˆCØð ØØ�cˆzˆzØ×"Ò" D¨# ;Ñ/Ô/Ð/Ø  CÐ'Ð'Ø37Ð0øå—’ÐKÈSÑQÔQÐQÐQàHPÐX•r”w—’¥r¤w×'9Ò'9¸(Ñ'CÔ'CÑDÔDÐDÐVXˆàð 1Ý�\Ñ"Ô"ð1å”—’˜lÑ+Ô+ð1ð 1Ð0ð	 	ð ð 	g˜hð 	g­r¬w¯}ª}¸\Ñ/JÔ/Jð 	gÝ�LŠLÐ[Ð]eÑfÔfÐfà-1ˆÔØ(,ˆŒØˆØÔð 	Ø%�oÑ'Ô'¨(Ñ2°WÑ<ˆGÝ  ¨6Ñ!1Ñ2Ô2ˆDŒNÝŒK˜œ°Ð6Ñ6Ô6Ð6Ø× Ò Ø˜œÐ/Ð/Ð/ð"ñ ô ð ð !ð Ð)Eð Ý&)¨'°KÑ*?Ñ&@Ô&@�Ô#Ý”˜DÔ/¸$Ð?Ñ?Ô?Ð?Ø×$Ò$Ø˜TÔ0Ð=Ð=Ð=ð&ñ ô ð øð !ð Ð)Eð Ø×$Ò$ØÐ<ð&ñ ô ð ð × Ò ð "ð "ð "ñ ô ð ð
 ð 	aÝ�KŠKÐHÈ,ÑWÔWÐWØ LÐ!=Ð!=Ð!=ÐLÀÐLˆKˆKØ)ð 	aÝ�LŠLÐ_Ñ`Ô`Ð`ðL	Qðð ð ð ð ð ð ð ð ð ð  :Ð9Ñ;Ô;ð ð �Ý˜; {Ô3Ñ4Ô4�Ø—:’:‘<”<ð 	õ —N’NðFàñô ð ð
 Ø—{’{‘}”}ð Ý—N’NØTÐVYñô ð ð Ø×"Ò"ØØ" ;Ô/ÐTÐT°+Ð>NÔ2OÐTÐTÐTð$ñ ô ð õ —’Ø:Ø Ô,ØÐ 0Ô1ñô ð ð ð !;Ð :Ñ <Ô <ð ð �Ý˜<¨Ô4Ñ5Ô5�Ø—z’z‘|”|ð Ý—N’NØYØñô ð ð Ø×"Ò"ØØ# KÔ0ÐVÐV°<Ð@PÔ3QÐVÐVÐVð$ñ ô ð õ —’Ø:Ø  Ô-Ø Ð!1Ô2ñô ð ð ð  :Ð9Ñ;Ô;ð ð �Ý˜; {Ô3Ñ4Ô4�Ø—z’z‘|”|ð Ý—N’NØXØñô ð ð Ø×"Ò"ØØ" ;Ô/ÐTÐT°+Ð>NÔ2OÐTÐTÐTð$ñ ô ð õ —’Ø9Ø Ô,ØÐ 0Ô1ñô ð ð ðøõ" ð 	Qð 	Qð 	QÝ�LŠLÐLÈaÑPÔPÐPÐPÐPÐPÐPÐPøøøøð	Qøøøõ *Ñ+Ô+ñ 	CÐÐ0Ð2Bõ 1ØÐ 4Ð6Fñ
ô 
ˆõ 4Ñ5Ô5ˆÝ!;Ð<PÑ!QÔ!QÐØð 	Ý"(ð )ð )ð )ð )Ø#Ô0ð)ñ )ô )ñ #ô #Ðð #ð ðGØ!4ðGð Gà$3ÐC�y�y¸ðGð Gð Gð ð
 #ð Ý&Øð Wð Wð Wñô ð õ —’ØYØñô ð ð 	×ÒÐ-Ñ.Ô.Ð.ð$  ñ J	ð ØTÐTÐTÐTÐTÐTØ5Ð5Ñ7Ô7×;Ò;¸GÑDÔDÐJÈ�
�
øÝ¥Ð)ð  ð  ð  Ø�
�
�
Ýð  ð  ð  ðØ�K�K�K�KøÝ"ð ð ð Øðøøøå—’ØPØñô ð ð  �
�
�
�
�
�
øøøøð øøøõ # :§>¢>Ð2EÀtÑ#LÔ#LÑMÔMˆOð'ð 'ð 'Ð#õ 14±´Ð#ðØNÐNÐNÐNÐNÐNð+ð +Ø-=×-KÒ-KÑ-MÔ-Mð+ñ +ô +Ð'Ð'øõ ð ð ð Ø�ðøøøà/Ð2IÑIˆIÝ ð !ð !ð !ð !ð !ð !Ø$ð!ñ !ô !ñ ô ˆKð" ð ðGØ!,ðGð Gà$3ÐC�y�y¸ðGð Gð Gð ð
 #ð Ý&Øð %ð %ð %ñô ð õ
 —’ð8Ø9=ñô ð ð
	)ØQÐQÐQÐQÐQÐQÝ$(Ø)Ð)Ñ+Ô+×/Ò/°Ñ8Ô8Ð>¸Bß’Ð(¨$Ñ/Ô/ñ%ô %Ð!Ð!øõ �WÐ%ð 	)ð 	)ð 	)Ø$(Ð!Ð!Ð!Ýð 	)ð 	)ð 	)à$(Ð!Ð!Ð!ð	)øøøð !ð 	)Ð%9ð 	)Ý˜dœi™œˆJØ×ÒÐ2Ñ3Ô3Ð3Ð3åÐ2Ñ3Ô3ˆJØ×Ò˜dœiÑ(Ô(Ð(ð )ŸnšnØ0°$ñ
ô 
Ðð ð 	5Ø&ŸNšN¨>¸2Ñ>Ô>ˆMØ+×1Ò1Ñ3Ô3ˆOð 1Ð2DÐEˆNØ.×4Ò4Ñ6Ô6ˆLØ˜~Ð-Ð-ØcÐcÐcÐcÐc oÐcÑcÔc�Øð Ý—N’Nð+à,3°\ñô ð ð
 #oÐ"nÐ"nÐ"nÐ"n¨oÐ"nÑ"nÔ"n�ð  ?Ð2Ð2Ø×&Ò& |Ñ4Ô4Ð4Ø),¯ª°/Ñ)BÔ)B×)HÒ)HÑ)JÔ)JˆJ�~Ñ&Ø˜nÔ-ð 5Ø—’˜~¨tÑ4Ô4Ð4àˆÝ˜*Ñ%Ô%ð 	@ð 	@ˆCØ�OŠO˜T cÐ#=Ð#=¨J°s¬OÐ#=Ð#=Ð>Ñ?Ô?Ð?Ð?ð  "ˆ	Øð 
	Ý/Ñ1Ô1ˆIØÐ$Ø% yÐ1�	Ý—’ÐGÈÑSÔSÐSÐSå—’ð*ñô ð õ '™=œ=Ð4¨HˆÔõ 9¸Ô9IÈ5ÑQÔQÐØð 	Ý�KŠKð?àñô ð õ
 -ØÐ0¥ i¡¤Ø'ð
ñ 
ô 
ˆõ
 	�ŠÐ,¨kÑ:Ô:Ð:ð ˆØÐ$ "ð 	(ð 	(ˆCÝ˜c¥3Ñ'Ô'ð Ý—’ÐPÐRUÑVÔVÐVØØ×"Ò" 3Ñ'Ô'Ð'Ð'Øð 	Ý =ØÐ!7ñ!ô !Ðð !ð ðGØ(ðGð Gà$3ÐC�y�y¸ðGð Gð Gð ð
 #ð Ý&Øð :ð :ð :ñô ð õ —’ØHÈ$ñô ð ð
 Øñàñð ñð ñ	ð
 ñð ñð ñð 	õ 	�ŠÐ)¨<Ñ8Ô8Ð8ð :¥4¤:¡<¤<Ô#3°B°Q°BÔ#7Ð9Ð9ˆõ -Õ-EÑ-GÔ-GÑHÔHˆÝ*¨7Ñ3Ô3ˆ
àÐ'ØÐ5¨Ð5Ð5ØÐ7¨Ð7Ð7ØÕ+Ð<Ð<¨lÐ<Ð<ð	
ˆ
ð ˆŒØ-ˆÔØ#5ˆÔ Ø)ˆÔð ˜CØ˜jØ˜lÝ˜|ð	
ˆŒð$ ˆØ#ñ D	"Ø×4Ò4Ø˜L¨,ñô ˆHð Ð#Ø&.Ñ#�˜eð !&�Ø"�Øð :Ø"&×">Ò">¸|Ñ"LÔ"L�KØ$/°6Ò$9�MØ ð $Ý—N’Nð1ð % S b SÔ)¨;Ð+C¸)Ø" Lñô ð ð
mÝ"œØ!Ô-¨t°T¸<ÐHØ+/Ø!%°À	Ø$&Ø"'Ý",Ô"4ðñ ô ð ð øõ 'Ô5µwÐ?ð mð mð mÝŸšÐ'UÐWcÐdgÐegÐdgÔWhÐjkÑlÔlÐlÐlÐlÐlÐlÐløøøøðmøøøà#�HØÐ#Ø&.Ñ#�˜eØ%1�Ô"Ø˜IÒ%Ð%ð2Ý"œØ!Ô-¨w¸ÐEØ+/Ø!%°À	Ø$&Ø"&Ý",Ô"4ðñ ô ð ð øõ 'Ô9½:Ô;TÐUð 2ð 2ð 2ÝŸšðHà(¨¨"¨Ô-¨u°añô ð ð
 .2˜Ô*Ð*Ð*Ð*Ð*Ð*øøøøð2øøøð Ô%ð "Ý—K’KØTØ$ S b SÔ)¨:°|ÀUñô ð ð "�Fàñ ,	^ð 1Ð@˜˜°x°jˆIàÔ  %¨ð	àð	ð ð	ð )ð	ð ð		ð
 ð	ð
 ð	ð ð	ð ð	ð ð	ð $ð	ˆGõ �LŠLÐ1°3·8²8¸GÑ3DÔ3DÑEÔEÐEðÝ#œØØ#'Ø¨¸	ØØÝ$Ô,ðñ ô ��øõ Ô1µ:Ô3LÐMð ð ð õ —’ØRØ" Añô ð õ ”ØÔ% t¨T°>ÐBØ#'°Ý$Ô,ðñ ô ð ð
 øøøøð#øøøð$ "(¤×!4Ò!4Ñ!6Ô!6ˆDÔÝ�KŠKÐ3°^ÀTÔEWÐX[ÐY[ÐX[ÔE\Ñ]Ô]Ð]ð #×7Ò7Ñ9Ô9ˆÔð 	×ÒÑÔÐÐÐsÁ   Ó-H#\ Ü
] Ü\;Ü;] ß<%`" à"a<à7	a<áaáa7áaá a7á7a<â5$c ã
c'ã&c'åAf æf5æ'f5æ4f5÷'/x øyø-$yùyù5.z$ ú${5ú?,{0û0{5ý>&~% þ%A@ÿ AA@Á@A@c                 ój  — |                       ¦   «         \  }}t          | j        ¦  «        }|                     |¦  «         |D ]}|                     |d¦  «         Œt          t          |¦  «        ¦  «        | _        g }t          |¦  «        D ]$}|                     d|› d||         › �g¦  «         Œ%|S )zçBuild -e KEY=VALUE args for injecting host env vars into init_session.

        These are used during init_session() so that export -p captures the
        configured environment and the current profile's forwarded values.
        Nr   r  )	Ú_resolve_passthrough_envr!   rn  rú   r¤  rG  r  rŽ  ra   )rJ  Úpassthrough_envÚunset_namesÚexec_envr  r  r   s          r   r®  z&DockerEnvironment._build_init_env_argsö  sÄ   € ð (,×'DÒ'DÑ'FÔ'FÑ$ˆ˜Ý#'¨¬	¡?¤?ˆØ�Š˜Ñ(Ô(Ð(Øð 	%ð 	%ˆDØ�LŠL˜˜tÑ$Ô$Ð$Ð$Ý-2µ6¸+Ñ3FÔ3FÑ-GÔ-GˆÔ*àˆÝ˜(Ñ#Ô#ð 	:ð 	:ˆCØ�KŠK˜ #Ð7Ð7¨°¬Ð7Ð7Ð8Ñ9Ô9Ð9Ð9Øˆr   c                 ó6   — |                       ¦   «         d         S )zBResolve forwarded host variables through the active profile scope.r   )ræ  rI  s    r   Ú_build_passthrough_envz(DockerEnvironment._build_passthrough_env  s   € à×,Ò,Ñ.Ô.¨qÔ1Ð1r   c                 óv  — i }t          | j        ¦  «        }t          ¦   «         }d}d}d„ }	 ddlm}m} ddlm}m}	 |} |	¦   «         }t           |¦   «         ¦  «        }n# t          $ r Y nw xY wd„ |D ¦   «         }
||
t          z
  z  }|rt          ¦   «         ni }t          ¦   «         }t          |¦  «        D ]}}t          j        |¦  «        p|                     |¦  «        }|� |||¦  «        }|�|||<   ŒA|r: ||¦  «        s/t                               |¦  «        r|                     |¦  «         Œ~||fS )z<Return forwarded values and scoped names that must be unset.NFc                 ó   — dS )NFrS   )Ú_names    r   ú<lambda>z<DockerEnvironment._resolve_passthrough_env.<locals>.<lambda>  s   €  e€ r   r   )Úget_all_passthroughÚresolve_passthrough_value)Ú_is_global_envÚis_multiplex_activec                 ó0   — h | ]}t          |¦  «        °|’ŒS rS   )r	   )rV   ro  s     r   rl  z=DockerEnvironment._resolve_passthrough_env.<locals>.<setcomp>$  s6   € ð 
ð 
ð 
ØÕ/IÈ!Ñ/LÔ/Lð
Øð
ð 
ð 
r   )r   rH  Útools.env_passthroughrð  rñ  Úagent.secret_scoperò  ró  r,   r   r-   r  r‹   rŒ   rÅ   r   Ú	fullmatchr   )rJ  ré  Úexplicit_forward_keysÚpassthrough_keysrñ  Úmultiplex_activeÚis_global_envrð  rò  Ú_is_multiplex_activeÚ_implicit_forwardÚforward_keysÚ
hermes_envrè  r   r&   s                   r   ræ  z*DockerEnvironment._resolve_passthrough_env  sÊ  € à#%ˆÝ # DÔ$5Ñ 6Ô 6ÐÝ%(¡U¤UÐØ$(Ð!Ø ÐØ+Ð+ˆð
	ðð ð ð ð ð ð ð ð gÐfÐfÐfÐfÐfÐfÐfØ*ˆMØ3Ð3Ñ5Ô5ÐÝ"Ð#6Ð#6Ñ#8Ô#8Ñ9Ô9ÐÐøÝð 	ð 	ð 	ØˆDð	øøøð
ð 
Ø'ð
ñ 
ô 
Ðð -Ð0AÕDbÑ0bÑcˆØ0<ÐDÕ*Ñ,Ô,Ð,À"ˆ
Ý #¡¤ˆÝ˜,Ñ'Ô'ð 	%ð 	%ˆCÝ”I˜c‘N”NÐ9 j§n¢n°SÑ&9Ô&9ˆEØ(Ð4Ø1Ð1°#°uÑ=Ô=�ØÐ Ø %�˜‘�Ø!ð %¨-¨-¸Ñ*<Ô*<ð %ÕAQ×A[ÒA[Ð\_ÑA`ÔA`ð %Ø—’ Ñ$Ô$Ð$øØ˜Ð$Ð$s   ­3A! Á!
A.Á-A.c                 óØ   — |                       ¦   «         \  }}g }t          |¦  «        D ]$}|                     d|› d||         › �g¦  «         Œ%|t          t          |¦  «        ¦  «        fS )zFBuild runtime forwarding args plus names absent from the active scope.r   r  )ræ  r  ra   rG  )rJ  rç  rè  r  r   s        r   Ú#_build_runtime_env_args_with_unsetsz5DockerEnvironment._build_runtime_env_args_with_unsets4  s~   € à'+×'DÒ'DÑ'FÔ'FÑ$ˆ˜ØˆÝ˜/Ñ*Ô*ð 	Að 	AˆCØ�KŠK˜ #Ð>Ð>¨¸Ô(<Ð>Ð>Ð?Ñ@Ô@Ð@Ð@Ø•U�6 +Ñ.Ô.Ñ/Ô/Ð/Ð/r   c                 ó6   — |                       ¦   «         d         S )z<Build only dynamic forwarded values for a non-login command.r   )r  rI  s    r   Ú_build_runtime_env_argsz)DockerEnvironment._build_runtime_env_args<  s   € à×7Ò7Ñ9Ô9¸!Ô<Ð<r   r†  )ÚloginrO   Ú
stdin_dataÚ
cmd_stringr  r  c                ó>  — | j         s
J d¦   «         ‚| j        dg}|�|                     d¦  «         d}|r|                     | j        ¦  «         n3| j        r,|                      ¦   «         \  }}|                     |¦  «         |rt          | dd¦  «        }|r'd                     d„ |D ¦   «         ¦  «        }d	|› d
|› �}|                     | j         g¦  «         |r|                     ddd|g¦  «         n|                     dd|g¦  «         t          ||¦  «        S )z1Spawn a bash process inside the Docker container.zContainer not startedÚexecNz-irS   rŽ  rx  c              3   ó>   K  — | ]}t          j        |¦  «        V — Œd S rg  )ÚshlexÚquote)rV   r  s     r   r£   z.DockerEnvironment._run_bash.<locals>.<genexpr>V  s,   è è € Ð#NÐ#N¸$¥E¤K°Ñ$5Ô$5Ð#NÐ#NÐ#NÐ#NÐ#NÐ#Nr   zunset z 2>/dev/null || true
Úbashz-lz-c)
r�  r¦  r   ra   r¯  Ú_profile_scoped_passthroughr  rÑ   r¥  r   )	rJ  r  r  rO   r  Úcmdrè  Úruntime_argsÚquoted_namess	            r   Ú	_run_bashzDockerEnvironment._run_bash@  s[  € ð Ô!Ð:Ð:Ð#:Ñ:Ô:Ð!ØÔ Ð(ˆØÐ!Ø�JŠJ�tÑÔÐð
 (*ˆØð 	%Ø�JŠJ�tÔ*Ñ+Ô+Ð+Ð+ØÔ-ð 	%Ø(,×(PÒ(PÑ(RÔ(RÑ%ˆL˜+Ø�JŠJ�|Ñ$Ô$Ð$àð 	MÝ! $Ð(GÈÑLÔLˆKØð 	SØŸ8š8Ð#NÐ#NÀ+Ð#NÑ#NÔ#NÑNÔNˆLØR ,ÐRÐRÀjÐRÐRˆJà�
Š
�DÔ&Ð'Ñ(Ô(Ð(àð 	3Ø�JŠJ˜  d¨JÐ7Ñ8Ô8Ð8Ð8à�JŠJ˜  jÐ1Ñ2Ô2Ð2å˜3 
Ñ+Ô+Ð+r   )zNo such containerzis not runningzno such containerÚoutputc                 óD   ‡— t          ˆfd„| j        D ¦   «         ¦  «        S )zCReturn True if the output indicates the container no longer exists.c              3   ó    •K  — | ]}|‰v V — Œ	d S rg  rS   )rV   Úpr  s     €r   r£   z7DockerEnvironment._is_container_gone.<locals>.<genexpr>n  s'   øè è € ÐDÐD 1�1˜�;ÐDÐDÐDÐDÐDÐDr   )r¤   Ú_NO_CONTAINER_PATTERNS)rJ  r  s    `r   Ú_is_container_gonez$DockerEnvironment._is_container_gonel  s)   ø€ åÐDÐDÐDÐD¨Ô(CÐDÑDÔDÑDÔDÐDr   c           
      ó  — | j         pddd…         }t                               d|¦  «         d| _         | j                             dd¦  «        }| j                             dd¦  «        }|                      ||| j                             t          d¦  «        ¦  «        }|�Ü|\  }}|dk    r+|| _         t                               d	|dd…         ¦  «         n¦	 t          j	        | j
        d
|gddddddt          j        ¬¦  «         || _         t                               d|dd…         ¦  «         nL# t          j        t          j        f$ r.}t                               d|dd…         |¦  «         Y d}~nd}~ww xY w| j         �s�| j        st                               d¦  «         dS 	 ddl}d|                     ¦   «         j        dd…         › �}	| j        rg ndg}
g }| j                             ¦   «         D ]!\  }}|                     d|› d|› �g¦  «         Œ"| j
        ddg|
¢d‘|	‘|¢d‘| j        ‘| j        ¢| j        ‘d‘d‘}t          j	        |ddddd dt          j        ¬¦  «        }|j                             ¦   «         | _         |	| _        t                               d!|	| j         dd…         ¦  «         nJ# t          j        t          j        t6          f$ r&}t                               d"|¦  «         Y d}~dS d}~ww xY w	 d| _        |                      ¦   «          n3# t<          $ r&}t                               d#|¦  «         Y d}~dS d}~ww xY wt                               d$| j         pddd…         ¦  «         dS )%a9  Recreate the container after it was removed out-of-band.

        Tries label-based reuse first; if no existing container is found,
        starts a fresh one with the same image and run-args.  Returns True
        on success, False if recreation fails (caller should surface the
        original error).
        r  Nr^   u7   Container %s appears to be gone â€” attempting recoveryr|  r}  rä   r  z&Recovery: reusing running container %sr€  TrG   rH   r[   rJ   z Recovery: restarted container %sz*Recovery: failed to start container %s: %sz8Recovery: no saved image name, cannot recreate containerFr   ry  rz  r�  r{  r  rc   r‚  rƒ  r„  r8  r…  r†  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Å   r«  rª  rr   rb   rc   r¦  rd   r­  re   r‘  rA  r§  r¨  r©  r“  r"   ra   rM  r”  rj   r   r’  rf   Ú_snapshot_readyr°  r,   )rJ  Úold_idrÛ  Úprofile_labelrÞ  rx   rß  ru   Ú_uuidÚnew_namerâ  rÜ  ro  Úvrã  r{   s                   r   Ú_recreate_containerz%DockerEnvironment._recreate_containerp  sO  € ð Ô$Ð*¨¨C¨R¨CÔ0ˆÝ�ŠØEÀvñ	
ô 	
ð 	
ð "ˆÔð ”\×%Ò%Ð&6¸Ñ;Ô;ˆ
Øœ×(Ò(Ð)9¸2Ñ>Ô>ˆØ×0Ò0Ø˜ t¤|×'7Ò'7Õ8IÈ5Ñ'QÔ'Qñ
ô 
ˆð ÐØ!‰JˆC�Ø˜	Ò!Ð!Ø%(�Ô"Ý—’ÐDÀcÈ#È2È#ÄhÑOÔOÐOÐOð	^Ý”NØÔ)¨7°CÐ8Ø'+°$ÀÐQZÐdfÐnrÝ(Ô0ðñ ô ð ð
 *-�DÔ&Ý—K’KÐ BÀCÈÈÈÄHÑMÔMÐMÐMøÝ"Ô5µzÔ7PÐQð ^ð ^ð ^Ý—N’NÐ#OÐQTÐUXÐVXÐUXÔQYÐ[\Ñ]Ô]Ð]Ð]Ð]Ð]Ð]Ð]øøøøð^øøøð Ô!ñ !	Ø”;ð Ý—’ÐWÑXÔXÐXØ�uðØ$Ð$Ð$Ð$Ø< U§[¢[¡]¤]Ô%6°r¸°rÔ%:Ð<Ð<�Ø"&Ô":ÐJ˜B˜BÀÀ
�	Ø�
Ø œL×.Ò.Ñ0Ô0ð ?ð ?‘D�A�qØ×%Ò% y°Q°*°*¸°*°*Ð&=Ñ>Ô>Ð>Ð>àÔ$ e¨Tð	àð	ð ð	ð 'ð	ð  ð		ð
 ð	ð
 œ(ð	ð Ô'ð	ð ”Kð	ð ð	ð (ð	�õ $œØ¨D°tÀgÐV_ÐilÐtxÝ$Ô,ðñ ô �ð &,¤]×%8Ò%8Ñ%:Ô%:�Ô"Ø'/�Ô$Ý—’Ø?Ø˜dÔ0°°"°Ô5ñô ð ð øõ Ô1µ:Ô3LÍgÐVð ð ð Ý—’ÐKÈQÑOÔOÐOØ�u�u�u�u�uøøøøðøøøð
	Ø#(ˆDÔ Ø×ÒÑÔÐÐøÝð 	ð 	ð 	Ý�LŠLÐMÈqÑQÔQÐQØ�5�5�5�5�5øøøøð	øøøõ 	�ŠÐ>ÀÔASÐAYÐWYÐ[^Ð\^Ð[^Ô@_Ñ`Ô`Ð`ØˆtsJ   ÃAD1 Ä1E:Å$E5Å5E:Æ)DJ< Ê<!LËK>Ë>LÌL# Ì#
MÌ-MÍMr  Úcommandc                 ó0  •—  t          ¦   «         j        ||fi |¤Ž}|                     dd¦  «        dk    r_|                      |                     dd¦  «        ¦  «        r6| j        r/|                      ¦   «         r t          ¦   «         j        ||fi |¤Ž}|S )a
  Execute a command, auto-recovering from dead containers.

        If the container was removed out-of-band (idle reaper, docker prune,
        OOM kill, daemon restart), detect the error and recreate the container
        transparently before retrying once.
        rh   r   r  r  )rˆ  ÚexecuterÅ   r  r‹  r  )rJ  r   rM  Úkwargsr{   rä  s        €r   r"  zDockerEnvironment.executeÄ  s§   ø€ ð !•‘”” ¨#Ð8Ð8°Ð8Ð8ˆà�JŠJ�| QÑ'Ô'¨1Ò,Ð,Ø×'Ò'¨¯
ª
°8¸RÑ(@Ô(@ÑAÔAð -àÔ.ð -ð ×'Ò'Ñ)Ô)ð AØ(�™œœ¨°#Ð@Ð@¸Ð@Ð@�Øˆr   c            	      ód  — t           �t           S 	 t          ¦   «         pd} t          j        | dddgddddd	t          j        ¬
¦  «        }|j                             ¦   «                              ¦   «         }|dk    rda dS t          j        | ddddgdddddt          j        ¬
¦  «        }|j        dk    rC|j                             ¦   «         }|r%t          j        | d|gddt          j        ¬¦  «         da nda n# t          $ r da Y nw xY wt                               dt           ¦  «         t           S )zìCheck if Docker's storage driver supports --storage-opt size=.
        
        Only overlay2 on XFS with pquota supports per-container disk quotas.
        Ubuntu (and most distros) default to ext4, where this flag errors out.
        Nr@   rr   rF   z{{.Driver}}TrG   rH   r€   r\   Úoverlay2FÚcreater\  zsize=1mzhello-worldrI   r   rY   r?  r‡  z Docker --storage-opt support: %s)r0  r`   rb   rc   rd   rj   r   Úlowerrh   r,   r   rg   )r@   r{   ÚdriverÚprober}   s        r   r˜  z(DockerEnvironment._storage_opt_supportedÕ  sk  € õ Ð&Ý"Ð"ð	$Ý ‘]”]Ð. hˆFÝ”^Ø˜ ¨]Ð;Ø#¨$¸ÈÐ\^Ý Ô(ðñ ô ˆFð
 ”]×(Ò(Ñ*Ô*×0Ò0Ñ2Ô2ˆFØ˜Ò#Ð#Ø"'�Ø�uõ ”NØ˜ ?°I¸}ÐMØ#¨$¸ÈÐ\^Ý Ô(ðñ ô ˆEð
 Ô 1Ò$Ð$à$œ|×1Ò1Ñ3Ô3�Øð =Ý”N F¨D°,Ð#?Ø26ÀÝ)3Ô);ð=ñ =ô =ð =ð #'��à"'�øøÝð 	$ð 	$ð 	$Ø#ˆOˆOˆOð	$øøøå�ŠÐ7½ÑIÔIÐIÝÐs   �A,C9 Á>A:C9 Ã9DÄDr}   c           
      ó¨  — 	 t          j        | j        ddd|gddddddt           j        ¬	¦  «        }n?# t           j        t
          f$ r&}t                               d
|¦  «         Y d}~dS d}~ww xY w|j        dk    r:t                               d|j        |j	         
                    ¦   «         ¦  «         dS |j         
                    ¦   «         }|pdS )a®  Return the container's ``HostConfig.NetworkMode`` (e.g. ``bridge``,
        ``none``, ``host``), or ``None`` when inspection fails.

        Used by the reuse path to make sure a persisted container's network
        mode still matches the operator's ``docker_network`` setting; callers
        treat ``None`` (unknown) as a mismatch when lockdown was requested,
        so a failed inspect fails closed rather than open.
        r   rF   z{{.HostConfig.NetworkMode}}TrG   rH   r€   FrJ   z%docker inspect NetworkMode failed: %sNr   z*docker inspect NetworkMode returned %d: %s)rb   rc   r¦  rd   re   rf   r   rg   rh   ri   r   rj   )rJ  r}   r{   ru   Úmodes        r   r¬  z)DockerEnvironment._container_network_mode   sû   € ð	Ý”^àÔ$ iØÐ =Ø ðð
  $Ø G°IØØÝ Ô(ðñ ô ˆFˆFøõ Ô)­7Ð3ð 	ð 	ð 	Ý�LŠLÐ@À!ÑDÔDÐDØ�4�4�4�4�4øøøøð	øøøð Ô Ò!Ð!Ý�LŠLØ<ØÔ! 6¤=×#6Ò#6Ñ#8Ô#8ñô ð ð �4ØŒ}×"Ò"Ñ$Ô$ˆØˆ|�tÐs   ‚03 ³A/Á	A*Á*A/rÛ  r  r¿  c           
      ó*  — 	 dddd|› �dd|› �g}|dk    r%|                      ddt          › d|› �g¦  «         d}nd	t          z   d
z   }t          j        | j        ddg|¢d‘|‘ddddddt          j        ¬¦  «        }n?# t          j        t          f$ r&}t           	                    d|¦  «         Y d}~dS d}~ww xY w|j
        dk    r:t           	                    d|j
        |j                             ¦   «         ¦  «         dS d„ |j                             ¦   «         D ¦   «         }|sdS d}	d}
|D ]â}|dk    r||                     dd¦  «        }t!          |¦  «        dk     rŒ2|d         |d                              ¦   «         |d         }}}|dvr#t           	                    d|t          |¦  «         ŒƒnL|                     dd¦  «        }t!          |¦  «        dk    rŒ®|d         |d                              ¦   «         }}|
€||f}
|dk    r|	€||f}	Œã|	p|
S ) uƒ  Look for an existing container labeled for this (task, profile).

        Returns ``(container_id, state)`` on hit, ``None`` on miss / on any
        failure (including ``docker ps`` itself failing). State is one of the
        values Docker reports via ``{{.State}}`` â€” e.g. ``running``, ``exited``,
        ``created``, ``paused``, ``restarting``, ``dead``. The caller decides
        whether the state warrants ``docker start`` before reuse.

        Restricted to the docker-stored label set this class creates; never
        matches containers that happened to be named ``hermes-*`` but were
        started by some other tool.
        rA   rB   zlabel=hermes-task-id=rC   rä   zlabel=r  z{{.ID}}	{{.State}}z{{.ID}}	{{.State}}	{{.Label "z"}}rD   rE   rF   TrG   rH   r€   FrJ   u;   docker ps probe failed: %s â€” will start a fresh containerNr   u@   docker ps probe returned %d: %s â€” will start a fresh containerc                 ó:   — g | ]}|                      ¦   «         ¯|‘ŒS rS   rT   rU   s     r   rX   z>DockerEnvironment._find_reusable_container.<locals>.<listcomp>[  s%   € ÐGÐGÐG˜¸B¿HºH¹J¼JÐG�ÐGÐGÐGr   ú	r  é   r]   )r  z
<no value>rä   z7skipping container %s for egress=off reuse: label %s=%rr  )ra   rª  rb   rc   r¦  rd   re   rf   r   rg   rh   ri   r   rj   rk   r  r  r'  )rJ  rÛ  r  r¿  rs   Úfmtr{   ru   Úlinesr  r(  rW   Úpartsrx   rß  Ú
egress_vals                   r   r«  z*DockerEnvironment._find_reusable_container"  s·  € ð$ 	àÐ2ØÐ@°JÐ@Ð@ØÐC°MÐCÐCðˆGð
 ˜uÒ$Ð$Ø—’ 
Ð,WÕ5FÐ,WÐ,WÈÐ,WÐ,WÐXÑYÔYÐYØ+��ð 8Õ:KÑKÈeÑS�Ý”^àÔ$ d¨Dðàðð ðð !$ðð
  $Ø G°IØØÝ Ô(ðñ ô ˆFˆFøõ Ô)­7Ð3ð 	ð 	ð 	Ý�LŠLÐVÐXYÑZÔZÐZØ�4�4�4�4�4øøøøð	øøøð Ô Ò!Ð!Ý�LŠLØRØÔ! 6¤=×#6Ò#6Ñ#8Ô#8ñô ð ð �4ØGÐG˜fœm×6Ò6Ñ8Ô8ÐGÑGÔGˆØð 	Ø�4ð ˆØˆØð 	'ð 	'ˆBØ˜uÒ$Ð$ð Ÿš  qÑ)Ô)�Ý�u‘:”: ’>�>ØØ).¨q¬°5¸´8·>²>Ñ3CÔ3CÀUÈ1ÄX˜J�U�ØÐ%>Ð>Ð>Ý—L’Lð&Ø'*Õ,=¸zñô ð ð ð ?ð Ÿš  qÑ)Ô)�Ý�u‘:”: ’?�?ØØ" 1œX u¨Q¤x§~¢~Ñ'7Ô'7�U�Øˆ}Ø˜e˜�Ø˜	Ò!Ð! g oØ ˜,�øØÐ˜%Ðs   ‚A:A= Á=B9ÂB4Â4B9)Úforce_remover4  c                óà  ‡‡‡‡	‡
— | j         Š‰s2| j        s)| j        | j        fD ]}|rt	          j        |d¬¦  «         ŒdS |rdŠ
dŠ	n| j        r	d| _         dS dŠ
dŠ	| j        Š‰dd…         Šd
ˆˆˆˆ	ˆ
fd„}ddl}| 	                    |dd‰› �¬	¦  «        }| 
                    ¦   «          || _        d| _         ‰	r0| j        s+| j        | j        fD ]}|rt	          j        |d¬¦  «         ŒdS dS dS )u}	  Tear down the container according to persist mode and *force_remove*.

        Persist-mode (``persist_across_processes=True``, the default) leaves the
        container **running** untouched. The docs promise "ONE long-lived
        container shared across sessions" and stopping it on every Hermes exit
        breaks that promise:

        * Background processes inside the container (``npm run dev``, watchers,
          long-running pytest) get killed every time the user runs ``/quit``.
        * Every reuse requires ``docker start`` + waiting for the container to
          come back up, adding 1â€“2s to the first tool call of the new session.
        * The user-visible difference between "ONE long-lived container" and
          "a new container that happens to share state" is exactly this:
          processes survive in the former, die in the latter.

        Resource reclamation for the persist-mode case lives in the
        ``reap_orphan_containers()`` path (see issue #20561 commit 3): if no
        Hermes process touches a labeled container for ``2 Ã— lifetime_seconds``
        it gets ``docker rm -f``'d at the next Hermes startup. That covers the
        SIGKILL / OOM / abandoned-laptop cases without us needing to stop the
        container on every graceful exit.

        Opt-out mode (``persist_across_processes=False``) still does
        ``docker stop`` + ``docker rm -f`` on every cleanup, matching the
        pre-PR behavior for users who explicitly want per-process isolation.

        ``force_remove=True`` overrides persist mode and always tears the
        container down (``docker stop`` + ``docker rm -f``). This is the
        explicit-teardown path for ``/reset``, ``cleanup_vm(task_id)``-driven
        resets, or any caller that wants a guaranteed fresh container on next
        ``DockerEnvironment(task_id=...)``. No current caller passes
        ``force_remove=True``; the parameter is here so the explicit-teardown
        semantics can be wired up later without changing this method's
        signature.

        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.
        T)Úignore_errorsNr^   r   c                  ó²  •— ‰rh	 t          j        ‰ddd‰gddt           j        ¬¦  «         n?# t           j        t          f$ r&} t
                               d‰| ¦  «         Y d } ~ nd } ~ ww xY w‰ri	 t          j        ‰dd	‰gddt           j        ¬¦  «         d S # t           j        t          f$ r'} t
                               d
‰| ¦  «         Y d } ~ d S d } ~ ww xY wd S )NÚstopz-tÚ10Tr[   r‡  z%docker stop %s timed out / failed: %srY   rZ   r_   )rb   rc   rd   re   rf   r   r   )ru   r}   r>   Úlog_idÚshould_removeÚshould_stops    €€€€€r   Ú_do_cleanupz.DockerEnvironment.cleanup.<locals>._do_cleanupÍ  sH  ø€ Øð WðWÝ”NØ# V¨T°4¸ÐFØ'+°RÝ(Ô0ðñ ô ð ð øõ
 #Ô1µ7Ð;ð Wð Wð WÝ—N’NÐ#JÈFÐTUÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøàð LðLÝ”NØ# T¨4°Ð>Ø'+°RÝ(Ô0ðñ ô ð ð ð øõ
 #Ô1µ7Ð;ð Lð Lð LÝ—N’NÐ#?ÀÈÑKÔKÐKÐKÐKÐKÐKÐKÐKøøøøðLøøøðLð Ls-   …'- ­A)ÁA$Á$A)Á/&B ÂCÂ-CÃCr   zhermes-cleanup-)ÚtargetÚdaemonr  ©r   N)r�  rŠ  r�  rž  r‘   Úrmtreer‹  r¦  Ú	threadingÚThreadr€  Ú_cleanup_thread)rJ  r4  Údr=  rB  rt  r}   r>   r:  r;  r<  s         @@@@@r   ÚcleanupzDockerEnvironment.cleanup~  s©  øøøøø€ ðT Ô)ˆØð 	ð Ô#ð =ØÔ-¨t¬~Ð>ð =ð =�AØð =Ýœ a°tÐ<Ñ<Ô<Ð<øØˆFð ð 	!ØˆKØ ˆMˆMØÔ+ð 	!ð "&ˆDÔØˆFàˆKØ ˆMð Ô%ˆ
Ø˜c˜r˜cÔ"ˆð	Lð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð 	Lð4 	ÐÐÐØ×Ò K¸ÐC]ÐU[ÐC]ÐC]ÐÑ^Ô^ˆØ	�Š‰	Œ	ˆ	Ø ˆÔØ!ˆÔð
 ð 	9 Ô!1ð 	9ØÔ)¨4¬>Ð:ð 9ð 9�Øð 9Ý”M !°4Ð8Ñ8Ô8Ð8øð	9ð 	9ð 	9ð 	9ð9ð 9r   ç      >@c                 óª   — t          | dd¦  «        }|�|                     ¦   «         sdS |                     |¬¦  «         |                     ¦   «          S )uÀ  Block up to *timeout* seconds for the cleanup worker thread.

        Returns ``True`` if the thread finished (or no thread was started),
        ``False`` on timeout. The atexit hook in terminal_tool.py calls this
        on every active environment so docker stop/rm actually completes
        before the Python process exits â€” without this, ``hermes /quit``
        races the interpreter shutdown and leaves stopped containers behind.
        rD  NT)rO   )rÑ   Úis_aliver¥  )rJ  rO   Úthreads      r   Úwait_for_cleanupz"DockerEnvironment.wait_for_cleanupõ  sU   € õ ˜Ð0°$Ñ7Ô7ˆØˆ> §¢Ñ!2Ô!2ˆ>Ø�4Ø�Š˜GˆÑ$Ô$Ð$Ø—?’?Ñ$Ô$Ð$Ð$r   )r  )rG  )$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r  rG  r   rK  Ú_DEFAULT_SHM_SIZEr#   r$   r%   r  r!   r   r‰  r®  rë  r   ræ  r  r  rb   ÚPopenr  r  r  r  r"  Ústaticmethodr˜  r¬  r«  rF  rK  Ú__classcell__)rä  s   @r   rE  rE  T  s'  ø€ € € € € ð	ð 	ð #'Ðð(¸eÀCÈÀH¼oð (ð (ð (ð (ð ØØØØØ&+Ø ØØ(,ØØØ"&Ø$Ø!&ØØ)-Ø)ð'N
ð N
àðN
ð ðN
ð ð	N
ð
 ðN
ð ðN
ð ðN
ð  $ðN
ð ðN
ð ðN
ð ˜#”Y Ñ%ðN
ð �D‰[ðN
ð ðN
ð ˜3”-ðN
ð ðN
ð  ð!N
ð" ð#N
ð$ #'ð%N
ð& ð'N
ð N
ð N
ð N
ð N
ð N
ð` d¨3¤ið ð ð ð ð$2¨¨S°#¨X¬ð 2ð 2ð 2ð 2ð&%¨%°°S¸#°X´ÀÀCÄÐ0HÔ*Ið &%ð &%ð &%ð &%ðP0°U¸4À¼9ÀeÈCÐQTÈHÄoÐ;UÔ5Vð 0ð 0ð 0ð 0ð=¨¨c¬ð =ð =ð =ð =ð ;@Ø!$Ø+/ð ,ð  ,ð  , Cð  ,°4ð  ,Øð ,à! D™jð ,à4>Ô4Dð ,ð  ,ð  ,ð  ,ðLÐðE¨ð E°ð Eð Eð Eð EðR Tð Rð Rð Rð Rðhð ˜sð ¨ð Àð ð ð ð ð ð ð" ð( Dð (ð (ð (ñ „\ð(ðT °Cð  ¸HÀS¼Mð  ð  ð  ð  ðDZ àðZ ð ðZ ð ð	Z ð
 
�%˜˜S˜”/Ô	"ðZ ð Z ð Z ð Z ðx /4ð u9ð u9ð u9 tð u9ð u9ð u9ð u9ðn%ð %¨ð %¸ð %ð %ð %ð %ð %ð %ð %ð %r   rE  )T)Fr@  )CrO  rë   ré   Úloggingr‹   rƒ   r
  r‘   rb   r–  r§  Úpathlibr   Útypingr   r™  r   r   r   Útools.environments.localr   r	   Ú	getLoggerrL  r   r“   r
   r   Ú__annotations__Úcompiler   rª  r  r   r!   r'   r-   r2   r5   r;   r#   r|   rp   r`   r  r•  rP  r%   r¥   r  r  r  rG  râ   rð   ró   r   rü   r  r   r)  r/  r0  r1  r;  rC  rE  rS   r   r   ú<module>r[     se  ððð ð ð €€€Ø €€€Ø €€€Ø 	€	€	€	Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð
ð ð ð ð ð ð ð ð
 
ˆÔ	˜8Ñ	$Ô	$€ðð ð Ð ð %)Ð �H˜S”MÐ (Ð (Ñ (Ø�2”:Ð9Ñ:Ô:Ð Ø#Ð ð¨d°3¬i¸$Ñ.>ð À4ÈÄ9ð ð ð ð ð2˜T D™[ð ¨T°#°s°(¬^ð ð ð ð ð<˜t C¨ Hœ~ð ð ð ð ð  �R”ZÐ 2Ñ3Ô3Ð ð ð ¨ð ð ð ð ð #ð ð ð ð ð" Ø!%Ø!ð	[ð [ð [àð[ð ˜$‘Jð[ð �d‘
ð	[ð
 	ð[ð [ð [ð [ð|  sð  ¸#ð  ð  ð  ð  ðF*�X˜c”]ð *ð *ð *ð *ðDð ð Ð ð Ð ð Ð ð	¨ð 	°$ð 	ð 	ð 	ð 	ð @Ð Ø;€ðð ð Ð ð^3 u¨T°#¬Y¸¸SÀ#¸X¼ÈÈSÌ	Ð-QÔ'Rð ^3ð ^3ð ^3ð ^3ðBDØ�c”ðDà˜˜S˜”>ðDð �CŒyðDð 	ð	Dð Dð Dð Dð(	ð 	 tð 	°tð 	ð 	ð 	ð 	ð¨d°3¸°8¬nð ÀÀSÄð ð ð ð ð#Ø�S”	ð#Ø+.¨s¬8ð#à	ˆ#„Yð#ð #ð #ð #ðB+ð +¨4ð +¸4ð +ÈDÐQTÌIð +ð +ð +ð +ð*H¨Cð *H¸ð *HÀð *Hð *Hð *Hð *HðZ ¨#¤ð ð ð ð ð$ #'€�˜$”Ð &Ð &Ñ &Ø$(Ð �8˜D”>Ð (Ð (Ñ (ð1 Cð 1¨Dð 1ð 1ð 1ð 1ðhMð Mð Mð Mð`n%ð n%ð n%ð n%ð n%˜ñ n%ô n%ð n%ð n%ð n%r   