The split matters more than the feature list.
Earendil released Pi 1.0 on October 1. The coding agent now includes Codemode, Model Context Protocol support, virtual models, deferred tool loading, prompt-cache warming, transcript-aware prompt changes, and a full-screen terminal interface.[1] That is already a wide control panel.
The release does something sharper beside it. Long-running, multi-client work does not get folded into the stable coding agent. It ships as Pi Durable, a separate experimental package. Earendil says the terminal agent remains a tool for one person on one machine. If its process dies, that person inspects the result and continues. Pi Durable handles a different job: many conversations, attached clients, stored work, and restart recovery.[2]
A durable agent is not a terminal session with a database bolted underneath.
This is good product restraint. Interactive work and unattended work have different failure contracts. A person at the keyboard can resolve ambiguity after a crash. A service must decide in advance whether a half-finished tool call may run again, whether a repeated request is the same job, and which process owns the state.
Replay policy is the real firewall.
Pi Durable stores each tool call's intent before execution. After a restart, it reruns the tool only when the tool declares replay: "safe". A call without that declaration returns an interrupted result to the model. The package documentation uses a search call as the safe example and a production deploy as the call that must not repeat.[3]
That small flag carries more weight than a generic "resume" promise. Reading an issue twice is usually harmless. Charging a card, publishing a package, or deploying a release twice is not. Recovery needs a per-effect decision. The model should not invent that decision after the process returns.
Submissions get a separate guard. A caller can attach a requestId. Retrying the same ID returns the existing submission instead of placing another one. This controls duplicate admission. It does not make every downstream tool exactly-once. The input gate and the effect gate remain separate.[2][3]
Storage has a custody label.
The package ships memory, SQLite, and JSONL backends. It also exposes a conformance suite for custom storage. One process owns a storage at a time. The README states that there is no cross-process lock.[3] That limit belongs in every deployment plan. Two workers opening the same state file is not a scale-out strategy.
The SQLite backend uses write-ahead logging with synchronous = NORMAL. The package says commits survive process crashes, while the newest commit may be lost after a power or host failure. JSONL can use fsync before each commit marker.[3] "Stored" needs a named failure boundary. A clean process restart, a dead host, and a lost volume are three different tests.
The same care appears in the live view. Answers and tool output are committed at most every 100 milliseconds. A crash can lose that newest window. Slow watchers eventually receive a fresh snapshot instead of an unlimited backlog.[3] These are useful, concrete limits. They make the interface inspectable.
Use the package boundary as an operating rule.
Keep an agent in the interactive chassis when a person owns the session, can see the process, and can decide what to do after interruption. Move toward a durable harness when work must survive process death, accept commands from more than one client, run several conversations at once, or expose a task graph outside the terminal.
Do not cross that boundary on a feature checkbox alone. Pi Durable is marked experimental. Its API may change without notice. Before adoption, choose one storage owner, classify every effect by replay safety, assign request IDs at the intake edge, and run a crash drill around a real side effect.
The packages are real. The public npm registry reported version 1.0.0 for the coding agent and Durable packages during this inspection. A clean temporary install loaded Pi Durable, opened an in-memory harness, created its root conversation, read the empty committed view, and closed it. That smoke check proves the published package can start on the inspected Node runtime. It does not prove SQLite recovery, tool replay, provider calls, or production fitness.[4]