pi-daemon1.3

Log 01 · Overview

Durable agents, free of any process.

pi-daemon keeps Pi agents in durable sessions that no process owns — not the terminal you started one from, not the client watching it, not even the daemon serving it. Close the laptop, restart the host or upgrade it mid-turn: each session carries on from its last commit, and any client on any machine can pick it up.

1 file
is a whole session: its chats, tasks and questions. Copy it to move it.
0
processes per session: a worker per profile runs them, and an idle session is a closed file
5
ways to attach and detach freely: Culture, pi-client, editors, applications and the browser
100 ms
the most a crash can take back; the rest resumes by itself

01Many lifetimes

One session, many lifetimes

A Pi in a terminal lives exactly as long as its process. A pi-daemon session lives in its own Pi Durable store instead, so nothing that touches it — a client, a worker, the daemon, the machine’s uptime — decides how long it lasts. Clients attach and detach; processes start, crash and restart; the session simply continues.

One session, many lifetimes A time line. At the top, one session: an unbroken band of commits from left to right. Below it, everything that touches the session comes and goes. pi-client on a laptop attaches; an application sends a turn and leaves; the laptop closes. With nothing using it, the store closes and the session is a file on disk, so the worker process crashing and restarting meanwhile touches nothing. Culture on a phone attaches to answer a question and the store opens again; the daemon is upgraded and restarts; the laptop comes back and pi-client attaches again. None of these lifetimes is the session's: it continues through every gap. THE SESSIONsession.sqliteevery turn, answer, question and tool call is a commit; the band never breakspi-clienton a laptopattachedattached againlaptop closedCultureon a phoneanswers a questionan applicationover AHPsends a turnworkerthe profile’s processcrashdaemonpi-daemon serveupgradestoreopen in memoryopenopenopenclosed on diskreopens
Fig. 1.1The red band is the session. Every other lifetime is shorter, and none of their gaps is the session’s.
  • Free of its clientStart a session from pi-client on your laptop, answer its question from Culture on your phone, let an application send it the next turn. Detaching never stops anything.
  • Free of its processNo process belongs to a session. A worker per profile runs whatever is working; an idle session costs a closed file and a catalog row.
  • Free of the daemon’s uptimeRestarting or upgrading the daemon is a resume: unfinished work picks up where it was committed, with no client action.
  • Free of the machineA session is one SQLite file. Back it up or move it to another host by copying it.

02Crash-only

What happens when you kill it

The proof is the worst case. pi-daemon keeps no journal, ticket store or replay log of its own: it hands work to Pi Durable, which commits every input, model step and tool call before anything sees it, and it records which sessions still hold unfinished work so it can pick exactly those up again.

What a kill -9 mid-turn does Four lanes over time. A client sends turn t7; the worker submits it to the session's Durable store with request id ahp:culture:t7, and the catalog marks the session live before the first commit. The model streams its answer, committed at most every 100 ms, then calls bash: the call's intent is committed before it runs. kill -9 cuts every lane. Only the last uncommitted window, at most 100 ms of streamed output, is lost. The worker restarts after 100 ms; because the catalog still marks the session live, its store reopens and its work resumes with no client action. bash is not declared replay-safe, so instead of running again the model gets an interrupted result, carries on from its checkpoint and answers. The client reconnects to a fresh snapshot that already shows the running turn; sending t7 again is rejected because the turn was already started, so it runs once. The answer is committed, the submission settles done and the catalog clears the live mark. CLIENTCultureWORKERprocessSESSION STOREsession.sqliteCATALOGliveWork≤ 100 mslostrestarts after 100 mspi.userplacedassistantcalls bashtool intentcommittedresume()store reopensbashinterruptedanswercommittedturn t7submit · requestId ahp:culture:t7reconnectfresh snapshott7 againrejected: already starteddonemarked live before the first commitcleared after the laststartup resumes exactly these sessions kill -9
Fig. 1.2The turn runs once. The cut costs only the shaded window; the tool that cannot safely run twice is reported to the model as interrupted instead.
  • Accepted means keptAn input is in the store before the client hears it was accepted. It is answered, or reported unanswered, whatever happens to the process.
  • Retries are freeAHP turns become Durable submissions with the request id ahp:<clientId>:<turnId>. Sending a turn again after a reconnect finds the same submission.
  • Tools are honestA call’s intent is committed before it runs. After a crash only a tool declared replay: "safe" runs again; any other gets an interrupted result with its output so far.
  • Idle stays closedAt startup only sessions marked live in the catalog are opened. Thousands of idle sessions cost nothing until someone touches one.

03What it is

One daemon, a worker per profile, a store per session

One pi-daemon runs per user per machine, as an ordinary user service with one listener, one catalog and one bearer. The server process authenticates, keeps the catalog and routes; it never runs a model call, a tool, an MCP server or an extension. Each profile gets its own supervised worker process, which holds the Durable Harnesses of that profile’s sessions. A crashed worker restarts and resumes its sessions; the others never notice.

pi-daemon topology Clients on the left — Culture, Paratenic's AHP upstream connector, an editor over ACP, an application over AHP or Chord, and a browser on /web — share one HTTP listener in the server process. The listener checks the bearer before routing; the router looks the session up in catalog.sqlite and forwards it over IPC to its profile's worker. Each worker is a separate supervised process holding a Harness pool and its sessions' SQLite stores: open ones, ones with unfinished work, and closed ones on disk. CultureAHP ParatenicAHP upstream an editorACP an applicationAHP or Chord a browser/web over Chord one listener/ahp · /acp · /chord · /web bearer check401 before any route routersession → its profile catalog.sqlite Harness poolregistry · models · MCP Harness poolits own extensions open live closed open closed SERVER PROCESS · NO AGENT CODE WORKER · PERSONAL WORKER · CACOPHONY ipc
Fig. 1.3Many clients, one listener. Agent code lives only behind the hatched worker edges.

The architecture, process by process

04Ways in

Open protocols, the same sessions

  • /ahpAgent Host Protocol 0.8The primary surface. Culture on every platform, Paratenic’s upstream connector and applications in any language list, create, prompt, steer and fork sessions. State is a projection of committed Durable state.
  • pi-clientTUI Pi, detachedpi-daemon’s own terminal client: TUI Pi’s transcript, editor, keys and footer over /chord, with every host’s sessions in one picker and sidebar.
  • /acpAgent Client ProtocolFor editors such as Zed: new and loaded sessions, prompts streamed as session updates, cancel, and agent questions as permission requests.
  • /chordDurable’s own viewsConversation views and agent events for JavaScript clients, with ChordClient in the package, pi-client and a small /web page on top.

Every path except /healthz and /readyz needs the instance’s bearer, checked before any route runs. All three surfaces reach the same sessions, so you can start a turn from an application, watch it in Culture and answer its question from an editor.

How each protocol maps onto Durable

05Where it sits

A node’s agent host, on its own or beside Paratenic

Three ways to run it Three panels. Standalone: Culture and an editor connect straight to pi-daemon on a node, Culture over AHP and the editor over ACP; pi-daemon holds the sessions' stores. Beside terminal Pi: Culture connects to Paratenic, which carries a Pi running in a terminal through its extension and backend socket, and republishes pi-daemon's sessions through its AHP upstream connector. A fleet: Culture is multi-host and connects to pi-daemon on two machines, each with its own URL and bearer. CultureAHP an editorACP pi-daemonthe node's agent host CultureAHP Paratenicone AHP host terminal Piits extension pi-daemonconnect ahp Culturetwo hosts pi-daemonatlas pi-daemonvega A · STANDALONE NODE B · BESIDE TERMINAL PI C · A FLEET socket AHP
Fig. 1.4pi-daemon is a complete AHP host. Paratenic is optional, for one view of daemon sessions and Pi running in terminals.
  • StandaloneCulture and editors connect straight to /ahp and /acp. Nothing else is needed on the node.
  • Beside terminal PiParatenic republishes the daemon’s sessions with paratenic connect ahp, next to the Pi you run in tmux.
  • A fleetCulture is multi-host: add each machine’s daemon with its own URL and bearer, and see them all at once.

Clients and how they connect

06What it is not

A generic host, by design

It is notBecause
an application serverIt has no wake, tickets, schedules, nudges, deadlines or delivery receipts. Applications express those as ordinary turns, cancels and session lifecycle, and bring behaviour as a profile’s extension modules and MCP servers.
a sandboxA worker is one trust domain and every client of an instance shares its bearer. Mutually untrusted work needs another uid, a container or a remote execution environment.
a home for TUI sessionsPi Daemon sessions and the sessions of pi in a terminal are separate pools. Nothing is imported or exported between them.
0.3.x1.0 is a rebuild on Durable with no compatibility: the Session API, NDJSON socket, Pi RPC host and wake tickets are gone, and old state is left untouched.

07Reading the drawings

One vocabulary on every page

How to read the drawings The glyphs used in every drawing. A cylinder is one session's SQLite store: solid while it is open in a worker, dashed while it is closed on disk, with a red band while it holds unfinished work that resumes at startup. A square is a Durable task: hollow pending, filled running, half-filled waiting on other tasks, and a dot inside while completing. A tag is a submission: dashed while queued, solid once placed, green with a tick when done, red with a cross when unanswered. A red tick on a rule is a commit. A hatched frame is a process: a crash stops at its edge. Indigo lines are protocols, ochre is a worker process. STORESopenin a workerclosedon diskunfinished workopen, marked liveresumes at startclosed, marked liveDURABLE TASKSpendingrunningwaitingcompletingon its childrenowned work endsSUBMISSIONSqueuedplaceddoneunansweredMARKSa commita processcrashes stop herea protocolworkinghighlighted: live
Fig. 1.5Stores, tasks, submissions and commits are drawn the same way throughout.

08Start

From nothing to a session in Culture

  1. Declare the service and a profile

    services.pi-daemon = {
      enable = true;
      profiles.personal.cwdRoots = [ "~/src" ];   # sessions may only run here
    };

    Home Manager installs one per-user service, pi-daemon, and its watchdog, on systemd, launchd or Nix-on-Droid’s supervisord. It listens on 127.0.0.1:7463.

  2. Check it and find the bearer

    pi-daemon status                     # exits 0 once ready
    ls -l ~/.local/state/pi-daemon/api-token   # generated, owner-only

    Point clients at the file; never paste the token into chat or a command line.

  3. Add it to Culture

    hosts:
      - id: pi
        label: Pi Daemon
        url: ws://127.0.0.1:7463/ahp
        token_file: ~/.local/state/pi-daemon/api-token

    Your profile appears as an agent. Create a session under one of its cwdRoots and send a turn.

  4. Or attach from any terminal

    pi-client                        # every host’s sessions, in a picker
    pi-client --new --name "Notes"   # a new session, and attach

    Quit whenever you like: the session keeps working, and you can pick it up again from anywhere.

The full quickstart

Release

These pages describe pi-daemon 1.3.1, of 18 October 2026: pi-client arrived in 1.3, module commands in 1.2, and tool approvals, terminals and changesets in 1.1.