Skip to content

Commit 17cacf5

Browse files
committed
chore: save WIP before removing native/wasmvm (moved to agent-os-registry)
1 parent 794caaf commit 17cacf5

51 files changed

Lines changed: 757 additions & 4945 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agent/contracts/node-bridge.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Define bridge boundary policy, third-party module boundaries, and capability expansion controls.
55
## Requirements
66
### Requirement: Bridge Scope Is Node Built-ins Only
7-
Bridge implementations injected into isolated-vm MUST be limited to Node.js built-in modules and types compatible with `@types/node`.
7+
Bridge implementations injected into the V8 isolate MUST be limited to Node.js built-in modules and types compatible with `@types/node`.
88

99
#### Scenario: Bridge request targets a third-party package
1010
- **WHEN** a proposed bridge module is not a Node.js built-in

CLAUDE.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,10 @@
122122
- the goal for WasmVM is full POSIX compliance 1:1 — every command, syscall, and shell behavior should match a real Linux system exactly
123123
- WasmVM and Python are experimental surfaces in this repo
124124
- all docs for WasmVM, Python, or other experimental runtime features must live under the `Experimental` section of the docs navigation, not the main getting-started/reference sections
125-
- the WasmVM runtime requires standalone WASM binaries in `native/wasmvm/target/wasm32-wasip1/release/commands/`
126-
- build them locally: `cd native/wasmvm && make wasm` (requires Rust nightly + wasm32-wasip1 target + rust-src component + wasm-opt/binaryen)
127-
- the Rust toolchain is pinned in `native/wasmvm/rust-toolchain.toml` — rustup will auto-install it
128-
- CI builds the binaries before tests; a CI-only guard test in `packages/wasmvm/test/driver.test.ts` fails if they're missing
129-
- story-critical C-built Wasm fixtures also have CI-only availability guards in `packages/wasmvm/test/ci-artifact-availability.test.ts` and `packages/secure-exec/tests/kernel/ci-wasm-artifact-availability.test.ts`; if they fail, rebuild with `make -C native/wasmvm/c sysroot && make -C native/wasmvm/c programs`
125+
- **All WASM command source code (Rust crates and C programs) has been moved to the agent-os-registry repo at `~/agent-os-registry/`** (GitHub: `rivet-dev/agent-os-registry`). The `native/wasmvm/` directory in this repo is the original copy and should no longer be the primary source for building commands. Build from the registry instead: `cd ~/agent-os-registry && make build-wasm`.
126+
- the WasmVM runtime driver (`packages/wasmvm/`) still lives in this repo. It loads and executes WASM binaries but does not contain command source code.
130127
- tests gated behind `skipIf(!hasWasmBinaries)` or `skipUnlessWasmBuilt()` will skip locally if binaries aren't built
131-
- see `native/wasmvm/CLAUDE.md` for full build details and architecture
128+
- the `native/wasmvm/` directory remains for reference and WASI host import definitions (`crates/wasi-ext/`), patches (`patches/`), and the C sysroot build
132129

133130
## WasmVM Syscall Coverage
134131

docs-internal/arch/active-handles.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Problem
44

5-
The sandboxed Node.js environment uses `isolated-vm` (V8 isolates) to run JavaScript code. Unlike real Node.js, isolated-vm does not have an event loop. Code runs synchronously and the sandbox exits immediately when the script finishes executing.
5+
The sandboxed Node.js environment uses V8 isolates to run JavaScript code. Unlike real Node.js, the V8 isolate does not have an event loop. Code runs synchronously and the sandbox exits immediately when the script finishes executing.
66

77
This causes problems with async APIs that use callbacks:
88

@@ -31,7 +31,7 @@ In real Node.js:
3131
4. Callbacks fire as events occur
3232
5. Process exits when no more active handles remain
3333

34-
In isolated-vm:
34+
In the V8 isolate:
3535
1. Script sets up event handlers
3636
2. Script finishes synchronous execution
3737
3. `exec()` returns immediately - no event loop
@@ -137,7 +137,7 @@ Active handles: [
137137

138138
| Feature | Node.js | secure-exec |
139139
|---------|---------|----------------|
140-
| Event loop | Built-in libuv | None (isolated-vm) |
140+
| Event loop | Built-in libuv | None (V8 isolate) |
141141
| Handle tracking | Automatic via libuv | Manual via `_registerHandle` |
142142
| `ref()`/`unref()` | Per-handle methods | Not implemented (all handles keep alive) |
143143
| Debugging | `process._getActiveHandles()` | `_getActiveHandles()` |

docs-internal/arch/kernel-integration.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ All kernel operations run on the **main thread** (the event loop). Each runtime'
8787
| Runtime | Execution Context | Sync Mechanism |
8888
|---------|------------------|----------------|
8989
| WasmVM | Web Worker (WASM instance) | SharedArrayBuffer + Atomics.wait |
90-
| Node | V8 Isolate (isolated-vm) | ivm.Reference (applySyncPromise) |
90+
| Node | V8 Isolate | Reference (applySyncPromise) |
9191
| Python | Node Worker (Pyodide) | Worker postMessage |
9292

93-
The main thread services all runtimes via the event loop. When a WasmVM Worker needs a file, it posts a message and blocks on `Atomics.wait`. The main thread handles the request and calls `Atomics.notify`. When a V8 isolate needs a file, the `ivm.Reference` suspends the isolate, the main thread resolves the promise, and the isolate resumes. No dedicated kernel worker needed.
93+
The main thread services all runtimes via the event loop. When a WasmVM Worker needs a file, it posts a message and blocks on `Atomics.wait`. The main thread handles the request and calls `Atomics.notify`. When a V8 isolate needs a file, the Reference suspends the isolate, the main thread resolves the promise, and the isolate resumes. No dedicated kernel worker needed.
9494

9595
---
9696

@@ -1031,7 +1031,7 @@ WasmVM internal docs stay with WasmVM. Only cross-project docs go to the top lev
10311031
2. Build instructions — `wasm32-wasip1`, nightly Rust, `-Z build-std`
10321032
3. Key decisions — brush-shell, uutils/sed, awk-rs, ripgrep, jaq, custom find
10331033
4. Dependency patching — three-tier: direct dep → vendor+patch → full fork
1034-
5. Why not Wasmtime/WASIX/Component Model
1034+
5. Why not native WASM runtimes/Component Model
10351035
6. Naming — `wasmvm/crates/`, `wasmvm/stubs/`, `wasmvm/patches/`
10361036
7. Deferred items → `wasmvm/notes/todo.md`
10371037

docs-internal/attack-vectors.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Catalog of known attack vectors against the sandbox runtime.
1111

1212
| Vector | Layer | Mitigated? | Notes |
1313
| ----------------------------------- | ------- | ---------- | -------------------------------------------------------------------------------------------- |
14-
| Infinite loop in sandbox code | Runtime | Partial | isolated-vm timeout via `cpuTimeLimitMs`. Gap: optional, no default; unset = no limit |
14+
| Infinite loop in sandbox code | Runtime | Partial | V8 isolate timeout via `cpuTimeLimitMs`. Gap: optional, no default; unset = no limit |
1515
| ReDoS (catastrophic regex) | Runtime | Partial | Caught by same CPU timeout. Gap: same; no per-regex complexity limit |
1616
| Crypto cost abuse (pbkdf2/scrypt) | Runtime | No | No caps on iterations/N/r/p parameters. Burns host CPU outside isolate timeout |
1717
| JSON.parse bomb on host | Runtime | No | 8 host-side JSON.parse calls, no size check. Runs in host process; isolate limits don't help |
@@ -20,7 +20,7 @@ Catalog of known attack vectors against the sandbox runtime.
2020

2121
| Vector | Layer | Mitigated? | Notes |
2222
| ----------------------------------- | ------- | ---------- | --------------------------------------------------------------------------------------- |
23-
| Isolate heap exhaustion | Runtime | Yes | isolated-vm `memoryLimit` (default 128MB). OOM kills isolate, not host process |
23+
| Isolate heap exhaustion | Runtime | Yes | V8 isolate `memoryLimit` (default 128MB). OOM kills isolate, not host process |
2424
| Base64 amplification on host | Runtime | No | 50MB file → 67MB base64 on host heap. No transfer size cap; host OOM possible |
2525
| Timer/interval bombing | Runtime | No | Bridge timer map grows unbounded. No limit on count of active timers |
2626
| stdout/stderr accumulation | Runtime | No | Output arrays grow unbounded on host. No cap on captured output size |
@@ -37,7 +37,7 @@ Catalog of known attack vectors against the sandbox runtime.
3737

3838
| Vector | Layer | Mitigated? | Notes |
3939
| ----------------------------------- | ------- | ---------- | --------------------------------------------------------------------------------------- |
40-
| Prototype pollution across boundary | Runtime | Likely safe | isolated-vm copies values, no shared prototypes. Needs verification test |
40+
| Prototype pollution across boundary | Runtime | Likely safe | V8 isolate copies values, no shared prototypes. Needs verification test |
4141
| Reference argument type confusion | Runtime | No | Host References don't validate argument types. String expected, object passed → UB |
4242
| Bridge global overwriting | Runtime | No | `_fs`, `_registerHandle` etc. are writable. Impact: self-sabotage / host hang, not escape |
4343
| Module resolution path traversal | Driver | Partial | VirtualFileSystem abstracts scope. Gap: no path canonicalization before permission check |

docs-internal/comarison.mdx

Lines changed: 0 additions & 22 deletions
This file was deleted.

docs-internal/friction.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
1. **[resolved]** `NodeRuntime` constructor ownership drifted between driver and direct adapter options.
4343
- Symptom: runtime capability and config ownership was split across `NodeRuntime` fallbacks and `createNodeDriver`, which made permission defaults and runtime injection behavior harder to reason about.
4444
- Fix: `NodeRuntime` now requires a `driver`, reads `processConfig`/`osConfig` from `driver.runtime`, and no longer accepts direct constructor adapters/permissions.
45-
- Follow-up: a dedicated pass should continue moving remaining `isolated-vm` execution internals from `NodeRuntime` into the Node driver implementation.
45+
- Follow-up: a dedicated pass should continue moving remaining V8 isolate execution internals from `NodeRuntime` into the Node driver implementation.
4646
2. **[resolved]** Browser runtime surface needed temporary de-scope during driver boundary refactor.
4747
- Symptom: maintaining Worker/browser runtime paths during Node driver ownership changes increased refactor risk and cross-runtime drift.
4848
- Fix: browser package exports were removed for this phase and browser entrypoints now return deterministic unsupported errors until follow-up restoration.
@@ -142,7 +142,7 @@
142142
- Symptom: requests reached the sandbox server but responded `400`; root cause was `instanceof http2.Http2ServerRequest` checks throwing when `http2` constructors were undefined.
143143
- Fix: added built-in `http2` compatibility stubs (`Http2ServerRequest`/`Http2ServerResponse`) and routed `require('http2')` / ESM `import 'http2'` to that stub module.
144144

145-
5. **[resolved]** Direct cloning of ESM module namespace objects failed in `isolated-vm`.
145+
5. **[resolved]** Direct cloning of ESM module namespace objects failed in the V8 isolate layer.
146146
- Symptom: using `entryModule.namespace.copy()` for `run()` exports failed with `[object Module] could not be cloned`.
147147
- Fix: after ESM evaluation, bind the namespace in isolate scope and copy `Object.fromEntries(Object.entries(namespace))` to the host.
148148

docs-internal/glossary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
- **Runtime** — the full `secure-exec` execution environment including the isolate, bridge, and resource controls. `NodeRuntime` and `PythonRuntime` are the public entry points.
55
- **Bridge** — the narrow layer between the isolate and the host that mediates all privileged operations. Untrusted code can only reach host capabilities through the bridge.
66
- **SystemDriver** — config object that bundles what the isolate can access (filesystem, network, command executor, permissions). Deny-by-default. Built by `createNodeDriver()` or `createBrowserDriver()`.
7-
- **Execution Driver** — host-side engine that owns the isolate lifecycle. `NodeExecutionDriver` (V8 via `isolated-vm`), `BrowserRuntimeDriver` (Web Worker), `PyodideRuntimeDriver` (Pyodide in a Node worker).
7+
- **Execution Driver** — host-side engine that owns the isolate lifecycle. `NodeExecutionDriver` (V8 isolate), `BrowserRuntimeDriver` (Web Worker), `PyodideRuntimeDriver` (Pyodide in a Node worker).

docs-internal/research/comparison/browser-node-runtimes.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ A comparison of tools that run Node.js-compatible code in browsers or sandboxed
8989

9090
### libsandbox (secure-exec)
9191

92-
**What it is:** A driver-based sandboxed Node.js runtime with two backends: `isolated-vm` for Node.js (V8 isolate-level isolation) and Web Workers for browsers. Designed for executing code snippets with controlled API access.
92+
**What it is:** A driver-based sandboxed Node.js runtime with two backends: V8 isolates for Node.js (isolate-level isolation) and Web Workers for browsers. Designed for executing code snippets with controlled API access.
9393

94-
**Architecture:** A unified bridge layer provides Node.js APIs (fs, process, child_process, network, os) that work identically across both drivers. The Node driver uses `isolated-vm` to create V8 isolates with explicit `Reference`-based bridges. The browser driver uses Web Workers with `postMessage` communication. A permission system gates access to filesystem, network, child process, and environment operations.
94+
**Architecture:** A unified bridge layer provides Node.js APIs (fs, process, child_process, network, os) that work identically across both drivers. The Node driver uses V8 isolates with explicit `Reference`-based bridges. The browser driver uses Web Workers with `postMessage` communication. A permission system gates access to filesystem, network, child process, and environment operations.
9595

9696
**Strengths:**
9797
- Strong isolation on Node.js (V8 isolate — separate heap)
@@ -108,7 +108,7 @@ A comparison of tools that run Node.js-compatible code in browsers or sandboxed
108108
- Browser driver isolation is weaker (Worker global scope is accessible)
109109
- No npm package installation
110110
- No real `node_modules` resolution (polyfills via node-stdlib-browser)
111-
- `isolated-vm` is a native addon (complicates deployment)
111+
- The V8 isolate package is a native addon (complicates deployment)
112112
- Single-threaded execution per isolate/Worker
113113

114114
**Node API coverage:** Targeted. Covers fs (full CRUD), path, process, child_process (spawn, exec, spawnSync, execSync, fork), http/https, fetch, dns, os, Buffer, URL, stream, events, timers, console, and modules via node-stdlib-browser polyfills.
@@ -119,7 +119,7 @@ A comparison of tools that run Node.js-compatible code in browsers or sandboxed
119119

120120
| Feature | WebContainers | Sandpack/Nodebox | almostnode | libsandbox |
121121
|---|---|---|---|---|
122-
| **Architecture** | WASM OS | Worker + bundler | In-memory JS | isolated-vm / Worker |
122+
| **Architecture** | WASM OS | Worker + bundler | In-memory JS | V8 Isolate / Worker |
123123
| **Bundle size** | ~10MB+ | ~2MB (Sandpack) | ~250KB target | ~500KB (with bridge) |
124124
| **Startup time** | 2-5s | 500ms-2s | <10ms | <10ms |
125125
| **Node API coverage** | High | Moderate | Partial | Targeted |
@@ -138,7 +138,7 @@ A comparison of tools that run Node.js-compatible code in browsers or sandboxed
138138

139139
libsandbox occupies a distinct niche: **fast, secure, dual-environment code execution** rather than full development environment simulation. Key differentiators:
140140

141-
1. **Security-first**: libsandbox is the only option with real memory isolation (via isolated-vm) and a structured permission system. WebContainers relies on browser sandboxing; almostnode has no isolation.
141+
1. **Security-first**: libsandbox is the only option with real memory isolation (via V8 isolates) and a structured permission system. WebContainers relies on browser sandboxing; almostnode has no isolation.
142142

143143
2. **Node.js as primary target**: libsandbox is designed to run on Node.js servers (for AI agent backends, code execution APIs) with browser as a secondary target. WebContainers and Sandpack are browser-first.
144144

docs-internal/research/comparison/cloudflare-workers-isolates.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ Cascading defense:
5050

5151
## Comparison with libsandbox
5252

53-
libsandbox uses `isolated-vm` (also V8 isolates) and shares some of the same principles.
53+
libsandbox uses V8 isolates and shares some of the same principles.
5454

5555
| Aspect | Cloudflare Workers | libsandbox |
5656
|---|---|---|
57-
| Isolate tech | V8 (custom workerd) | V8 (isolated-vm) |
57+
| Isolate tech | V8 (custom workerd) | V8 isolate |
5858
| Default posture | Zero capabilities | Zero capabilities |
5959
| Permission model | Capability bindings in config | Function-based permission checks |
6060
| FS access | Blocked at syscall level | No FS unless VirtualFileSystem provided |
@@ -65,7 +65,7 @@ libsandbox uses `isolated-vm` (also V8 isolates) and shares some of the same pri
6565
| OS-level sandbox | seccomp + namespaces | **None** |
6666
| Spectre mitigations | Frozen clocks, perf counters, process isolation | Default frozen timing mode + `SharedArrayBuffer` removed (`timingMitigation: "freeze"`) |
6767
| eval/dynamic code | Blocked during request handling | **Not restricted** |
68-
| Native code | Blocked (JS/Wasm only) | Blocked (isolated-vm limitation) |
68+
| Native code | Blocked (JS/Wasm only) | Blocked (V8 isolate limitation) |
6969

7070
### What libsandbox does well
7171

@@ -91,10 +91,10 @@ libsandbox uses `isolated-vm` (also V8 isolates) and shares some of the same pri
9191

9292
### 2. No OS-level sandboxing (MEDIUM-HIGH)
9393

94-
The host Node.js process has full OS access. If there is ever an isolated-vm escape (V8 bug), the attacker owns the host process with all its permissions. Cloudflare wraps everything in seccomp + empty namespaces.
94+
The host Node.js process has full OS access. If there is ever a V8 isolate escape (V8 bug), the attacker owns the host process with all its permissions. Cloudflare wraps everything in seccomp + empty namespaces.
9595

9696
**Recommendation:**
97-
- Document that isolated-vm alone is not sufficient for running untrusted code from the internet
97+
- Document that V8 isolates alone are not sufficient for running untrusted code from the internet
9898
- Provide guidance for users to run the host process in a container with minimal capabilities (`--cap-drop=ALL`)
9999
- Consider optional integration with Linux namespaces or seccomp for the host process
100100

@@ -117,7 +117,7 @@ The host Node.js process has full OS access. If there is ever an isolated-vm esc
117117

118118
Cloudflare blocks these during request handling because they make forensic analysis of exploits harder and expand the attack surface for V8 bugs.
119119

120-
**Recommendation:** Add an option to disable dynamic code generation in the isolate. `isolated-vm` may support this via V8 flags or by overriding these globals in the bridge.
120+
**Recommendation:** Add an option to disable dynamic code generation in the isolate. The V8 isolate package may support this via V8 flags or by overriding these globals in the bridge.
121121

122122
### 5. No resource limits on child processes/network (LOW-MEDIUM)
123123

0 commit comments

Comments
 (0)