How it works
The parts of Pistis, and why a crash loses no work.
Pistis splits a coding agent in two. The part that thinks and holds your keys runs on your server. Only the part that runs commands goes into the sandbox. That's why the sandbox can die at any time without losing work.
The parts
Other pages say "your Pistis server" for the brain. Config keys, commands and service names use these names:
- Brain. The Pistis server process. It runs the agent and the model, and keeps the conversation, approvals and keys in its database. The web app, Slack and the HTTP API all talk to it.
- Relay. A small service next to the brain. The brain and the sandbox both connect out to it, and it passes their messages without reading them. It holds no keys.
pistisd. A small program inside the sandbox. It reads files, writes files and runs commands. Nothing else.- Ledger. The brain's record of every tool call, written before the call goes out and again when its result is saved.
- Checkpoint. A saved copy of the sandbox's
/workspace, kept on your server after each turn.
How a command travels
- The model asks to run a command, such as
npm test. - The brain writes started in the ledger.
- The command goes through the relay to
pistisd, which runs it in/workspace. - The output streams back the same way.
- The brain saves the result and writes done.
When something dies
| What dies | What happens |
|---|---|
| The sandbox | On the next command, the brain resumes, restarts or replaces it, restored from the last checkpoint. |
| The brain | Another brain takes over its sessions, or it reloads them when it restarts. The turn continues. |
| The relay | Restart it. It keeps its state in one file, so sandboxes reconnect. |
In each case, a command that was running is reported to the model as an unknown outcome, and never run again by Pistis.
Your work is on your code host too
After each turn, Pistis pushes the session's repo to your code host as refs/pistis/sessions/<session>: every change the agent made, committed or not. It is a hidden ref, not a branch, so no CI runs and your branch list stays clean. The push comes from your server with the session's credential; the sandbox never holds it. The agent's own git state doesn't change.
So the work survives even when the sandbox, the server's disk and the session are all gone. To get it back:
git fetch origin refs/pistis/sessions/ses_8a2c…:recovered
git switch recoveredA change that looks like a credential (a cloud access key, a private key, a token) is not pushed. The server logs sync.blocked with what it found, never the value.
Why not retry?
A workflow engine retries a step after a crash. That is fine for ls and dangerous for git push --force, a migration or a deploy. Pistis never guesses. The model is told the command may have partly run, and it decides what to do.
Checkpoints
Only /workspace is saved, as of the last finished turn. Installed system packages and running processes are not. Copies over 256 MiB are skipped and the previous copy is kept. A new sandbox is restored before setup runs, so setup doesn't run twice.
How a sandbox joins
pistisd opened.The only secret a new sandbox gets is a join token. It works once, for one sandbox, and expires within ten minutes. A start-up script moves it out of the environment before any of your code runs. After joining, the sandbox holds only passes that work at the relay and nowhere else.
Under the hood
Pistis is built on two open-source libraries: pi-durable, which saves the agent's state so it survives crashes, and pi-env, which runs file operations and commands on a remote machine. pi-env's messages travel unchanged over a WebSocket through the relay.