What if…

Technical questions about what cherry π does when something goes wrong, or someone tries to make it. Each answer says what happens, and where the field manual has the detail.

Updated Field manual Extensions Brand kit Download Markdown

The model in one paragraph

An agent in cherry π is limited in four places. The box (section 09) limits what can run: a vendor agent runs whole inside it, with its shell, hooks and MCP servers. The token limits what that running process may ask the workspace for. Every tool is a verb, and each verb call is checked against the caller's policy and receipted. The proxy and the signer limit what can leave the machine. And you are asked about the calls that are hard to undo. None of these is meant to hold alone, and each answer below says which of them applies.

Inside the box

What if the agent reads PICACHE_TOKEN from its environment?

It already has it. The token is how its pane calls picache, so reading it gains nothing. The token names one actor (your shell, a vendor agent, Picache) and the folder it works in. It is minted when that pane starts and revoked when the pane closes.

Whatever presents the token can only call the verbs that actor may already call, and each call is checked by policy and receipted under the actor's name.

Anything else running in the same box can use the token too. That is why the box has to be tight, and the next questions are about how tight it is. Field manual, section 04.

What if the agent just uses bash instead of your tools?

Then its bash runs under the same limits as the agent. The box is around the whole agent, so its bash, Python or anything it installs is inside it too. It can write only its folder, its config and its own temp folder. With the default network setting, it reaches the network only through the proxy.

Some tools sandbox only the code interpreter. There, an agent's own shell still runs outside the sandbox.

Every tool is also a plain command, picache <verb>, so a script in any language can call the tools under the same policy, approvals and receipts. Section 09.

What if it leaves something behind that runs later as me?

Outside its folder, config and temp folder it can't write at all. So it can't add a cron job, a launch agent or a line to your shell profile.

Inside its folder, the risk is a file your own tools later run as you. The usual one is git's: a hook or setting in the repository. The box can't write those. When the box ends, cherry π lists anything the agent left in the repository that your git would write through as you and that git itself would not have made. It tells you to look at each one and remove it before you run git in that repository.

A box also can't rebase, so it can't leave a half-finished rebase for your next git rebase --continue to pick up as you.

Git is the only tool checked. Any other tool of yours that runs a file from the project (a build script, a Makefile) runs what the agent wrote, as it would for any collaborator's change. Review those files before you run them.

What if it reaches for localhost, my network or a metadata endpoint?

With the network set to ask (the default) or allowlist, the agent's only way out is a proxy outside the box. A name that resolves to this machine or a private network is refused unless a rule names that exact address. A connection that tries to go around the proxy has no route.

The proxy decides by host name and port. It carries HTTPS tunnels and plain HTTP, and never decrypts HTTPS.

Setting the network to open takes the proxy away, except for the vendor of a key that is injected. The agent can then reach loopback and your local network, including other agents' proxies, and cherry π labels the setting "open, anywhere". Section 09.

What if it runs sudo?

An agent's pane in a box can't use sudo by default, and on Linux neither can any pane an agent opens. On macOS, an agent's pane outside a box, and a pane an agent opens, can run sudo only with your password (terminal.sudo.unboxed_agents, which can refuse it instead). Your own shell can use sudo. Before an agent or Picache types into a pane, sudo forgets your password, so what they type can't run on it. Use sudo.

Keys and the signer

What if a script in the box reads my API key?

With the agent's key set to inject, there is no key in the box to read. The agent holds a stand-in of the same shape. When it calls its vendor, the proxy hands the connection to cherry π's signer outside the box. The signer opens the real key, swaps it in and sends the request on over verified TLS. A request whose key header holds anything but the stand-in is refused.

An agent starts with hand-in, where the key does sit in the box's environment, until cherry π's record for that agent shows it running injected under this machine's kind of box. After that it defaults to inject. A launch set to inject that can't inject is refused, and the key is not handed in instead. Keep the key out of the box.

What if the signer, or the proxy, is the thing attacked?

The signer and the proxy are the high-value targets, so they are kept small and apart. Both run outside the agent's box.

The signer holds the keys, sealed. An injected key is opened only inside the signer, for a request to that key's vendor. Any other key is opened for cherry π only where it is used: a cloud model call, an agent's box when its key is handed in, or an app's own call. The peer-to-peer sidecar, which talks to other machines, runs in a box of its own, away from the signer's keys.

Your answers to the proxy's questions are kept as receipts, and the proxy keeps a log.

The signer answers any process running as you and does not check who is asking. The sealed store is protected by its file modes and the signer's root key.

What if a key ends up in a receipt, a log or a command line?

Every authenticated picache call leaves a receipt, so receipts are filtered twice. A verb that knows an argument is secret hides it first. Then anything shaped like a key (sk-ant-…, a bearer token, a variable named as a key, a password in a URL) is replaced by a note of what kind of secret it was. App hooks get the same filtering, or no text at all.

An agent's token or an app's secret typed on the command line is refused. Pipe it in instead. On Linux, a sudo-capable pane's environment reaches systemd in a private file, removed once read, and never on its command line.

The key log never records typed text. Text an agent types into a pane is filtered by shape only, and a password has no shape. Where your secrets go.

What if someone copies my cherrypi.db?

They get receipts with no keys in them, and pane records with no pane tokens. Each record keeps a digest of its pane's token, and the token can't be recovered from the digest. The file and its backups are readable by you alone (0600). Your keys are in a different file, sealed under a root key only the signer reads. Where your secrets go.

Approvals, crashes and evidence

What if every action needs my approval?

Most don't. Each verb has an effect class. Reads run. Writes that can be undone run too, and every Picache turn snapshots the folder before and after, so a turn can be put back. Calls that are hard or impossible to undo ask you, by default. Because you are asked only about those, each question is one worth reading. Section 03, Undo a turn's changes.

What if something irreversible is hidden inside a shell command?

It depends whose shell it is. A command Picache runs goes through the run verb. The shell policy classifies the command before it runs, and run is irreversible, so it asks you. If the command changed files in the folder, the turn's snapshots let you put them back.

A vendor agent's own shell inside its box is not a verb, so no effect class sees what it does. The box bounds it instead: where it can write and what it can reach. That is why the box is around the whole agent.

What if cherry π crashes in the middle of an action?

A call that changes something is written on the turn's task before it runs. That includes calls you approved and calls a script or an app makes. If cherry π crashes midway, the call is left marked uncertain and is never run a second time on its own. An uncertain effect blocks a retry until someone settles it in Recovery.

A question nobody answered waits in Recovery too, and approving it continues the turn from that call. Section 10.

What if nobody reads the receipts?

They are still evidence after the fact. Within a turn, a hash chain binds every receipt, refusals included, so a missing or altered one shows.

The desktop also uses them as they come in. Its status line counts refusals and failures, Go to finds them, and Recovery acts on uncertain effects and waiting questions. Section 10.

The web desktop

What if another program on my machine calls the web server?

The web server listens only on loopback, but every program on the machine can reach loopback, an agent included. So the desktop's pages and APIs need a browser you signed in.

A launcher on this machine mints a one-time code, and the browser trades it for a session of its own. A request that changes something must also come from one of the desktop's pages. A request without a session gets 401. A confined agent's box doesn't see the folder where the codes and sessions live. Sign a browser in.

What if someone copies my terminal's browser credential?

Open in browser copies nothing. It opens a one-time sign-in link, and the page then asks for a credential of its own.

If you make a credential by hand for pasting, it is spent when the browser connects. The answer carries a new key that only that page holds. After that, the pasted credential can't read, type or revoke anything. From a browser.

What if a served app's page tries to use the desktop?

Inside Cherrytop, an app's page runs sandboxed in an origin of its own, so its scripts can't call the desktop's APIs or read its page. It can send Cherrytop a message asking to open a pane.

A canvas widget may run one verb its manifest names, read-only. Any write that verb would make is refused before it runs. Cherrytop takes which app is asking from the frame the message came from, never from what the message says. The web desktop.

What if another site frames the desktop to trick a click?

The desktop's pages refuse to be framed by any other site. Its sign-in cookie is also SameSite=Strict, so a framed copy would be signed out even if a browser framed it.

Not covered

The answers above leave these open:

  • Keys are handed into the box until cherry π's record for an agent shows it running injected (above).
  • A vendor agent's own shell commands are bounded by the box, and nothing classifies them one by one (above).
  • Files your own tools later run from the project, other than git's, are yours to review (above).
  • An open network removes the proxy and its refusals (above).
  • Anything that can act as you outside every box (read your home folder, run as your user) can do whatever you can. Nothing here defends against that, because it is you, or something already past every boundary on this page.