Command-line reference for the Vfs CLI.
The command and option sections between the GENERATED COMMAND REFERENCE
markers are rendered from the CLI's clap definitions and checked by
docs::tests::manual_help_parity, so this manual always matches
vfs --help.
Build from source (Linux is the first-tier platform; macOS is second-tier, NFS mount only):
cargo +nightly build --release --workspace --bins
install -m 0755 target/release/vfs ~/.local/bin/Every section below is generated from the clap definitions the binary actually parses; vfs <command> --help and this reference cannot disagree.
Manage shell completions (supported shells: bash, zsh, fish, elvish, powershell)
vfs completions <COMMAND>
Install shell completions to your shell rc file
vfs completions install [SHELL]
Arguments:
[SHELL]— Shell to install completions for (defaults to current shell) [possible values: bash, zsh, fish, elvish, power-shell]
Uninstall shell completions from your shell rc file
vfs completions uninstall [SHELL]
Arguments:
[SHELL]— Shell to uninstall completions for (defaults to current shell) [possible values: bash, zsh, fish, elvish, power-shell]
Print instructions for manual installation
vfs completions show
Initialize a new agent filesystem
vfs init [OPTIONS] [ID]
Arguments:
[ID]— Agent identifier (if not provided, generates a unique one)
Options:
--force— Overwrite existing file if it exists--base <BASE>— Base directory for overlay filesystem (copy-on-write)--key <KEY>— Hex-encoded encryption key. Enables local encryption when provided [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]-c, --command <COMMAND>— Command to execute after initialization (mounts the filesystem, runs command, unmounts)--backend <BACKEND>— Backend to use for mounting when using -c (default: fuse on Linux, nfs on macOS) [possible values: fuse, nfs; default: fuse]--sync-remote-url <SYNC_REMOTE_URL>--sync-partial-prefetch <SYNC_PARTIAL_PREFETCH>[possible values: true, false]--sync-partial-segment-size <SYNC_PARTIAL_SEGMENT_SIZE>--sync-partial-bootstrap-query <SYNC_PARTIAL_BOOTSTRAP_QUERY>--sync-partial-bootstrap-length <SYNC_PARTIAL_BOOTSTRAP_LENGTH>
Remote sync operations
vfs sync <ID_OR_PATH> <COMMAND>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Pull remote changes (only of vfs was initialized with remote sync)
vfs sync <ID_OR_PATH> pull
Push remote changes (only of vfs was initialized with remote sync)
vfs sync <ID_OR_PATH> push
Print synced database stats
vfs sync <ID_OR_PATH> stats
Checkpoint local synced db
vfs sync <ID_OR_PATH> checkpoint
Filesystem operations
vfs fs [OPTIONS] <ID_OR_PATH> <COMMAND>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--key <KEY>— Hex-encoded encryption key for encrypted databases [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]
List files in the filesystem
vfs fs <ID_OR_PATH> ls [FS_PATH]
Arguments:
[FS_PATH]— Path to list (default: /) [default: /]
Display file contents
vfs fs <ID_OR_PATH> cat <FILE_PATH>
Arguments:
<FILE_PATH>— Path to the file in the filesystem
Write file content
vfs fs <ID_OR_PATH> write <FILE_PATH> <CONTENT>
Arguments:
<FILE_PATH>— Path to the file in the filesystem<CONTENT>— Content of the file
Run a command in the sandboxed environment.
By default, uses FUSE+overlay with Linux user and mount namespaces for isolation. The overlay uses the host filesystem as a read-only base and stores all changes in a Vfs-backed delta layer. On macOS the overlay is mounted over NFS and a generated Seatbelt profile scopes writes to the sandbox and reads to the allowed directories plus required platform paths (see the Sandboxing section of docs/MANUAL.md).
vfs run [OPTIONS] [COMMAND] [ARGS]...
Arguments:
[COMMAND]— Command to execute (defaults to bash on Linux, zsh on macOS)[ARGS]...— Arguments for the command
Options:
--allow <PATH>— Allow read/write access to additional directories (can be specified multiple times)--no-default-allows— Disable default allowed directories (~/.config, ~/.cache, ~/.local, ~/.claude, etc.)--session <ID>— Session identifier for sharing delta layer across multiple runs. If not provided, a unique session ID is generated for each run. Use the same session ID to share the delta layer between runs--system— Allow other system users to access this mount (requires /etc/fuse.conf user_allow_other; use cautiously)--partial-origin <MODE>— Partial-origin policy for base-file writes: off, on, or auto [possible values: off, on, auto]--partial-origin-threshold-bytes <BYTES>— Size threshold for --partial-origin auto--key <KEY>— Hex-encoded encryption key for the delta layer. Enables local encryption when provided [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]--seed-pin <COMMIT>— Seed dirty and local-commit state against this git commit before mounting. Ignored files are not part of portable state
Execute a command with a Vfs filesystem mounted.
Mounts the specified Vfs to a temporary directory, runs the command with that directory as the working directory, then automatically unmounts. This is useful for running tools that need filesystem access without a persistent mount.
vfs exec [OPTIONS] <ID_OR_PATH> <COMMAND> [ARGS]...
Arguments:
<ID_OR_PATH>— Agent ID or database path<COMMAND>— Command to execute[ARGS]...— Arguments for the command
Options:
--backend <BACKEND>— Backend to use for mounting (default: fuse on Linux, nfs on macOS) [possible values: fuse, nfs; default: fuse]--key <KEY>— Hex-encoded encryption key for encrypted databases [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key) [env: VFS_CIPHER]
Clone a git repository into a Vfs database (fast bulk ingest).
Runs git clone --no-checkout through a temporary mount (pack files are large sequential writes), then materializes the worktree by bulk-importing blobs straight into the database in large transactions and fabricating a matching git index, skipping the per-file FUSE round trips of a regular checkout. The resulting repository lives entirely inside the database; nothing is written to the host filesystem. Submodules and smudge/clean filters are not supported.
vfs clone [OPTIONS] <ID_OR_PATH> <SOURCE> [NAME]
Arguments:
<ID_OR_PATH>— Agent ID or database path (created if it does not exist)<SOURCE>— Git repository to clone (URL or local path)[NAME]— Directory name for the repository inside the filesystem (default: derived from the source)
Options:
--backend <BACKEND>— Backend to use for mounting (default: fuse on Linux, nfs on macOS) [possible values: fuse, nfs; default: fuse]--verify— Verifygit statusis clean through the mount before finishing
Mount an agent filesystem using FUSE (or list mounts if no args)
vfs mount [OPTIONS] [ID_OR_PATH] [MOUNTPOINT]
Arguments:
[ID_OR_PATH]— Agent ID or database path (if omitted, lists current mounts)[MOUNTPOINT]— Mount point directory
Options:
-a, --auto-unmount— Automatically unmount on exit--allow-root— Allow root user to access filesystem--system— Allow other system users to access this mount (requires /etc/fuse.conf user_allow_other; use cautiously)-f, --foreground— Run in foreground (don't daemonize)--uid <UID>— User ID to report for all files (defaults to current user)--gid <GID>— Group ID to report for all files (defaults to current group)--backend <BACKEND>— Backend to use for mounting [possible values: fuse, nfs; default: fuse]--partial-origin <MODE>— Partial-origin policy for base-file writes: off, on, or auto [possible values: off, on, auto]--partial-origin-threshold-bytes <BYTES>— Size threshold for --partial-origin auto--key <KEY>— Hex-encoded encryption key for encrypted databases [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]
Show differences between base filesystem and delta (overlay mode only)
vfs diff <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Display agent action timeline from tool call audit log
vfs timeline [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--limit <LIMIT>— Limit number of entries to display [default: 100]--filter <FILTER>— Filter by tool name--status <STATUS>— Filter by status (pending/success/error) [possible values: pending, success, error]--format <FORMAT>— Output format [possible values: table, json; default: table]
Start an NFS server to export a Vfs filesystem over the network (deprecated: use vfs serve nfs instead)
vfs nfs [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--bind <BIND>— IP address to bind to [default: 127.0.0.1]--port <PORT>— Port to listen on [default: 11111]--key <KEY>— Hex-encoded encryption key for encrypted databases [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]
Start an MCP server exposing filesystem and KV-store tools (deprecated: use vfs serve mcp instead)
vfs mcp-server [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--tools <TOOLS>— Tools to expose (comma-separated). If not provided, all tools are exposed. Available tools: read_file, write_file, readdir, mkdir, remove, rename, stat, access, kv_get, kv_set, kv_delete, kv_list
Serve a Vfs filesystem via different protocols
vfs serve <COMMAND>
Start an NFS server to export a Vfs filesystem over the network
vfs serve nfs [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--bind <BIND>— IP address to bind to [default: 127.0.0.1]--port <PORT>— Port to listen on [default: 11111]--key <KEY>— Hex-encoded encryption key for encrypted databases [env: VFS_KEY]--cipher <CIPHER>— Cipher algorithm for encryption (required with --key). Options: aegis128l, aegis128x2, aegis128x4, aegis256, aegis256x2, aegis256x4, aes128gcm, aes256gcm [env: VFS_CIPHER]
Start an MCP server exposing filesystem and KV-store tools
vfs serve mcp [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--tools <TOOLS>— Tools to expose (comma-separated). If not provided, all tools are exposed. Available tools: read_file, write_file, readdir, mkdir, remove, rename, stat, access, kv_get, kv_set, kv_delete, kv_list
Prepare an inactive run session database for transfer
vfs pack [OPTIONS] <SESSION_ID>
Arguments:
<SESSION_ID>— Run session identifier
Options:
--prune <GLOB>— Additional delta path glob to prune (can be specified multiple times)--no-default-prunes— Disable the default generated-artifact prune globs--output <PATH>— Copy the packed database to this path--chunk-size <BYTES>— Byte size of the per-chunk verification digests reported in the manifest'schunkslist [default: 4194304]--json— Emit machine-readable JSON (pack output is always JSON)
Capture a run session's live git state into its portable delta.
Compares the session base checkout with --pin, imports dirty files and local commits without mounting, and records deletions as whiteouts. Ignored files are not part of portable state.
vfs seed [OPTIONS] <SESSION_ID>
Arguments:
<SESSION_ID>— Run session identifier
Options:
--pin <COMMIT>— Git commit used as the pristine portable base--json— Emit machine-readable JSON (seed output is always JSON)
Install an externally transferred run session.
Verifies a packed session database against the receiver's base git checkout (the checkout's HEAD must equal the artifact's recorded seed pin), migrates supported older artifact schemas to the current version, and atomically publishes ~/.vfs/run/<SESSION_ID>. After adopt, vfs run --session <SESSION_ID> resumes the transferred session.
vfs adopt [OPTIONS] <SESSION_ID>
Arguments:
<SESSION_ID>— Run session identifier
Options:
--db <PATH>— Packed session database produced byvfs pack--base <PATH>— The receiver's base git checkout for the session--pin <COMMIT>— Git commit the base checkout must be at (required only when the artifact does not record a seed pin)--json— Emit machine-readable JSON (adopt output is always JSON)
Show run session state for daemon preflight
vfs status [OPTIONS] <SESSION_ID>
Arguments:
<SESSION_ID>— Run session identifier
Options:
--json— Emit machine-readable JSON (status output is always JSON)--key <KEY>— Hex-encoded encryption key for an encrypted session database [env: VFS_KEY]--cipher <CIPHER>— Encryption cipher (required with --key) [env: VFS_CIPHER]
Show vfs version and feature capabilities
vfs version [OPTIONS]
Options:
--json— Emit machine-readable JSON
List active vfs run sessions
vfs ps
Prune unused resources
vfs prune <COMMAND>
Unmount unused vfs mount points
vfs prune mounts [OPTIONS]
Options:
--force— Skip confirmation prompt and unmount immediately
Check a local Vfs database for SQLite and schema corruption
vfs integrity [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--json— Emit machine-readable JSON--require-portable— Fail if the database depends on external partial-origin base files--check-base— Validate partial-origin base file fingerprints against the current base tree--checkpoint— Checkpoint the WAL and remove empty SQLite sidecars after checks pass--key <KEY>— Hex-encoded encryption key for encrypted databases--cipher <CIPHER>— Encryption cipher (required with --key)
Create a portable local Vfs database backup
vfs backup [OPTIONS] <ID_OR_PATH> <TARGET>
Arguments:
<ID_OR_PATH>— Agent ID or database path<TARGET>— Target database path to create
Options:
--verify— Reopen and verify the copied main database--materialize— Materialize partial-origin files into a portable backup--key <KEY>— Hex-encoded encryption key for encrypted databases--cipher <CIPHER>— Encryption cipher (required with --key)
Create a portable database by materializing partial-origin files
vfs materialize [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--output <OUTPUT>— Target database path to create--verify— Reopen and verify the materialized database--key <KEY>— Hex-encoded encryption key for encrypted databases--cipher <CIPHER>— Encryption cipher (required with --key)
Migrate database schema to the current version
vfs migrate [OPTIONS] <ID_OR_PATH>
Arguments:
<ID_OR_PATH>— Agent ID or database path
Options:
--dry-run— Preview migration without applying changes--copy <TARGET>— Copy-migrate into a new database file at this path instead of migrating in place--verify— Verify migrated state equivalence (requires --copy)--overwrite-target— Allow replacing an existing --copy target database--key <KEY>— Hex-encoded encryption key for encrypted databases--cipher <CIPHER>— Encryption cipher (required with --key)
vfs seed <session-id> --pin <commit> captures the live checkout state that
would otherwise be visible only through overlay base read-through. It imports
dirty and untracked files, records paths deleted since the pin as whiteouts,
and includes committed changes between the pin and HEAD. The import uses the
core bulk-import API directly; it never requires a FUSE or NFS mount.
For session creation, prefer the atomic startup form:
vfs run --session <session-id> --seed-pin <commit> -- <command>vfs run creates and seeds the delta under the session's exclusive lock, then
atomically downgrades that lock to the lifetime shared run lock before mounting
or starting the wrapped process. Seed writes a private staging database and
publishes it only after import, whiteouts, metadata, and finalization succeed,
so a failed seed leaves the live delta retryable. The standalone vfs seed
form is available when a session directory, base_path, and delta.db already
exist and the session is inactive.
Git-ignored files are not part of portable state. Seed uses
git status --untracked-files=all, so ignored build outputs, dependency trees,
and caches remain base-local. For local-only commits, seed writes a compact Git
pack plus HEAD and the current branch ref into delta .git/ paths. It also
copies the sender's index bytes, preserving staged versus unstaged state; Git
revalidates cached stat fields when the delta is materialized over a pristine
checkout at the pin.
Seed records the resolved pin inside the session database as the session's
base provenance; vfs adopt verifies the receiving base checkout against it.
Seed is a birth-time operation. A second call fails with
session already seeded, and a live mount or wrapped process fails with the
same exit-code-3 teardown gate used by vfs pack.
vfs pack <session-id> prepares ~/.vfs/run/<session-id>/delta.db as a
single-file transfer artifact. Pack owns the operation end to end:
- Every owner/joiner holds a shared advisory lock on
.session.lockfor its lifetime; pack must acquire the exclusive lock before it can inspect or publish the session. Kernel lock release on process death prevents stale lock files from wedging a session. - It rejects live mounts and live owner/joiner proc records with exit code
3and the messagesession still running; exit the wrapped process first. - It copies the SQLite main database and any WAL/SHM sidecars to a private staging family. Pruning, schema migration, generation increment, checkpoint, and compaction happen only on that copy.
- Pruning removes matching delta dentries/inodes through the core filesystem API. It never creates whiteouts: a pruned delta-only path disappears, while a pruned path that shadowed the base falls back to the base version.
- The Turso engine currently implements compaction as
VACUUM INTOrather than in-placeVACUUM; pack checkpoints the resulting database and removes its sidecars before publication. - Publication renames the old live database family to a deterministic private
backup, renames the completed single-file staging database into place,
verifies its metadata, and rolls back on any publication failure. A later
pack recovers that backup if the process died between renames. An
--outputartifact is copied from the same completed staging bytes and published with a no-replace hard link, so a concurrently-created target is never overwritten. Backup cleanup occurs only after both publications succeed.
The packed transfer artifact is only delta.db; procs/, mnt/,
.session.lock, base_path, and other session-directory files are never
included in that artifact.
Pack prints a one-line JSON manifest describing the published artifact.
dbSha256 and dbSizeBytes cover the whole file; artifactVersion is the
schema version the artifact was migrated to during staging; and chunks
lists {index, sizeBytes, sha256} digests over consecutive
--chunk-size-byte ranges (default 4194304) of the exact published bytes.
A consumer streams the artifact in precisely those chunks and verifies each
one, with the whole-file dbSha256 as the final check.
vfs version --json reports artifactVersion (the schema version this
binary writes when packing) and minSupportedArtifactVersion (the oldest
artifact schema it can still migrate forward during adopt), so two daemons
can agree on an artifact-version floor before transferring anything. The
sender's artifactVersion must be within the receiver's supported range;
vfs adopt enforces the ceiling by refusing an artifact newer than its own
artifactVersion with an error naming both versions.
vfs adopt <session-id> --db <path> --base <path> installs a transferred
pack artifact as a local run session. Adopt owns the receiver side of a
handoff end to end:
- It refuses a session ID whose
~/.vfs/run/<session-id>/delta.dbalready exists, and takes the same exclusive.session.lockused byrun,seed, andpack, so a live owner fails with exit code3. - It stages a private copy of the artifact, checks SQLite integrity, and
migrates supported older artifact schemas to the current version — the
same staging migration
vfs packperforms before it ships an artifact, so an adopted session always opens undervfs runwithout a separatevfs migratestep. An artifact written by a newer vfs is refused with an error naming both versions. - It verifies base provenance:
--basemust be a git checkout whoseHEADequals the seed pin recorded in the artifact byvfs seed. For artifacts without recorded provenance,--pin <commit>is required and verified the same way; a--pinthat contradicts recorded provenance is refused. A base checkout at any other commit is refused before anything is published. - Publication writes
base_pathand then atomically renames the staged database todelta.db. That rename is the commit point: on any earlier failure a session directory adopt created is removed again, so a partial or corrupt session is never observable.
Adopt prints a one-line JSON manifest:
{
"manifestVersion": 1,
"sessionId": "<session-id>",
"basePath": "/abs/receiver/checkout",
"basePin": "<commit>",
"generation": 1,
"schemaVersion": "0.6",
"seededPaths": ["src/lib.rs"],
"vfsVersion": "0.6.4"
}After adopt, resume the session with:
vfs run --session <session-id> -- <command>The installed layout — delta.db plus a base_path text file naming the
receiver checkout, with mnt/, procs/, .session.lock, and
runtime-status.json created lazily by vfs run — is an internal detail
owned by adopt; sessions must be installed through vfs adopt, not by
writing those files by hand.
vfs status <session-id> --json emits one JSON object:
{
"sessionId": "<session-id>",
"state": "stopped",
"mounted": false,
"pid": null,
"generation": 1,
"seeded": false
}state is stopped, busy, live, or stale-recovered. busy means an
exclusive seed, pack, or first-start transition owns the session; its pid is
null, and metadata fields are conservative defaults until the transition
finishes. For live, pid is the run owner PID. generation is the pack
generation (0 before the first pack), and seeded reports whether seed
metadata is present. Status preflight takes the session lock; when no owner
exists, it also recovers an interrupted pack publication, detaches a stale
mount, and removes stale process records before reporting stale-recovered.
vfs run preserves the wrapped command's exit status. A command terminated by
a signal uses the conventional 128 + signal status. Startup failures use
these reserved statuses before the wrapped command begins:
| Status | Meaning |
|---|---|
1 |
General CLI failure not assigned a more specific status |
2 |
Command-line usage or argument parsing failure |
3 |
The requested session is genuinely live; run, pack, seed, or adopt cannot take exclusive ownership |
4 |
vfs run could not create, recover, or install the session mount/sandbox |
5 |
The requested run session ID or adopted session directory is missing, malformed, or invalid |
126 |
The wrapped command was found but could not be executed |
127 |
The wrapped command was not found |
Once the wrapped command starts, its status is passed through unchanged and may numerically coincide with a reserved startup status.
The write_file tool overwrites existing files in place and keeps their
mode; files it creates get the default mode 0644 (rw-r--r--).
vfs run scopes both writes and reads at the OS level; the mechanism
differs by platform.
Linux (first-tier): FUSE + overlay inside user and mount namespaces.
Writes land only in the copy-on-write overlay and the allowed directories.
Reads are scoped by hiding the home directory and temp dirs behind
namespace-private tmpfs, re-exposing only the overlay cwd and the allowed
paths; all other system paths are remounted read-only. Writes to those
hidden non-allowed paths land in an ephemeral session-private view (the
namespace tmpfs): the host is protected, but that view is not persisted —
files written there vanish when the session exits and are not visible when
the session is resumed with --session.
macOS (second-tier): NFS mount + a generated sandbox-exec (Seatbelt)
profile. Writes are restricted to the mountpoint, temp directories,
~/Library, and the allowed paths. Reads are default-deny: only the session
directory (~/.vfs/run/<ID>), the allowed directories (the defaults plus
--allow), and a curated set of platform roots are readable (system
frameworks and libraries, the dyld shared cache cryptex, executable
directories, /private/etc, terminfo/locale data under /usr/share, temp
directories, /dev essentials, /opt, /usr/local, and /Applications).
Ancestors of readable roots are stat-able (metadata only) so path resolution
works. Notable consequences:
- The rest of your home directory, including
~/Libraryand credential stores such as~/.sshor~/.aws, is unreadable unless granted with--allow. (~/Libraryremains writable for Keychain and preferences compatibility, but is not readable.) - Tools that need read access outside the workspace must be granted it
explicitly with
--allow <PATH>, which grants read and write access, matching Linux.
CI covers the macOS read posture only via unit tests that pin the generated
profile; the runtime behavior is verified by the manual macOS release gate
(scripts/validation/macos-nfs-git-validation.sh), which includes a
read-scoping leg: a secret outside the allow list must be unreadable, and
--allow must make it readable. See docs/TESTING.md.
Every runtime knob (env var or first-class flag) is declared in the generated
docs/KNOBS.md ledger with its class, default, owner, and gate.
VFS_KEY / VFS_CIPHER provide default encryption credentials for
the commands whose --key / --cipher options declare them (see the
generated sections above); TURSO_DB_AUTH_TOKEN authenticates cloud sync.
On Linux kernels with fuse.enable_uring=1 (the VFS_FUSE_URING knob
controls whether Vfs uses the transport), the kernel drains a just-closed
FUSE connection for roughly two seconds, and a new mount racing that drain can
block inside mount(2) indefinitely (observed on kernel 7.1.2). Vfs
bounds this: the mount is retried for a few seconds and then fails with a
clear error instead of hanging. If rapid unmount-then-mount cycles keep
hitting the error, wait a couple of seconds between cycles or set
VFS_FUSE_URING=0 on the mount-owning processes. A mount left wedged by
other tooling can be recovered with
echo 1 > /sys/fs/fuse/connections/<id>/abort (verify the connection id
first).
The turso_core dependency (0.5.3) leaks tursodb-ephemeral-* sort-spill
files into the temp dir and never unlinks them (vdbe/execute.rs:10096). The
CLI therefore points its own TMPDIR at a private per-process directory that
is removed on exit, so hosts do not accumulate spill litter. This override is
process-internal: commands spawned by vfs run, vfs exec, and
vfs init -c see the original TMPDIR. Stale spill directories from
SIGKILLed processes are garbage-collected on the next CLI start.
Variables set inside an vfs run sandbox:
| Variable | Description |
|---|---|
VFS |
Set to 1 inside the Vfs sandbox |
VFS_SANDBOX |
Sandbox type: linux-namespace or macos-sandbox |
VFS_SESSION |
Current session ID |
Vfs supports encrypting the local SQLite database at rest.
Supported ciphers:
aes256gcm- AES-256-GCM (requires 64-character hex key)aes128gcm- AES-128-GCM (requires 32-character hex key)aegis256- AEGIS-256 (requires 64-character hex key)aegis128l- AEGIS-128L (requires 32-character hex key)aegis128x2,aegis128x4,aegis256x2,aegis256x4- AEGIS variants
Example: Create an encrypted filesystem
# Generate a 256-bit key (64 hex characters)
KEY=$(openssl rand -hex 32)
# Initialize with encryption
vfs init --key $KEY --cipher aes256gcm my-secure-agent
# Access the filesystem
vfs fs my-secure-agent --key $KEY --cipher aes256gcm ls /Example: Encrypted sandbox session
vfs run --key $KEY --cipher aes256gcm -- bashUsing environment variables:
export VFS_KEY=$(openssl rand -hex 32)
export VFS_CIPHER=aes256gcm
vfs init my-secure-agent
vfs fs my-secure-agent ls /Limitations:
- Local encryption cannot be used with cloud sync (
--sync-remote-url)
.vfs/<ID>.db- Agent filesystem database (relative to the working directory wherevfs initran)~/.vfs/run/-vfs runsession state (listed byvfs ps)
- Linux (FUSE):
fusermount3 -u <MOUNT_POINT>(orfusermount -u) - macOS (NFS):
umount <MOUNT_POINT>
- Agent Filesystem Specification - SQLite schema specification
- Runtime Knobs - generated knob ledger
- Testing - validation gates, benchmarks, and the manual macOS release gate