The file model
An agent reads and writes files across three surfaces, and they are not interchangeable. One holds the organization’s durable knowledge and the agent may only read it. One is the agent’s own deliverable surface, scoped to its task. One is the disk inside the sandbox, which disappears when the sandbox does. Keeping them distinct is what stops an agent from overwriting curated organizational content as a side effect of doing its work, and what stops one task from reading another’s files.The problem
“The agent needs files” hides three different requirements that pull in opposite directions. The agent needs context it did not produce — documentation, policies, reference material that belongs to the organization and outlives any task. That content is curated. An agent that can write to it can corrupt it, and a bad edit made by a model at 3am is discovered weeks later by someone reading the wrong version of a policy. The agent needs somewhere to put results that a user can retrieve after the task ends. That has to be durable and it has to be attributable to the task that produced it. The agent needs a working disk — somewhere to check out a repository, install dependencies, and write intermediate files. That is high-churn, large, and worthless once the work is done. Collapsing these into one store fails in a specific way. If the shell tool and the file tool write to different places, code the agent saves is invisible to the commands it runs, and the task stalls — the agent writesscript.py, runs
python script.py, and gets “file not found”. This is not hypothetical; it is
the failure the current design was built to fix.
How AgentArea approaches it
Three surfaces, described in the code as tiers.
The organization context store is read-only by construction. The toolset that
exposes it offers
list_context and read_context and nothing else — there is
no write or delete method to call. This is a property of the tool surface rather
than a permission check that could be misconfigured. Writing to org context is a
separate, explicit capability, so the sandbox never mutates it as a side effect.
The task workspace is content-addressed and scoped by both workspace and
task. Objects live under a key built from the workspace ID and task ID:
/objects/<that same hash>. A reference whose URI and digest disagree is malformed and rejected.
Paths are normalized before use: absolute paths, backslashes, .. traversal, and
paths that are not already in canonical form are all refused rather than cleaned
up. Rejecting rather than normalizing means a path that looks odd never silently
becomes a different, valid path.
The sandbox filesystem is what the shell sees. The file tool writes through
the control plane’s /sandbox/files endpoint to the pod’s /workspace, which is
the same filesystem bash runs against. That is what keeps the file tool and the
shell tool coherent.
Writes go to two places
A file the agent saves is written to the sandbox disk and then written through to the durable task workspace. Reads come from the sandbox disk, because that is the live state the shell is also changing. The write-through leg fails loudly. If the durable write fails, the tool raises rather than reporting success, on the reasoning that a deliverable the user cannot reach is a silent loss. Reads fall back to the durable workspace when the sandbox returns 404. That covers task inputs which are materialized onto the sandbox disk lazily: the agent can read an input file whether or not a shell command has run yet.Concurrency is explicit, not last-write-wins
The task workspace is versioned. Each commit carries a generation, the generation it was based on, and a fencing token, and the pointer to the current manifest is updated conditionally. A commit built on a stale base fails with a workspace conflict rather than overwriting whatever landed in between. Transfer URLs are deliberately excluded from the durable identity. The manifest reference that travels through Redis and workflow payloads carries no credentials; signed URLs are generated at activation time and are valid for a single short-lived request.Why not one shared filesystem for everything
A single mounted volume that all tasks and the org store share is the smallest possible design. No manifests, no content addressing, no write-through, and the shell and file tools are trivially coherent because there is only one disk. It gives up the two properties that matter most here. Task isolation disappears — any task can read and overwrite any other task’s files, and the “outside the authorized task prefix” check has nothing to enforce, because there are no prefixes. And the org store becomes writable by anything that can write a file, so an agent can corrupt curated content by accident. It also does not survive the sandbox being ephemeral. The whole point of reclaiming pods is that their disks go away, and a design whose durability story is “the volume is still there” cannot reclaim anything.Why not make the org store writable by agents
Agents accumulate useful knowledge, and letting them write it back is how a system gets better over time. The argument for it is real. The platform’s position is that writing to shared organizational memory is a different act from doing a task, and should be a different, explicit capability rather than an ambient side effect of having file tools. An agent with ambient write access to org context can be steered into corrupting it by the same prompt injection that would otherwise only have cost one task. Because the org store is what every future task reads, a bad write there is persistent and affects work that has nothing to do with the compromised task. The cost is that there is currently no supported path for an agent to contribute to org context; that has to go through whatever process writes the store directly.Limits
There is no per-user file surface. Scoping is by workspace and by task. Two users working in the same workspace read the same organization context, and there is no{user_id} prefix in the workspace repository’s key layout. A per-user
memory surface is not part of the current model.
The org context store is workspace-wide, with no narrowing below that. Any
task in a workspace can read everything in that workspace’s context store. There
is no per-agent, per-user, or per-task restriction on which context files are
visible, so anything placed there is readable by every agent that runs in the
workspace.
When the sandbox file API is unavailable, writes become durable-only and the
shell cannot see them. If the control plane returns 503 — for example on a
backend with no per-task file routing — the file tool writes only to the durable
task workspace and reports success. The file is retrievable by the user but is
not on the disk bash runs against, which reproduces exactly the invisibility
problem the write-through design exists to prevent. The agent gets no signal that
this happened.
Nothing written only by a shell command is durable. Write-through applies to
the file tool. A file created by bash and never collected as an artifact lives
on the sandbox disk and is deleted with the pod. See
sessions for when that happens.
Within a task, there is no separation between surfaces on disk. The sandbox
filesystem is one namespace. Task inputs, agent-authored files, and intermediate
build output share it, and the prefix guarantees described above apply to the
durable store, not to paths inside the pod.
The path checks are not shared between the two tools. The org context toolset
applies its own simpler check for absolute paths, backslashes, and ..
components, separate from the workspace repository’s normalization. They agree
today on what they reject, but they are separate implementations rather than one
enforcement point.
Related
- Sessions — when the sandbox disk disappears
- Artifacts — how task output is collected and served
- Isolation — the boundary around the filesystem
- Authorization basics — how workspace scoping is enforced elsewhere