@unbrained/pm-cli 2026.8.13 → 2026.8.15

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 (194) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +165 -113
  3. package/dist/cli/commander-usage.js +17 -4
  4. package/dist/cli/error-guidance.d.ts +2 -0
  5. package/dist/cli/error-guidance.js +52 -25
  6. package/dist/cli/main.js +40 -3
  7. package/dist/cli/register-mutation.js +4 -2
  8. package/dist/cli/register-operations.js +5 -5
  9. package/dist/cli-bundle/bundle-manifest.json +146 -178
  10. package/dist/cli-bundle/chunks/{chunk-F7FJYGK3.js → chunk-24GAV7XL.js} +2 -2
  11. package/dist/cli-bundle/chunks/chunk-AIM6VT2N.js +13 -0
  12. package/dist/cli-bundle/chunks/chunk-DSWDLTDR.js +197 -0
  13. package/dist/cli-bundle/chunks/{chunk-Q47C67TQ.js → chunk-J42EGKDK.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-KIEGUBYQ.js +2 -0
  15. package/dist/cli-bundle/chunks/{chunk-3ZMOWAFM.js → chunk-KLKYLSDX.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-QGTUPEU5.js → chunk-LJHOAVGI.js} +59 -59
  17. package/dist/cli-bundle/chunks/chunk-MEM2ZS3O.js +5 -0
  18. package/dist/cli-bundle/chunks/chunk-QHPCJWEJ.js +35 -0
  19. package/dist/cli-bundle/chunks/{chunk-YLBAPY22.js → chunk-WLPDLNEZ.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-list-query-4HIZ7EA3.js → register-list-query-CT3LFDDN.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-mutation-W64FZ5HN.js → register-mutation-NWEVA5YS.js} +3 -3
  22. package/dist/cli-bundle/chunks/register-operations-AHIAG5KM.js +2 -0
  23. package/dist/cli-bundle/chunks/{register-setup-634MFRXU.js → register-setup-ZJZFVAKE.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/chunk-4X57RE4U.js +2 -0
  25. package/dist/cli-bundle/focused-chunks/chunk-6XKF3PGV.js +18 -0
  26. package/dist/cli-bundle/focused-chunks/chunk-7NJ4QYQ2.js +2 -0
  27. package/dist/cli-bundle/focused-chunks/{chunk-I75MANL7.js → chunk-EXZA4257.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/chunk-ITAUHSO6.js +50 -0
  29. package/dist/cli-bundle/focused-chunks/{chunk-OOYYKQWX.js → chunk-KLVUMNXJ.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-2RI2FESN.js → chunk-KT5XMYSX.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/{chunk-E3AVJ655.js → chunk-KTKH4IMG.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-M67F5AIN.js +8 -0
  33. package/dist/cli-bundle/focused-chunks/{chunk-3DJSGWVB.js → chunk-NSPYTG6G.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/chunk-OKA6ELTL.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-PUISBOPP.js +2 -0
  36. package/dist/cli-bundle/focused-chunks/chunk-QLNMCESQ.js +155 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-IIS2FRKL.js → chunk-SLKC6QLJ.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-U65UC4G3.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-WTSER4WJ.js +16 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-2JP7W7GO.js → chunk-ZMFXQ7VF.js} +2 -2
  41. package/dist/cli-bundle/main.js +13 -13
  42. package/dist/cli-bundle/sdk-authoring.js +1 -1
  43. package/dist/cli-bundle/sdk-contracts.js +1 -1
  44. package/dist/cli-bundle/sdk-core.js +41 -41
  45. package/dist/cli-bundle/sdk-governance.js +1 -1
  46. package/dist/cli-bundle/sdk-graph.js +1 -1
  47. package/dist/cli-bundle/sdk-merge.js +110 -1
  48. package/dist/cli-bundle/sdk-query.js +1 -1
  49. package/dist/cli-bundle/sdk-runtime.js +1 -1
  50. package/dist/cli-bundle/sdk-testing.js +1 -1
  51. package/dist/cli-bundle/sdk.js +2 -2
  52. package/dist/core/diagnostics/remediation.js +7 -2
  53. package/dist/core/extensions/reserved-host-flags.js +3 -2
  54. package/dist/core/history/drift-scan.d.ts +6 -0
  55. package/dist/core/history/drift-scan.js +74 -50
  56. package/dist/core/history/replay.d.ts +14 -1
  57. package/dist/core/history/replay.js +45 -8
  58. package/dist/core/history/workspace-history.d.ts +59 -0
  59. package/dist/core/history/workspace-history.js +197 -10
  60. package/dist/core/output/output.d.ts +2 -0
  61. package/dist/core/output/output.js +13 -4
  62. package/dist/core/shared/command-types.d.ts +2 -0
  63. package/dist/core/shared/command-types.js +2 -2
  64. package/dist/core/shared/errors.d.ts +12 -0
  65. package/dist/core/shared/errors.js +2 -2
  66. package/dist/mcp/tool-definitions.js +9 -5
  67. package/dist/sdk/agent/refusal-reachability.d.ts +61 -0
  68. package/dist/sdk/agent/refusal-reachability.js +91 -3
  69. package/dist/sdk/cli-bootstrap.d.ts +2 -0
  70. package/dist/sdk/cli-bootstrap.js +7 -2
  71. package/dist/sdk/cli-contracts/completeness.js +3 -2
  72. package/dist/sdk/cli-contracts/flag-contracts.js +3 -2
  73. package/dist/sdk/cli-contracts/registration-helpers.js +3 -2
  74. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +11 -1
  75. package/dist/sdk/cli-contracts/runtime-contracts.js +176 -65
  76. package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -5
  77. package/dist/sdk/cli-contracts/tool-schema.js +10 -3
  78. package/dist/sdk/cli-program.js +4 -3
  79. package/dist/sdk/context-relevance.js +12 -4
  80. package/dist/sdk/core.d.ts +2 -2
  81. package/dist/sdk/core.js +3 -3
  82. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -2
  83. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -26
  84. package/dist/sdk/governance/assurance-action.d.ts +7 -1
  85. package/dist/sdk/governance/assurance-action.js +7 -6
  86. package/dist/sdk/governance/assurance-mutation-error.d.ts +42 -1
  87. package/dist/sdk/governance/assurance-mutation-error.js +27 -3
  88. package/dist/sdk/governance/assurance-runtime.js +12 -11
  89. package/dist/sdk/governance/assurance.d.ts +9 -0
  90. package/dist/sdk/governance/assurance.js +82 -16
  91. package/dist/sdk/governance/extension-host-version.d.ts +25 -0
  92. package/dist/sdk/governance/extension-host-version.js +105 -0
  93. package/dist/sdk/governance/health.d.ts +32 -1
  94. package/dist/sdk/governance/health.js +132 -28
  95. package/dist/sdk/governance/provenance-health.d.ts +27 -0
  96. package/dist/sdk/governance/provenance-health.js +95 -3
  97. package/dist/sdk/governance/validate-history-drift.d.ts +7 -0
  98. package/dist/sdk/governance/validate-history-drift.js +68 -0
  99. package/dist/sdk/governance/validate.js +9 -52
  100. package/dist/sdk/governance.d.ts +6 -0
  101. package/dist/sdk/governance.js +8 -2
  102. package/dist/sdk/graph/assembly.d.ts +23 -0
  103. package/dist/sdk/graph/assembly.js +54 -2
  104. package/dist/sdk/graph/durable-cache.js +50 -20
  105. package/dist/sdk/graph/governance-contracts.d.ts +1 -1
  106. package/dist/sdk/graph/governance-contracts.js +4 -2
  107. package/dist/sdk/graph/governance.d.ts +21 -1
  108. package/dist/sdk/graph/governance.js +94 -32
  109. package/dist/sdk/graph/index.d.ts +2 -2
  110. package/dist/sdk/graph/index.js +4 -4
  111. package/dist/sdk/graph/mutation-advisory.js +15 -7
  112. package/dist/sdk/graph/remediation.js +12 -2
  113. package/dist/sdk/history-read.d.ts +8 -0
  114. package/dist/sdk/history-read.js +2 -2
  115. package/dist/sdk/history-repair.d.ts +13 -1
  116. package/dist/sdk/history-repair.js +62 -18
  117. package/dist/sdk/index.d.ts +1 -1
  118. package/dist/sdk/index.js +3 -3
  119. package/dist/sdk/linked-artifacts.js +16 -5
  120. package/dist/sdk/pagination.d.ts +15 -0
  121. package/dist/sdk/pagination.js +9 -5
  122. package/dist/sdk/query/context.d.ts +5 -1
  123. package/dist/sdk/query/context.js +14 -5
  124. package/dist/sdk/query/history.js +20 -3
  125. package/dist/sdk/read-output/continuation.d.ts +11 -0
  126. package/dist/sdk/read-output/continuation.js +132 -0
  127. package/dist/sdk/read-output-budget.d.ts +3 -1
  128. package/dist/sdk/read-output-budget.js +24 -13
  129. package/dist/sdk/read-output-contracts.d.ts +127 -7
  130. package/dist/sdk/read-output-contracts.js +381 -35
  131. package/dist/sdk/read-output-rows.d.ts +13 -0
  132. package/dist/sdk/read-output-rows.js +60 -2
  133. package/dist/sdk/runtime-input.js +4 -2
  134. package/dist/sdk/runtime-primitives.d.ts +1 -1
  135. package/dist/sdk/runtime-primitives.js +3 -3
  136. package/dist/sdk/runtime.js +5 -3
  137. package/docs/ASSURANCE.md +68 -2
  138. package/docs/COMMANDS.md +39 -4
  139. package/docs/READ_OUTPUT_CONTRACTS.md +85 -8
  140. package/docs/RELATIONSHIP_GRAPH.md +20 -5
  141. package/docs/RELEASING.md +42 -5
  142. package/docs/SDK.md +12 -5
  143. package/docs/SDK_CONTEXT_INTEGRITY.md +94 -1
  144. package/docs/TESTING.md +23 -1
  145. package/docs/performance/sdk-entrypoint-import-costs.md +20 -13
  146. package/marketplace.json +2 -2
  147. package/package.json +7 -7
  148. package/packages/pm-beads/extensions/beads/index.ts +1 -0
  149. package/packages/pm-beads/package.json +1 -1
  150. package/packages/pm-calendar/extensions/calendar/index.ts +1 -0
  151. package/packages/pm-calendar/package.json +1 -1
  152. package/packages/pm-command-kit/package.json +1 -1
  153. package/packages/pm-digital-twin/extensions/digital-twin/index.ts +7 -0
  154. package/packages/pm-digital-twin/package.json +1 -1
  155. package/packages/pm-governance-audit/extensions/governance-audit/index.ts +4 -0
  156. package/packages/pm-governance-audit/package.json +1 -1
  157. package/packages/pm-guide-shell/extensions/guide-shell/index.ts +5 -0
  158. package/packages/pm-guide-shell/package.json +1 -1
  159. package/packages/pm-kanban/package.json +1 -1
  160. package/packages/pm-lifecycle-hooks/package.json +1 -1
  161. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.ts +6 -0
  162. package/packages/pm-linked-test-adapters/package.json +1 -1
  163. package/packages/pm-search-advanced/extensions/search-advanced/index.ts +2 -0
  164. package/packages/pm-search-advanced/package.json +1 -1
  165. package/packages/pm-templates/extensions/templates/index.ts +4 -0
  166. package/packages/pm-templates/package.json +1 -1
  167. package/packages/pm-todos/extensions/todos/index.ts +2 -0
  168. package/packages/pm-todos/package.json +1 -1
  169. package/packages/pm-vcs/extensions/vcs/index.ts +7 -0
  170. package/packages/pm-vcs/package.json +1 -1
  171. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  172. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  173. package/scripts/bundle-cli.mjs +17 -4
  174. package/sdk/public-surface.json +1283 -157
  175. package/dist/cli-bundle/chunks/chunk-DEDU3DG7.js +0 -196
  176. package/dist/cli-bundle/chunks/chunk-DL5M5J3V.js +0 -13
  177. package/dist/cli-bundle/chunks/chunk-HIUZVCMN.js +0 -5
  178. package/dist/cli-bundle/chunks/chunk-IMGIN7R6.js +0 -2
  179. package/dist/cli-bundle/chunks/chunk-TF3TPKPR.js +0 -34
  180. package/dist/cli-bundle/chunks/register-operations-C44ET7R5.js +0 -2
  181. package/dist/cli-bundle/focused-chunks/chunk-27N23W6M.js +0 -31
  182. package/dist/cli-bundle/focused-chunks/chunk-3BNVU6LC.js +0 -8
  183. package/dist/cli-bundle/focused-chunks/chunk-6MLIRBLV.js +0 -5
  184. package/dist/cli-bundle/focused-chunks/chunk-6XYLENDV.js +0 -155
  185. package/dist/cli-bundle/focused-chunks/chunk-CP4K4WFS.js +0 -2
  186. package/dist/cli-bundle/focused-chunks/chunk-EBTNSFYE.js +0 -2
  187. package/dist/cli-bundle/focused-chunks/chunk-HC2OL2H2.js +0 -2
  188. package/dist/cli-bundle/focused-chunks/chunk-NFHFZH2Z.js +0 -2
  189. package/dist/cli-bundle/focused-chunks/chunk-OGC4XSBC.js +0 -17
  190. package/dist/cli-bundle/focused-chunks/chunk-PKPOZXLL.js +0 -2
  191. package/dist/cli-bundle/focused-chunks/chunk-QDZUABWL.js +0 -2
  192. package/dist/cli-bundle/focused-chunks/chunk-QQX5TDFT.js +0 -16
  193. package/dist/cli-bundle/focused-chunks/chunk-TEZIXMTH.js +0 -2
  194. package/dist/cli-bundle/focused-chunks/chunk-WEH6NSL6.js +0 -18
@@ -5,7 +5,23 @@
5
5
  * envelopes, including dot-delimited nested paths used by graph projections.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ae6fbd4a-6c4e-5639-93ac-f107a336e95b")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0c69ff43-7bbc-5128-9533-bbf15365126b")}catch(e){}}();
9
+ const BUDGET_METADATA_ROOT_KEYS = new Set([
10
+ "applied_bound",
11
+ "completeness",
12
+ "budget_retention_policy",
13
+ "continuation_contract",
14
+ "continuation_kind",
15
+ "continuation_path",
16
+ "filters",
17
+ "omission_receipt",
18
+ "output_budget_truncation",
19
+ "projection",
20
+ "read_output",
21
+ "read_session",
22
+ "row_contract",
23
+ "sorting",
24
+ ]);
9
25
  function isRecord(value) {
10
26
  return value !== null && typeof value === "object" && !Array.isArray(value);
11
27
  }
@@ -35,6 +51,16 @@ function replaceValueAtPath(result, rowPath, replacement) {
35
51
  target[segments.at(-1)] = replacement;
36
52
  return root;
37
53
  }
54
+ /** Replace one declared row collection with a suffix beginning at an offset. */
55
+ export function sliceReadOutputRowCollection(result, rowPath, offset) {
56
+ const collection = readOutputRowCollections(result).find((entry) => entry.path === rowPath);
57
+ if (!collection)
58
+ return result;
59
+ const replacement = Array.isArray(collection.value)
60
+ ? collection.value.slice(offset)
61
+ : Object.fromEntries(Object.entries(collection.value).slice(offset));
62
+ return replaceValueAtPath(result, rowPath, replacement);
63
+ }
38
64
  /** Resolve declared row paths, falling back to top-level array properties. */
39
65
  export function readOutputRowPaths(result) {
40
66
  const contract = result.row_contract;
@@ -54,6 +80,38 @@ export function readOutputRowCollections(result) {
54
80
  : [];
55
81
  });
56
82
  }
83
+ /**
84
+ * Discover every collection the token-budget degradation ladder may reduce.
85
+ *
86
+ * Ordinary field and amount projections stay bound to declared row paths (or
87
+ * top-level array fallbacks), because a nested tag list is not an independent
88
+ * result row. Budget degradation has a different obligation: it must exhaust
89
+ * nested content collections before omitting the whole useful result. This
90
+ * census therefore adds nested arrays while excluding receipt/envelope metadata
91
+ * whose mutation would make the disclosure itself incomplete.
92
+ */
93
+ export function readOutputBudgetCollections(result) {
94
+ const collections = readOutputRowCollections(result);
95
+ const declaredPaths = new Set(collections.map((collection) => collection.path));
96
+ const visit = (value, path) => {
97
+ if (Array.isArray(value)) {
98
+ if (!declaredPaths.has(path)) {
99
+ collections.push({ path, value });
100
+ }
101
+ value.forEach((entry, index) => visit(entry, `${path}.${index}`));
102
+ return;
103
+ }
104
+ if (!isRecord(value))
105
+ return;
106
+ for (const [key, entry] of Object.entries(value)) {
107
+ if (path.length === 0 && BUDGET_METADATA_ROOT_KEYS.has(key))
108
+ continue;
109
+ visit(entry, path.length === 0 ? key : `${path}.${key}`);
110
+ }
111
+ };
112
+ visit(result, "");
113
+ return collections;
114
+ }
57
115
  /** Count array entries and object-map values across declared row collections. */
58
116
  export function countReadOutputRows(result) {
59
117
  return readOutputRowCollections(result).reduce((total, collection) => total +
@@ -97,4 +155,4 @@ export function boundReadOutputRows(result, amount) {
97
155
  return { result: projected, truncated };
98
156
  }
99
157
  //# sourceMappingURL=read-output-rows.js.map
100
- //# debugId=ae6fbd4a-6c4e-5639-93ac-f107a336e95b
158
+ //# debugId=0c69ff43-7bbc-5128-9533-bbf15365126b
@@ -5,7 +5,7 @@
5
5
  * primitives are shared by native action dispatchers and MCP-specific adapters.
6
6
  */
7
7
 
8
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bcda2578-3b01-5e64-9d53-cd32c0f927b8")}catch(e){}}();
8
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0e153ece-4fc0-5134-97f0-c2315aff0031")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { asRecordClone } from "../core/shared/primitives.js";
@@ -83,6 +83,7 @@ export function actionGlobalOptions(args) {
83
83
  outputLimit: readRuntimeScalarString(args, "outputLimit"),
84
84
  outputBudget: readRuntimeScalarString(args, "outputBudget"),
85
85
  outputSession: readRuntimeString(args, "outputSession"),
86
+ outputCursor: readRuntimeString(args, "outputCursor"),
86
87
  outputFormat: outputFormat === "json" || outputFormat === "toon"
87
88
  ? outputFormat
88
89
  : undefined,
@@ -167,6 +168,7 @@ const UNIVERSAL_READ_OUTPUT_OPTION_KEYS = [
167
168
  "outputBudget",
168
169
  "outputFormat",
169
170
  "outputSession",
171
+ "outputCursor",
170
172
  ];
171
173
  /** Reconcile MCP array/scalar option spellings with CLI flag expectations. */
172
174
  export function normalizeMcpOptionsArrays(options, action) {
@@ -501,4 +503,4 @@ export function updateManyOptionsFromFlat(options) {
501
503
  };
502
504
  }
503
505
  //# sourceMappingURL=runtime-input.js.map
504
- //# debugId=bcda2578-3b01-5e64-9d53-cd32c0f927b8
506
+ //# debugId=0e153ece-4fc0-5134-97f0-c2315aff0031
@@ -18,7 +18,7 @@ export { type HistoryDiffValueEntry, computeHistoryDiff, patchPathToChangedField
18
18
  export { enforceHistoryStreamPolicyForItem, enforceHistoryStreamPolicyForItems, } from "../core/history/history-stream-policy.js";
19
19
  export { appendHistoryEntry, CURRENT_HISTORY_ITEM_HASH_VERSION, createHistoryEntry, hashDocument, hashDocumentForVersion, hashEmptyDocument, SUPPORTED_HISTORY_ITEM_HASH_VERSIONS, type HistoryItemHashVersion, } from "../core/history/history.js";
20
20
  export { readHistoryEntries } from "../core/history/read.js";
21
- export { appendWorkspaceAuditEvent, appendWorkspaceHistoryChange, getWorkspaceHistoryPath, mutateWorkspaceJsonWithHistory, WORKSPACE_HISTORY_ID, writeWorkspaceJsonWithHistory, type WorkspaceAuditEventOptions, type WorkspaceHistoryChange, type WorkspaceJsonMutation, type WorkspaceJsonMutationOptions, type WorkspaceJsonWriteOptions, } from "../core/history/workspace-history.js";
21
+ export { appendWorkspaceAuditEvent, appendWorkspaceHistoryChange, getWorkspaceHistoryPath, inspectWorkspaceHistoryState, mutateWorkspaceJsonWithHistory, reconcileWorkspaceJsonHistory, restoreWorkspaceJsonFromHistory, WORKSPACE_HISTORY_ID, writeWorkspaceJsonWithHistory, type WorkspaceAuditEventOptions, type WorkspaceHistoryChange, type WorkspaceHistoryStateAgreement, type WorkspaceJsonMutation, type WorkspaceJsonMutationOptions, type WorkspaceJsonReconciliationOptions, type WorkspaceJsonRestoreOptions, type WorkspaceJsonRestoreResult, type WorkspaceJsonWriteOptions, } from "../core/history/workspace-history.js";
22
22
  export { normalizeReplayPatchOps, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, verifyHistoryChain, verifyHistoryChainWithVersion, } from "../core/history/replay.js";
23
23
  export { resolveBodyFileContent } from "../core/io/body-file.js";
24
24
  export { generateItemId, normalizeItemId, normalizeRawItemId, } from "../core/item/id.js";
@@ -7,7 +7,7 @@
7
7
  * prefer the typed operations exported by the main SDK barrel.
8
8
  */
9
9
 
10
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="78779372-1987-54d0-9ae4-775b52641a26")}catch(e){}}();
10
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a678b9f8-ba36-5127-877f-96bb4acc38c5")}catch(e){}}();
11
11
  export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
12
12
  export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
13
13
  export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
@@ -20,7 +20,7 @@ export { computeHistoryDiff, patchPathToChangedField, } from "../core/history/hi
20
20
  export { enforceHistoryStreamPolicyForItem, enforceHistoryStreamPolicyForItems, } from "../core/history/history-stream-policy.js";
21
21
  export { appendHistoryEntry, CURRENT_HISTORY_ITEM_HASH_VERSION, createHistoryEntry, hashDocument, hashDocumentForVersion, hashEmptyDocument, SUPPORTED_HISTORY_ITEM_HASH_VERSIONS, } from "../core/history/history.js";
22
22
  export { readHistoryEntries } from "../core/history/read.js";
23
- export { appendWorkspaceAuditEvent, appendWorkspaceHistoryChange, getWorkspaceHistoryPath, mutateWorkspaceJsonWithHistory, WORKSPACE_HISTORY_ID, writeWorkspaceJsonWithHistory, } from "../core/history/workspace-history.js";
23
+ export { appendWorkspaceAuditEvent, appendWorkspaceHistoryChange, getWorkspaceHistoryPath, inspectWorkspaceHistoryState, mutateWorkspaceJsonWithHistory, reconcileWorkspaceJsonHistory, restoreWorkspaceJsonFromHistory, WORKSPACE_HISTORY_ID, writeWorkspaceJsonWithHistory, } from "../core/history/workspace-history.js";
24
24
  export { normalizeReplayPatchOps, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, verifyHistoryChain, verifyHistoryChainWithVersion, } from "../core/history/replay.js";
25
25
  export { resolveBodyFileContent } from "../core/io/body-file.js";
26
26
  export { generateItemId, normalizeItemId, normalizeRawItemId, } from "../core/item/id.js";
@@ -81,4 +81,4 @@ export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
81
81
  export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
82
82
  export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
83
83
  //# sourceMappingURL=runtime-primitives.js.map
84
- //# debugId=78779372-1987-54d0-9ae4-775b52641a26
84
+ //# debugId=a678b9f8-ba36-5127-877f-96bb4acc38c5
@@ -4,7 +4,7 @@
4
4
  * Defines public SDK APIs and package-author helpers for Runtime.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7c27b516-1714-5f2b-8304-98e8372280be")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a387cd7a-cb16-5082-80e1-9632ebd02480")}catch(e){}}();
8
8
  export { PM_GITIGNORE_END, PM_GITIGNORE_START, ensurePmGitignore, getPmGitignoreBlock, } from "./workspace.js";
9
9
  export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -31,7 +31,7 @@ import { createExtensionCommandSdk } from "./extension-command-context.js";
31
31
  import { createUnknownSubcommandError } from "./agent/subcommand-recovery.js";
32
32
  import { applyContextIntentProjection, attachReadOutputContracts, } from "./context-intent-contracts.js";
33
33
  import { runWithDiscoveredContextIntentContracts, } from "./context-intent-runtime.js";
34
- import { validateReadOutputOptions, } from "./read-output-contracts.js";
34
+ import { normalizeReadOutputIncludeModeOptions, validateReadOutputOptions, } from "./read-output-contracts.js";
35
35
  export { clearWorkspaceContractsCache } from "./workspace-contracts-cache.js";
36
36
  import { normalizeActivityProjectionOptions, runActivity, } from "./query/activity.js";
37
37
  import { runAssuranceDispatch } from "./governance/assurance-action.js";
@@ -1870,6 +1870,7 @@ export function analyzeSdkActionCoverage(actions = PM_TOOL_ACTIONS) {
1870
1870
  async function dispatchAction(action, args, global, activeExtensions) {
1871
1871
  const options = optionsWithAuthor(args, action);
1872
1872
  validateReadOutputOptions(action, options);
1873
+ normalizeReadOutputIncludeModeOptions(action, options);
1873
1874
  const ctx = {
1874
1875
  action,
1875
1876
  args,
@@ -1883,6 +1884,7 @@ async function dispatchAction(action, args, global, activeExtensions) {
1883
1884
  const result = handler
1884
1885
  ? await handler(ctx)
1885
1886
  : await dispatchActiveExtensionAction(action, args, options, global, activeExtensions);
1887
+ options.resolvedOutputFormat = "json";
1886
1888
  return attachReadOutputContracts(action, options, result);
1887
1889
  }
1888
1890
  const actionRunnerTestHooks = {
@@ -1930,4 +1932,4 @@ async function loadWorkspaceExtensionRegistrations(pmRoot, settings, cwd) {
1930
1932
  }
1931
1933
  }
1932
1934
  //# sourceMappingURL=runtime.js.map
1933
- //# debugId=7c27b516-1714-5f2b-8304-98e8372280be
1935
+ //# debugId=a387cd7a-cb16-5082-80e1-9632ebd02480
package/docs/ASSURANCE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Project Assurance Primitives
2
2
 
3
- Tracker: [pm-2lex4r](../.agents/pm/features/pm-2lex4r.toon), [pm-lyfu7b](../.agents/pm/features/pm-lyfu7b.toon), [pm-wn6wot](../.agents/pm/features/pm-wn6wot.toon), [pm-91xeam](../.agents/pm/features/pm-91xeam.toon), [pm-uhv1m5](../.agents/pm/features/pm-uhv1m5.toon), [pm-m7bb7r](../.agents/pm/features/pm-m7bb7r.toon), [pm-py7qv2](../.agents/pm/issues/pm-py7qv2.toon), [pm-33mjrw](../.agents/pm/issues/pm-33mjrw.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon)
3
+ Tracker: [pm-2lex4r](../.agents/pm/features/pm-2lex4r.toon), [pm-lyfu7b](../.agents/pm/features/pm-lyfu7b.toon), [pm-wn6wot](../.agents/pm/features/pm-wn6wot.toon), [pm-91xeam](../.agents/pm/features/pm-91xeam.toon), [pm-uhv1m5](../.agents/pm/features/pm-uhv1m5.toon), [pm-m7bb7r](../.agents/pm/features/pm-m7bb7r.toon), [pm-py7qv2](../.agents/pm/issues/pm-py7qv2.toon), [pm-33mjrw](../.agents/pm/issues/pm-33mjrw.toon), [pm-q6n8sj](../.agents/pm/issues/pm-q6n8sj.toon), [pm-h06944](../.agents/pm/issues/pm-h06944.toon), [pm-88mo8m](../.agents/pm/issues/pm-88mo8m.toon), [pm-atnfh4](../.agents/pm/issues/pm-atnfh4.toon), [pm-xmmafu](../.agents/pm/issues/pm-xmmafu.toon), [pm-4ok4ex](../.agents/pm/tasks/pm-4ok4ex.toon), [pm-dwj33e](../.agents/pm/decisions/pm-dwj33e.toon)
4
4
 
5
5
  ## Agent Quick Context
6
6
 
@@ -12,6 +12,15 @@ Assurance turns project policy into three reusable SDK-owned declarations:
12
12
 
13
13
  Declarations live in `.agents/pm/assurance.json`. Every registry mutation and non-dry gate verdict is appended through the verified workspace history stream; never edit either file directly.
14
14
 
15
+ `pm history _workspace --verify`, `pm validate`, and `pm health` verify both
16
+ the hash chain and replay-to-disk agreement for every governed singleton. A
17
+ valid chain paired with a different, missing, or unreadable singleton is still
18
+ drift. SDK hosts can inspect that state with `inspectWorkspaceHistoryState`,
19
+ adopt a reviewed out-of-band value only through
20
+ `reconcileWorkspaceJsonHistory` with a terminal authorizing Decision, or
21
+ replace it from a verified version with `restoreWorkspaceJsonFromHistory`.
22
+ Both recovery paths append forward; neither rewrites the existing stream.
23
+
15
24
  ## Why Assurance Exists
16
25
 
17
26
  Project management is context management. A useful quality gate therefore needs more than a shell exit code: it must preserve what was measured, which population was judged, why a bound exists, who owns it, what changed the result, how expensive the evaluation was, and which immutable tree received the verdict.
@@ -34,6 +43,14 @@ Measurements support these built-in sources:
34
43
  | `derived` | Combine numeric measurements with deterministic arithmetic and cycle detection. |
35
44
  | `provider` | Delegate a measurement to an explicitly supplied host/package resolver. |
36
45
 
46
+ `ASSURANCE_MEASUREMENT_SOURCE_KINDS` and `ASSURANCE_GATE_TRIGGERS` are the
47
+ public SDK constants for these closed vocabularies. Runtime validation rejects
48
+ missing arrays and unknown discriminants with `AssuranceMutationRefusalError`;
49
+ it never persists an unrecognized source or leaks an incidental JavaScript
50
+ property-access error. Hosts that generate forms or package schemas can obtain
51
+ the same values from `pm contracts --command assurance --json` under
52
+ `assurance_contracts`.
53
+
37
54
  Each measurement may declare `max_cost`. Evaluation fails closed when the total abstract compute units exceed that ceiling. Every result reports units, scanned items, scanned history rows, provider calls, duration, population size, and contributors.
38
55
 
39
56
  One workspace context memoizes identical graph operations and the shared
@@ -254,15 +271,64 @@ await pm.assurance({
254
271
  });
255
272
  ```
256
273
 
257
- For direct host composition, use `evaluateMeasurement`, `evaluateAssuranceGate`, `createAssuranceWorkspaceContext`, the preset/derivation helpers, and the audited declaration/verdict helpers exported from `@unbrained/pm-cli/sdk`. Active extension registrations are discovered automatically. Embedding hosts may additionally pass stable resolver ids and matching `provider_capabilities` to `createAssuranceWorkspaceContext`; an absent resolver or capability fails loudly. The core evaluator bounds concurrent assertions and expression operands, and workspace history loading uses bounded concurrency; item-only callers can explicitly skip history and Git identity resolution.
274
+ For direct host composition, use `evaluateMeasurement`, `evaluateAssuranceGate`, `createAssuranceWorkspaceContext`, the preset/derivation helpers, and the audited declaration/verdict helpers exported from `@unbrained/pm-cli/sdk` and its focused `@unbrained/pm-cli/sdk/governance` entrypoint. Active extension registrations are discovered automatically. Embedding hosts may additionally pass stable resolver ids and matching `provider_capabilities` to `createAssuranceWorkspaceContext`; an absent resolver or capability fails loudly. The core evaluator bounds concurrent assertions and expression operands, and workspace history loading uses bounded concurrency; item-only callers can explicitly skip history and Git identity resolution.
275
+
276
+ Hosts that want the normal action transport and its audited registry lookup can
277
+ pass the same adapters as the third `runAssuranceAction` argument. The request
278
+ and project path remain transport data; resolver capabilities remain explicit
279
+ runtime authority:
280
+
281
+ ```ts
282
+ await runAssuranceAction(
283
+ {
284
+ action: "run",
285
+ id: "repository-static-quality",
286
+ trigger: "ci",
287
+ dry_run: true,
288
+ },
289
+ { path: ".agents/pm" },
290
+ {
291
+ workspace: {
292
+ include_history: false,
293
+ providers: {
294
+ "repository-quality": resolveRepositoryQualityMeasurement,
295
+ },
296
+ provider_capabilities: {
297
+ "repository-quality": { cost_class: "high", network: false },
298
+ },
299
+ },
300
+ },
301
+ );
302
+ ```
303
+
304
+ This is the migration boundary for repository automation: scripts may remain
305
+ focused process adapters, while assertion composition, provider policy,
306
+ negative controls, lifecycle triggers, and verdicts move into ordinary
307
+ assurance declarations. `scripts/release/gate-registry.json` records every
308
+ gate script as migrated, provider-backed, or retained and fails unless the
309
+ migrated/provider-backed population is the majority.
310
+
311
+ `AssuranceMutationRefusalError` and `AssuranceEvaluationRefusalError` are
312
+ exported from both `@unbrained/pm-cli/sdk` and
313
+ `@unbrained/pm-cli/sdk/governance`, so hosts can classify expected declaration
314
+ or evaluation refusals without parsing messages. Source-resolution refusals
315
+ also carry the gate, assertion, measurement, source kind, field, and optional
316
+ health/validate check, so a zero value remains distinct from an absent or
317
+ mistyped field.
258
318
 
259
319
  Generic SDK and MCP dispatch use `action: "assurance"` with `subcommand` set to `list`, `show`, `put`, `remove`, `run`, `verdicts`, `presets`, `apply`, `derive`, or `promote`. Discover the current machine contract instead of copying parameter lists:
260
320
 
261
321
  ```bash
262
322
  pm contracts --action assurance --schema-only --json
263
323
  pm contracts --command assurance --flags-only --json
324
+ pm contracts --command assurance --json
264
325
  ```
265
326
 
327
+ Command-scoped contract output omits unrelated extension, governance,
328
+ relationship, and Commander-alias catalogs unless `--full` is requested. This
329
+ keeps the selected action schema and its assurance vocabularies complete under
330
+ the default output budget instead of truncating the very enum a caller needs.
331
+
266
332
  ## Verdict Contract
267
333
 
268
334
  A gate emits one object containing:
package/docs/COMMANDS.md CHANGED
@@ -4,6 +4,8 @@ This is a task-oriented command guide. For exact flags, use runtime help because
4
4
 
5
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).
6
6
 
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
+
7
9
  ```bash
8
10
  pm <command> --help
9
11
  pm <command> --help --json
@@ -21,7 +23,29 @@ pm contracts --command <command> --flags-only --json
21
23
 
22
24
  Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon),
23
25
  [pm-7nqo6b](../.agents/pm/issues/pm-7nqo6b.toon), and
24
- [pm-j1r8gl](../.agents/pm/issues/pm-j1r8gl.toon).
26
+ [pm-j1r8gl](../.agents/pm/issues/pm-j1r8gl.toon). Universal command intent and
27
+ default output-budget enforcement are tracked by
28
+ [pm-5t33or](../.agents/pm/features/pm-5t33or.toon),
29
+ [pm-s2h0mq](../.agents/pm/issues/pm-s2h0mq.toon),
30
+ [pm-pmrae8](../.agents/pm/issues/pm-pmrae8.toon), and
31
+ [pm-7i97c3](../.agents/pm/issues/pm-7i97c3.toon).
32
+
33
+ ### Universal read-output ceiling
34
+
35
+ Every SDK-backed read has a format-aware default token ceiling discovered from
36
+ `pm contracts`. Results already within that ceiling are returned unchanged, so
37
+ the default adds no receipt overhead to ordinary reads. An oversized result is
38
+ degraded deterministically through string compaction, row compaction, and a
39
+ truthful omission envelope; automatic degradation adds `read_output` with
40
+ `budget_source: default`, `budget_tokens`, the final estimate, and the applied
41
+ compaction flags.
42
+
43
+ Use `--output-budget <tokens>` to request a tighter per-call ceiling. Use
44
+ `--output-budget unbounded` only when the caller deliberately accepts the full
45
+ cost. This cost opt-out is distinct from command-local row controls such as
46
+ `activity --unbounded`, which disable a row limit but do not disable the shared
47
+ token ceiling. `--output-format json` and global `--json` select the declared
48
+ JSON ceiling; TOON uses the smaller default agent ceiling.
25
49
 
26
50
  ## Command Families
27
51
 
@@ -943,6 +967,8 @@ pm history-repair <id> --dry-run
943
967
  pm history-repair <id> --message "re-anchor legacy drift"
944
968
  pm history-repair --all --dry-run
945
969
  pm history-repair --all --message "bulk re-anchor drifted streams"
970
+ pm history-repair --all --normalize-provenance --dry-run
971
+ pm history-repair --all --normalize-provenance --message "normalize invalid legacy provenance"
946
972
  pm activity # item digest for the last 24 hours
947
973
  pm activity --raw --id <id> --limit 50
948
974
  pm activity --full --id <id> --limit 50
@@ -998,8 +1024,10 @@ For governance dashboards, `--metadata-coverage` adds a `metadata_coverage` bloc
998
1024
  `history-redact` rewrites matching history payloads deterministically, recomputes hash chains, and appends an auditable `history_redact` marker entry when changes are applied. Its result reports only `literal_count`, `regex_count`, `total_count`, and whether the default replacement was selected; literal values, regex source text, and replacement text are never echoed in CLI, SDK, MCP, recovery, profile, or telemetry output. Treat regex text as sensitive input because it can contain the exact material being removed.
999
1025
  `history-compact` rewrites long streams into a synthetic checkpoint baseline plus a retained tail (`--before` accepts a 1-based version or ISO timestamp), re-anchors hashes, verifies integrity, and appends an auditable `history_compact` marker when applied.
1000
1026
  `history-compact` bulk mode (mutually exclusive with a positional `<id>`) compacts many streams in one audited pass. Select with `--ids <a,b,c>` (an explicit list — used on its own, not combined with the scan selectors below), or a scan: `--all-over <N>` (every stream with more than N entries) and/or a lifecycle filter `--closed` (terminal items only) or `--all-streams` (every stream). `--closed` and `--all-streams` are mutually exclusive. `--min-entries <N>` (default 3) skips already-compact streams; when `history.compact_policy` is enabled and `--all-over` is omitted, the policy's `max_entries` becomes the default threshold. `--before` is single-id only and is rejected in bulk mode. Each selected stream runs the same single-item compaction; one failing stream never aborts the rest — the result reports `totals` (`streams_considered`/`selected`/`items_compacted`/`items_skipped`/`items_errored`) plus one row per stream (`compacted`/`skipped` with a `skip_reason`/`errored`), and the command exits non-zero only if any stream errored.
1001
- `history-repair` re-anchors a drifted history chain when `pm health`/`pm validate --check-history-drift` report stale hashes: it replays the stream, recomputes every before/after hash, repairs legacy patch ops that no longer strictly apply, reconciles the latest hash with the on-disk item, and appends an auditable `history_repair` marker. It never modifies item content and is a safe no-op on a clean stream.
1002
- `history-repair --all` (mutually exclusive with `<id>`) runs the same drift scan `pm health` uses and applies the audited single-stream repair (ownership check, lock, post-repair no-drift verification, `--message` audit marker, per-stream `--force`) to every drifted stream in one pass. One failing stream never aborts the rest: the result lists one compact row per drifted stream (`repaired` / `skipped_clean` / `failed`) plus `totals`, and the command exits non-zero only if any stream failed.
1027
+ `history-repair` re-anchors a drifted history chain when `pm health`/`pm validate --check-history-drift` report stale hashes: it replays the stream, recomputes every before/after hash using the stream's detected hash epoch, repairs legacy patch ops that no longer strictly apply, reconciles the latest hash with the on-disk item, and appends an auditable `history_repair` marker. It never modifies item content and is a safe no-op on a clean stream. The result reports the before/after hash versions and whether the epoch was preserved or selected for an ambiguous broken stream, preventing old/new runtimes from alternately rewriting an otherwise consistent legacy chain.
1028
+ `history-repair --all` (mutually exclusive with `<id>`) runs the same drift scan `pm health` uses and applies the audited single-stream repair (ownership check, lock, post-repair no-drift verification, `--message` audit marker, per-stream `--force`) to every drifted stream in one pass. One failing stream never aborts the rest: the result lists one compact row per targeted stream (`repaired` / `skipped_clean` / `failed`) plus `totals`, and the command exits non-zero only if any stream failed. Add `--normalize-provenance` to include streams containing invalid boolean or single-digit provenance observations. The normalizer removes only those invalid observations and writes aggregate harness/dimension/kind counts in the audit receipt; it never echoes or retains the removed value.
1029
+
1030
+ Every `pm health` projection exposes `findings` and `failed_because`. A finding binds one warning token to its owning check, stable code, `advisory|gate_failing` severity, and either an executable remediation or `no_safe_automatic_remediation`. Extension health also publishes `host_version_census`, which enumerates the host and every pm-cli copy resolved by loaded extensions across npm/pnpm layouts. A version mismatch makes the extension check non-clean; matching workspace-linked or deduplicated copies remain healthy.
1003
1031
 
1004
1032
  `pm health --verbose-author-events --json` includes the complete actionable unknown-author coordinate list and an explicit `samples_truncated` marker. After evidence review, `pm history-author-acknowledge --all-actionable --attributed-author <principal> --reviewer <reviewer> --reason <evidence>` records one append-only disposition for the current complete set. `--all-actionable` and repeatable `--event <item-id:line>` are mutually exclusive; reviewer, attributed author, and reason remain mandatory.
1005
1033
 
@@ -1161,7 +1189,14 @@ Extension policy tokens are explicitly scoped by
1161
1189
  Project-governance setters use the separate `governance_contracts` value
1162
1190
  domains; in particular, workflow enforcement is `off|warn|strict`, not the
1163
1191
  extension policy token `enforce`.
1164
- Use `pm contracts --summary --json` first when bootstrapping in a tight context window; it emits one command and terse intent per row before the agent requests heavier command-specific flags or schemas.
1192
+ 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 children—with a meaningful intent plus
1195
+ `default_max_estimated_tokens` and the format-specific TOON/JSON ceilings.
1196
+ Package commands contribute their intent through command registration (falling
1197
+ back to the registered description), so agents never need a generic
1198
+ `Inspect flags.` placeholder. Request heavier command-specific flags or schemas
1199
+ only after selecting the exact path.
1165
1200
 
1166
1201
  ## Completion
1167
1202
 
@@ -1,17 +1,17 @@
1
1
  # Universal Read Output Contracts
2
2
 
3
- Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), and [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon).
3
+ Tracker references: [pm-hb7ug8](../.agents/pm/features/pm-hb7ug8.toon), [pm-cxr0jb](../.agents/pm/features/pm-cxr0jb.toon), [pm-hid9g1](../.agents/pm/features/pm-hid9g1.toon), [pm-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-sb0tns](../.agents/pm/issues/pm-sb0tns.toon), [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon), [pm-eugaqy](../.agents/pm/issues/pm-eugaqy.toon), [pm-jt8aa2](../.agents/pm/issues/pm-jt8aa2.toon), [pm-kyjdne](../.agents/pm/issues/pm-kyjdne.toon), [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), and [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon).
4
4
 
5
5
  ## Agent Quick Context
6
6
 
7
7
  Every built-in read surface uses four output dimensions: what to include, how much to return, how much the result may cost, and how to encode it. The same canonical controls work through the CLI, SDK, MCP, generated schemas, runtime contracts, and shell completions.
8
8
 
9
- | Dimension | CLI | SDK and MCP | Meaning |
10
- | --------- | ------------------------------- | --------------- | ---------------------------------------------------------- |
11
- | Include | `--output-include <csv>` | `outputInclude` | Retain named fields or top-level sections. |
12
- | Amount | `--output-limit <n\|unbounded>` | `outputLimit` | Bound shared row collections. |
13
- | Cost | `--output-budget <tokens>` | `outputBudget` | Fail closed when even the compact result cannot fit. |
14
- | Encoding | `--output-format <toon\|json>` | `outputFormat` | Select the CLI renderer and record the requested encoding. |
9
+ | Dimension | CLI | SDK and MCP | Meaning |
10
+ | --------- | -------------------------------- | --------------- | ---------------------------------------------------------------------- |
11
+ | Include | `--output-include <csv>` | `outputInclude` | Retain named fields or sections, or select a declared projection mode. |
12
+ | Amount | `--output-limit <n\|unbounded>` | `outputLimit` | Bound shared row collections. |
13
+ | Cost | `--output-budget <n\|unbounded>` | `outputBudget` | Fail closed when even the compact result cannot fit. |
14
+ | Encoding | `--output-format <toon\|json>` | `outputFormat` | Select the CLI renderer and record the requested encoding. |
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
 
@@ -24,6 +24,39 @@ repeated metadata from results by default. Request
24
24
  `--output-row-contract` / `outputRowContract: true` when a consumer needs the
25
25
  row paths, jq selector, and active TOON encoding contract.
26
26
 
27
+ ### Include Modes
28
+
29
+ `--output-include` accepts two kinds of token. A **field selector** names a row
30
+ field or section and narrows the computed result. A **projection mode** names a
31
+ whole declared projection and is the canonical spelling of a command-local mode
32
+ flag: `brief`, `compact`, `full`, `summary`, and `counts`, depending on the
33
+ surface. Controls that change execution rather than projection remain separate:
34
+ for example, `deps --collapse <none|repeated>` retains dependency-grouping
35
+ semantics, and `health --check-only` retains refresh-suppression semantics.
36
+
37
+ Mode tokens are resolved before the command computes its rows, because a mode
38
+ selects which fields exist rather than which of the computed fields survive.
39
+ `pm list --output-include brief` is therefore exactly `pm list --brief`, and the
40
+ two are byte-identical apart from the `read_output` receipt that records which
41
+ spelling was used. Modes and field selectors compose: the mode selects the
42
+ projection, the remaining selectors narrow it.
43
+
44
+ ```bash
45
+ pm list --status open --output-include brief # same result as --brief
46
+ pm contracts --output-include full # same result as --full
47
+ pm list --status open --output-include brief,id # brief projection, id only
48
+ ```
49
+
50
+ Read `readOutputIncludeModeOptions(command)` from the SDK for the exact
51
+ replacement modes a surface declares. Every compatibility alias also declares
52
+ `semantics: "replacement" | "behavior_preserving"`; generators therefore do
53
+ not have to infer obligation strength from prose. The executable migration test
54
+ derives all 22 projection-mode replacements from this table, invokes both
55
+ spellings in a temporary tracker, and compares their useful result after
56
+ removing spelling receipts and volatile run metadata. A selector that matches
57
+ neither a declared mode nor any field on any returned row is refused with the
58
+ legal domain, rather than returning rows with every field removed.
59
+
27
60
  ## Cross-Call Context Sessions
28
61
 
29
62
  `--output-session <json>` / `outputSession` composes the four per-call
@@ -84,6 +117,12 @@ tracker content.
84
117
 
85
118
  Resolution is deterministic: canonical controls win over command-local compatibility options, which win over intent defaults, which win over command defaults. Existing options such as `--fields`, `--limit`, `--token-budget`, `--format`, `--brief`, and `--full` remain accepted. Contract output marks them as hidden compatibility aliases and supplies a migration hint; traversal, cursor, side-effect, and streaming controls instead receive an explicit behavior-preservation hint because a static output control cannot replace their semantics. Callers that omit the four shaping dimensions retain the established data projection; the one intentional envelope correction is that repeated `row_contract` metadata is now opt-in.
86
119
 
120
+ Completeness spellings preserve their established promise. `pm list-all` and
121
+ list-family `--no-truncate` imply an unbounded cost dimension when the caller
122
+ does not supply `--output-budget`; they cannot silently return a budget-trimmed
123
+ subset while claiming to return every matched row. An explicit canonical
124
+ budget still has precedence and may request a bounded result deliberately.
125
+
87
126
  ```bash
88
127
  pm list-open --output-include id,title,status --output-limit 10
89
128
  pm context --for orient --output-budget 900 --output-format toon
@@ -92,7 +131,43 @@ pm stats --output-row-contract
92
131
  pm contracts --full --json
93
132
  ```
94
133
 
95
- Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed compatibility aliases, deterministic estimated token count, string/row compaction signals, and budget outcome. If no useful content can fit, `PmReadOutputBudgetExceeded` provides a discriminated omission result; use `isReadOutputBudgetExceeded` before accessing result-specific fields. Universal controls are rejected on mutation commands and on the mutation mode of hybrid commands such as `comments`, `notes`, `files`, and `docs`.
134
+ Every projected result carries a `read_output` receipt with the requested dimensions, precedence, observed compatibility aliases, deterministic estimated token count, string/row compaction signals, and budget outcome. Budget degradation discovers nested arrays as well as declared result rows, so validation diagnostics and other governance payloads compact their inner findings before the useful result is omitted. `compacted_row_paths` names every reduced collection without redefining those nested arrays as ordinary pagination rows.
135
+
136
+ When rows are dropped to satisfy a ceiling, the result also carries `output_budget_truncation`, naming the binding budget and its source, any explicitly requested dimension the budget overrode, every compacted collection path, and executable CLI/SDK/MCP recovery options — a default ceiling can override an explicit `--output-limit unbounded`, and that override is reported rather than silent. If a producer supplied an opaque item-page cursor, compaction rebases it to the last row actually returned and reports `continuation_cursor_rebased: true`; following the cursor therefore cannot skip rows removed from the middle of a producer page. If no useful content can fit, `PmReadOutputBudgetExceeded` provides a discriminated omission result, a compact `{ outputBudget: "unbounded" }` recovery object, and `omitted_result_estimated_tokens`, the last useful-result estimate before omission; use `isReadOutputBudgetExceeded` before accessing result-specific fields. Universal controls are rejected on mutation commands and on the mutation mode of hybrid commands such as `comments`, `notes`, `files`, and `docs`.
137
+
138
+ Cursor recovery carries the opaque value once in `recovery.cursor` and declares
139
+ the accepting `cli`, `sdk`, and `mcp` binding beside it. This avoids
140
+ serializing the same cursor once per transport while retaining an executable,
141
+ machine-readable binding for each surface.
142
+
143
+ Budget-compacted declared row paths are independently resumable. The
144
+ disclosure's `continuations` entries name the row path, retained/remaining/total
145
+ counts, and an opaque cursor. `continuation_kind` distinguishes a rebased
146
+ producer cursor, a universal output cursor, and a terminal page;
147
+ `next_cursor` mirrors the first universal entry for ordinary one-path
148
+ consumers. Replay the same query and budget
149
+ with `--output-cursor <cursor>` / `outputCursor`. The cursor validates the
150
+ command, declared row path, total, and stable row identities before slicing, so
151
+ a mismatched or stale replay fails closed instead of skipping evidence. A
152
+ bounded recovery therefore does not require replacing a 600-token request with
153
+ an unbounded multi-megabyte response;
154
+ `recovery_budget_multiplier: 1` declares that each next page retains the same
155
+ useful-result ceiling.
156
+
157
+ Assurance declares `budget_retention_policy: verdict_priority`: failing block,
158
+ warn, and observe rows precede retired and passing rows while preserving order
159
+ within each class. `assertions_total` remains the pre-projection denominator,
160
+ and the `assertions` row path uses the same continuation primitive. A blocking
161
+ verdict consequently keeps its causal evidence on the first bounded page even
162
+ when the failing assertion was declared last.
163
+
164
+ Diagnostic gates retain bounded, actionable predicates. Every metadata field
165
+ required by the active validation profile emits a numeric count, including
166
+ zero, so assurance expressions can distinguish a clean check from a missing
167
+ key. Health retains at most 100 warning rows and reports `warning_count`,
168
+ `warning_limit`, and `warnings_truncated`; `--strict-exit` defaults to summary
169
+ projection unless `--full` is explicit, keeping the failing check identities
170
+ and warning codes inside the ordinary budget.
96
171
 
97
172
  ## SDK and Package Usage
98
173
 
@@ -115,6 +190,7 @@ const result = await pm.list({
115
190
  spent_tokens: 0,
116
191
  seen_item_ids: [],
117
192
  },
193
+ // Supply outputCursor from output_budget_truncation to fetch the next row page.
118
194
  });
119
195
  ```
120
196
 
@@ -127,5 +203,6 @@ The full runtime contract reports every surface and all four dimensions. Strict
127
203
  ```bash
128
204
  pnpm contracts:check
129
205
  node scripts/run-tests.mjs test -- tests/unit/sdk/read-output-contracts.spec.ts
206
+ node scripts/run-tests.mjs test -- tests/unit/sdk/read-output-migration-hints.spec.ts
130
207
  node scripts/run-tests.mjs test -- tests/unit/commands/completion-command.spec.ts
131
208
  ```
@@ -1,6 +1,6 @@
1
1
  # Relationship graph semantics
2
2
 
3
- Tracked by [pm-4jqm](../.agents/pm/decisions/pm-4jqm.toon), [pm-ju83](../.agents/pm/features/pm-ju83.toon), [pm-8xr8](../.agents/pm/stories/pm-8xr8.toon), [pm-m2il](../.agents/pm/chores/pm-m2il.toon), and [pm-jiusod](../.agents/pm/issues/pm-jiusod.toon).
3
+ Tracked by [pm-4jqm](../.agents/pm/decisions/pm-4jqm.toon), [pm-dwj33e](../.agents/pm/decisions/pm-dwj33e.toon), [pm-ju83](../.agents/pm/features/pm-ju83.toon), [pm-8xr8](../.agents/pm/stories/pm-8xr8.toon), [pm-m2il](../.agents/pm/chores/pm-m2il.toon), [pm-jiusod](../.agents/pm/issues/pm-jiusod.toon), [pm-mfvsng](../.agents/pm/issues/pm-mfvsng.toon), [pm-9gzr4r](../.agents/pm/issues/pm-9gzr4r.toon), and [pm-xvt7ps](../.agents/pm/issues/pm-xvt7ps.toon).
4
4
 
5
5
  ## Decision
6
6
 
@@ -251,14 +251,21 @@ terminal dangling-reference partitions. Domain adapters pass their
251
251
  company, or package-defined edges survive assembly with their registered
252
252
  semantics. `auditWorkspaceRelationshipGraph`
253
253
  consumes that assembly and emits counts-first findings for active/terminal
254
- missing references, retired sentinels, ordering cycles, stale lifecycle blocks,
255
- and sparse or isolated active nodes. Findings include stable codes, severity,
254
+ missing references, retired sentinels, ordering cycles, exact
255
+ scalar-versus-structured ordering contradictions, stale lifecycle blocks, and
256
+ sparse or isolated active nodes. Findings include stable codes, severity,
256
257
  bounded deterministic samples, truncation, policy text, and safe remediation;
257
258
  the audit never invents an edge. Explicit isolate exemptions suppress policy
258
259
  findings without changing structural coverage metrics.
259
260
 
260
261
  The audit profile also exposes graph-wide resilience and delivery-lineage
261
- metrics. `articulation_points` and `bridge_edges` reuse the exact cut-structure
262
+ metrics. `nodes` and `edges` remain diagnostic totals. Structural ratchets use
263
+ `recorded_nodes`, which excludes synthesized missing/external placeholders,
264
+ and `informative_edges`, which subtracts the union of witnessed redundant edge
265
+ identities and structured rows proven to contradict scalar blocker precedence.
266
+ `redundant_edges` and `ordering_contradiction_edges` remain separate debt
267
+ censuses so repair can tighten their ceilings without weakening the
268
+ information-bearing floor. `articulation_points` and `bridge_edges` reuse the exact cut-structure
262
269
  algorithm; outcome metrics count explicit `Milestone` titles beginning with
263
270
  `Outcome milestone:` and follow only hierarchy or `implements` edges toward
264
271
  them. Active and terminal populations are reported separately, with integer
@@ -340,7 +347,15 @@ on terminal ones) reports raw dependency rows whose exact identity is stored
340
347
  more than once on one holder — invisible to every assembled-graph projection
341
348
  because graph construction deduplicates edges by identity, so
342
349
  `collectDuplicateDependencyRows` scans the pre-assembly item rows carried on
343
- the assembly. Coverage policy is type-aware: the audit profile's
350
+ the assembly. `collectOrderingStorageContradictions` similarly scans raw rows
351
+ before normalization: `blocked_by: target` plus a same-target source-first
352
+ ordering dependency asserts both directions and manufactures a two-node cycle.
353
+ The audit reports the exact holder, target, and removable dependency kind under
354
+ `ordering_storage_contradiction` or
355
+ `legacy_ordering_storage_contradiction`; cycle findings attach that evidence
356
+ instead of leaving agents to re-derive the storage cause. Mutation advisories
357
+ also identify a newly introduced contradiction before reporting its derived
358
+ cycle. Coverage policy is type-aware: the audit profile's
344
359
  `coverage_by_type` breaks active/isolated/degree≤1 counts down per item type
345
360
  (untyped items under `(untyped)`), and `isolateExemptTypes`
346
361
  (`--exempt-isolate-type`) suppresses isolate/sparse findings for types whose