planr 1.5.1 → 1.6.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.
package/README.md CHANGED
@@ -54,7 +54,7 @@ Manual downloads, from-source builds, and client wiring details: [Install Guide]
54
54
 
55
55
  ## Install The Plugin (Skills)
56
56
 
57
- The plugin under `plugins/planr` carries the ten Planr workflow skills. Optional model-routing roles come from repository-local routing bundles. The `planr` CLI (above) is required separately.
57
+ 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.
58
58
 
59
59
  <a id="install-plugin-codex"></a>
60
60
  <details>
@@ -112,7 +112,7 @@ planr prompt cli
112
112
 
113
113
  ## Tell Your Agent
114
114
 
115
- Remember one public entry point: `$planr`. It routes the request from live Planr state, including planning-only work and autonomous-goal preparation. Stage skills are advanced surfaces selected by the router.
115
+ Remember one public entry point: `$planr`. It routes ordinary planning and status work from live Planr state. For long autonomous runs, use the explicit two-step workflow: `$planr-goal` prepares durable state, then `$planr-loop` executes the resulting plan.
116
116
 
117
117
  Start a new product from an idea:
118
118
 
@@ -126,7 +126,7 @@ split an MVP build plan, check it, then build the Planr map. Do not implement ye
126
126
  For a long autonomous run, prepare outside the driver first. The preparation result prints a real plan id; Codex or Claude Code then starts only the plan-bound loop driver:
127
127
 
128
128
  ```text
129
- Use $planr to prepare an autonomous goal for the weekly overview feature.
129
+ Use $planr-goal to prepare an autonomous goal for the weekly overview feature.
130
130
 
131
131
  /goal Use $planr-loop on plan <plan-id>. The loop contract is stored in planr
132
132
  context (tag: goal-contract).
@@ -136,11 +136,24 @@ with log evidence, all reviews are closed complete, and a live verification log
136
136
  the feature working in the browser. Iteration budget: 10.
137
137
  ```
138
138
 
139
- Mid-project work (a new feature, refactor, or fix on an existing project) works the same — it gets its own feature-scoped plan and extends the existing map. Both journeys with example prompts: [Two Journeys](docs/SKILLS.md#two-journeys-new-project-vs-existing-project). Watch progress anytime with `planr map show`.
139
+ Mid-project work (a new feature, refactor, or fix on an existing project) works the same — it gets its own feature-scoped plan and extends the existing map. Both journeys with example prompts: [Two Journeys](docs/SKILLS.md#two-journeys-new-project-vs-existing-project). Coding agents inspect progress with the compact default `planr map show` or, preferably, `planr map show --json`. The tree preserves exact dependency vocabulary while marking satisfied edges as `blocks✓`; active `blocks` stay red. The boxed `planr map show --view diagram` renderer is exclusively for human supervision and uses neutral `then` routes once those dependencies are satisfied. Agents must not invoke it. Humans can add `--full` for complete status, title, worker, critical-lane, and pressure details. Interactive map output colors states automatically; `--no-color` and `NO_COLOR` keep it plain.
140
+
141
+ To supervise an agent from a second terminal, leave the agent running in terminal A and watch its scoped graph in terminal B:
142
+
143
+ ```bash
144
+ planr map watch --plan <plan-id>
145
+ # optional: exit after every scoped item settles
146
+ planr map watch --plan <plan-id> --until-settled
147
+ # optional: inspect complete node details
148
+ planr map watch --plan <plan-id> --full
149
+ ```
150
+
151
+ The watcher is likewise a human-only observer. It defaults to the condensed diagram view, polls the local SQLite graph once per second, and redraws only when state changes. Coding agents must not invoke `map watch`; they should use `map show --json` snapshots or the `/v1/events/stream` SSE endpoint instead. Use Ctrl-C to stop.
140
152
 
141
153
  ## What's new
142
154
 
143
- - **1.5.0 — Optional routing policies:** Planr Core stays provider-neutral while the independently buildable `planr-routing` package owns model policies and host bindings for Codex, Claude Code, Cursor, and mixed-host setups. Start with [Routing Bundles](docs/ROUTING_BUNDLES.md), the [`planr-routing` guide](planr-routing/docs/MODEL_ROUTING_POLICY.md), and the [1.5.0 release notes](https://github.com/instructa/planr/releases/tag/v1.5.0).
155
+ - **1.6.0 — Human map observation:** Added a condensed boxed diagram, live two-terminal watching, accessible state colors, and clearer satisfied dependency routes. These views are intentionally for human supervision; agents keep using the default tree or JSON snapshots. See [Task Graph Model](docs/TASK_GRAPH_MODEL.md), [CLI Reference](docs/CLI_REFERENCE.md), and the [1.6.0 changelog](CHANGELOG.md#160---2026-07-21).
156
+ - **1.5.2 — Standalone core, optional Switchloom:** Planr consumes provider-neutral repository declarations and route evidence only; it works without any routing files, and requested-only routing metadata is not execution proof. Optional model-routing lifecycle is external, with [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) verified as the repository-local handoff outside Planr. Start with [Model Routing](docs/MODEL_ROUTING.md), [Switchloom](https://switchloom.ai), the [Switchloom repository](https://github.com/instructa/switchloom), its tagged [setup quickstart](https://github.com/instructa/switchloom/blob/v0.2.1/README.md#setup-from-the-website) and [lifecycle docs](https://github.com/instructa/switchloom/blob/v0.2.1/docs/preset-composition.md#repository-lifecycle-commands), and the [Changelog](CHANGELOG.md).
144
157
  - **1.4.0 — Verified presets:** Added policy-driven composition, evaluation, signed registry evidence, and the public catalog. See the [1.4.0 release notes](https://github.com/instructa/planr/releases/tag/v1.4.0).
145
158
  - **1.3.0 — Native host hooks:** Added automatic session-state injection and loop recovery for supported hosts. See the [Hooks guide](docs/HOOKS.md) and [1.3.0 release notes](https://github.com/instructa/planr/releases/tag/v1.3.0).
146
159
 
@@ -6,7 +6,7 @@ Planr V1 is a single Rust binary with explicit module ownership. The crate stays
6
6
 
7
7
  - `src/`: the Rust CLI (module ownership below).
8
8
  - `tests/e2e.rs`: real CLI, MCP, HTTP, import, review-gate, run-log, and concurrent-pick tests.
9
- - `plugins/planr/`: the installable plugin payload — all ten skills, independent Claude/Cursor worker and reviewer role assets, and the per-host plugin manifests. Native Codex role TOMLs are generated from the selected binding instead of shipped here.
9
+ - `plugins/planr/`: the installable plugin payload — all ten skills, independent Claude/Cursor worker and reviewer role assets, and the per-host plugin manifests. Planr does not ship model-pinned Codex roles.
10
10
  - `.agents/plugins/marketplace.json`, `.claude-plugin/marketplace.json`: marketplace manifests pointing Codex and Claude Code at `plugins/planr`.
11
11
  - `docs/`: user and contributor guides; `docs/planr-spec/` is the production specification package for Planr V1.
12
12
  - `examples/real-world-flow.md`: executable real-world operator flow.
@@ -43,12 +43,10 @@ Planr V1 is a single Rust binary with explicit module ownership. The crate stays
43
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
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
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/routing_bundle.rs`: provider-neutral RoutingBundle v1 contract and repository transaction boundary. Owns validation, hashes, signatures, allowlisted paths, conflict and symlink rejection, atomic apply, rollback, and application receipts.
47
- - `planr-routing/`: independently buildable workspace package that owns model policies, host bindings, generated host artifacts, probes, evaluation, signing, registry data, and catalog publication.
48
46
  - `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.
49
47
  - `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.
50
48
  - `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.
51
- - `src/rolefiles.rs`: static host workflow roles and Cursor skill payloads. It does not select or pin models; generated routing artifacts belong to `planr-routing` bundles.
49
+ - `src/rolefiles.rs`: static host workflow roles and Cursor skill payloads. It does not select or pin models; externally generated routing artifacts stay outside Planr ownership.
52
50
  - `src/util.rs`: small CLI-boundary utilities. Owns ids, timestamps, path helpers, output formatting, and safe file writes.
53
51
 
54
52
  ## Boundary Rules
@@ -13,7 +13,8 @@ planr plan check <plan-id>
13
13
  planr plan audit <plan-id>
14
14
  planr plan show <plan-id>
15
15
  planr plan archive <plan-id>
16
- planr map show [--plan <plan-id>]
16
+ planr map show [--plan <plan-id>] [--view tree|diagram] [--full]
17
+ planr map watch [--plan <plan-id>] [--view tree|diagram] [--full] [--interval-ms 1000] [--no-clear] [--until-settled]
17
18
  planr map build --from <plan-id>
18
19
  planr map lane --critical
19
20
  planr map pressure
@@ -67,9 +68,6 @@ planr agents init [--force]
67
68
  planr agents init --profile|--skill|--route|--default-route|--interactive
68
69
  planr agents list [--json]
69
70
  planr agents check
70
- planr routing bundle inspect <bundle.json>
71
- planr routing bundle preview <bundle.json>
72
- planr routing bundle apply <bundle.json>
73
71
  planr doctor [--client codex|claude|cursor|all]
74
72
  planr install codex|claude|cursor [--dry-run] [--no-mcp] [--force] [--no-hooks]
75
73
  planr prompt cli|mcp|http [--client codex|claude|cursor|all]
@@ -80,7 +78,7 @@ planr import <file> [--preview] [--confirm]
80
78
  planr export --out planr.json [--include-plans] [--include-logs] [--template-name "..."] [--tag tag]
81
79
  ```
82
80
 
83
- Global flags: `--db <path>`, `--json`, `--no-color`. They are valid in both positions: `planr --json pick` and `planr pick --json` behave identically.
81
+ Global flags: `--db <path>`, `--json`, `--no-color`. They are valid in both positions: `planr --json pick` and `planr pick --json` behave identically. Human map output uses ANSI status colors only when stdout is an interactive terminal. `--no-color`, `NO_COLOR` (even when empty), `TERM=dumb`, redirected stdout, and JSON disable color; `PLANR_FORCE_COLOR=1` is available for compatible terminal wrappers and tests, but never overrides an explicit opt-out.
84
82
 
85
83
  ## JSON Envelope Convention
86
84
 
@@ -97,7 +95,11 @@ With `--json`, responses follow one convention so agents never guess where data
97
95
 
98
96
  `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`.
99
97
 
100
- `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>`.
98
+ `map show` defaults to the compact `tree` view used by agents and existing terminal workflows; coding agents should prefer `map show --json` when they need structured state. The tree keeps the canonical edge vocabulary visible: active dependencies render as red `blocks`, while an edge satisfied by a `closed` or `closed_partial` upstream renders as dim `blocks✓`. `map show --view diagram` is exclusively a human-supervision view and coding agents must not invoke it. It provides fixed-width boxes with at most two content lines in `ICON ITEM-ID TITLE` form, translating satisfied `blocks` edges to neutral `then` while active or cancelled blockers remain `blocks`; `hands_to`, joins, disconnected components, and cycle warnings remain explicit. Humans can add `--full` for verbose nodes with status words, complete wrapped titles, active workers, critical-lane markers, and downstream pressure. `--full` is rejected with tree view. This is a read-only presentation over the same canonical map projection; JSON/MCP/HTTP always retain the stored `kind: "blocks"` and are identical across diagram detail choices.
99
+
100
+ `map show --plan <plan-id>` narrows either human view 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>`.
101
+
102
+ `map watch` is the read-only live companion for a second human terminal. Coding agents must not invoke it; they should use `map show --json` snapshots or `planr serve` plus `/v1/events/stream`. Watch defaults to the condensed `--view diagram`, polls every 1000 ms, compares the canonical scoped projection, and clears/redraws an interactive terminal only when graph state changes. `--full`, `--view tree`, `--plan <plan-id>`, `--interval-ms <n>` (minimum 100), `--no-clear`, and `--until-settled` control presentation and lifetime; Ctrl-C uses normal process interruption. JSON mode remains rejected because watch is intentionally human-only.
101
103
 
102
104
  `context list --tag <tag>` filters notes by the tag they were stored with (`context add --tag`), so e.g. the goal contract is recoverable with `planr context list --tag goal-contract` instead of scanning all notes.
103
105
 
@@ -141,8 +143,6 @@ With `--json`, responses follow one convention so agents never guess where data
141
143
 
142
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.
143
145
 
144
- `routing bundle inspect|preview|apply` is Planr Core's only policy-package boundary. It accepts RoutingBundle v1, validates payload hashes, restricts targets to allowlisted repository-local paths, rejects traversal, symlinks, parent/child collisions, conflicts, and unsupported versions, and applies the validated set atomically. Signed bundles require both `--trusted-signer` and an external `--trusted-public-key-file`; a key embedded beside the content is never trusted. It never edits user configuration. Named policies, model ids, host bindings, evaluation, signing, and catalog operations are provided by the optional `planr-routing` package. See [Routing Bundles](ROUTING_BUNDLES.md).
145
-
146
146
  `agents init` writes a provider-neutral `.planr/agents.toml` scaffold or compiles explicit profile and route flags. `agents list` and `agents check` inspect it, while pick packets carry the resolved opaque profile, host, model, effort, tier, skill, route chain, and matched selector. Full guide: [Model Routing](MODEL_ROUTING.md).
147
147
 
148
148
  `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.
package/docs/CODEX.md CHANGED
@@ -22,15 +22,13 @@ $planr-goal <your goal>
22
22
 
23
23
  The stop condition lives in Planr (`--tag goal-contract`), so a dead session resumes with the same starter line from zero chat context.
24
24
 
25
- Optionally compile and apply a repository-local Codex routing bundle before starting the driver:
25
+ Optionally prepare repository-local routing declarations before starting the driver. Planr reads `.planr/agents.toml` and `.planr/policy.toml`; external tools such as [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) own any generated roles, application, or uninstall lifecycle:
26
26
 
27
27
  ```bash
28
- planr-routing compile balanced --host codex-openai --output routing-bundle.json
29
- planr routing bundle preview routing-bundle.json
30
- planr routing bundle apply routing-bundle.json
28
+ planr agents check
31
29
  ```
32
30
 
33
- The bundle generates repository-local roles and a routing skill. Follow that generated skill exactly, restart after role changes, and confirm child metadata reports the expected model, effort, role path, and context-fork behavior. Full workflow: [Long-Running Goals](GOALS.md).
31
+ Follow any externally generated repository role instructions outside Planr, restart after role changes when your host requires it, and confirm child metadata reports the expected model, effort, role path, and context-fork behavior. Full workflow: [Long-Running Goals](GOALS.md).
34
32
 
35
33
  ## MCP
36
34
 
@@ -53,12 +53,11 @@ planr agents check
53
53
  planr agents list
54
54
  ```
55
55
 
56
- Alternatively, an external policy package can compile a strict RoutingBundle v1. Preview and apply it through the generic Core boundary:
56
+ Alternatively, an external routing tool such as [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) can manage repository-local declarations and host roles outside Planr. After that external lifecycle step, Planr still sees only provider-neutral declarations:
57
57
 
58
58
  ```bash
59
- planr routing bundle inspect routing-bundle.json
60
- planr routing bundle preview routing-bundle.json
61
- planr routing bundle apply routing-bundle.json
59
+ planr agents check
60
+ planr agents list --json
62
61
  ```
63
62
 
64
63
  ## 2. Tag items by use case
@@ -101,4 +100,4 @@ planr trace item <item-id>
101
100
 
102
101
  A mismatch is recorded as advisory evidence instead of silently rewritten. Missing effective-host evidence stays unavailable and is never inferred from the registry.
103
102
 
104
- One-off exceptions use `planr item route <id> --set <profile>`; `--clear` restores policy resolution. See [Model Routing](MODEL_ROUTING.md) and [Routing Bundles](ROUTING_BUNDLES.md).
103
+ One-off exceptions use `planr item route <id> --set <profile>`; `--clear` restores policy resolution. See [Model Routing](MODEL_ROUTING.md) and [External Routing Declarations](ROUTING_BUNDLES.md).
package/docs/GOALS.md CHANGED
@@ -87,15 +87,13 @@ Iteration 1 reads the map and the stored contract: items already settled stay se
87
87
 
88
88
  ### Codex with `/goal`
89
89
 
90
- Install the plugin, initialize the repository, and optionally apply a repository routing bundle:
90
+ Install the plugin and initialize the repository. Optional routing declarations are repository-local and may be edited directly or managed by an external tool such as [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) before the run:
91
91
 
92
92
  ```bash
93
93
  codex plugin marketplace add instructa/planr
94
94
  codex plugin add planr@planr
95
95
  planr project init "My Product"
96
- planr-routing compile balanced --host codex-openai --output routing-bundle.json
97
- planr routing bundle preview routing-bundle.json
98
- planr routing bundle apply routing-bundle.json
96
+ planr agents check
99
97
  ```
100
98
 
101
99
  Then:
@@ -105,7 +103,7 @@ $planr-goal <your goal> # prep: plan, map, contract, starter command
105
103
  /goal Use $planr-loop on plan <plan-id>. The loop contract is stored in planr context (tag: goal-contract).
106
104
  ```
107
105
 
108
- When a routing bundle is applied, the `/goal` PM follows its generated repository skill and roles. The bundle owner decides exact models, effort, role names, and fork policy; Planr only carries the resulting opaque route in pick packets. Codex Automations use the same starter line.
106
+ When repository routing declarations exist, the `/goal` PM treats them as advisory dispatch input. The external routing owner decides exact models, effort, role names, fallback policy, and lifecycle; Planr only carries the resulting opaque route in pick packets and records observed evidence when workers provide it. Codex Automations use the same starter line.
109
107
 
110
108
  ### Claude Code
111
109
 
@@ -147,7 +145,7 @@ Any MCP-capable agent uses the same flow over `planr mcp`. Every session starts
147
145
 
148
146
  A goal run has distinct roles with different intelligence needs. Planr represents those decisions as opaque profiles and routes; it does not choose providers, models, effort levels, fallback chains, or host-native role names.
149
147
 
150
- An optional routing-policy package can map planning, exploration, implementation, mechanical work, and independent review onto different cost or quality tiers. If a routing bundle generated repository roles, follow its generated instructions and verify effective child metadata because declarations alone are not proof. The official package and its host-specific caveats live under [`planr-routing`](../planr-routing/docs/MODEL_ROUTING_POLICY.md); the Core contract is documented in [Model Routing](MODEL_ROUTING.md).
148
+ An optional external routing tool can map planning, exploration, implementation, mechanical work, and independent review onto different cost or quality tiers. If [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) or another repository-local process writes routing declarations or host roles, follow that tool's generated instructions outside Planr and verify effective child metadata because declarations alone are not proof. The Core contract is documented in [Model Routing](MODEL_ROUTING.md).
151
149
 
152
150
  ## Coming From Other Goal Tools
153
151
 
package/docs/INSTALL.md CHANGED
@@ -72,7 +72,7 @@ planr prompt cli --client codex
72
72
  planr prompt http
73
73
  ```
74
74
 
75
- `planr install codex` writes a project MCP snippet and project hooks; its workflow skills come from the Codex plugin, and it writes no project roles or skills. `planr install claude` writes project `.mcp.json`, standalone worker/reviewer roles, and hooks; workflow skills come from the Claude Code plugin. `planr install cursor` writes project MCP, roles, all ten skills, and hooks, then prints an optional user-level MCP deeplink. Optional model pins come from a repository-local routing bundle. Dry-runs print the complete repository artifact and hook-reconciliation paths without writing them; no command silently edits global user configuration.
75
+ `planr install codex` writes a project MCP snippet and project hooks; its workflow skills come from the Codex plugin, and it writes no project roles or skills. `planr install claude` writes project `.mcp.json`, standalone worker/reviewer roles, and hooks; workflow skills come from the Claude Code plugin. `planr install cursor` writes project MCP, roles, all ten skills, and hooks, then prints an optional user-level MCP deeplink. Optional model pins come from repository-local routing declarations managed outside Planr. Dry-runs print the complete repository artifact and hook-reconciliation paths without writing them; no command silently edits global user configuration.
76
76
 
77
77
  `--no-mcp` skips only the project MCP artifact. Codex then reconciles hooks only; Claude Code writes standalone project roles and hooks but no project skills; Cursor writes project roles, skills, and hooks. Add `--no-hooks` to skip hooks as well. The Codex and Claude Code plugins remain the owners of their workflow skills.
78
78
 
@@ -87,7 +87,7 @@ Open `http://127.0.0.1:7526/review` after `planr serve` for the local browser re
87
87
 
88
88
  ## Agent Skills And Plugin
89
89
 
90
- The repository ships a plugin under `plugins/planr` for Codex and Claude Code that bundles all ten workflow skills; Claude Code additionally registers plugin worker/reviewer agents. The Codex plugin does not register project agents. Cursor receives the ten skills and both project agents through `planr install cursor` (or its plugin manifest). Model-specific role files are optional routing-bundle artifacts. The CLI above must be installed separately. See [Skills](SKILLS.md).
90
+ The repository ships a plugin under `plugins/planr` for Codex and Claude Code that bundles all ten workflow skills; Claude Code additionally registers plugin worker/reviewer agents. The Codex plugin does not register project agents. Cursor receives the ten skills and both project agents through `planr install cursor` (or its plugin manifest). Model-specific role files are optional repository-local artifacts owned by external routing lifecycle. The CLI above must be installed separately. See [Skills](SKILLS.md).
91
91
 
92
92
  ## From Source
93
93
 
@@ -42,7 +42,7 @@ Required groups:
42
42
  - artifact add, list, and show
43
43
  - event list and debug bundle preview
44
44
  - trace item, log add, and log read (including three-stage route observations)
45
- - provider-neutral RoutingBundle v1 inspection, repository-safe preview/apply, and durable application evidence
45
+ - provider-neutral agent registry reads and route overrides
46
46
  - review annotate, ingest, artifact, evidence, and close
47
47
  - item close, context create, and search
48
48
 
@@ -28,12 +28,6 @@ Resolution order is per-item override, work type, plan, then default route. Unkn
28
28
 
29
29
  Workers may report observed routing with logs and route-audit evidence. Requested-only values never become effective proof; missing effective evidence remains explicitly unavailable.
30
30
 
31
- Host-specific model policies and generated repository roles are optional. The `planr-routing` workspace package compiles them into RoutingBundle v1, and Core safely previews and applies that bundle:
31
+ Host-specific model policies, generated repository roles, and uninstall/application lifecycle are external to Planr. [Switchloom](https://switchloom.ai) [v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1) can manage repository-local routing artifacts from its [repository](https://github.com/instructa/switchloom), [setup quickstart](https://github.com/instructa/switchloom/blob/v0.2.1/README.md#setup-from-the-website), and [repository lifecycle docs](https://github.com/instructa/switchloom/blob/v0.2.1/docs/preset-composition.md#repository-lifecycle-commands), but Planr does not install, invoke, compile, apply, or uninstall Switchloom output. After an external tool or operator changes `.planr/agents.toml` or `.planr/policy.toml`, run `planr agents check` and capture observed route evidence through `planr log add` or `planr done`.
32
32
 
33
- ```bash
34
- planr-routing compile balanced --host codex-openai --output routing-bundle.json
35
- planr routing bundle preview routing-bundle.json
36
- planr routing bundle apply routing-bundle.json
37
- ```
38
-
39
- Bundle application is restricted to the repository. Planr never edits user configuration such as `~/.codex/config.toml`. See [Routing Bundles](ROUTING_BUNDLES.md).
33
+ The hard boundary is provider-neutral: Planr consumes declarations and evidence; hosts and external routing tools decide whether any requested model, effort, role, or fallback actually ran. See [External Routing Declarations](ROUTING_BUNDLES.md).
@@ -1,32 +1,15 @@
1
- # Routing bundles
1
+ # External routing declarations
2
2
 
3
- Planr Core is provider-neutral. It parses `.planr/agents.toml`, resolves routes into pick packets, records declared-versus-observed evidence, and safely previews or applies a strict RoutingBundle v1:
3
+ Planr Core is provider-neutral. It parses `.planr/agents.toml`, resolves routes into pick packets, records declared-versus-observed evidence, and checks `.planr/policy.toml`. It does not own a bundle format, catalog, compiler, signer, installer, or uninstaller.
4
4
 
5
- ```bash
6
- planr routing bundle inspect routing-bundle.json
7
- planr routing bundle preview routing-bundle.json
8
- planr routing bundle apply routing-bundle.json
9
- ```
10
-
11
- Core accepts only allowlisted repository-local targets, verifies payload hashes, rejects absolute paths, traversal, symlinks, parent/child target collisions, conflicts, unsupported versions, and invalid payloads, and applies the validated set atomically. It never writes user configuration or files outside the repository.
12
-
13
- A signed bundle is accepted only with an independent trust anchor supplied to every inspect, preview, or apply call:
5
+ The current boundary is repository-local declaration plus evidence:
14
6
 
15
7
  ```bash
16
- planr routing bundle inspect signed-bundle.json \
17
- --trusted-signer planr-maintainers \
18
- --trusted-public-key-file /absolute/path/to/maintainer.pub
8
+ planr agents init
9
+ planr agents check
10
+ planr agents list --json
19
11
  ```
20
12
 
21
- The bundle contains the signer id and signature, not a self-trusted public key. Both trust flags are required together; unsigned bundles require neither. An unsigned bundle also cannot label its evidence `verified` or `recommended`.
22
-
23
- The `planr-routing` workspace package owns all volatile opinions: named policies, exact model ids, host bindings, generated role and skill files, capability probes, evaluation scenarios, signing, registry data, and the website catalog. A normal flow is:
24
-
25
- ```bash
26
- planr-routing policy list
27
- planr-routing compile balanced --host codex-openai --output routing-bundle.json
28
- planr routing bundle preview routing-bundle.json
29
- planr routing bundle apply routing-bundle.json
30
- ```
13
+ External tools, including Switchloom v0.2.1, may create, update, apply, or uninstall repository-local routing artifacts. Those lifecycle operations happen outside Planr. Planr only consumes the resulting provider-neutral declarations and the route observations workers attach to logs.
31
14
 
32
- The package emits the same provider-neutral bundle contract for Codex, Claude Code, Cursor, and mixed-host configurations. Offline evaluation remains experimental; a recommendation requires complete authenticated live-host evidence. Missing authentication or missing effective model, effort, role, or context-fork evidence cannot pass.
15
+ Because declarations are advisory, requested model values never become proof by themselves. Strong evidence keeps requested, host-resolved, and effective execution separate in route observations, with `unavailable` used when the host cannot prove what ran.
package/docs/SKILLS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Planr ships agent-facing skill templates under `plugins/planr/skills/`.
4
4
 
5
- The repository ships an installable plugin under `plugins/planr` for Codex and Claude Code, while Cursor receives the same skills through `planr install cursor`. Marketplace manifests at the repo root (`.agents/plugins/marketplace.json`, `.claude-plugin/marketplace.json`) point at that subdirectory — Codex silently ignores marketplaces whose plugin source is the repo root itself. The shared package carries skills and Claude's independent workflow roles; optional model-specific host roles come only from a repository-local routing bundle, never from Planr Core or static fallbacks. The `planr` CLI must be installed separately (`brew install instructa/tap/planr`).
5
+ The repository ships an installable plugin under `plugins/planr` for Codex and Claude Code, while Cursor receives the same skills through `planr install cursor`. Marketplace manifests at the repo root (`.agents/plugins/marketplace.json`, `.claude-plugin/marketplace.json`) point at that subdirectory — Codex silently ignores marketplaces whose plugin source is the repo root itself. The shared package carries skills and Claude's independent workflow roles; optional model-specific host roles come from repository-local routing declarations managed outside Planr, never from Planr Core or static fallbacks. The `planr` CLI must be installed separately (`brew install instructa/tap/planr`).
6
6
 
7
7
  ## Install As Plugin (preferred)
8
8
 
@@ -84,7 +84,7 @@ Do not implement yet. End with the build plan id, critical lane, and first ready
84
84
  Example autonomous feature loop (two separate prompts):
85
85
 
86
86
  ```text
87
- Use $planr to prepare an autonomous goal for the weekly overview feature.
87
+ Use $planr-goal to prepare an autonomous goal for the weekly overview feature.
88
88
 
89
89
  /goal Use $planr-loop on plan <plan-id>. The loop contract is stored in planr
90
90
  context (tag: goal-contract).
@@ -146,7 +146,7 @@ What the router does with that, and why:
146
146
  Or autonomous in two prompts:
147
147
 
148
148
  ```text
149
- Use $planr to prepare an autonomous goal for the auth system.
149
+ Use $planr-goal to prepare an autonomous goal for the auth system.
150
150
 
151
151
  /goal Use $planr-loop on plan <plan-id>. The loop contract is stored in planr
152
152
  context (tag: goal-contract).
@@ -176,7 +176,7 @@ planr install claude # provisions Claude's independent
176
176
  planr install cursor # provisions Cursor's independent roles and skills
177
177
  ```
178
178
 
179
- Optional project-scoped model-routing files are generated by `planr-routing` bundles. Core workflow skills remain host-neutral, and bundle application never overwrites conflicts or writes user configuration.
179
+ Optional project-scoped model-routing files are repository-local declarations. They may be edited directly or managed by an external tool such as [Switchloom v0.2.1](https://github.com/instructa/switchloom/releases/tag/v0.2.1); Core workflow skills remain host-neutral, and Planr does not install, invoke, apply, or uninstall external routing artifacts.
180
180
 
181
181
  Dispatches stay one line: `Use $planr-work on item <id>` and `Use $planr-review on item <id>`. The map and logs are the loop memory, so any iteration can resume from zero context.
182
182
 
@@ -60,6 +60,12 @@ planr link add <design-item> <implementation-item> --type blocks
60
60
 
61
61
  Use `blocks` for hard ordering. Use softer link types only when the product contract for that type is documented and tested.
62
62
 
63
+ Structured output always keeps that canonical `blocks` kind. Human rendering adds
64
+ current satisfaction state without mutating it: an upstream `closed` or
65
+ `closed_partial` item renders as dim `blocks✓` in the compact tree and neutral `then`
66
+ in the human-only diagram. Open, failed, and cancelled upstream items still render as
67
+ red `blocks`; cancellation does not satisfy readiness.
68
+
63
69
  ## Picking
64
70
 
65
71
  Picking is the concurrency boundary:
@@ -155,6 +161,50 @@ Settling commands (`done`, `close`, `review close`) report what they `unlocked`
155
161
 
156
162
  ## Graph Inspection
157
163
 
164
+ Coding agents use the compact default tree or `map show --json`. They must not
165
+ invoke the diagram renderer. The boxed workflow diagram is exclusively for a
166
+ person scanning the graph shape and current state:
167
+
168
+ ```bash
169
+ planr map show
170
+ planr map show --view diagram
171
+ planr map show --plan <plan-id> --view diagram
172
+ planr map show --plan <plan-id> --view diagram --full
173
+ ```
174
+
175
+ The default diagram keeps every box to at most two content lines in
176
+ `ICON ITEM-ID → TITLE` form. It still labels readiness-blocking routes, joins,
177
+ disconnected components, and cycles. Active dependencies use `blocks`; satisfied
178
+ dependencies use neutral `then`. Add `--full` for the previous verbose node
179
+ layout with status words, complete wrapped titles, critical items, downstream
180
+ pressure, and active workers. It is only a human renderer: coding agents do not
181
+ invoke it, the SQLite map
182
+ remains authoritative, the default `map show` view stays `tree`, and `--json`
183
+ returns the same projection regardless of diagram detail.
184
+
185
+ Human map states are colorized automatically on an interactive terminal while
186
+ retaining their symbols and words. `--no-color`, `NO_COLOR`, `TERM=dumb`, pipes,
187
+ and JSON stay plain.
188
+
189
+ For a person to observe an agent live, use a second terminal:
190
+
191
+ ```bash
192
+ # terminal A: agent/worker continues to pick, log, review, and close work
193
+ # terminal B:
194
+ planr map watch --plan <plan-id>
195
+ planr map watch --plan <plan-id> --until-settled
196
+ planr map watch --plan <plan-id> --full
197
+ ```
198
+
199
+ `map watch` is human-only; coding agents must not invoke it. Watch defaults to
200
+ the condensed diagram, polls once per second, and redraws only
201
+ after a canonical graph change. `--full`, `--view tree`, `--interval-ms`, and
202
+ `--no-clear` are available for detailed, compact-tree, or append-only
203
+ observation. It records no graph events. Agents use `map show --json` or the
204
+ local `/v1/events/stream` SSE endpoint instead.
205
+ Machine consumers should use JSON snapshots or the local
206
+ `/v1/events/stream` SSE endpoint.
207
+
158
208
  Use critical lane for ordering risk:
159
209
 
160
210
  ```bash
@@ -13,7 +13,7 @@ When sources disagree, authors must use this order and disclose the disagreement
13
13
  1. **Product intent and invariants:** `AGENTS.md` and `docs/planr-spec/`, especially `PRODUCT_SPEC.md`, `TECH_ARCHITECTURE.md`, and `API_AND_DATA_MODEL.md`.
14
14
  2. **Released executable behavior:** compiled `planr --help` output, `src/cli.rs`, `src/app/mcp.rs`, `src/app/http.rs`, `src/model.rs`, and the tested fixture `docs/fixtures/mcp-contract.json`. Runtime sources decide whether a command, option, schema, endpoint, state, or error exists in the current release.
15
15
  3. **Distribution contract:** `Cargo.toml`, `package.json`, `pnpm-workspace.yaml`, release workflows, installers, and release tests. These decide supported versions, artifacts, operating systems, and install commands.
16
- 4. **Existing explanatory material:** `README.md`, `docs/*.md`, `plugins/planr/skills/`, examples, and routing-package docs. These are migration inputs, not independent sources of truth.
16
+ 4. **Existing explanatory material:** `README.md`, `docs/*.md`, `plugins/planr/skills/`, and examples. These are migration inputs, not independent sources of truth.
17
17
  5. **External references:** official upstream documentation and inspected local projects may influence structure and implementation, but never define Planr behavior.
18
18
 
19
19
  If product intent is ahead of runtime, the public page must label the behavior as planned or omit it from executable instructions. If runtime is ahead of an older specification sentence, the public page documents the tested runtime and the discrepancy is added to the conflict register below.
@@ -41,7 +41,7 @@ Use these terms exactly. Prefer the lowercase form in prose unless it starts a s
41
41
  | artifact | Item-linked or project evidence such as a report, screenshot, or review file. | attachment when referring to the stored object |
42
42
  | recovery sweep | A preview/apply operation for stale, timed-out, and retryable work. | automatic retry loop |
43
43
  | package | A reusable export/import bundle of graph and optional Planr artifacts. | backup unless that is the user's intent |
44
- | routing bundle | A provider-neutral, validated set of repository-local routing artifacts. | model config |
44
+ | routing declaration | Provider-neutral repository data in `.planr/agents.toml` or `.planr/policy.toml`. | model config |
45
45
  | goal contract | Durable Planr context defining the completion oracle and stop condition. | prompt-only instruction |
46
46
 
47
47
  The canonical lifecycle is always:
@@ -92,11 +92,11 @@ Use Next.js 16 App Router, Fumadocs MDX, and content under `apps/docs/content/do
92
92
  Rejected for this scope:
93
93
 
94
94
  - TanStack Start: AgentRig proves it is viable, but it adds routing/build decisions that Planr does not otherwise own and is not needed for a documentation-only app.
95
- - A bespoke Rust-rendered site or the `planr-routing/website` static implementation: neither supplies the requested polished docs authoring/search system.
95
+ - A bespoke Rust-rendered site or an external routing-catalog static implementation: neither supplies the requested polished docs authoring/search system.
96
96
 
97
- ### DOC-ADR-003: Deploy with Alchemy and OpenNext on Cloudflare Workers
97
+ ### DOC-ADR-003: Deploy direct static assets with Alchemy on Cloudflare
98
98
 
99
- Use an Alchemy v2 Effect stack and OpenNext as the committed deployment owner. `Cloudflare.Website.StaticSite` runs the OpenNext build, uploads its prebuilt Worker with `bundle: false`, and serves the generated assets. Bind `docs.planr.so` only when the Alchemy stage is `prod`; development and preview stages use generated URLs. The Cloudflare zone must already exist in the authenticated account. Local credentials live in the Alchemy profile, shared state uses `Cloudflare.state()`, and CI verifies the OpenNext Worker artifact without deploying it.
99
+ Use an Alchemy v2 Effect stack as the committed deployment owner. Next.js exports every human and agent-readable route, Fumadocs search runs from a build-time Orama database in the browser, and `Cloudflare.Website.StaticSite` serves normal pages and files directly. A tiny edge worker is limited to exact legacy aliases and machine-readable Markdown, search, and LLM paths; it redirects, fixes content types, or delegates immediately to the asset binding. Bind `planr.so` only when the Alchemy stage is `prod`; development and preview stages use generated URLs. The Cloudflare zone must already exist in the authenticated account. Local credentials live in the Alchemy profile, shared state uses `Cloudflare.state()`, and CI verifies the complete static artifact and Wrangler configuration without deploying it. This avoids making public documentation availability depend on a paid application Worker CPU allowance.
100
100
 
101
101
  ### DOC-ADR-004: Use Fumadocs primitives before copying components
102
102
 
@@ -137,7 +137,7 @@ These findings are explicit inputs to implementation and content review.
137
137
  | --- | --- | --- |
138
138
  | GAP-001 | `docs/CLI_REFERENCE.md` says it is generated from help but omits current commands including `project delete`, `plan list`, `map export/import`, `item show/cancel`, `link remove`, `log show/list`, `review request/list/show`, `note`, and `scrub`. | Replace the list with generated/mechanically checked reference data; retain editorial detail around it. |
139
139
  | GAP-002 | `docs/planr-spec/PRODUCT_SPEC.md` still calls Rust and the HTTP server open decisions, but the repository ships a Rust binary and `planr serve`. | Document current released behavior; update product specs only in a separately scoped product-spec change. |
140
- | GAP-003 | `docs/ARCHITECTURE.md` describes one crate and one deployable while the root Cargo workspace includes the independent `planr-routing` member/package. | The architecture page must describe Planr Core and optional `planr-routing` ownership separately. |
140
+ | GAP-003 | Resolved on 2026-07-18: `docs/ARCHITECTURE.md` now describes Planr as one Rust binary plus wrappers/docs, with provider-neutral routing declarations owned in Core and external routing lifecycle outside Planr. | Keep architecture ownership aligned with current runtime modules and do not reintroduce routing-package ownership wording. |
141
141
  | GAP-004 | README leads with Homebrew, while `docs/INSTALL.md` calls GitHub Releases/repo installer canonical and Homebrew preferred day-to-day. | Say “Homebrew recommended on macOS”; GitHub Releases are the canonical artifact source; npm is the cross-package-manager native-binary path. |
142
142
  | GAP-005 | The CLI npm wrapper supports Node 18, while latest Fumadocs requires Node 22. | Keep separate requirement callouts: Planr CLI Node 18; docs contributors Node 22. |
143
143
  | GAP-006 | Product personas mention Gemini CLI and generic clients, but install helpers exist only for Codex, Claude Code, and Cursor. | Give the three supported clients first-class setup pages; route Gemini/opencode/other tools through clearly labeled generic CLI or stdio MCP instructions. Do not imply a native installer. |
@@ -148,7 +148,7 @@ These findings are explicit inputs to implementation and content review.
148
148
  | GAP-011 | The requested AgentRig path is stale. | Use `agentrig-public/apps/docs` only as recorded prior art; never make it a build dependency. |
149
149
  | GAP-012 | Windows native assets are not in the public install contract. | Installation clearly labels macOS/Linux native support and WSL/source alternatives; no unsupported Windows-native promise. |
150
150
  | GAP-013 | `opencode` appears in README but is not a first-class install target. | Include it only as an example on the generic CLI/MCP page, with no plugin or installer guarantee. |
151
- | GAP-014 | The optional `planr-routing` package has its own CLI, catalog, policies, bindings, and website artifacts outside the core CLI reference. | Give routing its own concept/guide/reference pages and label the package optional. |
151
+ | GAP-014 | Resolved on 2026-07-18: Planr no longer documents a routing package CLI, catalog, compiler, bundle, or application lifecycle as current product surface. | Document only provider-neutral declarations, policy checks, pick-packet routing, and route evidence; external tools such as Switchloom remain outside Planr execution. |
152
152
 
153
153
  ## Explicit exclusions
154
154
 
@@ -77,7 +77,7 @@ The executable and schema sources decide exact inventory. Editorial pages explai
77
77
  | Rust, docs, semantic, browser, accessibility gates | tests, scripts, CI workflows | `/docs/contributing/testing` |
78
78
  | Product release and publication | `scripts/release.sh`, release workflow, `docs/RELEASE.md` | `/docs/operations/release` |
79
79
  | Version synchronization and SQLite upgrades | release script, manifests, `src/storage/schema.rs` | `/docs/operations/versioning-and-migrations` |
80
- | Alchemy/OpenNext docs build and Cloudflare deployment | `apps/docs/alchemy.run.ts`, Next/OpenNext config, environment contract | `/docs/operations/docs-deployment` |
80
+ | Alchemy static docs build and Cloudflare deployment | `apps/docs/alchemy.run.ts`, Next static export, environment contract | `/docs/operations/docs-deployment` |
81
81
  | Runtime diagnosis | docs scripts, source loader, deployment config | `/docs/operations/health-and-diagnostics` |
82
82
  | Docs and product rollback boundaries | immutable deployment contract, schema owner, release policy | `/docs/operations/rollback` |
83
83
  | Ownership, freshness, redirects, coverage | this matrix, docs contract, IA, redirect inventory, CI | `/docs/operations/documentation-governance` |
@@ -97,7 +97,7 @@ Each named section also has its own index route. The application additionally ow
97
97
 
98
98
  ## Redirect policy
99
99
 
100
- `apps/docs/redirects.mjs` is the one executable inventory of retired public site aliases. `apps/docs/next.config.mjs` returns that inventory from Next.js `redirects()`, so production serves permanent redirects. The maintenance verifier enforces unique sources, current destinations, absence of alias/source collisions, and documentation of both sides here.
100
+ `apps/docs/redirects.mjs` is the one executable inventory of retired public site aliases. `apps/docs/worker.mjs` consumes that inventory and returns permanent redirects while preserving query strings; Alchemy derives the exact worker-first paths from the same inventory. The maintenance verifier enforces unique sources, current destinations, absence of alias/source collisions, and documentation of both sides here.
101
101
 
102
102
  The inventory covers these retired route families:
103
103
 
@@ -103,9 +103,6 @@
103
103
  "planr recover sweep",
104
104
  "planr agents list",
105
105
  "planr agents check",
106
- "planr routing bundle inspect",
107
- "planr routing bundle preview",
108
- "planr routing bundle apply",
109
106
  "planr item route",
110
107
  "planr trace item",
111
108
  "planr serve --port"
@@ -0,0 +1,164 @@
1
+ # Planr v1.5.2 Release Candidate Evidence
2
+
3
+ Candidate produced on 2026-07-20 in an isolated local workspace:
4
+
5
+ - Workspace: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2`
6
+ - Source clone: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/release-candidate-src`
7
+ - Local bare remote: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/local-origin.git`
8
+ - Config-proof rerun source clone: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/release-candidate-src`
9
+ - Config-proof rerun local bare remote: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/local-origin.git`
10
+ - Config-proof hash snapshots: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence`
11
+ - Public side effects: none. The candidate clone's `origin` points to the local bare remote, and the public `origin` check from this repository returned no `v1.5.2` tag.
12
+
13
+ ## Identity
14
+
15
+ - Upstream release-scope base commit: `f7763c6197ddf8cdd93227b9aa320f2b168a0523`
16
+ - Clean pre-release source commit: `9390af541ca51755e585bf3c1a652717997daeca`
17
+ - Clean pre-release source tree: `2569374e6321a88b812cc706257bbda086101437`
18
+ - Release commit: `678038db4536723867fc96b0cd0af703fda43ef1`
19
+ - Release tree: `80324b8afef14d7d7bd97950eb8352cd9c667e6a`
20
+ - Annotated tag object: `12c78b7a870552361b11c5de768a6c5da7c8f115`
21
+ - Tag target: `678038db4536723867fc96b0cd0af703fda43ef1`
22
+ - Config-proof rerun release commit: `0d6bab060793fd52a5e144b9862c1fbc77d10ec3`
23
+ - Config-proof rerun release tree: `80324b8afef14d7d7bd97950eb8352cd9c667e6a`
24
+ - Config-proof rerun annotated tag object: `78c6c99afbca24803d58abb7d9a507cafde40741`
25
+ - Config-proof rerun tag target: `0d6bab060793fd52a5e144b9862c1fbc77d10ec3`
26
+
27
+ ## Version Checks
28
+
29
+ Both runtime entry points reported `planr 1.5.2`:
30
+
31
+ - `target/release/planr --version`
32
+ - `node npm/bin/planr.js --version`
33
+
34
+ All release manifests carried `1.5.2`:
35
+
36
+ - `Cargo.toml`
37
+ - `package.json`
38
+ - `plugins/planr/.codex-plugin/plugin.json`
39
+ - `plugins/planr/.claude-plugin/plugin.json`
40
+ - `.cursor-plugin/plugin.json`
41
+
42
+ ## Artifact Digests
43
+
44
+ - Native binary `target/release/planr`: `e91917be04e84f97c5d515e673f829c33b21f5128dae87ce836e3721ece50473`
45
+ - npm tarball `planr-1.5.2.tgz`: `33df443e6ec20d6d44fcf05469efe56eb75b192c826467c33d47d44672297a34`
46
+ - Native archive `dist/planr-darwin-arm64.tar.gz`: `6fdaf803073d99bdb02522100e50094fb277409d52fc3a0c33e9d8bd6707d8ac`
47
+ - Archive checksum file `dist/SHA256SUMS`: `6347103b757e5045aef9a83a311ae2bcc43de5b6e9ada8a9efa2d52b84e3359b`
48
+ - Payload checksum file `dist/planr-1.5.2/SHA256SUMS`: `d8ac952c247706bb328e1539583b87e55f9e2b211b89c134aab08357d0cc665c`
49
+ - Config-proof rerun native binary `target/release/planr`: `00c1b3b46f66563dfe4c909e2ecb75dc448e72bfe75b6cb7d56d86c6539b5d6c`
50
+ - Config-proof rerun npm tarball `planr-1.5.2.tgz`: `33df443e6ec20d6d44fcf05469efe56eb75b192c826467c33d47d44672297a34`
51
+ - Config-proof rerun native archive `dist/planr-darwin-arm64.tar.gz`: `dbba6abece2cc37d1b7e038094b8b7483ce79e5c770f8ed64048c84446d17681`
52
+ - Config-proof rerun archive checksum file `dist/SHA256SUMS`: `1d77872f58c8ef8877cbed11b16ab0ea30524a6b2a9565f5190dfd059d69416c`
53
+ - Config-proof rerun payload checksum file `dist/planr-1.5.2/SHA256SUMS`: `ce2adbe238c9fe27838c11f3a89195d9eb8b262411c86d3a8b02304ee14eaec6`
54
+
55
+ `dist/SHA256SUMS` records:
56
+
57
+ ```text
58
+ 6fdaf803073d99bdb02522100e50094fb277409d52fc3a0c33e9d8bd6707d8ac planr-darwin-arm64.tar.gz
59
+ ```
60
+
61
+ `dist/planr-1.5.2/SHA256SUMS` records:
62
+
63
+ ```text
64
+ e91917be04e84f97c5d515e673f829c33b21f5128dae87ce836e3721ece50473 planr
65
+ a1e27e1cfb3d9d540dfe05f5d1212ee98be97b1f48e203d48209e31243383ba3 README.md
66
+ 61a9b281d04d62cdea4bef57d5e0b702c191b3219456409ac5ed651569228a30 LICENSE.md
67
+ ```
68
+
69
+ ## Gates Run
70
+
71
+ - `scripts/release.sh 1.5.2 'standalone Planr core with optional Switchloom handoff'`
72
+ - `cargo test`: 71 unit tests, 67 e2e tests, and 3 routing ownership tests passed.
73
+ - `npm pack --dry-run`: reported `planr@1.5.2`, 65 files, shasum `a3903ce5658be6f6140321232885f86f6515ae70`.
74
+ - `scripts/security-local.sh`: betterleaks found no leaks; Trivy reported 0 vulnerabilities for `Cargo.lock` and `pnpm-lock.yaml`.
75
+ - Pushed `main` and `v1.5.2` only to `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/local-origin.git`.
76
+ - `scripts/build-release.sh`: built `dist/planr-darwin-arm64.tar.gz`.
77
+ - `npm pack`: created `planr-1.5.2.tgz` locally; no npm publish was run.
78
+ - Config-proof rerun:
79
+ - `scripts/release.sh 1.5.2 'standalone Planr core with optional Switchloom handoff'`: 71 unit tests, 67 e2e tests, and 3 routing ownership tests passed; betterleaks found no leaks; Trivy reported 0 vulnerabilities; pushed only to `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/local-origin.git`.
80
+ - `scripts/build-release.sh`: built `dist/planr-darwin-arm64.tar.gz`.
81
+ - `npm pack`: created `planr-1.5.2.tgz` locally; no npm publish was run.
82
+ - `target/release/planr --version` and `node npm/bin/planr.js --version`: both reported `planr 1.5.2`.
83
+ - `git tag -l v1.5.2`: returned no local tag in `/Users/kregenrek/projects/planr`.
84
+ - `git ls-remote --heads --tags origin 'v1.5.2'`: returned no public remote ref.
85
+ - Candidate clone artifact inventory: no Switchloom files, no legacy routing-owner directories, and no routing manifests were present.
86
+
87
+ ## User Config Hash Proof
88
+
89
+ No release command targeted user/global host config files. The config-proof rerun captured hashes immediately before and after each release-owned run, stored without file contents:
90
+
91
+ - `scripts/release.sh`
92
+ - Before: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-before-release-sh.txt`
93
+ - After: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-after-release-sh.txt`
94
+ - Equality proof: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-release-sh-equality.txt` records `config hashes unchanged across scripts/release.sh`.
95
+ - `scripts/build-release.sh`
96
+ - Before: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-before-build-release.txt`
97
+ - After: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-after-build-release.txt`
98
+ - Equality proof: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-build-release-equality.txt` records `config hashes unchanged across scripts/build-release.sh`.
99
+ - `npm pack`
100
+ - Before: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-before-npm-pack.txt`
101
+ - After: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-after-npm-pack.txt`
102
+ - Equality proof: `/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/config-proof/evidence/config-npm-pack-equality.txt` records `config hashes unchanged across npm pack`.
103
+
104
+ Every before/after snapshot contains the same hashes:
105
+
106
+ - `/Users/kregenrek/.codex/config.toml`: `82224997e7d4d5147f892a8aa12f7f5f04e77c38267da6ba1274a9267b23f040`
107
+ - `/Users/kregenrek/.claude/settings.json`: `99a0eb17993d0dd0c952df03bec38d284fd119a9b0ed928f3201b1792224049f`
108
+ - `/Users/kregenrek/.claude.json`: `a5f901ce3b38943ed2591333b4cb6dbab0cab101f8d02ea348fc476021f55afb`
109
+ - `/Users/kregenrek/.cursor/mcp.json`: `cf7217adfcb48b532dfdbced62ca68eab4c60996ef38d510a8efb3d286ce5baf`
110
+
111
+ ## Switchloom v0.2.1 Optional Dogfood Evidence
112
+
113
+ Fresh non-replay dogfood ran on 2026-07-20 with the release-candidate Planr v1.5.2 binary and exact public Switchloom v0.2.1 bytes. The durable local audit receipt is:
114
+
115
+ - Receipt: `/private/tmp/planr-switchloom-cross-product-QEvWps/oracle-receipt.json`
116
+ - Receipt SHA-256: `c01f4b980977a15028f7a82cc6fc237aa50fb4b35310871ba3ad245ec1c699ee`
117
+ - Mode/result: `live`, `ok=true`
118
+ - Fresh root: `/private/tmp/planr-switchloom-cross-product-QEvWps`
119
+
120
+ Replayable command:
121
+
122
+ ```bash
123
+ PLANR_WORKER_ID=switchloom_optional_dogfood PLANR_BIN=/Users/kregenrek/projects/planr-dogfood/release-v1.5.2/release-candidate-src/target/release/planr SWITCHLOOM_TARBALL=/private/tmp/switchloom-public-0.2.1.MN008L/switchloom-0.2.1.tgz PLANR_ORACLE_TEMP_PARENT=/private/tmp node scripts/verify-switchloom-cross-product.mjs
124
+ ```
125
+
126
+ Public Switchloom package identity:
127
+
128
+ - Package: `switchloom@0.2.1`
129
+ - Tarball: `/private/tmp/switchloom-public-0.2.1.MN008L/switchloom-0.2.1.tgz`
130
+ - npm SHA-1 shasum: `e813283f54d0d64b5fd4835e17687aaaf3b0a6cb`
131
+ - SHA-512 integrity: `sha512-vUKHxYXHt7Sx7MkYQz5MRZ0Ll544iHoadHGCgvJPUYkpUzQWtzjt1o3xhyeQwExCA6tuLQ5vZnLPz+fO5uMiXg==`
132
+ - Local SHA-256: `028176063ce20b4981aa4e13199b25169b2f8296f648eeeec9291e6955e7549a`
133
+
134
+ Host routing evidence from the receipt:
135
+
136
+ - Codex CLI: `codex-cli 0.144.5`
137
+ - Maker role/model/effort: `model_routing_terra_high`, `gpt-5.6-terra`, `high`
138
+ - Reviewer role/model/effort: `model_routing_sol_high`, `gpt-5.6-sol`, `high`
139
+ - `fork_turns_all_used`: `false`
140
+ - Public Codex JSONL: `/private/tmp/planr-switchloom-cross-product-QEvWps/codex-live.jsonl`
141
+ - Parent rollout: `/Users/kregenrek/.codex/sessions/2026/07/20/rollout-2026-07-20T20-05-19-019f80b4-2e89-7470-a432-6937ddcbc7ac.jsonl`
142
+ - Maker rollout: `/Users/kregenrek/.codex/sessions/2026/07/20/rollout-2026-07-20T20-05-50-019f80b4-a7d3-73d1-bf34-9762ad7d9474.jsonl`
143
+ - Reviewer rollout: `/Users/kregenrek/.codex/sessions/2026/07/20/rollout-2026-07-20T20-06-37-019f80b5-5d7f-7441-97f3-c743d97e0a8c.jsonl`
144
+
145
+ Fresh Planr audit and uninstall evidence:
146
+
147
+ - Fresh oracle plan: `pln-773f1d88`
148
+ - Fresh oracle item: `i-build-first-slice-5c85`
149
+ - Audit result: holds with clauses `items_settled`, `reviews_complete`, `approvals_clear`, and `verification_logged`.
150
+ - Post-uninstall result: Switchloom uninstall removed only managed files and unrouted Planr still worked; the script reran the Planr audit after uninstall and required `holds=true`.
151
+ - Requested-only routing metadata was rejected as effective proof: `/private/tmp/planr-switchloom-cross-product-QEvWps/requested-only-route-audit.json`.
152
+
153
+ Protected configuration and source inventory proof:
154
+
155
+ - `/Users/kregenrek/.codex/config.toml`: `82224997e7d4d5147f892a8aa12f7f5f04e77c38267da6ba1274a9267b23f040`
156
+ - `/Users/kregenrek/.claude/settings.json`: `99a0eb17993d0dd0c952df03bec38d284fd119a9b0ed928f3201b1792224049f`
157
+ - `/Users/kregenrek/.claude.json`: `a5f901ce3b38943ed2591333b4cb6dbab0cab101f8d02ea348fc476021f55afb`
158
+ - `/Users/kregenrek/.cursor/mcp.json`: `cf7217adfcb48b532dfdbced62ca68eab4c60996ef38d510a8efb3d286ce5baf`
159
+ - Switchloom source root: `/Users/kregenrek/projects/model-routing`
160
+ - Switchloom source HEAD: `191f6aac91ff0f73fcae68ab269eb2d89c9e76e9`
161
+ - Switchloom source status SHA-256: `2ca939e3e14ba8971210e93152120323641d21b0ac465b02a85335860b01758c`
162
+ - Switchloom tracked files SHA-256: `0292bca86e80e9c63d5848984cab229b17df6e1162f1b0d8ec577474a9ac3591`
163
+
164
+ This section records paths, digests, roles, and verification outcomes only. It does not copy rollout contents, prompts, responses, credentials, or user configuration contents into the repository.
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Local-first planning and execution coordination for coding agents.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -23,7 +23,6 @@
23
23
  "build:native": "cargo build --release",
24
24
  "test": "cargo test",
25
25
  "pack:check": "npm pack --dry-run",
26
- "routing": "cargo run --manifest-path planr-routing/Cargo.toml --",
27
26
  "docs:dev": "pnpm --filter @planr/docs dev",
28
27
  "docs:alchemy:dev": "pnpm --filter @planr/docs alchemy:dev",
29
28
  "docs:build": "pnpm --filter @planr/docs build",
@@ -45,6 +44,7 @@
45
44
  "docs:verify-release": "pnpm --filter @planr/docs verify:release",
46
45
  "docs:verify-release-live": "pnpm --filter @planr/docs verify:release-live",
47
46
  "docs:verify-clean-install": "pnpm --filter @planr/docs verify:clean-install",
47
+ "verify:switchloom-cross-product": "node scripts/verify-switchloom-cross-product.mjs",
48
48
  "docs:reference:generate": "cargo build --bin planr && pnpm --filter @planr/docs reference:generate",
49
49
  "docs:verify-reference": "cargo build --bin planr && pnpm --filter @planr/docs reference:check && pnpm --filter @planr/docs verify:reference"
50
50
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "planr",
3
3
  "description": "Skill-driven planning and execution loop for coding agents: one planr entry point, an autonomous planr-loop, and evidence-backed task graph skills powered by the planr CLI.",
4
- "version": "1.5.1",
4
+ "version": "1.6.0",
5
5
  "author": {
6
6
  "name": "instructa"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Skill-driven planning and execution loop for coding agents: one $planr entry point, an autonomous $planr-loop, and evidence-backed task graph skills powered by the planr CLI.",
5
5
  "author": {
6
6
  "name": "instructa",
@@ -37,7 +37,7 @@ The stop condition itself is one command: `planr plan audit <plan-id> --json` ev
37
37
 
38
38
  ## Iteration Shape
39
39
 
40
- Each iteration is one dispatch through the routing skill — never a hand-written prompt:
40
+ Each iteration follows the Planr stage protocols — never a hand-written workflow prompt:
41
41
 
42
42
  ```text
43
43
  1. planr plan audit <plan-id> --json contract holds -> exit loop ($planr-status for deeper reads)
@@ -58,7 +58,7 @@ The loop never closes its own reviews when the host supports a second agent. Mak
58
58
 
59
59
  ## Skills Are The Prompts
60
60
 
61
- When the host supports subagents, the driver never implements: it dispatches, audits, and synthesizes. Driver tokens go into `plan audit`, dispatch decisions, and conflict resolution — implementation and review run in the subagent roles, which the host wiring can pin to a cheaper tier (see the role files and `docs/GOALS.md` "Cost Tiering"). When the pick packet carries a `routing` block, dispatch on it: run the worker on the named profile's client and model, and move down the `fallbacks` chain when the primary hits a rate limit or is unavailable the chain is ordered, so no mid-run registry edits. As the dispatching driver, read the packet with `planr pick --peek [--plan <id>]` — it returns the same packet without leasing, so the worker picks under its own identity and the maker/checker audit stays clean (never pick-and-release as the driver). Workers report the profile they actually ran on (`done --profile <id>` or `PLANR_PROFILE`), so a host that silently overrode the pin shows up in `planr trace item` instead of staying invisible. Delegate with skill references plus an item id, nothing more:
61
+ When the host supports subagents, the driver never implements: it dispatches, audits, and synthesizes. Driver tokens go into `plan audit`, dispatch decisions, and conflict resolution — implementation and review run in host-native subagent roles (see the role files and `docs/GOALS.md` "Cost Tiering"). Pick packets expose provider-neutral `routing.profile`; they do not expose a host-owned `routing.agent_type`. If an external repository declaration has generated a host role whose identifier exactly matches `routing.profile`, dispatch that profile identifier as the host-native role/`agent_type` through the host's subagent wiring. If no matching repository role exists, keep the host's default dispatch contract and treat the profile as advisory evidence only. Model, effort, profile, client, and fallback fields are advisory declarations and evidence labels only; Planr does not choose a model, choose effort, choose a client, choose a fallback, or infer that a host honored any requested value. The host owns whether and how those declarations can be honored. As the dispatching driver, read the packet with `planr pick --peek [--plan <id>]` — it returns the same packet without leasing, so the worker picks under its own identity and the maker/checker audit stays clean (never pick-and-release as the driver). Workers report the profile they actually ran on (`done --profile <id>` or `PLANR_PROFILE`) and attach route observations when available, so host overrides show up in `planr trace item` as evidence instead of being inferred from declarations. Delegate with skill references plus an item id in the message body, nothing more; host-native dispatch arguments still carry the selected role/profile and isolation controls:
62
62
 
63
63
  - Worker dispatch: `Use $planr-work on item <item-id>. Stop after requesting review.`
64
64
  - Checker dispatch: `Use $planr-review on item <item-id>. Close the review with a verdict.`
@@ -67,7 +67,8 @@ A worker subagent may take several items sequentially instead of being respawned
67
67
 
68
68
  Host wiring:
69
69
 
70
- - When a repository routing bundle supplies host roles, follow its generated routing skill exactly. Otherwise treat the profile in the pick packet as advisory and use the host's current dispatch contract. Never infer effective model or effort from a declaration alone.
70
+ - When external repository declarations supply host roles matching pick-packet `routing.profile` values, pass the matching profile identifier as the native host role/`agent_type` and follow the generated role instructions exactly. Otherwise treat the profile in the pick packet as advisory and use the host's current dispatch contract. Never infer effective model or effort from a declaration alone.
71
+ - Codex with native multi-agent roles (stable multi-agent or Multi-Agent v2): generated `.codex/config.toml` roles are matching repository roles. The `spawn_agent` tool call itself must include `agent_type` set exactly to the matching `routing.profile`, `fork_turns` set to `none`, a stable lowercase `task_name`, and the dispatch message above. A default-role maker/checker spawn without `agent_type` is invalid for a generated Codex role; do not wait on it or treat it as a fallback. Do not claim role binding is unavailable for generated Codex roles, and do not substitute the role name into `task_name`, prose, worker identity, or the message body as a replacement for `agent_type`; those are not native role-binding evidence.
71
72
  - Claude Code: subagents preload via the `skills:` frontmatter field. The Planr plugin registers `planr-worker` and `planr-reviewer` automatically from its `agents/` directory; standalone installs copy them to `.claude/agents/`. The reviewer subagent is read-only except for `planr review` commands.
72
73
  - Cursor: project subagents in `.cursor/agents/*.md` (Markdown templates in `agents/` next to this skill; `planr install cursor` provisions them). Dispatch explicitly: `/planr-worker implement item X`, `/planr-reviewer review item X`. Parallel dispatches are safe — the map's pick lease keeps one owner per item.
73
74
  - Single-agent hosts: run worker and checker as separate sequential dispatches with a fresh read of map state in between; never carry the worker's self-assessment into the review step. The mode is recorded automatically: `review close` derives `review_mode` (`single_agent`/`independent`) from worker identity.