Isolated vaults, not your host fs
Each agent operates inside a vault — a single-file workspace (SQLite by default, Sled or LMDB optional) that lives at ~/.avfs/vaults/<name>.avfs. The agent never touches your real filesystem.
Rust · MIT · crates.io/crates/agentvfs
agentvfs gives an agent an isolated vault, lets it fork the vault per task in milliseconds, checkpoints before risky work, mounts the workspace as a real directory, and runs one top-level command through a policy-gated proxy boundary — returning stdout, stderr, exit code, and a changed-files summary as one structured envelope.
The proxy boundary, in one line
agent → proxy boundary → mounted forked workspace → cli tools
The proxy mediates between your agent and the workspace. It governs which commands run, creates checkpoints around risky ones, and reports the filesystem delta back as structured JSON.
What the boundary actually enforces
Each agent operates inside a vault — a single-file workspace (SQLite by default, Sled or LMDB optional) that lives at ~/.avfs/vaults/<name>.avfs. The agent never touches your real filesystem.
`avfs vault fork` clones a vault into a task workspace in milliseconds. Run experiments in parallel without copying files, and discard the fork when the task is done.
`avfs checkpoint save` creates a rollback point. If a proxy execution mutates state in a way you didn't want, `checkpoint restore` snaps the workspace back. Risky commands can auto-checkpoint via policy.
`avfs proxy exec -- <cmd>` is the agent-facing execution surface. The PolicyEngine classifies the command, MountSession mounts the workspace via FUSE, the command runs, and a ChangeSummary plus exit metadata come back as one structured envelope.
Workspaces mount as real directories, so `git`, `cargo`, `npm`, `python`, `jq` run unchanged inside the boundary. No syscall shimming, no special agent SDK to learn.
Every command supports `--json`. `proxy exec` returns a versioned ExecutionEnvelope with stdout, stderr, exit code, duration, policy decision, and the list of changed files. Errors return typed `{error, message, ...}` objects.
Install
The native Rust crate is the source of truth. The npm and pip packages are wrappers that resolve the matching native binary — useful if your agent infrastructure is JS- or Python-shaped.
cargo install agentvfs Native crate; library API also available.
npm install -g agentvfs-cli CLI wrapper, fetches the matching native binary.
pip install agentvfs-cli Auto-fetches binary to ~/.cache/agentvfs/<version>/. AGENTVFS_BIN overrides.
Quickstart
Create a vault, fork it for a task, checkpoint, and run a real command through the proxy boundary.
# Create a workspace vault avfs vault create myproject # Fork it for a single task avfs vault fork myproject task-001 --use # Checkpoint before something risky avfs checkpoint save before-refactor # Run a command through the proxy boundary avfs proxy exec -- cargo test # → ExecutionEnvelope: stdout, stderr, exit_code, changed_files
Production runtime details
These are the invariants the runtime currently holds. They come from the production-features section of the README and the architecture document in docs/architecture.md.
All SQLite mutations use BEGIN IMMEDIATE / COMMIT / ROLLBACK, eliminating race conditions during concurrent access.
ExecutionTimeout is configurable as None or Millis(u64) (default 300s) with SIGTERM-then-SIGKILL escalation and dedicated pipe-drain threads.
MountSession owns mount/unmount through a state machine with double-unmount protection and automatic cleanup on drop.
A weak-reference cache ensures one backend handle per vault, preventing resource leaks under concurrent access.
FUSE file handles transition Open → Dirty → Persisting → Flushed, eliminating double-persist races.
Per-vault `max_size_mb`, `max_files`, and `max_file_size_mb` block runaway writes with typed QuotaExceeded errors.
How one proxy execution flows
01
Agent calls `avfs proxy exec -- <cmd>`. The runtime parses the top-level command into an ExecutionRequest.
02
PolicyEngine returns allow, allow_with_checkpoint, deny, or require_approval. Pure function — no fs side effects.
03
If policy says so, CheckpointService saves a rollback point before the workspace is mutated.
04
MountSession exposes the vault as a real directory via FUSE. State machine drives `Validating → Mounting → Executing → Completed`.
05
Command runs with the configured ExecutionTimeout (default 300s). SIGTERM then SIGKILL on timeout; pipe-drain threads collect stdout/stderr.
06
ChangeSummary lists what changed. ExecutionResult ships back as a versioned ExecutionEnvelope JSON contract.
The runtime services live under src/runtime/: PolicyEngine, WorkspaceService, CheckpointService, MountSession, ChangeSummaryService, and ProxyRuntime — the extension seams of the system.
Honest comparisons
There are good tools next to agentvfs that solve overlapping problems. We compare two: one container baseline and one AI-agent sandbox SaaS.
Docker isolates a process. agentvfs isolates a workspace and adds vault forks, checkpoints, and a policy-gated proxy designed for agent orchestration.
E2B is a hosted code-execution sandbox SaaS. agentvfs is an MIT-licensed runtime you embed locally with no managed runtime to depend on.
FAQ
No. agentvfs is a workspace runtime: a vault (single-file database) plus a proxy boundary that classifies, checkpoints, mounts, and runs one top-level command at a time. It is explicitly a top-level command boundary, not a syscall monitor or kernel-level sandbox. The README and ROADMAP both list full syscall tracing and complete subprocess visibility as explicit non-goals.
Via a FUSE mount. The MountSession transitions through explicit states, exposes the vault as a real directory, and tears down on drop. Standard CLIs (git, cargo, npm) see a normal filesystem path. FUSE-backed runtime pieces are feature-gated behind `--features fuse`.
Anything that can spawn a subprocess and parse JSON. The README ships native install via cargo, an npm CLI wrapper, and a pip wrapper that auto-fetches the matching native binary. The integration guide demonstrates Python; any language that runs `avfs --json <cmd>` works.
SQLite. The docs note that SQLite is the recommended production backend and that LMDB and Sled backends do not yet have atomic transaction wrappers. Sled and LMDB are pluggable via feature flags (`sled-backend`, `lmdb-backend`).
No, and agentvfs is honest about this. It is a top-level command boundary: it does not try to observe every subprocess launched from inside scripts. Pair it with OS-level isolation (containers, microVMs, seccomp) if you need stronger guarantees against a hostile process.
PolicyEngine classifies a top-level command and returns one of `allow`, `allow_with_checkpoint`, `deny`, or `require_approval`. It is side-effect-free and evaluated before any expensive workspace work, so denied commands never touch the mount.
Yes — MIT-licensed, published to crates.io as `agentvfs`. Source lives at github.com/neul-labs/agentvfs.
Explore the docs
The full surface, the execution path, the workflows it's built for, step-by-step guides, and honest comparisons — each section is its own page.
The full surface: vaults, forks, checkpoints, the policy-gated proxy boundary, and structured JSON results.
The execution path end to end — proxy exec, PolicyEngine, checkpoints, the FUSE MountSession state machine, and the ExecutionEnvelope.
Sandboxing agent code, per-task isolation with rollback, safe multi-agent workspaces, and composing under containers or microVMs.
Step-by-step HowTo guides: install the CLI, run a command in a vault, and checkpoint then roll back a task.
Honest, grounded comparisons with Docker, E2B, and the near-namesake Turso agentfs.
Long-form notes on agent sandbox design, execution-boundary patterns, and agent-aware filesystem access.
Is it a sandbox, how the FUSE mount works, which backend to run in production, and what the policy engine decides.
Precise definitions: vault, execution boundary, fork, checkpoint, PolicyEngine, MountSession, ExecutionEnvelope.
Design rationale and the threat-model summary — why the boundary sits at the top-level command.
MIT-licensed, single-binary install, library API in Rust, JSON contract for everything else. The proxy boundary is the cheapest useful place to draw the line.