pi-proofline
Pi extension that records every agent run as a verifiable proofline bundle: tamper-evident, secret-redacted, replayable evidence of what your coding agent actually did.
Package details
Install pi-proofline from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-proofline- Package
pi-proofline- Version
0.1.0- Published
- Aug 12, 2026
- Downloads
- 139/mo · 14/wk
- Author
- zwxxx
- License
- MIT
- Types
- extension
- Size
- 31.7 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-proofline
Verifiable evidence for every pi agent run.
Every prompt you give pi becomes one JSON bundle: the exact provider payloads pi sent, the assistant messages it received, every tool execution — secrets redacted, sealed under a stable SHA-256 digest. Anyone can verify, diff, or sign the bundle with the proofline CLI. No trust in you, this extension, or pi required.
$ pi "fix the failing test"
...
proofline: recorded .proofline/pi-run-20260812-134502-4c1f09a2.json (digest 59279513ca52)
$ uvx proofline verify .proofline/pi-run-20260812-134502-4c1f09a2.json
OK .proofline/pi-run-20260812-134502-4c1f09a2.json
How it works
pi events capture evidence
┌─────────────────────────────┐ ┌────────────────────┐ ┌───────────────────────────┐
│ before_provider_request ────┼──►│ request payload │ │ .proofline/pi-run-*.json │
│ turn_end ───────────────────┼──►│ assistant message ├──►│ · redacted │
│ tool_execution_start/end ───┼──►│ tool args, results │ │ · digest-sealed │
└─────────────────────────────┘ └────────────────────┘ │ · verifiable offline │
└───────────────────────────┘
One run (prompt → agent settled) produces one bundle. The digest covers the evidence but not volatile fields (run_id, timestamps), so two runs with identical behavior share a digest — which is what makes bundles diffable and regression-testable.
Why
Publish sessions with proof. If you share coding sessions — for example with pi-share-hf — a bundle gives consumers what a session log cannot: tamper detection, machine-checked secret redaction, and an optional Ed25519 signature.
Attribute behavior changes. proofline diff a.json b.json compares runs semantically, ignoring IDs and timestamps. Swap models mid-project and keep evidence of what actually changed.
Audit what the agent did. The bundle records what went over the wire, captured at the provider boundary — not a reconstruction from session state.
Install
pi install git:github.com/Powfu-zwx/pi-proofline
The entire extension is one dependency-free TypeScript file: extensions/proofline.ts (650 lines). Reviewing it before installing takes about ten minutes, and you should.
Use
Recording is automatic. Bundles land in .proofline/ under the project directory.
| Action | How |
|---|---|
| Check status | /proofline |
| Pause / resume | /proofline off · /proofline on |
| Change output directory | set PROOFLINE_DIR (absolute, or relative to the project) |
| Keep bundles out of git | add .proofline/ to .gitignore — or commit them as baselines |
Verify, diff, and sign with the reference CLI — no pi required:
uvx proofline verify .proofline/pi-run-*.json
uvx proofline diff baseline.json current.json
uvx proofline keygen --out signing.key && uvx proofline sign bundle.json --key signing.key
Inside a bundle
Abridged from a real run (spec):
{
"schema_version": "0.1",
"actor": { "type": "human+agent", "name": "admin", "version": "0.1.0" },
"project": { "name": "work", "revision": "4e7018d…", "dirty": null },
"invocation": { "argv": ["node", "…/pi", "-p", "Say hello briefly"], "cwd": "…", "env_keys": ["PATH", "…"] },
"steps": [
{
"step_id": "step-1",
"kind": "model",
"name": "mock/gpt-mock",
"status": "ok",
"input": { "model": "gpt-mock", "messages": ["…exact provider payload…"], "tools": ["…"] },
"output": { "role": "assistant", "content": ["…"], "usage": { "totalTokens": 17, "cost": { "total": 0 } } },
"input_digest": "b08bdb1d…",
"output_digest": "ae31d466…",
"metadata": { "http_status": 200, "turn_index": 0, "stop_reason": "stop" }
}
],
"redactions": ["/steps/0/input/messages/0/content"],
"bundle_digest": "59279513ca52…"
}
Recorded — per model call: the full request payload, the finalized assistant message, usage and cost, HTTP status, stop reason. Per tool execution: name, arguments, result, error status. Per run: git revision and dirty state, working directory, environment variable names, session ID.
Never recorded — HTTP headers (API keys never enter the bundle), environment variable values, anything outside the run.
Redaction — pattern-based and best-effort, matching proofline's rules: secret-looking keys (api_key, token, authorization, …) and secret-looking values (OpenAI/GitHub/AWS/Slack key shapes, JWTs, bearer tokens, PEM headers) become [REDACTED], each listed as a JSON Pointer under redactions. proofline verify re-scans for leaks independently. Treat bundles as sensitive until reviewed, exactly as you would a session log.
Byte-level compatibility
A digest is only useful if an independent verifier recomputes the same bytes. That requires canonical JSON to agree across languages, and the disagreements are where implementations usually die:
- Key order — Python sorts by Unicode code point, JavaScript by UTF-16 unit; they disagree beyond the BMP.
- Float formatting — Python
reprwrites3e-05where JavaScript writes0.00003. - Surrogates — Python's encoder rejects what JavaScript strings happily carry.
This port resolves all three and proves it in CI: several hundred fuzzed vectors plus a complete bundle are generated in TypeScript on every push and verified with the released proofline package from PyPI. The e2e suite does the same against a real pi install.
Limitations
- Auxiliary LLM calls that bypass the turn lifecycle (compaction, summarization) appear as
skippedsteps: request preserved, response not captured. - Aborted turns record whatever was captured before the abort.
proofline replayis not wired up for pi runs; bundles are still verifiable and diffable evidence.
Development
npm install
npm run typecheck
npm test # unit tests — node --test, no build step
npm run emit-vectors # write cross-language fixtures to out/
python tests/cross_verify.py # requires: pip install proofline
End-to-end against a real pi install, no API key needed — run the mock provider, then point an isolated pi at it:
node tests/e2e/mock-provider.mjs &
export PI_CODING_AGENT_DIR=$(mktemp -d) PI_OFFLINE=1
cat > "$PI_CODING_AGENT_DIR/models.json" <<'EOF'
{ "providers": { "mock": { "baseUrl": "http://127.0.0.1:8377/v1", "api": "openai-completions",
"apiKey": "dummy", "compat": { "supportsDeveloperRole": false, "supportsReasoningEffort": false },
"models": [ { "id": "gpt-mock" } ] } } }
EOF
pi -p --no-session --provider mock --model gpt-mock -e ./extensions/proofline.ts "Say hello"
uvx proofline verify .proofline/pi-run-*.json
See also
- proofline — the protocol and reference implementation: verify, diff, replay, sign
- Run bundle spec — format and verification rules
- pi — the coding agent this extends