@unbrained/pm-cli 2026.8.30 → 2026.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
  2. package/.agents/skills/README.md +1 -1
  3. package/.agents/skills/pm-developer/SKILL.md +1 -1
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +2 -2
  5. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +1 -1
  6. package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +1 -1
  7. package/.agents/skills/pm-extensions/SKILL.md +2 -2
  8. package/.agents/skills/pm-extensions/references/AUTHORING.md +1 -1
  9. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +1 -1
  10. package/.agents/skills/pm-sdk/SKILL.md +1 -1
  11. package/.agents/skills/pm-user/SKILL.md +2 -2
  12. package/.agents/skills/pm-user/references/WORKFLOWS.md +2 -2
  13. package/.claude-plugin/marketplace.json +2 -2
  14. package/AGENTS.md +16 -14
  15. package/CHANGELOG.md +41 -6
  16. package/README.md +3 -3
  17. package/dist/cli/commands/merge.d.ts +1 -1
  18. package/dist/cli/commands/merge.js +3 -3
  19. package/dist/cli/register-list-query.js +32 -17
  20. package/dist/cli/register-mutation.js +8 -5
  21. package/dist/cli/register-operations.d.ts +2 -0
  22. package/dist/cli/register-operations.js +20 -9
  23. package/dist/cli-bundle/bundle-manifest.json +144 -144
  24. package/dist/cli-bundle/chunks/{chunk-CMIEDWAY.js → chunk-2MC2LCXZ.js} +41 -41
  25. package/dist/cli-bundle/chunks/{chunk-WS2GJQVG.js → chunk-3WICXLVT.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-7SKMLSMX.js → chunk-6XIIGE7U.js} +2 -2
  27. package/dist/cli-bundle/chunks/chunk-ALKKAUFN.js +35 -0
  28. package/dist/cli-bundle/chunks/{chunk-MTTKAUBX.js → chunk-DTGWEL23.js} +2 -2
  29. package/dist/cli-bundle/chunks/chunk-GOACULJW.js +13 -0
  30. package/dist/cli-bundle/chunks/chunk-NOPL37X4.js +205 -0
  31. package/dist/cli-bundle/chunks/{chunk-2UETTHY6.js → chunk-TAG4VC22.js} +30 -30
  32. package/dist/cli-bundle/chunks/{chunk-3TEF3HM5.js → chunk-U45JXJCC.js} +2 -2
  33. package/dist/cli-bundle/chunks/{chunk-TGNAA66W.js → chunk-X4RCGLTX.js} +2 -2
  34. package/dist/cli-bundle/chunks/{chunk-2MKLQL2E.js → chunk-Y7VOMSZT.js} +2 -2
  35. package/dist/cli-bundle/chunks/{register-list-query-OMKJ5ONN.js → register-list-query-XYNX4ASQ.js} +11 -11
  36. package/dist/cli-bundle/chunks/register-mutation-2MVLRS3J.js +20 -0
  37. package/dist/cli-bundle/chunks/register-operations-WCIDXBU3.js +2 -0
  38. package/dist/cli-bundle/chunks/{register-setup-GLQ5SYV3.js → register-setup-KVNC5KPL.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-HVQ22RC4.js → chunk-2FEZ5SKM.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-Y3JJXRVK.js → chunk-4O4CJAR6.js} +5 -5
  41. package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +16 -0
  42. package/dist/cli-bundle/focused-chunks/{chunk-LYFWQMVC.js → chunk-BEVHCEWG.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/{chunk-TDK3OCX3.js → chunk-FWPLDEXF.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +2 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-JZYPPMXF.js → chunk-KB5OFSFD.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-73EDXGYE.js → chunk-MKHG3T76.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-3AVAWVZA.js → chunk-PF3E6Q36.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-AD6ULRAF.js → chunk-QDFJIRKN.js} +4 -4
  49. package/dist/cli-bundle/focused-chunks/{chunk-RKOKG43G.js → chunk-RMRCQPWU.js} +2 -2
  50. package/dist/cli-bundle/focused-chunks/{chunk-XXOWRJZ5.js → chunk-S4U5CN5Q.js} +2 -2
  51. package/dist/cli-bundle/focused-chunks/{chunk-THEPQMLX.js → chunk-SVXJYD6G.js} +2 -2
  52. package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +158 -0
  53. package/dist/cli-bundle/focused-chunks/chunk-Y6JJIX6I.js +51 -0
  54. package/dist/cli-bundle/main.js +2 -2
  55. package/dist/cli-bundle/sdk-authoring.js +1 -1
  56. package/dist/cli-bundle/sdk-contracts.js +1 -1
  57. package/dist/cli-bundle/sdk-core.js +27 -27
  58. package/dist/cli-bundle/sdk-governance.js +1 -1
  59. package/dist/cli-bundle/sdk-graph.js +1 -1
  60. package/dist/cli-bundle/sdk-merge.js +33 -33
  61. package/dist/cli-bundle/sdk-query.js +1 -1
  62. package/dist/cli-bundle/sdk-runtime.js +1 -1
  63. package/dist/cli-bundle/sdk-testing.js +1 -1
  64. package/dist/cli-bundle/sdk.js +10 -10
  65. package/dist/core/history/drift-scan.js +6 -6
  66. package/dist/core/history/history.d.ts +6 -0
  67. package/dist/core/history/history.js +47 -5
  68. package/dist/core/history/replay.d.ts +12 -1
  69. package/dist/core/history/replay.js +60 -39
  70. package/dist/core/schema/runtime-schema.d.ts +4 -0
  71. package/dist/core/schema/runtime-schema.js +60 -48
  72. package/dist/core/schema/status-defs-file.js +5 -2
  73. package/dist/mcp/legacy-adapter.d.ts +11 -2
  74. package/dist/mcp/legacy-adapter.js +26 -12
  75. package/dist/mcp/server.d.ts +2 -2
  76. package/dist/mcp/server.js +78 -15
  77. package/dist/mcp/tool-definitions.js +56 -2
  78. package/dist/sdk/agent-capability-contracts.js +4 -2
  79. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  80. package/dist/sdk/cli-contracts/flag-contracts.js +6 -2
  81. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +1 -1
  82. package/dist/sdk/cli-contracts/grammar-contracts.js +12 -2
  83. package/dist/sdk/cli-contracts/runtime-contracts.js +3 -2
  84. package/dist/sdk/cli-contracts/tool-schema.js +11 -3
  85. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
  86. package/dist/sdk/governance/health.js +17 -6
  87. package/dist/sdk/governance/status-role-diagnostics.d.ts +27 -0
  88. package/dist/sdk/governance/status-role-diagnostics.js +36 -0
  89. package/dist/sdk/governance/validate-normalization.d.ts +6 -0
  90. package/dist/sdk/governance/validate-normalization.js +37 -0
  91. package/dist/sdk/governance/validate.d.ts +1 -1
  92. package/dist/sdk/governance/validate.js +20 -35
  93. package/dist/sdk/governance/workspace-position.d.ts +69 -0
  94. package/dist/sdk/governance/workspace-position.js +164 -0
  95. package/dist/sdk/governance.d.ts +2 -0
  96. package/dist/sdk/governance.js +4 -2
  97. package/dist/sdk/history-read.js +14 -6
  98. package/dist/sdk/history-repair.js +17 -10
  99. package/dist/sdk/index.d.ts +2 -1
  100. package/dist/sdk/index.js +4 -3
  101. package/dist/sdk/init-agent-guidance.js +4 -4
  102. package/dist/sdk/lifecycle/update.js +23 -10
  103. package/dist/sdk/mcp/discovery.d.ts +152 -0
  104. package/dist/sdk/mcp/discovery.js +495 -0
  105. package/dist/sdk/mcp/protocol.d.ts +10 -2
  106. package/dist/sdk/mcp/protocol.js +15 -4
  107. package/dist/sdk/merge/index.d.ts +1 -1
  108. package/dist/sdk/merge/index.js +3 -3
  109. package/dist/sdk/merge/receipts.d.ts +27 -1
  110. package/dist/sdk/merge/receipts.js +27 -8
  111. package/dist/sdk/merge/three-way.d.ts +3 -1
  112. package/dist/sdk/merge/three-way.js +9 -7
  113. package/dist/sdk/query/context.js +11 -14
  114. package/dist/sdk/query/list.d.ts +2 -0
  115. package/dist/sdk/query/list.js +33 -12
  116. package/dist/sdk/runtime-extended-actions.js +10 -6
  117. package/dist/sdk/schema.js +12 -2
  118. package/dist/sdk/test/execution.d.ts +15 -0
  119. package/dist/sdk/test/execution.js +35 -27
  120. package/docs/AGENT_GUIDE.md +12 -4
  121. package/docs/AGENT_PROVENANCE_ADR.md +1 -1
  122. package/docs/AGENT_RUNTIME_PRIMITIVES.md +2 -2
  123. package/docs/ARCHITECTURE.md +5 -0
  124. package/docs/CLAUDE_CODE_PLUGIN.md +5 -5
  125. package/docs/COMMANDS.md +12 -12
  126. package/docs/CONFIGURATION.md +1 -1
  127. package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +14 -5
  128. package/docs/DEFECT_RECURRENCE.md +2 -0
  129. package/docs/MCP_2026_07_28.md +33 -9
  130. package/docs/MCP_2026_07_28_CONFORMANCE.md +1 -0
  131. package/docs/MCP_CAPABILITY_SURFACES.md +7 -1
  132. package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +15 -3
  133. package/docs/MERGE_SAFETY.md +30 -2
  134. package/docs/ONBOARDING.md +1 -1
  135. package/docs/OUTPUT_TOKEN_ACCOUNTING.md +5 -3
  136. package/docs/PROGRESSIVE_TOOL_DISCOVERY.md +42 -0
  137. package/docs/README.md +3 -1
  138. package/docs/READ_OUTPUT_CONTRACTS.md +1 -1
  139. package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +1 -1
  140. package/docs/SDK.md +3 -3
  141. package/docs/TESTING.md +23 -14
  142. package/docs/WORKSPACE_POSITION_AND_LIFECYCLE.md +113 -0
  143. package/docs/agent-task-token-baseline.json +157 -3
  144. package/docs/agent-task-transcripts.json +143 -0
  145. package/docs/examples/policy-restricted-extension/README.md +2 -2
  146. package/docs/examples/starter-extension/README.md +1 -1
  147. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  148. package/docs/performance/cli-transport-overhead.md +8 -6
  149. package/marketplace.json +2 -2
  150. package/package.json +4 -4
  151. package/packages/pm-beads/package.json +1 -1
  152. package/packages/pm-calendar/package.json +1 -1
  153. package/packages/pm-command-kit/package.json +1 -1
  154. package/packages/pm-digital-twin/package.json +1 -1
  155. package/packages/pm-governance-audit/package.json +1 -1
  156. package/packages/pm-guide-shell/package.json +1 -1
  157. package/packages/pm-kanban/package.json +1 -1
  158. package/packages/pm-lifecycle-hooks/package.json +1 -1
  159. package/packages/pm-linked-test-adapters/package.json +1 -1
  160. package/packages/pm-search-advanced/package.json +1 -1
  161. package/packages/pm-templates/package.json +1 -1
  162. package/packages/pm-todos/package.json +1 -1
  163. package/packages/pm-vcs/package.json +1 -1
  164. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  165. package/plugins/pm-claude/README.md +4 -3
  166. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  167. package/sdk/public-surface.json +314 -10
  168. package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +0 -34
  169. package/dist/cli-bundle/chunks/chunk-GNWPTEBW.js +0 -205
  170. package/dist/cli-bundle/chunks/chunk-N6OR6FAR.js +0 -13
  171. package/dist/cli-bundle/chunks/register-mutation-QBSNCOY3.js +0 -20
  172. package/dist/cli-bundle/chunks/register-operations-UC77FQZC.js +0 -2
  173. package/dist/cli-bundle/focused-chunks/chunk-3UMBF26I.js +0 -158
  174. package/dist/cli-bundle/focused-chunks/chunk-AXZ5AJAF.js +0 -50
  175. package/dist/cli-bundle/focused-chunks/chunk-G6PATS5E.js +0 -16
  176. package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +0 -2
@@ -55,7 +55,7 @@ This clones the repo, reads `.claude-plugin/marketplace.json` at the root, insta
55
55
  claude mcp add --transport stdio pm-mcp -- npx -y --package=@unbrained/pm-cli@latest pm-mcp
56
56
  ```
57
57
 
58
- Gives you the 31 MCP tools without skills or slash commands.
58
+ Gives you the 32 MCP tools without skills or slash commands.
59
59
 
60
60
  ### 3. Direct project `.mcp.json` (project-scoped MCP only)
61
61
 
@@ -117,7 +117,7 @@ pnpm smoke:claude-plugin
117
117
  ```
118
118
 
119
119
  Verifies: plugin file structure, manifest name consistency, stateless MCP
120
- discovery for `2026-07-28`, 31 tools present, full workflow (init → create →
120
+ discovery for `2026-07-28`, 32 tools present, full workflow (init → create →
121
121
  claim → update → link files/docs/tests → get → context → search → validate →
122
122
  health), and session-start hook.
123
123
 
@@ -134,8 +134,8 @@ pnpm smoke:codex-plugin
134
134
  ```bash
135
135
  pm contracts --schema-only --json
136
136
  pm contracts --command extension --flags-only --json
137
- pm extension --doctor --project --detail summary --strict-exit
138
- pm extension --reload --project
137
+ pm package doctor --project --detail summary --strict-exit
138
+ pm package reload --project
139
139
  ```
140
140
 
141
141
  Why this matters:
@@ -188,7 +188,7 @@ The authoritative plugin version is `plugins/pm-claude/.claude-plugin/plugin.jso
188
188
 
189
189
  The MCP server uses JSON-RPC 2.0 over stdio with canonical protocol version
190
190
  `2026-07-28`. A bounded legacy path remains for unversioned older hosts, with
191
- `2025-06-18` initialize available to enrich client identity; current hosts
191
+ initialize-era handshakes available to enrich client identity; current hosts
192
192
  discover the server and send metadata on every request.
193
193
 
194
194
  ## Extension Policy Diagnostics
package/docs/COMMANDS.md CHANGED
@@ -67,7 +67,7 @@ JSON ceiling; TOON uses the smaller default agent ceiling.
67
67
  | Packages | `install`, `upgrade`, `package`, `packages`, `extension`, package/extension command groups | install, upgrade, manage, and run package-backed extension commands |
68
68
  | Machines | `contracts`, `help`, optional `guide`/`completion` | command contracts plus optional guide-shell docs routing and shell helpers |
69
69
 
70
- `†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm install linked-test-adapters --project`).
70
+ `†` `test-runs` subcommands are provided by the optional `linked-test-adapters` package (`pm package install linked-test-adapters --project`).
71
71
 
72
72
  ## Bootstrap
73
73
 
@@ -113,21 +113,21 @@ Use `--with-packages` for one-step agent setup when bundled package commands sho
113
113
 
114
114
  ```bash
115
115
  pm package # bare command defaults to --explore (list installed)
116
- pm install '*' --project
116
+ pm package install '*' --project
117
117
  pm package catalog --project
118
118
  pm package manage --project --output-format json
119
- pm install npm:@scope/pm-package --project
119
+ pm package install npm:@scope/pm-package --project
120
120
  pm package describe --project # by-name surface map of every loaded package
121
121
  pm package describe my-package --markdown --output docs/my-package-reference.md
122
122
  pm package doctor --project --detail summary
123
123
  pm package migrate --project --dry-run --json
124
124
  pm package migrate --project --json
125
- pm upgrade --dry-run
126
- pm upgrade --packages-only
127
- pm upgrade --cli-only --repair
125
+ pm package upgrade --dry-run
126
+ pm package upgrade --packages-only
127
+ pm package upgrade --cli-only --repair
128
128
  ```
129
129
 
130
- `pm install` and `pm package` are the preferred package-first workflow. `pm package` and `pm extension` bare invocations default to `--explore` so agents can list installed packages without remembering an action flag. `pm install '*'`, shell-expanded `pm install *`, and `pm install all` install bundled first-party packages. `pm extension` remains as a compatibility command for direct extension lifecycle operations.
130
+ `pm package` is the canonical package-first workflow. `pm package` and the hidden `pm extension` alias default to `--explore` on a bare invocation so agents can list installed packages without remembering an action flag. `pm package install '*'`, shell-expanded `pm package install *`, and `pm package install all` install bundled first-party packages. `pm install`, `pm upgrade`, and `pm extension` remain executable as deprecated compatibility spellings declared in `PM_COMMAND_ALIAS_CONTRACTS`; they emit a migration hint and must not appear in documentation or skills as instructions.
131
131
  `pm package catalog` emits one row per package, with every resolvable bundled
132
132
  alias preserved in `aliases`; totals therefore measure packages rather than
133
133
  alias-index entries. `pm package manage` participates in the universal read
@@ -141,7 +141,7 @@ the choice ambiguous and provides explicit bare and `npm:` retry commands.
141
141
  durable workspace-history receipts; a successful migration is skipped on later
142
142
  processes, while a failed migration remains retryable. `extension migrate` is
143
143
  the compatibility spelling.
144
- When package-owned commands are unavailable, usage guidance includes an install-ready retry (for example `pm install calendar`, `pm install search-advanced`, `pm install governance-audit`, or `pm install guide-shell`).
144
+ When package-owned commands are unavailable, usage guidance includes an install-ready retry (for example `pm package install calendar`, `pm package install search-advanced`, `pm package install governance-audit`, or `pm package install guide-shell`).
145
145
 
146
146
  ## Triage
147
147
 
@@ -669,7 +669,7 @@ Tracker references: [pm-72xf](../.agents/pm/features/pm-72xf.toon).
669
669
 
670
670
  ## Templates
671
671
 
672
- After `pm install templates --project`, `pm templates` lists both saved templates and built-in starters:
672
+ After `pm package install templates --project`, `pm templates` lists both saved templates and built-in starters:
673
673
 
674
674
  ```bash
675
675
  pm templates
@@ -804,7 +804,7 @@ pm test <id> --run --only-last
804
804
  pm test-all --status in_progress --progress
805
805
  ```
806
806
 
807
- Linked test commands should be sandbox-safe. Prefer `node scripts/run-tests.mjs ...` for repo-local test suites; normal package-manager scripts such as `pnpm test` and `npm run test` are accepted because linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH`. Direct runner binaries such as `vitest` or `node --test` still need the wrapper or explicit inline sandbox env. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list.
807
+ Linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH` for every command and checks stored-command provenance before process creation. Direct runner binaries such as `vitest` or `node --test`, shell-wrapped equivalents, package-manager scripts, and non-Node runners are accepted consistently; prefer `node scripts/run-tests.mjs ...` when available because it also reproduces repository build, coverage, and cleanup policy. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list.
808
808
 
809
809
  Strict linked-test guards:
810
810
 
@@ -818,7 +818,7 @@ pm test <id> --run \
818
818
 
819
819
  ## Search Reindex and Eval
820
820
 
821
- `reindex` is provided by the `search-advanced` package (`pm install search-advanced --project`).
821
+ `reindex` is provided by the `search-advanced` package (`pm package install search-advanced --project`).
822
822
 
823
823
  ```bash
824
824
  pm reindex --mode keyword
@@ -1240,7 +1240,7 @@ only after selecting the exact path.
1240
1240
 
1241
1241
  ## Completion
1242
1242
 
1243
- `pm completion` is provided by the optional `guide-shell` package (`pm install guide-shell --project`).
1243
+ `pm completion` is provided by the optional `guide-shell` package (`pm package install guide-shell --project`).
1244
1244
 
1245
1245
  ```bash
1246
1246
  pm completion bash
@@ -210,7 +210,7 @@ Markdown item files are treated as legacy migration input only. Mutations always
210
210
  Most commands default to sparse TOON:
211
211
 
212
212
  ```bash
213
- pm list-open --limit 10
213
+ pm list --status open --limit 10
214
214
  ```
215
215
 
216
216
  Use JSON for strict machine parsing:
@@ -46,11 +46,20 @@ When multiple entries exist, the SDK selects the requested package by key or `na
46
46
 
47
47
  ## History and merge recovery
48
48
 
49
- History hash capability 3 distinguishes the current canonical writer surface from older epoch-2 writers while retaining readers for epochs 1 and 2. An unsupported epoch is version skew, not permission to reinterpret or silently normalize history.
50
-
51
- Health keeps the metadata-only cache path for clean history streams. A cached hash mismatch, chain mismatch, or writer-version skew is only a candidate: health rereads canonical item sources and verifies stream content hashes before reporting corruption. The `history_drift` details expose `cache_confirmation` candidate, confirmed, and resolved-false-positive item sets, while `cache_hit_verification: metadata_then_content_hash` identifies the authoritative fallback. Drift-cache envelopes also carry the current item-hash capability, so a runtime with incompatible hash semantics rebuilds the cache instead of trusting it.
52
-
53
- Merge reconciliation may consume a durable hash-only receipt without `--force` only when its canonical item path, complete declared-field set, and every merged-value hash exactly match the current item snapshot. Raw discarded values remain clone-local. Any incomplete or mismatched proof fails closed.
49
+ History hash capability 3 distinguishes the current canonical writer surface
50
+ from older writers while retaining frozen readers for epochs 1 and 2. Two
51
+ writer surfaces were historically emitted under epoch 2: its earlier form
52
+ excluded linked-test workspace/provenance fields and test-run execution
53
+ receipts while normalizing dependency ids; its later form included those
54
+ fields. Verification recognizes both immutable forms and requires each entry's
55
+ before/after hashes to use one consistent form. Current-document verification
56
+ selects the candidate that matches the verified chain head. An unsupported
57
+ epoch is version skew, not permission to reinterpret or silently normalize
58
+ history.
59
+
60
+ Health keeps the metadata-only cache path for clean history streams. A cached hash mismatch, chain mismatch, or writer-version skew is only a candidate: health rereads canonical item sources and verifies stream content hashes before reporting corruption. The `history_drift` details expose `cache_confirmation` candidate, confirmed, and resolved-false-positive item sets, while `cache_hit_verification: metadata_then_content_hash` identifies the authoritative fallback. Drift-cache envelopes carry both their schema version and the current item-hash capability, so changing legacy canonicalization invalidates prior verdicts and a runtime with incompatible hash semantics rebuilds the cache instead of trusting it.
61
+
62
+ Merge reconciliation may consume a durable hash-only receipt without `--force` only when its canonical item path, complete declared-field set, and every merged-value hash exactly match the current item snapshot. Raw discarded values remain clone-local. Any incomplete or mismatched proof fails closed. SDK gates use `inspectMergeReceiptEvidence` or `runMergeReceiptEvidenceReport` to retain the distinction between no evidence, rejected evidence, and clone-local evidence whose Git directory could not be resolved; `clone_local_evidence_resolved=false` makes the loss-aware report incomplete. The list-only and legacy report compatibility projections intentionally return valid receipts only. Diverged history unions also fail closed when deterministic suffix ordering would make any patch operation inapplicable, instead of publishing a rehashed stream with a skipped branch effect.
54
63
 
55
64
  ## Strict-create recovery
56
65
 
@@ -79,6 +79,8 @@ The repository example is [config/defect-recurrence-policy.json](../config/defec
79
79
 
80
80
  Repository policy validation rejects duplicate ids, absent historical examples, missing family negative controls, invalid taxonomy values, and budgets outside zero through one. Deterministic sorting makes the serialized policy merge-friendly.
81
81
 
82
+ Register a family whenever a defect is recorded as a recurrence of an earlier one, meaning the new item carries a `recurs_from` edge to its predecessor. A recurrence with no family produces no local and no hosted protection, so the next instance is rediscovered by hand. Coverage of recorded recurrence lineages is not yet computed by any gate; that gap is tracked on [pm-7c27ep](../.agents/pm/issues/pm-7c27ep.toon).
83
+
82
84
  ## Defect Evidence on PM Items
83
85
 
84
86
  Projects can register the structured fields without changing the SDK:
@@ -12,7 +12,9 @@ by [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
12
12
  [pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon), and
13
13
  [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon). Skills and Apps are tracked
14
14
  by [pm-8nzivt](../.agents/pm/features/pm-8nzivt.toon) and
15
- [pm-pznhee](../.agents/pm/features/pm-pznhee.toon).
15
+ [pm-pznhee](../.agents/pm/features/pm-pznhee.toon). Progressive tool discovery
16
+ and canonical model-facing results are tracked by
17
+ [pm-3g3f8z](../.agents/pm/features/pm-3g3f8z.toon).
16
18
 
17
19
  Status: accepted. MCP `2026-07-28` is pm's canonical protocol revision.
18
20
 
@@ -39,15 +41,37 @@ capabilities, public cache policy, server identity, and bounded instructions.
39
41
  No modern request reads identity, capabilities, or version from a previous
40
42
  request.
41
43
 
44
+ The optional `dev.unbrained.pm/progressive-tool-discovery` extension is also request-local. Negotiated clients receive a stable five-tool entry catalog and expand it with `pm_discover`; unnegotiated clients retain the complete profile-selected list. Negotiated tool results designate `structuredContent.result` as canonical and use text content only as a pointer, while the isolated compatibility adapter retains duplicated JSON text for existing clients. The public SDK owns ranking, cursor binding, token and omission receipts, and cache invalidation. See [Progressive Tool Discovery](PROGRESSIVE_TOOL_DISCOVERY.md).
45
+
42
46
  ## Legacy boundary
43
47
 
44
- The sole supported legacy revision is `2025-06-18`, accepted through the
45
- existing stdio adapter. Unversioned requests stay on this legacy path because
46
- they cannot claim the current revision; `initialize` enriches their client
47
- identity but is not required for compatibility with older pm hosts. The
48
- adapter has no session id, does not affect modern requests, and is excluded
49
- from `server/discover`'s `supportedVersions` because it cannot be selected
50
- through modern per-request metadata.
48
+ Legacy means every revision that establishes a session with an `initialize`
49
+ handshake, which the canonical revision defines as `2025-11-25` and earlier.
50
+ The stdio adapter therefore accepts the full initialize-era set, newest first:
51
+
52
+ | Revision | Accepted at `initialize` | Notes |
53
+ | ------------ | ------------------------ | -------------------------------------------------------------------- |
54
+ | `2025-11-25` | yes | Final legacy revision; offered when a client omits `protocolVersion` |
55
+ | `2025-06-18` | yes | Earlier legacy revision retained for existing consumers |
56
+
57
+ `initialize` answers with the revision the client requested, because a legacy
58
+ client has no fall-forward mechanism and treats the answered version as the
59
+ negotiated one. A revision outside the set is refused with `-32022` and the
60
+ refusal names every supported revision, since that error text is the only
61
+ diagnostic such a client can surface.
62
+
63
+ `PM_MCP_LEGACY_PROTOCOL_VERSIONS` on the public SDK surface is the single
64
+ declaration of this set. The plugin MCP smoke gate reads it from the built SDK
65
+ and drives one real `initialize` per declared revision against the released
66
+ launcher, plus a negative control for an undeclared revision, so the accepted
67
+ set and the documented set cannot drift apart.
68
+
69
+ Unversioned requests stay on this legacy path because they cannot claim the
70
+ current revision; `initialize` enriches their client identity but is not
71
+ required for compatibility with older pm hosts. The adapter has no session id,
72
+ does not affect modern requests, and is excluded from `server/discover`'s
73
+ `supportedVersions` because it cannot be selected through modern per-request
74
+ metadata.
51
75
 
52
76
  The adapter is scheduled for removal only after published-client telemetry and
53
77
  release probes show no required legacy consumers for two consecutive release
@@ -58,7 +82,7 @@ windows. Removal is a reviewed compatibility change, never a history rewrite.
58
82
  - Stdio modern clients call `server/discover` with current request metadata,
59
83
  then send the same version and capability keys on every request.
60
84
  - Stdio legacy clients retain their existing response shapes and may use
61
- `initialize` with `2025-06-18` to supply client identity.
85
+ `initialize` with any accepted legacy revision to supply client identity.
62
86
  - Streamable HTTP requires `MCP-Protocol-Version` and `Mcp-Method` on every
63
87
  request. `Mcp-Name` is required only for `prompts/get`, `resources/read`, and
64
88
  `tools/call`; other methods omit it. Schema-declared `x-mcp-header` values are
@@ -13,6 +13,7 @@ evidence or an explicit open obligation.
13
13
  | Header mismatch `-32020` and missing capability `-32021` | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented in SDK, stdio, and Streamable HTTP | SDK negative controls and `tests/integration/mcp-streamable-http.spec.ts` |
14
14
  | Required result `resultType`; legacy omission means complete only at compatibility boundary | [pm-vae5ec](../.agents/pm/features/pm-vae5ec.toon) | Implemented for modern pm results | SDK unit and modern direct-server tests |
15
15
  | No modern initialize, initialized notification, ping, or protocol session | [pm-sqvshj](../.agents/pm/decisions/pm-sqvshj.toon) | Implemented with bounded legacy stdio adapter | modern removed-method and legacy handshake tests |
16
+ | Legacy interoperability covers every initialize-era revision the spec names | [pm-edywqn](../.agents/pm/issues/pm-edywqn.toon) | Implemented: `2025-11-25` and `2025-06-18` accepted, requested revision echoed | `tests/integration/mcp-handshake.spec.ts` handshake matrix plus the plugin smoke `assertProtocolHandshakeMatrix` real-process gate and its negative control |
16
17
  | MRTR `input_required`, retry state, and reverse-request removal | [pm-rz9gep](../.agents/pm/features/pm-rz9gep.toon) | Implemented for SDK and stateless stdio adapter | `tests/unit/sdk/mcp/interactions.spec.ts`; direct server negative controls |
17
18
  | `subscriptions/listen`, request-scoped streams, no SSE resumability | [pm-v7e337](../.agents/pm/features/pm-v7e337.toon) | Implemented locally; packed and published proof follows merge | subscription SDK, stdio, HTTP, backpressure, disconnect, and retry tests |
18
19
  | Official `io.modelcontextprotocol/tasks` extension | [pm-rzs24j](../.agents/pm/features/pm-rzs24j.toon) | Implemented for eligible tool calls, durable lifecycle, and stdio methods; notifications remain with subscriptions owner | `tests/unit/sdk/mcp/tasks.spec.ts`, `tests/integration/mcp-stateless-protocol.spec.ts` |
@@ -1,6 +1,6 @@
1
1
  # Runtime capability surfaces
2
2
 
3
- Tracker: [pm-xwah](../.agents/pm/chores/pm-xwah.toon), [pm-kxci8x](../.agents/pm/tasks/pm-kxci8x.toon), [pm-mu8m](../.agents/pm/tasks/pm-mu8m.toon), [pm-9k90](../.agents/pm/features/pm-9k90.toon), [pm-m4ikkz](../.agents/pm/features/pm-m4ikkz.toon), [pm-yf07b7](../.agents/pm/features/pm-yf07b7.toon)
3
+ Tracker: [pm-xwah](../.agents/pm/chores/pm-xwah.toon), [pm-kxci8x](../.agents/pm/tasks/pm-kxci8x.toon), [pm-mu8m](../.agents/pm/tasks/pm-mu8m.toon), [pm-9k90](../.agents/pm/features/pm-9k90.toon), [pm-m4ikkz](../.agents/pm/features/pm-m4ikkz.toon), [pm-yf07b7](../.agents/pm/features/pm-yf07b7.toon), and [pm-3g3f8z](../.agents/pm/features/pm-3g3f8z.toon).
4
4
 
5
5
  The SDK exports one agent capability contract for command visibility, MCP tool profiles, resources, and workflow prompts. CLI-facing generators and MCP hosts should project from these contracts instead of maintaining independent allowlists.
6
6
 
@@ -15,6 +15,12 @@ Set `PM_MCP_PROFILE` for the `pm-mcp` process:
15
15
 
16
16
  An activated extension command makes `pm_run` discoverable outside a custom profile. Its action is added to the live `pm_run` action enumeration. Custom profiles remain exact allowlists.
17
17
 
18
+ ## Progressive discovery
19
+
20
+ Modern clients may negotiate `dev.unbrained.pm/progressive-tool-discovery`. Their initial `tools/list` response is the stable five-tool entry catalog, and `pm_discover` expands authorized tools by intent, family, and tier under explicit row and token ceilings. Unnegotiated and initialize-era clients retain the full selected profile.
21
+
22
+ The SDK ranks with visible lexical, semantic, graph, permission, freshness, and usage signals, binds cursors to all ranking inputs, and emits omission recovery plus cache invalidation metadata. Negotiated tool calls make `structuredContent.result` canonical and replace duplicated JSON text with a pointer; compatibility clients retain the old representation. See [Progressive Tool Discovery](PROGRESSIVE_TOOL_DISCOVERY.md).
23
+
18
24
  Package authors can declare `tier: "core" | "standard" | "full" | "internal"` on `registerCommand()` definitions. The default is `standard`; `internal` commands remain callable by native dispatch but are not advertised by normal MCP profiles.
19
25
 
20
26
  ## Workspace schema projection
@@ -1,13 +1,14 @@
1
1
  # MCP Remote Transport, Authorization, and Migration
2
2
 
3
- Tracker references: [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
3
+ Tracker references: [pm-3g3f8z](../.agents/pm/features/pm-3g3f8z.toon),
4
+ [pm-v7e337](../.agents/pm/features/pm-v7e337.toon),
4
5
  [pm-3zh9s4](../.agents/pm/features/pm-3zh9s4.toon), and
5
6
  [pm-vzcisw](../.agents/pm/chores/pm-vzcisw.toon).
6
7
 
7
8
  pm exposes the same MCP 2026-07-28 dispatcher through two adapters:
8
9
 
9
10
  - `pm-mcp` is the local JSON-RPC/stdio process. It retains a bounded
10
- `2025-06-18` compatibility adapter for existing local consumers.
11
+ initialize-era compatibility adapter for existing local consumers.
11
12
  - `pm-mcp-http` is the canonical sessionless Streamable HTTP POST process. It
12
13
  accepts only modern request-local protocol metadata and never creates an
13
14
  MCP session.
@@ -36,6 +37,7 @@ Configuration is explicit and environment-only:
36
37
  | `PM_MCP_HTTP_AUTH_ISSUER` | Exact HTTPS authorization-server issuer | none |
37
38
  | `PM_MCP_HTTP_RESOURCE` | Canonical MCP resource/audience URI | none |
38
39
  | `PM_MCP_HTTP_SCOPES` | Space-separated consent scopes | `pm:read pm:write` |
40
+ | `PM_MCP_DISCOVERY_CURSOR_KEY` | Shared 32-byte-or-longer secret for discovery pages | process-local key |
39
41
 
40
42
  A non-loopback bind fails closed unless token, issuer, and resource are all
41
43
  present. Production deployments should normally call
@@ -50,9 +52,17 @@ placing a real credential in documentation:
50
52
  PM_MCP_HTTP_BEARER_TOKEN='<deployment-secret>' \
51
53
  PM_MCP_HTTP_AUTH_ISSUER='https://auth.example.test' \
52
54
  PM_MCP_HTTP_RESOURCE='http://127.0.0.1:3000/mcp' \
55
+ PM_MCP_DISCOVERY_CURSOR_KEY='<32-byte-or-longer-random-secret>' \
53
56
  pm-mcp-http
54
57
  ```
55
58
 
59
+ Single-process deployments may omit the discovery cursor key. That selects a
60
+ random process-local HMAC key and deliberately makes pagination process-affine:
61
+ a restart or another worker rejects the cursor as stale. Multi-worker or
62
+ restart-continuous deployments must provide the same high-entropy value to
63
+ every worker. Rotating it invalidates outstanding discovery cursors without
64
+ exposing the key in MCP input, output, errors, traces, or cache identities.
65
+
56
66
  The adapter serves RFC 9728 protected-resource metadata at both
57
67
  `/.well-known/oauth-protected-resource` and the path-qualified
58
68
  `/.well-known/oauth-protected-resource/mcp` location.
@@ -155,7 +165,9 @@ an unlisted source path cannot create that exemption. Any canonical match for a
155
165
  removed method, session header, SSE resume mechanism, legacy
156
166
  resource-subscription method, or deprecated server policy fails the gate.
157
167
 
158
- The compatibility adapter supports only protocol `2025-06-18` on local stdio.
168
+ The compatibility adapter supports the initialize-era revisions declared by
169
+ `PM_MCP_LEGACY_PROTOCOL_VERSIONS` (`2025-11-25` and `2025-06-18`) on local
170
+ stdio.
159
171
  It may be removed after telemetry and installed-consumer probes show no
160
172
  required legacy clients for two consecutive release windows. Deprecated
161
173
  2026-07-28 fields remain available only where the normative registry requires
@@ -97,7 +97,20 @@ pm merge report
97
97
  pm merge report --include-reconciled
98
98
  ```
99
99
 
100
- The underlying public SDK exports are `mergeItemDocuments`, `mergeHistoryStreams`, `mergeRelationshipEventStreams`, `mergeJsonDocuments`, `runMergeDriver`, `runMergeInstall`, `installMergeFence`, `findGitWorkspaceRoot`, `runMergeReconcile`, `runMergeReceiptReport`, `listMergeReceipts`, `auditMergeDriverConfiguration`, `refreshMergeAttributeFenceIfInstalled`, `buildMergeAttributePatterns`, and `auditMergeAttributeFence` from `@unbrained/pm-cli/sdk`. `installMergeFence` accepts explicit tracker and workspace roots, so custom init hosts do not depend on process cwd or CLI globals.
100
+ The underlying public SDK exports are `mergeItemDocuments`, `mergeHistoryStreams`, `mergeRelationshipEventStreams`, `mergeJsonDocuments`, `runMergeDriver`, `runMergeInstall`, `installMergeFence`, `findGitWorkspaceRoot`, `runMergeReconcile`, `runMergeReceiptReport`, `runMergeReceiptEvidenceReport`, `inspectMergeReceiptEvidence`, `listMergeReceipts`, `auditMergeDriverConfiguration`, `refreshMergeAttributeFenceIfInstalled`, `buildMergeAttributePatterns`, and `auditMergeAttributeFence` from `@unbrained/pm-cli/sdk`. `installMergeFence` accepts explicit tracker and workspace roots, so custom init hosts do not depend on process cwd or CLI globals.
101
+
102
+ `listMergeReceipts` is the compatibility projection for callers that only need
103
+ validated receipts. It cannot distinguish an empty evidence store from a store
104
+ whose candidates were all rejected. Gates and diagnostic integrations should
105
+ use `inspectMergeReceiptEvidence`, whose `invalid_evidence_count` preserves
106
+ that distinction without returning malformed contents.
107
+ `runMergeReceiptEvidenceReport` and `pm merge report --json` expose the same
108
+ loss-aware contract through `complete`, `invalid_evidence_count`, and
109
+ `clone_local_evidence_resolved`; the CLI
110
+ exits nonzero when evidence is incomplete, even when the valid-receipt count is
111
+ zero. Current SDK implementations always emit the new field, while its optional
112
+ type preserves structural compatibility for existing typed adapters and test
113
+ fixtures. `runMergeReceiptReport` remains the compatible valid-only report.
101
114
 
102
115
  ## Cross-branch id collision safety
103
116
 
@@ -189,7 +202,22 @@ pm merge reconcile --dry-run --json
189
202
 
190
203
  `history-repair` records the reconciliation patch and classifies its changed fields against the final item. Append-only collection unions and deterministic reordering are reported as preserved context without a data-loss warning. Fields whose replayed values are actually removed or replaced remain loud with discarded event authors/operations and recovery guidance. Re-apply any intended losing mutation as a normal `pm update` so it remains explicit and auditable.
191
204
 
192
- History events now declare an item-hash epoch. The current epoch preserves linked-test insertion order; unversioned streams are verified against both the legacy sorted-test canonicalization and the order-preserving canonicalization. An unknown explicit epoch is reported as `unsupported_item_hash_version` and repair refuses to guess. This keeps version incompatibility distinct from item corruption and is tracked by [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon).
205
+ History events now declare an item-hash epoch. Epochs are immutable writer
206
+ contracts, not aliases for the current item serializer: epoch 1 sorts linked
207
+ tests; epoch 2 preserves their insertion order and has both an earlier
208
+ field-frozen form and a later expanded form because the writer surface grew
209
+ before the marker advanced; epoch 3 is the current form. Verification accepts
210
+ both recorded epoch-2 forms without allowing one entry to mix them, and repair
211
+ preserves the form evidenced by each event. Unversioned streams are verified
212
+ against the supported legacy canonicalizations. Current-document comparison
213
+ selects the resolved epoch candidate that matches the chain head. A union merge
214
+ may consume suffixes written by both epoch-2 forms, but its synthesized output
215
+ uses one form for the complete re-anchored stream so every stored `after_hash`
216
+ is exactly the next stored `before_hash`. An unknown explicit epoch is
217
+ reported as `unsupported_item_hash_version` and repair refuses to guess. This
218
+ keeps version incompatibility distinct from item corruption and is tracked by
219
+ [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon) and
220
+ [pm-2qahia](../.agents/pm/issues/pm-2qahia.toon).
193
221
 
194
222
  ## Delete versus modify policy
195
223
 
@@ -43,7 +43,7 @@ pm context --limit 10
43
43
  pm search "<request keywords>" --limit 10
44
44
  pm list --status open --limit 20
45
45
  pm list --status in_progress --limit 20
46
- pm install guide-shell --project
46
+ pm package install guide-shell --project
47
47
  pm guide workflows
48
48
  ```
49
49
 
@@ -1,6 +1,6 @@
1
1
  # Output Token Accounting
2
2
 
3
- Tracker references: [pm-t5dt4z](../.agents/pm/tasks/pm-t5dt4z.toon), [pm-g3n00m](../.agents/pm/stories/pm-g3n00m.toon), [pm-8pnj](../.agents/pm/features/pm-8pnj.toon), [pm-f05lsg](../.agents/pm/features/pm-f05lsg.toon), and [pm-srns](../.agents/pm/issues/pm-srns.toon).
3
+ Tracker references: [pm-t5dt4z](../.agents/pm/tasks/pm-t5dt4z.toon), [pm-g3n00m](../.agents/pm/stories/pm-g3n00m.toon), [pm-8pnj](../.agents/pm/features/pm-8pnj.toon), [pm-f05lsg](../.agents/pm/features/pm-f05lsg.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), and [pm-jjqyzd](../.agents/pm/issues/pm-jjqyzd.toon).
4
4
 
5
5
  ## Agent Quick Context
6
6
 
@@ -39,7 +39,9 @@ The command still exits with its normal non-zero status; the receipt is additive
39
39
 
40
40
  ## Release-Level Task Entitlement
41
41
 
42
- [`agent-task-transcripts.json`](agent-task-transcripts.json) is the SDK-validated, versioned golden corpus. [`agent-task-token-baseline.json`](agent-task-token-baseline.json) is its externally shipped release ratchet. The gate executes the built CLI against independent, identically seeded accounting-on and accounting-off workspaces. Its five complete workflows cover:
42
+ [`agent-task-transcripts.json`](agent-task-transcripts.json) is the SDK-validated, versioned golden corpus. [`agent-task-token-baseline.json`](agent-task-token-baseline.json) is its externally shipped release ratchet. The gate executes the built CLI against independent, identically seeded accounting-on and accounting-off workspaces. Its eight complete workflows cover:
43
+
44
+ - three equivalent cold-start protocols and a fail-closed rule that the documented canonical protocol must remain the measured winner: `context --for orient` at 1,055 estimated tokens, the historical four-read sequence at 2,293, and `contracts --summary` plus `next` at 4,798 on the fixed 101-item corpus;
43
45
 
44
46
  - bounded triage, scaled-workspace orientation, and returning-agent inspection;
45
47
  - a closed-domain refusal followed by the exact advertised shell-free retry;
@@ -49,7 +51,7 @@ The command still exits with its normal non-zero status; the receipt is additive
49
51
 
50
52
  Every step verifies its public SDK output family, canonical successful or refusal exit status, required own-property paths, declared `expected_field_values`, and refusal identity where applicable. Recovery steps must declare a successful output family instead of chaining one refusal to another, every refusal in a completed task must have a later successful `recovery_for` step, and every completed task must terminate with successful output. Successful steps cannot carry refusal-only metadata. Dot-separated `required_fields` and `expected_field_values` paths are traversed structurally from the output root, so incidental prose or nested key names cannot satisfy completeness or terminal-state assertions. The report publishes bytes and estimated tokens for each step and completed task, retry counts, corpus digest, and composite cost. Accounting-on application payloads must be byte-equivalent to their independently captured accounting-off payloads after removing only the receipt. Receipt byte and token fields are independently measured rather than trusted. Runtime refusals verify that their self-reported `total_bytes` matches the independent transport and that `total_estimated_tokens` equals `ceil(total_bytes / 4)`; Commander usage refusals that happen before accounting attachment are measured directly from the captured transport and labeled `independent_transport`.
51
53
 
52
- The baseline fails closed on corpus digest, task identity, step identity, missing or non-finite per-step and per-task ceilings, and missing or non-finite composite cost ceilings. A seeded million-token completed-task regression proves the ratchet fails. Run it with:
54
+ The baseline fails closed on corpus digest, task identity, step identity, the canonical orientation winner and its ceiling, missing or non-finite per-step and per-task ceilings, and missing or non-finite composite cost ceilings. A seeded million-token completed-task regression proves the ratchet fails. Run it with:
53
55
 
54
56
  ```bash
55
57
  pnpm quality:agent-task-token
@@ -0,0 +1,42 @@
1
+ # Progressive Tool Discovery
2
+
3
+ Tracker: [pm-3g3f8z](../.agents/pm/features/pm-3g3f8z.toon).
4
+
5
+ `pm` exposes a public SDK discovery engine and an opt-in MCP extension for large tool catalogs. The design keeps the full legacy-compatible catalog available while allowing capable clients to attach only a small entry surface and expand it by intent.
6
+
7
+ ## Negotiation and entry catalog
8
+
9
+ `server/discover` advertises the namespaced `dev.unbrained.pm/progressive-tool-discovery` extension. A client opts in by returning that extension in the request-local MCP capabilities on every modern request. Negotiated `tools/list` responses contain the stable entry catalog:
10
+
11
+ - `pm_discover` for bounded capability expansion;
12
+ - `pm_next` and `pm_context` for action and workspace orientation;
13
+ - `pm_search` and `pm_get` for targeted retrieval.
14
+
15
+ Clients that do not negotiate the extension receive the complete profile-selected tool list. Legacy initialize-era clients are unchanged.
16
+
17
+ ## Public SDK contract
18
+
19
+ `discoverPmTools()` accepts an authorization-filtered candidate catalog plus query, family, tier, limit, cursor, schema projection, profile, output-budget, and optional host-owned cursor-integrity-key options. It returns:
20
+
21
+ - deterministic score-then-name ordering;
22
+ - lexical, semantic, graph, permission, freshness, and usage scores with public weights and source provenance;
23
+ - a tamper-evident cursor bound to query, filters, schemas, authorization-filtered catalog, ranking inputs, and either the private discovery process or an explicit shared host key;
24
+ - exact estimated token cost and a fail-closed `within_budget` verdict;
25
+ - explicit schema, row-limit, and token-budget omission receipts with recovery;
26
+ - a private cache key, 30-second TTL, and named invalidation events.
27
+
28
+ Hosts may supply normalized semantic, graph, freshness, and usage signals. Missing host values use documented deterministic fallbacks, and the result identifies every signal source; the formula never changes implicitly.
29
+
30
+ SDK hosts that route pages across processes or restarts must pass the same random, secret `cursorIntegrityKey` of at least 32 bytes on every call. Omitting it deliberately selects a random process-local key: that securely enforces process affinity, and a cursor reaching another process fails closed as stale. The bundled MCP adapter reads the shared key from `PM_MCP_DISCOVERY_CURSOR_KEY`; local stdio needs no override, while multi-worker or restart-continuous HTTP deployments must configure one shared high-entropy value.
31
+
32
+ ## Canonical tool results
33
+
34
+ Negotiated clients treat `structuredContent.result` as the single canonical model-facing application result. The text content becomes a stable pointer instead of a second JSON serialization. Errors use the same rule through `structuredContent`.
35
+
36
+ Unnegotiated and legacy clients retain the prior duplicated JSON text plus structured result. That compatibility behavior is isolated at the MCP adapter boundary; domain operations and SDK results do not branch on transport generation.
37
+
38
+ ## Scale and change safety
39
+
40
+ The discovery quality gate exercises selection, deterministic pagination, stale-cursor refusal, permission filtering, schema recovery, and token ceilings at 100, 1,000, and 10,000 candidate tools. Contract snapshots cover the tool schema, and modern MCP integration tests prove both negotiated and compatibility modes.
41
+
42
+ Any tool-definition, workspace-extension, profile, authorization, ranking-signal, or cursor-key change invalidates prior cursors and cache entries. Process-local cursors also expire when that process exits. Clients restart discovery without a cursor after an explicit stale-cursor refusal.
package/docs/README.md CHANGED
@@ -7,7 +7,7 @@ This directory is the public documentation home for `pm-cli`. It is organized fo
7
7
  `pm guide` is provided by the optional `guide-shell` package. Install it when local in-CLI documentation routing is useful:
8
8
 
9
9
  ```bash
10
- pm install guide-shell --project
10
+ pm package install guide-shell --project
11
11
  pm guide
12
12
  pm guide quickstart
13
13
  pm guide commands --depth standard
@@ -45,6 +45,7 @@ pm guide release --json
45
45
  - [Package SDK Contract Conformance](PACKAGE_SDK_CONTRACT_CONFORMANCE.md) - authoritative public types, `typeof` module derivation, and the first-party parity gate.
46
46
  - [SDK Action and Boundary Conformance](SDK_ACTION_CONFORMANCE.md) - derived CLI/SDK/MCP action vocabulary, public-import ratchets, intent budget diagnostics, and package-runner proof.
47
47
  - [MCP 2026-07-28 Protocol Decision](MCP_2026_07_28.md) - stateless request metadata, discovery, result envelopes, explicit legacy boundary, and migration policy.
48
+ - [Progressive Tool Discovery](PROGRESSIVE_TOOL_DISCOVERY.md) - opt-in bounded MCP catalogs, public SDK ranking and pagination, canonical results, and compatibility isolation.
48
49
  - [MCP 2026-07-28 Conformance Matrix](MCP_2026_07_28_CONFORMANCE.md) - official revision changes mapped to canonical owners and executable evidence.
49
50
  - [MCP Interaction and Task SDK](SDK_MCP_INTERACTIONS.md) - public MRTR continuation, cache/schema validation, and durable task-store contracts.
50
51
  - [MCP Skills and Apps](MCP_SKILLS_AND_APPS.md) - negotiated draft workflow discovery, stable interactive views, digests, provenance, accessibility, and trust boundaries.
@@ -72,6 +73,7 @@ pm guide release --json
72
73
  - [SDK Evidence Traceability and Integrity](SDK_EVIDENCE_TRACEABILITY.md) - reverse source-to-item lookup, atomic evidence replacement, no-op history, linked-test collision classification, and telemetry drain receipts.
73
74
  - [SDK Context and Evidence Contracts](SDK_CONTEXT_EVIDENCE_CONTRACTS.md) - material omission receipts, scoped preflight activation, truthful merge preference, claim-race classification, and versioned history hashes.
74
75
  - [Reproducible Workspaces and Snapshots](REPRODUCIBLE_WORKSPACES.md) - deterministic SDK recipes and content-addressed authoritative tracker restore points.
76
+ - [Workspace Position and Lifecycle Roles](WORKSPACE_POSITION_AND_LIFECYCLE.md) - role-safe custom workflows plus one bounded merge-fence, receipt, history-drift, and next-action SDK read.
75
77
  - [Portable Corpus Shapes](CORPUS_SHAPES.md) - versioned SDK populations for realistic benchmarks, evaluations, and package tests.
76
78
  - [Agent UX Contracts](AGENT_UX_CONTRACTS.md) - ordering-cycle advisories, graph count units, collision safety, compact context, ownership wording, and recovery behavior.
77
79
  - [Packages and Extensions](EXTENSIONS.md) - package install workflows, runtime extension lifecycle, and API reference.
@@ -144,7 +144,7 @@ consumer therefore cannot interpret the missing command or action arrays as a
144
144
  successful empty contract.
145
145
 
146
146
  ```bash
147
- pm list-open --output-include id,title,status --output-limit 10
147
+ pm list --status open --output-include id,title,status --output-limit 10
148
148
  pm context --for orient --output-budget 900 --output-format toon
149
149
  pm search "runtime contracts" --output-limit 5 --output-format json
150
150
  pm stats --output-row-contract
@@ -129,7 +129,7 @@ pm reindex --mode hybrid
129
129
  If the command is absent, recovery is a two-step executable sequence:
130
130
 
131
131
  ```bash
132
- pm install search-advanced --project
132
+ pm package install search-advanced --project
133
133
  pm reindex --mode hybrid
134
134
  ```
135
135
 
package/docs/SDK.md CHANGED
@@ -137,7 +137,7 @@ List consumers can inspect `LIST_COMMAND_DEFAULT_PROJECTIONS` instead of
137
137
  copying command-specific defaults. Every compact or field-projected list result
138
138
  now echoes the applied `projection`; `brief` remains distinct from `compact`,
139
139
  and `DEFAULT_COMPACT_LIST_FIELDS` / `BRIEF_LIST_FIELDS` provide the canonical
140
- field sets. `pm contracts --command list-open --flags-only --json` includes the
140
+ field sets. `pm contracts --command list --flags-only --json` includes the
141
141
  same per-command projection surface.
142
142
 
143
143
  ### Public-surface compatibility
@@ -336,7 +336,7 @@ Command/action contract exports:
336
336
  - Annotation and relationship option/result contracts: `CommentsCommandOptions` / `CommentsResult`, `NotesCommandOptions` / `NotesResult`, `LearningsCommandOptions` / `LearningsResult`, `FilesCommandOptions` / `FilesResult`, `FilesDiscoverOptions` / `FilesDiscoverResult`, `DocsCommandOptions` / `DocsResult`, `DepsCommandOptions` / `DepsResult`, `AppendCommandOptions` / `AppendResult`
337
337
  - Annotation kernel primitives: `resolveAnnotationInput`, `runAnnotationCommand`, `resolveAnnotationIndex`, `parseAnnotationTextInput`, `limitAnnotationEntries`, `readAnnotationEntries`, `wrapOwnershipConflict`, `isErrnoError`, and their typed input/config/result contracts
338
338
  - Linked-resource kernel primitives: `runFiles`, `runFilesDiscover`, `runDocs`, `runDeps`, `runLinkedArtifacts`, `assertLinkedArtifactMutationIsUnambiguous`, parsing/normalization/path-validation helpers, and their typed contracts. The CLI files/docs/deps modules are presentation-only re-exports of these SDK implementations. A transaction that resolves one path into both its add and remove sets fails before item or history mutation; split an intentional replacement into two commands so its context remains explicit.
339
- - Actionability primitives: `collectBlockedByIds`, `resolveItemBlockers`, `collectDependencyBlockedIds`, and `computeActionabilityReport` expose the same edge-aware blocked/ready definition used by `pm next`, `pm context`, and `pm list-blocked`. Embedded schedulers can therefore classify custom lifecycle schemas without importing CLI or core modules.
339
+ - Actionability primitives: `collectBlockedByIds`, `resolveItemBlockers`, `collectDependencyBlockedIds`, and `computeActionabilityReport` expose the same edge-aware blocked/ready definition used by `pm next`, `pm context`, and `pm list --status blocked`. Embedded schedulers can therefore classify custom lifecycle schemas without importing CLI or core modules.
340
340
  - Dependency-governance primitives: `collectDanglingDependencyReferences`, `collectMissingDependencyTargetIds`, and `assembleWorkspaceRelationshipGraph` normalize hierarchy, scalar blockers, and structured dependencies into one graph while partitioning missing targets into actionable active holders, informational terminal-history holders, and the legacy `no-active-blocker` sentinel without mutating stored history.
341
341
  - Relationship graph primitives: `RelationshipKindRegistry`, `createRelationshipKindRegistry`, `assertRelationshipEdgeAllowed`, `RelationshipGraph`, `RelationshipEventLog`, `RelationshipEventStore`, `planRelationshipEventBackfill`, `buildRelationshipContext`, `buildDepsRelationshipContext`, `hierarchyAncestors`, `hierarchyDescendants`, `orderingPredecessors`, `orderingSuccessors`, `enumerateRelationshipPaths`, `auditWorkspaceRelationshipGraph`, `isOrderingRelationshipKind`, and `dependencyToRelationship` provide application-defined edge semantics, durable replay, deterministic legacy migration, bounded semantic traversal, policy-aware governance, and explainable context queries. Mutation adapters should call `assertRelationshipEdgeAllowed` with the active registry before persistence; it resolves aliases and honors custom `allowSelf` definitions while built-in self edges fail before item or history writes. `RelationshipEventLog.stream/project` and their durable-store equivalents page immutable prefixes and fold them into deterministic application state with exact version, processed-count, and as-of metadata. `RelationshipEventStore.appendBatch` validates a complete import under one cross-process lock and atomically publishes it; `skip_identical` resume mode rejects same-id semantic collisions. `RelationshipGraphAdapter`, `createRelationshipGraphSnapshot`, `syncRelationshipGraphAdapter`, `loadRelationshipGraphAdapter`, and `federateRelationshipGraphSnapshots` form the backend-neutral content-addressed projection boundary for database or remote graph packages. `MemoryRelationshipGraphAdapter`, `assertRelationshipGraphAdapterConformance`, and `createRelationshipGraphScaleFixture` give package authors a reference implementation, reusable compatibility contract, and lazy deterministic fixtures through one million nodes. See [Relationship graph semantics](RELATIONSHIP_GRAPH.md).
342
342
  - Built-in `recurs_from` records that the source is a later occurrence of the target. Its registry contract is directed, `source_after_target`, non-ordering, many-to-many, and persistent across terminal lifecycle states. Local mutation paths enforce strictly later source `created_at` metadata before item or history persistence and return structured source/target evidence when chronology is equal, reversed, or unverifiable. It therefore connects an incident family for traversal and analytics without reclassifying `supersedes` replacements or `duplicate_of` identity collapse.
@@ -1642,7 +1642,7 @@ const certified = certifyCompleteListResult(candidate);
1642
1642
 
1643
1643
  `PmCompleteListValidationError.receipt` lists every failed invariant and carries
1644
1644
  the exact recovery command
1645
- `pm list-all --full --strict-read --no-truncate --output-budget unbounded --json`.
1645
+ `pm list --all --full --strict-read --no-truncate --output-budget unbounded --json`.
1646
1646
  The helper never infers completeness from a large limit: derived-index reads,
1647
1647
  terminal-state filtering, duplicate ids, cursor/session projection, compaction,
1648
1648
  and any omission receipt all prevent certification.