Skip to content

pi participant and claim guard

The optional pi participant runs the exact verified @earendil-works/pi-coding-agent 0.87.1 RPC host as a child process. Node.js 22.19 or later is required. Install the separately packaged extension from the source checkout using the installation commands below. Use its node_modules/.bin/pi executable or another exact 0.87.1 binary. The Python participant refuses a different version.

For the repository's Pi host, install dependencies and verify the installed security pin before launching it:

cd integrations/pi
npm ci --ignore-scripts
python ../../tools/sync_pi_dependency_pins.py

Pi 0.87.1 ships an upstream shrinkwrap that can install brace-expansion 5.0.9 even when the outer lock and its audit report 5.0.12. The verification command checks the reviewed registry archive against the outer lock's SHA-512 digest, then installs only that package's exact files. It does not resolve the remaining dependencies or change the admitted Pi version. CI runs this verification after each Pi installation. Run it after a fresh npm ci and before starting Pi.

Without an explicit claim binding, pi runs with no tools. This is useful for model-only turns and for testing the provider and session contract:

synapse participant ask pi "Reply with one sentence" \
  --model ollama/gemma3:1b \
  --pi-binary ./integrations/pi/node_modules/.bin/pi \
  --pi-directory "$PWD" --json

Configure the chosen pi model and its credentials using pi's own documented configuration. Synapse does not supply or infer a provider account. A completed participant.turn_result carries the provider's reported input/output tokens, cost, stop reason and an exact UUID resume token. Use --pi-resume-session UUID for a later CLI turn. Sessions live under the owner's XDG state directory by default; --pi-session-dir selects another owner-private directory. An unknown resume UUID is refused rather than silently starting a new session. The pi child currently inherits the launching process's environment, including any provider keys or hub tokens stored there. Launch it from an environment containing only the credentials the chosen provider needs; the claim guard is not an environment-secret boundary.

Enable claim-checked coding tools

First claim the intended files on the live hub with the exact Synapse seat and task. Query that claim's current epoch:

synapse adapters pi-claim-status \
  --identity PROJECT/seat --project PROJECT \
  --repository "$PWD" --task-id TASK-ID \
  --uri ws://localhost:8876

If the command reports eligible: true, pass its numeric epoch together with the same project, repository and task. The participant then loads the pinned extension and enables only pi's built-in read, grep, find, ls, write, edit and bash tools. Before sending a tool-enabled prompt, it requires pi's RPC command catalog to confirm that this exact extension file loaded:

synapse participant ask pi "Edit the claimed file" \
  --model PROVIDER/MODEL --identity PROJECT/seat \
  --pi-binary ./integrations/pi/node_modules/.bin/pi \
  --pi-directory "$PWD" --pi-extension ./integrations/pi/index.ts \
  --pi-project PROJECT --pi-repository "$PWD" \
  --pi-task-id TASK-ID --pi-epoch EPOCH \
  --pi-hub-uri ws://localhost:8876

For a secured hub, add --pi-token-file with an owner-only file. The extension passes that path to the Synapse hook; it does not put token bytes in the pi command line or its JSONL stream. The token file must be outside the repository, so the pi read and search tools cannot discover it there. read, grep, find and ls are limited to paths whose current physical location is inside the repository; paths through symlinks to outside files are denied. If a claim is released, expired, reissued at a new epoch, or the hub cannot be reached, write and edit fail closed. A denied tool call is reported as an error result. bash is always denied because its effects cannot be bounded by parsing command text. Unknown tools are also denied. The session ID observed by pi must equal the one fixed when the child was launched.

The hook is a cooperative pre-tool check, not an operating-system sandbox. It governs calls through this participant and the loaded extension; it does not take custody of arbitrary child processes, other pi sessions, raw pi RPC clients, or direct filesystem writes. A file claim is checked immediately before each supported mutation, while another process may still change the workspace afterward. Run untrusted models or extensions under an independent OS-enforced sandbox when stronger custody is required.

Pi RPC uses LF-delimited UTF-8 JSON records. A command response acknowledges receipt only; Synapse waits for agent_settled after tool calls, retries and queued follow-ups before returning the participant result. A terminated child, malformed/oversize frame or timeout yields an error, and the owned process group is reaped. Delivery through the hub retains its documented at-least-once provider-effect boundary: a completed replay is deduplicated by the delivery bridge, but an effect interrupted by a process crash needs reconciliation.

See the Participant CLI and delivery contract for the surrounding bus semantics.