grep, cat, pipes, redirects) run in the workspace itself; python3, node and any other program go to the runtime that captures them. Each runtime reaches the workspace’s files its own way.
Routing
runtimes is an ordered list: the first runtime whose captures name a program runs it, and workspace takes the rest. Without the key, the list is [monty, quickjs, workspace] in both SDKs.
name, captures, config and
script. The name is a runtime Mirage ships, one you registered in code, or
a ./file.py:Class (Python) or ./file.mjs:Class (TypeScript) reference to
your own runtime. Config keys are snake_case in YAML for both SDKs, and a
runtime rejects a key it does not know.
A route policy can pick the runtime per line instead.
Captures
captures lists the programs a runtime takes:
- Mirage’s own commands (
cat,grep,sha1sum), pipes and redirects stay in Mirage.cd,exportandechostay even when named. @externaldoes not takepython,python3,nodeorjs: Mirage has those itself and gives them to the Python or JavaScript runtime in the list. Name them to send them somewhere else.- A program no runtime takes exits 127,
command not found. - A name only
@externaltakes has no file, sowhich,command -vandtypereport it missing; running it still works. - Globs expand against the workspace first (
python3 job.py *.csvrunspython3 job.py a.csv b.csv), and permission rules judge that argv.
python3 job.py | grep error runs python3 in the container and
grep in Mirage, and ffmpeg -i a.mp4 b.webm runs in the container.
Files
Mount modes, profiles and policies apply to every file call that reaches the workspace. A host or sandbox runtime also has its own files and network, which they do not cover; only an all in-process list, with no Pyodide
init_module, keeps agent code inside them.
Resource limits
command_limits apply to a runtime’s programs as to any command: past
timeout_seconds a program exits 124 (python3: timed out after Ns), and
max_bytes and max_lines cap its output.
local, Sandlock
and the Python SDK’s QuickJS. The TypeScript SDK’s QuickJS and the other
sandboxes only stop waiting, so give untrusted code a finite workload; see
sandbox timeouts.