Ë
    LþÝjªH  ã                  óT  — d Z ddlm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mZ ddlmZmZ ddlmZ d	d
lmZmZmZmZmZ dZdZ e«       Z  G d„ de!«      Z"d„ Z#eZ$ddd„Z%dd„Z&dZ'dZ( e)dh«      Z* e)ddh«      Z+dd„Z, G d„ de«      Z-g d¢Z.y)aØ  CagedCodexRunner: fuehrt Codex in einem systemd --user --scope aus, der iso_exec.py
mit einem pro-Lauf erzeugten Landlock/seccomp-Profil startet.

Ablauf je Lauf:
  1. ephemere Verzeichnisse unter workspace_root anlegen (ws/home/codex-home/authdir/tmp).
  2. das EINE Credential als read-only KOPIE ins authdir legen; im codex-home einen Verweis
     (Symlink) darauf (M1). Das echte ~/.codex ist nie in der Allowlist.
  3. Profil-Konfiguration (text|tools) bauen und als cfg.json schreiben. tools: Home nur lesend,
     Schreiben nur in den Lauf-Verzeichnissen und in write_allowlist (E44 Option 2; ungueltiger
     Eintrag beim Profilbau -> WRITE_ALLOWLIST_INVALID, nichts startet).
  4. Platzhalter {unit}/{cfg}/{workdir} in der (geprueften) Argumentliste ersetzen.
  5. Argumentliste pruefen: tools-Profil erlaubt die Bypass-Tokens NUR, wenn ein echter Kaefig
     (systemd-run ... iso_exec ... --) davor steht; sonst/alle anderen Profile: hart ablehnen.
  6. Popen mit EXPLIZITER Umgebung (nur XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS, PATH),
     keine Shell, eigene Prozessgruppe. Supervision wie SubprocessRunner (Limit/Timeout/Kill).
  7. bei Timeout/Ende: Prozessgruppe toeten UND `systemctl --user stop <unit>` (cgroup-Kill der
     Enkel). last.txt aus dem Workspace lesen (M3-Quercheck), dann aufraeumen + reset-failed.

Fehlt der User-Bus, liefert run() den strukturierten Fehler NO_USER_BUS und startet NICHTS
ohne Scope (M3). Jeder andere Setup-Fehler ist ebenfalls fail-closed.
é    )ÚannotationsN)ÚPath)ÚMappingÚOptionalé   )ÚISO_EXEC_PATHÚPKG_REPO_ROOT)Úprofilesé   )Ú	RunResultÚRunSpecÚSubprocessRunnerÚUnsafeCommandErrorÚassert_safe_argvz--zlast.txtc                  ó   — e Zd ZdZy)Ú_BridgeTerminatedzXWird vom SIGTERM-Handler geworfen, damit der finally-Block den Scope stoppt (Review #9).N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úC/home/aria/aria-v3-dev/python/aria_router/isolation/caged_runner.pyr   r   /   s   „ Úbr   r   c                ó   — t        «       ‚©N)r   )ÚsignumÚframes     r   Ú_raise_terminatedr   3   s   € Ü
Ó
Ðr   c                óL   — | €t        j                  «       n| } d| › �d| › d�ddœS )Nz
/run/user/zunix:path=/run/user/z/busz/usr/bin:/bin)ÚXDG_RUNTIME_DIRÚDBUS_SESSION_BUS_ADDRESSÚPATH)ÚosÚgetuid)Úuids    r   Údefault_bus_envr&   <   s6   € Ø˜Œ"�)‰)Œ+¨#€Cà'¨ uÐ-Ø&:¸3¸%¸tÐ$DØñð r   c                óî   — ddi}| €|S | j                   �| j                   |d<   | j                  �| j                  |d<   | j                  �| j                  |d<   | j                  �| j                  |d<   |S )zXResourceLimits -> iso_exec rlimits. M3: AS/CPU/FSIZE/NOFILE als harter Boden im Wrapper.ÚCOREr   ÚASÚCPUÚFSIZEÚNOFILE)Úaddress_space_bytesÚcpu_secondsÚmax_file_bytesÚmax_open_files)ÚresÚlims     r   Ú_res_to_rlimitsr3   E   s‚   € à�1ˆ+€CØ
€{Øˆ
Ø
×ÑÐ*Ø×+Ñ+ˆˆD‰	Ø
‡�Ð"Ø—_‘_ˆˆE‰
Ø
×ÑÐ%Ø×)Ñ)ˆˆG‰Ø
×ÑÐ%Ø×*Ñ*ˆˆH‰Ø€Jr   z/usr/bin/systemd-run)z/usr/bin/envz-iz/usr/bin/python3z-Iz--quietz--unitú-pc                óž  — t        | t        t        f«      rt        | vry| j	                  t        «      }t        | d| «      }t        |«      dk  ry|d   t        k7  s|d   dk7  s|d   dk7  ryt        |d	d
 «      t        k7  ry|d
   }t        j                  j                  |«      r"t        j                  j                  |«      dk(  sy|d   }|dk(  s t        j                  j                  |«      sy|dd	 }d}|t        |«      k  rC||   }|t        v r|dz  }n!|t        v r|dz   t        |«      k\  ry|dz  }ny|t        |«      k  rŒCy)aß  Prueft STRUKTURELL (nicht per Namenssuche), dass vor dem Codex-Aufruf ein echter Kaefig steht:

        /usr/bin/systemd-run --user --scope [ --quiet | --unit X | -p KEY=VAL ]* \
            /usr/bin/env -i /usr/bin/python3 -I <abs .../iso_exec.py> <cfg> -- <codex> ...

    Nur exakt diese Form (richtige Reihenfolge, feste Kette direkt vor dem Separator, keine fremden
    Tokens in der Mitte) gilt als Kaefig. python3 -c / sh -c / Decoy-Argumente werden abgelehnt (Review #1).FNé	   r   r   ú--userr   z--scopeiúÿÿÿéþÿÿÿziso_exec.pyéÿÿÿÿú{cfg}é   T)Ú
isinstanceÚlistÚtupleÚCODEX_ARG_SEPÚindexÚlenÚSYSTEMD_RUNÚCAGE_FIXED_TAILr#   ÚpathÚisabsÚbasenameÚ_CAGE_MIDDLE_FLAGSÚ_CAGE_MIDDLE_PAIRS)ÚargvÚsepÚwÚisoÚcfgÚmiddleÚiÚtoks           r   Úwrapper_is_tools_cagerQ   ^   sF  € ô �dœT¤5˜MÔ*¬mÀ4Ñ.GØØ
�*‰*”]Ó
#€CÜˆT�$�3ˆZÓ€Aä
ˆ1ƒv�‚zØØˆ�tŒ{Ò˜a ™d hÒ.°!°A±$¸)Ò2CØÜˆQˆr�"ˆXƒœ/Ò)ØØ
ˆB‰%€CÜ�G‰G�M‰M˜#Ô¤2§7¡7×#3Ñ#3°CÓ#8¸MÒ#IØØ
ˆB‰%€CØ�7ŠNœbŸg™gŸm™m¨CÔ0ØØˆq�ˆW€FØ	€AØ
Œc�&‹kŠ/Ø�Q‰iˆØÔ$Ñ$Ø�‰F‰AØÔ&Ñ&Ø�1‰uœ˜F›Ò#ØØ�‰F‰Aàð Œc�&‹k‹/ð r   c                  óÎ   ‡ — e Zd Zddddddddddd	d	ddd
ddœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dˆ fd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	d d„Z
d!d„Zd!d„Zd"d„Zd#d„Zˆ xZS )$ÚCagedCodexRunnerÚtextNz/home/aria/.codex/auth.jsonFz
/home/ariaz/usr/bin/systemctlé   gš™™™™™É?g      @Tr   )ÚprofileÚresource_limitsÚ	auth_fileÚcodex_auth_writableÚ	home_rootÚbus_envÚsystemctl_pathÚiso_min_abiÚsecret_filesÚexit_drain_secondsÚbus_check_timeoutÚscope_stop_timeoutÚ	state_dirÚ	repo_rootÚprotect_startupÚwrite_allowlistc               ón  •— t         ‰| �  |||¬«       |dvrt        d«      ‚|dk7  r|rt        d«      ‚|dk(  rt        |dd «      �t        d«      ‚|| _        t        |«      | _        t        |«      | _        t        j                  j                  |«      | _        |�t        |«      n	t        «       | _        || _        |	| _        |
| _        || _        || _        |rt        j                  j                  |«      nd | _        |rt        j                  j                  |«      nt,        | _        t        |«      | _        t3        j4                  t7        |«      | j                  | j*                  | j.                  t        j                  j                  t        | j8                  «      «      ¬«      | _        y )	N)rW   r_   )rT   Útoolszprofile must be text or toolsrg   z/write_allowlist is only valid for profile toolsr-   z6address_space_bytes is incompatible with profile tools)rZ   rb   rc   Ú	runs_root)ÚsuperÚ__init__Ú
ValueErrorÚgetattrrV   ÚstrrX   ÚboolrY   r#   rD   ÚabspathrZ   Údictr&   r[   r\   r]   Ú_secret_filesr`   ra   rb   Ú_PKG_REPO_ROOTrc   rd   ÚPÚvalidate_write_allowlistr=   Úworkspace_rootre   )Úselfru   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   rb   rc   rd   re   Ú	__class__s                     €r   rj   zCagedCodexRunner.__init__‡   sb  ø€ ô 	‰Ñ˜¸Ð]oÐÔpØÐ+Ñ+ÜÐ<Ó=Ð=Ø�gÒ¡/äÐNÓOÐOØ�gÒ¤'¨/Ð;PÐRVÓ"WÐ"cäÐUÓVÐVØˆŒÜ˜Y›ˆŒÜ#'Ð(;Ó#<ˆÔ ÜŸ™Ÿ™¨Ó3ˆŒØ(/Ð(;”t˜G”}ÄÓARˆŒØ,ˆÔØ&ˆÔØ)ˆÔØ!2ˆÔØ"4ˆÔÙ7@œŸ™Ÿ™¨Ô3ÀdˆŒá7@œŸ™Ÿ™¨Ô3ÄnˆŒÜ# OÓ4ˆÔô  !×9Ñ9Ü�Ó!¨T¯^©^ÀtÇ~Á~Ø—n‘n´·±·±ÄÀD×DWÑDWÓ@XÓ0Yô [ˆÕr   c                ó  — 	 t        j                  | j                  ddddgt        | j                  «      d| j
                  d¬«      }|j                  dk(  xr d	|j                  v S # t        t         j                  f$ r Y yw xY w)
Nr7   Úshowr4   ÚVersionTF©ÚenvÚcapture_outputÚtimeoutÚcheckr   s   Version=)
Ú
subprocessÚrunr\   rp   r[   r`   ÚOSErrorÚTimeoutExpiredÚ
returncodeÚstdout)rv   Úprocs     r   Úbus_reachablezCagedCodexRunner.bus_reachable°   s�   € ð	Ü—>‘> 4×#6Ñ#6¸À&È$ÐPYÐ"ZÜ&*¨4¯<©<Ó&8ÈØ*.×*@Ñ*@ÈôOˆDð
 �‰ !Ñ#ÒB¨°t·{±{Ð(BÐBøô œ×2Ñ2Ð3ò 	Ùð	ús   ‚AA' Á'BÂBc           	     ó0  — t        j                  dt        | j                  «      ¬«      }i }dD ]=  }t        j
                  j                  ||«      }t	        j                  |d«       |||<   Œ? t        j                  ||d   |d   |d   |d   |d	   «      S )
Nz	codexrun-)ÚprefixÚdir)ÚwsÚhomeú
codex-homeÚauthdirÚtmpiÀ  r‹   rŒ   r�   rŽ   r�   )
ÚtempfileÚmkdtemprm   ru   r#   rD   ÚjoinÚmkdirrs   ÚRunDirs)rv   ÚrootÚsubÚnameÚds        r   Ú_make_run_dirszCagedCodexRunner._make_run_dirsº   s‘   € Ü×Ñ {¼¸D×<OÑ<OÓ8PÔQˆØˆØBò 	ˆDÜ—‘—‘˜T 4Ó(ˆAÜ�H‰H�Q˜ÔØˆC�ŠIð	ô �y‰y˜˜s 4™y¨#¨f©+°s¸<Ñ7HÈ#ÈiÉ.ÐZ]Ð^cÑZdÓeÐer   c                ó  — t        j                  | j                  |j                  «       t	        j
                  |j                  | j                  rdnd«       t	        j                  |j                  |j                  «       y )Ni€  é   )	ÚshutilÚcopyfilerX   Ú	auth_copyr#   ÚchmodrY   ÚsymlinkÚcodex_home_auth_link)rv   Údirss     r   Ú_stage_authzCagedCodexRunner._stage_authÃ   sL   € ä�‰˜Ÿ™¨¯©Ô7Ü
�‰�—‘¨$×*BÒ*B¡ÈÔNä
�
‰
�4—>‘> 4×#<Ñ#<Õ=r   c                óè  — t        | j                  «      }| j                  dk(  r¡t        j                  |||| j
                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  t        j                  j                  t!        | j"                  «      «      ¬«      S t        j$                  |||| j                  | j                  ¬«      S )Nrg   )Ú	codex_binÚrlimitsrZ   Úwritable_authÚmin_abir^   rb   rc   rd   re   rh   )r¥   r¦   r§   r¨   )r3   rW   rV   rs   Útools_profilerZ   rY   r]   rq   rb   rc   rd   re   r#   rD   ro   rm   ru   Útext_profile)rv   r¢   r¥   r¦   s       r   Ú
_build_cfgzCagedCodexRunner._build_cfgÊ   sÀ   € Ü! $×"6Ñ"6Ó7ˆØ�<‰<˜7Ò"Ü—?‘? 4°9ÀgÐY]×YgÑYgØ15×1IÑ1IÐSW×ScÑScØ04×0BÑ0BÈdÏnÉnØ-1¯^©^ÈT×MaÑMaØ37×3GÑ3GÜ-/¯W©W¯_©_¼SÀ×ATÑATÓ=UÓ-VôXð Xô �~‰~˜d¨iÀØ,0×,DÑ,DÈd×N^ÑN^ô`ð 	`r   c                óR  — t         |vrt        d«      ‚|||j                  dœ}g }|D ]=  }|j                  «       D ]  \  }}	|j	                  ||	«      }Œ |j                  |«       Œ? t        |«      }| j                  dk(  }
|
rt        |«      st        d«      ‚t        ||
¬«       |S )NÚINVALID_CAGE_ARGV)z{unit}r:   z	{workdir}rg   ÚTOOLS_PROFILE_REQUIRES_CAGE©Úallow_bypass_sandbox)
r?   r   Ú	workspaceÚitemsÚreplaceÚappendr>   rV   rQ   r   )rv   Útemplate_argvr¢   Úcfg_pathÚunitÚsubsrI   ÚaÚkÚvÚallow_bypasss              r   Ú_compose_argvzCagedCodexRunner._compose_argvÖ   s¬   € Ü Ñ-Ü$Ð%8Ó9Ð9Ø¨ÀÇÁÑOˆØˆØò 	ˆAØŸ
™
›ò $‘��1Ø—I‘I˜a “O‘ð$à�K‰K˜�Nð	ô �T‹{ˆà—|‘| wÑ.ˆÙÔ 5°dÔ ;Ü$Ð%BÓCÐCÜ˜°LÕAØˆr   c                óì   — ||j                  t        «      dz      }t        j                  j	                  |«      j                  «       dk(  rt        d«      ‚t        j                  j                  |«      S )Nr   ÚclaudeÚCODEX_BIN_IS_CLAUDE)r@   r?   r#   rD   rF   Úlowerr   Úrealpath)rv   rµ   Úbin_s      r   Ú_codex_bin_ofzCagedCodexRunner._codex_bin_ofç   s]   € Ø˜]×0Ñ0´Ó?À!ÑCÑDˆÜ�7‰7×Ñ˜DÓ!×'Ñ'Ó)¨XÒ5Ü$Ð%:Ó;Ð;Ü�w‰w×Ñ Ó%Ð%r   c                óÎ   — 	 t        j                  | j                  dg|¢t        | j                  «      d| j
                  d¬«       y # t        t         j                  f$ r Y y w xY w)Nr7   TFr{   )r€   r�   r\   rp   r[   ra   r‚   rƒ   )rv   Úargss     r   Ú
_systemctlzCagedCodexRunner._systemctlî   s\   € ð	Ü�N‰N˜D×/Ñ/°ÐA¸DÐAÄtÈDÏLÉLÓGYØ*.¸×8OÑ8OÐW\ö^øäœ×2Ñ2Ð3ò 	Ùð	ús   ‚AA ÁA$Á#A$c                ó(   — | j                  d|«       y )NÚstop©rÇ   ©rv   r·   s     r   Ú
stop_scopezCagedCodexRunner.stop_scopeõ   s   € Ø�‰˜ Õ%r   c                ó(   — | j                  d|«       y )Nzreset-failedrÊ   rË   s     r   Úreset_scopezCagedCodexRunner.reset_scopeø   s   € Ø�‰˜¨Õ-r   c                ó6  — t        j                  «       }	 t        |j                  | j                  dk(  ¬«       t        |j                  vrt        dd«      S t        |j                  t        «      st        dd«      S |j                  rt        dd«      S | j                  j                  «       st        dd«      S t        j                   j#                  | j$                  «      st        dd«      S | j'                  «       st        dd	«      S 	 | j)                  |j                  «      }	 | j+                  «       }d
t/        j0                  «       j2                  › d�}t4        }	 t7        j6                  t6        j8                  t:        «      }	 	 | j?                  |«       	 | jK                  ||«      }t        j                   jS                  |jH                  d«      }	tU        |	dd¬«      5 }
tW        jX                  ||
«       d d d «       	 | j[                  |j                  ||	|«      }	 t]        j^                  |t\        j`                  t\        j`                  t\        j`                  |jH                  tc        | jd                  «      ddd¬«	      }| jg                  |||«      }| jA                  |«       | ji                  ||jj                  «      }tm        jn                  ||¬«      |t4        ur%	 t7        j6                  t6        j8                  |«       | jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S # t
        $ r }t        d|j                  «      cY d }~S d }~ww xY w# t
        $ r }t        d|j                  «      cY d }~S d }~ww xY w# t,        $ r t        dd«      cY S w xY w# t<        t,        f$ r
 t4        }Y �ŒTw xY w# t,        $ r• t        dd«      cY |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S w xY w# tL        jN                  $ r• t        dd«      cY |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S tP        $ r• t        dd«      cY |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S w xY w# 1 sw Y   �ŒÍxY w# t
        $ r¦}t        d|j                  «      cY d }~|t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S d }~ww xY w# t,        $ r¬ t        ddt        j                  «       |z
  ¬«      cY |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S w xY w# t<        t,        f$ r Y �ŒDw xY w# tp        $ r¬ t        ddt        j                  «       |z
  ¬«      cY |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       S w xY w# |t4        ur;	 t7        j6                  t6        j8                  |«       n# t<        t,        f$ r Y nw xY w| jA                  |«       | jC                  |«       tE        jF                  |jH                  d¬«       w xY w)Nrg   r¯   Fr­   ÚINVALID_STDINÚATTACHMENTS_UNSUPPORTEDÚWORKSPACE_UNAVAILABLEÚAUTH_UNAVAILABLEÚNO_USER_BUSzaria-codex-z.scopeÚAUTH_STAGE_FAILEDT)Úignore_errorsÚWRITE_ALLOWLIST_INVALIDÚPROFILE_BUILD_FAILEDzcfg.jsonrK   zutf-8)Úencoding)Ústdinr…   ÚstderrÚcwdr|   ÚshellÚ	close_fdsÚstart_new_sessionÚSTART_FAILED)Úduration_seconds)ÚartifactÚBRIDGE_TERMINATED)9ÚtimeÚ	monotonicr   rI   rV   r   r   Úcoder?   r<   rÚ   ÚbytesÚfilesru   Úis_dirr#   rD   ÚisfilerX   r‡   rÄ   r™   r‚   ÚuuidÚuuid4ÚhexÚ_MISSING_HANDLERÚsignalÚSIGTERMr   rk   r£   rÌ   rÎ   rœ   Úrmtreer•   r«   rs   ÚWriteAllowlistErrorÚ	Exceptionr’   ÚopenÚjsonÚdumpr½   r€   ÚPopenÚPIPErp   r[   Ú
_superviseÚ
_read_lastÚmax_output_bytesÚdataclassesr³   r   )rv   ÚspecÚstartedÚexcr¥   r¢   r·   Úprev_handlerrM   r¶   ÚfhrI   r†   Úresultrâ   s                  r   r�   zCagedCodexRunner.runü   sï  € Ü—.‘.Ó"ˆð	.Ü˜TŸY™Y¸d¿l¹lÈgÑ>UÕWô  §	¡	Ñ)Ü˜UÐ$7Ó8Ð8Ü˜$Ÿ*™*¤eÔ,Ü˜U OÓ4Ð4ð �:Š:Ü˜UÐ$=Ó>Ð>Ø×"Ñ"×)Ñ)Ô+Ü˜UÐ$;Ó<Ð<Ü�w‰w�~‰~˜dŸn™nÔ-Ü˜UÐ$6Ó7Ð7Ø×!Ñ!Ô#ä˜U MÓ2Ð2ð	.Ø×*Ñ*¨4¯9©9Ó5ˆIð	=Ø×&Ñ&Ó(ˆDð
 œTŸZ™Z›\×-Ñ-Ð.¨fÐ5ˆô (ˆð	,Ü!Ÿ=™=¬¯©Ô9JÓKˆLð-	9ð=Ø× Ñ  Ô&ð@Ø—o‘o d¨IÓ6�ô —w‘w—|‘| D§I¡I¨zÓ:ˆHÜ�h ¨gÔ6ð #¸"Ü—	‘	˜#˜rÔ"÷#ð2Ø×)Ñ)¨$¯)©)°T¸8ÀTÓJ�ðeÜ!×'Ñ'Ø¤
§¡¼
¿¹ÔPZ×P_ÑP_ØŸ	™	¤t¨D¯L©LÓ'9ÀÐRVØ&*ô�ð —_‘_ T¨4°Ó9ˆFð �O‰O˜DÔ!Ø—‘ t¨T×-BÑ-BÓCˆHÜ×&Ñ& v¸ÔAð
 Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Ô?ð �O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8øôc "ò 	.Ü˜U C§H¡HÓ-Õ-ûð	.ûô& "ò 	.Ü˜U C§H¡HÓ-Õ-ûð	.ûô ò 	=Ü˜UÐ$;Ó<Ò<ð	=ûô œGÐ$ò 	,Ü+‹Lð	,ûô
 ò =Ü  Ð(;Ó<Ñ<ðD Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ðU=ûô ×(Ñ(ò Cô ! Ð(AÓBÑBð8 Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ôE ò @Ü  Ð(>Ó?Ñ?ð4 Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ðE@ú÷#ñ #ûô &ò 2Ü  ¨¯©Ó1Ô1ð& Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ûð72ûô ò eÜ  ¨ÌÏÉÓIYÐ\cÑIcÔdÑdð Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ð'eûô #¤GÐ,ò Úðûô !ò 	fä˜UÐ$7Ì$Ï.É.ÓJZÐ]dÑJdÔeÑeàÔ#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8ð	fûð Ô#3Ñ3ðÜ—M‘M¤&§.¡.°,Õ?øÜ"¤GÐ,ò Ùðúà�O‰O˜DÔ!Ø×Ñ˜TÔ"Ü�M‰M˜$Ÿ)™)°4Ö8úsÖ  –$M ÄN  Ä*N, Å#(O ÆO# ÆR Æ18] Ç)WÈ ] È	W È(A%Z
 ÊA] Ë,$]Í	M=ÍM8Í2M=Í8M=Î 	N)Î	N$ÎN)Î$N)Î,OÏOÏO ÏO Ï#RÏ8] Ð$P'Ð'P9Ð8P9Ò RÒ] ÒWÒ#] Ò-$SÓS$Ó#S$Ô+WÔ?] Õ	$U.Õ.V Õ?V ×W×] ×W×] ×	Z×!Z×6Z×7] Ø$X)Ø)X;Ø:X;ÚZÚ] Ú
,\?Ú6] Û $[%Û%[7Û6[7Ü>\?Ü?] Ý]Ý]Ý,`Þ` Þ$^3Þ3_ß_à`à` à	bà$`?à>bà?aábáaáAbc                óB  — t         j                  j                  |j                  «      }t         j                  j	                  |t
        «      }	 t        j                  |t         j                  t         j                  z  t         j                  z  t         j                  z  «      }	 t        j                  |«      }t        j                  |j                  «      s	 t        j                   |«       yt         j                  j                  |«      }||k7  s"t         j                  j#                  |«      |k7  r	 t        j                   |«       yt%        «       }t'        d|«      dz   }	t)        |«      |	k  rF	 t        j*                  ||	t)        |«      z
  «      }
|
sn |j/                  |
«       t)        |«      |	k  rŒFt1        |dt'        d|«       «      t        j                   |«       S # t        $ r Y yw xY w# t,        $ r Y ŒGw xY w# t        j                   |«       w xY w)a  Liest <workspace>/last.txt rennfrei: EIN open mit O_NOFOLLOW|O_NONBLOCK (kein Symlink-
        Folgen), fstat auf den geoeffneten fd (S_ISREG), und der aufgeloeste Pfad muss direkt
        unter dem realpath-Workspace liegen. Wird erst nach stop_scope aufgerufen (Review #7).r   r   N)r#   rD   rÂ   r±   r’   ÚLAST_TXTrô   ÚO_RDONLYÚ
O_NOFOLLOWÚ
O_NONBLOCKÚ	O_CLOEXECr‚   ÚfstatÚstatÚS_ISREGÚst_modeÚcloseÚdirnameÚ	bytearrayÚmaxrA   ÚreadÚBlockingIOErrorÚextendrç   )rv   r¢   Úlimitr‹   rD   ÚfdÚstÚrealÚdataÚwantÚchunks              r   rú   zCagedCodexRunner._read_lastS  s“  € ô �W‰W×Ñ˜dŸn™nÓ-ˆÜ�w‰w�|‰|˜B¤Ó)ˆð	Ü—‘˜œrŸ{™{¬R¯]©]Ñ:¼R¿]¹]ÑJÌRÏ\É\ÑYÓZˆBð	Ü—‘˜"“ˆBÜ—<‘< §
¡
Ô+Øô  �H‰H�R�Lô —7‘7×#Ñ# DÓ)ˆDØ�tŠ|œrŸw™wŸ™¨tÓ4¸Ò:Øô �H‰H�R�Lô “;ˆDÜ�q˜%“= 1Ñ$ˆDÜ�d“)˜dÒ"ðÜŸG™G B¨¬s°4«yÑ(8Ó9�Eñ ØØ—‘˜EÔ"ô �d“)˜dÓ"ô ˜˜o¤ A u£Ð.Ó/ä�H‰H�R�Løô+ ò 	Ùð	ûô 'ò Ùðûô �H‰H�R�LúsV   ÁAG) Â'4H Ã2AH Å'H Å7"G8 Æ"H Æ<H Ç)	G5Ç4G5Ç8	HÈH ÈHÈH ÈH)rV   rm   rX   rm   rY   rn   rZ   rm   r[   zOptional[Mapping[str, str]]r\   rm   r]   Úintr^   zOptional[set]r_   Úfloatr`   r  ra   r  rb   úOptional[str]rc   r  rd   rn   ©Úreturnrn   )r  ú	P.RunDirs)r¢   r   r  ÚNone)r¢   r   r¥   rm   r  rp   )r¢   r   r¶   rm   r·   rm   )r  rm   )r  r!  )r·   rm   r  r!  )rý   r   r  r   )r¢   r   r  r  r  rç   )r   r   r   rj   r‡   r™   r£   r«   r½   rÄ   rÇ   rÌ   rÎ   r�   rú   Ú__classcell__)rw   s   @r   rS   rS   †   s  ø„ Ø9?ÐQUØ"?Ð]bØ".ÐW[Ø';ÐPQØ/3ÐQTØ,/ÈSØ,0ÈTØ)-¸rñ&[Øð&[ØVZð&[àð&[à9Tð&[ð "%ð&[ð KNð&[ð  -ð	&[ð JOð	&[ð
 %*ð&[ð
 FKð&[ð *ð&[ð >Kð&[ð #'õ&[óRCófó>ó
`óó"&óó&ó.óU9÷nr   rS   )rS   r&   rQ   r   )r%   zOptional[int]r  rp   )r  rp   r  )/r   Ú
__future__r   rü   rõ   r#   rœ   rï   r
  r€   r�   rä   rë   Úpathlibr   Útypingr   r   Ú r   r	   r
   rs   Úrunnerr   r   r   r   r   r?   r  Úobjectrî   ÚBaseExceptionr   r   rr   r&   r3   rB   rC   Ú	frozensetrG   rH   rQ   rS   Ú__all__r   r   r   ú<module>r,     s¿   ðñõ* #ã Û Û 	Û Û Û Û Û Û Û Ý ß $ç *Ý ß _Õ _à€Ø€á“8Ð ôc˜ô còð €ôóð  %€ð C€á 	˜{Ó+Ð Ù ¨$Ð/Ó0Ð ó%ôPjÐ'ô jòZ K�r   