If you've ever wired up an AI agent to do real work, you've probably hit the same wall I did: filesystem access is a minefield. Give it too much rope and it'll happily rm -rf something important. Lock it down too hard and it can't actually do anything useful.
I've been bouncing between three approaches over the last year — raw FS access with allowlists, container-based isolation, and most recently a virtual filesystem layer. Each has real tradeoffs. The trending before relying on specifics; the project looks early and the API surface may shift.
Conceptually, the pattern looks like this:
# Sketch of the virtual FS pattern (not Mirage's exact API)
fs = VirtualFS(
root="./project", # underlying real directory
mode="overlay", # writes go to an overlay, not the real FS
)
# Agent calls look like normal FS ops
fs.write("src/app.py", new_content)
fs.read("README.md")
# But changes are staged, not committed
diff = fs.pending_changes() # inspect what the agent did
fs.commit() # apply to real FS
# or
fs.discard() # throw it all away
What I like about this model:
Review-before-apply is built in. The agent can do 50 file edits and I get to see the diff before any of them touch disk.
Path consistency. The agent always sees./src/app.py, regardless of whether the backend is a local dir, an object store, or an in-memory overlay.
Cheaper than containers for the common case of "edit some files, run some checks."
What I'm cautious about:
- It's another abstraction layer. When something breaks, you're now debugging the agent, the VFS, and the underlying storage.
- Isolation is logical, not physical. If the agent shells out to a subprocess, that subprocess sees the real FS unless you also wrap exec calls. A container actually contains; a virtual FS doesn't, by itself.
- It's new. I haven't tested Mirage thoroughly enough to vouch for edge cases like large binary files, partial writes, or concurrent agents on the same overlay.
Side by side
| Raw FS + allowlist | Container | Virtual FS layer | |
|---|---|---|---|
| Setup cost | Lowest | Highest | Medium |
| Blast radius | Workspace dir (if careful) | Container boundary | Logical workspace |
| Subprocess isolation | None | Yes | None (unless wrapped) |
| Review before apply | Manual (git) | Manual (git) | Built into the model |
| Startup latency | None | Seconds | Milliseconds |
| Good for | Quick scripts | Real code changes | Iterative agent loops |
How I'd pick today
If I'm running a coding agent against a repo I care about, I'm still reaching for containers first. The physical isolation is just too valuable when an agent decides to get creative with find -delete.
If I'm building an interactive loop — agent proposes changes, I approve, agent continues — a virtual FS layer is genuinely better. The commit/discard semantics map directly onto the workflow, and you skip the container startup tax on every iteration.
If I'm prototyping and the workspace is already disposable, raw FS with a path-resolution check is fine. Don't over-engineer it.
A migration sketch
If you're currently on raw FS and want to try a VFS layer, the migration is less invasive than you'd expect:
# Before: direct FS calls scattered through the agent's tools
def read_file_tool(path: str) -> str:
return Path(path).read_text()
def write_file_tool(path: str, content: str) -> None:
Path(path).write_text(content)
# After: same interface, FS calls go through the virtual layer
def read_file_tool(path: str) -> str:
return fs.read(path)
def write_file_tool(path: str, content: str) -> None:
fs.write(path, content) # staged, not yet on disk
# New control surface: review/commit between agent steps
def step_complete():
show_diff(fs.pending_changes())
if user_approves():
fs.commit()
else:
fs.discard()
The tool interface barely changes. What changes is the control loop around it — you now have a place to insert review and approval that you didn't have before.
That's the real reason I'm watching this category. Containers won the "how do we sandbox processes" question a decade ago. The "how do we sandbox an agent's intentions before they become actions" question is still wide open, and a virtual filesystem is one of the more interesting answers I've seen lately.
SOCIAL SHARE CARD GENERATOR