Pi Daemon embeds Pi through the public
@earendil-works/pi-coding-agent SDK. It does not import Pi
source-tree internals and does not run stock runRpcMode()
inside hosted sessions: that helper owns process stdin/stdout, signal
handlers, and exit, so it is one-process/one-session infrastructure
rather than an embeddable dispatcher.
The current exact baseline is Pi 0.82.1. This is the first audited release for the full host because its public SDK provides:
AgentSessionRuntime and
createAgentSessionRuntime() for new, switch, fork, clone,
import, and runtime replacement;createAgentSessionServices() and
createAgentSessionFromServices() for rebuilding cwd-bound
per-session services;AgentSession.isIdle, waitForIdle(),
agent_settled, and entry_appended;RpcCommand union and
RpcResponse types;max thinking level.src/pi-sdk-contract.ts intentionally compiles the
reviewed RPC command and session-event unions against the installed SDK.
An upstream addition/removal is a deliberate compatibility event, not
something dependency automation may land silently.
fixtures/pi-rpc-command-types.json is the language-neutral
reviewed command inventory, and
test/pi-sdk-compatibility.test.mjs exercises real in-memory
AgentSessionRuntime replacement without a provider
turn.
package.json pins an exact SDK version and
package-lock.json pins every transitive tarball and
integrity digest. The project .npmrc routes the
@earendil-works scope to the public npm registry and
disables ambient registry host rewriting. This matters when an
enterprise npm mirror lags the public Pi release: npm ci
must consume the reviewed lock rather than silently resolving an older
package from the ambient registry.
Every Pi release so far, including 0.82.1, publishes a shrinkwrap
that omits integrity fields for three nested Pi workspace packages. npm
accepts those records, but Nix's prefetch-npm-deps
correctly rejects non-git dependencies without integrity. The checked
lock carries the public registry SHA-512 values for
pi-agent-core, pi-ai, and pi-tui,
and the compatibility test prevents a later lock regeneration from
dropping them.
npm run lock:repair-integrity restores those values from
the registry's own published dist.integrity for the exact
name and version the entry already names, so an upgrade does not need
the repair performed by hand.
npm run lock:repair-integrity:check fails without
rewriting, for CI. Where the same tarball also appears elsewhere in the
lock with integrity intact, the script cross-checks the two and refuses
on disagreement; where it does not, the registry is the only witness,
which is why the script accepts only
https://registry.npmjs.org/ URLs. flake.nix
selects npmDepsFetcherVersion = 2 because the older Nix
fetcher does not populate npm's offline cache correctly for those nested
shrinkwrap entries; downgrading the fetcher makes npm ci
request uncached Pi tarballs.
The exact fixed-output cache is also exported as
packages.<system>.npm-deps. Release staging can run
nix build .#npm-deps before the package build; after that
output is in the Nix store or a trusted binary cache,
nix build --offline .#npm-deps requires no registry. First
materialization has an outer three-attempt bound around the pinned
fetcher, but only reviewed transport failures such as curl 92 HTTP/2
framing and timeouts retry. Integrity, package identity, lock, and
unknown failures stop immediately. Structured lines name the tarball,
transport class, attempt/max, backoff, and whether a partial cache was
retained or removed; credentials and response bodies are never added.
The recursive fixed-output hash remains the final byte-for-byte
authority.
Read the Pi release notes plus complete SDK, RPC, extension, settings, session-format, and security documentation for the candidate version.
Confirm the exact package exists independently of the ambient mirror:
npm view @earendil-works/pi-coding-agent@VERSION version dist.integrity \
--registry=https://registry.npmjs.orgUpdate the exact dependency and regenerate only from the public registry:
npm install --package-lock-only --ignore-scripts --save-exact \
@earendil-works/pi-coding-agent@VERSION \
--registry=https://registry.npmjs.orgRestore any missing published nested-package integrity fields
from each package's npm view ... dist.integrity output. Run
npm ci --ignore-scripts; the Pi lock-integrity
compatibility test must pass.
Update PI_SDK_COMPATIBILITY_VERSION, the RPC command
fixture, required event mapping, protocol thinking levels, and
compatibility assertions together. Review every union difference; never
weaken the exact assertion merely to make compilation pass.
Keep npmDepsFetcherVersion = 2 and refresh the
pinned Nix dependency hash with npm run nix:deps-hash
rather than transcribing a fixed-output mismatch by hand, then run the
focused SDK compatibility test. The repository's final queue/CI then
owns the complete Node and Nix gates.
When provider/session behavior changed, run the optional credentialed live multiplex acceptance and preserve the zero-Pi-child-process assertion.
Each logical host slot uses AgentSessionRuntime. Runtime
replacement recreates locked cwd-bound services, rebinds
extension/session listeners to runtime.session, and durably
records the new Pi ID/file before returning; stale
AgentSession, SessionManager, resource loader,
or extension objects do not survive a replacement. If rebinding or
identity persistence fails, the adapter remains invalidated rather than
serving the disposed conversation. The raw /rpc surface
preserves Pi command/event shapes, but a daemon-owned transport-neutral
controller performs dispatch and routing.
Per-session configuration is a snapshot built from supported public
SDK inputs. The default unisolated mode does not promise
independent process.env, cwd, module globals, provider
registries, or arbitrary extension code inside one Node heap. Never swap
process-wide env/cwd around concurrent turns. Provider secrets use
scoped auth data where supported, tool env uses scoped operations/spawn
hooks, and raw secrets are not persisted in daemon manifests.
Rollback means reverting the exact SDK version, lockfile, compatibility version and command fixture, event/thinking mappings, and Nix dependency hash in one change. Do not float a semver range or move a published Pi Daemon tag. Durable Pi session files must remain readable by the rollback version; if Pi changed its session format incompatibly, stop admission and require an explicit migration or forward fix rather than opening files with an unverified older SDK.