@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.
- package/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
- package/.agents/skills/README.md +1 -1
- package/.agents/skills/pm-developer/SKILL.md +1 -1
- package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +2 -2
- package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +1 -1
- package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +1 -1
- package/.agents/skills/pm-extensions/SKILL.md +2 -2
- package/.agents/skills/pm-extensions/references/AUTHORING.md +1 -1
- package/.agents/skills/pm-extensions/references/LIFECYCLE.md +1 -1
- package/.agents/skills/pm-sdk/SKILL.md +1 -1
- package/.agents/skills/pm-user/SKILL.md +2 -2
- package/.agents/skills/pm-user/references/WORKFLOWS.md +2 -2
- package/.claude-plugin/marketplace.json +2 -2
- package/AGENTS.md +16 -14
- package/CHANGELOG.md +41 -6
- package/README.md +3 -3
- package/dist/cli/commands/merge.d.ts +1 -1
- package/dist/cli/commands/merge.js +3 -3
- package/dist/cli/register-list-query.js +32 -17
- package/dist/cli/register-mutation.js +8 -5
- package/dist/cli/register-operations.d.ts +2 -0
- package/dist/cli/register-operations.js +20 -9
- package/dist/cli-bundle/bundle-manifest.json +144 -144
- package/dist/cli-bundle/chunks/{chunk-CMIEDWAY.js → chunk-2MC2LCXZ.js} +41 -41
- package/dist/cli-bundle/chunks/{chunk-WS2GJQVG.js → chunk-3WICXLVT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7SKMLSMX.js → chunk-6XIIGE7U.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-ALKKAUFN.js +35 -0
- package/dist/cli-bundle/chunks/{chunk-MTTKAUBX.js → chunk-DTGWEL23.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-GOACULJW.js +13 -0
- package/dist/cli-bundle/chunks/chunk-NOPL37X4.js +205 -0
- package/dist/cli-bundle/chunks/{chunk-2UETTHY6.js → chunk-TAG4VC22.js} +30 -30
- package/dist/cli-bundle/chunks/{chunk-3TEF3HM5.js → chunk-U45JXJCC.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TGNAA66W.js → chunk-X4RCGLTX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2MKLQL2E.js → chunk-Y7VOMSZT.js} +2 -2
- package/dist/cli-bundle/chunks/{register-list-query-OMKJ5ONN.js → register-list-query-XYNX4ASQ.js} +11 -11
- package/dist/cli-bundle/chunks/register-mutation-2MVLRS3J.js +20 -0
- package/dist/cli-bundle/chunks/register-operations-WCIDXBU3.js +2 -0
- package/dist/cli-bundle/chunks/{register-setup-GLQ5SYV3.js → register-setup-KVNC5KPL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-HVQ22RC4.js → chunk-2FEZ5SKM.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-Y3JJXRVK.js → chunk-4O4CJAR6.js} +5 -5
- package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-LYFWQMVC.js → chunk-BEVHCEWG.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-TDK3OCX3.js → chunk-FWPLDEXF.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +2 -0
- package/dist/cli-bundle/focused-chunks/{chunk-JZYPPMXF.js → chunk-KB5OFSFD.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-73EDXGYE.js → chunk-MKHG3T76.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-3AVAWVZA.js → chunk-PF3E6Q36.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-AD6ULRAF.js → chunk-QDFJIRKN.js} +4 -4
- package/dist/cli-bundle/focused-chunks/{chunk-RKOKG43G.js → chunk-RMRCQPWU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-XXOWRJZ5.js → chunk-S4U5CN5Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-THEPQMLX.js → chunk-SVXJYD6G.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +158 -0
- package/dist/cli-bundle/focused-chunks/chunk-Y6JJIX6I.js +51 -0
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-authoring.js +1 -1
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +27 -27
- package/dist/cli-bundle/sdk-governance.js +1 -1
- package/dist/cli-bundle/sdk-graph.js +1 -1
- package/dist/cli-bundle/sdk-merge.js +33 -33
- package/dist/cli-bundle/sdk-query.js +1 -1
- package/dist/cli-bundle/sdk-runtime.js +1 -1
- package/dist/cli-bundle/sdk-testing.js +1 -1
- package/dist/cli-bundle/sdk.js +10 -10
- package/dist/core/history/drift-scan.js +6 -6
- package/dist/core/history/history.d.ts +6 -0
- package/dist/core/history/history.js +47 -5
- package/dist/core/history/replay.d.ts +12 -1
- package/dist/core/history/replay.js +60 -39
- package/dist/core/schema/runtime-schema.d.ts +4 -0
- package/dist/core/schema/runtime-schema.js +60 -48
- package/dist/core/schema/status-defs-file.js +5 -2
- package/dist/mcp/legacy-adapter.d.ts +11 -2
- package/dist/mcp/legacy-adapter.js +26 -12
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +78 -15
- package/dist/mcp/tool-definitions.js +56 -2
- package/dist/sdk/agent-capability-contracts.js +4 -2
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +6 -2
- package/dist/sdk/cli-contracts/grammar-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/grammar-contracts.js +12 -2
- package/dist/sdk/cli-contracts/runtime-contracts.js +3 -2
- package/dist/sdk/cli-contracts/tool-schema.js +11 -3
- package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
- package/dist/sdk/governance/health.js +17 -6
- package/dist/sdk/governance/status-role-diagnostics.d.ts +27 -0
- package/dist/sdk/governance/status-role-diagnostics.js +36 -0
- package/dist/sdk/governance/validate-normalization.d.ts +6 -0
- package/dist/sdk/governance/validate-normalization.js +37 -0
- package/dist/sdk/governance/validate.d.ts +1 -1
- package/dist/sdk/governance/validate.js +20 -35
- package/dist/sdk/governance/workspace-position.d.ts +69 -0
- package/dist/sdk/governance/workspace-position.js +164 -0
- package/dist/sdk/governance.d.ts +2 -0
- package/dist/sdk/governance.js +4 -2
- package/dist/sdk/history-read.js +14 -6
- package/dist/sdk/history-repair.js +17 -10
- package/dist/sdk/index.d.ts +2 -1
- package/dist/sdk/index.js +4 -3
- package/dist/sdk/init-agent-guidance.js +4 -4
- package/dist/sdk/lifecycle/update.js +23 -10
- package/dist/sdk/mcp/discovery.d.ts +152 -0
- package/dist/sdk/mcp/discovery.js +495 -0
- package/dist/sdk/mcp/protocol.d.ts +10 -2
- package/dist/sdk/mcp/protocol.js +15 -4
- package/dist/sdk/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +27 -1
- package/dist/sdk/merge/receipts.js +27 -8
- package/dist/sdk/merge/three-way.d.ts +3 -1
- package/dist/sdk/merge/three-way.js +9 -7
- package/dist/sdk/query/context.js +11 -14
- package/dist/sdk/query/list.d.ts +2 -0
- package/dist/sdk/query/list.js +33 -12
- package/dist/sdk/runtime-extended-actions.js +10 -6
- package/dist/sdk/schema.js +12 -2
- package/dist/sdk/test/execution.d.ts +15 -0
- package/dist/sdk/test/execution.js +35 -27
- package/docs/AGENT_GUIDE.md +12 -4
- package/docs/AGENT_PROVENANCE_ADR.md +1 -1
- package/docs/AGENT_RUNTIME_PRIMITIVES.md +2 -2
- package/docs/ARCHITECTURE.md +5 -0
- package/docs/CLAUDE_CODE_PLUGIN.md +5 -5
- package/docs/COMMANDS.md +12 -12
- package/docs/CONFIGURATION.md +1 -1
- package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +14 -5
- package/docs/DEFECT_RECURRENCE.md +2 -0
- package/docs/MCP_2026_07_28.md +33 -9
- package/docs/MCP_2026_07_28_CONFORMANCE.md +1 -0
- package/docs/MCP_CAPABILITY_SURFACES.md +7 -1
- package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +15 -3
- package/docs/MERGE_SAFETY.md +30 -2
- package/docs/ONBOARDING.md +1 -1
- package/docs/OUTPUT_TOKEN_ACCOUNTING.md +5 -3
- package/docs/PROGRESSIVE_TOOL_DISCOVERY.md +42 -0
- package/docs/README.md +3 -1
- package/docs/READ_OUTPUT_CONTRACTS.md +1 -1
- package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +1 -1
- package/docs/SDK.md +3 -3
- package/docs/TESTING.md +23 -14
- package/docs/WORKSPACE_POSITION_AND_LIFECYCLE.md +113 -0
- package/docs/agent-task-token-baseline.json +157 -3
- package/docs/agent-task-transcripts.json +143 -0
- package/docs/examples/policy-restricted-extension/README.md +2 -2
- package/docs/examples/starter-extension/README.md +1 -1
- package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
- package/docs/performance/cli-transport-overhead.md +8 -6
- package/marketplace.json +2 -2
- package/package.json +4 -4
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-digital-twin/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/README.md +4 -3
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/sdk/public-surface.json +314 -10
- package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +0 -34
- package/dist/cli-bundle/chunks/chunk-GNWPTEBW.js +0 -205
- package/dist/cli-bundle/chunks/chunk-N6OR6FAR.js +0 -13
- package/dist/cli-bundle/chunks/register-mutation-QBSNCOY3.js +0 -20
- package/dist/cli-bundle/chunks/register-operations-UC77FQZC.js +0 -2
- package/dist/cli-bundle/focused-chunks/chunk-3UMBF26I.js +0 -158
- package/dist/cli-bundle/focused-chunks/chunk-AXZ5AJAF.js +0 -50
- package/dist/cli-bundle/focused-chunks/chunk-G6PATS5E.js +0 -16
- 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
|
|
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`,
|
|
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
|
|
138
|
-
pm
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -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
|
|
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
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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:
|
package/docs/MCP_2026_07_28.md
CHANGED
|
@@ -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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
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
|
|
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
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -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.
|
|
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
|
|
package/docs/ONBOARDING.md
CHANGED
|
@@ -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),
|
|
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
|
|
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
|
|
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
|
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
|
|
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
|
|
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
|
|
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.
|