@unbrained/pm-cli 2026.8.17 → 2026.8.19

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 (204) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/AGENTS.md +4 -3
  3. package/CHANGELOG.md +51 -5
  4. package/README.md +3 -3
  5. package/dist/cli/error-guidance.js +8 -4
  6. package/dist/cli/help-content.js +32 -13
  7. package/dist/cli/help-json-payload.d.ts +15 -0
  8. package/dist/cli/help-json-payload.js +101 -23
  9. package/dist/cli/main.js +6 -2
  10. package/dist/cli/register-list-query.js +138 -54
  11. package/dist/cli/register-mutation.js +8 -8
  12. package/dist/cli/register-operations.js +6 -6
  13. package/dist/cli-bundle/bundle-manifest.json +149 -149
  14. package/dist/cli-bundle/chunks/chunk-4NRRH7AM.js +2 -0
  15. package/dist/cli-bundle/chunks/chunk-4THEB6PD.js +13 -0
  16. package/dist/cli-bundle/chunks/{chunk-HBJAS566.js → chunk-BHYMXLAE.js} +2 -2
  17. package/dist/cli-bundle/chunks/chunk-GWMXAQOD.js +197 -0
  18. package/dist/cli-bundle/chunks/chunk-HVFQTLYM.js +35 -0
  19. package/dist/cli-bundle/chunks/chunk-OI4XI562.js +5 -0
  20. package/dist/cli-bundle/chunks/{chunk-3UEGXBMR.js → chunk-OIOKV6NO.js} +58 -54
  21. package/dist/cli-bundle/chunks/chunk-QXSH7BLM.js +3 -0
  22. package/dist/cli-bundle/chunks/chunk-SARFF5H5.js +3 -0
  23. package/dist/cli-bundle/chunks/{chunk-7IBRGCHX.js → chunk-TOXJM4WA.js} +2 -2
  24. package/dist/cli-bundle/chunks/{chunk-JOKATURE.js → chunk-YBMRWW4E.js} +44 -44
  25. package/dist/cli-bundle/chunks/register-list-query-Y56KINDU.js +11 -0
  26. package/dist/cli-bundle/chunks/register-mutation-AUWVCW4M.js +20 -0
  27. package/dist/cli-bundle/chunks/register-operations-PZQPHXW5.js +2 -0
  28. package/dist/cli-bundle/chunks/{register-setup-DOSFBGKE.js → register-setup-I4LUHGVW.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/chunk-34QBIYZI.js +155 -0
  30. package/dist/cli-bundle/focused-chunks/{chunk-MHPIL773.js → chunk-BJRYFVSH.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/chunk-DKPLYW3L.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-SALH6B6K.js → chunk-EF6ZS5GH.js} +44 -44
  33. package/dist/cli-bundle/focused-chunks/{chunk-XKAMP5OU.js → chunk-ESISGDAY.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/{chunk-SYZENPIT.js → chunk-EXBCLIBU.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/chunk-JDOMQ7VQ.js +4 -0
  36. package/dist/cli-bundle/focused-chunks/chunk-L623ZPNK.js +2 -0
  37. package/dist/cli-bundle/focused-chunks/chunk-MCZXYZAF.js +2 -0
  38. package/dist/cli-bundle/focused-chunks/chunk-ODHQEECS.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/{chunk-ZQPGZZWQ.js → chunk-PRHY2IMX.js} +3 -3
  40. package/dist/cli-bundle/focused-chunks/chunk-RZU5U6Q7.js +2 -0
  41. package/dist/cli-bundle/focused-chunks/{chunk-ATEY76SX.js → chunk-US7VEYZG.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/chunk-VXDSU5MC.js +26 -0
  43. package/dist/cli-bundle/focused-chunks/chunk-YBMGXBFV.js +16 -0
  44. package/dist/cli-bundle/focused-chunks/chunk-YLVBJ6GF.js +2 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-CYFK5UPB.js → chunk-ZBIQQYMI.js} +2 -2
  46. package/dist/cli-bundle/main.js +13 -13
  47. package/dist/cli-bundle/sdk-authoring.js +1 -1
  48. package/dist/cli-bundle/sdk-contracts.js +2 -1
  49. package/dist/cli-bundle/sdk-core.js +28 -28
  50. package/dist/cli-bundle/sdk-governance.js +1 -1
  51. package/dist/cli-bundle/sdk-graph.js +1 -1
  52. package/dist/cli-bundle/sdk-merge.js +32 -32
  53. package/dist/cli-bundle/sdk-query.js +1 -1
  54. package/dist/cli-bundle/sdk-runtime.js +1 -1
  55. package/dist/cli-bundle/sdk-testing.js +1 -1
  56. package/dist/cli-bundle/sdk.js +5 -4
  57. package/dist/core/config/nested-settings.js +8 -2
  58. package/dist/core/extensions/exporter-output-contract.d.ts +12 -0
  59. package/dist/core/extensions/exporter-output-contract.js +67 -0
  60. package/dist/core/extensions/extension-types.d.ts +36 -1
  61. package/dist/core/extensions/extension-types.js +2 -2
  62. package/dist/core/extensions/loader.js +35 -44
  63. package/dist/core/history/event-index.d.ts +5 -0
  64. package/dist/core/history/event-index.js +133 -27
  65. package/dist/core/sentry/helpers.js +3 -3
  66. package/dist/core/shared/constants.js +5 -2
  67. package/dist/core/shared/errors.d.ts +2 -0
  68. package/dist/core/shared/errors.js +2 -2
  69. package/dist/core/store/settings-validator.d.ts +4 -0
  70. package/dist/core/store/settings-validator.js +3 -2
  71. package/dist/core/store/settings.js +8 -2
  72. package/dist/mcp/tool-definitions.js +12 -7
  73. package/dist/sdk/agent/refusal-closure.d.ts +41 -0
  74. package/dist/sdk/agent/refusal-closure.js +92 -0
  75. package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
  76. package/dist/sdk/agent/refusal-reachability.js +4 -4
  77. package/dist/sdk/agent-capability-contracts.d.ts +13 -0
  78. package/dist/sdk/agent-capability-contracts.js +104 -7
  79. package/dist/sdk/authoring.d.ts +1 -1
  80. package/dist/sdk/authoring.js +2 -2
  81. package/dist/sdk/cli-bootstrap.d.ts +2 -2
  82. package/dist/sdk/cli-bootstrap.js +4 -4
  83. package/dist/sdk/cli-contracts/command-aliases.d.ts +34 -2
  84. package/dist/sdk/cli-contracts/command-aliases.js +80 -13
  85. package/dist/sdk/cli-contracts/commander-mutation-options.js +30 -6
  86. package/dist/sdk/cli-contracts/commander-types.js +5 -4
  87. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
  88. package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
  89. package/dist/sdk/cli-contracts/flag-contracts.d.ts +5 -0
  90. package/dist/sdk/cli-contracts/flag-contracts.js +84 -13
  91. package/dist/sdk/cli-contracts/flag-lexicon-contracts.d.ts +55 -0
  92. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +240 -0
  93. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +151 -0
  94. package/dist/sdk/cli-contracts/grammar-contracts.js +958 -0
  95. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +33 -5
  96. package/dist/sdk/cli-contracts/runtime-contracts.js +100 -23
  97. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +28 -1
  98. package/dist/sdk/cli-contracts/tool-option-contracts.js +38 -3
  99. package/dist/sdk/cli-contracts/tool-parameter-tables.js +7 -2
  100. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  101. package/dist/sdk/cli-contracts/tool-schema.js +20 -11
  102. package/dist/sdk/cli-contracts.d.ts +5 -4
  103. package/dist/sdk/cli-contracts.js +7 -6
  104. package/dist/sdk/completion.js +13 -15
  105. package/dist/sdk/compose.d.ts +3 -3
  106. package/dist/sdk/compose.js +2 -2
  107. package/dist/sdk/context-intent-contracts.d.ts +2 -2
  108. package/dist/sdk/context-intent-contracts.js +22 -7
  109. package/dist/sdk/contracts.d.ts +3 -0
  110. package/dist/sdk/contracts.js +5 -2
  111. package/dist/sdk/core.d.ts +1 -1
  112. package/dist/sdk/core.js +3 -3
  113. package/dist/sdk/environment/host-environment-errors.js +3 -3
  114. package/dist/sdk/flag-invocation-contracts.d.ts +37 -0
  115. package/dist/sdk/flag-invocation-contracts.js +218 -9
  116. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +186 -14
  117. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +194 -26
  118. package/dist/sdk/guide-topics.js +5 -5
  119. package/dist/sdk/index.d.ts +10 -7
  120. package/dist/sdk/index.js +10 -7
  121. package/dist/sdk/init-agent-guidance.js +3 -3
  122. package/dist/sdk/mutation-events.d.ts +18 -2
  123. package/dist/sdk/mutation-events.js +59 -16
  124. package/dist/sdk/output-projection.d.ts +2 -0
  125. package/dist/sdk/output-projection.js +11 -5
  126. package/dist/sdk/output.d.ts +44 -0
  127. package/dist/sdk/output.js +28 -2
  128. package/dist/sdk/query/complete-list.d.ts +94 -0
  129. package/dist/sdk/query/complete-list.js +173 -0
  130. package/dist/sdk/query/get.js +25 -6
  131. package/dist/sdk/query/list.js +19 -2
  132. package/dist/sdk/query/search-contracts.d.ts +1 -1
  133. package/dist/sdk/query/search-contracts.js +23 -9
  134. package/dist/sdk/query/search.js +3 -3
  135. package/dist/sdk/query.d.ts +1 -0
  136. package/dist/sdk/query.js +3 -2
  137. package/dist/sdk/read-output/continuation.d.ts +1 -1
  138. package/dist/sdk/read-output/continuation.js +7 -24
  139. package/dist/sdk/read-output-contracts.d.ts +2 -2
  140. package/dist/sdk/read-output-contracts.js +89 -13
  141. package/dist/sdk/read-output-rows.d.ts +4 -0
  142. package/dist/sdk/read-output-rows.js +47 -18
  143. package/dist/sdk/runtime-extended-actions.js +10 -2
  144. package/dist/sdk/runtime.d.ts +8 -2
  145. package/dist/sdk/runtime.js +18 -11
  146. package/dist/sdk/workspace-snapshot.d.ts +2 -0
  147. package/dist/sdk/workspace-snapshot.js +10 -2
  148. package/dist/types.d.ts +5 -0
  149. package/dist/types.js +2 -2
  150. package/docs/AGENT_GUIDE.md +25 -9
  151. package/docs/CLI_GRAMMAR.md +106 -0
  152. package/docs/COMMANDS.md +39 -27
  153. package/docs/ONBOARDING.md +4 -4
  154. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +11 -2
  155. package/docs/QUICKSTART.md +1 -1
  156. package/docs/README.md +2 -0
  157. package/docs/READ_OUTPUT_CONTRACTS.md +10 -6
  158. package/docs/RELEASING.md +30 -6
  159. package/docs/SDK.md +42 -2
  160. package/docs/SDK_ARTIFACT_OUTPUT.md +72 -0
  161. package/docs/SDK_CONTEXT_COORDINATION.md +46 -12
  162. package/docs/TESTING.md +14 -1
  163. package/docs/agent-task-token-baseline.json +5 -5
  164. package/docs/generated/AGENT_COMMAND_SURFACE.md +78 -78
  165. package/docs/generated/FLAG_LEXICON_BUDGETS.md +76 -0
  166. package/marketplace.json +2 -2
  167. package/package.json +5 -2
  168. package/packages/pm-beads/package.json +1 -1
  169. package/packages/pm-calendar/package.json +1 -1
  170. package/packages/pm-command-kit/package.json +1 -1
  171. package/packages/pm-digital-twin/package.json +1 -1
  172. package/packages/pm-governance-audit/package.json +1 -1
  173. package/packages/pm-guide-shell/package.json +1 -1
  174. package/packages/pm-kanban/package.json +1 -1
  175. package/packages/pm-lifecycle-hooks/package.json +1 -1
  176. package/packages/pm-linked-test-adapters/package.json +1 -1
  177. package/packages/pm-search-advanced/package.json +1 -1
  178. package/packages/pm-templates/package.json +1 -1
  179. package/packages/pm-todos/package.json +1 -1
  180. package/packages/pm-vcs/package.json +1 -1
  181. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  182. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  183. package/scripts/generate-agent-capability-surfaces.mjs +20 -14
  184. package/sdk/public-surface.json +1245 -60
  185. package/dist/cli-bundle/chunks/chunk-2QLOXC3V.js +0 -3
  186. package/dist/cli-bundle/chunks/chunk-4JPYF536.js +0 -35
  187. package/dist/cli-bundle/chunks/chunk-6VDLG2FC.js +0 -13
  188. package/dist/cli-bundle/chunks/chunk-ION3E43Q.js +0 -197
  189. package/dist/cli-bundle/chunks/chunk-OAC5NIV4.js +0 -3
  190. package/dist/cli-bundle/chunks/chunk-TPXZIBIV.js +0 -5
  191. package/dist/cli-bundle/chunks/chunk-YM2YAMF7.js +0 -2
  192. package/dist/cli-bundle/chunks/register-list-query-Q7KII4G5.js +0 -10
  193. package/dist/cli-bundle/chunks/register-mutation-4WBRPXLV.js +0 -20
  194. package/dist/cli-bundle/chunks/register-operations-SSENDH5B.js +0 -2
  195. package/dist/cli-bundle/focused-chunks/chunk-267MUUS6.js +0 -16
  196. package/dist/cli-bundle/focused-chunks/chunk-2NNFLLNG.js +0 -2
  197. package/dist/cli-bundle/focused-chunks/chunk-2QSAKMIH.js +0 -2
  198. package/dist/cli-bundle/focused-chunks/chunk-BUCG4ZI2.js +0 -2
  199. package/dist/cli-bundle/focused-chunks/chunk-EHXIKD6K.js +0 -2
  200. package/dist/cli-bundle/focused-chunks/chunk-KGEXTMPG.js +0 -2
  201. package/dist/cli-bundle/focused-chunks/chunk-KP2VQQVQ.js +0 -2
  202. package/dist/cli-bundle/focused-chunks/chunk-POEEAD2V.js +0 -4
  203. package/dist/cli-bundle/focused-chunks/chunk-XPIC53VA.js +0 -26
  204. package/dist/cli-bundle/focused-chunks/chunk-ZT2DJS27.js +0 -155
package/docs/COMMANDS.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is a task-oriented command guide. For exact flags, use runtime help because extensions and settings can change the active surface:
4
4
 
5
- Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-qd3woa](../.agents/pm/issues/pm-qd3woa.toon), [pm-ypuc39](../.agents/pm/issues/pm-ypuc39.toon), [pm-tz2ikr](../.agents/pm/issues/pm-tz2ikr.toon), the schema-migration recovery contract [pm-s79kel](../.agents/pm/issues/pm-s79kel.toon), the lossless mutation contracts [pm-x3dq0l](../.agents/pm/issues/pm-x3dq0l.toon), [pm-lppm6y](../.agents/pm/issues/pm-lppm6y.toon), and [pm-embm6t](../.agents/pm/issues/pm-embm6t.toon), and the SDK-first agent grammar tranche [pm-p316vn](../.agents/pm/issues/pm-p316vn.toon), [pm-st7wgu](../.agents/pm/issues/pm-st7wgu.toon), [pm-mkinft](../.agents/pm/issues/pm-mkinft.toon), [pm-ulqu](../.agents/pm/issues/pm-ulqu.toon), [pm-qmjx](../.agents/pm/issues/pm-qmjx.toon), [pm-4bzq](../.agents/pm/features/pm-4bzq.toon), [pm-x2vx](../.agents/pm/issues/pm-x2vx.toon), and [pm-g543](../.agents/pm/issues/pm-g543.toon).
5
+ Tracked implementation updates: [pm-52eh](../.agents/pm/features/pm-52eh.toon), [pm-mcxr](../.agents/pm/issues/pm-mcxr.toon), [pm-qd3woa](../.agents/pm/issues/pm-qd3woa.toon), [pm-ypuc39](../.agents/pm/issues/pm-ypuc39.toon), [pm-tz2ikr](../.agents/pm/issues/pm-tz2ikr.toon), the schema-migration recovery contract [pm-s79kel](../.agents/pm/issues/pm-s79kel.toon), the lossless mutation contracts [pm-x3dq0l](../.agents/pm/issues/pm-x3dq0l.toon), [pm-lppm6y](../.agents/pm/issues/pm-lppm6y.toon), and [pm-embm6t](../.agents/pm/issues/pm-embm6t.toon), positional action discovery [pm-2tan](../.agents/pm/issues/pm-2tan.toon), and the SDK-first agent grammar tranche [pm-p316vn](../.agents/pm/issues/pm-p316vn.toon), [pm-st7wgu](../.agents/pm/issues/pm-st7wgu.toon), [pm-mkinft](../.agents/pm/issues/pm-mkinft.toon), [pm-ulqu](../.agents/pm/issues/pm-ulqu.toon), [pm-qmjx](../.agents/pm/issues/pm-qmjx.toon), [pm-4bzq](../.agents/pm/features/pm-4bzq.toon), [pm-x2vx](../.agents/pm/issues/pm-x2vx.toon), and [pm-g543](../.agents/pm/issues/pm-g543.toon).
6
6
 
7
7
  Workspace-integrity contracts are tracked by [pm-22rzjp](../.agents/pm/issues/pm-22rzjp.toon), [pm-76fkpp](../.agents/pm/issues/pm-76fkpp.toon), [pm-igdvfq](../.agents/pm/issues/pm-igdvfq.toon), [pm-643e0k](../.agents/pm/issues/pm-643e0k.toon), and [pm-larv4r](../.agents/pm/issues/pm-larv4r.toon).
8
8
 
@@ -141,8 +141,8 @@ pm search "calendar reminder validation" --limit 10
141
141
  pm get pm-a1b2 # read one item; add --fields/--depth for lower-token projections
142
142
  pm get pm-a1b2 --tree --tree-depth 2 # item plus its descendant subtree
143
143
  pm get pm-a1b2 --at 7 # verified, mutation-free historical version
144
- pm list-open --type Task --priority 1 --limit 20
145
- pm list-in-progress --limit 20
144
+ pm list --status open --type Task --priority 1 --limit 20
145
+ pm list --status in_progress --limit 20
146
146
  pm aggregate --group-by parent,type --status open
147
147
  pm aggregate --group-by parent,type --completion --include-unparented
148
148
  pm duplicates --status all --threshold 0.8
@@ -173,7 +173,7 @@ Each aggregate row carries an explicit `group_label`: a blank/null group value (
173
173
  `--sort` accepts `priority|deadline|updated_at|created_at|title|parent`, plus the convenience aliases `updated` (→ `updated_at`) and `created` (→ `created_at`):
174
174
 
175
175
  ```bash
176
- pm list-all --sort updated --order desc
176
+ pm list --all --sort updated --order desc
177
177
  ```
178
178
 
179
179
  ### Incremental "what changed since" filters
@@ -182,16 +182,16 @@ Every `list*` command accepts `--updated-after`/`--updated-before`/`--created-af
182
182
 
183
183
  ```bash
184
184
  # Items touched since my last context window (feed back the previous run's `now`)
185
- pm list-all --updated-after 2026-06-04T15:18:32Z --brief
185
+ pm list --all --updated-after 2026-06-04T15:18:32Z --brief
186
186
 
187
187
  # Relative offsets are SIGNED: -2h/-7d reach into the past, +1d into the future.
188
188
  # Units are h/d/w/m (m = months — there is no minutes unit).
189
- pm list-open --updated-after=-2h --brief
190
- pm list-all --created-after=-7d --status open
189
+ pm list --status open --updated-after=-2h --brief
190
+ pm list --status open --created-after=-7d
191
191
 
192
- # Common list windows avoid date math (`list-open` keeps the view open-only).
193
- pm list-open --today --brief
194
- pm list-all --recent --brief
192
+ # Common list windows avoid date math (`pm list --status open` keeps the view open-only).
193
+ pm list --status open --today --brief
194
+ pm list --all --recent --brief
195
195
 
196
196
  # Search scoped to open work only (drops closed-history noise); statuses accept
197
197
  # all (no lifecycle restriction), open/closed/canceled aliases, or configured
@@ -293,12 +293,12 @@ pm eval --fail-under 0.6 --json # CI gate: exit non-zero when aggregate nDC
293
293
 
294
294
  ### Full results, totals, and bodies
295
295
 
296
- `pm list*` returns every matched row when neither `--limit` nor `--offset` is set. Every JSON/TOON result has the same pagination envelope: `total` is the pre-pagination match count, `has_more` and `truncated` are booleans, and `next_cursor` is either the continuation token or `null`. `completeness` reports whether the corpus was `complete`, `partial`, or `unchecked` (derived-index page), with unreadable item/directory counts. Use `--strict-read` when omissions must fail the command. The `filters` object omits unset values instead of emitting null placeholders, keeping long-running agent context stable and lean. Pass `--no-truncate` (alias `--all`) to force the entire matched set and override any `--limit` in one call the canonical "give me everything" flag for large-corpus audits:
296
+ `pm list` returns every matched row when neither `--limit` nor `--offset` is set. Every JSON/TOON result has the same pagination envelope: `total` is the pre-pagination match count, `has_more` and `truncated` are booleans, and `next_cursor` is either the continuation token or `null`. `completeness` reports whether the corpus was `complete`, `partial`, or `unchecked` (derived-index page), with unreadable item/directory counts. Use `--strict-read` when omissions must fail the command. The `filters` object omits unset values instead of emitting null placeholders, keeping long-running agent context stable and lean. Pass `--no-truncate` to force the entire matched set and override any `--limit` in one call. `--all` selects every lifecycle status; combine the flags for an unbounded all-status audit:
297
297
 
298
298
  ```bash
299
- pm list-all --no-truncate --brief # every matched row, ignoring any --limit
300
- pm list-open --limit 20 --json # stable total/has_more/truncated/next_cursor envelope
301
- pm list-all --strict-read --json # fail if any source item cannot be read
299
+ pm list --all --no-truncate --brief # every matched row, ignoring any --limit
300
+ pm list --status open --limit 20 --json # stable total/has_more/truncated/next_cursor envelope
301
+ pm list --all --strict-read --json # fail if any source item cannot be read
302
302
  ```
303
303
 
304
304
  Compatibility note: older responses emitted `total` only when pagination
@@ -312,7 +312,7 @@ unconditional pre-pagination match count, branch on `has_more` or
312
312
  JSON output is compact by default (id/status/type/title) for token efficiency. To pull item bodies in bulk in a single call — instead of one `pm get` per item — add `--include-body`, which expands each row to the full field set plus `body`:
313
313
 
314
314
  ```bash
315
- pm list-open --json --include-body # full fields + body for every returned row
315
+ pm list --status open --json --include-body # full fields + body for every returned row
316
316
  ```
317
317
 
318
318
  `pm get <id> --json` returns the item's `body` **inside** the `item` object (i.e. `.item.body`), matching where `list --include-body` places it and the long-form `description`/`acceptance_criteria` fields — so a single read exposes every field at a consistent path. Body is included at the default `standard` depth and above; `--depth brief` omits it.
@@ -322,10 +322,10 @@ pm list-open --json --include-body # full fields + body for every return
322
322
  `pm list*` accepts `--format <csv|table|json|ndjson|toon>` to choose how rows render. `csv` and `table` are **human export** modes — pipe them into a spreadsheet or read them directly in a terminal — while `json`/`toon` override the machine output format the same way the global `--json` flag does. `ndjson` writes each projected item as one self-contained JSON object per line, with no wrapper or trailing summary. The rendered fields follow the active projection, so combine `--format` with `--fields`/`--brief`/`--compact` to control exactly what appears:
323
323
 
324
324
  ```bash
325
- pm list-open --format table # aligned, monospace-friendly columns
326
- pm list-all --fields id,title,priority --format csv # spreadsheet export with chosen columns
327
- pm list-open --format csv > backlog.csv # capture for reporting
328
- pm list-all --brief --format ndjson | jq -c 'select(.status == "open")'
325
+ pm list --status open --format table # aligned, monospace-friendly columns
326
+ pm list --all --fields id,title,priority --format csv # spreadsheet export with chosen columns
327
+ pm list --status open --format csv > backlog.csv # capture for reporting
328
+ pm list --all --brief --format ndjson | jq -c 'select(.status == "open")'
329
329
  ```
330
330
 
331
331
  CSV output is RFC 4180 compliant (values with commas, quotes, or newlines are quoted; array fields such as `tags` join with `;`). `--format csv|table|ndjson` cannot be combined with the legacy envelope-oriented `--stream` mode.
@@ -338,13 +338,13 @@ The same `list*` commands and `pm search` extend this with governance-field pres
338
338
 
339
339
  ```bash
340
340
  # Find open Tasks that still need acceptance criteria
341
- pm list-open --type Task --filter-ac-missing --brief
341
+ pm list --status open --type Task --filter-ac-missing --brief
342
342
 
343
343
  # Closed items that were never given a resolution
344
- pm list-closed --filter-resolution-missing --json
344
+ pm list --status closed --filter-resolution-missing --json
345
345
 
346
346
  # Open items that still need a reviewer assigned
347
- pm list-open --filter-reviewer-missing --brief
347
+ pm list --status open --filter-reviewer-missing --brief
348
348
  ```
349
349
 
350
350
  ### Content-field presence filters
@@ -353,10 +353,10 @@ pm list-open --filter-reviewer-missing --brief
353
353
 
354
354
  ```bash
355
355
  # Closed items that shipped no documented learnings
356
- pm list-closed --no-learnings --brief
356
+ pm list --status closed --no-learnings --brief
357
357
 
358
358
  # Open work that has linked tests but no linked files yet
359
- pm list-open --has-tests --no-files --json
359
+ pm list --status open --has-tests --no-files --json
360
360
  ```
361
361
 
362
362
  ## Bulk Operations
@@ -1120,6 +1120,13 @@ Profiles are extensible: a package can ship its own archetype with `api.register
1120
1120
 
1121
1121
  Plan creation shares the normal create contract. Governance fields such as `--status`, `--deadline`, `--estimate`, `--acceptance-criteria`, `--assignee`, review/risk fields, comments, notes, learnings, reminders, events, and linked resources are accepted directly and pass through the same strict/progressive schema validation as `pm create`.
1122
1122
 
1123
+ Every positional plan action is also a discoverable virtual command path. Use
1124
+ `pm plan create --help --json` or `pm help plan create --json` for its exact
1125
+ arguments and effective flags, and use `pm contracts --command "plan create"
1126
+ --flags-only --json` for the matching machine contract. Root `pm plan --help
1127
+ --json` publishes the same action inventory under `subcommands`; omitting the
1128
+ required action fails as `missing_required_argument` before mutation dispatch.
1129
+
1123
1130
  ```bash
1124
1131
  pm plan create --title "Refactor lock retry" --scope "Improve retry semantics" --harness claude-code --parent pm-epic1 --related pm-rel1,pm-rel2 --claim
1125
1132
  pm plan create --title "Fix flaky retry test" --step "Read lock.ts" --step "Write the fix" --step "Run the tests"
@@ -1190,9 +1197,14 @@ Project-governance setters use the separate `governance_contracts` value
1190
1197
  domains; in particular, workflow enforcement is `off|warn|strict`, not the
1191
1198
  extension policy token `enforce`.
1192
1199
  Use `pm contracts --summary --json` first when bootstrapping in a tight context
1193
- window. `command_summaries` contains exactly one row per advertised command
1194
- path—including aliases and namespace childrenwith a meaningful intent plus
1195
- `default_max_estimated_tokens` and the format-specific TOON/JSON ceilings.
1200
+ window. `command_summaries` contains one row per registered command path,
1201
+ including aliases and namespace children, with a meaningful intent plus
1202
+ `default_max_estimated_tokens`. The low-token summary intentionally does not
1203
+ repeat the 32 virtual positional Plan, Assurance, and workspace-snapshot action rows;
1204
+ `grammar_contracts.positional_action_count` and `positional_action_parents`
1205
+ retain their complete discoverability and route callers to root help. A
1206
+ command-scoped contract for an exact action restores its typed positional
1207
+ signature, exact flags, provenance, and format-specific TOON/JSON ceilings.
1196
1208
  Package commands contribute their intent through command registration (falling
1197
1209
  back to the registered description), so agents never need a generic
1198
1210
  `Inspect flags.` placeholder. Request heavier command-specific flags or schemas
@@ -41,8 +41,8 @@ Use progressive disclosure:
41
41
  ```bash
42
42
  pm context --limit 10
43
43
  pm search "<request keywords>" --limit 10
44
- pm list-open --limit 20
45
- pm list-in-progress --limit 20
44
+ pm list --status open --limit 20
45
+ pm list --status in_progress --limit 20
46
46
  pm install guide-shell --project
47
47
  pm guide workflows
48
48
  ```
@@ -82,8 +82,8 @@ The canonical loop is maintained in [AGENT_GUIDE.md](AGENT_GUIDE.md) — this is
82
82
  ```bash
83
83
  pm context --limit 10
84
84
  pm search "<keywords>" --limit 10
85
- pm list-open --limit 20
86
- pm list-in-progress --limit 20
85
+ pm list --status open --limit 20
86
+ pm list --status in_progress --limit 20
87
87
  ```
88
88
 
89
89
  2. Claim and start
@@ -15,7 +15,8 @@ selectors are tracked by
15
15
  [pm-x710qm](../.agents/pm/issues/pm-x710qm.toon). Default contract suppression
16
16
  and canonical TOON tables are tracked by
17
17
  [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon) and
18
- [pm-5y05kq](../.agents/pm/issues/pm-5y05kq.toon).
18
+ [pm-5y05kq](../.agents/pm/issues/pm-5y05kq.toon). Nested evidence continuation
19
+ is tracked by [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon).
19
20
 
20
21
  ## Agent Quick Context
21
22
 
@@ -73,6 +74,7 @@ or not the current page has rows:
73
74
  "command": "list",
74
75
  "row_kind": "collection",
75
76
  "row_keys": ["items"],
77
+ "continuation_row_keys": ["items"],
76
78
  "fields": "supported",
77
79
  "jq_selector": ".row_contract.row_keys[] as $key | getpath($key | split(\".\")) | if type == \"array\" then .[] else if type == \"object\" then to_entries[] else empty end end",
78
80
  "toon_encoding": "tabular_when_uniform"
@@ -89,6 +91,12 @@ nested dependency graph and relationship-context rows addressable as
89
91
  `graph.nodes`, `graph.edges`, `context.nodes`, and `context.edges` without
90
92
  duplicating them at the envelope root. Array collections produce their
91
93
  elements; object maps produce jq `to_entries` rows.
94
+ `continuation_row_keys` is optional and defaults to `row_keys`. A command uses
95
+ it only when independently resumable nested evidence differs from its primary
96
+ amount-bounded rows. Validate, for example, keeps `checks` and `warnings` as
97
+ primary rows while a rich result can name
98
+ `checks.0.details.missing_resolution_rows` as a continuation row. This prevents
99
+ an inner diagnostic array from disabling `--output-limit` on the outer checks.
92
100
  `toon_encoding: "tabular_when_uniform"` declares that an array of flat objects
93
101
  with one shared key set renders as a length-marked TOON table; mixed, nested,
94
102
  or heterogeneous arrays retain the expanded representation. Quoted,
@@ -107,7 +115,8 @@ publish a row contract.
107
115
  SDK and package authors can import `PM_READ_ROW_CONTRACTS`,
108
116
  `PM_READ_ROW_JQ_SELECTOR`, and `resolveReadRowContract` from
109
117
  `@unbrained/pm-cli/sdk`. Existing package declarations are preserved only
110
- when `command`, `row_kind`, `row_keys`, `fields`, the conditional
118
+ when `command`, `row_kind`, `row_keys`, optional unique non-empty
119
+ `continuation_row_keys`, `fields`, the conditional
111
120
  `jq_selector`, and any supplied `toon_encoding` form a structurally valid row contract; malformed declarations
112
121
  are replaced by the canonical built-in contract when one applies.
113
122
 
@@ -94,7 +94,7 @@ Useful item types:
94
94
  ```bash
95
95
  pm context --limit 10
96
96
  pm search "restore lock retry" --limit 10
97
- pm list-open --limit 20
97
+ pm list --status open --limit 20
98
98
  pm claim <item-id>
99
99
  pm update <item-id> --status in_progress --message "Start implementation"
100
100
  pm update <item-id> --add-tags urgent,backend
package/docs/README.md CHANGED
@@ -40,9 +40,11 @@ pm guide release --json
40
40
  - [Testing](TESTING.md) - sandbox-safe local tests and linked-test orchestration.
41
41
  - [Security Governance](SECURITY_GOVERNANCE.md) - vulnerability reporting, review discipline, property fuzzing, and OpenSSF limitations.
42
42
  - [Architecture](ARCHITECTURE.md) - contributor internals: storage, mutation flow, search, extensions, and command contracts.
43
+ - [Noun–Verb CLI Grammar](CLI_GRAMMAR.md) - accepted command architecture, exhaustive destination census, hidden aliases, and the surface-growth gate.
43
44
  - [SDK Primitive Inventory](SDK_PRIMITIVE_INVENTORY.md) - SDK-first migration map and private-import ratchet for CLI/MCP layering.
44
45
  - [Package SDK Contract Conformance](PACKAGE_SDK_CONTRACT_CONFORMANCE.md) - authoritative public types, `typeof` module derivation, and the first-party parity gate.
45
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
+ - [SDK Artifact Output Contracts](SDK_ARTIFACT_OUTPUT.md) - clean stdout/file exporter channels, bounded receipts, binary-safe delivery, and shared NDJSON terminal framing.
46
48
  - [Context Relevance and Packing](CONTEXT_RELEVANCE.md) - shared CLI/SDK signals, derived-store provenance, ranking explanations, and token budgets.
47
49
  - [Output Projection and Omission Contracts](OUTPUT_PROJECTION_CONTRACTS.md) - explicit withheld-field receipts, mode-paired row keys, and completion resolver outcomes.
48
50
  - [Output Token Accounting](OUTPUT_TOKEN_ACCOUNTING.md) - opt-in CLI/MCP byte attribution, bounded receipt overhead, and release-level tokens-per-task baselines.
@@ -15,10 +15,13 @@ Every built-in read surface uses four output dimensions: what to include, how mu
15
15
 
16
16
  The contract covers `list`, `context`, `search`, `get`, `next`, `health`, `deps`, `graph`, `history`, `activity`, `validate`, `events`, `contracts`, `comments`, `notes`, `files`, `docs`, `stats`, and `aggregate`, including list aliases and `ctx`.
17
17
 
18
- Row shaping follows each envelope's `row_contract.row_keys`, including
19
- dot-delimited nested arrays and object maps such as `graph.nodes`. Include,
20
- amount, repeat suppression, and cost compaction therefore operate on the same
21
- machine-declared rows; they do not rely on command-specific top-level keys.
18
+ Primary row shaping follows each envelope's `row_contract.row_keys`, including
19
+ dot-delimited arrays and object maps such as `graph.nodes`. Include, amount, and
20
+ repeat suppression therefore remain bound to the rows the command says it
21
+ returns. A result may additionally declare `continuation_row_keys` when a
22
+ nested evidence collection must resume independently without redefining the
23
+ primary rows that `--output-limit` bounds. Cost compaction may inspect both
24
+ primary and nested collections; it does not rely on command-specific keys.
22
25
  The runtime uses that declaration internally on every read but omits the
23
26
  repeated metadata from results by default. Request
24
27
  `--output-row-contract` / `outputRowContract: true` when a consumer needs the
@@ -153,8 +156,9 @@ producer cursor, a universal output cursor, and a terminal page;
153
156
  `next_cursor` mirrors the first universal entry for ordinary one-path
154
157
  consumers. Replay the same query and budget
155
158
  with `--output-cursor <cursor>` / `outputCursor`. The cursor validates the
156
- command, declared row path, total, and stable row identities before slicing, so
157
- a mismatched or stale replay fails closed instead of skipping evidence. A
159
+ command, declared continuation path, total, and canonical content fingerprint
160
+ before slicing, so same-cardinality content changes and other stale replays
161
+ fail closed instead of skipping evidence. A
158
162
  bounded recovery therefore does not require replacing a 600-token request with
159
163
  an unbounded multi-megabyte response;
160
164
  `recovery_budget_multiplier: 1` declares that each next page retains the same
package/docs/RELEASING.md CHANGED
@@ -27,7 +27,8 @@ The local/hosted gate selection contract is tracked by
27
27
  [pm-ei6x66](../.agents/pm/tasks/pm-ei6x66.toon). Release-candidate analyzer
28
28
  provenance is tracked by [pm-u1baah](../.agents/pm/issues/pm-u1baah.toon), and
29
29
  authoritative blocker-recovery run selection by
30
- [pm-db8onn](../.agents/pm/issues/pm-db8onn.toon).
30
+ [pm-db8onn](../.agents/pm/issues/pm-db8onn.toon), and queued automatic
31
+ same-day recovery by [pm-dm2vfz](../.agents/pm/issues/pm-dm2vfz.toon).
31
32
 
32
33
  ## Version Policy
33
34
 
@@ -78,11 +79,11 @@ Policy:
78
79
  created, a non-`github-actions[bot]` closure of the exact bot-created
79
80
  `Auto Release blocked` issue on the same UTC day triggers one preparation
80
81
  retry
81
- - if today's tag already exists, blocker closure bypasses release-preparation
82
- provenance, dependency installation, and build work, then selects immutable
83
- Release evidence across both tag-push and guarded workflow-dispatch runs; a
84
- completed success is authoritative over stale failures and is recorded as
85
- recovered without republishing
82
+ - if today's tag already exists, a queued schedule or blocker closure bypasses
83
+ candidate preparation and accepts the immutable result only after independent
84
+ public-distribution evidence confirms the exact release; incomplete
85
+ publication continues through bounded recovery instead of being accepted
86
+ from tag presence alone
86
87
  - release preparation must pass all quality and compatibility gates before commit+tag push
87
88
  - before dependency installation or build, auto-release verifies that the
88
89
  candidate has exact-commit analyzer results or an immutable tree-identical
@@ -104,6 +105,10 @@ Policy:
104
105
  before release mutation and reported as `retry_already_attempted`, and
105
106
  workflow cleanup closures by `github-actions[bot]` are ignored.
106
107
  - after a scheduled run publishes a tag and the downstream release workflow succeeds, auto-release closes any open `Auto Release blocked` issue so the GitHub tracker reflects current release health
108
+ - workflow concurrency can leave a delayed schedule queued behind another
109
+ production run. The queued schedule resolves the current UTC-day immutable
110
+ result before candidate provenance, proves publication, and exits without
111
+ evaluating the generated release commit as a new candidate
107
112
 
108
113
  Pipeline entrypoint:
109
114
 
@@ -268,6 +273,25 @@ confirms that exact merge SHA, `main` base, and reviewed head. Remediate a
268
273
  refused direct-main candidate by landing the next tree-changing fix through a
269
274
  reviewed PR; never copy, synthesize, or bypass analyzer evidence.
270
275
 
276
+ ### Reviewed Delivery Closeout
277
+
278
+ The reviewed delivery includes its PM evidence, item closure, and generated
279
+ changelog. Complete those mutations on the implementation branch before merge
280
+ whenever their evidence is already available. A pull request is not complete
281
+ while known tracker or changelog closeout remains queued for a direct push.
282
+
283
+ When a repository update genuinely depends on the merge SHA or a post-merge
284
+ hosted result, create a normal follow-up branch from `main` and land that update
285
+ through another reviewed pull request. Do not push `.agents/pm/**` or
286
+ `CHANGELOG.md` closeout directly to `main`. Although tracker-only commits do not
287
+ create package-release eligibility by themselves, the direct commit still
288
+ becomes the default-branch head and lacks the reviewed analyzer evidence needed
289
+ by the next release-relevant candidate. `Release analyzer readiness (main)`
290
+ must fail closed in that state; its failure is a provenance control, not an
291
+ analyzer approval. Restore readiness only with a tree-changing, `main`-based,
292
+ reviewed pull request—never by copying statuses, weakening the gate, or
293
+ synthesizing a pull-request association.
294
+
271
295
  ```bash
272
296
  # Read-only parity check
273
297
  pnpm release:pipeline:dry-run
package/docs/SDK.md CHANGED
@@ -47,6 +47,13 @@ first-class recurrence relationships are tracked by
47
47
  [pm-rf120g](../.agents/pm/tasks/pm-rf120g.toon),
48
48
  [pm-3crymx](../.agents/pm/issues/pm-3crymx.toon), and
49
49
  [pm-ouyq3n](../.agents/pm/issues/pm-ouyq3n.toon).
50
+ Fail-closed whole-corpus reads and package-catalog output controls are tracked by
51
+ [pm-y4aaol](../.agents/pm/issues/pm-y4aaol.toon) and
52
+ [pm-2firut](../.agents/pm/issues/pm-2firut.toon).
53
+ Positional command signatures, action-scoped discovery, and MCP/CLI option
54
+ parity are tracked by [pm-ya7x55](../.agents/pm/tasks/pm-ya7x55.toon),
55
+ [pm-2tan](../.agents/pm/issues/pm-2tan.toon), and
56
+ [pm-y0htkd](../.agents/pm/issues/pm-y0htkd.toon).
50
57
 
51
58
  Use it for extension authoring, package authoring, command/action contract discovery, and deterministic app or CI automation. Do not import private `src/core/...` modules from external integrations or packages.
52
59
 
@@ -199,6 +206,7 @@ Source of truth:
199
206
  - [`src/sdk/merge/index.ts`](../src/sdk/merge/index.ts)
200
207
  - [`src/sdk/workspace-transaction-gc.ts`](../src/sdk/workspace-transaction-gc.ts)
201
208
  - [`src/sdk/query/list.ts`](../src/sdk/query/list.ts)
209
+ - [`src/sdk/query/complete-list.ts`](../src/sdk/query/complete-list.ts)
202
210
  - [`src/sdk/query/search.ts`](../src/sdk/query/search.ts)
203
211
  - [`src/sdk/query/search-pagination.ts`](../src/sdk/query/search-pagination.ts)
204
212
  - [`src/sdk/query/search-rendering.ts`](../src/sdk/query/search-rendering.ts)
@@ -292,7 +300,7 @@ Storage format-version exports (under `@unbrained/pm-cli/sdk/runtime`):
292
300
  Command/action contract exports:
293
301
 
294
302
  - `PmClient` / `runAction` (high-level in-process action execution for custom tools, bots, CI, and embedded runtimes)
295
- - Typed read primitives on `PmClient`: `get` (including `GetOptions.at` point-in-time reads), `list`, `search`, `context`, `next`, `aggregate`, `stats`, and `duplicates`; direct `getItemAt` reconstructs a canonical historical document without mutation. `duplicates` performs one bounded all-status metadata sweep and returns deterministic canonical-candidate and close-command guidance without mutating items.
303
+ - Typed read primitives on `PmClient`: `get` (including `GetOptions.at` point-in-time reads), `list`, `listAllComplete`, `search`, `context`, `next`, `aggregate`, `stats`, and `duplicates`; direct `getItemAt` reconstructs a canonical historical document without mutation. `listAllComplete` forces an all-status, full, strict, unbounded read and fails closed unless the returned envelope proves source completeness, unique ids, exact counts, no pagination, no field or budget omission, and no session projection. `duplicates` performs one bounded all-status metadata sweep and returns deterministic canonical-candidate and close-command guidance without mutating items.
296
304
  - Read primitive option/result contracts: `GetOptions` / `GetResult`, `ListOptions` / `ListResult`, `SearchOptions` / `SearchResult`, `ContextOptions` / `ContextResult`, `NextOptions` / `NextResult`, `AggregateOptions` / `AggregateResult`, `StatsCommandOptions` / `StatsResult`. Standard and brief `get` projections omit note bodies but expose `item.notes_count`; deep/full reads return the notes themselves, and narrow consumers can request `notes_count` explicitly.
297
305
  - Stream projection primitive: `serializeNdjsonRows` frames SDK-owned object rows as newline-delimited JSON without a trailing newline and rejects scalar/array rows, so package transports can match list/search/context CLI semantics without importing presentation code.
298
306
  - Context relevance primitives: `buildItemContextRelevanceCandidates`, `buildContextSignalSnapshot`, `ContextSignalStore`, `JsonFileContextSignalStoreAdapter`, `parseContextSignalSnapshot`, `defaultScoreContextCandidates`, `scoreContextCandidates`, `scoreContextCandidatesWithActiveExtensions`, `evaluateContextRanking`, `runContextEvaluationScenario`, `runContextEvaluationCorpus`, and `summarizeContextEvaluationReports`
@@ -336,6 +344,8 @@ Command/action contract exports:
336
344
  - Execution and diagnostics contracts: `TestCommandOptions` / `TestResult` / `TestRunResult`, `TestAllCommandOptions` / `TestAllResult`, `StartBackgroundRunCommandOptions` / `StartBackgroundRunResult`, `TestRuns*CommandOptions`, `EvalOptions` / `EvalResult`, `TelemetryCommandOptions` / `TelemetrySubcommand`, and `StatsCommandOptions` / `StatsResult`.
337
345
  - Linked-test authoring primitives: `parseLinkedTestJsonEntries`, the `parseLinkedTest*` field parsers, `LINKED_TEST_PM_CONTEXT_MODE_VALUES`, `LINKED_TEST_PROTECTED_ENV_KEYS`, `classifyLinkedTestFailure`, `countFailureCategories`, and `summarizeContextPreflight` let custom hosts validate, execute, classify, and report linked tests without duplicating CLI policy.
338
346
  - Agent command primitives: `normalizeItemAddressInvocation` and `supportsItemIdAlias` project one item-id grammar across CLI adapters; `renderMissingOptionRetry`, `resolveMissingOptionPlaceholder`, and `resolveRecoveryCommandName` preserve attempted argv, derive enum/boolean/scalar recovery arity from flag contracts, and identify the actual command without mistaking a global option value for one; `createUnknownSubcommandError` provides one typed positional refusal with complete allowed values and deterministic nearest retry; `rankCommandPaths` and `scoreCommandPathMatch` provide deterministic synonym/edit-distance/substring ranking; `resolveCreateExplicitEmptyFlag` and `supportsCreateExplicitEmpty` model a considered-but-empty strict repeatable input without inventing metadata or graph edges.
347
+ - Positional grammar primitives: `PM_COMMAND_POSITIONAL_CONTRACTS` declares every core and known-package command signature as ordered, typed slots; `PM_POSITIONAL_ACTION_CONTRACTS` promotes positional plan and assurance actions into discoverable virtual command paths with action-scoped flags, examples, and intent. `resolvePmCommandPositionalContract`, `resolvePmPositionalActionContract`, and `verifyPmCommandPositionalContracts` let custom hosts resolve or fail-closed compare the same signatures emitted by runtime contracts. The grammar receipt ratchets distinct semantic shapes through `positional_shape_budget` so a new arity cannot silently expand agent context.
348
+ - MCP/CLI option parity primitive: `verifyToolOptionCliParity` compares one `ToolOptionFlagContract` table with its executable `CliFlagContract` table. It fails when the transport-selected canonical flag is absent or when a parameter such as `linkedFile` cannot be invoked using its kebab-case CLI spelling (`--linked-file`) canonically or through a registered alias. Core create/update parity is part of the required command-grammar gate.
339
349
  - Refusal reachability primitives: generated `PmErrorCodeContract.owned_states` declarations bind stable codes to concrete states, probe ids, entrypoints, and exit classes; `verifyPmRefusalReachability` compares those declarations with real CLI, SDK, MCP, or package observations and fails closed for missing, duplicate, wrong-entrypoint, mismatched, or undeclared probes.
340
350
  - Typed plan workflow primitives on `PmClient`: `plan`, `planCreate`, `planShow`, `planAddStep`, `planUpdateStep`, `planCompleteStep`, `planBlockStep`, `planReorderStep`, `planRemoveStep`, `planLink`, `planUnlink`, `planDecision`, `planDiscovery`, `planValidation`, `planResume`, `planApprove`, and `planMaterialize`
341
351
  - Plan contracts: `PlanSubcommand`, `PlanCommandOptions`, `PlanCommandResult`, `PlanResultPlan`, `PlanStepSummary`, `PlanShowDepth`, and `PlanTemplateName`
@@ -1468,6 +1478,10 @@ helpers return `ExtensionCommandResult`; both names describe the same lifecycle
1468
1478
  payload shape with vocabulary-appropriate SDK signatures. `UpgradeResult` is the
1469
1479
  same structured payload rendered by the CLI, so embedded tools can own their
1470
1480
  presentation layer while sharing pm's package/install/doctor semantics.
1481
+ `packageCatalog` is a read surface and accepts the universal output controls;
1482
+ the CLI-equivalent `pm --output-budget unbounded package --catalog --json`
1483
+ therefore composes with the same output contract while catalog-plus-mutation
1484
+ invocations fail before any package state can change.
1471
1485
 
1472
1486
  Annotation and relationship convenience methods turn "project management =
1473
1487
  context management" into a typed SDK surface. Use `pm.comments`, `pm.notes`,
@@ -1576,9 +1590,35 @@ compact or `fields` projections return `ListProjectedItem` dictionaries. Use
1576
1590
  a `partial` scan with unreadable item/directory counts, and an `unchecked`
1577
1591
  derived-index page. Set `ListOptions.strictRead` (CLI `--strict-read`) when an
1578
1592
  automation must fail instead of accepting omissions.
1579
- `full: true` when an integration requires complete item metadata; the overload
1593
+ Use `full: true` when an integration requires complete item metadata; the overload
1580
1594
  then returns `ListFullResult` without an assertion or cast.
1581
1595
 
1596
+ When correctness depends on the entire workspace rather than a page, use the
1597
+ certifying primitive instead of rebuilding these conditions at every call site:
1598
+
1599
+ ```ts
1600
+ import {
1601
+ PmClient,
1602
+ certifyCompleteListResult,
1603
+ createCompleteListOptions,
1604
+ } from "@unbrained/pm-cli/sdk/runtime";
1605
+
1606
+ const pm = new PmClient({ pmRoot: "/workspace/.agents/pm" });
1607
+ const corpus = await pm.listAllComplete({ includeBody: true });
1608
+ corpus.complete_list.source_complete; // true, otherwise the call throws
1609
+
1610
+ // Custom transports can apply the same request and certificate independently.
1611
+ const candidate = await pm.list(createCompleteListOptions());
1612
+ const certified = certifyCompleteListResult(candidate);
1613
+ ```
1614
+
1615
+ `PmCompleteListValidationError.receipt` lists every failed invariant and carries
1616
+ the exact recovery command
1617
+ `pm list-all --full --strict-read --no-truncate --output-budget unbounded --json`.
1618
+ The helper never infers completeness from a large limit: derived-index reads,
1619
+ terminal-state filtering, duplicate ids, cursor/session projection, compaction,
1620
+ and any omission receipt all prevent certification.
1621
+
1582
1622
  CLI JSON consumers can add `--lean` to compact null and empty values. On
1583
1623
  item-list envelopes, lean output also removes request echoes (`filters`, `now`,
1584
1624
  `projection`, and `sorting`) and removes `next_cursor` when `has_more` is not
@@ -0,0 +1,72 @@
1
+ # SDK artifact output contracts
2
+
3
+ Trackers: [pm-dilou2](../.agents/pm/issues/pm-dilou2.toon) and [pm-mav1ak](../.agents/pm/features/pm-mav1ak.toon).
4
+
5
+ Exporter artifacts are data streams, not command receipts. A package declares
6
+ the channel when it registers an exporter so the host never guesses whether a
7
+ returned value should be appended to artifact bytes.
8
+
9
+ ## Agent quick context
10
+
11
+ - Declare `output.channel: "stdout"` for JSON, NDJSON, CSV, or opaque bytes.
12
+ The host suppresses its receipt by default, including under global `--json`.
13
+ - Declare `output.channel: "file"` when the exporter writes a file. The host
14
+ renders the returned bounded receipt by default.
15
+ - An exporter may still return a structured result. Suppressed receipts remain
16
+ available to hooks, telemetry, and embedding hosts.
17
+ - Write optional human progress or summaries to stderr. Never mix them into a
18
+ stdout artifact.
19
+ - Legacy registrations without `output` retain their previous rendering.
20
+
21
+ ## Registration
22
+
23
+ ```ts
24
+ import type { ExtensionApi } from "@unbrained/pm-cli/sdk";
25
+
26
+ export function activate(api: ExtensionApi): void {
27
+ api.registerExporter(
28
+ "report-json",
29
+ async () => {
30
+ process.stdout.write('{"items":[]}\n');
31
+ return { exported: 0 };
32
+ },
33
+ {
34
+ description: "Export a complete JSON report to stdout.",
35
+ output: {
36
+ channel: "stdout",
37
+ media_type: "application/json",
38
+ },
39
+ },
40
+ );
41
+ }
42
+ ```
43
+
44
+ The normalized contract is visible in the extension contribution inventory.
45
+ Derived help also states that stdout artifact bytes are exclusive and host
46
+ receipt rendering is suppressed when the extension does not supply a custom
47
+ description.
48
+
49
+ ## Channel behavior
50
+
51
+ | Artifact channel | Default receipt | stdout | stderr |
52
+ | --- | --- | --- | --- |
53
+ | `stdout` | `suppress` | Artifact bytes only | Extension-owned diagnostics or summary |
54
+ | `file` | `render` | Bounded structured receipt | Extension-owned diagnostics |
55
+
56
+ File exporters may select `receipt: "render"` or `receipt: "suppress"` as an
57
+ explicit compatibility control. Stdout artifacts always suppress the host
58
+ receipt; declaring `receipt: "render"` with `channel: "stdout"` is rejected at
59
+ registration so redirection, `jq`, and binary output remain clean by
60
+ construction.
61
+
62
+ The host does not decode, re-encode, buffer, or inspect stdout artifact bytes.
63
+ Consequently NUL bytes and non-UTF-8 payloads pass through unchanged. The
64
+ extension owns media correctness and stream completion; the host owns only the
65
+ post-handler receipt policy.
66
+
67
+ ## Shared NDJSON framing
68
+
69
+ SDK-built producers can use `serializeNdjsonStream(rows, trailer)` to append one
70
+ typed `pm.stream.trailer` after a bounded row batch. It supplies one stable
71
+ place for counts, continuation cursors, source identity, and constant-size
72
+ producer metadata without adding per-row overhead.
@@ -1,6 +1,6 @@
1
1
  # SDK context coordination primitives
2
2
 
3
- Trackers: [pm-e200](../.agents/pm/features/pm-e200.toon), [pm-4ri6](../.agents/pm/features/pm-4ri6.toon), and [pm-hcrmye](../.agents/pm/issues/pm-hcrmye.toon).
3
+ Trackers: [pm-e200](../.agents/pm/features/pm-e200.toon), [pm-ez1dfg](../.agents/pm/tasks/pm-ez1dfg.toon), [pm-4ri6](../.agents/pm/features/pm-4ri6.toon), and [pm-hcrmye](../.agents/pm/issues/pm-hcrmye.toon).
4
4
 
5
5
  `pm` treats project management as context management. These primitives let an
6
6
  agent learn what changed, avoid creating redundant work, and keep that work
@@ -26,38 +26,72 @@ Read committed history facts as newline-delimited JSON:
26
26
  pm events --type create --author agent-a --limit 100
27
27
  pm events --since <cursor> --item pm-abcd
28
28
  pm events --since <cursor> --follow --interval-ms 250
29
+ pm events --cursor-mode row --since <cursor>
29
30
  ```
30
31
 
31
- Each line carries `cursor`, `item_id`, `version`, `ts`, `author`, `type`, and
32
- `patch_count`; `--full` also includes the complete authoritative history entry.
32
+ By default, event rows carry `item_id`, `version`, `ts`, `author`, `type`, and
33
+ `patch_count`, followed by one `pm.stream.trailer` record with `count`,
34
+ `has_more`, `next_cursor`, and `source`. Persist the trailer cursor only after
35
+ the batch is durable. A crash before cursor persistence can replay the last
36
+ batch repeatedly, including across multiple crashes. Consumers must process
37
+ idempotently or deduplicate replays. `--cursor-mode row` preserves the previous
38
+ shape with one `cursor` per event and no trailer for consumers that checkpoint
39
+ every row. Already issued version-1 cursors remain accepted by `--since`.
40
+
41
+ Node runtimes use the rebuildable SQLite event projection. Runtimes such as Bun
42
+ that do not expose `node:sqlite` transparently scan the authoritative history
43
+ streams with the same ordering, filters, pagination, and cursor contract; pages
44
+ identify that path with `source: "authoritative_history"`.
45
+
46
+ `--full` also includes the complete authoritative history entry.
33
47
  `--type`, `--author`, and `--item` accept repeatable or comma-separated values.
34
48
  `--since` accepts either a cursor or an ISO timestamp. The CLI emits only event
35
- rows, so it composes directly with standard NDJSON consumers.
49
+ rows and the typed terminal record, so consumers can distinguish data from
50
+ recovery metadata without relying on position alone. Under `--follow`, every
51
+ non-empty page ends at the same batch boundary and an empty boundary is emitted
52
+ as an idle heartbeat.
36
53
 
37
54
  The public SDK provides bounded pages and an abortable async iterator:
38
55
 
39
56
  ```ts
40
57
  import {
41
58
  listMutationEvents,
59
+ subscribeMutationEventBatches,
42
60
  subscribeMutationEvents,
43
61
  } from "@unbrained/pm-cli/sdk";
44
62
 
45
- const page = await listMutationEvents({
46
- pmRoot,
47
- type: ["create", "update"],
48
- limit: 100,
49
- });
63
+ const eventTypes = ["create", "update"] as const;
64
+ let cursor: string | undefined;
65
+ let hasMore = true;
66
+ while (hasMore) {
67
+ const page = await listMutationEvents({
68
+ pmRoot,
69
+ type: eventTypes,
70
+ limit: 100,
71
+ ...(cursor === undefined ? {} : { since: cursor }),
72
+ });
73
+ await consumeBatch(page.events);
74
+ await persistCursor(page.next_cursor);
75
+ cursor = page.next_cursor;
76
+ hasMore = page.has_more;
77
+ }
50
78
 
51
79
  const controller = new AbortController();
52
- for await (const event of subscribeMutationEvents({
80
+ for await (const batch of subscribeMutationEventBatches({
53
81
  pmRoot,
54
- since: page.next_cursor,
82
+ type: eventTypes,
83
+ ...(cursor === undefined ? {} : { since: cursor }),
55
84
  signal: controller.signal,
56
85
  })) {
57
- await consume(event);
86
+ await consumeBatch(batch.events);
87
+ await persistCursor(batch.next_cursor);
58
88
  }
59
89
  ```
60
90
 
91
+ `subscribeMutationEvents` remains the per-event compatibility iterator and
92
+ defaults to row cursors. `subscribeMutationEventBatches` is the token-efficient
93
+ coordination primitive; it exposes the same boundaries used by the CLI.
94
+
61
95
  The `pm_events` MCP tool exposes the same bounded page contract. Consumers such
62
96
  as notification packages can store `next_cursor`, catch up after a restart,
63
97
  then follow without requiring a daemon. A pm-slack migration can replace
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).
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).
6
6
 
7
7
  ## Agent Quick Context
8
8
 
@@ -259,6 +259,19 @@ Do not update the baseline merely to make CI green. Change judgments and
259
259
  rationales in the corpus when product intent changes, and commit the corpus,
260
260
  baseline, scorer tests, and SDK documentation together.
261
261
 
262
+ Context-intent classification has a separate calibration receipt and one
263
+ manifest-backed recovery spelling:
264
+
265
+ ```bash
266
+ pnpm context:intent:calibrate
267
+ pnpm context:intent:calibrate --update
268
+ ```
269
+
270
+ The gate verifies that `package.json` exposes that exact script before it reads
271
+ or refreshes `scripts/release/context-intent-calibration.json`. A missing or
272
+ renamed script therefore fails with the same command contributors are told to
273
+ run, and pnpm forwards `--update` to the calibration gate.
274
+
262
275
  ## Hosted Gate Registry
263
276
 
264
277
  Tracked by [pm-k6t4yb](../.agents/pm/tasks/pm-k6t4yb.toon) and