@unbrained/pm-cli 2026.10.28 → 2026.10.31

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 (278) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +50 -0
  3. package/dist/cli/commander-usage.js +2 -2
  4. package/dist/cli/commands/lifecycle/append.d.ts +4 -0
  5. package/dist/cli/commands/lifecycle/append.js +1 -1
  6. package/dist/cli/commands/lifecycle/create.d.ts +4 -0
  7. package/dist/cli/commands/lifecycle/create.js +1 -1
  8. package/dist/cli/commands/lifecycle/plan.d.ts +3 -0
  9. package/dist/cli/commands/lifecycle/plan.js +1 -1
  10. package/dist/cli/commands/lifecycle/update-many.d.ts +4 -0
  11. package/dist/cli/commands/lifecycle/update-many.js +1 -1
  12. package/dist/cli/commands/lifecycle/update.d.ts +4 -0
  13. package/dist/cli/commands/lifecycle/update.js +1 -1
  14. package/dist/cli/error-guidance.d.ts +45 -5
  15. package/dist/cli/error-guidance.js +5 -3
  16. package/dist/cli/extension-command-help.d.ts +1 -0
  17. package/dist/cli/extension-command-help.js +2 -2
  18. package/dist/cli/help-content.js +2 -2
  19. package/dist/cli/main.d.ts +1 -5
  20. package/dist/cli/main.js +5 -5
  21. package/dist/cli/migration-gates.d.ts +1 -1
  22. package/dist/cli/migration-gates.js +1 -1
  23. package/dist/cli/preflight-warnings.d.ts +11 -0
  24. package/dist/cli/preflight-warnings.js +4 -0
  25. package/dist/cli/register-list-query.js +3 -3
  26. package/dist/cli/register-mutation.js +2 -2
  27. package/dist/cli-bundle/bundle-manifest.json +1 -1
  28. package/dist/cli-bundle/chunks/chunk-24J6TNYE.js +8 -0
  29. package/dist/cli-bundle/chunks/{chunk-YYD5MNAV.js → chunk-2AHSPMKJ.js} +2 -2
  30. package/dist/cli-bundle/chunks/chunk-35Q2B2GJ.js +2 -0
  31. package/dist/cli-bundle/chunks/chunk-43R7UTWV.js +2 -0
  32. package/dist/cli-bundle/chunks/chunk-6PSDQ7T7.js +8 -0
  33. package/dist/cli-bundle/chunks/{chunk-YUBUNECD.js → chunk-BS2KXT24.js} +84 -84
  34. package/dist/cli-bundle/chunks/{chunk-D3AIQZXF.js → chunk-GMBDZID5.js} +3 -3
  35. package/dist/cli-bundle/chunks/chunk-HSBTITO4.js +3 -0
  36. package/dist/cli-bundle/chunks/{chunk-LWW4F4G2.js → chunk-MRUA2Z43.js} +2 -2
  37. package/dist/cli-bundle/chunks/chunk-P3LNMWL2.js +2 -0
  38. package/dist/cli-bundle/chunks/chunk-PT7TS6E7.js +2 -0
  39. package/dist/cli-bundle/chunks/{chunk-TH5KPAN4.js → chunk-SBVX5CMV.js} +2 -2
  40. package/dist/cli-bundle/chunks/{chunk-D6P6IBPN.js → chunk-TL3O5GZA.js} +45 -45
  41. package/dist/cli-bundle/chunks/chunk-U7JXZMU5.js +6 -0
  42. package/dist/cli-bundle/chunks/{chunk-DM3PICGU.js → chunk-V6EWBTNH.js} +2 -2
  43. package/dist/cli-bundle/chunks/chunk-VC7TA67O.js +20 -0
  44. package/dist/cli-bundle/chunks/chunk-WNF6FOL7.js +31 -0
  45. package/dist/cli-bundle/chunks/chunk-WRXQAW7Q.js +114 -0
  46. package/dist/cli-bundle/chunks/{chunk-RZQNFHXO.js → chunk-WX25MU4N.js} +3 -3
  47. package/dist/cli-bundle/chunks/chunk-XDDPSWIW.js +2 -0
  48. package/dist/cli-bundle/chunks/chunk-YT5D5HNG.js +2 -0
  49. package/dist/cli-bundle/chunks/chunk-ZTJVOBDU.js +128 -0
  50. package/dist/cli-bundle/chunks/{indexed-receipt-blobs-LHLE7PSG.js → indexed-receipt-blobs-KGMJVFH2.js} +2 -2
  51. package/dist/cli-bundle/chunks/item-transaction-UWV6UNSV.js +2 -0
  52. package/dist/cli-bundle/chunks/{mutation-admission-GKDKHRTZ.js → mutation-admission-I4RHIT3Q.js} +2 -2
  53. package/dist/cli-bundle/chunks/{register-list-query-MHJJUM6M.js → register-list-query-MVDL5EXG.js} +6 -6
  54. package/dist/cli-bundle/chunks/register-mutation-GAF7LXRB.js +20 -0
  55. package/dist/cli-bundle/chunks/register-operations-JLFRL36Q.js +2 -0
  56. package/dist/cli-bundle/chunks/{register-setup-WUZ2ZSMY.js → register-setup-MZN6ONB3.js} +2 -2
  57. package/dist/cli-bundle/chunks/{settlement-hook-MN3Y7LVX.js → settlement-hook-YWSWFOZY.js} +2 -2
  58. package/dist/cli-bundle/chunks/{stage-2FYJGGG3.js → stage-2ZORTOF6.js} +2 -2
  59. package/dist/cli-bundle/focused-chunks/{chunk-4GN2ZPT5.js → chunk-2J7T2UCH.js} +2 -2
  60. package/dist/cli-bundle/focused-chunks/{chunk-YLVHHWHN.js → chunk-4PW5XWVI.js} +2 -2
  61. package/dist/cli-bundle/focused-chunks/chunk-4QPGJO2G.js +26 -0
  62. package/dist/cli-bundle/focused-chunks/{chunk-IQKLJFJE.js → chunk-57HPXGOQ.js} +18 -18
  63. package/dist/cli-bundle/focused-chunks/chunk-5MCGYBOQ.js +91 -0
  64. package/dist/cli-bundle/focused-chunks/chunk-6F6APBCX.js +3 -0
  65. package/dist/cli-bundle/focused-chunks/chunk-AFVN2KCP.js +44 -0
  66. package/dist/cli-bundle/focused-chunks/{chunk-ON5WFDCG.js → chunk-DFUTCKUF.js} +2 -2
  67. package/dist/cli-bundle/focused-chunks/chunk-EA65HVBO.js +12 -0
  68. package/dist/cli-bundle/focused-chunks/chunk-GP2WU43K.js +26 -0
  69. package/dist/cli-bundle/focused-chunks/{chunk-C2GLO7HU.js → chunk-HPWT3RBG.js} +54 -54
  70. package/dist/cli-bundle/focused-chunks/chunk-HSAEEWSI.js +2 -0
  71. package/dist/cli-bundle/focused-chunks/{chunk-7SZPZOIC.js → chunk-JLXGRDTG.js} +3 -3
  72. package/dist/cli-bundle/focused-chunks/chunk-JNKRUCVZ.js +2 -0
  73. package/dist/cli-bundle/focused-chunks/{chunk-JTCGDODH.js → chunk-KH5QJXY7.js} +2 -2
  74. package/dist/cli-bundle/focused-chunks/chunk-KKRIFBSL.js +2 -0
  75. package/dist/cli-bundle/focused-chunks/{chunk-TUN4M757.js → chunk-MW77Q3AQ.js} +2 -2
  76. package/dist/cli-bundle/focused-chunks/chunk-NOKG4RFN.js +22 -0
  77. package/dist/cli-bundle/focused-chunks/{chunk-DRN4W3YJ.js → chunk-NRBUMDLF.js} +2 -2
  78. package/dist/cli-bundle/focused-chunks/{chunk-ML5JIUM6.js → chunk-PC3R5CJV.js} +2 -2
  79. package/dist/cli-bundle/focused-chunks/chunk-PFBQOZPK.js +2 -0
  80. package/dist/cli-bundle/focused-chunks/{chunk-R3EA3SDW.js → chunk-QFMJGQGO.js} +3 -3
  81. package/dist/cli-bundle/focused-chunks/{chunk-I4X6AKOO.js → chunk-SFQKCA5K.js} +2 -2
  82. package/dist/cli-bundle/focused-chunks/chunk-WHIE2C6Q.js +2 -0
  83. package/dist/cli-bundle/focused-chunks/chunk-Y6UYRMVG.js +6 -0
  84. package/dist/cli-bundle/focused-chunks/{indexed-receipt-blobs-5H6RMRTK.js → indexed-receipt-blobs-KHWT44EK.js} +2 -2
  85. package/dist/cli-bundle/focused-chunks/item-transaction-LU75EG7D.js +2 -0
  86. package/dist/cli-bundle/focused-chunks/{mutation-admission-TM3SVU2O.js → mutation-admission-KDJ7SCPA.js} +2 -2
  87. package/dist/cli-bundle/focused-chunks/{settlement-hook-LBVWWSCF.js → settlement-hook-SJV52ZTV.js} +2 -2
  88. package/dist/cli-bundle/focused-chunks/{stage-7ZBRX2Q2.js → stage-R4KEBO37.js} +2 -2
  89. package/dist/cli-bundle/main.js +26 -22
  90. package/dist/cli-bundle/sdk-authoring.js +1 -1
  91. package/dist/cli-bundle/sdk-contracts.js +4 -4
  92. package/dist/cli-bundle/sdk-core.js +1 -43
  93. package/dist/cli-bundle/sdk-governance.js +1 -1
  94. package/dist/cli-bundle/sdk-graph.js +1 -1
  95. package/dist/cli-bundle/sdk-merge.js +61 -61
  96. package/dist/cli-bundle/sdk-query.js +1 -1
  97. package/dist/cli-bundle/sdk-runtime.js +1 -1
  98. package/dist/cli-bundle/sdk-testing.js +1 -1
  99. package/dist/cli-bundle/sdk.js +11 -11
  100. package/dist/core/config/nested-settings.js +1 -1
  101. package/dist/core/extensions/extension-hook-runtime.js +1 -1
  102. package/dist/core/extensions/extension-types.d.ts +4 -0
  103. package/dist/core/extensions/extension-types.js +1 -1
  104. package/dist/core/extensions/loader.js +1 -1
  105. package/dist/core/history/operation-contract.d.ts +2 -2
  106. package/dist/core/history/operation-contract.js +1 -1
  107. package/dist/core/item/literal-mutation-input.d.ts +12 -0
  108. package/dist/core/item/literal-mutation-input.js +2 -0
  109. package/dist/core/item/parse.d.ts +2 -0
  110. package/dist/core/item/parse.js +2 -2
  111. package/dist/core/lock/lock.js +4 -4
  112. package/dist/core/output/output.js +3 -3
  113. package/dist/core/schema/fields-file.js +1 -1
  114. package/dist/core/sentry/helpers.d.ts +6 -0
  115. package/dist/core/sentry/helpers.js +1 -1
  116. package/dist/core/sentry/instrument.d.ts +1 -1
  117. package/dist/core/sentry/instrument.js +1 -1
  118. package/dist/core/shared/constants.js +1 -1
  119. package/dist/core/shared/errors.d.ts +6 -0
  120. package/dist/core/shared/errors.js +1 -1
  121. package/dist/core/shared/output-unicode.d.ts +10 -0
  122. package/dist/core/shared/output-unicode.js +2 -0
  123. package/dist/core/store/item-store.js +1 -1
  124. package/dist/core/store/settings-validator.d.ts +1 -0
  125. package/dist/core/store/settings-validator.js +1 -1
  126. package/dist/core/store/settings.js +1 -1
  127. package/dist/core/telemetry/policy.d.ts +8 -0
  128. package/dist/core/telemetry/policy.js +1 -1
  129. package/dist/core/telemetry/runtime.js +3 -3
  130. package/dist/sdk/agent/command-recovery.d.ts +15 -0
  131. package/dist/sdk/agent/command-recovery.js +1 -1
  132. package/dist/sdk/cli-bootstrap.js +1 -1
  133. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +28 -0
  134. package/dist/sdk/cli-contracts/agent-output-contracts.js +2 -2
  135. package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1
  136. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  137. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  138. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  139. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -1
  140. package/dist/sdk/cli-contracts/registration-helpers.js +1 -1
  141. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -1
  142. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  143. package/dist/sdk/cli-contracts.d.ts +1 -1
  144. package/dist/sdk/cli-contracts.js +1 -1
  145. package/dist/sdk/completion/fish.js +4 -4
  146. package/dist/sdk/completion/zsh.js +3 -3
  147. package/dist/sdk/config.d.ts +1 -0
  148. package/dist/sdk/config.js +1 -1
  149. package/dist/sdk/core.d.ts +1 -0
  150. package/dist/sdk/core.js +1 -1
  151. package/dist/sdk/error-runtime.d.ts +9 -0
  152. package/dist/sdk/error-runtime.js +1 -1
  153. package/dist/sdk/errors.js +1 -1
  154. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  155. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  156. package/dist/sdk/index.d.ts +2 -2
  157. package/dist/sdk/index.js +1 -1
  158. package/dist/sdk/item-transaction.d.ts +33 -2
  159. package/dist/sdk/item-transaction.js +1 -1
  160. package/dist/sdk/lifecycle/append.js +1 -1
  161. package/dist/sdk/lifecycle/claim.js +1 -1
  162. package/dist/sdk/lifecycle/cli-input.d.ts +4 -0
  163. package/dist/sdk/lifecycle/cli-input.js +2 -0
  164. package/dist/sdk/lifecycle/close.js +1 -1
  165. package/dist/sdk/lifecycle/create.js +1 -1
  166. package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -1
  167. package/dist/sdk/lifecycle/plan.d.ts +2 -3
  168. package/dist/sdk/lifecycle/plan.js +1 -1
  169. package/dist/sdk/lifecycle/reopen.js +1 -1
  170. package/dist/sdk/lifecycle/repeated-terminal-state.d.ts +45 -0
  171. package/dist/sdk/lifecycle/repeated-terminal-state.js +2 -0
  172. package/dist/sdk/lifecycle/shared-unset-fields.d.ts +9 -0
  173. package/dist/sdk/lifecycle/shared-unset-fields.js +1 -1
  174. package/dist/sdk/lifecycle/update-many.d.ts +0 -1
  175. package/dist/sdk/lifecycle/update-many.js +1 -1
  176. package/dist/sdk/lifecycle/update.d.ts +29 -1
  177. package/dist/sdk/lifecycle/update.js +2 -2
  178. package/dist/sdk/output/table-rows.d.ts +15 -1
  179. package/dist/sdk/output/table-rows.js +1 -1
  180. package/dist/sdk/output.d.ts +1 -0
  181. package/dist/sdk/output.js +2 -2
  182. package/dist/sdk/ownership-source.d.ts +18 -0
  183. package/dist/sdk/ownership-source.js +1 -1
  184. package/dist/sdk/public-surface.json +1 -1
  185. package/dist/sdk/query/get.d.ts +1 -1
  186. package/dist/sdk/query/get.js +1 -1
  187. package/dist/sdk/query/history.d.ts +2 -0
  188. package/dist/sdk/query/history.js +1 -1
  189. package/dist/sdk/query/next-ranking-policy.d.ts +35 -0
  190. package/dist/sdk/query/next-ranking-policy.js +2 -0
  191. package/dist/sdk/query/next.d.ts +12 -2
  192. package/dist/sdk/query/next.js +2 -2
  193. package/dist/sdk/query/projection-contracts.d.ts +4 -0
  194. package/dist/sdk/query/projection-contracts.js +1 -1
  195. package/dist/sdk/read-output/surfaces.d.ts +27 -0
  196. package/dist/sdk/read-output/surfaces.js +2 -0
  197. package/dist/sdk/read-output-contracts.js +1 -1
  198. package/dist/sdk/runtime/mutation-value-validation.d.ts +16 -0
  199. package/dist/sdk/runtime/mutation-value-validation.js +2 -0
  200. package/dist/sdk/runtime-input.js +1 -1
  201. package/dist/sdk/runtime-primitives.d.ts +2 -0
  202. package/dist/sdk/runtime-primitives.js +1 -1
  203. package/dist/sdk/runtime.d.ts +14 -0
  204. package/dist/sdk/runtime.js +1 -1
  205. package/dist/sdk/structured-mutations.js +1 -1
  206. package/dist/sdk/test/execution-receipts.d.ts +25 -0
  207. package/dist/sdk/test/execution-receipts.js +2 -2
  208. package/dist/sdk/test/execution.d.ts +5 -0
  209. package/dist/sdk/test/execution.js +2 -2
  210. package/dist/sdk/workspace-transaction-gc.js +1 -1
  211. package/dist/sdk/workspace-transaction.d.ts +54 -0
  212. package/dist/sdk/workspace-transaction.js +2 -2
  213. package/dist/types.d.ts +2 -0
  214. package/dist/types.js +1 -1
  215. package/docs/AGENT_GUIDE.md +1 -1
  216. package/docs/AGENT_OUTPUT_ENCODINGS.md +12 -0
  217. package/docs/AGENT_UX_CONTRACTS.md +2 -1
  218. package/docs/COMMANDS.md +73 -15
  219. package/docs/CONFIGURATION.md +48 -1
  220. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +26 -0
  221. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +24 -2
  222. package/docs/PACKED_FIRST_RUN.md +2 -1
  223. package/docs/READ_OUTPUT_CONTRACTS.md +24 -6
  224. package/docs/SDK.md +207 -11
  225. package/docs/TESTING.md +46 -2
  226. package/docs/agent-task-token-baseline.json +1 -1
  227. package/docs/generated/FLAG_LEXICON_BUDGETS.md +1 -1
  228. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +6 -3
  229. package/marketplace.json +1 -1
  230. package/package.json +1 -1
  231. package/packages/pm-beads/package.json +1 -1
  232. package/packages/pm-calendar/extensions/calendar/index.ts +1 -0
  233. package/packages/pm-calendar/package.json +1 -1
  234. package/packages/pm-command-kit/package.json +1 -1
  235. package/packages/pm-digital-twin/package.json +1 -1
  236. package/packages/pm-governance-audit/package.json +1 -1
  237. package/packages/pm-guide-shell/package.json +1 -1
  238. package/packages/pm-kanban/package.json +1 -1
  239. package/packages/pm-lifecycle-hooks/package.json +1 -1
  240. package/packages/pm-linked-test-adapters/package.json +1 -1
  241. package/packages/pm-search-advanced/package.json +1 -1
  242. package/packages/pm-templates/package.json +1 -1
  243. package/packages/pm-todos/package.json +1 -1
  244. package/packages/pm-vcs/package.json +1 -1
  245. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  246. package/plugins/pm-claude/package.json +1 -1
  247. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  248. package/plugins/pm-codex/package.json +1 -1
  249. package/plugins/pm-codex/plugin.json +1 -1
  250. package/runtime-dependencies.json +1 -1
  251. package/dist/cli-bundle/chunks/chunk-2J7I54MQ.js +0 -2
  252. package/dist/cli-bundle/chunks/chunk-3KMYHYJV.js +0 -2
  253. package/dist/cli-bundle/chunks/chunk-4D25HF3V.js +0 -2
  254. package/dist/cli-bundle/chunks/chunk-7V37RC2L.js +0 -114
  255. package/dist/cli-bundle/chunks/chunk-AHVN4GHF.js +0 -31
  256. package/dist/cli-bundle/chunks/chunk-CS7QDSUX.js +0 -128
  257. package/dist/cli-bundle/chunks/chunk-CXUQEZDX.js +0 -8
  258. package/dist/cli-bundle/chunks/chunk-DKLEDWVW.js +0 -3
  259. package/dist/cli-bundle/chunks/chunk-E5QBZ4HI.js +0 -8
  260. package/dist/cli-bundle/chunks/chunk-JESLOJD7.js +0 -2
  261. package/dist/cli-bundle/chunks/chunk-PQLRKFPZ.js +0 -20
  262. package/dist/cli-bundle/chunks/chunk-SGFQQXFD.js +0 -2
  263. package/dist/cli-bundle/chunks/chunk-XHONSCLJ.js +0 -6
  264. package/dist/cli-bundle/chunks/chunk-ZX3XMTZG.js +0 -2
  265. package/dist/cli-bundle/chunks/register-mutation-SN425O3R.js +0 -20
  266. package/dist/cli-bundle/chunks/register-operations-EYUIUGPW.js +0 -2
  267. package/dist/cli-bundle/focused-chunks/chunk-3EHVI673.js +0 -2
  268. package/dist/cli-bundle/focused-chunks/chunk-46WLWK73.js +0 -2
  269. package/dist/cli-bundle/focused-chunks/chunk-6L4KKRK7.js +0 -26
  270. package/dist/cli-bundle/focused-chunks/chunk-6VDRAJYX.js +0 -2
  271. package/dist/cli-bundle/focused-chunks/chunk-B4ZQJEMT.js +0 -6
  272. package/dist/cli-bundle/focused-chunks/chunk-BZSACRVX.js +0 -91
  273. package/dist/cli-bundle/focused-chunks/chunk-F6UQJJYB.js +0 -2
  274. package/dist/cli-bundle/focused-chunks/chunk-L5GX2FGZ.js +0 -2
  275. package/dist/cli-bundle/focused-chunks/chunk-LPWZERVD.js +0 -12
  276. package/dist/cli-bundle/focused-chunks/chunk-OASYSUOH.js +0 -22
  277. package/dist/cli-bundle/focused-chunks/chunk-QUPGBO2L.js +0 -26
  278. package/dist/cli-bundle/focused-chunks/chunk-Z26ZPQH6.js +0 -3
@@ -68,10 +68,11 @@ When an agenda event belongs to an item already emitted in `high_level`, `low_le
68
68
 
69
69
  Claim conflicts distinguish stored assignment from an explicit claim:
70
70
 
71
- - `assigned to <identity>` means assignment metadata owns the current value.
71
+ - `assigned to <identity>` means assignment metadata owns the current value. The same phrase is used when history cannot establish the origin (unreadable history, no assignee change recorded, or a newest change that set a different holder); then `claim_source` is `unknown` and `claimed_at` is `null`, so read `claim_source` rather than the phrase when the origin matters.
72
72
  - `claimed by <identity>` means the latest ownership mutation was `pm claim`.
73
73
 
74
74
  The structured conflict code remains `already_claimed_by` for compatibility with atomic claim retry loops.
75
+ The refusal also carries the holder as typed fields (`claimed_by`, `claim_source`, `claimed_at`) in the error context, the JSON envelope and the public SDK `PmCliErrorContext`, so a retry loop can decide to wait, skip or coordinate without parsing the sentence; `resolveItemOwnershipConflict` exposes the same evidence to packages.
75
76
 
76
77
  ## Input and tracker recovery
77
78
 
package/docs/COMMANDS.md CHANGED
@@ -169,6 +169,31 @@ pm next --parent pm-epic01 # scope readiness to one epic's subtree
169
169
  pm next --ready-only --limit 3 --json # tightest agent-loop projection
170
170
  ```
171
171
 
172
+ `pm next` has two budgets with different scopes. `--token-budget <n>` bounds
173
+ only the selection (`recommended` plus `ready`) and reports it under
174
+ `truncation.ready_budget`; `filters.token_budget` echoes that request and is
175
+ `null` when none was made. The complete response, including `decision_needed`,
176
+ `containers`, `blocked` and `held_by_others`, is bounded by the universal
177
+ output budget (`--output-budget`, default ceiling of the read class) and
178
+ disclosed by the `read_output` receipt, which a selection budget now always
179
+ triggers so the total cost and the ceiling that bound it are visible. Use
180
+ `--token-accounting` for per-section bytes. Companion sections are not
181
+ visibility toggles: `--include-decisions`, `--include-gates` and
182
+ `--include-containers` move those rows into the claimable `ready` queue.
183
+
184
+ The ready queue is ordered by a declared policy, disclosed as
185
+ `filters.ranking_policy`. The default, `priority_floor`, resumes in-progress
186
+ work first, then orders ready items by priority tier and lets the relevance
187
+ score (recency, activity, deadlines, graph proximity) order items only within
188
+ a tier, so an automated log that gains a comment every hour cannot outrank a
189
+ ready P0 incident (GH-1618). `weighted` keeps the blended relevance order. Set
190
+ it per tracker with `pm config project set context_next_ranking_policy
191
+ weighted` (SDK callers pass `rankingPolicy`); a project's own
192
+ `context_relevance` scorer keeps its order under either policy. When the
193
+ policy and the score disagree, the recommendation's `reasons` say so
194
+ (`priority floor (relevance rank N)` or `relevance over pN ready work`), and
195
+ `--explain-ranking` still shows every item's score beside its final rank.
196
+
172
197
  Use `context` first for a compact active-work snapshot. Use `search` when the request names a concept, component, or prior issue.
173
198
  Use `duplicates --status all` for a true whole-history duplicate check. The
174
199
  result echoes `filters.statuses: null` for the unrestricted corpus; named or
@@ -495,7 +520,7 @@ it does not implicitly force an ownership or lock override.
495
520
  New checkpoints use schema version 2 so older CLI versions also refuse them
496
521
  instead of applying their former whole-item restoration behavior.
497
522
 
498
- When a flag is rejected with `Unknown option`, the error guidance now suggests the nearest supported flag (including abbreviations like `--desc` → `--description`) and notes when the flag is valid on a different command (for example `--type` on `test-all` points to `create`/`list`). Unknown-command guidance ranks agent verb synonyms first, bounded edit distance second, and substring matches last; `pm log` therefore points to `history`, `comments`, and `notes`, never a `catalog` command.
523
+ When a flag is rejected with `Unknown option`, the error guidance now suggests the nearest supported flag (including abbreviations like `--desc` → `--description`) and notes when the flag is valid on a different command (for example `--type` on `test-all` points to `create`/`list`). A quoted value that starts with `--` and contains spaces, such as a close reason `"--unset is now a list"`, is parsed as an unknown option. Its refusal says so, and its replay never drops the value. When only options follow the value, the replay passes it after a `--` separator, for example `pm close <id> -- "--unset is now a list"`. Otherwise the refusal explains how to pass it ([pm-stq61b](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-stq61b.toon); repository-only tracker record excluded from npm). Unknown-command guidance ranks agent verb synonyms first, bounded edit distance second, and substring matches last; `pm log` therefore points to `history`, `comments`, and `notes`, never a `catalog` command.
499
524
 
500
525
  Commands addressed to one item retain their canonical positional form and also accept `--id <item-id>` consistently. For example, `pm get --id pm-a1`, `pm comments --id pm-a1 --add "..."`, and `pm test --id pm-a1 --run` are equivalent to their positional forms. Supplying both forms is a usage error. Command-scoped `pm contracts --flags-only`, completion, and help expose the same alias.
501
526
 
@@ -645,9 +670,22 @@ pm --id-only create "Probe item" # output is only id + status
645
670
 
646
671
  For strict JSON consumers, the global `--lean` flag recursively omits null,
647
672
  undefined, empty-array, and empty-object noise while preserving meaningful
648
- false/zero/empty-string values. On usage failures it keeps only actionable
649
- error fields (`type`, `code`, `detail`, `exit_code`, examples, next steps, and
650
- recovery), reducing retry context without hiding the deterministic fix:
673
+ false/zero/empty-string values. On refusals it keeps only the fields that
674
+ change the next action: `type`, `code`, `detail`, `exit_code`, `next_steps`,
675
+ code-specific `required`/`examples`/`why`, specific recovery
676
+ (`suggested_retry`, `missing`, `allowed_values`, `next_best_command`) and
677
+ typed evidence such as the holder fields below. The generic requirement, the
678
+ `pm --help` examples and the invocation echo (`attempted_command`,
679
+ `normalized_args`, `provided_fields`) are dropped, in text as well as JSON,
680
+ so a lean refusal is never larger than its default rendering (GH-1610). Text
681
+ refusals print a single-line message once, as the headline, and repeat it
682
+ under `What happened` only when the headline is a classification.
683
+ An `already_claimed_by` refusal carries the holder as typed fields in every
684
+ mode: `claimed_by`, `claim_source` (`claim`, `assignment`, or `unknown`
685
+ when history is unreadable, silent, or names a different holder) and
686
+ `claimed_at` (the latest assignee change, or `null` when the origin is
687
+ unknown); text output renders them as `Held by: <holder> (<source> since
688
+ <time>)` and caps a very long holder name, which JSON keeps whole.
651
689
 
652
690
  ```bash
653
691
  pm --json --lean get pm-a1b2
@@ -662,6 +700,8 @@ Use `pm close <duplicate-id> --duplicate-of <canonical-id>` to close duplicates.
662
700
 
663
701
  Every transition into a terminal status stamps two distinct ISO timestamps: `closed_at` records when the tracker mutation happened, while `completed_at` records when the work actually finished. They initially match, but a delayed close can supply `pm close <id> --completed-at <timestamp>` and a terminal item can be corrected through the governed `pm update <id> --completed-at <timestamp>` path. Reopening clears both fields, and `pm copy` strips both. Time-window context, release notes, and changelog bucketing prefer `completed_at`; legacy items disclose their compatibility path by falling back to `closed_at`, then `updated_at` only when neither lifecycle timestamp exists.
664
702
 
703
+ `--unset` on `pm create`, `pm update` and `pm update many` clears scalar metadata fields by name. It is repeatable and also accepts a comma-separated list, so `--unset deadline,assignee --unset release` is the same as three separate flags. Each name is validated on its own: an unknown or empty part is refused by name before anything is written, including in `update many` dry runs. Field keys cannot contain commas, so the split is never ambiguous, and `pm schema add-field` refuses comma keys and flags ([pm-gh1633](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1633.toon); repository-only tracker record excluded from npm).
704
+
665
705
  `pm create --blocked-by <id>` and `pm update --blocked-by <id>` keep the scalar `blocked_by` field as the latest/primary blocker for compatibility. When the value resolves to a real item, the command also appends a `blocked_by` dependency edge so `pm deps` and reverse dependency scans see the full blocker graph. Repeating `pm update --blocked-by` with a different blocker preserves the prior blocker edge and appends the new one; repeating the same blocker is deduplicated. Use `pm update <id> --unset blocked-by` to clear the scalar and all `blocked_by` dependency edges.
666
706
 
667
707
  Unsupported `pm block` and `pm unblock` invocations return usage errors with
@@ -859,6 +899,19 @@ Template-defined custom type options accept string, number, and boolean defaults
859
899
  Tracker reference: [pm-l6rz](../.agents/pm/issues/pm-l6rz.toon).
860
900
 
861
901
  Use `pm close <id> "<reason>"` instead of `pm update --status closed`.
902
+ An update that still names the close status routes through `pm close` and
903
+ reports `auto_routed_from_update_to_close`. When the item is already closed
904
+ with the same reason (and the same `--completed-at`, if given), the update is
905
+ not a transition: it keeps `closed_at`, writes no closure history, and reports
906
+ `terminal_state_unchanged` instead, even with `--force` (GH-1628). Any other
907
+ requested fields take the ordinary update path: `updated_at` moves and a
908
+ history entry is written only when one of them changes a stored value, so a
909
+ request whose every field already matches leaves the item untouched. A
910
+ different reason is a repeat closure, which still needs `--force`. A blank
911
+ reason while `governance.require_close_reason` is enabled goes to the close
912
+ route, which refuses it exactly as it would on an open item. If another writer
913
+ reopens the item before the other fields are written, the request is closed
914
+ through `pm close` as usual.
862
915
 
863
916
  ## Lifecycle Aliases
864
917
 
@@ -996,7 +1049,7 @@ pm test <id> --run --only-last
996
1049
  pm test-all --status in_progress --progress
997
1050
  ```
998
1051
 
999
- Linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH` for every command and checks stored-command provenance before process creation. Direct runner binaries such as `vitest` or `node --test`, shell-wrapped equivalents, package-manager scripts, and non-Node runners are accepted consistently; prefer `node scripts/run-tests.mjs ...` when available because it also reproduces repository build, coverage, and cleanup policy. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list.
1052
+ Linked-test execution injects temporary `PM_PATH` and `PM_GLOBAL_PATH` for every command and checks stored-command provenance before process creation. Direct runner binaries such as `vitest` or `node --test`, shell-wrapped equivalents, package-manager scripts, and non-Node runners are accepted consistently; prefer `node scripts/run-tests.mjs ...` when available because it also reproduces repository build, coverage, and cleanup policy. The two-token form `--add command "npm test -- parser"` (and `--add path "..."` / `--remove command "..."`) is accepted when the value is quoted into a single shell argument; it is normalized to `--add command=...` before parsing. Use `--add-json` when command strings contain commas, nested quotes, shell variables, or `--` separators that are awkward to preserve through CSV-style `--add` parsing. Linked tests retain append order; consequently `--only-last` always selects the most recently added stored test. `--match`, `--only-index`, and `--only-last` select which linked tests execute without mutating the stored linked-test list. When a selector skips any test, the run receipt lists only the selected entries in `tests[]`. `count` still reports the full stored collection, `selection` records the selected 1-based indexes and the skipped count, and `tests_omitted: { count, restore_with: "pm test <id> --list" }` names the read that returns every stored test. The receipt no longer repeats the selection as a warning string. On a 58-test item, an `--only-last` receipt went from 8,662 to 2,212 bytes in TOON and from 18,826 to 2,695 bytes in JSON ([pm-gh1630](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1630.toon); repository-only tracker record excluded from npm). With `--lean`, a run that passed with no context mismatch and no failure category also replaces the sandbox `execution_context` with its modes, `mismatch_detected: false`, the `trusted` boolean (a passing run can be untrusted under an explicit override), the trust reason and `restore_with: "not retained; a run without --lean reports the full context"`, and omits the all-zero `failure_categories`. The hint deliberately does not say to rerun: a rerun repeats any mutating flags of the original invocation, such as `--remove-index`. That run measured 865 bytes in TOON and 1,166 in JSON. A failure, refusal, skip or context mismatch keeps the full provenance and categories ([pm-covpax](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-covpax.toon); repository-only tracker record excluded from npm).
1000
1053
 
1001
1054
  Strict linked-test guards:
1002
1055
 
@@ -1182,16 +1235,21 @@ unowned hooks. Default installation remains hook-free. See
1182
1235
 
1183
1236
  ## History and Recovery
1184
1237
 
1185
- Compact and provenance history without `--limit` display newest entries first,
1186
- so the latest handoff survives an output budget. The `order` receipt declares
1187
- the display direction and `total` counts all matching entries before limits.
1188
- Physical `index` values and durable version addresses retain their original
1189
- meaning. Use the returned `output_budget_truncation` continuation with
1190
- `--output-cursor` to read older rows without gaps or duplicates. Explicit
1191
- `--limit N` keeps the latest N entries in chronological order; `--full
1192
- --output-budget unbounded` returns complete chronological entries. Verification
1193
- always checks the full authoritative chain
1194
- ([pm-gh1605](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1605.toon); tracker record excluded from npm).
1238
+ Compact and provenance history default to newest-first, including reads with
1239
+ `--limit`. Full entries default to oldest-first. Use `--order oldest_first` or
1240
+ `--order newest_first` to choose the same direction for any projection and its
1241
+ value diffs. `--limit N` selects the latest N matching entries before ordering.
1242
+ The `order` receipt declares direction and `total` counts matches before limits.
1243
+ Physical indices and durable versions retain their original meaning. Use
1244
+ `--output-cursor` with the returned continuation to traverse the selected order.
1245
+ Verification always checks the full authoritative chain.
1246
+
1247
+ Compatibility: a compact/provenance latest-N read used to flip to chronological
1248
+ order. Chronological consumers should explicitly use, for example,
1249
+ `pm history pm-a1b2 --diff --limit 20 --order oldest_first`.
1250
+ Full reads keep their chronological default.
1251
+ Tracked by [pm-gh1617](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1617.toon)
1252
+ (tracker record excluded from npm).
1195
1253
 
1196
1254
  After a branch merge that touched tracker history, preview and apply the
1197
1255
  one-command reconciliation gate:
@@ -110,7 +110,43 @@ capture an opaque boot/PID-namespace coordinate and the owner's process start
110
110
  tick. A matching host can reclaim a provably dead original owner before TTL,
111
111
  including when its PID has been reused. Foreign hosts, legacy receipts, denied
112
112
  process probes and unavailable identity remain subject to the existing TTL
113
- policy. Early recovery writes an immutable `locks/recoveries/*.json` intent
113
+ policy. A commit gate with a provably dead same-host owner can also be recovered
114
+ immediately, before its ordinary age threshold. Its original owner receipt is
115
+ retained in `locks/recoveries/gate-<generation-hash>/owner.json`. These nonempty
116
+ generation directories prevent concurrent recoverers from retiring a replacement
117
+ gate and must be retained while writers may still hold observations of that
118
+ generation. Recovery after the age grace requires a dead PID or verified PID
119
+ reuse for a readable owner, and uses the same retained generation protocol.
120
+ A live PID with unavailable start identity keeps its gate regardless of age;
121
+ elapsed time alone cannot safely distinguish a paused writer from abandonment.
122
+ Recorded host coordinates must be verified before recovery; a recorded foreign
123
+ host or unavailable recorded host evidence cannot be replaced by a local PID
124
+ comparison. Legacy receipts without `host_identity` use a local PID probe after
125
+ the grace period. On shared storage, that probe can retire a gate owned by a
126
+ writer on another host whose PID appears dead locally; these legacy receipts
127
+ do not provide cross-host recovery safety.
128
+ Non-missing owner-file read errors also retain the gate regardless of age.
129
+ Lock wait durations use a monotonic clock independently of the
130
+ wall-clock timestamps used for TTL policy. This recovery is tracked by
131
+ [pm-gh1609](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1609.toon)
132
+ (repository tracker record excluded from npm).
133
+
134
+ If a reboot, PID-namespace change or tracker relocation leaves an unverifiable
135
+ `locks/<lock-file>.stale-cleanup` gate, automatic age-based recovery intentionally
136
+ refuses it. `pm gc --scope locks` does not remove these gate directories.
137
+ For manual recovery, first stop every CLI, MCP server, watcher and service that
138
+ can write this tracker, including writers on other hosts when storage is shared.
139
+ Independently establish that the recorded original owner cannot still run; a
140
+ different host hash or an old timestamp alone is insufficient. While exclusive
141
+ access is maintained, preserve the complete gate directory and its `owner.json`
142
+ receipt by moving it to a unique backup location outside `locks`, without
143
+ overwriting any existing backup. Keep `locks/recoveries` evidence intact. Then
144
+ retry the original command, run `pm health --check-only`, and verify the affected
145
+ item's history with `pm history <id> --verify --strict-exit`. If exclusive access
146
+ or owner death cannot be established, retain the gate and investigate ownership.
147
+ This procedure does not override the remaining lease's TTL or ownership checks.
148
+
149
+ Early recovery writes an immutable `locks/recoveries/*.json` intent
114
150
  receipt before removal; it records the original owner and is an attempted
115
151
  recovery audit, not proof that a later mutation committed. Keep these local
116
152
  runtime receipts out of version control.
@@ -390,6 +426,16 @@ pm get <id> --full --json
390
426
  pm contracts --json
391
427
  ```
392
428
 
429
+ With JSON output, preflight advisories are deferred until the command outcome.
430
+ A failed command includes their stable codes in the error envelope's `warnings`
431
+ array on stderr, preserving one parseable error and its original exit code.
432
+ Additional explanatory or remediation text is retained in `warning_details`.
433
+ A successful command emits one `{ "type": "warning", "warnings": [...] }`
434
+ diagnostic on stderr when needed; its result remains on stdout. Human output
435
+ keeps immediate warning text. See
436
+ [pm-gh1602](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1602.toon)
437
+ (repository tracker record excluded from npm).
438
+
393
439
  `--output-format json|toon` selects encoding on both reads and mutations.
394
440
  Item collection and lifecycle commands accept `--format json|toon` as a
395
441
  compatibility alias, before or after the command:
@@ -593,6 +639,7 @@ Useful commands:
593
639
 
594
640
  ```bash
595
641
  pm config project set search_default_mode keyword
642
+ pm config project set context_next_ranking_policy weighted # pm next: priority_floor (default) or weighted
596
643
  pm config project set search_mutation_refresh_policy cache_only
597
644
  pm config project set search_embedding_corpus_max_characters 12000
598
645
  pm config project set search_query_expansion_enabled true
@@ -130,6 +130,32 @@ patterns, absolute paths and invocation-relative anchoring remain supported.
130
130
  The regression uses a real temporary directory and the same deeply nested input
131
131
  that failed before the replacement. Audit errors remain mandatory failures.
132
132
 
133
+ ## Redirect credential and glob amplification advisories
134
+
135
+ [pm-irviv0](../.agents/pm/issues/pm-irviv0.toon) tracks
136
+ [GHSA-mrwp-f3q8-3g9p](https://github.com/advisories/GHSA-mrwp-f3q8-3g9p)
137
+ (`follow-redirects` 1.16.0 through 1.16.1: cross-realm `sensitiveHeaders`
138
+ arrays are discarded, so custom credentials can follow redirects) and
139
+ [GHSA-g3hv-75wg-m249](https://github.com/advisories/GHSA-g3hv-75wg-m249)
140
+ (`minimatch` before 11.0.1: denial of service through glob-part
141
+ amplification). Both were published on October 30 and the registry feed
142
+ reported them from the next run on `main` while OSV was still clean, so the
143
+ advisory gate refused every PR and the scheduled release path until the lock
144
+ changed. `follow-redirects` is reached only through the CodSpeed benchmark
145
+ plugin's Axios client, and `minimatch` through ESLint and its config array
146
+ and as a direct dependency of `@stryker-mutator/core` (mutation testing); all
147
+ of these are development dependencies and none establishes a CLI or SDK
148
+ route. The pnpm overrides require `follow-redirects` 1.16.2 or a newer
149
+ 1.x release and `minimatch` 11.0.1 or a newer 11.x release. `minimatch` 11
150
+ keeps dual CommonJS and ES module exports, so ESLint's `require` path is
151
+ unchanged and the full lint run passes; the override applies to the Stryker
152
+ path as well. Both releases satisfy pnpm's one-day
153
+ minimum release age without an exclusion; the seven-day Dependabot cooldown
154
+ is unchanged. The gate's catch-all refusal said that no feed success could be
155
+ inferred, which hid the real cause (a non-empty registry id list); read
156
+ `.cache/dependency-security/receipt.json` before treating that message as a
157
+ feed outage.
158
+
133
159
  ## CodSpeed 5.7.1 patch
134
160
 
135
161
  CodSpeed's declared dependency previously resolved Axios 1.19.0, and both
@@ -120,8 +120,9 @@ primary rows while a rich result can name
120
120
  `checks.0.details.missing_resolution_rows` as a continuation row. This prevents
121
121
  an inner diagnostic array from disabling `--output-limit` on the outer checks.
122
122
  `toon_encoding: "tabular_when_uniform"` declares that an array of flat objects
123
- with one shared key set renders as a length-marked TOON table; mixed, nested,
124
- or heterogeneous arrays retain the expanded representation. Quoted,
123
+ with one shared key set can render as a length-marked TOON table. Nested or
124
+ heterogeneous object rows can also use a smaller table with explicit sibling
125
+ encoding metadata; otherwise they retain the expanded representation. Quoted,
125
126
  separator-bearing, and multiline values use the canonical TOON encoder and
126
127
  round-trip through the strict decoder.
127
128
  Commands without a row collection, including a dependency tree or leaf `get`,
@@ -463,3 +464,24 @@ Continuation and compaction slice these receipts with the rows. Self-describing
463
464
  focus rows need no extra receipt. Semantic receipts are preserved during
464
465
  explanatory-string compaction, and corrupt alphabet or row-count mismatches are
465
466
  rejected.
467
+
468
+
469
+ ### Compact nested table metadata
470
+
471
+ Tracked by [pm-gh1603](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1603.toon)
472
+ (tracker record excluded from npm). The SDK `encodePmTableRows(rows, { compact: true })`
473
+ can declare `list_columns` (column to delimiter) and `null_columns` alongside
474
+ `json_columns` and `absent`. Omitted null columns also carry `column_order`
475
+ to restore their original first-occurrence positions. `decodePmTableRows` restores
476
+ these facts exactly.
477
+ A safe string-array column uses `;` between nonempty members; an empty cell means
478
+ an empty array. Any empty member, delimiter collision, mixed type or nested value
479
+ uses the existing JSON-column encoding instead. Null columns are omitted only
480
+ when every row explicitly contains null; missing fields remain distinct.
481
+
482
+ The TOON host selects compact tables only when they reduce rendered bytes.
483
+ Agenda rows therefore share null-field declarations and tag arrays avoid repeated
484
+ JSON escaping. JSON output and SDK query results retain their original values.
485
+ Consumers of TOON tables must honor all declared encoding metadata or use the
486
+ current SDK decoder. Whole-envelope budgets measure the actual serialized form,
487
+ including decoding metadata.
@@ -6,7 +6,8 @@ Trackers: [pm-ygli86](../.agents/pm/tasks/pm-ygli86.toon),
6
6
  [pm-p5u6](../.agents/pm/chores/pm-p5u6.toon).
7
7
 
8
8
  CI globally installs one tarball in isolated npm prefixes on Ubuntu/macOS/Windows
9
- with Node 22.18.0 and 24, runs the installed `pm` shim, then invokes:
9
+ with Node 22.18.0 and 24, one `Packed runtime (<os>)` job per OS with a fresh
10
+ prefix, cache and home per Node version, runs the installed `pm` shim, then invokes:
10
11
 
11
12
  ```bash
12
13
  node scripts/release/packed-first-run.mjs /path/to/installed/@unbrained/pm-cli
@@ -221,12 +221,30 @@ Read-option recovery is tracked by
221
221
  use `--output-format toon|json` across read commands. Completeness uses
222
222
  `--output-include full` on list, search and get; context detail depth uses
223
223
  `--depth full`. These controls retain the normal row and token ceilings.
224
- When `context --full`, `list/search --depth full`, or `--toon` on list, search,
225
- context or get is refused,
226
- the error provides `recovery.suggested_retry_args` for the same command with the
227
- supported spelling. The SDK's `resolveReadOptionRetryArgs` exposes the same
228
- token-preserving correction. Conflicting controls or ambiguous operands do not
229
- receive a guessed retry.
224
+ When a completeness spelling is refused on a read command that has an
225
+ equivalent spelling of its own, the error provides
226
+ `recovery.suggested_retry_args` for that same command. Examples are
227
+ `get/context --brief`, which becomes `--depth brief`, and
228
+ `list/search/history --depth full`, which becomes `--full`. The same applies to
229
+ `--toon` on list, search, context or get, which becomes `--output-format toon`.
230
+ The correction is derived from runtime contracts, not from a hand-maintained
231
+ list. A boolean `--<level>` maps to `--depth <level>` only when that command's
232
+ `--depth` flag contract declares the level in its `values` domain. A
233
+ `--depth <level>` maps to `--<level>` only when the level is one of the
234
+ command's declared read-output projection modes. `--depth standard` on a
235
+ command without `--depth` replays without the flag, because standard is every
236
+ command's default level. Aliased paths such as `deps` and `health` replay on
237
+ their canonical noun-first path (`pm item deps`, `pm ops health`). When a
238
+ command has no equivalent, for example `search --depth brief`, no retry is
239
+ guessed. The refusal instead lists the controls that command accepts: for
240
+ search, `Completeness controls accepted by pm search: --compact, --full.`
241
+ ([pm-gh1626](https://github.com/unbraind/pm-cli/blob/main/.agents/pm/issues/pm-gh1626.toon);
242
+ repository-only tracker record excluded from npm). The SDK's
243
+ `resolveReadOptionRetryArgs` exposes the same token-preserving correction, and
244
+ `resolveReadCompletenessControls` returns each command's declared vocabulary.
245
+ Conflicting controls such as `--fields`, `--output-include`, `--section`, `--for`
246
+ or another completeness flag, and ambiguous operands, do not receive a guessed
247
+ retry.
230
248
  An explicit `--json` conflicts with `--toon`, so that invocation receives no
231
249
  encoding-changing retry. Non-conflicting TOON refusals include the corrected
232
250
  command in human output without requiring JSON diagnostics.