Living Document Notice
Published 2026-09-16. The evolving architecture, revisions, and connected notes for this dispatch live in the Stax Digital Garden.

Sandboxing AST Extensions with Outrigger

Sandboxing AST Extensions with Outrigger: Abstract monochrome amber phosphor CRT isolated geometric core within nested concentric boundary rings over coordinate graticule grid

Summary

Allowing user-written plugins to alter Markdown syntax trees introduces stability and security vulnerabilities. Conventional script runtimes that execute third-party code with full host filesystem privileges expose user vaults to malicious file access and unbounded CPU execution loops.

Bosun isolates third-party transformation hooks within the Outrigger Protocol WebAssembly System Interface (WASI) runtime. By constraining plugins to isolated memory spaces with explicit fuel metering, extensions can transform syntax nodes without obtaining access to the operating system or blocking the host engine thread.

Capability-Based WASI Isolation

Outrigger executes plugins as compiled WebAssembly modules with zero default capabilities. The host engine denies access to host environment variables, system clocks, network sockets, and directory trees.

pub struct SandboxConfig {
    pub max_memory_pages: u32,
    pub initial_fuel: u64,
    pub allowed_directories: Vec<PathBuf>,
}
 
impl SandboxConfig {
    pub fn restricted_ast_transform() -> Self {
        Self {
            max_memory_pages: 128, // 8 MB limit
            initial_fuel: 50_000_000,
            allowed_directories: Vec::new(),
        }
    }
}

If an extension module attempts to open file handles or invoke OS syscalls, the WASI host layer returns an access denied error code, aborting execution immediately.

Host functions exposed to guest modules are restricted to pure mathematical operations and string span evaluations. No raw pointers into host memory are ever shared with the guest execution environment.

Deterministic Fuel Metering and Instruction Limits

Unbounded recursion or infinite loops inside user plugins can stall processing pipelines. Outrigger prevents denial-of-service conditions by injecting fuel consumption checks into compiled WebAssembly basic blocks.

store.set_fuel(50_000_000).unwrap();
let result = instance
    .get_typed_func::<(), ()>(&mut store, "transform_ast")
    .unwrap()
    .call(&mut store, ());
 
match result {
    Ok(_) => println!("Transformation completed successfully"),
    Err(trap) if store.get_fuel().unwrap_or(0) == 0 => {
        eprintln!("Plugin exceeded execution fuel allocation");
    }
    Err(trap) => eprintln!("Plugin trapped: {trap}"),
}

Each executed instruction decrements the fuel counter. When fuel reaches zero, the WebAssembly runtime traps, allowing the host engine to log the offending plugin and continue processing remaining vault files.

Fuel bounds are calibrated to allow complex syntax transformations across 10,000-line files while capping runtime execution to under 25 milliseconds per document.

AST Serialization and Host-Guest Memory Exchange

AST nodes pass into the sandbox via shared linear memory buffers using a flat binary representation. The host serializes target subtrees into guest memory, passes the offset, and reads back modified node buffers upon completion.

This memory boundary prevents guest modules from corrupting host pointer addresses or tampering with adjacent document memory spaces.

The serialized format uses compact integer offsets and enum tags, avoiding JSON serialization overhead and keeping inter-boundary transfer latency below 15 microseconds.

Sandbox Execution Overhead and Fuel Consumption

The table below details performance and overhead metrics for sandboxed plugin executions under Outrigger.

Extension OperationSandbox InstantiationFuel ConsumedExecution OverheadMemory Quota Ceiling
Tag Normalizer Hook0.42 ms120,400 units48 μs8 MB
Wikilink Alias Expander0.44 ms310,200 units85 μs8 MB
Callout Block Transformer0.45 ms890,500 units164 μs16 MB
Custom Math Renderer0.51 ms2,410,000 units420 μs32 MB

  • Directus Target: bosunpkm-blog
  • Garden Source Reference: MOC - Bosun PKM Engine, MOC - Bosun PKM Tools, MOC - Outrigger Protocol, MOC - Agentic Containment and Sandbox Boundaries, [OUT-1001 - Verifying Autonomous Agent Bounds with Pure Standard Library](OUT-1001 - Verifying Autonomous Agent Bounds with Pure Standard Library)