Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .claude/skills/publish-registry/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ just registry-publish-all [tag]

## Rules

- Do not publish registry packages from secure-exec.
- Do not publish registry packages from agentos.
- Do not move `latest` unless the user explicitly asks for a release.
- Prefer AgentOS workspace builds while iterating; published pins are for
consumers and release validation.
6 changes: 3 additions & 3 deletions .claude/skills/release-preview/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ AgentOS previews are branch snapshots from this repository. The workflow builds
debug artifacts and publishes npm packages under a sanitized branch dist-tag.
No crates.io release, git tag, or GitHub release is created.

secure-exec is a generated mirror. Do not bump a secure-exec ref or cut a
secure-exec preview by hand.
agentos is a generated mirror. Do not bump a agentos ref or cut a
agentos preview by hand.

## Procedure

Expand All @@ -32,6 +32,6 @@ npm install @rivet-dev/agentos-core@<sanitized-branch>
## Rules

- Release-preview is for previews only; releases use the `release` skill.
- All code changes belong in AgentOS. The secure-exec mirror is regenerated
- All code changes belong in AgentOS. The agentos mirror is regenerated
from AgentOS and follows the published AgentOS version.
- On failure: `gh run view <run> --log-failed`, fix, re-dispatch, re-watch.
6 changes: 3 additions & 3 deletions .claude/skills/release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ The publish flow lives in `scripts/publish` and is driven by

AgentOS is the source of truth. It publishes npm packages, crates, runtime
sidecars, Pyodide/R2 assets, and `@agentos-software/*` registry packages from
this repository. secure-exec releases are generated compatibility shims that
follow the AgentOS version; never release secure-exec first.
this repository. agentos releases are generated compatibility shims that
follow the AgentOS version; never release agentos first.

## Procedure

Expand All @@ -37,6 +37,6 @@ gh run watch -R rivet-dev/agentos "$run" --exit-status
- `scripts/publish/src/local/cut-release.ts` is a pure trigger; version changes
happen in the ephemeral CI checkout.
- `workspace:*` deps are rewritten to literal versions by the publish bump pass.
- Generated secure-exec shims are dispatched after AgentOS publishes and must
- Generated agentos shims are dispatched after AgentOS publishes and must
use the same version.
- If anything fails, stop and report — do not retry automatically.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# The Rust kernel is the substance of this repo; the rest is the TypeScript
# client/protocol/registry plus a large test suite (the kernel itself lives in
# the secure-exec repo). We count Rust in full, plus the core client surface
# the agentos repo). We count Rust in full, plus the core client surface
# (the AgentOS client entrypoint + its sidecar wire layer) and the core JS
# binary-resolver shim, and exclude everything else (tests, demos, tooling,
# generated bundles, the website, and the remaining client/registry code).
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/ci-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ jobs:
sudo apt-get install --yes cmake
fi
- run: pnpm install --frozen-lockfile
- run: node --test scripts/generate-secure-exec-mirror.test.mjs
- run: make -C toolchain commands
- run: make -C toolchain cmd/duckdb
- run: make -C toolchain codex
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ jobs:
- run: node scripts/verify-fixed-versions.mjs
- run: node --test scripts/check-layout.test.mjs
- run: pnpm check-layout
- run: node --test scripts/generate-secure-exec-mirror.test.mjs
- run: node --test scripts/check-rustfmt.test.mjs
- run: node scripts/check-rustfmt.mjs
- run: pnpm check-types
Expand All @@ -82,7 +81,6 @@ jobs:
--filter '@rivet-dev/agentos-build-tools' \
--filter '@rivet-dev/agentos-toolchain' \
--filter '@rivet-dev/agentos-runtime-sidecar' \
--filter 'secure-exec' \
test
- run: pnpm lint
continue-on-error: true
Expand Down
15 changes: 15 additions & 0 deletions .pnpmfile.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const PINNED_RIVETKIT_VERSION = "0.0.0-sqlite-uds.4e59a38";

module.exports = {
hooks: {
readPackage(pkg) {
if (pkg.name === "rivetkit" && pkg.version === PINNED_RIVETKIT_VERSION) {
// This preview bundles its ./agent-os implementation but still declares
// the retired external runtime. Keeping the declaration would restore the
// sunset package graph even though no bundled RivetKit module imports it.
delete pkg.dependencies?.["@rivet-dev/agent-os-core"];
}
return pkg;
},
},
};
9 changes: 0 additions & 9 deletions .secure-exec-local-path

This file was deleted.

16 changes: 8 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# agentOS

AgentOS owns the runtime, kernel, VFS, language execution, registry packages,
ACP/session layer, AgentOS client APIs, docs, and publish machinery. The
`secure-exec` repository is now a generated compatibility mirror only.
ACP/session layer, AgentOS client APIs, docs, and publish machinery. Agent OS
Exec is the JavaScript, TypeScript, and Python execution surface of AgentOS.

## Boundaries

Expand All @@ -16,9 +16,8 @@ ACP/session layer, AgentOS client APIs, docs, and publish machinery. The
or public API that already uses the word.
- The protocol has no backward compatibility guarantee. Client, sidecar, and
protocol crates ship in same-version lockstep; update both sides together.
- Generic runtime work belongs here, not in `../secure-exec`. Regenerate that
mirror with `node scripts/generate-secure-exec-mirror.mjs` after changing a
shimmed public surface.
- Generic runtime and language-execution work belongs here. Do not add a
compatibility mirror or a second package namespace for Agent OS Exec.
- Keep root `package.json` scripts limited to Turbo orchestration; repo-specific
commands belong in `justfile` recipes or scoped package scripts.
- AgentOS targets native Linux/container execution. Browser support is not
Expand Down Expand Up @@ -218,9 +217,10 @@ custom host-syscall imports. Treat that target as **native POSIX**;

- `scripts/publish` is the source of truth for npm/crates discovery, version
rewriting, npm publish, crates publish, release assets, and R2 upload.
- Publishable npm packages and Rust crates are AgentOS-owned. Compatibility
`@secure-exec/*`, `secure-exec`, and `secure-exec-*` artifacts are emitted
from the generated mirror.
- Publishable npm packages and Rust crates are AgentOS-owned. Agent OS Exec is
published through `@rivet-dev/agentos-javascript` and
`@rivet-dev/agentos-python`; `@rivet-dev/agentos` owns the actor API. Do not
publish compatibility artifacts or language subpaths from the actor package.
- The release workflow must build and stage the native sidecar binaries,
runtime-sidecar binaries, registry WASM commands, and pyodide assets before
publish.
Expand Down
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fixtures and benchmarks that exercise host VFS callbacks. Disabled browser
sources remain dormant reference code, not a supported production VFS.

- [x] Remove the core in-memory VFS and overlay/layer-store implementations.
- [x] Remove their root and secure-exec compatibility exports.
- [x] Remove their root and agentos compatibility exports.
- [x] Require a caller-owned filesystem in the low-level compatibility runtime.
- [x] Move remaining repository fixtures to the explicit test-only surface.
- [x] Remove obsolete duplicate semantic tests.
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"!packages/runtime-browser",
"!packages/playground",
"!packages/core/src/sidecar/generated-protocol.ts",
"!_secure-exec-sibling",
"!_agentos-sibling",
"!/**/node_modules"
],
"ignoreUnknown": true
Expand Down
8 changes: 4 additions & 4 deletions crates/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The Rust sidecar implements the kernel: virtual filesystem, process table, socke
The kernel orchestrates three execution environments:

- **WASM processes** -- POSIX utilities (coreutils, sh, grep, etc.) compiled to WebAssembly, running within the sidecar's managed runtime.
- **Node.js (V8 isolates)** -- JS/TS executes inside isolated V8 contexts managed by the sidecar's execution engine. All Node.js builtin modules (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table via synchronous RPC. Module loading is intercepted so guest code never touches real host APIs. **⚠️ CURRENTLY BROKEN**: The execution engine currently spawns real host `node` child processes instead of V8 isolates, and most builtins fall through to real host modules. This is being actively fixed. The complete working polyfill code from the original `@secure-exec` packages has been recovered to `~/.agents/recovery/secure-exec/` (source repo: `/home/nathan/secure-exec-1/`). See `crates/execution/CLAUDE.md` for the gap table and recovery file list.
- **Node.js (V8 isolates)** -- JS/TS executes inside isolated V8 contexts managed by the sidecar's execution engine. All Node.js builtin modules (`fs`, `net`, `child_process`, `dns`, `http`, `os`, etc.) are kernel-backed polyfills that route through the kernel VFS, socket table, and process table via synchronous RPC. Module loading is intercepted so guest code never touches real host APIs. **⚠️ CURRENTLY BROKEN**: The execution engine currently spawns real host `node` child processes instead of V8 isolates, and most builtins fall through to real host modules. This is being actively fixed. The complete working polyfill code from the original `@agentos` packages has been recovered to `~/.agents/recovery/agentos/` (source repo: `/home/nathan/agentos-1/`). See `crates/execution/CLAUDE.md` for the gap table and recovery file list.
- **Python (Pyodide)** -- CPython compiled to WASM via Pyodide, with kernel-backed file/network I/O.

**ALL guest code MUST execute inside the kernel with ZERO host escapes.** No runtime may spawn unsandboxed host processes, touch real host filesystems, open real network sockets, or call real Node.js builtins. Every syscall goes through the kernel. This is the single most important architectural invariant. Any path where guest code reaches the real host is a critical security violation.
Expand All @@ -19,7 +19,7 @@ These are hard rules with no exceptions:
1. **Every guest syscall goes through the kernel.** File reads go through the kernel VFS, not real `node:fs`. Network connections go through the kernel socket table, not real `node:net`. Process spawning go through the kernel process table, not real `node:child_process`. DNS resolution goes through the kernel's DNS resolver, not real `node:dns`. There are no shortcuts where guest code touches host resources directly.
2. **No real host builtins.** When a guest does `require('fs')` or `import net from 'node:net'`, the module loader must return a kernel-backed polyfill. If no polyfill exists yet, the builtin must be denied (`ERR_ACCESS_DENIED`). The loader must never fall through to Node.js's default resolution and hand the guest the real host module.
3. **The host is an implementation detail.** Guest code should not be able to observe that it is running on a host Node.js process. `process.pid` should be the kernel PID, `os.hostname()` should be the kernel hostname, `fs.readdirSync('/')` should show the kernel VFS root. `process.cwd()` should return the kernel CWD, not a host path. `process.env` must not contain internal `AGENT_OS_*` control variables. Error messages and stack traces must not reveal host filesystem paths. `require.resolve()` must return guest-visible paths, not host paths. Any host state leaking through to the guest is a bug.
4. **Polyfills are ports, not wrappers.** A path-translating shim over real `node:fs` is not a polyfill -- it is a wrapper around a host API. A real polyfill implements the API semantics using only kernel primitives (VFS, socket table, process table, pipe manager). The original JS kernel (`@secure-exec/core` + `@secure-exec/nodejs`, deleted in commit `5a43882`) had full kernel-backed polyfills for `fs`, `net`, `http`, `dns`, `dgram`, `child_process`, and `os`. The Rust sidecar must reach the same level of isolation.
4. **Polyfills are ports, not wrappers.** A path-translating shim over real `node:fs` is not a polyfill -- it is a wrapper around a host API. A real polyfill implements the API semantics using only kernel primitives (VFS, socket table, process table, pipe manager). The original JavaScript kernel packages, deleted in commit `5a43882`, had full kernel-backed polyfills for `fs`, `net`, `http`, `dns`, `dgram`, `child_process`, and `os`. The Rust sidecar must reach the same level of isolation.
5. **Control channels must be out-of-band.** The sidecar must not use in-band magic prefixes on stdout/stderr for control signaling (exit codes, metrics, signal registration). Guest code can write these prefixes to inject fake control messages. Use dedicated file descriptors, separate pipes, or a side-channel protocol for all sidecar-internal communication.
6. **Resource consumption must be bounded.** Every guest-allocatable resource must have a configurable limit enforced by the kernel: filesystem total size, inode count, process count, open FDs, pipes, PTYs, sockets, connections. Unbounded allocation from guest input is a DoS vector. The kernel's `ResourceLimits` must cover all resource types, not just processes and FDs.
Sidecar metadata parsing should start from `ResourceLimits::default()` and only override keys that are actually present; rebuilding the struct from sparse metadata drops default filesystem byte/inode caps.
Expand Down Expand Up @@ -61,8 +61,8 @@ These are hard rules with no exceptions:
- **`sandbox_agent` `pread` should prefer HTTP `Range` on `/v1/fs/file`, but older remotes may ignore it and return `200 OK`.** Keep the compatibility path that warns and slices the full response body instead of failing, because the sidecar still has to interoperate with pre-range sandbox-agent servers.
- **Native sidecar security/audit telemetry should use structured bridge events, not ad hoc strings.** In `crates/sidecar/src/service.rs`, emit security-relevant records with `bridge.emit_structured_event(...)` and include a `timestamp` field plus stable keys such as `policy`, `path`, `source_pid`, `target_pid`, or `reason` so tests and downstream aggregation can assert on them directly.
- **Native mount plugins live under `crates/sidecar/src/plugins/` and register through `plugins/mod.rs`.** Keep `host_dir`, `s3`, `google_drive`, and `sandbox_agent` there with shared registration glue, while `bridge.rs` only layers on sidecar-specific in-memory and JS-bridge plugin registration.
- **The sidecar execution driver's shell-visible builtin commands must mirror the compat runtime surface.** Seed `node` and `wasm` during `create_vm()` and preserve them when refreshing `/__secure_exec/commands/*` in `configure_vm()`, but do not materialize extra `/bin/*` runtime stubs such as `python` unless a lower snapshot or installed software explicitly provides them. Direct `ExecuteRequest { runtime: ... }` dispatch still covers runtimes that are not meant to appear in the guest filesystem.
- **Mounted WASM command directories need both command-map refresh and guest `PATH` refresh.** When `crates/sidecar/src/vm.rs` rediscovers `/__secure_exec/commands/*`, update `vm.command_guest_paths` and prepend those parent directories into `vm.guest_env["PATH"]`; `crates/sidecar/src/execution.rs` child-process resolution should search `PATH` entries before falling back to `/bin`, `/usr/bin`, and `/usr/local/bin`, or guest `child_process.spawn("sh")`/`spawn("grep")` misses mounted registry commands.
- **The sidecar execution driver's shell-visible builtin commands must mirror the compat runtime surface.** Seed `node` and `wasm` during `create_vm()` and preserve them when refreshing `/__agentos/commands/*` in `configure_vm()`, but do not materialize extra `/bin/*` runtime stubs such as `python` unless a lower snapshot or installed software explicitly provides them. Direct `ExecuteRequest { runtime: ... }` dispatch still covers runtimes that are not meant to appear in the guest filesystem.
- **Mounted WASM command directories need both command-map refresh and guest `PATH` refresh.** When `crates/sidecar/src/vm.rs` rediscovers `/__agentos/commands/*`, update `vm.command_guest_paths` and prepend those parent directories into `vm.guest_env["PATH"]`; `crates/sidecar/src/execution.rs` child-process resolution should search `PATH` entries before falling back to `/bin`, `/usr/bin`, and `/usr/local/bin`, or guest `child_process.spawn("sh")`/`spawn("grep")` misses mounted registry commands.
- **Native-sidecar command resolution must use the caller's effective `PATH`, not just `vm.guest_env`.** In `crates/sidecar/src/execution.rs`, path-like guest candidates emitted by shells (for example `/home/agentos/.pi/agent/bin/printf`) should only be treated as executables when the candidate or mapped host file actually exists; if the parent directory came from `PATH` but the file is missing, fall back to the basename so registry command remapping can still find `printf`/`bash`/`which`.
- **Native-sidecar WASM commands see the shadow root, so standard guest directories must be seeded there during VM creation.** In `crates/sidecar/src/vm.rs`, keep `/tmp`, `/var/tmp`, `/bin`, `/usr`, and the rest of the POSIX bootstrap tree materialized in the shadow root before any WASM command runs, or shell redirection and absolute-path checks will disagree with the kernel VFS (`vm.stat("/tmp")` works while `sh -c 'echo hi > /tmp/x'` fails).
- **Host filesystem API writes that should be visible to WASM commands must mirror into the shadow root immediately.** In `crates/sidecar/src/filesystem.rs`, `GuestFilesystemOperation::WriteFile` needs to update both the kernel VFS and the VM shadow tree right away, or `vm.writeFile("/tmp/x")` will succeed while guest `sh`/`cat`/`ls` still miss the file until some later sync path runs.
Expand Down
2 changes: 1 addition & 1 deletion crates/agentos-protocol/protocol/agent_os_acp_v1.bare
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Agent OS ACP extension protocol schema, version 1.
# This schema is intentionally standalone. It imports no secure-exec schema.
# This schema is intentionally standalone. It imports no agentos schema.

type JsonUtf8 str

Expand Down
4 changes: 2 additions & 2 deletions crates/agentos-sidecar-browser/src/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! wasm-bindgen entry point for the Agent OS browser sidecar.
//!
//! Mirrors secure-exec's `BrowserSidecarWasm` (pushFrame/pollEvent over the shared
//! Mirrors agentos's `BrowserSidecarWasm` (pushFrame/pollEvent over the shared
//! `BrowserWireDispatcher` + `BrowserJsBridge`) but registers the Agent OS ACP
//! `BrowserExtension` into the dispatcher's sidecar, so guest ACP/session traffic
//! is handled by the Agent OS wrapper while every kernel syscall still routes
//! through the converged secure-exec wasm kernel (the sole enforcement point).
//! through the converged agentos wasm kernel (the sole enforcement point).

use agentos_native_sidecar_browser::wire_dispatch::{BrowserWireDispatcher, BROWSER_SIDECAR_ID};
use agentos_native_sidecar_browser::BrowserJsBridge;
Expand Down
2 changes: 1 addition & 1 deletion crates/agentos-sidecar-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Host-free core for the Agent OS ACP sidecar extension.
//!
//! This crate holds the parts of the ACP extension that do NOT depend on the host
//! runtime (tokio, std::fs, the native secure-exec sidecar): the request/response
//! runtime (tokio, std::fs, the native agentos sidecar): the request/response
//! wire codec and the per-session data model. It compiles to wasm32 so the browser
//! sidecar (`agentos-sidecar-browser`) can run the same ACP logic the native sidecar
//! (`agentos-sidecar`) runs, with each backend supplying the host operations
Expand Down
Loading