Est.

File System Layout Conventions for Agent VMs

Structured filesystem isolation prevents AI agent failures caused by uncontrolled file access.

· 10 min read
Cover illustration for “File System Layout Conventions for Agent VMs”
Persistent Agents · October 15, 2026 · 10 min read · 2,308 words

Most AI coding agents fail in production not because models err or prompts go wrong, but because filesystem access is granted with no deliberate structure. The first systematic study of this problem, the SOSP '26 paper "Don't Let AI Agents YOLO Your Files," analyzed 290 public reports of data corruption, data loss, and credential leakage. Every one of them stems from two gaps: limited information about filesystem effects and insufficient control over them. A deliberate on-disk layout does not close those gaps by itself, but it narrows them and shrinks the blast radius of any misuse.

Why agents need a deliberate on-disk layout, not a default Linux tree

The consequences of ad-hoc filesystem access are severe and documented. The information gap makes these failures possible: neither the user nor the agent can reliably determine what a command will do to the filesystem. A build command can silently read an SSH key and rewrite shell config while the approval prompt shows nothing suspicious.

The control gap is equally structural. Instruction-level guardrails get bypassed, agents ignore directives like "do not read my SSH key," and prompt injection can override them entirely. The approval dilemma compounds both gaps: frequent prompts stall the agent and cause approval fatigue, so users approve everything blindly or enable unchecked "YOLO mode," removing all protection. A deliberate layout constrains where the agent operates. That constraint is the precondition for every other safeguard this article describes.

The three storage lifecycles every agent VM needs to distinguish

The core error is treating all agent data as the same kind of thing. You separate storage into three zones with different lifecycles and access semantics, and you do it once, at VM setup, before any agent code runs. It is a design principle, not a classification exercise applied retroactively.

Zone 1, working state, is volatile. It holds core parameters, behavioral policies, and long-term goals. It is rarely updated and never overwritten by task execution.

The danger lies in conflation. When working state and event memory share a directory, a runaway task can overwrite learned context. When identity and config live in the working tree, a file-write tool call can silently alter behavioral policy. The three-zone model is the conceptual skeleton on which every concrete path convention below hangs. It also works most reliably when each zone is not just a logical boundary but a physical isolation boundary, which is why agents running on dedicated persistent virtual machines can enforce lifecycle separation more strictly than those sharing kernel space or relying on runtime policies alone.

A concrete reference layout: how MUSE-Autoskill structures the disk

The MUSE-Autoskill system, described in arXiv:2605.27366 from May 2026, provides the most detailed published reference layout for an agent VM's persistent structure. Its conventions map directly onto the three-zone model, and they offer a working pattern rather than a philosophy. The host-side persistent root is $HOME/.autoskill, overridable via the AUTOSKILL_HOME environment variable. It is created on first launch and holds all state that is not specific to a single session. The skills directory contains one subdirectory per skill, and each skill subdirectory holds five components: SKILL.md with the skill's instructions and interface contract, .memory.md for per-skill experience accumulated across invocations, scripts/ for executable code the skill runs, tests/ for skill validation, and resources/ for static assets.

The sandbox splits into an input zone and an output zone. The sandbox itself is destroyed at session end, so no skill execution can touch host state. Mapping to the three zones: skills/ and memory/ are Zone 2, AUTOSKILL_HOME config is Zone 3, and /sandbox/ is Zone 1, ephemeral by design. This layout assumes each agent has persistent, personal disk ownership and the ability to preserve state across wake-sleep cycles, precisely the model that persistent VM-based agent hosting platforms enable and that serverless or shared-container setups cannot guarantee without rebuilding state on every invocation.

The memory file format that makes Zone 2 safe to write concurrently

Plain Markdown with an append-only, timestamped-block discipline is the simplest memory file format that is both human-readable and safe for concurrent agent access. All memory files in MUSE-Autoskill, whether long-term, short-term, or per-skill, share this format. A writer appends a single timestamped block. A reader reads line-by-line without parsing structure. No entry is ever edited or deleted.

This constraint matters most under concurrency. Because no writer touches existing content, two sessions can write simultaneously without locking. Developers should resist the urge to add memory compaction that rewrites old entries. If context-window size requires pruning, prune from the read side by passing a tail of the file, never from the write side.

The sandbox boundary: how a virtio-blk block device enforces Zone 1 isolation at the hardware level

The /sandbox/ boundary is only as strong as the isolation layer beneath it. A Firecracker micro-VM's virtio-blk device makes that boundary physical, not just logical. Firecracker is a VMM built in Rust by AWS, and each micro-VM boots its own guest kernel on top of hardware virtualization through KVM. There is no shared kernel between sandboxes.

Each micro-VM gets its own virtio-blk block device, which maps directly to the isolated /sandbox/ tree. Two sandboxes share no kernel code paths whatsoever, making lateral propagation of kernel vulnerabilities structurally impossible rather than policy-dependent. Firecracker's minimal device model, virtio-net, virtio-block, serial console, and a one-button keyboard with no BIOS, no PCI, and no USB, means the attack surface exposed to a compromised sandbox is negligible compared to a full VM or a shared container runtime. When each agent owns its own filesystem boundary, a deliberate layout becomes enforceable by the infrastructure itself, not just by instruction.

Contrast this with container-based approaches. A container shares the host kernel, so a kernel exploit in one container can affect all others. The device is detached and discarded at the hypervisor level.

Instruction files as a fourth layer: where AGENTS.md, SKILL.md, and DESIGN.md live in the tree

A practical agent VM layout includes a distinct layer of instruction files that govern agent behavior within the project tree. Their placement follows a lookup chain that developers need to design explicitly, and that placement is itself a layout decision. AGENTS.md holds project-level operating instructions for coding agents: build commands, test commands, lint rules, naming conventions, what to ask before changing, and what never to touch. OpenAI released it in August 2025 and donated it to the Linux Foundation's Agentic AI Foundation in December 2025, and that cross-tool convergence makes it the default choice for most teams.

The scope rule is simple: an AGENTS.md file governs the entire directory tree rooted at the folder containing it, and more-deeply-nested files take precedence over shallower ones on conflicting instructions. In a monorepo, a universal AGENTS.md at the repo root carries PR conventions, security rules, and secrets policy, while per-package files live in subdirectories such as apps/web/, apps/api/, packages/ui/, and infra/. If Claude Code is your primary harness, keep CLAUDE.md, which still supports capabilities AGENTS.md does not standardize, notably hierarchical loading and imports, and symlink or duplicate it for cross-tool compatibility.

Specialist files like DESIGN.md, SCHEMA.md, and CONTEXT.md belong at the repo root only when a domain is complex enough that explaining it inline would bloat AGENTS.md. A project with 40 tables and non-obvious business rules does. Instruction files sit at the repo root or package level, never inside /sandbox/ or the working-state zone, because an agent should never overwrite them during task execution. They are Zone 3 from the agent's perspective. Community best practice converges on keeping AGENTS.md under 150 lines, since token cost rises faster than usefulness past that threshold.

The virtual filesystem as an interface contract, not a literal path

The layout zones and paths defined above are interface contracts the agent navigates. What backs each path can be swapped without changing agent behavior, and that decoupling is the key to scaling the layout across heterogeneous storage. A filesystem does not have to mean literal files on disk. The agent only needs to understand how to navigate files.

A concrete mapping makes this practical. /docs/ can be backed by cloud object storage. /memories/ can sit on SQLite where relational data is synthesized into readable files on read. /workspace/ maps to local disk for generated outputs. A routing layer dispatches directory prefixes to different storage systems, and from the agent's reasoning loop nothing changes when the backing store changes. An enterprise-grade backend can also handle writes differently: if a file already exists at a path, it can upload a new version rather than silently overwrite, so agent-generated artifacts inherit version history without the agent knowing it is happening.

Define zones and paths early, and you can have a virtual filesystem later. The tradeoff deserves honesty: virtualizing the backing store introduces latency and unpredictable data volume that literal file I/O does not. That is acceptable for long-lived agent context in Zones 2 and 3, but wrong for Zone 1 working state, which needs the lowest-latency path available.

Snapshot-restore and the economics of keeping Zone 2 alive while Zone 1 costs nothing

The separation of Zone 1 from Zones 2 and 3 is what allows snapshot-restore scheduling to reduce idle agent cost toward zero without sacrificing continuity. When an agent goes idle, whether it has handed control back to the model, is waiting on a user, or is parked between bursts, the entire VM is snapshotted. Working directory, installed dependencies, running processes, and warm page cache are frozen exactly as they were, then the VM is destroyed and the host is freed. On the next inbound message, the VM restores from snapshot in under a second. From the agent's perspective nothing was lost: Zones 2 and 3 are intact on the persistent disk, and Zone 1 returns to the exact working state it held when the snapshot fired.

Idle time, which is most of an agent's lifetime, becomes a storage charge rather than a compute charge. Maritime's scheduler is built on exactly this model. Content-addressable disk storage makes Zone 2 snapshots cheap. A fleet of agents restored from the same base image costs only what each has actually dirtied.

This only works cleanly if Zone 1 is clearly separated from Zone 2. If working state and learned memory are co-mingled in one directory, every snapshot must be treated as fully mutable, and the storage savings from content-addressing collapse. Zone separation is not an organizational preference. It is an economic decision.

Agent-native filesystem primitives: introspect, undo, and gate as the safety layer over the layout

A deliberate layout creates the preconditions for agent-native filesystem primitives that close the information and control gaps from the opening. The SOSP '26 paper proposes three. Introspect effects lets the filesystem describe what a pending operation will do before it does it: what files will change, what will be created, what will be deleted, so neither the user nor the agent is blind to side effects. Undo mutations snapshots intermediate states so the agent can self-correct after a bad operation with no user intervention. The paper's YoloFS prototype enabled agents to self-correct on most of eleven tasks with hidden side effects. Gate accesses offers progressive permission: you define access rules during execution as the agent's behavior shows its intent, instead of choosing between blanket approval and blanket lockdown at the start.

These primitives only work reliably when the filesystem knows which zone a file belongs to. Staging mutations in Zone 1 before committing them to Zone 2 is possible only if the zones are explicitly defined and the agent-native layer can distinguish them. A permissions policy that says Zone 1 is writable by the agent at all times and Zone 3 requires user confirmation is expressible and enforceable only when Zone 3 has a distinct, declared path. The layout conventions in this article are the foundation those primitives require.

A practical layout checklist a developer can apply today

Every convention in this article collapses into a set of explicit layout decisions made once at VM setup time. The three zones should be declared as named directories at provisioning time, never created organically by the agent or the runtime. Zone 1 lives at /sandbox/ or an equivalent ephemeral mount, destroyed at session end and never snapshotted as persistent data. Zone 2 lives at $AGENT_HOME/memory/ and $AGENT_HOME/skills/ with append-only write discipline and snapshotting as part of the persistent disk. Zone 3 lives at $AGENT_HOME/config/ or equivalent, never written by task execution and updated only by explicit operator action. Instruction files sit at the correct level: AGENTS.md at the repo root and per-package subdirectories, kept under 150 lines and treated as Zone 3, read by the agent but never written. SKILL.md lives inside each skill subdirectory under skills/, co-located with .memory.md, scripts/, tests/, and resources/. Specialist files appear at the repo root only when domain complexity justifies them, otherwise inline in AGENTS.md.

Memory files enforce append-only semantics across the board, with timestamped blocks, no edits, and no deletes, pruning context from the read side. Sandbox inputs remain separate from outputs: files entering a skill land in /sandbox/inputs/, files produced land in /sandbox/outputs/, and results move to the persistent zone explicitly through a download step. Permissions match zone semantics, with Zone 1 freely writable by the agent, Zone 2 writable only through append operations, and Zone 3 read-only to the agent process. AGENT_HOME stays an environment variable overridable at launch, never hardcoded, so the layout is portable across VMs and testable locally. Where a virtual filesystem abstraction is in use, backing stores get assigned by zone: local disk for Zone 1's latency needs, a content-addressable or versioned store for Zone 2, and a read-only mount or secrets manager for Zone 3. On Maritime, the persistent disk per agent VM is the natural home for Zones 2 and 3, the in-VM working directory serves as Zone 1, and the snapshot-restore scheduler preserves Zones 2 and 3 across sleep cycles at storage cost only.

Sources

  1. Don’t Let AI Agents YOLO Your Files:
  2. MUSE-Autoskill: Self-Evolving Agents via Skill Creation, Memory, Management, and Evaluation

More in Persistent Agents