Architecture Overview¶
This document describes the current architecture of agentvfs and the abstraction boundaries the project is converging around.
Outcome View¶
agentvfs is no longer just "a virtual filesystem CLI". The intended operating model is:
That means the primary product surface is a mediated execution boundary. The filesystem, forks, checkpoints, and mounts sit behind that boundary as runtime mechanics.
Layered Model¶
+---------------------------------------------------------------+
| Agent Layer |
| top-level command requests only |
+-------------------------------+-------------------------------+
|
+-------------------------------v-------------------------------+
| Proxy Boundary Layer |
| ExecutionRequest | PolicyEngine | ProxyRuntime | audit/log |
+-------------------------------+-------------------------------+
|
+-------------------------------v-------------------------------+
| Workspace Runtime Layer |
| WorkspaceService | CheckpointService | MountSession | changes |
+-------------------------------+-------------------------------+
|
+-------------------------------v-------------------------------+
| Storage Layer |
| files | versions | metadata | tags | snapshots | audit |
+-------------------------------+-------------------------------+
|
+-------------------------------v-------------------------------+
| Storage Backend Layer |
| SQLite | Sled | LMDB | future |
+---------------------------------------------------------------+
Core Runtime Abstractions¶
The current runtime split is implemented under src/runtime/.
| Abstraction | Role | Current module |
|---|---|---|
ExecutionRequest |
Normalized top-level command request passed into the proxy runtime | src/runtime/execution.rs |
ExecutionDecision |
Policy outcome for that request | src/runtime/execution.rs |
ExecutionResult |
Structured result returned after execution | src/runtime/execution.rs |
ExecutionEnvelope |
Versioned external proxy-execution contract for JSON output | src/runtime/execution.rs |
PolicyEngine |
Side-effect-free command classification and decision logic | src/runtime/policy.rs |
WorkspaceService |
Resolve vaults, describe workspaces, open backends, create forks | src/runtime/workspace.rs |
CheckpointService |
Create rollback points for risky work | src/runtime/checkpoint.rs |
ChangeSummaryService |
Summarize changed files after execution | src/runtime/change_summary.rs |
MountSession |
Own mount lifecycle for a workspace view | src/runtime/mount_session.rs |
ProxyRuntime |
Orchestrate policy, workspace resolution, checkpoints, mounts, execution, and reporting | src/runtime/proxy.rs |
These are the main seams the rest of the system should build on.
Request / Decision / Result Contracts¶
The proxy boundary is intentionally explicit about its input and output contracts.
CommandSpec¶
CommandSpec describes how a top-level command is represented:
Argv(Vec<String>)Shell(String)
The runtime should prefer argv-style execution when available and only fall back to shell-mode when the agent truly needs shell parsing.
ExecutionRequest¶
ExecutionRequest is the canonical input to the proxy runtime. It currently carries:
- target vault selection
- mounted working directory inside the workspace
- read-only intent
- checkpoint mode
- explicit or automatic mountpoint
- the requested top-level command
The request is validated before any expensive runtime work happens.
ExecutionDecision¶
ExecutionDecision is the policy output. It includes:
PolicyActionAllowAllowWithCheckpointDenyRequireApproval- command categories
- an optional reason
This keeps policy inspectable and easy to audit.
ExecutionResult¶
ExecutionResult is the structured proxy response. It includes:
- vault and mountpoint used
- cwd and command string
- stdout, stderr, and exit code
- execution duration
- whether execution was read-only
- checkpoint created, if any
- changed-files summary
- the policy decision that governed execution
That result shape is the basis for a stable agent-facing JSON contract.
ExecutionEnvelope¶
ExecutionEnvelope is the current versioned JSON wrapper for proxy exec. It exists so the external machine-readable contract can evolve deliberately without forcing agents to parse ad hoc CLI output.
It currently includes:
schema_versionkindsuccess- normalized request metadata
- the structured
ExecutionResult
Policy Boundary¶
PolicyEngine is intentionally a cheap, top-level decision layer.
It classifies a requested command into coarse categories:
ReadOnlyMutatingDestructiveNetworkedHostEscapeRiskInteractive
The important constraint is that this is a top-level command boundary only. The proxy is not trying to observe every child process or syscall launched from inside scripts.
This is a deliberate performance tradeoff:
- cheap enough to run for every agent command
- useful enough to gate risky work
- simple enough to extend without turning the runtime into a full sandbox
Workspace Runtime¶
The workspace runtime owns the mechanics behind the proxy boundary.
WorkspaceService¶
WorkspaceService separates task-workspace lifecycle from CLI argument parsing and from low-level storage code. Its responsibilities are:
- resolve the current vault or an explicitly requested vault
- describe a workspace and open its backend
- create cheap forks for task-scoped work
Fork creation is backend-aware and uses copy-on-write cloning where the host filesystem supports it.
CheckpointService¶
CheckpointService owns checkpoint creation for rollback-oriented workflows. This keeps checkpoint behavior out of command handlers and makes it available to the proxy runtime as a reusable service.
MountSession¶
MountSession is the library-level mount abstraction used by the runtime. It exists to prevent the proxy from shelling out to avfs mount as a subprocess.
Its responsibilities are:
- prepare a mountpoint
- create a mounted workspace view
- own cleanup on drop
This is the main performance-oriented seam for future session reuse.
ChangeSummaryService¶
ChangeSummaryService provides a post-execution summary of which workspace paths changed. The current implementation is audit-delta based, which keeps it cheap and scoped to the executed command.
Proxy Runtime¶
ProxyRuntime is the orchestration layer behind the proxy command path.
Its current execution flow is:
- validate the
ExecutionRequest - resolve the target workspace
- evaluate policy with
PolicyEngine - reject denied or approval-gated commands
- baseline change tracking
- create an automatic checkpoint when policy and mode require it
- create a
MountSession - execute the top-level command in the mounted workspace
- summarize changed files
- return an
ExecutionResult
This is the right architectural center for future proxy features.
CLI Adapters¶
CLI command handlers under src/commands/ should stay thin.
Their role is:
- parse user input
- construct runtime requests
- call runtime services
- render output
They should not become the place where mount lifecycle, policy decisions, checkpoint strategy, or workspace orchestration accumulates.
Storage Layer¶
The storage layer remains responsible for durable filesystem state:
- path resolution
- content storage
- version history
- metadata and tags
- snapshots / checkpoints
- audit records
This layer should stay backend-agnostic. Proxy policy and runtime lifecycle should sit above it, not inside it.
Backend Layer¶
Backends provide physical persistence and indexing behavior.
Current direction:
- SQLite as the default durable backend
- Sled as an optional embedded backend
- LMDB as an optional read-heavy backend
The runtime layer should depend on backend capabilities through storage abstractions, not through backend-specific policy logic.
Extension Rules¶
These rules matter for both performance and maintainability:
- Keep policy evaluation side-effect-free.
- Classify commands before forks, checkpoints, or mounts when possible.
- Keep mount lifecycle in
MountSession, not in CLI subprocess wrappers. - Keep task-workspace lifecycle in
WorkspaceService, not mixed into general vault CRUD forever. - Keep changed-file reporting in runtime/reporting services, not buried in command handlers.
- Keep agent-facing execution contracts explicit through
ExecutionRequest,ExecutionResult, andExecutionEnvelope.
Current Limits¶
The architecture is intentionally constrained in a few ways right now:
- the boundary governs top-level commands, not child-process tracing
- persistent
keep_mountproxy sessions are not implemented in the runtime path yet MountSessionandProxyRuntimeare currently FUSE-gated- command execution is orchestrated inside
ProxyRuntimetoday and can later be split into a dedicated executor if needed
Those are acceptable limits for the current phase because the main goal is a cheap and practical execution boundary.