@unbrained/pm-cli 2026.8.31 → 2026.9.2
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/.claude-plugin/marketplace.json +2 -2
- package/AGENTS.md +15 -13
- package/CHANGELOG.md +33 -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-mutation.js +8 -5
- package/dist/cli-bundle/bundle-manifest.json +129 -129
- package/dist/cli-bundle/chunks/{chunk-52JXYSDW.js → chunk-3WICXLVT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JIFYOJF7.js → chunk-DTGWEL23.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SXMHPK4V.js → chunk-FZ4Z2J4F.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-GOACULJW.js +13 -0
- package/dist/cli-bundle/chunks/{chunk-NW6LV3TU.js → chunk-NOPL37X4.js} +64 -64
- package/dist/cli-bundle/chunks/{chunk-OUGDA7NR.js → chunk-T6H5BZCP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IEFJ3ZEB.js → chunk-TAG4VC22.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-MWIN6OH2.js → chunk-UDW64J2W.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5DH5XCJL.js → chunk-X4RCGLTX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QZCIBZR3.js → chunk-Y7VOMSZT.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-ZLJIFSOE.js +35 -0
- package/dist/cli-bundle/chunks/{register-list-query-7C7DKZ2U.js → register-list-query-XYNX4ASQ.js} +2 -2
- package/dist/cli-bundle/chunks/register-mutation-WFQ7MJTX.js +20 -0
- package/dist/cli-bundle/chunks/{register-operations-IIMA5OKO.js → register-operations-JVTI7JPP.js} +2 -2
- package/dist/cli-bundle/chunks/{register-setup-52H36QCB.js → register-setup-KVNC5KPL.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-VJ7EFMFL.js → chunk-242AXYB2.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +16 -0
- package/dist/cli-bundle/focused-chunks/{chunk-FOMZ6NG5.js → chunk-MKHG3T76.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-JCOOAUHK.js → chunk-O67VDLOT.js} +48 -48
- package/dist/cli-bundle/focused-chunks/{chunk-UN34D63M.js → chunk-PF3E6Q36.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-APN4QN6R.js → chunk-RMRCQPWU.js} +2 -2
- package/dist/cli-bundle/focused-chunks/{chunk-BPWJ4QM5.js → chunk-S4U5CN5Q.js} +2 -2
- package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +158 -0
- package/dist/cli-bundle/main.js +2 -2
- package/dist/cli-bundle/sdk-contracts.js +1 -1
- package/dist/cli-bundle/sdk-core.js +25 -25
- 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 +32 -32
- 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/diagnostics/remediation.js +9 -4
- 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/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/generated/generated-error-code-catalog-part-1.js +14 -2
- package/dist/sdk/governance/health.js +77 -11
- package/dist/sdk/governance/validate.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 +1 -0
- package/dist/sdk/index.js +3 -2
- 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/merge/index.d.ts +1 -1
- package/dist/sdk/merge/index.js +3 -3
- package/dist/sdk/merge/receipts.d.ts +51 -1
- package/dist/sdk/merge/receipts.js +146 -35
- package/dist/sdk/merge/three-way.d.ts +3 -1
- package/dist/sdk/merge/three-way.js +9 -7
- package/dist/sdk/runtime-extended-actions.js +4 -4
- package/docs/AGENT_GUIDE.md +11 -3
- package/docs/ARCHITECTURE.md +5 -0
- package/docs/CLAUDE_CODE_PLUGIN.md +2 -2
- package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +24 -6
- package/docs/MCP_2026_07_28.md +9 -5
- package/docs/MCP_CAPABILITY_SURFACES.md +7 -1
- package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +11 -1
- package/docs/MERGE_SAFETY.md +44 -2
- package/docs/OUTPUT_TOKEN_ACCOUNTING.md +5 -3
- package/docs/PROGRESSIVE_TOOL_DISCOVERY.md +42 -0
- package/docs/README.md +1 -0
- package/docs/agent-task-token-baseline.json +157 -3
- package/docs/agent-task-transcripts.json +143 -0
- 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 +2 -2
- 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 +168 -2
- package/dist/cli-bundle/chunks/chunk-2XVV45NJ.js +0 -35
- package/dist/cli-bundle/chunks/chunk-3FCSFWZT.js +0 -13
- package/dist/cli-bundle/chunks/register-mutation-OI4BJLUX.js +0 -20
- package/dist/cli-bundle/focused-chunks/chunk-BMD42PUG.js +0 -158
- package/dist/cli-bundle/focused-chunks/chunk-EUTABA4M.js +0 -16
|
@@ -1,6 +1,7 @@
|
|
|
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
|
|
|
@@ -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.
|
package/docs/MERGE_SAFETY.md
CHANGED
|
@@ -97,7 +97,34 @@ 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`, bounded
|
|
109
|
+
`invalid_evidence[]`, `invalid_evidence_truncated`, and
|
|
110
|
+
`clone_local_evidence_resolved`. Each rejected candidate reports a stable
|
|
111
|
+
reason plus its `clone_local`, `durable`, or copy-consistency source. A safe
|
|
112
|
+
receipt filename is returned as `receipt_id`; unsafe candidate names are
|
|
113
|
+
represented only by `candidate_name_hash`, and malformed contents are never
|
|
114
|
+
returned. The detail list is capped at 100 rows while the count remains exact,
|
|
115
|
+
so automated gates stay token-bounded. Directory traversal distinguishes a
|
|
116
|
+
truly absent store from a non-directory or unreadable ancestor on Windows and
|
|
117
|
+
POSIX instead of treating platform-specific `ENOENT`/`ENOTDIR` spellings as
|
|
118
|
+
equivalent. Full health also cross-checks the privacy-safe receipt summaries in
|
|
119
|
+
append-only history against valid pending and reconciled evidence. Missing
|
|
120
|
+
evidence emits `merge_receipt_history_reference_missing:<n>` with bounded item,
|
|
121
|
+
history-line, and receipt-id-or-hash coordinates. Its remediation enumerates
|
|
122
|
+
the exact references and directs recovery from an authoritative clone or
|
|
123
|
+
backup; it never recommends deleting receipts or rewriting history. The CLI
|
|
124
|
+
exits nonzero when evidence is incomplete, even when the valid-receipt count is
|
|
125
|
+
zero. Current SDK implementations always emit the new field, while its optional
|
|
126
|
+
type preserves structural compatibility for existing typed adapters and test
|
|
127
|
+
fixtures. `runMergeReceiptReport` remains the compatible valid-only report.
|
|
101
128
|
|
|
102
129
|
## Cross-branch id collision safety
|
|
103
130
|
|
|
@@ -189,7 +216,22 @@ pm merge reconcile --dry-run --json
|
|
|
189
216
|
|
|
190
217
|
`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
218
|
|
|
192
|
-
History events now declare an item-hash epoch.
|
|
219
|
+
History events now declare an item-hash epoch. Epochs are immutable writer
|
|
220
|
+
contracts, not aliases for the current item serializer: epoch 1 sorts linked
|
|
221
|
+
tests; epoch 2 preserves their insertion order and has both an earlier
|
|
222
|
+
field-frozen form and a later expanded form because the writer surface grew
|
|
223
|
+
before the marker advanced; epoch 3 is the current form. Verification accepts
|
|
224
|
+
both recorded epoch-2 forms without allowing one entry to mix them, and repair
|
|
225
|
+
preserves the form evidenced by each event. Unversioned streams are verified
|
|
226
|
+
against the supported legacy canonicalizations. Current-document comparison
|
|
227
|
+
selects the resolved epoch candidate that matches the chain head. A union merge
|
|
228
|
+
may consume suffixes written by both epoch-2 forms, but its synthesized output
|
|
229
|
+
uses one form for the complete re-anchored stream so every stored `after_hash`
|
|
230
|
+
is exactly the next stored `before_hash`. An unknown explicit epoch is
|
|
231
|
+
reported as `unsupported_item_hash_version` and repair refuses to guess. This
|
|
232
|
+
keeps version incompatibility distinct from item corruption and is tracked by
|
|
233
|
+
[pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon) and
|
|
234
|
+
[pm-2qahia](../.agents/pm/issues/pm-2qahia.toon).
|
|
193
235
|
|
|
194
236
|
## Delete versus modify policy
|
|
195
237
|
|
|
@@ -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
|
@@ -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.
|
|
@@ -1,11 +1,165 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 4,
|
|
3
3
|
"transcript_version": 2,
|
|
4
|
-
"transcript_digest": "sha256:
|
|
4
|
+
"transcript_digest": "sha256:4f9e96bb6ce12bbbeb2514e4bd5958d201c4e62e95083bcbebd749d1e48cc82d",
|
|
5
5
|
"estimator": "ceil(utf8_bytes / 4)",
|
|
6
6
|
"measurement_scope": "output_before_token_accounting",
|
|
7
7
|
"published_with_release": true,
|
|
8
|
+
"orientation": {
|
|
9
|
+
"canonical_task_id": "orientation-context-intent",
|
|
10
|
+
"required_capabilities": [
|
|
11
|
+
"actionable_work",
|
|
12
|
+
"active_ownership",
|
|
13
|
+
"workspace_state"
|
|
14
|
+
],
|
|
15
|
+
"measured_winner_tokens": 1055,
|
|
16
|
+
"protocols": [
|
|
17
|
+
{
|
|
18
|
+
"task_id": "orientation-context-intent",
|
|
19
|
+
"command_count": 1,
|
|
20
|
+
"estimated_tokens": 1055,
|
|
21
|
+
"capabilities": [
|
|
22
|
+
"actionable_work",
|
|
23
|
+
"active_ownership",
|
|
24
|
+
"workspace_state"
|
|
25
|
+
],
|
|
26
|
+
"capability_evidence": {
|
|
27
|
+
"actionable_work": [
|
|
28
|
+
{
|
|
29
|
+
"step_id": "context",
|
|
30
|
+
"field_path": "hierarchy"
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"active_ownership": [
|
|
34
|
+
{
|
|
35
|
+
"step_id": "context",
|
|
36
|
+
"field_path": "activity"
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"workspace_state": [
|
|
40
|
+
{
|
|
41
|
+
"step_id": "context",
|
|
42
|
+
"field_path": "summary.active_items"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"task_id": "orientation-operating-rules",
|
|
49
|
+
"command_count": 4,
|
|
50
|
+
"estimated_tokens": 2293,
|
|
51
|
+
"capabilities": [
|
|
52
|
+
"actionable_work",
|
|
53
|
+
"active_ownership",
|
|
54
|
+
"workspace_state"
|
|
55
|
+
],
|
|
56
|
+
"capability_evidence": {
|
|
57
|
+
"actionable_work": [
|
|
58
|
+
{
|
|
59
|
+
"step_id": "open",
|
|
60
|
+
"field_path": "items"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"active_ownership": [
|
|
64
|
+
{
|
|
65
|
+
"step_id": "in-progress",
|
|
66
|
+
"field_path": "items"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"workspace_state": [
|
|
70
|
+
{
|
|
71
|
+
"step_id": "context",
|
|
72
|
+
"field_path": "summary.active_items"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"task_id": "orientation-contracts-next",
|
|
79
|
+
"command_count": 2,
|
|
80
|
+
"estimated_tokens": 4798,
|
|
81
|
+
"capabilities": [
|
|
82
|
+
"actionable_work",
|
|
83
|
+
"active_ownership",
|
|
84
|
+
"workspace_state"
|
|
85
|
+
],
|
|
86
|
+
"capability_evidence": {
|
|
87
|
+
"actionable_work": [
|
|
88
|
+
{
|
|
89
|
+
"step_id": "next",
|
|
90
|
+
"field_path": "recommended.id"
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
"active_ownership": [
|
|
94
|
+
{
|
|
95
|
+
"step_id": "next",
|
|
96
|
+
"field_path": "held_by_others"
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"workspace_state": [
|
|
100
|
+
{
|
|
101
|
+
"step_id": "next",
|
|
102
|
+
"field_path": "summary.in_progress"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
8
109
|
"tasks": [
|
|
110
|
+
{
|
|
111
|
+
"id": "orientation-context-intent",
|
|
112
|
+
"max_estimated_tokens": 1055,
|
|
113
|
+
"steps": [
|
|
114
|
+
{
|
|
115
|
+
"id": "context",
|
|
116
|
+
"max_estimated_tokens": 1055,
|
|
117
|
+
"accounting_mode": "self_reported"
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "orientation-contracts-next",
|
|
123
|
+
"max_estimated_tokens": 4798,
|
|
124
|
+
"steps": [
|
|
125
|
+
{
|
|
126
|
+
"id": "contracts",
|
|
127
|
+
"max_estimated_tokens": 4111,
|
|
128
|
+
"accounting_mode": "self_reported"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": "next",
|
|
132
|
+
"max_estimated_tokens": 687,
|
|
133
|
+
"accounting_mode": "self_reported"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "orientation-operating-rules",
|
|
139
|
+
"max_estimated_tokens": 2293,
|
|
140
|
+
"steps": [
|
|
141
|
+
{
|
|
142
|
+
"id": "context",
|
|
143
|
+
"max_estimated_tokens": 1055,
|
|
144
|
+
"accounting_mode": "self_reported"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"id": "search",
|
|
148
|
+
"max_estimated_tokens": 164,
|
|
149
|
+
"accounting_mode": "self_reported"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "open",
|
|
153
|
+
"max_estimated_tokens": 878,
|
|
154
|
+
"accounting_mode": "self_reported"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "in-progress",
|
|
158
|
+
"max_estimated_tokens": 196,
|
|
159
|
+
"accounting_mode": "self_reported"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
},
|
|
9
163
|
{
|
|
10
164
|
"id": "context-bootstrap",
|
|
11
165
|
"max_estimated_tokens": 1978,
|
|
@@ -107,5 +261,5 @@
|
|
|
107
261
|
]
|
|
108
262
|
}
|
|
109
263
|
],
|
|
110
|
-
"composite_max_estimated_tokens":
|
|
264
|
+
"composite_max_estimated_tokens": 12477
|
|
111
265
|
}
|
|
@@ -1,6 +1,149 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 2,
|
|
3
|
+
"orientation": {
|
|
4
|
+
"canonical_task_id": "orientation-context-intent",
|
|
5
|
+
"required_capabilities": [
|
|
6
|
+
"workspace_state",
|
|
7
|
+
"active_ownership",
|
|
8
|
+
"actionable_work"
|
|
9
|
+
],
|
|
10
|
+
"protocols": [
|
|
11
|
+
{
|
|
12
|
+
"task_id": "orientation-context-intent",
|
|
13
|
+
"capabilities": [
|
|
14
|
+
"workspace_state",
|
|
15
|
+
"active_ownership",
|
|
16
|
+
"actionable_work"
|
|
17
|
+
],
|
|
18
|
+
"capability_evidence": {
|
|
19
|
+
"workspace_state": [
|
|
20
|
+
{ "step_id": "context", "field_path": "summary.active_items" }
|
|
21
|
+
],
|
|
22
|
+
"active_ownership": [
|
|
23
|
+
{ "step_id": "context", "field_path": "activity" }
|
|
24
|
+
],
|
|
25
|
+
"actionable_work": [
|
|
26
|
+
{ "step_id": "context", "field_path": "hierarchy" }
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"task_id": "orientation-contracts-next",
|
|
32
|
+
"capabilities": [
|
|
33
|
+
"workspace_state",
|
|
34
|
+
"active_ownership",
|
|
35
|
+
"actionable_work"
|
|
36
|
+
],
|
|
37
|
+
"capability_evidence": {
|
|
38
|
+
"workspace_state": [
|
|
39
|
+
{ "step_id": "next", "field_path": "summary.in_progress" }
|
|
40
|
+
],
|
|
41
|
+
"active_ownership": [
|
|
42
|
+
{ "step_id": "next", "field_path": "held_by_others" }
|
|
43
|
+
],
|
|
44
|
+
"actionable_work": [
|
|
45
|
+
{ "step_id": "next", "field_path": "recommended.id" }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"task_id": "orientation-operating-rules",
|
|
51
|
+
"capabilities": [
|
|
52
|
+
"workspace_state",
|
|
53
|
+
"active_ownership",
|
|
54
|
+
"actionable_work"
|
|
55
|
+
],
|
|
56
|
+
"capability_evidence": {
|
|
57
|
+
"workspace_state": [
|
|
58
|
+
{ "step_id": "context", "field_path": "summary.active_items" }
|
|
59
|
+
],
|
|
60
|
+
"active_ownership": [
|
|
61
|
+
{ "step_id": "in-progress", "field_path": "items" }
|
|
62
|
+
],
|
|
63
|
+
"actionable_work": [{ "step_id": "open", "field_path": "items" }]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
3
68
|
"tasks": [
|
|
69
|
+
{
|
|
70
|
+
"id": "orientation-context-intent",
|
|
71
|
+
"description": "Build sufficient cold-start workspace, ownership, and actionable-work context with the bounded orientation intent.",
|
|
72
|
+
"steps": [
|
|
73
|
+
{
|
|
74
|
+
"id": "context",
|
|
75
|
+
"args": ["context", "--for", "orient", "--limit", "10"],
|
|
76
|
+
"expected_exit_code": 0,
|
|
77
|
+
"expected_output_kind": "diagnostic",
|
|
78
|
+
"expected_accounting_mode": "self_reported",
|
|
79
|
+
"required_fields": ["summary.active_items", "hierarchy", "activity"]
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "orientation-contracts-next",
|
|
85
|
+
"description": "Compare the proposed contracts-summary plus next cold-start protocol on the same fixed workspace.",
|
|
86
|
+
"steps": [
|
|
87
|
+
{
|
|
88
|
+
"id": "contracts",
|
|
89
|
+
"args": ["contracts", "--summary"],
|
|
90
|
+
"expected_exit_code": 0,
|
|
91
|
+
"expected_output_kind": "collection",
|
|
92
|
+
"expected_accounting_mode": "self_reported",
|
|
93
|
+
"required_fields": ["commands"]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"id": "next",
|
|
97
|
+
"args": ["next", "--for", "execute", "--ready-only", "--limit", "3"],
|
|
98
|
+
"expected_exit_code": 0,
|
|
99
|
+
"expected_output_kind": "diagnostic",
|
|
100
|
+
"expected_accounting_mode": "self_reported",
|
|
101
|
+
"required_fields": [
|
|
102
|
+
"summary.in_progress",
|
|
103
|
+
"held_by_others",
|
|
104
|
+
"recommended.id"
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"id": "orientation-operating-rules",
|
|
111
|
+
"description": "Compare the historical context, search, open-list, and in-progress-list orientation sequence.",
|
|
112
|
+
"steps": [
|
|
113
|
+
{
|
|
114
|
+
"id": "context",
|
|
115
|
+
"args": ["context", "--for", "orient", "--limit", "10"],
|
|
116
|
+
"expected_exit_code": 0,
|
|
117
|
+
"expected_output_kind": "diagnostic",
|
|
118
|
+
"expected_accounting_mode": "self_reported",
|
|
119
|
+
"required_fields": ["summary.active_items", "hierarchy", "activity"]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "search",
|
|
123
|
+
"args": ["search", "agent task", "--status", "all", "--limit", "10"],
|
|
124
|
+
"expected_exit_code": 0,
|
|
125
|
+
"expected_output_kind": "collection",
|
|
126
|
+
"expected_accounting_mode": "self_reported",
|
|
127
|
+
"required_fields": ["items"]
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "open",
|
|
131
|
+
"args": ["list", "--status", "open", "--limit", "20"],
|
|
132
|
+
"expected_exit_code": 0,
|
|
133
|
+
"expected_output_kind": "collection",
|
|
134
|
+
"expected_accounting_mode": "self_reported",
|
|
135
|
+
"required_fields": ["items"]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "in-progress",
|
|
139
|
+
"args": ["list", "--status", "in_progress", "--limit", "20"],
|
|
140
|
+
"expected_exit_code": 0,
|
|
141
|
+
"expected_output_kind": "collection",
|
|
142
|
+
"expected_accounting_mode": "self_reported",
|
|
143
|
+
"required_fields": ["items"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
4
147
|
{
|
|
5
148
|
"id": "context-bootstrap",
|
|
6
149
|
"description": "Orient in a scaled workspace and inspect the canonical focus item.",
|
|
@@ -4,12 +4,12 @@ Tracker: `pm-f05lsg`.
|
|
|
4
4
|
|
|
5
5
|
Every catalog code is listed. An `uncovered` row is an explicit closure obligation, never an omission or implied approval.
|
|
6
6
|
|
|
7
|
-
- Catalog error codes:
|
|
7
|
+
- Catalog error codes: 355
|
|
8
8
|
- Executable error codes: 19
|
|
9
9
|
- Executable-code ratchet floor: 18
|
|
10
10
|
- Required executable canonical codes: `bulk_ids_input_empty`, `bulk_ids_input_missing_path`, `bulk_ids_input_unreadable`, `invalid_argument_value`, `manifest_unknown_key`, `missing_lifecycle_target`, `missing_required_argument`, `no_version_bounds_declared`, `projection_options_mutually_exclusive`, `tracker_not_initialized`, `tracker_root_missing`, `tracker_root_not_directory`, `tracker_root_unreadable`, `unknown_context_intent`, `unknown_field_projection`, `unknown_option`, `unknown_subcommand`
|
|
11
|
-
- Uncovered error codes:
|
|
12
|
-
- Coverage fraction: 0.
|
|
11
|
+
- Uncovered error codes: 336
|
|
12
|
+
- Coverage fraction: 0.053521
|
|
13
13
|
- Closed-domain probes: 19
|
|
14
14
|
- Grammar probes: 94
|
|
15
15
|
|
|
@@ -186,6 +186,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
|
|
|
186
186
|
| `merge_decisions_unreviewed` | `merge_decisions_unreviewed` | uncovered | none | 0 |
|
|
187
187
|
| `merge_git_config_unwritable` | `merge_git_config_unwritable` | uncovered | none | 0 |
|
|
188
188
|
| `merge_receipt_evidence_invalid` | `merge_receipt_evidence_invalid` | uncovered | none | 0 |
|
|
189
|
+
| `merge_receipt_history_reference_missing` | `merge_receipt_history_reference_missing` | uncovered | none | 0 |
|
|
189
190
|
| `merge_receipts_pending` | `merge_receipts_pending` | uncovered | none | 0 |
|
|
190
191
|
| `merge_reconcile_receipt_evidence_untrusted` | `merge_reconcile_receipt_evidence_untrusted` | uncovered | none | 0 |
|
|
191
192
|
| `merge_root_not_found` | `merge_root_not_found` | uncovered | none | 0 |
|
|
@@ -7,12 +7,14 @@ admission reliability owned by
|
|
|
7
7
|
Each result starts from a fresh isolated workspace containing exactly one item.
|
|
8
8
|
The command runs in a fresh Node v26.5.0 process on
|
|
9
9
|
linux/x64; setup and fixture generation are
|
|
10
|
-
outside the timed interval.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
outside the timed interval. The default gate measures ten post-warmup fresh
|
|
11
|
+
processes per command and uses the best observed latency, which keeps the
|
|
12
|
+
immutable ratchets meaningful under transient host contention; the report
|
|
13
|
+
retains p50 and p95 evidence. RSS admission uses the measured median so one
|
|
14
|
+
page-level outlier cannot false-fail the gate; the maximum remains in the report
|
|
15
|
+
as diagnostic evidence. Every post-warmup RSS sample must be a finite
|
|
16
|
+
measurement; an unavailable sample makes the admission median unavailable and
|
|
17
|
+
fails closed when a budget exists. Admission adds a fixed 512 KiB noise margin
|
|
16
18
|
without changing the committed budget; a majority persistent increase beyond
|
|
17
19
|
that bounded margin still fails.
|
|
18
20
|
|
package/marketplace.json
CHANGED
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
|
|
9
|
-
"version": "2026.
|
|
9
|
+
"version": "2026.9.2"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "pm-claude",
|
|
14
14
|
"source": "./plugins/pm-claude",
|
|
15
15
|
"description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
|
|
16
|
-
"version": "2026.
|
|
16
|
+
"version": "2026.9.2",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "unbrained",
|
|
19
19
|
"url": "https://github.com/unbraind/pm-cli"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-cli",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.9.2",
|
|
4
4
|
"description": "Git-native project management CLI for humans and agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "pnpm@11.10.0",
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
"fast-check": "^4.9.0",
|
|
232
232
|
"greptile": "^3.4.2",
|
|
233
233
|
"jscpd": "^5.0.16",
|
|
234
|
-
"tsx": "^4.23.
|
|
234
|
+
"tsx": "^4.23.13",
|
|
235
235
|
"typescript": "^6.0.3",
|
|
236
236
|
"typescript-eslint": "^8.68.0",
|
|
237
237
|
"vitest": "^4.1.11"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbrained/pm-digital-twin",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.9.2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
|