planr 1.3.0-alpha.1 → 1.4.0

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.
Files changed (46) hide show
  1. package/README.md +32 -1
  2. package/docs/ARCHITECTURE.md +5 -0
  3. package/docs/CLI_REFERENCE.md +21 -4
  4. package/docs/MCP_CONTRACT.md +5 -1
  5. package/docs/MODEL_ROUTING.md +2 -2
  6. package/docs/PRESET_COMPOSITION.md +109 -0
  7. package/docs/PRESET_EVALUATION.md +118 -0
  8. package/docs/PRESET_REGISTRY.md +61 -0
  9. package/docs/fixtures/mcp-contract.json +16 -0
  10. package/evaluations/preset-suite-v1.toml +127 -0
  11. package/evaluations/sol-luna-codex-v1.toml +42 -0
  12. package/npm/native/darwin-arm64/planr +0 -0
  13. package/npm/native/darwin-x86_64/planr +0 -0
  14. package/npm/native/linux-arm64/planr +0 -0
  15. package/npm/native/linux-x86_64/planr +0 -0
  16. package/package.json +15 -2
  17. package/plugins/planr/.claude-plugin/plugin.json +1 -1
  18. package/plugins/planr/.codex-plugin/plugin.json +1 -1
  19. package/plugins/planr/skills/planr-verify-web/SKILL.md +1 -0
  20. package/presets/bindings/claude-native.toml +52 -0
  21. package/presets/bindings/codex-openai.toml +56 -0
  22. package/presets/bindings/cursor-fable-grok.toml +49 -0
  23. package/presets/bindings/cursor-openai.toml +49 -0
  24. package/presets/bindings/mixed-host.toml +64 -0
  25. package/presets/policies/balanced.toml +50 -0
  26. package/presets/policies/low-usage.toml +50 -0
  27. package/presets/policies/max-quality.toml +50 -0
  28. package/presets/policies/read-only-audit.toml +50 -0
  29. package/website/README.md +79 -0
  30. package/website/_headers +7 -0
  31. package/website/alchemy-runtime.test.mjs +21 -0
  32. package/website/app.mjs +216 -0
  33. package/website/build-catalog.mjs +135 -0
  34. package/website/build-site.test.mjs +69 -0
  35. package/website/catalog-model.mjs +185 -0
  36. package/website/catalog-model.test.mjs +124 -0
  37. package/website/cloudflare-launcher.test.mjs +38 -0
  38. package/website/data/catalog.json +307 -0
  39. package/website/index.html +122 -0
  40. package/website/registry/manifest.toml +48 -0
  41. package/website/registry/report.md +33 -0
  42. package/website/registry/trusted-maintainers.toml +6 -0
  43. package/website/registry/verification.json +7258 -0
  44. package/website/serve.mjs +41 -0
  45. package/website/styles.css +201 -0
  46. package/website/test-fixtures/recommended.json +72 -0
package/README.md CHANGED
@@ -22,7 +22,38 @@ Flat todo lists break down the moment real work has structure. Planr models work
22
22
 
23
23
  Three layers make that work: **Plans** (reviewable Markdown packages), the **Map** (live dependency graph with picks, reviews, logs), and **Agent loops** (skills, CLI, and MCP workflows for every major coding agent). Full model: [Task Graph Model](docs/TASK_GRAPH_MODEL.md) and [Operating Model](docs/OPERATING_MODEL.md).
24
24
 
25
- ## New in 1.2.0: Model Routing
25
+ ## New in 1.4.0: Verified Presets & Catalog
26
+
27
+ Planr now ships a verified preset system for composing a provider-neutral usage policy with a host binding, previewing every repository-local change, and applying the result only after confirmation:
28
+
29
+ ```bash
30
+ planr agents preset list
31
+ planr agents preset apply balanced --binding codex-openai --preview
32
+ planr agents preset apply balanced --binding codex-openai --confirm
33
+ ```
34
+
35
+ The built-in catalog includes four policies, five host bindings, and 20 declared safe pairs. Reproducible evaluation, signed registry verification, and the public [Planr Preset Catalog](https://planr-test-catalog.office-35d.workers.dev/) keep recommendation evidence inspectable without making the registry a runtime dependency. Full guides: [Preset Composition](docs/PRESET_COMPOSITION.md) · [Preset Evaluation](docs/PRESET_EVALUATION.md) · [Preset Registry](docs/PRESET_REGISTRY.md).
36
+
37
+ ## New in 1.3.0: Native Host Hooks
38
+
39
+ `planr install codex|claude|cursor` now wires Planr into the host's native hook system by default — every new session (including post-compaction restarts) gets one compact state block injected automatically:
40
+
41
+ ```text
42
+ ## planr state
43
+ project: Hookboard | map: 5/5 settled | 0 ready, 0 picked, 0 in_review
44
+ goal contract: DONE when every in-scope map item is closed with log evidence, ...
45
+ routing: registry active (3 profiles; pick packets carry model routing)
46
+ next: planr plan audit pln-fc584c28 --json
47
+ ```
48
+
49
+ - **`planr prime`** — the state block behind the hooks: project, map counts, held items with log status, goal contract, and the next command. Silent in repos without a Planr database.
50
+ - **Loop recovery becomes mechanism, not discipline** — an agent that restarts or compacts mid-loop picks up exactly where the map says it left off.
51
+ - **Evidence guard (Cursor)** — a subagent that stops while its own pick has no completion log gets one advisory reminder naming the item and the two ways out.
52
+ - **Fail-open and additive** — hooks never block a session (10s timeout, always exit 0), existing hook files are merged, `--no-hooks` opts out.
53
+
54
+ Full guide: [Hooks](docs/HOOKS.md) · [Release notes](https://github.com/instructa/planr/releases/tag/v1.3.0).
55
+
56
+ ## Model Routing (1.2.0)
26
57
 
27
58
  Declare once which model handles which work — every task then carries its own routing, and your agents delegate automatically:
28
59
 
@@ -40,6 +40,11 @@ Planr V1 is a single Rust binary with explicit module ownership. The crate stays
40
40
  - `src/storage/rows.rs`: SQLite row mapping boundary. Owns row-to-DTO and row-to-JSON mapping functions.
41
41
  - `src/planpack.rs`: Markdown package generation and parsing. Owns project context templates, product/build plan templates, plan metadata parsing, hashes, search body extraction, and task extraction.
42
42
  - `src/agents.rs`: agent profile registry core. Owns `.planr/agents.toml` parsing, registry validation warnings, and the pure advisory `resolve_route` precedence logic (override > work_type > plan > default); no storage or host concerns.
43
+ - `src/usage_policy.rs`: provider-neutral Usage Policy v1 core. Owns strict `.planr/policy.toml` parsing, policy and task-contract vocabulary, materiality classification, budget/concurrency validation, and the pure five-way transition resolver; it contains no provider ids, host dispatch, or execution-permission behavior.
44
+ - `src/execution_policy.rs`: execution admission core. Owns per-role filesystem, network, tool/MCP, structured command, environment, hook, secret, and approval grants; permission-diff previews; bounded task-contract admission; fail-closed command grammar; and isolated write-scope concurrency. It never selects models or mutates graph state. `src/app/policy.rs` binds that pure decision to the current SQLite lease owner and pick token, and only treats an admission from that exact lease generation as authoritative.
45
+ - `src/route_audit.rs`: provider-neutral run-observation contract. Owns strict requested/resolved/effective route stages, model/effort/fork enforcement confidence, transition provenance, policy/binding versions, and per-dimension metering confidence. It rejects requested-only values in the effective stage rather than inferring host execution.
46
+ - `src/preset.rs`: pure preset-composition core. Owns versioned host-binding types, abstract-role compatibility, model/effort/fork capability validation, deterministic registry projection, verification age, permission additions, and provenance-lock vocabulary; it performs no writes.
47
+ - `src/app/presets.rs`: shared CLI/MCP preset application service and repository-artifact writer. Owns preview/conflict reporting, canonical-root and allowlist enforcement, symlink/traversal rejection, create-only apply, rollback on write failure, and `policy_applied`/rejection events.
43
48
  - `src/app/agents.rs`: routing application boundary. Owns the `agents` and `item route` command handlers, the shared `*_value` JSON shapes reused by MCP, per-item route facts assembly, and registry-aware role content selection for installs.
44
49
  - `src/app/agents_init.rs`: registry bootstrap boundary. Owns `planr agents init` — the static cost-tiering scaffold and, per the agent-pool plan, the flag-spec builder and interactive wizard.
45
50
  - `src/integrations.rs`: agent-client integration descriptor boundary. Owns Codex, Claude Code, Cursor, MCP install metadata, MCP tool schemas, MCP resources, and MCP text response wrapping.
@@ -44,11 +44,13 @@ planr approval approve <item-id> --by "name" [--comment "..."]
44
44
  planr approval deny <item-id> --by "name" [--comment "..."]
45
45
  planr approval list [--open]
46
46
  planr artifact add "name"|--name "name" [--item <item-id>] [--kind evidence] [--path file] [--content "..."] [--mime text/plain]
47
+ # --kind is free-form vocabulary; common values: evidence, screenshot, video, recording, report, review
47
48
  planr artifact show <artifact-id>
48
49
  planr artifact list [--item <item-id>]
49
50
  planr event list [--item <item-id>] [--limit 50]
50
51
  planr debug bundle [--item <item-id>] --preview
51
- planr log add --item <item-id> --summary "..." [--files a --files b | --files a,b] [--cmd "..."] [--kind completion|progress|verification] [--profile <id>]
52
+ planr trace item <item-id>
53
+ planr log add --item <item-id> --summary "..." [--files a --files b | --files a,b] [--cmd "..."] [--kind completion|progress|verification] [--profile <id>] [--route-audit <observation.json>]
52
54
  # machine consumers: --cmd writes the `commands` field in log JSON; --tests writes `tests`
53
55
  planr review request <item-id>
54
56
  planr review annotate <item-id> --message "..." [--severity info|warning|blocking] [--file path] [--line N] [--author "..."]
@@ -65,6 +67,11 @@ planr agents init [--force]
65
67
  planr agents init --profile|--skill|--route|--default-route|--interactive
66
68
  planr agents list [--json]
67
69
  planr agents check
70
+ planr agents preset list [--json]
71
+ planr agents preset apply <policy-path-or-id> --binding <binding-path-or-id> [--preview|--confirm]
72
+ planr agents preset registry verify <manifest> --entry <id> --content-root <dir> [--trust-store <path>] [--at-unix <timestamp>] [--host <host>]
73
+ planr agents preset registry import <manifest> --entry <id> --content-root <dir> [--trust-store <path>] [--at-unix <timestamp>] [--host <host>] [--preview|--confirm]
74
+ planr agents preset registry list [--at-unix <timestamp>]
68
75
  planr doctor [--client codex|claude|cursor|all]
69
76
  planr install codex|claude|cursor [--dry-run] [--no-mcp] [--force] [--no-hooks]
70
77
  planr prompt cli|mcp|http [--client codex|claude|cursor|all]
@@ -90,7 +97,7 @@ With `--json`, responses follow one convention so agents never guess where data
90
97
 
91
98
  `plan check` validates path, YAML frontmatter, and that required sections have content: build plans need `## Scope Decision`, `## Verification`, and `## Acceptance Criteria` filled; product plans need `## Problem`, `## Requirements`, and `## Success Criteria` filled in `PRODUCT_SPEC.md`. It also flags a task list that still contains only the scaffold placeholder (or no work specs at all) — `map build` would turn that into a single coarse item, so the fix names the granularity contract: one `### TASK-00n:` heading (or `- [ ]` line) per verifiable slice, typically 4-8, in execution order. Each warning is structured — `{"file", "section", "message", "fix"}` — and names the exact file to edit plus the re-run command, so a failed check is a repair instruction, not a riddle.
92
99
 
93
- `plan audit <plan-id>` is the one-call contract verdict for a plan's map scope. It evaluates four clauses with evidence: `items_settled` (open items listed), `reviews_complete` (open review items listed), `approvals_clear` (requested/denied approvals listed), and `verification_logged` (logs with `--kind verification` on scope items). The stored goal contract (`planr context --tag goal-contract` mentioning the plan id) is included; the verification clause is binding only when such a contract exists. `holds: true` means the contract is satisfied — loop agents use this as their stop condition instead of stitching the verdict together from `map status`, `log list`, and `approval list`. When the contract is open, `next` carries the exact next command derived from the first actionable gap: build the map, pick the ready review or work item (plan-scoped), resolve the blocking approval, inspect stalled leases, or log the missing verification. Also available as MCP `planr_plan_audit`.
100
+ `plan audit <plan-id>` is the one-call contract verdict for a plan's map scope. JSON shape for machine consumers: top-level `holds` (bool) and `clauses[]` with `clause` (name) and `pass` (bool) — e.g. `planr plan audit <id> --json | jq '.holds, (.clauses[] | {clause, pass})'`. It evaluates four clauses with evidence: `items_settled` (open items listed), `reviews_complete` (open review items listed), `approvals_clear` (requested/denied approvals listed), and `verification_logged` (logs with `--kind verification` on scope items). The stored goal contract (`planr context --tag goal-contract` mentioning the plan id) is included; the verification clause is binding only when such a contract exists. `holds: true` means the contract is satisfied — loop agents use this as their stop condition instead of stitching the verdict together from `map status`, `log list`, and `approval list`. When the contract is open, `next` carries the exact next command derived from the first actionable gap: build the map, pick the ready review or work item (plan-scoped), resolve the blocking approval, inspect stalled leases, or log the missing verification. Also available as MCP `planr_plan_audit`.
94
101
 
95
102
  `map show --plan <plan-id>` narrows the map to one plan's items and the links among them, with plan-scoped counts — plan-scoped goal runs on shared boards audit their slice, not the whole board. An unknown plan id is an error, never a silent unscoped view. Also available on MCP `planr_map_show` (`plan`) and HTTP `GET /v1/projects/{id}/map?plan=<plan-id>`.
96
103
 
@@ -122,7 +129,7 @@ With `--json`, responses follow one convention so agents never guess where data
122
129
 
123
130
  `review close` writes `.planr/reviews/<review-item-id>.review.md` and registers it as a review artifact. A `not-complete` or `unclear` verdict creates fix and follow-up review work; the follow-up review gates the same target item, so the chain keeps working with `--close-target`. With `--close-target` (complete verdicts only) the reviewed item is closed in the same command, provided it already has a completion log; the artifact is rendered after the target transition, so it snapshots the final target status. `--close-target` is also available through MCP `planr_review_close` and HTTP `POST /v1/reviews/{id}/close` (`"close_target": true`). `review close` responses include the same `remaining` progress snapshot as `done` and `close`. `--reviewer <id>` records the checker's identity on the review log, artifact, and event (defaults to the worker id), keeping maker and checker distinguishable in the audit trail. Closing an already-settled review fails with error code `already_closed` instead of silently duplicating evidence logs. The maker/checker split is derived, not declared: `review_mode` compares the closing reviewer identity against the target item's lease holder and reports `single_agent`, `independent`, or `unattributed` in the response, review log, artifact, and event — no ceremony note required. An `unattributed` close explains itself in the output: it means the target has no recorded lease (work was never picked or its lease was released), not that the reviewer's identity was missing.
124
131
 
125
- `trace item` on a review item inlines the target item and its evidence logs under `target`, so a reviewer's first trace already contains what is being audited. The human (non-JSON) mode renders the packet: status, owner, links, logs. When the item has a declared route or a run recorded a profile, the trace gains a `routing` section — the declared route next to every run's actual client/profile with an advisory `mismatch` marker and a mismatch count; items without either keep the exact pre-routing trace shape.
132
+ `trace item` on a review item inlines the target item and its evidence logs under `target`, so a reviewer's first trace already contains what is being audited. The human (non-JSON) mode renders the packet: status, owner, links, logs. When the item has a declared route, a run profile, or a route observation, the trace gains a `routing` section — the declared route next to every run's actual client/profile and, when supplied, its independent requested → resolved → effective model/effort/context-fork stages, transition reason, policy/binding provenance, and per-dimension metering confidence. Unknown effective host values remain `null`/`unavailable`; requested values are never copied forward as proof. MCP `planr_trace_item` returns the identical JSON shape.
126
133
 
127
134
  `doctor` also reports the agent registry in all states without ever failing: absent (informational hint), degraded (parse error with line context), or loaded with profile/route counts, validation warnings, and per-artifact drift — a rendered role file whose content no longer matches what the current registry would render is flagged `drifted` with a `planr install <client> --force` hint, while files without the generated-from header are the user's (`manual`) and never flagged.
128
135
 
@@ -134,9 +141,19 @@ With `--json`, responses follow one convention so agents never guess where data
134
141
 
135
142
  `pick --work-type <type>` restricts the lease to one work type, so checker agents pick only `review` items and makers only work items. `pick --plan <plan-id>` restricts the lease to one plan's items, so plan-scoped goal runs never pick work outside their contract even when other plans share the board; an unknown plan id is an error, never a silent unscoped pick. Both filters are available on MCP `planr_pick_item` and HTTP `POST /v1/pick` (`work_type`, `plan`). A null pick is never blind: `{"item": null}` carries a `reason` (`empty_map`, `all_settled`, `nothing_ready`, `ready_items_excluded_by_filter`) and the `remaining` snapshot. When ready work exists but the active filters rejected all of it, `excluded` lists each ready item with the cause (`work_type` mismatch, outside the `--plan` scope, or just requested by this worker) and `repair` carries the exact pick commands that would lease that work — across CLI, MCP, and HTTP. On a review item, `close_effect` previews the full `--close-target` cascade: it lists the work that closing the review (and with it the reviewed item) would unlock.
136
143
 
144
+ `policy show` and `policy check` inspect the provider-neutral Usage Policy v1 file (`.planr/policy.toml`). A missing policy is an explicit successful state that preserves existing advisory routing; a malformed or unsafe policy fails `check` with parser/field diagnostics and leaves enforcement unavailable. Usage Policy v1 fixes delegation depth at one and keeps retry, availability fallback, quality escalation, quota downgrade, and safety stop as distinct transition contracts. Its separate `execution` section declares bounded per-role filesystem, network, tool/MCP, structured command, environment, hook, secret-reference, and approval grants. `policy admit <request.json>` requires the picked item's current `item_id` and `pick_token`, authorizes the current worker as lease owner, evaluates a bounded task contract before delegation, previews any permission addition, records the decision and lease generation, rejects unclassified commands and destructive or out-of-scope work, permits overlapping readers, and admits concurrent writers only for disjoint scopes isolated in distinct worktrees. Released or recovered leases never inherit historical admitted scopes. MCP `planr_policy_show`, `planr_policy_check`, and `planr_policy_admit`, plus HTTP `POST /v1/policy/admit`, call the same admission service and return the same decision shape.
145
+
146
+ `agents preset list` enumerates the embedded catalog: `balanced`, `low-usage`, `max-quality`, and `read-only-audit` policies; `codex-openai`, `cursor-openai`, `cursor-fable-grok`, `claude-native`, and `mixed-host` bindings; source checksums; and every declared safe pair. MCP `planr_presets_list` returns the identical catalog.
147
+
148
+ `agents preset apply <policy-path-or-id> --binding <binding-path-or-id>` composes a provider-neutral Usage Policy v1 file with a strict, versioned host binding. Embedded id pairs report `pack.status = safe`; explicit file inputs remain allowed custom compositions and receive a clear non-safe warning even if they reuse built-in ids. Preview is the default and reports compatibility, per-role permission additions, verification age, provenance, content hashes, every normalized repository-relative target, create/unchanged/conflict state, and a redacted old/proposed configuration projection. Policy limits/transitions and generated registry routes, concrete models/efforts, and fallbacks are therefore auditable before confirmation without returning secret-like values. `--confirm` writes exactly the conflict-free preview to `.planr/policy.toml`, `.planr/agents.toml`, `.planr/preset.lock.toml`, and allowlisted repository-local host artifacts; it never overwrites different existing files. Absolute paths, traversal, symlink crossings, user/home/global configuration, and repository `.codex/config.toml` fail before the first write. Secret-like binding metadata is rejected with field-only diagnostics before dispatch/warning output or mutation. Bindings own exact client/model/effort and fork capabilities: Codex cross-tier dispatch is keyed by the binding host identity, defaults to `none`, rejects `all`, and accepts a positive partial fork only with declared limits and non-blank capability evidence. Host-specific bindings require every profile client to match the host; explicit cross-client mappings use `host = "mixed-host"`. MCP `planr_preset_apply` calls the same application service and returns the identical shape (`confirm` defaults to false). Binding schema and repository-boundary details: [Preset Composition](PRESET_COMPOSITION.md).
149
+
150
+ `agents preset evaluate [--report-dir <dir>] [--at-unix <timestamp>] [--host <host>] [--live-host-command <absolute-executable> [--live-host-arg <arg>]... [--trusted-telemetry-signer <registry-id> --trusted-telemetry-collector <absolute-executable>]]` defaults to the embedded offline simulation: no process/network execution, estimated projections, unavailable effective routes, and no recommendation. Explicit live mode creates a Planr-controlled challenge/workspace for every versioned task. The adapter must read the challenge and write a bounded strict-schema artifact whose independently computed hash, candidate/task/input/artifact binding, challenge binding, and task oracle Planr validates. Live `evidence_complete` requires every required task execution and oracle pass; missing or invalid artifacts produce `unverified` candidates and make report-level `reproducible_evidence` false. Policy tool/write capabilities remain authoritative. Without telemetry, host route and tool/token/credit claims remain estimated and recommendation-ineligible. The all-or-none telemetry flags select a signer and collector independently pinned in `.planr/trusted-telemetry.toml`. Planr creates a fresh run UUID and task challenge, invokes the hash-pinned collector only after independently reading the artifact, verifies the registry-pinned Ed25519 signature and exact run/suite/time/task/input/artifact/challenge/host bindings, then promotes only receipt-backed effective route and usage dimensions to `telemetry_receipt`/`trusted`. Caller-supplied keys, run ids, and precomputed bundles are not accepted; missing, replayed, or tampered post-run receipts fail closed. Valid complete telemetry makes `recommended` reachable on CLI and MCP. Constant responders, public-label request mappers, and read-only candidates on write fixtures cannot recommend. Full protocol: [Preset Evaluation](PRESET_EVALUATION.md).
151
+
152
+ `agents preset registry verify/import/list` implements the optional declarative registry boundary. Verification checks version compatibility, host compatibility, lifecycle/revocation, exact byte lengths and SHA-256 digests, canonical policy/binding semantics and safe artifacts, and optional Ed25519 signatures against separately pinned maintainer keys. `recommended` additionally requires a current canonical evaluation bound to the shipped policy/binding bytes, independently derived metrics and thresholds, task/oracle/result-hash completeness, and trusted route/metering evidence; a trusted signature alone cannot promote it. Import previews by default and, on `--confirm`, atomically caches only manifest-declared files plus the original manifest below `.planr/registry/cache/`. Offline listing treats the receipt as inventory only and re-verifies the manifest hash, signature, manifest-owned checksums, and freshness, so coordinated content/receipt tampering fails closed and a registry outage cannot affect active projects or already verified content. See [Preset Registry](PRESET_REGISTRY.md).
153
+
137
154
  `agents init` writes a commented starter registry with the cost-tiering defaults (premium driver that keeps the verdicts, standard steerable implementer, budget helper for token-hungry side work, plus code/fix/review/default routes) and names the follow-up commands; an existing `.planr/agents.toml` is never overwritten without `--force`. Individual pools generate from repeatable spec flags — `--profile designer=claude-code/opus@high#premium` declares a profile, `--skill designer=frontend-design` pairs it with a skill, `--route frontend=designer,driver` routes a use-case work type with fallbacks, `--default-route` catches the rest; validation is fail-closed (unknown profile references and malformed specs error, naming the grammar, before anything is written), and consistent specs generate a zero-warning registry. `--interactive` walks the same questions as guided prompts (requires a terminal; conflicts with spec flags) and can render the host role files at the end. `agents list` and `agents check` inspect the agent profile registry (`.planr/agents.toml`): named profiles (host client, model, effort, cost tier) and advisory routes from work selectors to profiles. When a registry resolves for a picked item, the pick packet carries a `routing` block — profile, client, model, effort, cost tier, fallback chain, and the matched selector — resolved with precedence per-item override > `work_type` > `plan` > default route. `item route` shows an item's resolved route and its source (`override` or `policy`), pins a registry profile with `--set <profile>` (emits `route_overridden`), and unpins with `--clear` (emits `route_override_cleared`); a pinned profile that later disappears from the registry falls back to policy routing with a repair hint. The same JSON shapes are exposed over MCP: `planr_agents_list` and `planr_item_route` read, `planr_item_route_set` and `planr_item_route_clear` mutate. Routing is advisory: Planr never dispatches models, a missing registry just omits the block, a malformed one degrades picking to no-routing (only `agents check` fails, with the parser's line context), and validation warnings (unknown profile references, duplicate selectors, review work on a budget tier, secret-like values) never affect exit codes. When a registry is present, `install codex|claude|cursor` renders the subagent role files with model pins from it — the `work_type=code` route pins the worker, the `work_type=review` route pins the reviewer, and a role only pins profiles whose `client` matches the install target (a Cursor-profile review route never writes a Cursor model into a Codex TOML). Rendered files carry a `# generated from .planr/agents.toml` header; without a registry (or when no matching route resolves) the shipped static role files are written byte-identically, and existing files are never overwritten without `install --force`. Full guide: [Model Routing](MODEL_ROUTING.md).
138
155
 
139
- `log add` and `done` accept `--profile <id>` — the registry profile the run actually executed on (`PLANR_PROFILE` env is the fallback, so rendered role files can export it). The profile is stored on the recorded run; when it differs from the item's declared route, Planr emits an advisory `route_mismatch_observed` event (declared, actual, run id) visible in `event list --item`. Runs without a profile, logs without commands/tests, and projects without a registry produce no comparison and no event, and mismatches never block logging, review, or closure. The MCP `planr_log_add` tool and `POST .../log` accept the same optional `profile`.
156
+ `log add` and `done` accept `--profile <id>` — the registry profile the run actually executed on (`PLANR_PROFILE` env is the fallback, so rendered role files can export it). They also accept `--route-audit <observation.json>` for the strict three-stage observation contract. A route audit records each stage's model, effort, and context-fork value with enforcement state (`verified`, `requested_only`, `estimated`, or `unavailable`), an evidence-source enum, typed transition plus reason, policy/binding ids and versions, and wall-time/tool/token/credit values with independent confidence. It is stored in run metadata, projected into its durable log and trace, and emits local route-stage/transition events. The profile remains backward compatible: when it differs from the item's declared route, Planr emits advisory `route_mismatch_observed`. Runs without commands/tests record neither a run nor a route observation. MCP `planr_log_add` and HTTP item log accept the same optional `route_observation` object.
140
157
 
141
158
  `artifact add` infers the mime type from the file extension when `--path` is given without `--mime` (PNG screenshots land as `image/png`, not `text/plain`); inline `--content` defaults to `text/plain`. The same inference applies on MCP `planr_artifact_add` and HTTP `POST /v1/artifacts`.
142
159
 
@@ -41,7 +41,11 @@ Required groups:
41
41
  - approval request, approve, deny, and list
42
42
  - artifact add, list, and show
43
43
  - event list and debug bundle preview
44
- - log add and read
44
+ - trace item, log add, and log read (including three-stage route observations)
45
+ - built-in policy/binding catalog listing plus safe-pack/custom composition status
46
+ - declarative registry verification with canonical evaluation/safe-binding gates, preview-first immutable import, and manifest-anchored integrity/signature/freshness-checked offline cache listing
47
+ - policy preset preview/apply by path or built-in id with repository-only target validation and deterministic provenance lock
48
+ - deterministic offline preset simulation plus explicit opt-in live-host execution with Planr-controlled challenge workspaces, strict task artifacts read and hashed by Planr, candidate/task outcome oracles, failed-live-attempt `unverified`/incomplete lifecycle semantics, production policy-capability checks, estimated arbitrary-process claims, optional Ed25519-verified run/suite/time/task/challenge-bound telemetry that alone can promote effective route and usage evidence to trusted/recommendation-eligible, observed process latency, transition/correction/violation counts, result hashes, and deterministic lifecycle thresholds
45
49
  - review annotate, ingest, artifact, evidence, and close
46
50
  - item close, context create, and search
47
51
 
@@ -117,9 +117,9 @@ Without a registry, installs write the static role files byte-identically to pre
117
117
 
118
118
  ## Run Audit
119
119
 
120
- Every host has a silent override path — the `CLAUDE_CODE_SUBAGENT_MODEL` env var, Cursor plan/admin/Max-Mode policy, Codex full-history forks, org allowlists — so a pin alone is not proof. The audit loop closes this: workers report the profile they actually ran on via `planr log add`/`planr done --profile <id>` (or the `PLANR_PROFILE` env var, which rendered role files can export), the profile lands on the recorded run, and when it differs from the item's declared route Planr emits an advisory `route_mismatch_observed` event with the declared and actual ids.
120
+ Every host has a silent override path — the `CLAUDE_CODE_SUBAGENT_MODEL` env var, Cursor plan/admin/Max-Mode policy, Codex full-history forks, org allowlists — so a pin alone is not proof. The audit loop closes this at two levels: workers report the profile they actually ran on via `planr log add`/`planr done --profile <id>` (or `PLANR_PROFILE`) for backward-compatible mismatch checks, and can attach a strict `--route-audit <observation.json>` that keeps requested, host-resolved, and effective model/effort/fork values separate. Every dimension carries enforcement confidence and a constrained evidence source; missing host evidence stays unavailable instead of inheriting the request.
121
121
 
122
- - `planr trace item <id>` shows the declared route next to every run's actual client/profile with a `mismatch` marker.
122
+ - `planr trace item <id>` (MCP: `planr_trace_item`) shows the declared route next to every run's actual client/profile and three-stage observation with a `mismatch` marker.
123
123
  - Runs also record the host they observably executed under (`observed_client`, detected from environment variables the hosts set themselves — no flags); a run whose host differs from the declared route's client emits an advisory `client_mismatch_observed` event, which catches exactly the deviation profile self-report cannot: a different host standing in for the declared client, even when the model matched.
124
124
  - `planr doctor` reports the registry state (absent, degraded with parse context, loaded with counts and warnings) and flags rendered role files that drifted from the current registry (`planr install <client> --force` re-renders).
125
125
  - `planr export`/`import` carry the registry with the package, preview-first; an existing registry at the destination is never silently overwritten.
@@ -0,0 +1,109 @@
1
+ # Preset Composition
2
+
3
+ Planr composes two independent inputs:
4
+
5
+ - a provider-neutral Usage Policy v1 TOML file;
6
+ - a versioned host binding containing exact client/model/effort and dispatch capabilities.
7
+
8
+ Preview is the default:
9
+
10
+ ```bash
11
+ planr agents preset apply ./policy.toml --binding ./codex-binding.toml --preview --json
12
+ planr agents preset apply ./policy.toml --binding ./codex-binding.toml --confirm --json
13
+ ```
14
+
15
+ The equivalent MCP tool is `planr_preset_apply` with `policy`, `binding`, and optional `confirm` fields. Both surfaces call one application service and return the same compatibility, permission, verification-age, provenance, conflict, and artifact shapes.
16
+
17
+ ## Built-in Catalog and Safe Packs
18
+
19
+ `planr agents preset list --json` (MCP: `planr_presets_list`) lists the four embedded policy presets, five host bindings, source checksums, and 20 declared safe pairs. Built-ins resolve by id or id plus `.toml`, so they work from any repository without copying package files first:
20
+
21
+ ```bash
22
+ planr agents preset apply balanced --binding codex-openai --preview --json
23
+ planr agents preset apply read-only-audit --binding mixed-host --confirm --json
24
+ ```
25
+
26
+ Policies: `balanced`, `low-usage`, `max-quality`, and `read-only-audit`. Bindings: `codex-openai`, `cursor-openai`, `cursor-fable-grok`, `claude-native`, and `mixed-host`. The exact inspectable sources ship under `presets/policies/` and `presets/bindings/` and are also compiled into the binary.
27
+
28
+ A response whose inputs came from the embedded catalog carries `pack.status = "safe"` and `pack.safe = true`. Explicit file inputs remain custom even when their internal ids match a built-in; they are allowed, carry `pack.status = "custom"`, and add a warning requiring review of compatibility, permission, and artifact diffs. This prevents copied or modified files from inheriting safe-pack status by name alone.
29
+
30
+ ## Host Binding v1
31
+
32
+ Bindings use strict TOML: unknown fields fail parsing. Abstract role keys must cover every role in `policy.execution.roles`; bindings may add a driver profile without adding it to execution permissions.
33
+
34
+ ```toml
35
+ schema_version = 1
36
+ id = "codex-team"
37
+ version = "1.0.0"
38
+ host = "codex"
39
+ driver_role = "driver"
40
+ default_role = "driver"
41
+ capability_evidence = ["codex-0.138-cross-tier-smoke"]
42
+ billing_assumptions = ["local subscription"]
43
+ known_limitations = ["effective model requires host evidence"]
44
+
45
+ [capabilities]
46
+ model_override = true
47
+ effort_override = true
48
+ fork_none = true
49
+ fork_all = true
50
+ max_partial_fork_turns = 4
51
+
52
+ [profiles.driver]
53
+ profile = "sol"
54
+ client = "codex"
55
+ model = "gpt-5.5"
56
+ effort = "xhigh"
57
+
58
+ [profiles.worker]
59
+ profile = "luna"
60
+ client = "codex"
61
+ model = "gpt-5.4-mini"
62
+ effort = "high"
63
+ skill = "planr-work"
64
+ # Omit for the deterministic `none` default.
65
+ fork_turns = { mode = "partial", turns = 2 }
66
+
67
+ [[routes]]
68
+ work_type = "code"
69
+ role = "worker"
70
+ fallback_roles = ["driver"]
71
+
72
+ [verification]
73
+ id = "verify-codex-team"
74
+ verified_at_unix = 1900000000
75
+ max_age_seconds = 2592000
76
+
77
+ [[artifacts]]
78
+ path = ".codex/agents/luna.toml"
79
+ kind = "codex_agent"
80
+ content = '''model = "gpt-5.4-mini"
81
+ model_reasoning_effort = "high"
82
+ '''
83
+ ```
84
+
85
+ Codex cross-tier children never accept `fork_turns = { mode = "all" }`, because full history inheritance defeats the requested model/effort override. Omitted fork configuration defaults to `none`. A partial fork must be positive, at or below `max_partial_fork_turns`, and backed by non-empty `capability_evidence`. Secret-like values are forbidden in all binding metadata, including capability evidence, billing assumptions, limitations, profile metadata, routes, and artifact paths/kinds; composition rejects them with field-only diagnostics before producing dispatch/warning output or mutating the repository.
86
+
87
+ ## Preview and Lock
88
+
89
+ The preview includes:
90
+
91
+ - composed abstract-role to registry-profile and dispatch-context mappings;
92
+ - compatibility errors and host/billing limitations;
93
+ - execution-permission additions relative to the active policy;
94
+ - verification id, age, maximum age, and fresh/stale state;
95
+ - source ids, versions, SHA-256 hashes, Planr version, and applied-at value;
96
+ - every target's kind, size, proposed/existing hash, `create`, `unchanged`, or `conflict` action, and deterministic old/proposed configuration. TOML is projected structurally so policy limits/transitions and registry routes/profiles/fallbacks are directly auditable; other text is line-projected. Secret-like keys and credential-shaped values are replaced with `[REDACTED]`.
97
+
98
+ Confirmed apply writes the previewed bytes and records `policy_applied`. The lock at `.planr/preset.lock.toml` contains source hashes and hashes for every generated non-lock artifact. Tests and reproducible packaging can pin `PLANR_PRESET_NOW_UNIX` and `PLANR_PRESET_APPLIED_AT`; ordinary operation records current time.
99
+
100
+ ## Repository Boundary
101
+
102
+ Only these repository-relative targets are valid:
103
+
104
+ - `.planr/policy.toml`
105
+ - `.planr/agents.toml`
106
+ - `.planr/preset.lock.toml`
107
+ - files below `.codex/{agents,skills}/`, `.claude/{agents,skills}/`, or `.cursor/{agents,skills}/`
108
+
109
+ Planr rejects absolute paths, `.`/`..` traversal, non-normalized paths, symlink crossings, home/global targets, and repository `.codex/config.toml` before the first write. Existing different files are conflicts and are never overwritten; there is no force or privileged mode.
@@ -0,0 +1,118 @@
1
+ # Preset Evaluation
2
+
3
+ Planr provides three explicit evidence levels over the same versioned fixture and lifecycle engine:
4
+
5
+ - the default offline policy simulation performs no external execution and can reach `verified` but never `recommended`;
6
+ - the opt-in live-host runner executes every task through a user-selected local adapter and evaluates Planr-owned workspace artifacts, but arbitrary-process route and cost claims cannot reach `recommended` without independent instrumentation.
7
+ - the instrumented live-host runner joins those artifacts to Ed25519-signed telemetry receipts and can reach `recommended` when trusted route, usage, and all other thresholds pass.
8
+
9
+ `evaluations/preset-suite-v1.toml` defines distinct inputs, artifact kinds, and candidate/task-bound output oracles for exploration, implementation, mechanical, browser, visual, security, and subagent workflows. Input and result artifacts are SHA-256 hashed.
10
+
11
+ ```sh
12
+ planr agents preset evaluate
13
+ planr --json agents preset evaluate --at-unix 1783987200
14
+ planr agents preset evaluate --report-dir reports/preset-v1
15
+ planr agents preset evaluate \
16
+ --live-host-command /absolute/path/to/host-adapter \
17
+ --live-host-arg optional-argument \
18
+ --trusted-telemetry-signer production-collector \
19
+ --trusted-telemetry-collector /absolute/path/to/collector
20
+ ```
21
+
22
+ Evaluation defaults to current wall-clock time, so evidence becomes `stale` after fixture expiry. `--at-unix` is the deterministic override for tests and reproducible exports. `--host` requires binding compatibility. The signer and collector flags are all-or-none and require live mode. MCP exposes the equivalent optional `at_unix`, `host`, `live_host_command`, `live_host_args`, `trusted_telemetry_signer`, and `trusted_telemetry_collector` inputs.
23
+
24
+ ## Offline simulation
25
+
26
+ Offline artifacts say `evidence_scope = "policy_simulation"`, `task_executed = false`, `outcome_oracle_evaluated = false`, and `recommendation_eligible = false`. Projected tool, token, credit, and latency values carry `metrics_source = "estimated_projection"` and `metering_confidence = "estimated"`.
27
+
28
+ Binding configuration populates only requested and resolved route stages. Effective model, effort, and context-fork dimensions remain `unavailable`, so route coverage is zero and the recommendation list is empty. Offline `verified` means only that policy composition, transition simulation, and hashes are complete.
29
+
30
+ ## Explicit live-host runner
31
+
32
+ `--live-host-command` must be an absolute executable path. Planr starts it once per candidate/task fixture, writes one JSON request to stdin, waits for process completion, measures elapsed time, and parses one JSON response from stdout. This is an explicit arbitrary-process boundary: only run a trusted adapter. No live process is started without the flag.
33
+
34
+ For each run, Planr creates a Planr-controlled temporary workspace containing `challenge.json`. The request contains schema/suite/candidate/policy/binding/task versions, task kind, input, input hash, required artifact kind, and absolute workspace/challenge/artifact paths. It deliberately does not expose the expected output or challenge contents. The adapter must read the challenge, write a strict schema-v1 artifact to `artifact_path`, hash those exact bytes, and bind its response back to that artifact:
35
+
36
+ ```json
37
+ {
38
+ "schema_version": 1,
39
+ "host_id": "example-host",
40
+ "host_version": "1.0.0",
41
+ "candidate_id": "balanced-codex-openai",
42
+ "task_id": "browser-report-smoke",
43
+ "input_sha256": "<request input hash>",
44
+ "artifact_kind": "browser_trace",
45
+ "artifact_sha256": "<SHA-256 of the artifact file>",
46
+ "output": "balanced-codex-openai:browser-report-smoke:browser-report-inspected",
47
+ "effective_model": "model-id",
48
+ "effective_effort": "high",
49
+ "effective_context_fork": { "mode": "none" },
50
+ "tool_calls": 1,
51
+ "tokens": 10,
52
+ "credits_micros": 100,
53
+ "retries": 1,
54
+ "availability_fallbacks": 1,
55
+ "quality_escalations": 1,
56
+ "corrections": 0,
57
+ "violations": 0
58
+ }
59
+ ```
60
+
61
+ The artifact file is separate from stdout and has this strict shape:
62
+
63
+ ```json
64
+ {
65
+ "schema_version": 1,
66
+ "candidate_id": "balanced-codex-openai",
67
+ "task_id": "browser-report-smoke",
68
+ "input_sha256": "<request input hash>",
69
+ "artifact_kind": "browser_trace",
70
+ "challenge_sha256": "<SHA-256 of Planr's challenge file>",
71
+ "output": "balanced-codex-openai:browser-report-smoke:browser-report-inspected"
72
+ }
73
+ ```
74
+
75
+ Planr reads the artifact itself after the process exits, rejects missing, symlinked, oversized, malformed, or extra-field artifacts, computes its SHA-256 independently, verifies candidate/task/input/artifact and challenge binding, and finally evaluates the versioned task oracle. Neither a constant responder nor a request-aware mapper that only echoes dynamic request fields and public success labels writes this Planr-controlled artifact, so both have `task_executed = false`, `evidence_complete = false`, status `unverified`, and cannot recommend. A wholly failed live attempt also sets the report-level `reproducible_evidence = false`; merely attempting the adapter is never described as evaluated live evidence.
76
+
77
+ Production policy checks remain authoritative: tool-budget and write-capability checks are evaluated from the candidate policy, never adapter claims. A read-only candidate fails the implementation and mechanical write fixtures even if the adapter returns otherwise successful JSON.
78
+
79
+ The adapter reports effective route and usage values, but process exit does not make those claims trusted. Effective route fields are labeled `host_report` with `estimated` enforcement, so they do not increment `verified_route_runs`. Tool/token/credit metering is also `estimated`; only elapsed process latency is independently measured by Planr. Retry/fallback/escalation/correction/violation counts remain visible host reports. The process-adapter boundary therefore always sets `recommendation_eligible = false`, even when every workspace artifact passes.
80
+
81
+ ## Independently signed telemetry
82
+
83
+ Recommendation-capable live evaluation uses a separately provisioned telemetry collector. The repository trust registry at `.planr/trusted-telemetry.toml` pins both an Ed25519 signer key and the SHA-256 of the collector executable; the evaluation invocation supplies only the registry signer id and the absolute collector path. A caller-selected public key, run id, or precomputed receipt bundle is not accepted. The registry shape is:
84
+
85
+ ```toml
86
+ schema_version = 1
87
+
88
+ [[signers]]
89
+ id = "production-collector"
90
+ public_key_hex = "<64-hex-character-ed25519-public-key>"
91
+ collector_sha256 = "<64-hex-character-executable-sha256>"
92
+ ```
93
+
94
+ Planr creates a fresh run UUID before evaluation and a fresh challenge nonce for every task. Only after the live adapter exits and Planr reads and hashes the workspace artifact does it invoke the hash-pinned collector. The collector receives a strict JSON identity request containing the Planr-owned run id, evaluation and suite identity, candidate/task/input/artifact identity, exact artifact SHA-256, and challenge nonce. It independently adds host route, usage, transition, correction, and violation measurements, then returns `{ "payload": ..., "signature_hex": "..." }`. The adapter never receives a signing key, and pre-run receipts cannot know the fresh run/challenge/artifact tuple.
95
+
96
+ Before invocation Planr verifies that the collector is a regular absolute-path file whose SHA-256 matches the selected registry entry, and it rechecks the digest for every task. It rejects the trust upgrade for a failed collector, malformed response, bad signature, wrong run/suite/time, wrong task/input/artifact/challenge binding, blank host identity, or host identity mismatch with the live adapter response. Missing or rejected receipts do not abort artifact evaluation: that result falls back to `host_reported`/`estimated`, gets zero verified route credit, and is recommendation-ineligible. Registry, signer, and collector configuration errors fail the evaluation before execution.
97
+
98
+ For a verified post-run receipt, Planr uses only signed route, usage, transition, correction, and violation values. Effective route dimensions carry `evidence = "telemetry_receipt"` and `enforcement = "verified"`; tool/token/credit dimensions and result `metering_confidence` are `trusted`; process latency remains Planr-observed. These results use `metrics_source = "trusted_telemetry"` and may satisfy recommendation gates.
99
+
100
+ ## Lifecycle and thresholds
101
+
102
+ - `recommended`: every task artifact and oracle passes, every effective route and usage measurement has a valid signed telemetry receipt, and all thresholds pass;
103
+ - `verified`: offline simulation is complete, or every required live workspace artifact and outcome oracle passed but recommendation-grade instrumentation is unavailable or a threshold failed;
104
+ - `stale`: evaluation time is later than fixture expiry;
105
+ - `incompatible`: requested host is unsupported by the binding;
106
+ - `unverified`: required composition, transition, hash, live task execution, challenge-bound artifact, or outcome-oracle evidence is incomplete.
107
+
108
+ Only independently instrumented live task evidence can set `recommendation_evidence_complete = true`. Hashing simulator-authored JSON, process stdout, or an adapter-authored route/cost claim cannot promote it.
109
+
110
+ ## Immutable output
111
+
112
+ `--report-dir` accepts only a normalized repository-relative directory and rejects absolute paths, traversal, non-directory components, and symlink crossings. It creates `verification.json` and `report.md` without overwrite; either existing target fails the command.
113
+
114
+ The report includes suite/Planr/configured-model provenance. Live results additionally include host id/version, Planr-read workspace artifact and oracle hashes, host route/usage evidence with explicit estimated or trusted provenance, observed process latency, corrections/transitions/violations, policy-capability checks, and result hashes.
115
+
116
+ ## Sol/Luna Codex contract
117
+
118
+ `evaluations/sol-luna-codex-v1.toml` independently proves that cross-tier `fork_turns = "all"` is rejected, `none` preserves Luna parameters, missing effective evidence cannot route-verify, and process-evidenced effective model/effort/fork values can verify.
@@ -0,0 +1,61 @@
1
+ # Preset Registry
2
+
3
+ Planr's registry is an optional distribution boundary, never a runtime dependency. Active projects keep using their repository-local `.planr/policy.toml`, `.planr/agents.toml`, and preset lock when the registry is unavailable. Previously imported packs remain available under `.planr/registry/cache/` for deterministic offline use.
4
+
5
+ ## Trust and integrity
6
+
7
+ A schema-v1 registry manifest identifies a registry version and one or more versioned entries. Each entry declares:
8
+
9
+ - kind (`policy`, `host-binding`, or `pack`), lifecycle (`published`, `deprecated`, or `revoked`), and evaluation status;
10
+ - Planr version bounds and compatible hosts;
11
+ - verification and review timestamps, a verification artifact, and optional replacement/revocation metadata;
12
+ - for `verified` or `recommended` entries, the exact policy, binding, and evaluation-suite ids and versions covered by that evidence;
13
+ - the normalized path, declarative kind, byte length, and SHA-256 digest of every artifact;
14
+ - an optional Ed25519 signature.
15
+
16
+ Signatures do not establish their own trust. Planr verifies them only against keys provisioned separately in `.planr/registry/trusted-maintainers.toml` (or an explicitly selected trust store):
17
+
18
+ ```toml
19
+ schema_version = 1
20
+
21
+ [[maintainers]]
22
+ id = "planr-maintainers"
23
+ public_key = "<64 hexadecimal Ed25519 public-key characters>"
24
+ revoked = false
25
+ ```
26
+
27
+ An unsigned pack can be checksum-verified, but a manifest's `recommended` claim is demoted to `verified` unless a non-revoked pinned maintainer signature verifies. A trusted signature is necessary but not sufficient: Planr also re-runs canonical policy/binding composition and safe-artifact validation, binds the shipped bytes to the current built-in evaluation inputs, and validates the current suite/task provenance. Candidate metrics and threshold gates are derived again from the task results; result hashes, task-oracle coverage, the canonical Codex dispatch contract, trusted route/metering evidence, and the report recommendation record must all agree before `recommended` survives. A merely signed status label or stale suite therefore cannot promote an entry.
28
+
29
+ Invalid signatures, revoked entries/signers, incompatible Planr/host constraints, checksum/size mismatches, traversal, symlinks, binary or executable content, secret-like content, semantically invalid bindings, and malformed declarative artifacts fail closed. Every registry policy, including an `experimental` entry without evaluation metadata, uses the same public-distribution safety check: commands, hooks, environment grants, network/MCP access, secret references, and overwrite permission are rejected. Manifest ids, versions, hosts, references, reasons, paths, and signer metadata are screened field-by-field for secret-like values before they can reach diagnostics; public keys and signature bytes are shape-validated but deliberately not classified as secrets. Stale verification or deprecation remains visible and removes recommendation.
30
+
31
+ ## Verification and offline import
32
+
33
+ Remote retrieval is deliberately outside the command. Downloading a manifest and its content is an explicit operator action; Planr then verifies local inputs:
34
+
35
+ ```sh
36
+ planr agents preset registry verify registry.toml \
37
+ --entry balanced-codex \
38
+ --content-root ./download \
39
+ --host codex
40
+ ```
41
+
42
+ `--host` may be omitted only for entries whose `compatible_hosts` list is empty. A constrained entry with no explicit host fails closed.
43
+
44
+ Import is preview-first. The preview lists exactly the manifest-declared files and deterministic cache target. `--confirm` copies only those verified files into a manifest-hash-addressed immutable directory and atomically stores both the original registry manifest and a cache receipt:
45
+
46
+ ```sh
47
+ planr agents preset registry import registry.toml \
48
+ --entry balanced-codex \
49
+ --content-root ./download \
50
+ --host codex
51
+
52
+ planr agents preset registry import registry.toml \
53
+ --entry balanced-codex \
54
+ --content-root ./download \
55
+ --host codex \
56
+ --confirm
57
+ ```
58
+
59
+ `planr agents preset registry list` requires no source manifest or network. The mutable receipt is inventory metadata, not a checksum or trust authority. Every read binds the cache path to the stored manifest hash, re-verifies the original manifest and maintainer signature against the repository trust store, compares receipt inventory with the manifest, and recomputes artifact sizes and hashes from the manifest. Coordinated edits to content and receipt therefore remain detectable. The command reports `current` or `stale` freshness from the review timestamp and marks malformed or tampered cache entries unusable. Extra source files are never imported.
60
+
61
+ The equivalent MCP tools are `planr_preset_registry_verify`, `planr_preset_registry_import`, and `planr_preset_registry_list`. MCP import also previews unless `confirm` is true.
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "tools": [
3
3
  "planr_project_show",
4
+ "planr_trace_item",
4
5
  "planr_map_show",
5
6
  "planr_map_status",
6
7
  "planr_map_preview",
@@ -19,6 +20,15 @@
19
20
  "planr_item_amend",
20
21
  "planr_item_replan",
21
22
  "planr_agents_list",
23
+ "planr_presets_list",
24
+ "planr_preset_evaluate",
25
+ "planr_preset_apply",
26
+ "planr_preset_registry_verify",
27
+ "planr_preset_registry_import",
28
+ "planr_preset_registry_list",
29
+ "planr_policy_show",
30
+ "planr_policy_check",
31
+ "planr_policy_admit",
22
32
  "planr_item_route",
23
33
  "planr_item_route_set",
24
34
  "planr_item_route_clear",
@@ -99,7 +109,13 @@
99
109
  "planr recover sweep",
100
110
  "planr agents list",
101
111
  "planr agents check",
112
+ "planr agents preset list",
113
+ "planr agents preset apply",
114
+ "planr agents preset registry verify",
115
+ "planr agents preset registry import",
116
+ "planr agents preset registry list",
102
117
  "planr item route",
118
+ "planr trace item",
103
119
  "planr serve --port"
104
120
  ]
105
121
  }