Skip to content

ADR-0020: WebAssembly/WASI held as a watch item for per-tool sandboxing — not adopted

  • Status: Accepted (Watch)
  • Date: 2026-07-31
  • Deciders: El
  • Related: ADR-0014 (per-tenant container / Docker network isolation), ADR-0018 (Hermes not adopted — blast-radius reasoning), tool-execution architecture

Context

WebAssembly (WASM), with WASI for server-side system access under capability-based permissions, is a portable, language-agnostic, fast-starting, sandboxed compute unit. The question is whether it belongs in ABOS's tool-execution path.

The key mental model: WASM is not an alternative to Docker — the two nest. Docker is the coarse per-tenant isolation boundary (one container per client: separate Postgres, network, volume — ADR-0014 §5–6). WASM is a fine sandbox that runs inside a container, for a single tool or function — a per-invocation sandbox with no ambient filesystem/network access unless a capability is explicitly granted.

Decision

Do not adopt now. Hold as a watch item. WASM is a strong solution to a problem we do not yet have: safe execution of untrusted code — client-authored scriptlets, or LLM-generated tools/transforms — inside a tenant container.

  • Today, tools run via n8n and Python in the LangGraph brain. For tools we wrote and trust, that is sufficient and simpler; WASM buys nothing there.
  • WASM's value switches on precisely when the executed code is untrusted or model-generated — the same blast-radius instinct that made us reject Hermes' autonomous executor (ADR-0018), applied one level down: "run this exact function, with these inputs, and nothing else."
  • Trigger to revisit: "we are about to execute code we did not write ourselves" — per-tenant scripting, generated transforms, or shipping reusable/bespoke tools that need host-agnostic, capability-scoped execution.

It is not an AI-inference play for us: inference stays server-side via llm-client, and AU residency is solved at the infra layer, not the runtime. Separately noted: Cloudflare Workers (where the portal frontend and marketing already live) run a WASM runtime — a low-friction option for edge logic someday, unrelated to inference.

Consequences

No build now. When the trigger fires, WASM is the likely right tool for per-tool sandboxing, so we reach for it rather than reinventing a weaker sandbox. Until then it stays off the critical path, which is the gate, autonomy ladder and eval harness.

Alternatives considered

  • Adopt WASM now for all tool execution — rejected: our bottleneck is LLM latency, integration plumbing and trust, not CPU; trusted tools gain nothing from a WASM sandbox.
  • Treat WASM as a Docker replacement — rejected on the facts: different grain, different job; they nest.
  • Run untrusted/generated code directly in the tenant container (plain Python) — acceptable only while no untrusted code runs; the moment generated or client-authored code executes, revisit this ADR.