planr 1.2.0-alpha.1 → 1.2.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.
@@ -27,9 +27,10 @@ planr item insert "title" --description "..." --after <item-id> [--before <item-
27
27
  planr item amend <item-id> --note "..." [--tag amendment]
28
28
  planr item replan <parent-id> --into "A, B, C" [--preview|--confirm]
29
29
  planr item update <item-id> [--title "..."] [--description "..."] [--work-type <type>]
30
+ # plan task lists can declare work types inline: `### TASK-001 (backend): ...` / `- [ ] (frontend) ...` seed map build directly
30
31
  planr item route <item-id> [--set <profile>|--clear]
31
32
  planr link add <from-item> <to-item> --type blocks
32
- planr pick
33
+ planr pick [--work-type <type>] [--plan <plan-id>] [--peek]
33
34
  planr pick release <item-id> [--force]
34
35
  planr pick heartbeat [item-id]
35
36
  planr pick progress <item-id> --percent 0..100 [--note "..."]
@@ -47,6 +48,7 @@ planr artifact list [--item <item-id>]
47
48
  planr event list [--item <item-id>] [--limit 50]
48
49
  planr debug bundle [--item <item-id>] --preview
49
50
  planr log add --item <item-id> --summary "..." [--files a --files b | --files a,b] [--cmd "..."] [--kind completion|progress|verification] [--profile <id>]
51
+ # machine consumers: --cmd writes the `commands` field in log JSON; --tests writes `tests`
50
52
  planr review request <item-id>
51
53
  planr review annotate <item-id> --message "..." [--severity info|warning|blocking] [--file path] [--line N] [--author "..."]
52
54
  planr review ingest <item-id> (--from feedback.json|--stdin)
@@ -125,7 +127,7 @@ With `--json`, responses follow one convention so agents never guess where data
125
127
 
126
128
  `done` is the compound worker command: it writes a completion log, then requests a review (`--review`) or closes the item, and optionally picks the next ready item (`--next`). Without `--next`, the response's `next` field carries the exact follow-up command instead (`planr pick --work-type review --json` after a review request, `planr pick --json` after a close), so every settlement output ends in an action. It chains the same single-owner operations as `log add`, `review request`, `close`, and `pick` — identical evidence, fewer commands. `done`, `close`, and `review close` report what the settlement `unlocked` (id, title, work type of every item that became ready), `done` and `close` echo the item's `post_condition` at completion time, and a `hint` asks for `--cmd`/`--tests` evidence when downstream items depend on an item that closed without any. `done`, `close`, `review close`, and the pick packet include a `remaining` progress snapshot so loop agents can evaluate their stop condition without an extra `map status` call. `remaining.counts` always carries the full status vocabulary (`pending`, `ready`, `picked`, `running`, `in_review`, `blocked`, `failed`, `cancelled`, `closed`, `closed_partial`) with explicit zeros — a missing count never has to be inferred.
127
129
 
128
- `pick --json` returns one flat work packet in which every fact appears exactly once: `item`, `links`, `logs`, `runtime`, `recovery`, `conditions`, `approval`, recall context (`contexts`, `relevant_contexts`, `upstream_handoffs`, `review_history`, `source_links`, `possible_file_conflicts`), `close_effect`, `privacy`, `deeper_reads`, and `remaining`. Worker identity lives in `item.worker_id` and `runtime.worker_id`. Empty collections and inactive gates are omitted — a missing key means "empty". No separate `trace item` call is needed. Evidence written via `log add` or `done` by the pick owner refreshes the runtime heartbeat automatically. The same packet shape is returned by MCP `planr_pick_item`, HTTP `POST /v1/pick`, and `done --next`.
130
+ `pick --json` returns one flat work packet in which every fact appears exactly once: `item`, `links`, `logs`, `runtime`, `recovery`, `conditions`, `approval`, recall context (`contexts`, `relevant_contexts`, `upstream_handoffs`, `review_history`, `source_links`, `possible_file_conflicts`), `close_effect`, `privacy`, `deeper_reads`, and `remaining`. Worker identity lives in `item.worker_id` and `runtime.worker_id`. Empty collections and inactive gates are omitted — a missing key means "empty". No separate `trace item` call is needed. Evidence written via `log add` or `done` by the pick owner refreshes the runtime heartbeat automatically. The same packet shape is returned by MCP `planr_pick_item`, HTTP `POST /v1/pick`, and `done --next`. `pick --peek` (MCP: `"peek": true`) returns the same packet for the next pickable item *without* leasing it — no lease, heartbeat, or pick event is written, and the packet carries `"peek": true` with the item still `ready`. Built for dispatching drivers: read the routing block, dispatch the worker, and let the worker take the lease under its own identity — replacing the pick → `pick release --force` → re-pick sequence.
129
131
 
130
132
  `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.
131
133
 
@@ -126,6 +126,10 @@ Every host has a silent override path — the `CLAUDE_CODE_SUBAGENT_MODEL` env v
126
126
 
127
127
  Everything here is advisory (ADR-001): mismatches never fail logging, reviews, or closes. No profile reported, no run recorded, or no registry means no comparison and no event.
128
128
 
129
+ One legitimate mismatch source to know: a driver adding a live-verification log to a routed item runs on the driver profile by design, which emits a `route_mismatch_observed` event. The payload carries `log_kind`, so audit consumers can discount `verification` entries and alarm only on `completion` mismatches.
130
+
131
+ For single-host pools (e.g. all-Cursor), declare the host's *exact* model slugs (`claude-opus-4-8-thinking-high`, not `opus`): dispatch APIs resolve slugs, not aliases, and a driver forced to map `fable-5` onto the nearest slug at dispatch time is a silent translation the audit cannot see.
132
+
129
133
  ## Failure Behavior
130
134
 
131
135
  - **No registry file**: nothing changes. Pick packets simply have no `routing` key.
@@ -171,6 +175,8 @@ Create items with the use-case work type (`planr item create ... --work-type fro
171
175
 
172
176
  Declare the `client` you will actually dispatch on. A loop running inside one host dispatches that host's subagents — an in-Cursor driver that dispatches Cursor subagents with per-dispatch models is running `client = "cursor"` profiles in practice, even when the model matches. A `client = "codex"` profile is only honest when the driver really spawns a Codex process (`codex exec ...`). This matters for the audit: workers report the *profile id*, so a profile whose declared client differs from the real dispatch host passes the mismatch check on the model alone — the client deviation stays invisible.
173
177
 
178
+ When do you actually need more than one client? Hosts with a full model catalog (Cursor) can serve an entire pool natively — an all-`cursor` registry with different models per profile is the normal case there. Cross-client profiles exist for two real situations: vendor-locked hosts (Claude Code dispatches only Anthropic models, Codex CLI only OpenAI models — a Claude-Code driver that wants a GPT implementer must process-dispatch via `codex exec`), and subscription economics (the same model can bill differently per host, so routing backend work through a flat-rate CLI subscription instead of the driver host's quota is a legitimate cost decision).
179
+
174
180
  ## Host Matrix
175
181
 
176
182
  Where each host reads its model configuration from, and what silently defeats a pin there (state of July 2026):
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.2.0-alpha.1",
3
+ "version": "1.2.0",
4
4
  "description": "Local-first planning and execution coordination for coding agents.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -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.2.0-alpha.1",
4
+ "version": "1.2.0",
5
5
  "author": {
6
6
  "name": "instructa"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "1.2.0-alpha.1",
3
+ "version": "1.2.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",
@@ -42,7 +42,7 @@ Before `map build`, expand the plan's task list: the scaffold ships a single pla
42
42
  planr link add <earlier-item> <later-item> --type blocks
43
43
  ```
44
44
 
45
- If `planr agents list --json` shows routes with use-case `work_type` selectors (e.g. `frontend`, `backend`), retag the built items to match their work (`planr item update <id> --work-type frontend`) so every pick packet carries the declared profile and paired skill — this is prep-agent work, never a question for the user.
45
+ If `planr agents list --json` shows routes with use-case `work_type` selectors (e.g. `frontend`, `backend`), declare them in the plan's task list before building — `### TASK-00n (backend): ...` headings and `- [ ] (frontend) ...` items seed with that work type directly. For maps already built without annotations, retag (`planr item update <id> --work-type frontend`). Either way this is prep-agent work, never a question for the user.
46
46
 
47
47
  ## Store The Goal Contract
48
48
 
@@ -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. 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 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:
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.`
@@ -53,15 +53,16 @@ A build plan must include:
53
53
 
54
54
  ## Route-Aware Tagging
55
55
 
56
- Before `map build`, check whether the project declares model routing: `planr agents list --json`. If routes exist, their `work_type` selectors are the project's use-case vocabulary (e.g. `frontend`, `backend`, `design`) — and tagging is your job, not the user's; never ask a human to name work types. `map build` seeds every item as `code`, so after building the map, retag each item whose work matches a declared route:
56
+ Before writing the task list, check whether the project declares model routing: `planr agents list --json`. If routes exist, their `work_type` selectors are the project's use-case vocabulary (e.g. `frontend`, `backend`, `design`) — and tagging is your job, not the user's; never ask a human to name work types.
57
57
 
58
- ```bash
59
- planr agents list --json # route selectors = the use-case vocabulary
60
- planr map build --from <build-plan-id>
61
- planr item update <item-id> --work-type frontend # per item that matches a route
58
+ Declare the use case in the task list itself — `map build` seeds annotated tasks with that work type directly:
59
+
60
+ ```markdown
61
+ ### TASK-001 (backend): REST API for todos
62
+ - [ ] (frontend) Build the form and list view
62
63
  ```
63
64
 
64
- Match by the item's actual work (UI/components/styling -> a `frontend` route, API/server/storage -> `backend`, and so on). Items matching no route keep `code` the default route covers them. The payoff: every pick packet then carries the right profile, model, and paired skill for its use case, so dispatch needs no human routing knowledge.
65
+ Match by the task's actual work (UI/components/styling -> a `frontend` route, API/server/storage -> `backend`, and so on); unannotated tasks stay `code`, which the default route covers. For maps that were already built without annotations, retag instead: `planr item update <item-id> --work-type frontend`. The payoff: every pick packet then carries the right profile, model, and paired skill for its use case, so dispatch needs no human routing knowledge.
65
66
 
66
67
  ## Done
67
68
 
@@ -30,6 +30,8 @@ Live verification (browser flow, executed binary, real requests) gets its own lo
30
30
  planr log add --item <item-id> --kind verification --summary "verified <flow>: <observed outcome>" --cmd "<exact command>"
31
31
  ```
32
32
 
33
+ The `--cmd` value must be copy-paste replayable: a real shell command (or a small script you committed), never a prose transcript like "start server; curl /; check stats". A reviewer replays your command verbatim — if it cannot run, the verification cannot be independently confirmed.
34
+
33
35
  Log persistent evidence, not transient noise: a failure you immediately fixed belongs in the final log's narrative, not as a standalone failure log. Only record a failure separately when it blocks the item.
34
36
 
35
37
  Evidence logging refreshes the heartbeat automatically — a separate `planr pick heartbeat` is only needed for long silent stretches without logs.