planr 1.8.0 → 1.10.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -3
- package/docs/RELEASE.md +37 -7
- package/docs/contracts/EVIDENCE_CONTRACT_V1.md +283 -0
- package/docs/contracts/PI_INTEGRATION_V1.md +164 -0
- package/docs/contracts/fixtures/evidence/v1/examples/coverage-verdict.json +66 -0
- package/docs/contracts/fixtures/evidence/v1/examples/evidence-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/examples/evidence-policy.json +117 -0
- package/docs/contracts/fixtures/evidence/v1/examples/evidence-receipt.json +93 -0
- package/docs/contracts/fixtures/evidence/v1/examples/evidence-waiver.json +31 -0
- package/docs/contracts/fixtures/evidence/v1/examples/proof-obligation.json +67 -0
- package/docs/contracts/fixtures/evidence/v1/examples/proof-preset.json +28 -0
- package/docs/contracts/fixtures/evidence/v1/examples/untrusted-evidence-proposal.json +20 -0
- package/docs/contracts/fixtures/evidence/v1/examples/verification-capability-instance.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/examples/verification-capability-manifest.json +52 -0
- package/docs/contracts/fixtures/evidence/v1/negative/aborted-zero-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/adapter-registration-missing-execution-contract.json +97 -0
- package/docs/contracts/fixtures/evidence/v1/negative/available-empty-probe-capability.json +27 -0
- package/docs/contracts/fixtures/evidence/v1/negative/blocked-coverage-with-stale-reason.json +27 -0
- package/docs/contracts/fixtures/evidence/v1/negative/empty-trust-bindings-receipt.json +72 -0
- package/docs/contracts/fixtures/evidence/v1/negative/failed-zero-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/forged-trusted-receipt.json +35 -0
- package/docs/contracts/fixtures/evidence/v1/negative/inconclusive-clean-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/inconclusive-coverage-with-blocked-reason.json +27 -0
- package/docs/contracts/fixtures/evidence/v1/negative/minimal-policy-missing-owned-inputs.json +5 -0
- package/docs/contracts/fixtures/evidence/v1/negative/mismatched-probe-execution-id-capability.json +42 -0
- package/docs/contracts/fixtures/evidence/v1/negative/passed-empty-attempt.json +22 -0
- package/docs/contracts/fixtures/evidence/v1/negative/policy-default-preset-unregistered.json +111 -0
- package/docs/contracts/fixtures/evidence/v1/negative/policy-weakening-without-waiver.json +111 -0
- package/docs/contracts/fixtures/evidence/v1/negative/process-probe-missing-output-limits.json +49 -0
- package/docs/contracts/fixtures/evidence/v1/negative/satisfied-empty-coverage-verdict.json +14 -0
- package/docs/contracts/fixtures/evidence/v1/negative/skipped-zero-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/stale-coverage-with-inconclusive-reason.json +27 -0
- package/docs/contracts/fixtures/evidence/v1/negative/timed-out-zero-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/unavailable-zero-exit-attempt.json +39 -0
- package/docs/contracts/fixtures/evidence/v1/negative/unbound-waiver.json +21 -0
- package/docs/contracts/fixtures/evidence/v1/negative/unsatisfied-coverage-without-gap.json +63 -0
- package/docs/contracts/fixtures/evidence/v1/negative/waived-coverage-forbidden-gap-reason.json +28 -0
- package/docs/contracts/fixtures/evidence/v1/negative/waived-coverage-missing-waiver-id.json +27 -0
- package/docs/contracts/fixtures/evidence/v1/schemas/evidence-contract-v1.schema.json +2705 -0
- package/docs/documentation/COVERAGE.md +10 -6
- package/docs/documentation/INFORMATION_ARCHITECTURE.md +1 -1
- package/docs/fixtures/mcp-contract.json +18 -2
- package/npm/native/darwin-arm64/planr +0 -0
- package/npm/native/darwin-arm64/planr-host-capability-validator +0 -0
- package/npm/native/darwin-x86_64/planr +0 -0
- package/npm/native/darwin-x86_64/planr-host-capability-validator +0 -0
- package/npm/native/linux-arm64/planr +0 -0
- package/npm/native/linux-arm64/planr-host-capability-validator +0 -0
- package/npm/native/linux-x86_64/planr +0 -0
- package/npm/native/linux-x86_64/planr-host-capability-validator +0 -0
- package/package.json +15 -3
- package/plugins/planr/.claude-plugin/plugin.json +1 -1
- package/plugins/planr/.codex-plugin/plugin.json +1 -1
- package/plugins/planr/agents/pi/planr-reviewer.md +16 -0
- package/plugins/planr/agents/pi/planr-worker.md +14 -0
- package/plugins/planr/skills/planr-goal/SKILL.md +4 -2
- package/plugins/planr/skills/planr-loop/SKILL.md +7 -5
- package/plugins/planr/skills/planr-loop/references/host-dispatch.md +1 -0
- package/plugins/planr/skills/planr-review/SKILL.md +5 -1
- package/plugins/planr/skills/planr-verify-web/SKILL.md +3 -1
- package/plugins/planr/skills/planr-work/SKILL.md +12 -1
- package/scripts/host-capability-experiment.mjs +2477 -0
- package/scripts/host-capability-runtime/v1/schemas/host-capability-expected-manifest.schema.json +377 -0
- package/scripts/host-capability-runtime/v1/schemas/host-capability-observed-raw.schema.json +439 -0
- package/scripts/host-capability-runtime/v1/schemas/host-capability-provenance.schema.json +178 -0
- package/scripts/planr-host-capability-validator +51 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
Planr is a local-first planning and execution coordination tool for coding agents. It combines reviewable Markdown plans with a dependency-aware work map so Codex, Claude Code, Cursor, Grok Build, generic MCP clients, and human operators can drive the same work safely — from idea to verified completion.
|
|
5
|
+
Planr is a local-first planning and execution coordination tool for coding agents. It combines reviewable Markdown plans with a dependency-aware work map so Codex, Claude Code, Cursor, Grok Build, Pi, generic MCP clients, and human operators can drive the same work safely — from idea to verified completion.
|
|
6
6
|
|
|
7
7
|
[**View the Demo →**](https://x.com/kevinkern/status/2066957434564808884?s=20)
|
|
8
8
|
|
|
@@ -53,7 +53,7 @@ curl -fsSL https://raw.githubusercontent.com/instructa/planr/main/scripts/instal
|
|
|
53
53
|
> On an affected Linux release, build from source on the target distribution or upgrade to v1.7.3.
|
|
54
54
|
<!-- planr:linux-release-portability:end surface=README schema=1 -->
|
|
55
55
|
|
|
56
|
-
Then initialize a project. When selected, Claude Code and Cursor also receive standalone project worker/reviewer roles; Codex workflow skills come from its plugin. Grok Build
|
|
56
|
+
Then initialize a project. When selected, Claude Code and Cursor also receive standalone project worker/reviewer roles; Codex workflow skills come from its plugin. Grok Build and Pi are separate explicit opt-ins and are not included by `all`:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
59
|
planr project init "My Product" --client all
|
|
@@ -61,6 +61,16 @@ planr project init "My Product" --client all
|
|
|
61
61
|
|
|
62
62
|
Manual downloads, from-source builds, and client wiring details: [Install Guide](https://planr.so/docs/getting-started/installation).
|
|
63
63
|
|
|
64
|
+
To add Pi's native Agent Skills and optional pi-subagents roles to a trusted repository, select it explicitly:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
planr install pi --dry-run
|
|
68
|
+
planr install pi
|
|
69
|
+
planr project init "My Product" --client pi
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Planr writes repository-local `.pi/skills/` workflow assets and optional `.pi/agents/` roles only. It does not install Pi, pi-subagents, MCP config, hooks, global settings, provider credentials, or session state. Full setup and trust guidance: [Pi integration](https://planr.so/docs/integrations/pi).
|
|
73
|
+
|
|
64
74
|
## Install The Plugin (Skills)
|
|
65
75
|
|
|
66
76
|
The plugin under `plugins/planr` carries the ten Planr workflow skills. Optional model-routing declarations live in repository-local files such as `.planr/agents.toml` and `.planr/policy.toml`; external tools may manage those files, but Planr does not install or invoke a routing engine. The `planr` CLI (above) is required separately.
|
|
@@ -123,6 +133,22 @@ Planr writes portable `.grok/config.toml` MCP configuration plus native `.grok/a
|
|
|
123
133
|
|
|
124
134
|
</details>
|
|
125
135
|
|
|
136
|
+
<a id="install-pi"></a>
|
|
137
|
+
<details>
|
|
138
|
+
<summary><strong>Pi</strong></summary>
|
|
139
|
+
|
|
140
|
+
Preview or install the repository-local Pi integration:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
planr install pi --dry-run
|
|
144
|
+
planr install pi
|
|
145
|
+
planr doctor --client pi --json
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Planr writes native `.pi/skills/` workflow assets and optional `.pi/agents/` role files for `pi-subagents`. It writes no MCP configuration, hooks, extension package, global Pi settings, provider credentials, model pin, or session reference. Pi is intentionally explicit opt-in and is not part of `--client all`. See the [Pi integration guide](https://planr.so/docs/integrations/pi).
|
|
149
|
+
|
|
150
|
+
</details>
|
|
151
|
+
|
|
126
152
|
<a id="install-plugin-opencode"></a>
|
|
127
153
|
<details>
|
|
128
154
|
<summary><strong>opencode</strong></summary>
|
|
@@ -200,6 +226,7 @@ The watcher is likewise a human-only observer. It defaults to the condensed diag
|
|
|
200
226
|
|
|
201
227
|
## What's new
|
|
202
228
|
|
|
229
|
+
- **1.9.0 — First-class Pi integration:** Added an explicit repository opt-in that installs native Pi Agent Skills plus optional `pi-subagents` worker/reviewer roles without treating Pi as an MCP host. The integration writes no Pi global settings, hooks, provider credentials, model pin, or session reference, and `--client all` remains unchanged for existing Codex, Claude Code, Cursor, and Grok setup. See the [Pi integration guide](https://planr.so/docs/integrations/pi), [Pi contract](docs/contracts/PI_INTEGRATION_V1.md), and [1.9.0 changelog](CHANGELOG.md#190---2026-07-27).
|
|
203
230
|
- **1.8.0 — First-class Grok Build integration:** Added an explicit repository opt-in that installs portable project MCP configuration plus native Grok agents and all ten Planr workflow skills. The integration writes no plugin, hooks, model setting, xAI credentials, or provider runtime dependency; authenticated verification remains maintainer-local and never runs in CI. See the [Grok Build guide](https://planr.so/docs/integrations/grok-build) and [1.8.0 changelog](CHANGELOG.md#180---2026-07-27).
|
|
204
231
|
- **1.7.2 — Reproducible release candidates:** Locked the pnpm workspace inventory, made external eval fixtures self-contained, refreshed reviewed workflow runtimes, and made all four published architectures execute the exact tagged version before upload. Model-backed evaluation remains a local, candidate-bound maintainer gate; this patch makes no unmeasured speed or quality claim. See the [1.7.2 changelog](CHANGELOG.md#172---2026-07-25) and [release guidance](https://planr.so/docs/operations/release).
|
|
205
232
|
- **1.7.1 — Leaner agent guidance and safer local releases:** Slimmed the hot-path Planr skills while preserving their execution and review contracts, moved maintainer benchmark inputs and results outside the public repository, added a fail-closed local release-evidence gate without API keys in CI, and verified the optional external Switchloom v0.3.2 integration. The public 1.7 eval CLI remains available in this patch. See the [1.7.1 changelog](CHANGELOG.md#171---2026-07-25) and [release guidance](https://planr.so/docs/operations/release).
|
|
@@ -220,7 +247,7 @@ Full documentation lives at [planr.so/docs](https://planr.so/docs).
|
|
|
220
247
|
- [Plugins and Model Routing](https://planr.so/docs/plugins) · [Recipes](https://planr.so/docs/guides/recipes)
|
|
221
248
|
- [Integrations and Host Hooks](https://planr.so/docs/integrations)
|
|
222
249
|
- [CLI Reference](https://planr.so/docs/reference/cli) · [MCP Reference](https://planr.so/docs/reference/mcp)
|
|
223
|
-
- [Codex](https://planr.so/docs/integrations/codex) · [Claude Code](https://planr.so/docs/integrations/claude-code) · [Cursor](https://planr.so/docs/integrations/cursor) · [Grok Build](https://planr.so/docs/integrations/grok-build)
|
|
250
|
+
- [Codex](https://planr.so/docs/integrations/codex) · [Claude Code](https://planr.so/docs/integrations/claude-code) · [Cursor](https://planr.so/docs/integrations/cursor) · [Grok Build](https://planr.so/docs/integrations/grok-build) · [Pi](https://planr.so/docs/integrations/pi)
|
|
224
251
|
- [Daily Worker Loop](https://planr.so/docs/guides/daily-worker-loop)
|
|
225
252
|
- [Task Graph Model](https://planr.so/docs/concepts/graph-and-readiness)
|
|
226
253
|
- [Architecture](https://planr.so/docs/contributing/architecture)
|
package/docs/RELEASE.md
CHANGED
|
@@ -24,25 +24,44 @@ full candidate verification and independent review on that exact commit.
|
|
|
24
24
|
|
|
25
25
|
`scripts/release.sh` is the only supported publication path. It runs on clean
|
|
26
26
|
`main`, requires every version and generated reference to already match the
|
|
27
|
-
requested version,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
requested version, verifies an independently green CI run and human approval
|
|
28
|
+
for the exact `HEAD` SHA, and only then creates and pushes the annotated tag.
|
|
29
|
+
It does not replay the Rust, docs, or packaging suites already proven by that
|
|
30
|
+
CI run. Security, secret, dependency, and workflow scanners are deliberate
|
|
31
|
+
local maintainer preflight commands rather than automatic pull-request or push
|
|
32
|
+
CI evidence. Editing manifests by hand or publishing an unprepared commit skips
|
|
33
|
+
this ownership boundary.
|
|
31
34
|
|
|
32
35
|
```bash
|
|
33
36
|
scripts/prepare-release-candidate.sh 1.2.0
|
|
34
37
|
```
|
|
35
38
|
|
|
39
|
+
```bash
|
|
40
|
+
export PLANR_RELEASE_CI_RECEIPT=/path/to/downloaded/promotion-receipt.json
|
|
41
|
+
export PLANR_RELEASE_APPROVAL=/path/to/exact-sha-release-approval.json
|
|
42
|
+
scripts/release.sh 1.2.0 "one-line release summary"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Download `release-promotion-<sha>` from the successful `CI` run for the exact
|
|
46
|
+
main commit. The approval file uses schema `planr.release-approval.v1` and
|
|
47
|
+
contains only `approval_id`, `source_sha`, `version`, `decision: "approved"`,
|
|
48
|
+
`approved_by`, and `approved_at` in addition to `schema_version`. Publication
|
|
49
|
+
queries the recorded GitHub Actions run and rejects a stale SHA, non-main or
|
|
50
|
+
non-push run, failed conclusion, repository mismatch, or non-approved decision.
|
|
51
|
+
|
|
52
|
+
External evaluation is conditional. When the evaluated workflow subject or its
|
|
53
|
+
explicit evaluation policy changed since the previous release tag, also set:
|
|
54
|
+
|
|
36
55
|
```bash
|
|
37
56
|
export PLANR_RELEASE_EVAL_SUITE="$HOME/projects/planr-evals/suites/planr-lean-skills-dogfood.suite.json"
|
|
38
57
|
export PLANR_RELEASE_EVAL_RECEIPT=/path/to/sanitized-release-eval-receipt.json
|
|
39
58
|
export PLANR_RELEASE_EVAL_DB=/path/to/planr-evals/results/eval.sqlite
|
|
40
|
-
|
|
59
|
+
export PLANR_RELEASE_PLANR_BIN=/path/to/reviewed/candidate/planr
|
|
41
60
|
```
|
|
42
61
|
|
|
43
62
|
Maintainer benchmarks, baselines, model/effort runs, and results live outside
|
|
44
63
|
the public repository in `~/projects/planr-evals`; that workspace and its exact
|
|
45
|
-
layout are not a Planr runtime contract. All
|
|
64
|
+
layout are not a Planr runtime contract. All external evaluation paths above are explicit so a
|
|
46
65
|
release cannot silently use the product repository's ordinary `.planr` database
|
|
47
66
|
or a stale bundled suite. The receipt is a short-lived local pointer containing
|
|
48
67
|
only `schema_version`, comparison and candidate-run identities, suite and
|
|
@@ -76,7 +95,7 @@ The two scripts enforce, in order:
|
|
|
76
95
|
4. the candidate build synchronizes `Cargo.lock`, then regenerates and strictly checks both references without Git mutation;
|
|
77
96
|
5. candidate source, changelog, contracts, and generated files are committed and independently reviewed before publication approval;
|
|
78
97
|
6. publication requires clean `main`, the exact prepared versions/references, a committed changelog section, and no existing tag;
|
|
79
|
-
7. the
|
|
98
|
+
7. publication validates the exact-SHA CI and approval receipts; when the evaluated subject or policy changed, the reviewed candidate binary also validates the sanitized eval receipt and recomputed comparison;
|
|
80
99
|
8. publication creates and pushes only the annotated `vx.y.z` tag for that reviewed commit.
|
|
81
100
|
|
|
82
101
|
Two independent gates back the script:
|
|
@@ -145,6 +164,11 @@ scripts/ci-local.sh
|
|
|
145
164
|
scripts/security-local.sh
|
|
146
165
|
```
|
|
147
166
|
|
|
167
|
+
`scripts/security-local.sh`, `cargo audit --deny warnings`, and local
|
|
168
|
+
`zizmor .` are on-demand maintainer checks. Pull-request and push workflows do
|
|
169
|
+
not install or execute BetterLeaks, Trivy, TruffleHog, cargo-audit, zizmor, or
|
|
170
|
+
equivalent dependency/security scanners.
|
|
171
|
+
|
|
148
172
|
The external consumer E2E suite must pass when available on the release machine.
|
|
149
173
|
Pull-request CI separately builds both Linux architectures through the canonical
|
|
150
174
|
containerized release script, runs the full portability contract without
|
|
@@ -164,6 +188,9 @@ cat dist/planr-*/SHA256SUMS
|
|
|
164
188
|
The artifact contains:
|
|
165
189
|
|
|
166
190
|
- `planr`
|
|
191
|
+
- `scripts/host-capability-experiment.mjs`
|
|
192
|
+
- `scripts/host-capability-runtime/v1/schemas/*.schema.json`
|
|
193
|
+
- `scripts/planr-host-capability-validator`
|
|
167
194
|
- `README.md`
|
|
168
195
|
- `LICENSE.md`
|
|
169
196
|
- `SHA256SUMS`
|
|
@@ -187,6 +214,9 @@ npm pack --dry-run
|
|
|
187
214
|
The package must include:
|
|
188
215
|
|
|
189
216
|
- `npm/bin/planr.js`
|
|
217
|
+
- `scripts/host-capability-experiment.mjs`
|
|
218
|
+
- `scripts/host-capability-runtime/v1/schemas/*.schema.json`
|
|
219
|
+
- `scripts/planr-host-capability-validator`
|
|
190
220
|
- `docs/`
|
|
191
221
|
- `docs/fixtures/mcp-contract.json`
|
|
192
222
|
- `plugins/`
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# Evidence Contract v1
|
|
2
|
+
|
|
3
|
+
Status: frozen for implementation
|
|
4
|
+
|
|
5
|
+
Evidence Contract v1 is Planr's local-first contract for proving acceptance criteria. It defines the durable vocabulary for proof obligations, observation requirements, capability declarations, execution attempts, untrusted proposals, trusted receipts, coverage verdicts, policy, presets, waivers, statuses, compatibility, and extension naming. It does not add public commands by itself and does not grant closure authority until later implementation slices wire the contract into storage, audit, review, trace, pick, and active-goal enforcement.
|
|
6
|
+
|
|
7
|
+
## Ownership
|
|
8
|
+
|
|
9
|
+
- Product and build plans own authored acceptance criteria and the reviewed `ProofObligation` records bound to those criteria.
|
|
10
|
+
- The Evidence domain owns `ProofObligation`, `ObservationRequirement`, `VerificationCapabilityManifest`, `VerificationCapabilityInstance`, `EvidenceAttempt`, `UntrustedEvidenceProposal`, `EvidenceReceipt`, `CoverageVerdict`, `EvidencePolicy`, `ProofPreset`, and `EvidenceWaiver`.
|
|
11
|
+
- Planr assigns trusted provenance only from Planr-observed execution, verified host events, accepted MCP attestation, validated artifact import, or explicit approval-backed user attestation.
|
|
12
|
+
- Public JSON, agent-authored JSON, adapter stdout, logs, and artifacts may propose claims, but they cannot construct trusted provenance, execution identity, freshness, target binding, receipt digest, or closure authority.
|
|
13
|
+
- `src/canonical_json.rs` is the future single production owner for RFC 8785/JCS-compatible canonical bytes and SHA-256 digests used by this contract.
|
|
14
|
+
- `src/execution.rs` is the future shared owner for bounded process execution, cancellation, process-tree cleanup, output limits, and stdout/stderr digests.
|
|
15
|
+
- CLI, MCP, HTTP, docs, audit, hooks, review, trace, and pick surfaces are renderers or consumers. They must use the same Evidence application service and cannot implement alternate coverage decisions.
|
|
16
|
+
|
|
17
|
+
## Existing-System Boundaries
|
|
18
|
+
|
|
19
|
+
- Eval remains the owner of comparative candidate evaluation, immutable eval runs, case results, samples, comparisons, invalidations, and eval evidence references. Eval evidence keeps `closure_authority = false`; an eval verdict may support review but cannot close or reopen Planr work by itself.
|
|
20
|
+
- Route Audit remains the owner of requested, resolved, and effective routing evidence. Evidence may consume a mapped provenance view, but it must not copy requested route declarations into effective execution proof.
|
|
21
|
+
- Agent Profiles, model-routing capability classes, usage-policy capability classes, MCP protocol capabilities, and context tags are dispatch or protocol metadata. They are not verification capability instances and do not prove runtime availability.
|
|
22
|
+
- Planr logs remain narrative and supporting records. A legacy `kind = verification` log is preserved as a claim and can be referenced, but it never automatically satisfies a binding observation.
|
|
23
|
+
- Pre-Evidence plans and non-binding scopes keep their historical closure compatibility until an operator explicitly migrates a plan into binding Evidence. Migration is plan-scoped, previewable, idempotent, and materializes ordinary immutable `ProofObligation` rows; it must not rewrite plans, logs, reviews, artifacts, or historical claims.
|
|
24
|
+
- Planr artifacts remain files or references with digests. An artifact alone is not trusted evidence unless a trusted receipt binds it to the source revision, target, environment, execution identity, observation results, and policy.
|
|
25
|
+
|
|
26
|
+
## Versioning And Compatibility
|
|
27
|
+
|
|
28
|
+
- `schema_version` for all v1 objects is `evidence.contract.v1`.
|
|
29
|
+
- Additive optional fields are allowed only when old readers can ignore them without changing coverage, trust, freshness, or closure decisions.
|
|
30
|
+
- Status enum values, failure reason codes, provenance source kinds, namespace rules, digest algorithms, and trusted/untrusted boundaries are frozen for v1.
|
|
31
|
+
- Removing fields, renaming statuses, weakening required trust checks, changing digest semantics, or treating legacy logs as binding proof requires a new major contract.
|
|
32
|
+
- Unknown object kinds, observation types, schema versions, status values, provenance kinds, or namespaces are invalid for trusted coverage unless an explicit project extension registers them.
|
|
33
|
+
- Canonical JSON bytes and digests are computed over the object without non-contractual display fields. The frozen schema fixture in `docs/contracts/fixtures/evidence/v1/schemas/evidence-contract-v1.schema.json` names each object's required fields.
|
|
34
|
+
|
|
35
|
+
## Contract Digests
|
|
36
|
+
|
|
37
|
+
Digest preimages use RFC 8785/JCS canonical JSON bytes over the contract object after the digest field being produced is removed. No other contract field is implicitly excluded.
|
|
38
|
+
|
|
39
|
+
- `EvidenceReceipt.receipt_digest`: hash the complete receipt object without the top-level `receipt_digest` field. Source, target, environment, capability, provenance, execution identity, observations, attempts, artifacts, raw result, config digest, fixture disclosure, permissions, sandbox, proof gaps, and timings all remain in the preimage.
|
|
40
|
+
- `EvidencePolicy.policy_digest`: hash the complete policy object without the top-level `policy_digest` field. Defaults, presets, observation schema registrations, adapter registrations, extension namespaces, trust/freshness/fixture/completion/layering policy all remain in the preimage. Nested `PolicyLayer.policy_digest` values are included as references to already-materialized lower-layer policies and must not repeat the enclosing policy digest.
|
|
41
|
+
|
|
42
|
+
The canonical fixture vectors are executable through `node scripts/verify-evidence-contract-vectors.mjs`.
|
|
43
|
+
|
|
44
|
+
## Namespaces And Extensions
|
|
45
|
+
|
|
46
|
+
Built-in observation types and proof presets are starter vocabulary only. They are conveniences for common API, process, browser, desktop, mobile, deployment, filesystem, database, queue, and artifact cases, not a closed enum.
|
|
47
|
+
|
|
48
|
+
Observation type names and preset names use one of these namespaces:
|
|
49
|
+
|
|
50
|
+
- `planr.*`: reserved for Planr-owned built-ins.
|
|
51
|
+
- `mcp.*`: reserved for MCP attestation vocabulary that Planr validates.
|
|
52
|
+
- `host.*`: reserved for verified host-native capture contracts.
|
|
53
|
+
- Reverse-domain namespaces such as `com.example.queue.job.processed`.
|
|
54
|
+
- Project-local namespaces such as `project.queue.job.processed` inside the repository that defines them.
|
|
55
|
+
|
|
56
|
+
Custom observation types must reference a versioned JSON Schema and a registration digest in repository-local Evidence policy. Unknown, unregistered, or unavailable custom types remain uncovered and cannot be silently accepted as a weaker built-in.
|
|
57
|
+
|
|
58
|
+
## Object Model
|
|
59
|
+
|
|
60
|
+
### ProofObligation
|
|
61
|
+
|
|
62
|
+
A reviewed, binding or advisory contract for one acceptance criterion.
|
|
63
|
+
|
|
64
|
+
Required fields:
|
|
65
|
+
|
|
66
|
+
- `id`, `schema_version`, `criterion_id`, `plan_id`, optional `item_id`.
|
|
67
|
+
- `title`, `binding`, `observations`, `fixture_policy`, `freshness_policy`, `assurance_policy`.
|
|
68
|
+
- `policy_digest`, `config_digest`, `created_at`, and optional `supersedes`.
|
|
69
|
+
|
|
70
|
+
`binding = true` means closure must evaluate Evidence coverage. `binding = false` may be rendered as guidance but cannot block or satisfy closure.
|
|
71
|
+
|
|
72
|
+
### ObservationRequirement
|
|
73
|
+
|
|
74
|
+
One atomic fact that must be observed.
|
|
75
|
+
|
|
76
|
+
Required fields:
|
|
77
|
+
|
|
78
|
+
- `id`, namespaced `type`, `subject`, `expected`, `target`, `environment`, `runtime_target`.
|
|
79
|
+
- Optional `payload_schema`, `state_transitions`, `persistence`, `negative_assertions`, `freshness_policy`, and `assurance_policy`.
|
|
80
|
+
|
|
81
|
+
The `type` says what fact is being observed, not which tool must observe it. Tool preference belongs in policy.
|
|
82
|
+
|
|
83
|
+
### VerificationCapabilityManifest
|
|
84
|
+
|
|
85
|
+
A versioned static declaration from an adapter, host, or attestor.
|
|
86
|
+
|
|
87
|
+
Required fields:
|
|
88
|
+
|
|
89
|
+
- `id`, `schema_version`, `version`, `adapter_kind`, `adapter_digest`.
|
|
90
|
+
- Supported surfaces, observation type/schema/digest triples, interactions, artifacts, runtime targets, provenance path, permissions, costs, determinism, repeatability, independence, blind spots, and availability probe contract.
|
|
91
|
+
- Process adapters declare a closed `availability_probe.kind = process` contract with executable name, arguments, optional working directory, timeout, stdout/stderr byte limits, and the payload schema binding for emitted observations.
|
|
92
|
+
|
|
93
|
+
A manifest is a claim about what a method can observe. It is not proof that the method is available now.
|
|
94
|
+
|
|
95
|
+
### VerificationCapabilityInstance
|
|
96
|
+
|
|
97
|
+
A runtime availability snapshot for one exact manifest, host, surface, version, environment, and permission set.
|
|
98
|
+
|
|
99
|
+
Required fields:
|
|
100
|
+
|
|
101
|
+
- `id`, `schema_version`, `manifest_id`, `manifest_digest`, `host`, `surface`, `host_version`, `adapter_version`, `environment`, `permissions`, `availability`, `probe_result`, `observed_payload_contract`, `limitations`, `captured_at`.
|
|
102
|
+
|
|
103
|
+
`probe_result.probe_execution_id` is the single authoritative runtime probe execution identity for a capability instance. A separate top-level probe execution ID is not part of the contract.
|
|
104
|
+
|
|
105
|
+
Instances expire or become stale when manifest, host, environment, permission, schema, or policy inputs change.
|
|
106
|
+
|
|
107
|
+
### EvidenceAttempt
|
|
108
|
+
|
|
109
|
+
An immutable record of each verification attempt.
|
|
110
|
+
|
|
111
|
+
Required fields:
|
|
112
|
+
|
|
113
|
+
- `id`, `schema_version`, `criterion_id`, `obligation_id`, `capability_instance_id`.
|
|
114
|
+
- `started_at`, `ended_at`, `status`, resolved command or tool call, exit/signal/error details, retry lineage, stdout/stderr digests, raw result reference, artifact references, and output bounds.
|
|
115
|
+
|
|
116
|
+
Attempts are durable whether they pass, fail, time out, abort, skip, become unavailable, or end inconclusively. A later passing attempt does not erase earlier failures.
|
|
117
|
+
|
|
118
|
+
Attempt status and execution result must agree: `passed` requires clean exit code `0`; `failed` requires a non-zero exit code; `timed_out`, `skipped`, and `unavailable` require no exit code or signal and the matching error value; `aborted` requires no exit code plus an abort signal and error; `inconclusive` requires a completed exit with an inconclusive error marker.
|
|
119
|
+
|
|
120
|
+
### UntrustedEvidenceProposal
|
|
121
|
+
|
|
122
|
+
Adapter, host, import, or agent input before Planr assigns provenance.
|
|
123
|
+
|
|
124
|
+
Required fields:
|
|
125
|
+
|
|
126
|
+
- `id`, `schema_version`, `source_kind`, `submitted_at`, `claims`, `artifact_refs`, `producer_metadata`.
|
|
127
|
+
|
|
128
|
+
Forbidden authoritative fields:
|
|
129
|
+
|
|
130
|
+
- Trusted provenance, execution identity, source revision binding, target digest binding, environment identity, freshness result, policy result, coverage result, receipt digest, or closure authority.
|
|
131
|
+
|
|
132
|
+
### EvidenceReceipt
|
|
133
|
+
|
|
134
|
+
The trusted outer envelope created only by Planr or an accepted attestation verifier after validation.
|
|
135
|
+
|
|
136
|
+
Required fields:
|
|
137
|
+
|
|
138
|
+
- `id`, `schema_version`, `criterion_id`, `obligation_id`, `receipt_status`.
|
|
139
|
+
- Source revision/tree state, target digest/URI/deployment ID, environment identity, vantage point.
|
|
140
|
+
- Capability manifest and instance digests, Planr-assigned provenance, execution/tool-call ID.
|
|
141
|
+
- Observation results, attempt IDs and retry history, artifact references and digests.
|
|
142
|
+
- Fixture/mock disclosure, permission and sandbox state, proof gaps, started/ended timestamps, and `receipt_digest`.
|
|
143
|
+
|
|
144
|
+
Receipts can satisfy coverage only when trusted, fresh, policy-compliant, target-matched, schema-valid, and observation-equivalent to the requirement.
|
|
145
|
+
|
|
146
|
+
### CoverageVerdict
|
|
147
|
+
|
|
148
|
+
The canonical coverage result for a criterion, item, plan, or goal.
|
|
149
|
+
|
|
150
|
+
Required fields:
|
|
151
|
+
|
|
152
|
+
- `id`, `schema_version`, `scope`, `evaluated_at`, `status`, `observation_coverage`, `validation_details`, `suggested_next_action`, `actionable_now`.
|
|
153
|
+
|
|
154
|
+
Allowed statuses:
|
|
155
|
+
|
|
156
|
+
- `satisfied`: every binding observation is covered by trusted, fresh, policy-compliant receipts.
|
|
157
|
+
- `unsatisfied`: one or more observations lack sufficient proof and a product or test failure is indicated.
|
|
158
|
+
- `blocked`: proof cannot currently be produced because a required capability, permission, sandbox, environment, or dependency is unavailable.
|
|
159
|
+
- `inconclusive`: attempted evidence cannot decide the required observation.
|
|
160
|
+
- `waived`: every remaining binding gap is covered by a valid scoped waiver.
|
|
161
|
+
- `stale`: previously sufficient evidence was invalidated by source, target, environment, policy, adapter, schema, configuration, or freshness change.
|
|
162
|
+
|
|
163
|
+
Gap coverage must match the verdict status:
|
|
164
|
+
|
|
165
|
+
- `unsatisfied` uses `missing` or `unsatisfied` gap entries with missing/product/verifier/policy/trust/schema/fixture/waiver/unsupported-observation reasons.
|
|
166
|
+
- `blocked` uses `blocked` gap entries with capability, permission, sandbox, environment, dependency, or runtime-target reasons.
|
|
167
|
+
- `inconclusive` uses `inconclusive` gap entries with timeout, abort, inconclusive-result, or verifier-failed reasons.
|
|
168
|
+
- `waived` uses `waived` gap entries, requires `waiver_id`, and records the underlying waived reason rather than `waiver_missing` or `waiver_expired`.
|
|
169
|
+
- `stale` uses `stale` gap entries with stale source, target, environment, policy, adapter schema, or configuration reasons.
|
|
170
|
+
|
|
171
|
+
### EvidencePolicy, ProofPreset, EvidenceWaiver
|
|
172
|
+
|
|
173
|
+
Repository policy lives in `.planr/evidence.yaml`. It owns defaults, named presets, observation schema registrations, adapter registrations, trust/freshness/fixture/completion policy, and extension namespaces.
|
|
174
|
+
|
|
175
|
+
Adapter registrations bind the manifest ID, repository-local manifest path, manifest digest, observation types, payload schema bindings, provenance path, and closed execution contract used by Planr-observed process adapters.
|
|
176
|
+
|
|
177
|
+
Policy layer scope uses the frozen `EvidenceScope` chain. Repository policy defaults and extension declarations are document-level policy. Product-level policy is represented by `goal`, plan-level policy by `plan`, item-specific branches by `item`, and criterion-level policy by `criterion`.
|
|
178
|
+
|
|
179
|
+
Policy layers may strengthen lower-level requirements. Weakening requires an explicit waiver. Waivers include identity, reason, scope, exact observation IDs, source/target binding, created-at, expires-at, approval reference, and audit trail.
|
|
180
|
+
|
|
181
|
+
## Status And Failure Vocabularies
|
|
182
|
+
|
|
183
|
+
`EvidenceAttempt.status` values:
|
|
184
|
+
|
|
185
|
+
- `passed`, `failed`, `skipped`, `timed_out`, `aborted`, `unavailable`, `inconclusive`.
|
|
186
|
+
|
|
187
|
+
`EvidenceReceipt.receipt_status` values:
|
|
188
|
+
|
|
189
|
+
- `trusted`, `rejected`, `untrusted`, `stale`, `superseded`.
|
|
190
|
+
|
|
191
|
+
`VerificationCapabilityInstance.availability.status` values:
|
|
192
|
+
|
|
193
|
+
- `available`, `unavailable`, `degraded`, `permission_denied`, `sandbox_blocked`, `unsupported`, `probe_failed`.
|
|
194
|
+
|
|
195
|
+
Coverage gap/failure reason codes:
|
|
196
|
+
|
|
197
|
+
- `missing_observation`, `missing_capability`, `permission_denied`, `sandbox_blocked`, `environment_unavailable`, `external_dependency_unavailable`, `product_failed`, `verifier_failed`, `timed_out`, `aborted`, `inconclusive_result`, `stale_source`, `stale_target`, `stale_environment`, `stale_policy`, `stale_adapter_schema`, `stale_configuration`, `target_mismatch`, `schema_mismatch`, `manifest_mismatch`, `untrusted_provenance`, `fixture_disallowed`, `mock_disallowed`, `insufficient_assurance`, `waiver_missing`, `waiver_expired`, `unknown_observation_type`, `unsupported_runtime_target`.
|
|
198
|
+
|
|
199
|
+
Legacy/operator aliases are rendered as aliases only and resolve to the canonical codes above: `capability_unavailable` -> `missing_capability`, `dependency_unavailable` -> `external_dependency_unavailable`, `policy_failed` -> `stale_policy`, `trust_failed` -> `untrusted_provenance`, and `stale_evidence` -> `stale_source`. Unknown legacy reasons are classified as `verifier_failed` rather than `product_failed`.
|
|
200
|
+
|
|
201
|
+
Explicit pre-Evidence migration input uses `schema_version = "planr.evidence.migration.v1"`, a single `plan_id`, and an `obligations[]` array of full `ProofObligation` objects whose `plan_id` matches the migration plan and whose `binding` is `true`. Preview is non-mutating. Apply is atomic for the migration payload: any conflict or malformed obligation leaves the plan with no newly bound partial obligations. Reapplying an identical payload is `unchanged`.
|
|
202
|
+
|
|
203
|
+
Process adapters may report a host boundary failure only with an exact single-field JSON line on stdout or stderr:
|
|
204
|
+
|
|
205
|
+
- `{"planr_adapter_boundary":"permission_denied"}`
|
|
206
|
+
- `{"planr_adapter_boundary":"sandbox_blocked"}`
|
|
207
|
+
|
|
208
|
+
Planr treats those structured lines as adapter boundary signals for failed process attempts and capability probes. Numeric exit codes alone do not imply `sandbox_blocked`; shell exit code 126 remains permission denied.
|
|
209
|
+
|
|
210
|
+
## Trust And Provenance Rules
|
|
211
|
+
|
|
212
|
+
- Public deserialization always produces an `UntrustedEvidenceProposal` or authored policy object, never a trusted receipt.
|
|
213
|
+
- Adapter output can report observed facts and artifact references, but Planr binds the actual source revision, target, environment, execution identity, timings, retries, sandbox, permissions, output bounds, and receipt digest.
|
|
214
|
+
- Requested route metadata, declared agent profile metadata, and model names are not effective execution proof.
|
|
215
|
+
- A user approval can attest a fact only through the waiver or user-attestation path, with identity, reason, scope, expiry where applicable, and audit trail. It cannot silently convert agent JSON into Planr-observed execution.
|
|
216
|
+
- Artifacts referenced by trusted receipts require content digests and repository/root containment or explicit external URI policy.
|
|
217
|
+
- Fixture and mock use must be disclosed and accepted by policy for the exact observation.
|
|
218
|
+
|
|
219
|
+
## Canonical Fixtures
|
|
220
|
+
|
|
221
|
+
The v1 frozen fixtures are:
|
|
222
|
+
|
|
223
|
+
- `docs/contracts/fixtures/evidence/v1/schemas/evidence-contract-v1.schema.json`
|
|
224
|
+
- `docs/contracts/fixtures/evidence/v1/examples/proof-obligation.json`
|
|
225
|
+
- `docs/contracts/fixtures/evidence/v1/examples/verification-capability-manifest.json`
|
|
226
|
+
- `docs/contracts/fixtures/evidence/v1/examples/verification-capability-instance.json`
|
|
227
|
+
- `docs/contracts/fixtures/evidence/v1/examples/evidence-attempt.json`
|
|
228
|
+
- `docs/contracts/fixtures/evidence/v1/examples/untrusted-evidence-proposal.json`
|
|
229
|
+
- `docs/contracts/fixtures/evidence/v1/examples/evidence-receipt.json`
|
|
230
|
+
- `docs/contracts/fixtures/evidence/v1/examples/coverage-verdict.json`
|
|
231
|
+
- `docs/contracts/fixtures/evidence/v1/examples/evidence-policy.json`
|
|
232
|
+
- `docs/contracts/fixtures/evidence/v1/examples/proof-preset.json`
|
|
233
|
+
- `docs/contracts/fixtures/evidence/v1/examples/evidence-waiver.json`
|
|
234
|
+
- `docs/contracts/fixtures/evidence/v1/negative/available-empty-probe-capability.json`
|
|
235
|
+
- `docs/contracts/fixtures/evidence/v1/negative/mismatched-probe-execution-id-capability.json`
|
|
236
|
+
- `docs/contracts/fixtures/evidence/v1/negative/empty-trust-bindings-receipt.json`
|
|
237
|
+
- `docs/contracts/fixtures/evidence/v1/negative/failed-zero-exit-attempt.json`
|
|
238
|
+
- `docs/contracts/fixtures/evidence/v1/negative/forged-trusted-receipt.json`
|
|
239
|
+
- `docs/contracts/fixtures/evidence/v1/negative/timed-out-zero-exit-attempt.json`
|
|
240
|
+
- `docs/contracts/fixtures/evidence/v1/negative/aborted-zero-exit-attempt.json`
|
|
241
|
+
- `docs/contracts/fixtures/evidence/v1/negative/skipped-zero-exit-attempt.json`
|
|
242
|
+
- `docs/contracts/fixtures/evidence/v1/negative/unavailable-zero-exit-attempt.json`
|
|
243
|
+
- `docs/contracts/fixtures/evidence/v1/negative/inconclusive-clean-exit-attempt.json`
|
|
244
|
+
- `docs/contracts/fixtures/evidence/v1/negative/passed-empty-attempt.json`
|
|
245
|
+
- `docs/contracts/fixtures/evidence/v1/negative/unbound-waiver.json`
|
|
246
|
+
- `docs/contracts/fixtures/evidence/v1/negative/minimal-policy-missing-owned-inputs.json`
|
|
247
|
+
- `docs/contracts/fixtures/evidence/v1/negative/policy-default-preset-unregistered.json`
|
|
248
|
+
- `docs/contracts/fixtures/evidence/v1/negative/policy-weakening-without-waiver.json`
|
|
249
|
+
- `docs/contracts/fixtures/evidence/v1/negative/satisfied-empty-coverage-verdict.json`
|
|
250
|
+
- `docs/contracts/fixtures/evidence/v1/negative/unsatisfied-coverage-without-gap.json`
|
|
251
|
+
- `docs/contracts/fixtures/evidence/v1/negative/process-probe-missing-output-limits.json`
|
|
252
|
+
- `docs/contracts/fixtures/evidence/v1/negative/adapter-registration-missing-execution-contract.json`
|
|
253
|
+
- `docs/contracts/fixtures/evidence/v1/negative/waived-coverage-missing-waiver-id.json`
|
|
254
|
+
- `docs/contracts/fixtures/evidence/v1/negative/waived-coverage-forbidden-gap-reason.json`
|
|
255
|
+
- `docs/contracts/fixtures/evidence/v1/negative/blocked-coverage-with-stale-reason.json`
|
|
256
|
+
- `docs/contracts/fixtures/evidence/v1/negative/inconclusive-coverage-with-blocked-reason.json`
|
|
257
|
+
- `docs/contracts/fixtures/evidence/v1/negative/stale-coverage-with-inconclusive-reason.json`
|
|
258
|
+
|
|
259
|
+
Replayable schema validation:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
set -e
|
|
263
|
+
schema='docs/contracts/fixtures/evidence/v1/schemas/evidence-contract-v1.schema.json'
|
|
264
|
+
node scripts/verify-evidence-contract-vectors.mjs
|
|
265
|
+
npx --yes ajv-cli@5.0.0 validate --spec=draft2020 --validate-formats=false -s "$schema" -d 'docs/contracts/fixtures/evidence/v1/examples/*.json'
|
|
266
|
+
for fixture in docs/contracts/fixtures/evidence/v1/negative/*.json; do
|
|
267
|
+
case "$fixture" in
|
|
268
|
+
*policy-default-preset-unregistered.json)
|
|
269
|
+
npx --yes ajv-cli@5.0.0 validate --spec=draft2020 --validate-formats=false -s "$schema" -d "$fixture"
|
|
270
|
+
echo "$fixture accepted by schema for semantic validation"
|
|
271
|
+
continue
|
|
272
|
+
;;
|
|
273
|
+
esac
|
|
274
|
+
if npx --yes ajv-cli@5.0.0 validate --spec=draft2020 --validate-formats=false -s "$schema" -d "$fixture" >/tmp/planr-evidence-negative.out 2>&1; then
|
|
275
|
+
cat /tmp/planr-evidence-negative.out
|
|
276
|
+
echo "unexpected valid negative fixture: $fixture" >&2
|
|
277
|
+
exit 1
|
|
278
|
+
fi
|
|
279
|
+
echo "$fixture rejected as expected"
|
|
280
|
+
done
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Later implementation slices must use these fixtures as no-drift inputs for production canonicalization, schema validation, and coverage behavior.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Pi Integration Contract v1
|
|
2
|
+
|
|
3
|
+
Status: frozen for implementation
|
|
4
|
+
|
|
5
|
+
Frozen: 2026-07-27
|
|
6
|
+
|
|
7
|
+
Upstream source probes:
|
|
8
|
+
|
|
9
|
+
- `earendil-works/pi` `main` commit
|
|
10
|
+
`a597371bda2af70372d1323d550483b5f4a0ae36` (2026-07-27).
|
|
11
|
+
- Pi release `v0.82.1` commit
|
|
12
|
+
`b4f293684bba718d59cc1157679bcf6157b3a7f5` (2026-07-27).
|
|
13
|
+
- `nicobailon/pi-subagents` `main` commit `73fb2fc` (2026-07-27).
|
|
14
|
+
|
|
15
|
+
The Pi repository currently publishes release tags ahead of the fetched
|
|
16
|
+
`main` version line, so this contract records both: `main` is the requested
|
|
17
|
+
source probe, while `v0.82.1` is the latest released runtime/API baseline.
|
|
18
|
+
|
|
19
|
+
This contract is the implementation boundary for first-class Pi support.
|
|
20
|
+
It follows Pi's native extension model instead of treating every coding agent
|
|
21
|
+
as an MCP host. Pi core deliberately ships without MCP, subagents, plan mode,
|
|
22
|
+
or permission popups. It natively discovers Agent Skills and can run their CLI
|
|
23
|
+
workflows through its built-in `bash` tool.
|
|
24
|
+
|
|
25
|
+
## Frozen artifact and discovery policy
|
|
26
|
+
|
|
27
|
+
`planr install pi` owns exactly the repository paths in the executable
|
|
28
|
+
contract below. Workflow files are copied byte-for-byte from the canonical
|
|
29
|
+
`plugins/planr/skills` sources. Pi-specific role bodies exist only because
|
|
30
|
+
`pi-subagents` frontmatter is not interchangeable with Claude/Cursor role
|
|
31
|
+
frontmatter: it uses `thinking`, explicit tool/skill inheritance controls, and
|
|
32
|
+
project agents under `.pi/agents/**/*.md`.
|
|
33
|
+
|
|
34
|
+
Pi loads `.pi/skills/` only after the repository is trusted. Interactive Pi
|
|
35
|
+
asks for trust; non-interactive `-p`, JSON, and RPC runs ignore untrusted
|
|
36
|
+
project resources by default. A headless operator who has deliberately chosen
|
|
37
|
+
to trust the repository passes `--approve` for that run. Planr never writes
|
|
38
|
+
Pi's user trust store or `.pi/settings.json`.
|
|
39
|
+
|
|
40
|
+
`pi-subagents` is optional. When installed, it discovers both Planr roles.
|
|
41
|
+
Without it, the role files are inert and the same Planr skills remain usable
|
|
42
|
+
in the parent Pi session or separate Pi processes.
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"contract_version": 1,
|
|
47
|
+
"pi_main_revision": "a597371bda2af70372d1323d550483b5f4a0ae36",
|
|
48
|
+
"pi_release": {
|
|
49
|
+
"tag": "v0.82.1",
|
|
50
|
+
"revision": "b4f293684bba718d59cc1157679bcf6157b3a7f5"
|
|
51
|
+
},
|
|
52
|
+
"pi_subagents_revision": "73fb2fc",
|
|
53
|
+
"artifacts": [
|
|
54
|
+
{"target": ".pi/agents/planr-reviewer.md", "source": "plugins/planr/agents/pi/planr-reviewer.md", "kind": "agent"},
|
|
55
|
+
{"target": ".pi/agents/planr-worker.md", "source": "plugins/planr/agents/pi/planr-worker.md", "kind": "agent"},
|
|
56
|
+
{"target": ".pi/skills/planr-goal/SKILL.md", "source": "plugins/planr/skills/planr-goal/SKILL.md", "kind": "skill"},
|
|
57
|
+
{"target": ".pi/skills/planr-loop/SKILL.md", "source": "plugins/planr/skills/planr-loop/SKILL.md", "kind": "skill"},
|
|
58
|
+
{"target": ".pi/skills/planr-loop/agents/planr-reviewer.md", "source": "plugins/planr/skills/planr-loop/agents/planr-reviewer.md", "kind": "skill_asset"},
|
|
59
|
+
{"target": ".pi/skills/planr-loop/agents/planr-worker.md", "source": "plugins/planr/skills/planr-loop/agents/planr-worker.md", "kind": "skill_asset"},
|
|
60
|
+
{"target": ".pi/skills/planr-loop/references/host-dispatch.md", "source": "plugins/planr/skills/planr-loop/references/host-dispatch.md", "kind": "skill_asset"},
|
|
61
|
+
{"target": ".pi/skills/planr-loop/references/recovery-and-verification.md", "source": "plugins/planr/skills/planr-loop/references/recovery-and-verification.md", "kind": "skill_asset"},
|
|
62
|
+
{"target": ".pi/skills/planr-plan/SKILL.md", "source": "plugins/planr/skills/planr-plan/SKILL.md", "kind": "skill"},
|
|
63
|
+
{"target": ".pi/skills/planr-review/SKILL.md", "source": "plugins/planr/skills/planr-review/SKILL.md", "kind": "skill"},
|
|
64
|
+
{"target": ".pi/skills/planr-status/SKILL.md", "source": "plugins/planr/skills/planr-status/SKILL.md", "kind": "skill"},
|
|
65
|
+
{"target": ".pi/skills/planr-summary/SKILL.md", "source": "plugins/planr/skills/planr-summary/SKILL.md", "kind": "skill"},
|
|
66
|
+
{"target": ".pi/skills/planr-task-graph/SKILL.md", "source": "plugins/planr/skills/planr-task-graph/SKILL.md", "kind": "skill"},
|
|
67
|
+
{"target": ".pi/skills/planr-verify-web/SKILL.md", "source": "plugins/planr/skills/planr-verify-web/SKILL.md", "kind": "skill"},
|
|
68
|
+
{"target": ".pi/skills/planr-work/SKILL.md", "source": "plugins/planr/skills/planr-work/SKILL.md", "kind": "skill"},
|
|
69
|
+
{"target": ".pi/skills/planr/SKILL.md", "source": "plugins/planr/skills/planr/SKILL.md", "kind": "skill"}
|
|
70
|
+
],
|
|
71
|
+
"mcp": {"supported": false, "artifacts": []},
|
|
72
|
+
"extensions": {"emitted": false, "artifacts": []},
|
|
73
|
+
"hooks": {"supported": false, "artifacts": []},
|
|
74
|
+
"settings": {"emitted": false, "artifacts": []},
|
|
75
|
+
"trust": {
|
|
76
|
+
"project_resources_require_trust": true,
|
|
77
|
+
"interactive": "Pi prompts the operator",
|
|
78
|
+
"headless": "pass --approve only after choosing to trust the repository"
|
|
79
|
+
},
|
|
80
|
+
"observed_client": {
|
|
81
|
+
"environment": "PI_CODING_AGENT",
|
|
82
|
+
"accepted_value": "true",
|
|
83
|
+
"stored_value": "pi",
|
|
84
|
+
"advisory_only": true
|
|
85
|
+
},
|
|
86
|
+
"client_all_includes_pi": false,
|
|
87
|
+
"headless": {
|
|
88
|
+
"command": "pi --approve --model <provider/model> --thinking <level> -p \"<prompt>\""
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Pi role contract
|
|
94
|
+
|
|
95
|
+
Both role files use `pi-subagents` project-agent frontmatter:
|
|
96
|
+
|
|
97
|
+
- `name` is exactly `planr-worker` or `planr-reviewer`;
|
|
98
|
+
- `systemPromptMode: replace`;
|
|
99
|
+
- `inheritProjectContext: true`;
|
|
100
|
+
- `inheritSkills: false`;
|
|
101
|
+
- `skills` names exactly `planr-work` or `planr-review`;
|
|
102
|
+
- the worker tool allowlist includes read/search, `bash`, `edit`, and `write`;
|
|
103
|
+
- the reviewer tool allowlist includes read/search and mutation-capable `bash`,
|
|
104
|
+
but omits the `edit` and `write` tools;
|
|
105
|
+
- the reviewer declares `acceptanceRole: read-only` and
|
|
106
|
+
`completionGuard: false`, so pi-subagents treats the bash-enabled validator
|
|
107
|
+
as non-implementation work without changing its tool access;
|
|
108
|
+
- no role pins `model`, `thinking`, `fallbackModels`, provider credentials, or
|
|
109
|
+
extensions.
|
|
110
|
+
|
|
111
|
+
Model and thinking selection remain external host policy. Operators can use
|
|
112
|
+
Pi or `pi-subagents` settings/overrides, while Planr records only requested and
|
|
113
|
+
observed evidence.
|
|
114
|
+
|
|
115
|
+
## Merge and overwrite policy
|
|
116
|
+
|
|
117
|
+
- Missing target: write the canonical packaged source.
|
|
118
|
+
- Existing identical content: unchanged.
|
|
119
|
+
- Existing different content: preserve without `--force`; replace only that
|
|
120
|
+
target with `--force`.
|
|
121
|
+
- `--no-mcp` and `--no-hooks` are accepted for install-command parity but
|
|
122
|
+
change no Pi path because the v1 artifact set contains neither.
|
|
123
|
+
- Dry-run enumerates the same paths the corresponding write reconciles.
|
|
124
|
+
- `project init --client pi` provisions the same skills and roles without
|
|
125
|
+
writing any other Pi artifact.
|
|
126
|
+
- `--client all` remains the legacy Codex, Claude Code, and Cursor expansion.
|
|
127
|
+
|
|
128
|
+
## Runtime observation boundary
|
|
129
|
+
|
|
130
|
+
Pi documents that commands launched by its built-in tools receive
|
|
131
|
+
`PI_CODING_AGENT=true`. Planr accepts only that exact value as advisory
|
|
132
|
+
`runs.observed_client=pi`. Other values and other ambient `PI_*` variables are
|
|
133
|
+
ignored. The marker is not authentication, authorization, proof of model,
|
|
134
|
+
proof of `pi-subagents`, or worker identity.
|
|
135
|
+
|
|
136
|
+
Pi has no Planr hook in v1. Run `planr prime` manually after startup or
|
|
137
|
+
compaction when a fresh state block is useful. Agent Skills remain the primary
|
|
138
|
+
entry point: `/skill:planr` explicitly loads the router, while natural-language
|
|
139
|
+
requests may trigger Pi's skill discovery.
|
|
140
|
+
|
|
141
|
+
## Security and CI boundary
|
|
142
|
+
|
|
143
|
+
Planr installation must not read or write:
|
|
144
|
+
|
|
145
|
+
- `~/.pi`, Pi auth files, provider keys, OAuth tokens, sessions, transcripts,
|
|
146
|
+
prompts, responses, model catalogs, package caches, or trust decisions;
|
|
147
|
+
- `.pi/settings.json`, `.pi/extensions/`, `.pi/prompts/`, or an MCP config;
|
|
148
|
+
- global `pi install`, `pi config`, package enablement, or user settings.
|
|
149
|
+
|
|
150
|
+
Release and CI workflows do not install/invoke Pi, `pi-subagents`, a provider,
|
|
151
|
+
or a live model. Deterministic tests parse the frozen contract, compile/write
|
|
152
|
+
assets into disposable repositories, and validate CLI/docs output.
|
|
153
|
+
|
|
154
|
+
## Sources
|
|
155
|
+
|
|
156
|
+
- `packages/coding-agent/README.md` at Pi `v0.82.1`: project trust, skills,
|
|
157
|
+
extensions, packages, philosophy, CLI, and `PI_CODING_AGENT`.
|
|
158
|
+
- `packages/coding-agent/docs/skills.md` at Pi `v0.82.1`.
|
|
159
|
+
- `nicobailon/pi-subagents` README at `73fb2fc`: project agent discovery,
|
|
160
|
+
prompt assembly, frontmatter, and model overrides.
|
|
161
|
+
- `nicobailon/pi-subagents` `test/unit/agent-frontmatter.test.ts` and
|
|
162
|
+
`test/unit/path-resolution.test.ts` at `73fb2fc`.
|
|
163
|
+
- https://github.com/earendil-works/pi
|
|
164
|
+
- https://github.com/nicobailon/pi-subagents
|