where does an agent keep FILES?
Give software somewhere to work and you've answered most of what it needs. The industry's answer for agents has been one of two bad options: hand over your real disk — your keychain, your documents, everything a bad instruction can reach — or rent a computer in the cloud, metered by the second, so the agent has a scratch directory that evaporates when the meter stops.
Both answers share an assumption worth questioning: that a file system has to belong to a machine. Yours, or someone else's. But the amount of disk a project actually needs is small, and what it needs from that disk is mundane — paths, directories, read, write, list. Nothing about that requires an operating system underneath. It just requires somewhere structured for bytes to live.
So the missing piece isn't a bigger disk or a cheaper rental. It's a disk that belongs to the project — one that travels when the project travels, and stops existing for you the moment you delete the file. That's what this lesson is about.
the DEFINITION
1. the workbook's own disk: a virtual file system — real files and directories, SQLite-backed — riding inside the artifact, readable and writable by the workbook's code and agents, and sealed off from the host machine by construction.
It's the third layer of the workbook anatomy: the interface up front, WebAssembly for compute, and underneath them a disk — so the file doesn't just describe a piece of software, it contains the place where that software keeps its things.
a disk you can QUERY
Under the paths, the VFS is tables — and that duality is the feature:
Here's the same picture as the engine sees it. Code and agents come at the store through paths; questions come at it through SQL; both land on the same bytes, and the bytes are riding in the html:
flowchart LR code["code + agents — speak in paths
open · read · write · list"] q["questions — speak in SQL
SELECT path FROM files WHERE …"] subgraph store["one SQLite store — gzip-bound into the html"] direction TB f1["/notes/june.org"] f2["/data/orders.csv"] f3["/reports/week-24.org"] end code -- "a program's verbs" --> store q -- "a question's verbs" --> store style store fill:#fbfaf6,stroke:#121316 style f1 fill:#a8d4f0,stroke:#121316 style f2 fill:#a8d4f0,stroke:#121316 style f3 fill:#a8d4f0,stroke:#121316 style code fill:#ffffff,stroke:#121316 style q fill:#ffffff,stroke:#121316
Most file systems make you choose: easy paths or real queries. Because this one is a database wearing a directory tree, questions that are painful on a normal disk — everything modified since the last deploy, every file over a megabyte, every note tagged urgent — are single statements. The claim deserves to be concrete, so here are three of them, against a real workbook's disk:
-- everything modified since the last deploy
SELECT path FROM files WHERE mtime > '2026-06-09';
→ /notes/june.org · /reports/week-24.org · … 6 rows
-- where the megabytes actually live
SELECT dir, sum(size) FROM files GROUP BY dir ORDER BY 2 DESC;
→ /assets 11.2 MB · /data 3.4 MB · /notes 0.2 MB
-- every file the agent touched this week
SELECT path FROM files WHERE writer = 'agent'
AND mtime > date('now', '-7 days');
→ 14 rows — its notes, two drafts, one finished report
Try asking your operating system the second question. There's a progress bar involved. Here it's an index lookup, because a listing was never a crawl in the first place — it was always a query, the way it should have been all along.
what's actually INSIDE
depth rung · skippable — the store's shape, for the curious
No mystery meat. The store holds three kinds of thing, and none of
them is exotic. Paths — the namespace, a table of names that makes
/notes/june.org mean something. Blobs — the bytes
themselves, one per file, sitting in the same store. And metadata —
sizes, times, kinds, who wrote what — as columns, not as a cache your
tools rebuild by crawling.
Directories deserve a sentence of their own. On a normal disk, the
question what belongs to this project? is answered by folklore —
a naming convention, a .gitignore, a README that says don't
touch /vendor. Here a directory is a fact in a table, the
project boundary is the store's edge, and "what's in this tree, who wrote
it, and when" are answers you SELECT, not answers you
reconstruct.
And the door swings both ways. Unbundle a workbook and the VFS unpacks to ordinary files in ordinary directories on your real disk — open them in anything, commit them anywhere, walk away entirely if you choose. The store is also plain SQLite, readable by the most widely deployed database tooling on earth. The format holds your files; it doesn't hold them hostage. That's the same no-invented-formats promise the whole anatomy makes, kept one layer down.
two readings, AGAIN
The workbook page describes one file with two readings — a document to a human, a container to an engine. The VFS is where that duality becomes concrete:
Opened in a browser, the VFS loads into memory. Code reads and writes it for real — a game saves, a dashboard filters, an agent's notes are right there — and when you close the tab, the file on your disk is exactly what it was. The artifact stays honest: viewing never mutates.
Docked into a Nexus, the same VFS becomes the workbook's live disk — persistent, synced, served. Writes survive restarts, schedules write into it overnight, and the copy you serve to a thousand people reads from it. Same paths, same queries, same code; the only thing that changed is that the disk now has a heartbeat.
sequenceDiagram participant T as a browser tab participant F as the .html file participant N as a nexus rect rgb(251,250,246) Note over T,F: reading one — opened F->>T: VFS loads into memory T->>T: code reads + writes — for real T--xF: tab closes — file byte-identical end rect rgb(232,243,250) Note over F,N: reading two — docked F->>N: engine takes the VFS live N->>N: writes persist · a schedule writes overnight N->>T: served copies read from the live disk end
Read the diagram's two halves as one promise with two tenses. In the top half the disk is a reading — fully real while you're there, gone without a trace when you leave. In the bottom half it's a residence. Nothing about the file changed between the halves; what changed is whether something with a power supply has agreed to keep its state.
the workspace IS the artifact
Here's the consequence that makes the whole construct worth a lesson. An agent's working directory — its notes, its drafts, its intermediate data, its org-layer memory — lives in the VFS of the workbook it's tending. Which means the workspace and the work product are the same object.
Hand someone the file and you've handed them the project: the app, its data, and the entire working state of the agents that built it. No "let me zip up my folder", no "it works on my sandbox". The thing you collaborate on and the thing you ship stopped being different things.
This is also what makes handoffs between humans and
agents boring, in the good way. There's no
export-from-the-sandbox step where context dies; the agent's scratch
files, half-finished drafts, and decision notes are sitting in
/notes next to the deliverable in /reports,
and whoever opens the file next — human or agent — starts from the
real state, not a summary of it.
a day in the LIFE
Abstractions should earn their keep, so here's one ordinary day in the life of one workbook's disk.
06:00. A schedule fires on the engine. An
agent runs its workflow, pulls the week's orders
out of /data, and writes the finished report to
/reports/week-24.org — a path that didn't exist at 05:59.
Its working notes land in /notes, timestamped, beside last
week's.
09:00. You open the served workbook with your coffee. The dashboard's chart isn't an email attachment someone generated — it's a live query against the path the agent wrote three hours ago. Nothing was uploaded, deployed, or synced, because the disk the agent wrote and the disk the dashboard reads were never two disks.
11:00. Your accountant asks for the numbers. She does not want a login. You unbundle one file out of the VFS and email her an ordinary CSV — the disk travels with the file, and any single file travels out of the disk.
23:00. Nothing happens, on your laptop, because your laptop was never involved. It could have been closed in a bag all day. Every byte in this story lived in the workbook's own disk — written by the agents, read by the served copies, versioned with the project. That's the whole pitch, wearing a Tuesday.
why this is the SAFE shape
An agent that needs your file system is an agent you have to trust with
your file system. An agent whose entire disk is the workbook's VFS needs
no trust at all — there is nothing else its writes can reach. Not
your documents, not your keychain, not a stray ~/.env. The
security model's grants-not-inheritance rule starts
here: the default disk is the one riding in the artifact, and everything
beyond it is a specific, revocable permission.
flowchart TD
agent["an agent — even a confused one"]
subgraph wb["the workbook — where writes can land"]
vfs["the VFS
versioned · diffable · restorable"]
end
subgraph host["your computer — no path resolves here"]
docs["~/Documents"]
keys["keychain · ~/.env"]
os["the OS disk"]
end
agent -- "every write" --> vfs
vfs -. "a specific, revocable grant — the only door" .-> host
style vfs fill:#a8d4f0,stroke:#121316,stroke-width:2.5px
style wb fill:#fbfaf6,stroke:#121316
style host fill:#fbfaf6,stroke:#121316
style docs fill:#d9dbd3,stroke:#121316
style keys fill:#d9dbd3,stroke:#121316
style os fill:#d9dbd3,stroke:#121316
style agent fill:#ffffff,stroke:#121316
Now add the part people underestimate: prompt injection. The Nexus lesson puts it plainly — anyone whose text reaches your agent is partially steering it. A web page it reads, an email it summarizes, a comment in a file. Give a steerable agent your operating system and you've built an exfiltration machine with a stranger near the wheel. Give it a VFS and the same hostile instruction hits a wall made of construction, not policy: the worst text can do is trash one project-sized disk.
And even that worst case is boring, because the disk lives inside a file that git has been tracking all along. A bad Thursday looks like this:
flowchart LR c1["tue
v1 ships"] --> c2["wed
agent writes /reports"] --> c3["thu
bad write trashes /data"] --> c4["thu + 30s
git revert — disk restored"] style c1 fill:#d9dbd3,stroke:#121316 style c2 fill:#d9dbd3,stroke:#121316 style c3 fill:#f3c5a3,stroke:#121316 style c4 fill:#13d943,stroke:#121316,stroke-width:2.5px
Versioned, diffable, restorable — not because anyone wired up a backup system for agent workspaces, but because the workspace is bytes in a file and files already have the best undo humanity ever shipped.
four places to keep BYTES
It's worth lining the disk up against its alternatives honestly. Project bytes live in one of four places today:
| travels with the project? | queryable? | sandboxed from host? | versioned with the work? | costs a meter? | |
|---|---|---|---|---|---|
| your OS disk | no — it's the machine | no — crawl it | it is the host | only what you commit | no |
| a cloud bucket (S3) | no — the project points at it | listings, not content | from yours — creds reach it | separately, if configured | storage + egress, forever |
| a rented sandbox volume | no — evaporates with the VM | no | yes | no | by the second |
| the VFS | it is the project file | yes — it's SQLite | by construction | git tracks the file | no — bytes in a file |
The honest read of that table: the other three still exist for reasons, and you'll meet them at your system's boundaries. The OS disk is where workbooks sit; a bucket is the right home for a terabyte of video; rented isolation is fine for a one-off job. But notice which column each one wins and which four it forfeits. The VFS is the only row that doesn't trade away the project's coherence to get its one virtue — because its virtue is the project's coherence.
where the disk ENDS
Honesty section. The VFS is a project-scale disk, not a media vault — SQLite holds gigabytes comfortably, but a workbook stays pleasant to share in the tens of megabytes, so heavy assets belong behind an engine with the workbook querying them. Put the catalog in the file and the warehouse behind the Nexus; the table above already told you a bucket wins exactly one column, and raw tonnage is it.
And in a browser, persistence is the file's: changes live in memory until you save or dock — the open tab is a reading room, not a writing desk. That's a designed property, not a gap — it's what makes opening a workbook from a stranger safe, and what keeps the artifact honest — but it means the browser alone is not where durable state accumulates. For durability, schedules, and serving, the engine is the answer, the way it always is for the living part.
questions people actually ASK
Are they real files or "files"?
Real, to everything inside: code opens paths, agents list directories, tools read and write bytes. The quotation marks only appear from the host machine's point of view — which is exactly the point. Your OS sees one .html file; the workbook sees a disk.
Can I get files out?
Always. Unbundle the workbook and the tree unpacks to ordinary files; or query the live VFS on an engine and export what you need. The disk travels with the file — it's never trapped in it.
What happens to the VFS when I email the file?
It goes along — the disk is bytes in the html, so sending the file sends the disk, exactly as it stood when you sent it. The recipient opens the same paths, runs the same queries, no setup. Their copy and yours are now two readings; if you want them to converge again, that's what docking into a shared engine is for.
Can code inside the workbook list MY computer's files?
No — and not because a setting says no. There is no path that resolves outside the artifact: every open, read, and list bottoms out in the store riding in the file, so "escape to the host disk" isn't a permission to deny, it's a sentence with no referent. Reaching beyond the file takes a specific, revocable grant — and that's the security model working, not failing.
What about two people writing at once?
That's a docked question — through a Nexus, the engine holds the live VFS and serializes writes, the same way it serves the workbook to both of you. Two open browser copies are two readings; the engine is where they become one disk.
Why SQLite underneath, and not a custom store?
Same reason as the rest of the anatomy: no invented formats. SQLite is the most deployed database on earth, battle-tested for decades, and it makes the disk queryable for free. The trick was never a new ingredient — it's what the existing ones do when they share a file.
the deep DIVES
Go deeper into this area — the technical docs underneath it.
keep GOING
The disk makes more sense the more of its neighbors you've met.