@unbrained/pm-cli 2026.8.22 → 2026.8.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +42 -1
  3. package/dist/cli/description-stdin.js +5 -4
  4. package/dist/cli/error-guidance.d.ts +13 -0
  5. package/dist/cli/error-guidance.js +62 -6
  6. package/dist/cli/extension-command-help.d.ts +5 -0
  7. package/dist/cli/extension-command-help.js +6 -2
  8. package/dist/cli/help-content.d.ts +5 -0
  9. package/dist/cli/help-content.js +56 -3
  10. package/dist/cli/help-json-payload.d.ts +5 -2
  11. package/dist/cli/help-json-payload.js +57 -17
  12. package/dist/cli/main.d.ts +3 -0
  13. package/dist/cli/main.js +39 -5
  14. package/dist/cli/register-annotations.js +5 -5
  15. package/dist/cli/register-mutation.js +77 -31
  16. package/dist/cli/register-operations.d.ts +73 -0
  17. package/dist/cli/register-operations.js +39 -14
  18. package/dist/cli/register-setup.js +3 -3
  19. package/dist/cli/schema-registration-helpers.d.ts +8 -1
  20. package/dist/cli/schema-registration-helpers.js +14 -5
  21. package/dist/cli-bundle/bundle-manifest.json +155 -155
  22. package/dist/cli-bundle/chunks/chunk-AGUL3HUT.js +3 -0
  23. package/dist/cli-bundle/chunks/{chunk-WG4STC36.js → chunk-DJNJBWAQ.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-MYYI3ZOA.js → chunk-I5Q7QSZX.js} +2 -2
  25. package/dist/cli-bundle/chunks/chunk-IW72J5FW.js +2 -0
  26. package/dist/cli-bundle/chunks/{chunk-BWX4SK46.js → chunk-L22NP5MA.js} +66 -66
  27. package/dist/cli-bundle/chunks/chunk-MKE6MD2K.js +36 -0
  28. package/dist/cli-bundle/chunks/{chunk-MZTZQTMS.js → chunk-NXBFO63A.js} +2 -2
  29. package/dist/cli-bundle/chunks/chunk-TEQDR5KI.js +202 -0
  30. package/dist/cli-bundle/chunks/chunk-X7WWQDYQ.js +2 -0
  31. package/dist/cli-bundle/chunks/chunk-YOLLRCLY.js +13 -0
  32. package/dist/cli-bundle/chunks/{chunk-U6GQ4VMV.js → chunk-ZAVCS2GH.js} +4 -4
  33. package/dist/cli-bundle/chunks/{register-list-query-HZKBQNWW.js → register-list-query-37A4P6O4.js} +2 -2
  34. package/dist/cli-bundle/chunks/register-mutation-TBJDHYIT.js +20 -0
  35. package/dist/cli-bundle/chunks/register-operations-WRZNEBUM.js +2 -0
  36. package/dist/cli-bundle/chunks/{register-setup-QK4OTOXN.js → register-setup-H4PDLACD.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-GMYPD4FX.js → chunk-4WP7LNE3.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-6MUTDXMP.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-6Z24ZMU3.js +2 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-2ARQGDDW.js → chunk-BFA6KKCI.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/chunk-CWCN5RLO.js +26 -0
  42. package/dist/cli-bundle/focused-chunks/chunk-FCTT4CZU.js +5 -0
  43. package/dist/cli-bundle/focused-chunks/chunk-GJR6YEMR.js +156 -0
  44. package/dist/cli-bundle/focused-chunks/{chunk-2POVTNLY.js → chunk-IMWTYKII.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/{chunk-D6RBZEJJ.js → chunk-IZNRRCU3.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-PMGJUFNQ.js → chunk-MNPECIRL.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-A2BC5PQL.js → chunk-O4ZXNJMT.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/chunk-Q63PSLO4.js +2 -0
  49. package/dist/cli-bundle/focused-chunks/chunk-QBP5FSBX.js +4 -0
  50. package/dist/cli-bundle/focused-chunks/{chunk-R6SR45XU.js → chunk-QV5UP27O.js} +48 -47
  51. package/dist/cli-bundle/focused-chunks/chunk-RASVBJX5.js +8 -0
  52. package/dist/cli-bundle/focused-chunks/{chunk-E2EWYPY6.js → chunk-RPRLENVA.js} +2 -2
  53. package/dist/cli-bundle/focused-chunks/chunk-TOFVXBWA.js +19 -0
  54. package/dist/cli-bundle/focused-chunks/{chunk-6S2MO3Q3.js → chunk-WZLSSGEU.js} +2 -2
  55. package/dist/cli-bundle/main.js +18 -17
  56. package/dist/cli-bundle/sdk-authoring.js +1 -1
  57. package/dist/cli-bundle/sdk-contracts.js +2 -2
  58. package/dist/cli-bundle/sdk-core.js +41 -41
  59. package/dist/cli-bundle/sdk-governance.js +1 -1
  60. package/dist/cli-bundle/sdk-graph.js +1 -1
  61. package/dist/cli-bundle/sdk-merge.js +33 -32
  62. package/dist/cli-bundle/sdk-query.js +1 -1
  63. package/dist/cli-bundle/sdk-runtime.js +1 -1
  64. package/dist/cli-bundle/sdk-testing.js +1 -1
  65. package/dist/cli-bundle/sdk.js +6 -5
  66. package/dist/core/config/nested-settings.js +8 -2
  67. package/dist/core/config/positional-value.d.ts +1 -1
  68. package/dist/core/config/positional-value.js +5 -2
  69. package/dist/core/extensions/command-metadata-contract.d.ts +10 -0
  70. package/dist/core/extensions/command-metadata-contract.js +23 -0
  71. package/dist/core/extensions/command-visibility-tier.js +12 -2
  72. package/dist/core/extensions/extension-types.d.ts +6 -0
  73. package/dist/core/extensions/extension-types.js +2 -2
  74. package/dist/core/extensions/loader.js +4 -3
  75. package/dist/core/history/history.js +3 -3
  76. package/dist/core/io/body-file.js +7 -2
  77. package/dist/core/io/bulk-ids-input.d.ts +24 -0
  78. package/dist/core/io/bulk-ids-input.js +113 -0
  79. package/dist/core/item/item-format.js +66 -12
  80. package/dist/core/item/parse.d.ts +22 -2
  81. package/dist/core/item/parse.js +97 -4
  82. package/dist/core/reproducibility/context.d.ts +4 -0
  83. package/dist/core/reproducibility/context.js +14 -8
  84. package/dist/core/shared/author.d.ts +55 -1
  85. package/dist/core/shared/author.js +333 -16
  86. package/dist/core/shared/constants.js +3 -2
  87. package/dist/core/store/settings-validator.d.ts +1 -0
  88. package/dist/core/store/settings-validator.js +6 -3
  89. package/dist/core/store/settings.js +5 -2
  90. package/dist/mcp/server.d.ts +4 -3
  91. package/dist/mcp/server.js +44 -16
  92. package/dist/sdk/agent/identity-config.d.ts +63 -0
  93. package/dist/sdk/agent/identity-config.js +107 -0
  94. package/dist/sdk/agent/refusal-closure-census.d.ts +66 -0
  95. package/dist/sdk/agent/refusal-closure-census.js +144 -0
  96. package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
  97. package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
  98. package/dist/sdk/agent-capability-contracts.d.ts +34 -1
  99. package/dist/sdk/agent-capability-contracts.js +104 -6
  100. package/dist/sdk/annotations.d.ts +2 -0
  101. package/dist/sdk/annotations.js +25 -7
  102. package/dist/sdk/cli-contracts/agent-output-contracts.js +6 -4
  103. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
  104. package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
  105. package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
  106. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
  107. package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
  108. package/dist/sdk/cli-contracts/tool-parameter-tables.js +58 -2
  109. package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
  110. package/dist/sdk/cli-contracts/tool-schema.js +14 -3
  111. package/dist/sdk/cli-contracts/typed-action-inputs.d.ts +4 -1
  112. package/dist/sdk/cli-contracts/typed-action-inputs.js +2 -2
  113. package/dist/sdk/cli-contracts.d.ts +3 -3
  114. package/dist/sdk/cli-contracts.js +4 -4
  115. package/dist/sdk/comments.js +15 -7
  116. package/dist/sdk/config.d.ts +6 -1
  117. package/dist/sdk/config.js +119 -14
  118. package/dist/sdk/context-intent-contracts.js +4 -2
  119. package/dist/sdk/core-governance.d.ts +1 -1
  120. package/dist/sdk/core-governance.js +3 -3
  121. package/dist/sdk/extension/scaffold.js +11 -5
  122. package/dist/sdk/flag-invocation-contracts.d.ts +2 -0
  123. package/dist/sdk/flag-invocation-contracts.js +30 -3
  124. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +83 -2
  125. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -2
  126. package/dist/sdk/governance/assurance-action.js +30 -10
  127. package/dist/sdk/governance/validate.d.ts +2 -2
  128. package/dist/sdk/governance/validate.js +39 -14
  129. package/dist/sdk/guide-topics.d.ts +0 -5
  130. package/dist/sdk/guide-topics.js +28 -2
  131. package/dist/sdk/history-compact.d.ts +2 -1
  132. package/dist/sdk/history-compact.js +24 -5
  133. package/dist/sdk/history-mcp.js +11 -10
  134. package/dist/sdk/index.d.ts +8 -2
  135. package/dist/sdk/index.js +9 -3
  136. package/dist/sdk/item-transaction.js +19 -12
  137. package/dist/sdk/lifecycle/append.js +4 -4
  138. package/dist/sdk/lifecycle/close-many.js +16 -7
  139. package/dist/sdk/lifecycle/create.js +33 -22
  140. package/dist/sdk/lifecycle/plan.js +24 -6
  141. package/dist/sdk/lifecycle/update-many.js +15 -8
  142. package/dist/sdk/lifecycle/update.d.ts +2 -0
  143. package/dist/sdk/lifecycle/update.js +37 -25
  144. package/dist/sdk/merge/three-way.js +105 -26
  145. package/dist/sdk/read-output-budget.d.ts +21 -0
  146. package/dist/sdk/read-output-budget.js +39 -2
  147. package/dist/sdk/read-output-contracts.d.ts +5 -3
  148. package/dist/sdk/read-output-contracts.js +20 -12
  149. package/dist/sdk/reproducibility/process.d.ts +19 -0
  150. package/dist/sdk/reproducibility/process.js +88 -0
  151. package/dist/sdk/runtime-extended-actions.js +5 -3
  152. package/dist/sdk/runtime-input.d.ts +4 -0
  153. package/dist/sdk/runtime-input.js +98 -23
  154. package/dist/sdk/runtime-primitives.d.ts +3 -2
  155. package/dist/sdk/runtime-primitives.js +5 -4
  156. package/dist/sdk/runtime.js +11 -23
  157. package/dist/sdk/scheduling-shortcuts.js +5 -3
  158. package/dist/sdk/structured-mutations.js +10 -3
  159. package/dist/sdk/test/batch.d.ts +6 -0
  160. package/dist/sdk/test/batch.js +15 -3
  161. package/dist/sdk/test/entry.d.ts +1 -1
  162. package/dist/sdk/test/entry.js +3 -2
  163. package/dist/sdk/test/execution.d.ts +28 -3
  164. package/dist/sdk/test/execution.js +193 -34
  165. package/dist/sdk/test/parsers.d.ts +6 -0
  166. package/dist/sdk/test/parsers.js +21 -2
  167. package/dist/sdk/test/trust.d.ts +33 -0
  168. package/dist/sdk/test/trust.js +207 -0
  169. package/dist/sdk/workspace-contracts.d.ts +3 -0
  170. package/dist/sdk/workspace-contracts.js +3 -2
  171. package/dist/types.d.ts +23 -0
  172. package/dist/types.js +2 -2
  173. package/docs/AGENT_PROVENANCE_ADR.md +41 -5
  174. package/docs/CONFIGURATION.md +4 -0
  175. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +19 -2
  176. package/docs/MERGE_SAFETY.md +15 -1
  177. package/docs/README.md +2 -0
  178. package/docs/READ_OUTPUT_CONTRACTS.md +11 -1
  179. package/docs/RELEASING.md +40 -21
  180. package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
  181. package/docs/SCRIPTING.md +62 -3
  182. package/docs/SDK.md +17 -0
  183. package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
  184. package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
  185. package/docs/TESTING.md +75 -8
  186. package/docs/agent-task-token-baseline.json +2 -2
  187. package/docs/generated/AGENT_CAPABILITY_ROUTING.md +17 -0
  188. package/docs/generated/AGENT_COMMAND_SURFACE.md +1 -1
  189. package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
  190. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +355 -0
  191. package/marketplace.json +2 -2
  192. package/package.json +2 -2
  193. package/packages/pm-beads/package.json +1 -1
  194. package/packages/pm-calendar/package.json +1 -1
  195. package/packages/pm-command-kit/README.md +9 -11
  196. package/packages/pm-command-kit/extensions/command-kit/index.ts +3 -1
  197. package/packages/pm-command-kit/package.json +1 -1
  198. package/packages/pm-digital-twin/package.json +1 -1
  199. package/packages/pm-governance-audit/package.json +1 -1
  200. package/packages/pm-guide-shell/extensions/guide-shell/index.ts +10 -0
  201. package/packages/pm-guide-shell/package.json +1 -1
  202. package/packages/pm-kanban/package.json +1 -1
  203. package/packages/pm-lifecycle-hooks/package.json +1 -1
  204. package/packages/pm-linked-test-adapters/package.json +1 -1
  205. package/packages/pm-search-advanced/package.json +1 -1
  206. package/packages/pm-templates/package.json +1 -1
  207. package/packages/pm-todos/package.json +1 -1
  208. package/packages/pm-vcs/package.json +1 -1
  209. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  210. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  211. package/scripts/generate-agent-capability-surfaces.mjs +27 -1
  212. package/sdk/public-surface.json +642 -28
  213. package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +0 -13
  214. package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +0 -200
  215. package/dist/cli-bundle/chunks/chunk-QI2CT3IX.js +0 -2
  216. package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +0 -35
  217. package/dist/cli-bundle/chunks/chunk-VMMIL3SI.js +0 -2
  218. package/dist/cli-bundle/chunks/chunk-YBPJAOQQ.js +0 -3
  219. package/dist/cli-bundle/chunks/register-mutation-HTKEEGRD.js +0 -20
  220. package/dist/cli-bundle/chunks/register-operations-6EMRWJJY.js +0 -2
  221. package/dist/cli-bundle/focused-chunks/chunk-2AZT5WXZ.js +0 -2
  222. package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +0 -4
  223. package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +0 -2
  224. package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +0 -5
  225. package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +0 -155
  226. package/dist/cli-bundle/focused-chunks/chunk-MB37AYN6.js +0 -26
  227. package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +0 -2
  228. package/dist/cli-bundle/focused-chunks/chunk-PH2OXXVZ.js +0 -18
  229. package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +0 -8
package/docs/RELEASING.md CHANGED
@@ -59,13 +59,13 @@ pnpm version:check
59
59
 
60
60
  ## One-Time Setup
61
61
 
62
- - Use npm provenance publishing for `.github/workflows/release.yml` so GitHub-hosted release jobs publish signed packages. Keep `id-token: write`, Node 24 or newer, npm 11.5.1 or newer, `NODE_AUTH_TOKEN` from the `release` environment `NPM_TOKEN` secret, and `npm publish --access public --provenance`. The token must authenticate as a maintainer with read-write access to `@unbrained/pm-cli`.
62
+ - Use npm trusted publishing for `.github/workflows/release.yml` so GitHub-hosted release jobs exchange their OIDC identity for a short-lived npm publish credential and publish signed packages. Keep `id-token: write`, the `release` environment, Node 24 or newer, npm 11.5.1 or newer, and `npm publish --access public --provenance`. The npm Trusted Publisher must match repository `unbraind/pm-cli`, workflow `release.yml`, and environment `release`. The release job performs a tokenless `npm publish --dry-run` OIDC exchange before the long release gates and fails early with npm's sanitized exchange diagnostic when the registry refuses the configured identity. Do not pass `registry-url` to `actions/setup-node`: its generated token-placeholder npmrc can suppress npm's OIDC exchange when no token is present. Keep `@unbrained/pm-cli` public; trusted publishing authorizes `npm publish`, not `npm access`, so restore package visibility manually before retrying if an anonymous metadata probe fails. Do not expose `NODE_AUTH_TOKEN` or `NPM_TOKEN` to the publish step; if private dependencies ever require a read token, scope it only to the install step.
63
63
  - Add `RELEASE_PAT` to the `release` environment from a maintainer token with `contents:write` and branch-protection bypass rights. Auto Release creates a checked version/changelog commit and tag on `main`; the default `GITHUB_TOKEN` has `contents:write` but cannot satisfy protected-branch required status checks for that freshly-created commit. The workflow does not persist this elevated token during checkout or dependency installation; `run-release-pipeline.mjs` scopes it to the git push process.
64
64
  - Add `SENTRY_AUTH_TOKEN` as an optional GitHub Environment or repository secret when Sentry release creation and sourcemap upload should run. Add `SENTRY_PERSONAL_ADMIN_TOKEN` for the GitHub-hosted Sentry issue-threshold gate; CI-scoped release tokens may not have issue-read scope. The release workflow skips Sentry upload cleanly when `SENTRY_AUTH_TOKEN` is absent, but fails the reliability threshold gate when `SENTRY_PERSONAL_ADMIN_TOKEN` is absent; local maintainers should still run the token-backed Sentry gate before release.
65
65
  - Keep any `release` environment compatible with free GitHub features. This repository is public, so environment secrets and tag/branch deployment rules are compatible with the free GitHub path; do not add paid-only release gates.
66
66
  - Ensure `GITHUB_TOKEN` has `contents: write` for GitHub Release creation.
67
67
  - Keep `package.json` repository, homepage, and bugs URLs aligned with `https://github.com/unbraind/pm-cli`.
68
- - Keep npm publishing compatible with provenance. The release workflow must keep `id-token: write`, a GitHub-hosted runner, Node 24 or newer, npm 11.5.1 or newer, a valid `NPM_TOKEN`, and `npm publish --access public --provenance`.
68
+ - Keep npm publishing compatible with provenance. The release workflow must keep `id-token: write`, a GitHub-hosted runner, Node 24 or newer, npm 11.5.1 or newer, tokenless public metadata probes, and `npm publish --access public --provenance` through the configured Trusted Publisher.
69
69
 
70
70
  ## Automated Daily Driver
71
71
 
@@ -88,6 +88,11 @@ Policy:
88
88
  - before dependency installation or build, auto-release verifies that the
89
89
  candidate has exact-commit analyzer results or an immutable tree-identical
90
90
  reviewed PR head with successful DeepScan and CodeFactor results
91
+ - after the automatic version commit lands, main CI accepts its parent's
92
+ analyzer evidence only when the commit is the exact immutable-tagged release
93
+ projection: the canonical commit message, every expected distribution
94
+ manifest changed by version substitution alone, and only the generated
95
+ changelog heading changed. Any other path or content still fails closed
91
96
  - `CHANGELOG.md` is generated by the latest npm `pm-changelog` package (`pm install npm:pm-changelog --project`, then `pm changelog generate --mode replace --all-release-tags`) from closed tracker items across git release tag windows and checked in CI; do not edit it by hand
92
97
  - protected-branch pushes require `RELEASE_PAT`; Auto Release fails fast before the expensive release gates when `push=true`, `dry_run=false`, and that secret is not configured
93
98
  - release reliability gating requires `SENTRY_PERSONAL_ADMIN_TOKEN` for issue-threshold checks; Auto Release fails before creating the version commit/tag when the token is missing and `push=true`, while sourcemap upload remains optional through `SENTRY_AUTH_TOKEN`
@@ -248,8 +253,9 @@ protection is enabled and enforced, and CodeFactor plus DeepScan are effective
248
253
  required contexts. That summary intentionally cannot attest the admin-only
249
254
  strict-update setting: its receipt reports `strict: null`,
250
255
  `strict_verified: false`, and `verification_scope: effective_required_checks`
251
- instead of inventing a positive result. Exact or immutable identical-tree
252
- analyzer provenance remains mandatory and is emitted beside the policy receipt,
256
+ instead of inventing a positive result. Exact, immutable identical-tree, or
257
+ fully validated deterministic-release analyzer provenance remains mandatory
258
+ and is emitted beside the policy receipt,
253
259
  so the restricted-token recovery cannot admit an unanalyzed or different-tree
254
260
  candidate. A maintainer token with administration-read access still verifies
255
261
  and reports `strict: true` through REST or paginated GraphQL. It reads the
@@ -260,9 +266,23 @@ Squash provenance additionally requires one unambiguous GitHub association to a
260
266
  closed PR merged into `main` with the release commit as its merge commit.
261
267
  Missing, ambiguous, or different-tree provenance fails closed.
262
268
 
269
+ The automatic release commit is the sole non-identical-tree derivation. The
270
+ gate requires one parent, the canonical release subject and body, an immutable
271
+ `v<version>` tag resolving to the candidate, the complete expected manifest
272
+ inventory, exact old-version to new-version substitutions in every manifest,
273
+ and an exact `Unreleased` changelog-heading replacement. It then resolves the
274
+ parent through the same exact or reviewed identical-tree analyzer contract.
275
+ Added, deleted, renamed, missing, or otherwise modified paths are refused, as
276
+ are malformed manifests, changelog edits, untagged commits, and parents without
277
+ successful analyzer evidence. The receipt reports
278
+ `analysis_source: deterministic_release_transform` and names both the release
279
+ parent and the parent's analyzer source; it never describes the changed release
280
+ tree as identical to the analyzed tree.
281
+
263
282
  The supported default-branch arrival path is a reviewed pull request. A direct
264
283
  push to `main` is releasable only if both analyzers attached successful evidence
265
- to that exact commit; when they did not, the gate explicitly refuses the
284
+ to that exact commit or it is the narrowly validated automatic release
285
+ projection above; when neither condition holds, the gate explicitly refuses the
266
286
  candidate instead of letting the next scheduled release discover the missing
267
287
  precondition after expensive work. CI runs `Release analyzer readiness (main)`
268
288
  on every product-relevant push to `main`, providing continuous visibility
@@ -325,7 +345,7 @@ git push origin v<version>
325
345
  `.github/workflows/release.yml` runs on `v*.*.*` tags and handles:
326
346
 
327
347
  - full-history checkout
328
- - manual `workflow_dispatch` by tag for recovery. An authenticated exact-version probe keeps already-published access recovery on the reviewed dispatch-time `main` source; when the immutable tag exists but npm publication never completed, recovery checks out that exact tagged source and retains the original version guard
348
+ - manual `workflow_dispatch` by tag for recovery. An isolated anonymous exact-version probe keeps already-published recovery on the reviewed dispatch-time `main` source; when the immutable tag exists but npm publication never completed, recovery checks out that exact tagged source and retains the original version guard
329
349
  - pnpm install with frozen lockfile
330
350
  - version policy and tag guard
331
351
  - secret scan
@@ -351,13 +371,12 @@ git push origin v<version>
351
371
  dispatch may do so only when its source-selection preflight pinned the
352
372
  checkout to the requested immutable tag; reviewed-main recovery continues
353
373
  to refuse publication of a missing target. Only
354
- when neither the target nor package metadata is anonymously visible does the
355
- same-tag recovery path attempt to restore public package access, because a
356
- hidden version can also return 404 to authenticated metadata reads. After a
357
- successful access recovery it rechecks anonymous metadata, then either skips
358
- the now-visible target or publishes the still-missing version. Permission,
359
- authentication, and registry failures stop the workflow instead of risking
360
- an immutable-version overwrite. The checked-out tag's `package.json` supplies
374
+ when neither the target nor package metadata is anonymously visible, the
375
+ same-tag recovery path fails closed and instructs the maintainer to restore
376
+ public package visibility outside the workflow. Trusted publishing does not
377
+ authorize package-access mutations. Permission, authentication, and registry
378
+ failures stop the workflow instead of risking an immutable-version overwrite.
379
+ The checked-out tag's `package.json` supplies
361
380
  the canonical package identity to both the publish guard and the
362
381
  post-publish npm/npx/bunx verifier so those identities cannot drift. The
363
382
  explicit stable dist-tag also preserves
@@ -415,8 +434,8 @@ Use the npm registry package for maintainer global updates. Do not use `npm inst
415
434
  `workflow_dispatch` and `tag=v<version>` (or close the current bot-created
416
435
  blocker once to trigger the guarded exact-run recovery). The workflow skips
417
436
  duplicate npm publication for an anonymously visible version. Before
418
- installing or running gates, dispatch performs an authenticated exact-version
419
- probe. An
437
+ installing or running gates, dispatch performs an isolated anonymous
438
+ exact-version probe. An
420
439
  existing version keeps the reviewed dispatch-time `main` source and cannot
421
440
  be republished. A definitive missing-version response pins the checkout to
422
441
  the existing immutable tag, reapplies the version guard, installs the managed
@@ -428,12 +447,12 @@ Use the npm registry package for maintainer global updates. Do not use `npm inst
428
447
  by rerunning the same tag workflow, document the incident and ship the code
429
448
  fix in the next UTC day's release.
430
449
  - A manual exact-tag `workflow_dispatch` recovery uses isolated anonymous
431
- registry probes before any account-level access mutation. A visible package
432
- with a missing target version proceeds directly to exact-tag publication, so
433
- a publish-capable automation token is not required to change package access.
434
- Access recovery is reserved for the ambiguous case where neither the package
435
- nor target version is anonymously visible. An already-visible immutable
436
- version is still verified and never republished. Recovery starts from the
450
+ registry probes and never mutates package access. A visible package with a
451
+ missing target version proceeds directly to exact-tag OIDC publication. When
452
+ neither the package nor target version is anonymously visible, recovery fails
453
+ closed until a maintainer restores public visibility outside the workflow. An
454
+ already-visible immutable version is still verified and never republished.
455
+ Recovery starts from the
437
456
  dispatch-time commit SHA and fails unless the dispatch ref is the repository
438
457
  default branch (`main`). It remains on that reviewed source when the exact
439
458
  npm version exists. When the version is definitively absent, it switches to
@@ -1,7 +1,8 @@
1
1
  # Reproducible Workspaces and Snapshots
2
2
 
3
- Tracked by [pm-rbcvt2](../.agents/pm/features/pm-rbcvt2.toon) and
4
- [pm-dkrmzv](../.agents/pm/features/pm-dkrmzv.toon).
3
+ Tracked by [pm-rbcvt2](../.agents/pm/features/pm-rbcvt2.toon),
4
+ [pm-dkrmzv](../.agents/pm/features/pm-dkrmzv.toon), and
5
+ [pm-gh1089](../.agents/pm/issues/pm-gh1089.toon).
5
6
 
6
7
  These SDK primitives make a pm workspace reproducible without changing normal
7
8
  interactive behavior. Recipes control time and identifier entropy only inside
@@ -22,9 +23,7 @@ const recipe: WorkspaceRecipe = {
22
23
  seed: "example-fixture-v1",
23
24
  clock: "2026-07-28T10:00:00.000Z",
24
25
  tickMs: 1,
25
- operations: [
26
- { action: "create", input: { title: "Deterministic task" } },
27
- ],
26
+ operations: [{ action: "create", input: { title: "Deterministic task" } }],
28
27
  };
29
28
 
30
29
  const results = await executeWorkspaceRecipe(
@@ -36,9 +35,9 @@ const results = await executeWorkspaceRecipe(
36
35
  The caller owns action dispatch. pm owns the deterministic execution context:
37
36
  `nowIso()` advances from `clock` by `tickMs`, and generated item identifiers
38
37
  derive from `seed`. Async scopes are isolated with `AsyncLocalStorage`, so
39
- concurrent recipes do not share counters. Outside `runWithWorkspaceRecipe` or
40
- `executeWorkspaceRecipe`, the CLI continues using the system clock and
41
- cryptographic randomness.
38
+ concurrent recipes do not share counters. Normal CLI and MCP execution still
39
+ uses the system clock and cryptographic randomness unless the process opts in
40
+ through the environment contract below.
42
41
 
43
42
  `defineWorkspaceRecipe` immediately validates the clock, seed, tick, schema,
44
43
  operation actions, and recursively JSON-compatible inputs. Its TypeScript
@@ -51,6 +50,41 @@ Seeds are reproducibility inputs, not secrets. A replay is byte-identical only
51
50
  when it begins from equivalent authoritative state and invokes the same ordered
52
51
  operations with the same recipe.
53
52
 
53
+ ## CLI and MCP process configuration
54
+
55
+ Shell-based harnesses can install the same SDK-owned deterministic context for
56
+ the `pm` and `pm-mcp` processes without patching JavaScript globals:
57
+
58
+ ```bash
59
+ PM_CLOCK=2026-07-28T10:00:00.000Z \
60
+ PM_CLOCK_TICK_MS=1 \
61
+ PM_SEED=example-fixture-v1 \
62
+ pm create --title "Deterministic task" --type Task --json
63
+ ```
64
+
65
+ `PM_CLOCK` and `PM_SEED` are required together. `PM_CLOCK` must be an ISO-8601
66
+ instant with `Z` or a numeric UTC offset; timezone-less and non-ISO inputs are
67
+ rejected so separate hosts cannot interpret the same configuration differently.
68
+ `PM_CLOCK_TICK_MS` is optional, defaults to `1`, and must be a non-negative integer. Partial or invalid input
69
+ fails before command dispatch with the stable
70
+ `invalid_reproducible_process_environment` code and recovery that names the
71
+ missing or invalid variable. Unset all three variables for normal interactive
72
+ behavior.
73
+
74
+ Every CLI process invocation begins a fresh deterministic scope. A workflow
75
+ that launches several CLI processes must derive a stable, distinct seed for
76
+ each ordered step; reusing one seed intentionally reproduces the same entropy
77
+ sequence and can reproduce an existing generated identifier. A long-lived MCP
78
+ server instead owns one process-lifetime sequence and advances it across its
79
+ serialized JSON-RPC requests. Two equivalent servers therefore produce the
80
+ same files without generating duplicate identifiers inside either server.
81
+
82
+ The public SDK exports `PM_REPRODUCIBLE_PROCESS_ENV`,
83
+ `resolveReproducibleProcessEnvironment`,
84
+ `runWithReproducibleProcessEnvironment`, and
85
+ `createReproducibleProcessRunner` for custom one-shot and long-lived process
86
+ transports.
87
+
54
88
  ## Content-addressed snapshots
55
89
 
56
90
  The SDK exports:
package/docs/SCRIPTING.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # CLI Scripting Contract
2
2
 
3
- Tracked by [pm-psy1](../.agents/pm/tasks/pm-psy1.toon), [pm-hqa8g1](../.agents/pm/tasks/pm-hqa8g1.toon), [pm-gknu](../.agents/pm/issues/pm-gknu.toon), [pm-999jh7](../.agents/pm/issues/pm-999jh7.toon), and [pm-srns](../.agents/pm/issues/pm-srns.toon).
3
+ Tracked by [pm-psy1](../.agents/pm/tasks/pm-psy1.toon), [pm-hqa8g1](../.agents/pm/tasks/pm-hqa8g1.toon), [pm-gknu](../.agents/pm/issues/pm-gknu.toon), [pm-999jh7](../.agents/pm/issues/pm-999jh7.toon), [pm-srns](../.agents/pm/issues/pm-srns.toon), [pm-3oq022](../.agents/pm/issues/pm-3oq022.toon), [pm-iktj](../.agents/pm/tasks/pm-iktj.toon), and [pm-kexu](../.agents/pm/issues/pm-kexu.toon).
4
4
 
5
5
  Use this contract when composing `pm` with shells, CI runners, `jq`, or another process. Exact flags remain discoverable from `pm <command> --help --json` and `pm contracts --command <command> --flags-only --json`.
6
6
 
@@ -14,8 +14,8 @@ Use this contract when composing `pm` with shells, CI runners, `jq`, or another
14
14
  | `3` | Requested tracker or resource was not found. | Correct the path or ID. |
15
15
  | `4` | State or concurrency conflict. | Refresh live state before deciding whether to retry. |
16
16
  | `5` | A required dependency operation failed. | Inspect the dependency evidence before retrying. |
17
- | `6` | The request succeeded but matched nothing to change. | Treat as success and inspect the effect receipt. |
18
- | `7` | The request succeeded and changed only part of the selected targets. | Treat as success and inspect unmatched/skipped rows. |
17
+ | `6` | The request succeeded but matched nothing to change. | Treat as success and inspect the effect receipt. |
18
+ | `7` | The request succeeded and changed only part of the selected targets. | Treat as success and inspect unmatched/skipped rows. |
19
19
 
20
20
  Exits `0`, `6`, and `7` are successful outcomes. Bulk mutation envelopes repeat
21
21
  the distinction as `outcome: effect`, `outcome: no_effect`, or `outcome:
@@ -134,6 +134,65 @@ else
134
134
  fi
135
135
  ```
136
136
 
137
+ Bulk selectors on `update-many`, `close-many`, and `history-compact` accept the
138
+ same explicit ID grammar through three CLI channels: comma/newline-delimited
139
+ argv text, `-` for stdin, and `@path` for a UTF-8 file. This makes a
140
+ read-selector-write pipeline executable without `xargs` command fan-out:
141
+
142
+ ```bash
143
+ pm list --status open,in_progress --fields id,priority --json |
144
+ jq -r '.items[] | select(.priority >= 2) | .id' |
145
+ pm update-many --ids - --priority 1 --dry-run --json
146
+
147
+ pm close-many --ids @reviewed-ids.txt \
148
+ --reason "Reviewed batch completed" --dry-run --json
149
+
150
+ pm list --status closed --fields id --json |
151
+ jq -r '.items[].id' |
152
+ pm history-compact --ids - --dry-run --json
153
+ ```
154
+
155
+ An unreadable `@path`, empty stdin, or empty file fails before the tracker is
156
+ read or mutated. `unmatched_ids` means the requested ID does not exist; an
157
+ existing ID excluded by another filter is not misreported as nonexistent.
158
+ Apply-mode exit `6`/`7` and the structured effect receipt remain authoritative.
159
+
160
+ `update-many --dry-run` may be filter-only. It returns the matched rows with an
161
+ empty `planned_update_options` object and empty per-row `changes`, which is a
162
+ bounded way to validate a selector before choosing a mutation. The same
163
+ filter-only invocation without `--dry-run` is rejected with exit `2`.
164
+
165
+ Direct SDK and MCP callers may pass `ids` as a string, a finite numeric scalar,
166
+ or an array of string and finite numeric IDs. The SDK normalizes every accepted
167
+ shape through the same stable-deduplicating parser; non-finite numbers and
168
+ unsupported explicit selector values are rejected before target selection:
169
+
170
+ ```ts
171
+ import { PmClient } from "@unbrained/pm-cli/sdk";
172
+
173
+ const pm = new PmClient({ pmRoot: ".agents/pm" });
174
+ await pm.run("update-many", {
175
+ options: {
176
+ ids: ["pm-a1b2", "pm-c3d4"],
177
+ priority: 1,
178
+ dryRun: true,
179
+ },
180
+ });
181
+ ```
182
+
183
+ File-reading text flags use the same stdin sentinel. `--body-file -` reads a
184
+ create/update body, while `comments`, `notes`, and `learnings` accept
185
+ `--file -`. Real file paths remain compatible:
186
+
187
+ ```bash
188
+ generate_body | pm create --title "Generated plan" --body-file -
189
+ render_review | pm comments pm-a1b2 --file -
190
+ ```
191
+
192
+ Each command invocation may consume stdin for only one option. Competing
193
+ stdin-backed inputs such as `--description - --body-file -` are rejected before
194
+ the stream is read.
195
+
137
196
  Use NDJSON for streaming row-by-row tools:
138
197
 
139
198
  ```bash
package/docs/SDK.md CHANGED
@@ -1702,6 +1702,15 @@ const telemetry = await runTelemetry(
1702
1702
  global tracker roots. `pm_context_mode`, run-level overrides, automatic tracker
1703
1703
  context, assertion requirements, empty-run detection, and failure categories are
1704
1704
  part of the SDK result contract rather than presentation-layer behavior.
1705
+ Workspace results distinguish the run-level requested mode from the effective
1706
+ per-test mode. `isolated` executes from an empty disposable directory;
1707
+ `snapshot` executes from a filtered disposable workspace. Trust preflight
1708
+ failures report `trust_refusal`, while malformed or incomplete provenance uses
1709
+ the additive `provenance_invalid` storage marker and fail-closed
1710
+ `invalid_provenance` trust reason. Package mutation adapters can call
1711
+ `attachLinkedTestMutationProvenance` so Git inspection occurs only when commands
1712
+ are added; `resolveLinkedTestSourceWorkspaceRoot` keeps their source-ref lookup
1713
+ aligned with CLI execution and `PM_SOURCE_WORKSPACE_ROOT` overrides.
1705
1714
  When item test-result tracking is enabled, `measure` persists typed numeric
1706
1715
  evidence on the producing run. Each entry has a stable name, finite numeric
1707
1716
  value, optional unit and threshold, and the run timestamp. Run history remains
@@ -2037,6 +2046,8 @@ export default defineExtension({
2037
2046
  api.registerCommand({
2038
2047
  name: "hello",
2039
2048
  action: "hello",
2049
+ tier: "standard",
2050
+ family: "extensions",
2040
2051
  description: "Return a deterministic hello payload.",
2041
2052
  intent: "verify SDK extension activation",
2042
2053
  examples: ["pm hello"],
@@ -2091,6 +2102,12 @@ For a complete commands-capability package that combines `registerCommand`,
2091
2102
  `registerFlags`, and `registerParser`, see the first-party
2092
2103
  [pm-command-kit exemplar](../packages/pm-command-kit/README.md).
2093
2104
 
2105
+ Every command definition can declare its agent-surface `tier` (`core`,
2106
+ `standard`, `full`, or `internal`) and capability `family`. These are the same
2107
+ fields projected into CLI help, completion, MCP profiles, workspace contracts,
2108
+ and generated routing documentation. Omitted package values normalize to
2109
+ `standard` and `extensions`.
2110
+
2094
2111
  For a generated starter, use `pm package init ./my-package`. Pass
2095
2112
  `--capability hooks` to scaffold a command plus an `afterCommand` lifecycle
2096
2113
  reactor and a runnable `node:test` file that exercises
@@ -6,7 +6,8 @@ Tracker references: [pm-9wbiye](../.agents/pm/issues/pm-9wbiye.toon),
6
6
  [pm-3zgh2c](../.agents/pm/features/pm-3zgh2c.toon),
7
7
  [pm-eq9dlw](../.agents/pm/issues/pm-eq9dlw.toon), and
8
8
  [pm-lu6sca](../.agents/pm/features/pm-lu6sca.toon), plus
9
- [pm-5q8wa0](../.agents/pm/issues/pm-5q8wa0.toon).
9
+ [pm-5q8wa0](../.agents/pm/issues/pm-5q8wa0.toon) and
10
+ [pm-c0lrdm](../.agents/pm/features/pm-c0lrdm.toon).
10
11
 
11
12
  Project management is context management. The public SDK therefore carries a
12
13
  session's purpose and episode boundary through the same immutable history that
@@ -128,9 +129,10 @@ public SDK exports for custom hosts.
128
129
  the bounded built-in resolver. It never contains environment values, session
129
130
  paths, prompts, or file contents.
130
131
 
131
- New mutation history records failed resolver outcomes under
132
- `context.agent_provenance_outcomes`; ordinary unavailable dimensions retain
133
- the compact legacy-compatible null projection. A resolver is only counted as
132
+ New mutation history records failed or explicitly unavailable configured
133
+ resolver outcomes under `context.agent_provenance_outcomes`; dimensions with
134
+ no configured resolver retain the compact legacy-compatible null projection.
135
+ A resolver is only counted as
134
136
  attempted when its required input belongs to the detected harness; a foreign
135
137
  host's shared `AI_AGENT` value is not Codex input. Consequently `pm health` can report
136
138
  `provenance_resolver_zero_success:<harness>:<dimension>:<resolver>:<attempts>`
@@ -111,7 +111,7 @@ pair pre-redaction item content with post-redaction history during validation.
111
111
 
112
112
  ## Operational receipts
113
113
 
114
- Linked tests recognize compound acquisition failures such as “could not acquire … lock” together with contention context such as “already running” or “held by another” as `infra_collision`. Generic assertion text mentioning a lock or timeout remains `assertion_failure`, preventing false infrastructure classifications.
114
+ Linked tests recognize compound acquisition failures such as “could not acquire … lock” together with contention context such as “already running” or “held by another” as `infra_collision`. Generic assertion text mentioning a lock or timeout remains `assertion_failure`, preventing false infrastructure classifications. A command refused by clone-local provenance policy is classified separately as `trust_refusal`, so reports do not misstate a pre-execution safety decision as an assertion failure.
115
115
 
116
116
  Telemetry flush receipts distinguish progress from completion:
117
117
 
package/docs/TESTING.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This page describes safe local tests, linked tests, coverage, and release-readiness checks.
4
4
 
5
- Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-u42x](../.agents/pm/issues/pm-u42x.toon), [pm-atfm](../.agents/pm/features/pm-atfm.toon), [pm-xmp5](../.agents/pm/tasks/pm-xmp5.toon), [pm-39cqqx](../.agents/pm/tasks/pm-39cqqx.toon), [pm-5cgm2z](../.agents/pm/chores/pm-5cgm2z.toon), [pm-avv3wx](../.agents/pm/issues/pm-avv3wx.toon), [pm-rizqb6](../.agents/pm/issues/pm-rizqb6.toon), [pm-95h7pg](../.agents/pm/issues/pm-95h7pg.toon), [pm-giks4s](../.agents/pm/issues/pm-giks4s.toon), [pm-xa3t0o](../.agents/pm/issues/pm-xa3t0o.toon).
5
+ Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-u42x](../.agents/pm/issues/pm-u42x.toon), [pm-atfm](../.agents/pm/features/pm-atfm.toon), [pm-xmp5](../.agents/pm/tasks/pm-xmp5.toon), [pm-39cqqx](../.agents/pm/tasks/pm-39cqqx.toon), [pm-5cgm2z](../.agents/pm/chores/pm-5cgm2z.toon), [pm-avv3wx](../.agents/pm/issues/pm-avv3wx.toon), [pm-rizqb6](../.agents/pm/issues/pm-rizqb6.toon), [pm-95h7pg](../.agents/pm/issues/pm-95h7pg.toon), [pm-giks4s](../.agents/pm/issues/pm-giks4s.toon), [pm-xa3t0o](../.agents/pm/issues/pm-xa3t0o.toon), [pm-e97jyf](../.agents/pm/issues/pm-e97jyf.toon), [pm-efkvdy](../.agents/pm/issues/pm-efkvdy.toon), and [pm-ed28wi](../.agents/pm/issues/pm-ed28wi.toon).
6
6
 
7
7
  ## Agent Quick Context
8
8
 
@@ -372,11 +372,14 @@ Diagnostic ceilings share the executable refusal gate:
372
372
  pnpm quality:recovery-closure
373
373
  ```
374
374
 
375
- The gate replays 22 refusal contracts and ratchets ten representative failure
376
- paths against `PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS`. Every diagnostic must fit
377
- its declared JSON ceiling and preserve a mechanically actionable correction;
378
- the missing-probe negative control proves that the diagnostic corpus cannot
379
- silently shrink.
375
+ The gate replays 117 refusal contracts: 18 closed-domain rows, 88
376
+ grammar-derived required-argument omissions, seven closed positional-action
377
+ families, and four tracker-preflight states. It also ratchets ten representative
378
+ failure paths against `PM_DIAGNOSTIC_OUTPUT_BUDGET_CONTRACTS`. Every diagnostic
379
+ must fit its declared JSON ceiling and preserve a mechanically actionable
380
+ correction; executable retry argv is never collection-truncated. The
381
+ missing-probe negative control and the authoritative tracker-state snapshot
382
+ prove that the corpus cannot silently shrink or turn a refusal into a mutation.
380
383
 
381
384
  The gate derives every supported harness, model, session, and provenance
382
385
  environment key from the SDK-owned harness descriptor registry. It deletes
@@ -441,6 +444,69 @@ into constrained temporary storage.
441
444
  Capacity, permission, and resource failures while seeding a required tracker
442
445
  surface as typed, path-redacted host-environment refusals with recovery steps.
443
446
 
447
+ ## Source Workspace Modes
448
+
449
+ Linked tests have a separate source-workspace contract. Store a default on one
450
+ entry with `workspace_context_mode`, or choose a run-level mode with
451
+ `--workspace-context`:
452
+
453
+ ```bash
454
+ pm test <item-id> --add-json '{"command":"pnpm quality:static","workspace_context_mode":"isolated"}'
455
+ pm test <item-id> --run --workspace-context snapshot --override-linked-workspace-context
456
+ ```
457
+
458
+ - `source` (default) runs in the source checkout and exposes its read-only
459
+ source-context environment, preserving existing linked-test behavior.
460
+ - `isolated` runs from an empty disposable directory and removes
461
+ `PM_SOURCE_WORKSPACE_ROOT`, `PM_SOURCE_PM_PATH`, and the source-context access
462
+ declaration. Use it only for commands that do not require checkout files.
463
+ - `snapshot` copies the workspace into the linked-test sandbox, runs from that
464
+ copy, and binds its `.agents/pm` path to the selected temporary tracker.
465
+ `.git`, `.agents`, `node_modules`, coverage output, and common cache
466
+ directories are excluded at every directory depth; an existing top-level
467
+ `node_modules` is linked read-only by convention. Built output remains
468
+ available so linked commands such as `node dist/cli.js` keep working. Writes
469
+ therefore land in the disposable snapshot rather than the source checkout.
470
+
471
+ Every result reports the requested/effective workspace mode, working
472
+ directory, exposed source root, and trust decision. Recorded `test_runs` retain
473
+ the effective workspace mode and trust reason beside the command.
474
+
475
+ ## Linked-Test Command Trust
476
+
477
+ Linked commands are stored shell programs, so merge-unioned tracker data is an
478
+ execution boundary. New command entries record author, creation time, source
479
+ branch when available, and whether the item merge driver introduced the entry.
480
+ Locally created commands keep their previous run behavior. Commands marked as
481
+ merge-unioned or carrying a different source ref fail before process creation.
482
+ Malformed provenance is sanitized to the additive `provenance_invalid` marker
483
+ and receives the same fail-closed treatment; it is never normalized into a
484
+ trusted legacy command.
485
+ These pre-execution refusals use the `trust_refusal` failure category, separate
486
+ from command or assertion failures.
487
+
488
+ Choose one explicit recovery:
489
+
490
+ ```bash
491
+ # Review and trust the item's current command fingerprints in this clone.
492
+ pm test <item-id> --acknowledge-linked-tests
493
+
494
+ # Or permit a single reviewed run. Both controls are required.
495
+ pm config project set untrusted-linked-test-execution enabled
496
+ pm test <item-id> --run --allow-untrusted-linked-tests
497
+ ```
498
+
499
+ Acknowledgments live in the clone-local ignored runtime directory and bind to
500
+ the full command, tracker/workspace context, environment controls, host-safety
501
+ mode, and provenance fingerprint; editing any of those fields requires a new
502
+ review. Enabling the project policy alone never executes
503
+ an untrusted command, and the per-run flag alone is also refused. Inspect all
504
+ unacknowledged entries without executing them with:
505
+
506
+ ```bash
507
+ pm validate --check-command-references --verbose-diagnostics
508
+ ```
509
+
444
510
  Use explicit modes when needed:
445
511
 
446
512
  ```bash
@@ -493,8 +559,9 @@ pm test <item-id> --metric-below coverage=100 --metric-diff p95_latency
493
559
  Measurements are stored on the producing `test_runs` row, retained with the
494
560
  bounded run history, and exposed consistently by CLI, SDK, MCP, and contracts.
495
561
  Each recorded row also keeps a bounded `executions` list with the exact linked
496
- command plus its requested and effective `pm_context_mode`, so tracker-backed
497
- verification remains attributable after the transient process logs are gone.
562
+ command, requested/effective `pm_context_mode`, effective workspace mode, and
563
+ trust reason, so tracker-backed verification remains attributable after the
564
+ transient process logs are gone.
498
565
 
499
566
  ## Linked-Test Assertions
500
567
 
@@ -18,8 +18,8 @@
18
18
  },
19
19
  {
20
20
  "id": "failing-command",
21
- "max_estimated_tokens": 200
21
+ "max_estimated_tokens": 219
22
22
  }
23
23
  ],
24
- "composite_max_estimated_tokens": 2178
24
+ "composite_max_estimated_tokens": 2197
25
25
  }
@@ -0,0 +1,17 @@
1
+ # Generated agent capability routing
2
+
3
+ Tracker: `pm-kxci8x`.
4
+
5
+ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it manually.
6
+
7
+ | Capability family | Commands |
8
+ | --- | --- |
9
+ | workspace | `init`, `config`, `merge`, `schema`, `profile`, `telemetry`, `health`, `gc`, `workspace` |
10
+ | intake | `create`, `copy`, `focus`, `restore` |
11
+ | context | `list`, `aggregate`, `context`, `get`, `search`, `duplicates`, `eval`, `next`, `activity`, `stats`, `help` |
12
+ | lifecycle | `update`, `update-many`, `close`, `close-many`, `delete`, `claim`, `release`, `start-task`, `pause-task`, `close-task` |
13
+ | evidence | `history`, `events`, `history-redact`, `history-repair`, `history-compact`, `history-author-acknowledge`, `append`, `comments`, `notes`, `learnings`, `files`, `docs` |
14
+ | graph | `graph`, `deps`, `plan` |
15
+ | quality | `test`, `test-all`, `validate`, `assurance`, `contracts` |
16
+ | automation | `meet`, `event`, `remind` |
17
+ | extensions | `extension`, `package`, `packages`, `install`, `upgrade` |
@@ -4,7 +4,7 @@ This file is generated from `PM_COMMAND_CAPABILITY_CONTRACTS`. Do not edit it ma
4
4
 
5
5
  | Command | Minimum visibility tier | Capability family |
6
6
  | --- | --- | --- |
7
- | `init` | full | workspace |
7
+ | `init` | core | workspace |
8
8
  | `config` | standard | workspace |
9
9
  | `extension` | full | extensions |
10
10
  | `package` | full | extensions |
@@ -55,8 +55,8 @@ This file is generated by `listPmFlagLexicon()`. Compatibility aliases do not co
55
55
  | `docs` | evidence | 30 | 30 |
56
56
  | `deps` | graph | 32 | 32 |
57
57
  | `plan` | graph | 109 | 109 |
58
- | `test` | quality | 48 | 48 |
59
- | `test-all` | quality | 37 | 37 |
58
+ | `test` | quality | 52 | 52 |
59
+ | `test-all` | quality | 40 | 40 |
60
60
  | `telemetry` | workspace | 21 | 21 |
61
61
  | `stats` | context | 29 | 29 |
62
62
  | `health` | workspace | 36 | 36 |