A bot's work lives in storage, so whichever worker has the job picks it up where the last one stopped. If a machine dies, the work doesn't. If nobody is working, no machine runs.
Where this runs today
Everything on this page runs on our development environment at develop.chattic.us, and each behavior below has been run live there except where this section says otherwise. Staging and production still run the earlier Python control plane. They move over when we promote the TypeScript rewrite.
One path differs. A computer in a customer's own AWS account takes a simpler route today: the same snapshot and shared disk, but not the pi-durable handoff or the computer that stays up between turns. Editing files while the computer is off is merged and covered by our behavior suite. Its recorded live walkthrough is the one proof still outstanding.
The session is stored
pi-durable, published as @earendil-works/pi-durable, is the library underneath Chatticus's agent loop. It writes each step of an agent's work to storage before anything shows it: the transcript, the state of each tool call, the messages waiting to be handled.
Chatticus keeps one session per bot per channel. The data sits in S3, one file per commit, with a small DynamoDB index that makes a commit visible. Nothing about the session lives in a container's memory, so if a worker stops, another process can pick up from the last commit.
The rule that keeps this safe is the fence. Opening a session as its owner takes the next number in a sequence that only goes up, and every write checks that its number is still the current one. If a second owner takes over, the first owner's next write is refused and it stops. At any moment, only one owner can write.
The control plane around it is TypeScript now. We ported everything from Python, and the Python tree is gone from our develop branch.
A turn starts light and hands off
A message arrives
A serverless worker opens the session.
It loads the bot's stored session, runs the model, and answers. Plenty of turns end right here, and no computer ever starts.
The model reaches for the computer
The turn parks.
The first time the model calls a computer tool (read, write or edit a file, or run a command) the session is saved, the worker ends, and a start job goes out if no computer is up.
The computer takes over
It continues the same session.
A program on the computer claims the parked turn, takes the next fence number, and carries on in the same session. Tools run locally, and the model is reached through a gateway.
The turn finishes
The light path starts again.
When the turn is done, the next turn starts on a serverless worker again, with a higher fence than the last one had.
The computer is summoned, not assumed
Chatticus doesn't put a computer-ready barrier in front of the bot. A bot can answer while the computer is still starting, and a turn that never touches a computer tool never starts one.
People get the same deal. The Files panel in the web app lists and opens the workspace's files with the computer off, straight from the last snapshot. You can edit a text file, create a file or folder, rename, and delete, all with the computer off.
Those edits go into a pending changes overlay kept beside the snapshot. The next computer to start applies them after it restores the disk and before it runs any turn, so the bot sees your edit. An entry is cleared only after a snapshot that holds it has been recorded, and the overlay survives a crash of the computer in between.
Two protections come with it. Every save names the version of the file you started from. If the file has changed since, because the bot rewrote it or someone else edited it, the save is refused or kept as a conflict with both versions shown, and it is never applied silently. Files that look like secrets are masked until someone asks to reveal them, and each reveal and each edit goes into an audit log.
The edge is this: when the bot itself reads or writes a workspace file, that starts the computer. Viewing and editing from the web app doesn't.
Reading files without a computer
A computer that stays up between turns
After a turn ends the computer doesn't switch off. It keeps asking the control plane whether there's work: every second for the first minute idle, every three seconds until the fifth minute, then every ten. Nothing reaches into the computer. It only makes outbound requests, with no open port.
A follow-up message lands on a computer that's already running: no cold start and no snapshot to restore. A cold start takes around half a minute in our measurements, and 22 seconds of that is the median just to get a container running.
After 15 minutes without work the computer asks the control plane for permission to stop, saves a snapshot if the disk changed, and exits. Waiting work vetoes the stop. A stopped computer costs nothing to run, and the next message starts a fresh one that restores the snapshot.
When something breaks
A crashed computer is replaced. If a computer stops answering for 30 seconds, the control plane counts it dead. The next one claims the turn with a higher fence, restores the last snapshot, and the turn finishes. A tool call that was running when it died is reported to the model as lost, not run twice. In a live run we stopped the computer 20 seconds into a 90-second command. A replacement claimed the turn about 30 seconds later and the right answer came back.
What a crash can cost. The replacement restores the last snapshot. The computer saves one 30 seconds after a turn goes quiet and every ten minutes while it sits idle, so a crash can lose edits made since the last snapshot. A computer that can't reach the control plane for 25 seconds stops itself, so two of them never write the same disk.
A maximum lifetime. A computer is replaced after at most 50 minutes. The control plane tells it to drain: it gives the turn in hand up to five minutes to finish, saves a snapshot, and stops. In a live run one computer, kept busy by a message about every eight minutes, served seven turns and drained at 3,004 seconds. The next message started a fresh one.
Snapshots on storage you own
The durable disk is a snapshot in S3: the workspace and the browser profile, packed one file at a time with an index beside it, so the web app can open one file without unpacking the rest. A computer restores from the snapshot when it starts, and any host that can run the computer image can do it.
To keep snapshots small, package and build folders such as node_modules are left out, and so is any file over 50 MiB. After a cold start the bot reinstalls what it needs.
Where the snapshot lives depends on where the computer runs. For a computer in a customer's own AWS account it goes to a bucket in that account. We ran that end to end on development: a file written on one start was still there after a stop and a restart. In our own accounts it goes to a bucket of ours.
Isolation, in plain words
The shell isn't the owner. Commands the model chooses run as an unprivileged user with a stripped environment. That user can't read the credentials the computer's own program holds, and it can write only to the workspace and temporary space.
Credentials per turn. Each turn gets its own short-lived credentials, good for about an hour. They can't reach another organization's data or another bot's conversation.
The model key stays home. The computer calls the model through a model gateway in the control plane, using a token that works for one turn. The computer never holds the model key, and a token taken from it can't be used for anything else.
Bots on one computer share its workspace, so a bot is not a security boundary against its teammates. The organization is the boundary. The limits we know about are written down in the open in the project's handoff notes.
Read the handoff notes and their limits
Built around the person who runs it
Hosted coding agents that bundle their own cloud computers sell you the agent and the machine as one thing. That's a fair deal if you want one bill and nothing to set up.
Chatticus is built the other way around. The session is in storage, so no machine owns it, and the computer is a host you point it at: your own AWS account, where the deployment already lives, or hardware you own. What you spend on that computer is your own AWS bill, and the source is MIT licensed.
On AWS this is proven. A computer in a separate customer account started, wrote files into a bucket in that account, and found them after a restart. On hardware you own, the design is a worker that pulls jobs, so nothing reaches into your machine, running the same image that runs on Fargate, EC2 and local Docker. Our live runs so far have been on AWS.
Cheap when nobody is working
Nothing always on. There's no always-on process in the path a reply takes and no load balancer in front of the API. The transcript lives in DynamoDB. A stream lasts one turn, so reconnecting is a new request that reads what's already stored.
Progress you can watch. Output reaches the browser in coalesced chunks. A person watching sees a turn move along, which is what they need. We don't pay for token-by-token delivery.
A computer that stops. At AWS list prices the computer we run costs about a cent an hour, and it stops after 15 idle minutes. Polling for work adds a fraction of a cent an hour on top.
Not built yet
None of this exists today, and we're not putting dates on it.
Sizes
Move a running session between instance sizes
Today there's one computer image and one size. The session already lives outside the machine, which is what would make a move between instance sizes or types possible with pi-durable. Choosing a size for a task, and the move itself, aren't built.
Long-running work
Background processes and a live preview
A command runs to completion and ends with the turn. A dev server can't keep running in the background after the turn, and there is no live preview of it in the browser.
Files
Richer live file tools
The Files panel lists, opens, edits, creates, renames and deletes, and edits are limited to text files up to 256 KiB. Anything beyond those file tools is not built.