Skip to main content
When several runtimes can run the same command, the route policy picks one per line. Here monty runs python3 in-process (fast, stdlib-only) and docker runs it in your container (your packages, an exec round-trip):
policy.py
python3 /jobs/train.py runs in the container; cat data.csv | python3 -c ... stays on monty.

Input: the line’s context

The script reads one global, ctx:
commands has one entry per pipeline stage; command and builtin mirror the first. It round-trips through JSON (RouteContext.from_dict) for tests.

Output: the verdict

In code the typed forms are RouteResult and DenyResult:
A runtime entry’s own script: answers a yes or no: will it serve this line? With no placement, the first willing capturer wins. A runtime a policy places the line on must also say yes, or the line is refused with runtimes.<name> as the refusal’s policy. The caller’s runtime= argument skips the scripts.

Admit, then route

The route policy is the built-in answer to the policy’s pre_execute hook, asked before any coded policy. A coded policy places a line the same way:
A line the rules refuse is never placed. A Deny beats any Route, and two policies naming different runtimes refuse the line. Nested lines ($( ), eval, source, xargs) keep the outer line’s placement. ws.explain(line) shows each placement answer and each command’s runtime.

What runs the scripts

A script runs on an evaluator runtime from the runtimes list: a .py script on the first Python evaluator (monty, or pyodide in TypeScript), a .js one on the first JavaScript evaluator (quickjs). With no evaluator the first decision fails. A script that runs past 10 seconds fails the line. In code, route_policy= also takes a plain function, sync or async, called directly; a runtime’s script= takes (ctx) -> bool:

Bring your own

Inherit EvaluatorMixin (Python) or implement Evaluator with the EVALUATOR brand (TypeScript) on your runtime, and it can evaluate scripts: eval(code, inputs=...) returns the last expression’s value. The docker examples do it by piping a harness to python3 -: python, typescript.