Skip to main content

Storage Model

Orca has two storage surfaces:
  • VirtualFS-backed filesystem tools (read_file, write_file, list_dir, delete_file) expose scoped paths under conventional directories such as /agents, /pools, /s3, /data, and /kb.
  • Artifact tools (save_artifact, get_artifact, list_artifacts) expose raw run/session-keyed S3-compatible objects.
  • Memory Bank persists per-profile long-lived memories under memory/<profile>/<id>.json when S3-compatible storage is configured. See Memory Bank.
Local Docker uses SeaweedFS. Production can use any S3-compatible backend, including AWS S3, R2, or MinIO.

Environment Contract

VirtualFS is configured from explicit VFS_* variables, or from production defaults when VFS_BACKEND=production is set:

Mount strictness

A mount is strictly identified by its path AND its backing data source (kind + bucket + endpoint + prefix). The prod, dev, and disk profiles each register one system mount named root at /; /agents, /pools, /s3, /data, and /kb are directories inside that mount, not separate boot-time mounts. Runtime user mounts can still register non-root prefixes, and the dispatcher resolves paths with longest-prefix-wins. Two important consequences:
  • The server never substitutes a different backend for a missing one. If the prod profile is configured for R2 and R2 is unreachable at boot, the root mount comes up unavailable — not silently backed by RAM.
  • The client never assumes a mount is what it declares; it checks. Use Workspace.validate() to fail fast on bucket drift or kind mismatch.
Mounts that fail to initialize at boot do not crash the server. The server boots; their entries surface in GET /vfs/mounts with status: "unavailable" and a human-readable reason. Operations on those mounts return MOUNT_UNAVAILABLE.

Single coherent filesystem

The VFS presents path operations as one tree:
  • Addressable: every byte lives at exactly one absolute path (/agents/..., /data/..., /kb/...), regardless of whether the selected mount is RAM, R2, or another backend.
  • Navigable: ls / returns top-level directories visible from the active mount table; cd / works; stat / reports a directory.
  • Searchable: find / and grep -r / traverse the visible tree and apply the active session allowlist before returning entries or matches.
  • Mutable across subtrees or mounts: cp /agents/x /data/y and mv /a/x /b/y stream bytes through the dispatcher.
Strict identity (above) and unification (here) are independent guarantees. Strict means each mount honestly reports its data source; unification means callers don’t have to enumerate mounts to walk the tree. Together they let an agent treat the substrate like a real filesystem without hiding what’s actually under each subtree. With no VFS_* environment, the runner still boots with an in-memory VirtualFS dispatcher. That keeps @fs, @pool, and @vfs usable for a single runner process, but state is not shared with a separate vfs serve process. Configure both processes with the same VirtualFS backend settings when dashboard Files, vfs serve, and agent tools should see the same data. The dashboard Files page is a VFS client too. From any writable directory, operators can upload files or folders with the Upload menu or by dragging them into the listing. Folder picks and dropped directories preserve relative paths, while the upload queue shows per-file progress, retry, cancel-all, and clear controls. Raw artifacts and Memory Bank persistence are configured from the standard AWS SDK environment plus Orca-specific bucket flags: Run-event blobs can use a separate internal bucket. This keeps operational run transcripts out of the tenant-facing artifact bucket used by artifact tools, Memory Bank, and the dashboard storage API: When raw artifact storage is not configured, artifact calls return a “not configured” tool error and the dashboard storage API reports configured: false. When S3_BUCKET is configured for the conductor, startup probes the bucket with a small list request before wiring artifact storage. Missing buckets, wrong endpoints, or invalid credentials fail startup with artifacts.bucket_unavailable instead of silently dropping run-event writes. When INTERNAL_S3_BUCKET is configured, the conductor probes that bucket too and uses it for run-event blobs. If the internal bucket is omitted, run events fall back to the primary S3_BUCKET, so single-bucket local and CI setups need no extra configuration.

Filesystem View

Filesystem tools use absolute POSIX paths and dispatch through VirtualFS. With the default S3/R2-backed root mount, user-facing paths stay stable, while the dispatcher scopes bucket keys under the authenticated tenant’s jail prefix (tenants/{tenant}/...). Entries returned by ls, find, grep, stat, and writes are decoded back to tenant-facing POSIX paths before callers see them. Every profile has implicit read/write/delete access to /agents/{self}/**.
delete defaults to write when omitted. deny overrides all grants.

File Tools

@fs is part of @default. Relative paths are resolved under the agent home. For example, write_file("notes.md") writes /agents/{self}/notes.md. When a VirtualFS dispatcher is wired, @fs, @pool, @sandbox-transfer, and @vfs share the same backing substrate. A file written with write_file under /agents/{self} is visible to VirtualFS shell commands such as vfs_execute running inside a sandbox.

Artifact Tools

@artifacts is opt-in. These tools use run/session-keyed object paths:
When there is no run ID, objects are written under shared/sessions/<sessionId>/.... Inline tool payloads are capped at 8 MiB.

Dashboard Storage API

The conductor exposes storage endpoints used by the dashboard’s storage browser: Non-UTF-8 object content is base64 encoded in GET responses. DELETE against a folder prefix walks up to 1000 entries (one List page) and removes them serially.

Local SeaweedFS

The compose stack starts SeaweedFS and creates the default bucket:
The default local endpoint is http://localhost:8333, bucket agent-artifacts, access key agent-orc, and secret agent-orc-secret.