aido-runtime

Every action the agent runs
passes through here.

Tu peux simuler avant, snapshot avant, annuler si ça casse.

policy chain · per action live
always_allow · meta? policy_check, simulate, …no
desktop_gate · is_desktop_action()?pass
mode · readonly / confirm?confirm
action_enabled · per-action switchtrue
pipeline_preflight · all steps?recurse
path_walls · allowed_read/write pathsok
deny_patterns · **/.ssh/** · /etc/shadowdeny
9 chain steps · single-pass evaluation ~5 µs
primitives · 58 total

Every primitive is typed, classified, audited.

No free-form actions, no string-blob arguments. Each primitive is a Rust enum Action variant · the policy engine, the simulator, the audit log all introspect the same tree. Add a primitive in one place, the safety chain picks it up everywhere.

Safety

7

The headline family. simulate projects what would happen; everything else gates or reverts.

simulatepolicy_checksafe_changepipelinetryifassertvalidate

Filesystem (typed)

10

Read + write through the policy + audit chain. Shell does the trivia (ls/cat/find); the runtime owns the writes.

read_fileread_fileswrite_fileedit_fileapply_patchpatch_setstat_filesfile_infochecksummove_to_trash

Process & sandbox

3

The only ways the agent spawns a process · and each one is policy-gated. run_in_sandbox wraps in Podman.

run_commandrun_in_sandboxrun_container_groupssh_exec

Snapshots

4

btrfs/zfs reflink · O(1) create, < 200 ms restore. The agent's undo button.

create_snapshotrestore_snapshotlist_snapshotsdelete_snapshot

Memory · cross-session

4

Persistent remember store at ~/.aido/memory/. Survives restarts, agents, projects.

rememberrecallforgetlist_memory

Events & handles

4

Reactive primitives + async handle bookkeeping. watch_and_react wires file events to actions.

subscribecheck_handlestop_handlelist_handleswatch_and_react

Composite primitives

8

The agent defines new tools at runtime. Rhai today, WASM next. Each defined function is exposed as its own MCP tool to other agents.

define_functioncall_functionlist_functionsdelete_functiondefine_primitivecall_primitivelist_custom_primitivesdelete_primitive

Desktop · computer-use

14

Wayland-native click / type / screenshot / clipboard. Gated by desktop.enabled and policy. For the agent that drives a host UI.

screenshotclickdouble_clickmove_mousescrolltype_textpress_keypress_key_combinationfocus_windowget_window_treeget_focused_windowget_clipboardset_clipboardsend_notification

Artifacts

6

Sandboxed localhost-served outputs. The agent generates a webapp / canvas → user opens it at localhost:7800/a/<id>/.

artifact_createartifact_listartifact_serveartifact_saveartifact_stopartifact_destroy

Network & LLM

5

Outbound HTTP + the agent's ability to call sibling LLMs. Multi-agent native · llm_call is just a tool.

http_requestfetch_urlport_checkdns_lookupllm_callollama_chatollama_api

Search

2

Multi-pattern regex search + read combiner. The "give me the function and its 3 callers in one shot" primitive.

search_codesearch_and_read

Human-in-loop & misc

8

Approval gates + diff + structured logs. The bits that let the agent pause safely.

ask_humanconfirmask_multiple_choicediffread_logsrandom_byteslist_processesrender_template
policy engine

Every action gets classified before it runs.

The policy engine is the heart of aido-runtime. Each Action variant falls into one of 8 side-effect classes. The classifier feeds every safety primitive · simulate uses it to project, policy_check uses it to gate, the audit log uses it to label. Classify once, reuse everywhere.

read_only
read_file · search_code · stat_files · checksum · list_processes
fs_write
write_file · edit_file · apply_patch · patch_set
process_spawn
run_command · run_in_sandbox · ssh_exec · watch_and_react
network
http_request · fetch_url · dns_lookup · port_check · llm_call
desktop
screenshot · click · type_text · scroll · set_clipboard
destructive
move_to_trash · delete_snapshot · artifact_destroy · forget · restore_snapshot
composite
pipeline · try · safe_change · if · render_template · simulate
meta
policy_check · check_handle · list_handles · remember · recall
// The classifier is public, callable from any executor module. // `Simulate` walks the tree and asks for a verdict per leaf. pub fn classify(&self, action: &Action) -> SideEffectClass { if is_composite(action) { return SideEffectClass::Composite; } if is_network_action(action) { return SideEffectClass::Network; } if is_destructive_action(action) { return SideEffectClass::Destructive; } if self.is_desktop_action(action) { return SideEffectClass::Desktop; } if self.is_run_command(action) { return SideEffectClass::ProcessSpawn; } if self.is_write_action(action) { return SideEffectClass::FsWrite; } if self.is_read_action(action) { return SideEffectClass::ReadOnly; } SideEffectClass::Meta }
safety mechanisms

Six gates between intent and execution.

The agent's typed call goes through 6 independent layers before anything mutates state. Most never trigger · most calls are read_only on allowed paths. But when an action is risky, at least one of these stops it.

01

Per-action enable map

Boolean per action type · actions.toml can disable RunCommand entirely. Always-allow list bypasses for meta tools.

02

Mode gate

readonly blocks all writes/spawns/desktop. confirm turns every mutation into a RequireConfirmation verdict.

03

Path walls

allowed_read_paths + allowed_write_paths with tilde expansion. Symlinks resolved before check · no ../ escapes.

04

Deny patterns

Glob blacklist (**/.ssh/**, /etc/shadow, **/.env). Wins over allow paths. The "no matter what" backstop.

05

Pipeline preflight

Composite actions (Pipeline / Try / SafeChange / If) get every leaf preflighted before the first step runs. Atomic refusal.

06

simulate · the new one

The dry-run primitive: walks the tree, projects side effects, returns the verdict aggregate · 0 mutations, < 1 ms typical.

build profile

Ship only what you need.

Optional primitive families are cargo features. Build with just prim-network for a headless code agent. Add prim-desktop for computer-use. The default all-prims ships everything.

featurewhat it shipsdefault
all-prims Meta-feature · enables every prim-* below. Default for the standard binary. on
prim-desktop Wayland computer-use: screenshot, click, type_text, scroll, clipboard, window tree. on
prim-network Outbound HTTP + DNS + port check. Required for any internet-reaching agent. on
prim-events Reactive primitives + async handles: subscribe / check_handle / watch_and_react. on
prim-ml llm_call, ollama_chat, dataset_generate, document_extract. Multi-agent native. on
serve HTTP/SSE serve mode · exposes /actions and /events for web frontends. on
architecture

One library, two binaries.

The crate compiles to a library (so aido-orchestrator can embed the executor in-process) and to the aido-runtime binary that exposes the same primitives over MCP stdio or HTTP.

┌── MCP client (Claude Code · Codex · aido-orchestrator · …) │ │ JSON-RPC over stdio / HTTP ▼ ┌────────────────────────────────────────────────────┐ │ aido-runtime binary │ │ ─────────────── │ │ ┌──────────────┐ ┌──────────────────────────┐ │ │ │ ToolRegistry │ │ PolicyEngine │ │ │ │ MCP schema │ │ · classify(action) │ │ │ │ → Action │ ─→ │ · evaluate(action) │ │ │ │ parser │ │ · 6 gates (see above) │ │ │ └──────────────┘ └────────────┬─────────────┘ │ │ │ │ │ ┌────────────────────────────────▼────────────┐ │ │ │ execute_action (29 executor modules) │ │ │ │ fs · process · sandbox · snapshot · … │ │ │ │ artifact · ml · desktop · events · ssh │ │ │ │ simulate · validate · template · scripted │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ │ audit JSONL ▼ ActionResult │ │ ~/.aido/audit/ · structured │ │ · stable codes │ └────────────────────────────────────────────────────┘
# Two binaries cargo build --release -p aido-runtime target/release/aido-runtime --mode mcp # stdio MCP server target/release/aido-runtime --mode serve --port 7800 # HTTP/SSE # And one library · embed the executor in-process use aido_runtime::{Action, AppConfig, PolicyEngine, execute_action}; let action = Action::Pipeline { steps: vec![ ... ], ..Default::default() }; let result = execute_action(&action, &cfg, handles, &policy, &rl, &composites).await;
quickstart

From cargo build to first action.

The runtime ships sane defaults (allowed paths under your home, deny patterns for .ssh + .env, network on, desktop off). Tighten with ~/.aido/config.toml.

# 1. Build + install cargo build --release -p aido-runtime install -m 755 target/release/aido-runtime ~/.cargo/bin/ # 2. MCP stdio (Claude Code, Codex, Cursor) # .mcp.json : { "mcpServers": { "aido": { "command": "aido-runtime", "args": ["--mode", "mcp"] } } } # 3. HTTP serve (for web frontends, observability) aido-runtime --mode serve --port 7800 # 4. Tail audit log tail -f ~/.aido/audit/$(date +%F).jsonl | jq # 5. Try simulate by hand { "name": "simulate", "arguments": { "target": { "type": "SafeChange", "steps": [ { "type": "WriteFile", "path": "/tmp/x", "content": "hi" } ] } } } # → { would_execute: true, steps: [...], side_effects: { paths_written: ["/tmp/x"] } }