@unbrained/pm-cli 2026.8.24 → 2026.8.25

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 (95) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +13 -0
  3. package/dist/cli-bundle/bundle-manifest.json +152 -152
  4. package/dist/cli-bundle/chunks/{chunk-ZAVCS2GH.js → chunk-244MI4GS.js} +3 -3
  5. package/dist/cli-bundle/chunks/{chunk-NXBFO63A.js → chunk-2F3LUFMW.js} +2 -2
  6. package/dist/cli-bundle/chunks/{chunk-DJNJBWAQ.js → chunk-5I5RWIJC.js} +2 -2
  7. package/dist/cli-bundle/chunks/{chunk-X7WWQDYQ.js → chunk-65MHLHAA.js} +2 -2
  8. package/dist/cli-bundle/chunks/chunk-6C7GIMIL.js +13 -0
  9. package/dist/cli-bundle/chunks/{chunk-IW72J5FW.js → chunk-OWHNAR2B.js} +2 -2
  10. package/dist/cli-bundle/chunks/{chunk-TEQDR5KI.js → chunk-QKGMHGEI.js} +62 -62
  11. package/dist/cli-bundle/chunks/{chunk-L22NP5MA.js → chunk-QLUORNIB.js} +86 -86
  12. package/dist/cli-bundle/chunks/{chunk-AGUL3HUT.js → chunk-T2ENPRXF.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-I5Q7QSZX.js → chunk-TPQIBSL2.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-YQMYF3YD.js +35 -0
  15. package/dist/cli-bundle/chunks/{register-list-query-37A4P6O4.js → register-list-query-XVN2ZLI7.js} +2 -2
  16. package/dist/cli-bundle/chunks/{register-mutation-TBJDHYIT.js → register-mutation-QCKAEGIJ.js} +3 -3
  17. package/dist/cli-bundle/chunks/{register-operations-WRZNEBUM.js → register-operations-SDEAXE7E.js} +2 -2
  18. package/dist/cli-bundle/chunks/{register-setup-H4PDLACD.js → register-setup-LXVBRCJ3.js} +2 -2
  19. package/dist/cli-bundle/focused-chunks/{chunk-CWCN5RLO.js → chunk-2UIWOP3O.js} +2 -2
  20. package/dist/cli-bundle/focused-chunks/chunk-42S3GGZ7.js +50 -0
  21. package/dist/cli-bundle/focused-chunks/{chunk-BFA6KKCI.js → chunk-7I23XGWO.js} +2 -2
  22. package/dist/cli-bundle/focused-chunks/{chunk-6Z24ZMU3.js → chunk-7YCDTCBC.js} +2 -2
  23. package/dist/cli-bundle/focused-chunks/{chunk-O4ZXNJMT.js → chunk-A644DUFQ.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/{chunk-4WP7LNE3.js → chunk-GQR3WH3F.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-RASVBJX5.js → chunk-H5JZEIQV.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/chunk-IBZZZGK3.js +2 -0
  27. package/dist/cli-bundle/focused-chunks/chunk-LMKG3DFE.js +5 -0
  28. package/dist/cli-bundle/focused-chunks/{chunk-6MUTDXMP.js → chunk-N7W67YIG.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/{chunk-IMWTYKII.js → chunk-NOOZGIXP.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-WZLSSGEU.js → chunk-OHIHZ7HS.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/chunk-ONYQCALA.js +19 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-QBP5FSBX.js → chunk-OVJL6NZE.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-RAFKLNZX.js +16 -0
  34. package/dist/cli-bundle/focused-chunks/{chunk-GJR6YEMR.js → chunk-VXWATRFL.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-IZNRRCU3.js → chunk-XUQPEKRN.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/{chunk-MNPECIRL.js → chunk-YO3ZF3FI.js} +2 -2
  37. package/dist/cli-bundle/main.js +2 -2
  38. package/dist/cli-bundle/sdk-authoring.js +1 -1
  39. package/dist/cli-bundle/sdk-contracts.js +2 -2
  40. package/dist/cli-bundle/sdk-core.js +41 -41
  41. package/dist/cli-bundle/sdk-governance.js +1 -1
  42. package/dist/cli-bundle/sdk-graph.js +1 -1
  43. package/dist/cli-bundle/sdk-merge.js +32 -33
  44. package/dist/cli-bundle/sdk-query.js +1 -1
  45. package/dist/cli-bundle/sdk-runtime.js +1 -1
  46. package/dist/cli-bundle/sdk-testing.js +1 -1
  47. package/dist/cli-bundle/sdk.js +5 -5
  48. package/dist/core/diagnostics/remediation.js +17 -2
  49. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +10 -0
  50. package/dist/sdk/cli-contracts/runtime-contracts.js +20 -3
  51. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +49 -25
  52. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +26 -2
  53. package/dist/sdk/governance/health.js +98 -11
  54. package/dist/sdk/governance/validate.js +15 -9
  55. package/dist/sdk/history-repair.d.ts +24 -0
  56. package/dist/sdk/history-repair.js +145 -4
  57. package/dist/sdk/merge/driver.js +25 -4
  58. package/dist/sdk/merge/receipt-file-boundary.d.ts +21 -0
  59. package/dist/sdk/merge/receipt-file-boundary.js +47 -0
  60. package/dist/sdk/merge/receipts.d.ts +24 -1
  61. package/dist/sdk/merge/receipts.js +342 -36
  62. package/dist/sdk/merge/reconcile.js +117 -47
  63. package/dist/sdk/read-output/continuation.d.ts +15 -2
  64. package/dist/sdk/read-output/continuation.js +86 -6
  65. package/dist/sdk/read-output-contracts.d.ts +4 -1
  66. package/dist/sdk/read-output-contracts.js +9 -6
  67. package/docs/MERGE_SAFETY.md +34 -5
  68. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +13 -1
  69. package/docs/READ_OUTPUT_CONTRACTS.md +25 -2
  70. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +7 -3
  71. package/marketplace.json +2 -2
  72. package/package.json +1 -1
  73. package/packages/pm-beads/package.json +1 -1
  74. package/packages/pm-calendar/package.json +1 -1
  75. package/packages/pm-command-kit/package.json +1 -1
  76. package/packages/pm-digital-twin/package.json +1 -1
  77. package/packages/pm-governance-audit/package.json +1 -1
  78. package/packages/pm-guide-shell/package.json +1 -1
  79. package/packages/pm-kanban/package.json +1 -1
  80. package/packages/pm-lifecycle-hooks/package.json +1 -1
  81. package/packages/pm-linked-test-adapters/package.json +1 -1
  82. package/packages/pm-search-advanced/package.json +1 -1
  83. package/packages/pm-templates/package.json +1 -1
  84. package/packages/pm-todos/package.json +1 -1
  85. package/packages/pm-vcs/package.json +1 -1
  86. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  87. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  88. package/sdk/public-surface.json +136 -15
  89. package/dist/cli-bundle/chunks/chunk-MKE6MD2K.js +0 -36
  90. package/dist/cli-bundle/chunks/chunk-YOLLRCLY.js +0 -13
  91. package/dist/cli-bundle/focused-chunks/chunk-FCTT4CZU.js +0 -5
  92. package/dist/cli-bundle/focused-chunks/chunk-Q63PSLO4.js +0 -2
  93. package/dist/cli-bundle/focused-chunks/chunk-QV5UP27O.js +0 -51
  94. package/dist/cli-bundle/focused-chunks/chunk-RPRLENVA.js +0 -16
  95. package/dist/cli-bundle/focused-chunks/chunk-TOFVXBWA.js +0 -19
@@ -1,6 +1,19 @@
1
1
  import type { PmReadOutputCursorEnvelope, PmReadOutputSurface } from "../read-output-contracts.js";
2
- /** Fingerprint the complete canonical row snapshot so changed evidence fails closed. */
3
- export declare function readOutputCollectionFingerprint(path: string, value: unknown[] | Record<string, unknown>): string;
2
+ /** Stable snapshot policy for a read surface whose probes refresh observation metadata. */
3
+ export interface PmReadOutputContinuationFingerprintPolicy {
4
+ /** Version included in fingerprints so policy changes invalidate older cursors. */
5
+ version: 3;
6
+ /** Declared continuation row paths governed by this policy. */
7
+ paths: readonly string[];
8
+ /** Exact direct detail fields excluded for each named dynamic row. */
9
+ ignored_detail_field_names_by_row: Readonly<Record<string, readonly string[]>>;
10
+ /** Promise that verdicts, stable configuration, and nonvolatile evidence remain bound. */
11
+ guarantee: "nonvolatile_snapshot_and_stable_configuration";
12
+ }
13
+ /** Command-specific exceptions to complete-row continuation fingerprinting. */
14
+ export declare const PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES: Readonly<Partial<Record<PmReadOutputSurface, PmReadOutputContinuationFingerprintPolicy>>>;
15
+ /** Fingerprint the policy-normalized row snapshot so stable evidence changes fail closed. */
16
+ export declare function readOutputCollectionFingerprint(path: string, value: unknown[] | Record<string, unknown>, command?: PmReadOutputSurface): string;
4
17
  /** Encode one stable declared-row continuation for CLI, SDK, and MCP callers. */
5
18
  export declare function encodeReadOutputContinuationCursor(cursor: Omit<PmReadOutputCursorEnvelope, "version">): string;
6
19
  /** Decode and validate one universal declared-row continuation cursor. */
@@ -6,7 +6,7 @@
6
6
  * resolution and budget policy.
7
7
  */
8
8
 
9
- !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]="1c73c31e-6246-5730-8c8a-d3ba7c9ec112")}catch(e){}}();
9
+ !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]="9e63b4b0-09a5-50bf-9f56-5f239c75ffe5")}catch(e){}}();
10
10
  import { createHash } from "node:crypto";
11
11
  import { EXIT_CODE } from "../../core/shared/constants.js";
12
12
  import { PmCliError } from "../../core/shared/errors.js";
@@ -14,13 +14,93 @@ import { stableStringify } from "../../core/shared/serialization.js";
14
14
  import { resolveReadOutputSurface } from "../read-output-contracts.js";
15
15
  import { readOutputContinuationRowCollections, sliceReadOutputRowCollection, } from "../read-output-rows.js";
16
16
  const MAX_READ_OUTPUT_CURSOR_LENGTH = 4096;
17
+ const HEALTH_TELEMETRY_VOLATILE_DETAIL_FIELDS = Object.freeze([
18
+ "queue_draining",
19
+ "queue_entries",
20
+ "queue_exists",
21
+ "queue_high_retry_entries",
22
+ "queue_invalid_rows",
23
+ "queue_max_attempts",
24
+ "queue_rows_total",
25
+ "queue_size_bytes",
26
+ "pending_otel_spans",
27
+ "last_attempted_flush_at",
28
+ "last_failed_flush_at",
29
+ "last_otel_attempt_at",
30
+ "last_otel_failure_at",
31
+ "last_otel_success_at",
32
+ "last_successful_flush_at",
33
+ ]);
34
+ /** Command-specific exceptions to complete-row continuation fingerprinting. */
35
+ export const PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES = Object.freeze({
36
+ health: Object.freeze({
37
+ version: 3,
38
+ paths: Object.freeze(["checks"]),
39
+ ignored_detail_field_names_by_row: Object.freeze({
40
+ telemetry: HEALTH_TELEMETRY_VOLATILE_DETAIL_FIELDS,
41
+ }),
42
+ guarantee: "nonvolatile_snapshot_and_stable_configuration",
43
+ }),
44
+ });
17
45
  function isRecord(value) {
18
46
  return value !== null && typeof value === "object" && !Array.isArray(value);
19
47
  }
20
- /** Fingerprint the complete canonical row snapshot so changed evidence fails closed. */
21
- export function readOutputCollectionFingerprint(path, value) {
48
+ function normalizeReadOutputFingerprintValue(value) {
49
+ if (Array.isArray(value)) {
50
+ return value.map(normalizeReadOutputFingerprintValue);
51
+ }
52
+ if (!isRecord(value))
53
+ return value;
54
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
55
+ key,
56
+ normalizeReadOutputFingerprintValue(entry),
57
+ ]));
58
+ }
59
+ function normalizeReadOutputFingerprintRow(value, policy) {
60
+ if (!isRecord(value))
61
+ return normalizeReadOutputFingerprintValue(value);
62
+ const rowName = typeof value.name === "string" ? value.name : undefined;
63
+ const ignoredDetailFields = rowName !== undefined &&
64
+ Object.hasOwn(policy.ignored_detail_field_names_by_row, rowName)
65
+ ? policy.ignored_detail_field_names_by_row[rowName]
66
+ : undefined;
67
+ return Object.fromEntries(Object.entries(value)
68
+ .map(([key, entry]) => {
69
+ if (key !== "details" || !ignoredDetailFields || !isRecord(entry)) {
70
+ return [key, normalizeReadOutputFingerprintValue(entry)];
71
+ }
72
+ return [
73
+ key,
74
+ Object.fromEntries(Object.entries(entry)
75
+ .filter(([detailKey]) => !ignoredDetailFields.includes(detailKey))
76
+ .map(([detailKey, detailValue]) => [
77
+ detailKey,
78
+ normalizeReadOutputFingerprintValue(detailValue),
79
+ ])),
80
+ ];
81
+ }));
82
+ }
83
+ function normalizeReadOutputFingerprintSnapshot(value, policy) {
84
+ return Array.isArray(value)
85
+ ? value.map((row) => normalizeReadOutputFingerprintRow(row, policy))
86
+ : normalizeReadOutputFingerprintRow(value, policy);
87
+ }
88
+ /** Fingerprint the policy-normalized row snapshot so stable evidence changes fail closed. */
89
+ export function readOutputCollectionFingerprint(path, value, command) {
90
+ const policy = command
91
+ ? PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES[command]
92
+ : undefined;
93
+ const policyApplies = policy?.paths.includes(path) === true;
22
94
  return createHash("sha256")
23
- .update(stableStringify({ path, value }))
95
+ .update(stableStringify({
96
+ path,
97
+ value: policyApplies
98
+ ? normalizeReadOutputFingerprintSnapshot(value, policy)
99
+ : value,
100
+ ...(policyApplies
101
+ ? { fingerprint_policy_version: policy.version }
102
+ : {}),
103
+ }))
24
104
  .digest("base64url")
25
105
  .slice(0, 16);
26
106
  }
@@ -105,11 +185,11 @@ export function applyReadOutputContinuation(result, command, cursor) {
105
185
  if (!collection ||
106
186
  totalRows !== cursor.total_rows ||
107
187
  cursor.offset > totalRows ||
108
- readOutputCollectionFingerprint(cursor.path, collection.value) !==
188
+ readOutputCollectionFingerprint(cursor.path, collection.value, command) !==
109
189
  cursor.fingerprint) {
110
190
  throw new PmCliError("The read-output continuation no longer matches the declared row collection; restart the bounded read.", EXIT_CODE.USAGE, { code: "read_output_cursor_stale" });
111
191
  }
112
192
  return sliceReadOutputRowCollection(result, cursor.path, cursor.offset);
113
193
  }
114
194
  //# sourceMappingURL=continuation.js.map
115
- //# debugId=1c73c31e-6246-5730-8c8a-d3ba7c9ec112
195
+ //# debugId=9e63b4b0-09a5-50bf-9f56-5f239c75ffe5
@@ -1,6 +1,7 @@
1
1
  export { resolveReadOutputRecoveryBudget } from "./read-output-budget.js";
2
2
  export type { PmReadOutputRecoveryBudget, PmReadOutputRecoveryBudgetInput, } from "./read-output-budget.js";
3
- export { decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, } from "./read-output/continuation.js";
3
+ export { decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES, readOutputCollectionFingerprint, } from "./read-output/continuation.js";
4
+ export type { PmReadOutputContinuationFingerprintPolicy } from "./read-output/continuation.js";
4
5
  import { type PmReadOutputSessionReceipt, type PmReadOutputSessionState } from "./read-output-session.js";
5
6
  /** Stable output dimensions shared by every read surface. */
6
7
  export declare const PM_READ_OUTPUT_DIMENSIONS: readonly ["include", "amount", "cost", "encoding"];
@@ -61,6 +62,8 @@ export interface PmReadOutputSurfaceContract {
61
62
  precedence: readonly ["canonical", "legacy", "intent", "default"];
62
63
  /** Stable policy used before budget compaction selects retained rows. */
63
64
  budget_retention_policy: "ordered_prefix" | "verdict_priority";
65
+ /** Exact command-local whole-result modes accepted by `outputInclude`. */
66
+ projection_modes?: readonly string[];
64
67
  }
65
68
  /** Source that selected an effective output dimension. */
66
69
  export type PmReadOutputDimensionSource = "canonical" | "legacy" | "intent" | "default";
@@ -5,7 +5,7 @@
5
5
  * surface without coupling package authors to command-specific option names.
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]="76c9c2d0-951d-579e-916e-e8d54d4a8be9")}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]="d084da05-c967-58f1-afe4-069f09838e6f")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  import { compactReadOutputToBudget, estimateReadOutputTokens, resolveReadOutputRecoveryBudget, updateReadOutputReceiptEstimate, } from "./read-output-budget.js";
@@ -13,7 +13,7 @@ export { resolveReadOutputRecoveryBudget } from "./read-output-budget.js";
13
13
  import { resolvePmCommandOutputBudget } from "./cli-contracts/agent-output-contracts.js";
14
14
  import { boundReadOutputRows, countReadOutputRows, mapReadOutputRows, readOutputBudgetCollections, readOutputContinuationRowCollections, readOutputRowPaths, } from "./read-output-rows.js";
15
15
  import { applyReadOutputContinuation, decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, prioritizeAssuranceAssertions, readOutputCollectionFingerprint, } from "./read-output/continuation.js";
16
- export { decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, } from "./read-output/continuation.js";
16
+ export { decodeReadOutputContinuationCursor, encodeReadOutputContinuationCursor, PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES, readOutputCollectionFingerprint, } from "./read-output/continuation.js";
17
17
  import { applyReadOutputSessionReferences, attachReadOutputSessionReceipt, parseReadOutputSession, readOutputSessionRemainingTokens, } from "./read-output-session.js";
18
18
  import { decodeQueryCursorEnvelope, encodeQueryCursor } from "./pagination.js";
19
19
  /** Stable output dimensions shared by every read surface. */
@@ -205,6 +205,9 @@ function buildSurfaceContract(command) {
205
205
  dimensions,
206
206
  precedence: READ_OUTPUT_PRECEDENCE,
207
207
  budget_retention_policy: command === "assurance" ? "verdict_priority" : "ordered_prefix",
208
+ projection_modes: Object.freeze([
209
+ ...readOutputIncludeModeOptions(command).keys(),
210
+ ]),
208
211
  });
209
212
  }
210
213
  /** Universal output contract for every built-in read surface. */
@@ -1092,7 +1095,7 @@ function rebaseBudgetCompactedCursor(projected, originalItemCount, cursorSource,
1092
1095
  }
1093
1096
  return true;
1094
1097
  }
1095
- function captureReadOutputContinuationState(projected, cursor, options) {
1098
+ function captureReadOutputContinuationState(projected, command, cursor, options) {
1096
1099
  const collectionsBeforeBudget = new Map(readOutputContinuationRowCollections(projected).map((collection) => {
1097
1100
  const rows = Array.isArray(collection.value)
1098
1101
  ? collection.value.length
@@ -1106,7 +1109,7 @@ function captureReadOutputContinuationState(projected, cursor, options) {
1106
1109
  baseOffset: continued ? cursor.offset : 0,
1107
1110
  fingerprint: continued
1108
1111
  ? cursor.fingerprint
1109
- : readOutputCollectionFingerprint(collection.path, collection.value),
1112
+ : readOutputCollectionFingerprint(collection.path, collection.value, command),
1110
1113
  },
1111
1114
  ];
1112
1115
  }));
@@ -1154,7 +1157,7 @@ export function applyReadOutputDimensions(command, options, result) {
1154
1157
  const continuationReadyResult = attachValidateDiagnosticRowContract(resolved.command, result);
1155
1158
  const bindingBudget = resolveBindingReadOutputBudget(resolved, session);
1156
1159
  let projected = projectReadOutputRows(continuationReadyResult, resolved, session, cursor);
1157
- const continuationState = captureReadOutputContinuationState(projected, cursor, options);
1160
+ const continuationState = captureReadOutputContinuationState(projected, resolved.command, cursor, options);
1158
1161
  const receipt = {
1159
1162
  contract_version: 1,
1160
1163
  command: resolved.command,
@@ -1207,4 +1210,4 @@ export function resolveReadOutputEncoding(command, options) {
1207
1210
  : undefined;
1208
1211
  }
1209
1212
  //# sourceMappingURL=read-output-contracts.js.map
1210
- //# debugId=76c9c2d0-951d-579e-916e-e8d54d4a8be9
1213
+ //# debugId=d084da05-c967-58f1-afe4-069f09838e6f
@@ -2,6 +2,9 @@
2
2
 
3
3
  Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity and concurrency fixes [pm-9q2t](../.agents/pm/issues/pm-9q2t.toon), [pm-cxyv](../.agents/pm/issues/pm-cxyv.toon), [pm-gpo7](../.agents/pm/issues/pm-gpo7.toon), [pm-m3nl](../.agents/pm/issues/pm-m3nl.toon), [pm-wwfd](../.agents/pm/issues/pm-wwfd.toon), and [pm-xdn6](../.agents/pm/issues/pm-xdn6.toon). Fresh-init fence ownership is tracked by [pm-1w3ljt](../.agents/pm/issues/pm-1w3ljt.toon); runtime-cache index governance by [pm-hous](../.agents/pm/issues/pm-hous.toon); local allocation safety by [pm-khdq](../.agents/pm/issues/pm-khdq.toon); fence-coverage completeness and drift detection by [pm-i4fx](../.agents/pm/issues/pm-i4fx.toon); package-defined item coverage by [pm-5rexki](../.agents/pm/issues/pm-5rexki.toon); non-item JSON coverage by [pm-gjicmx](../.agents/pm/issues/pm-gjicmx.toon); portable driver identity by [pm-w91mvg](../.agents/pm/issues/pm-w91mvg.toon); pending receipt validation by [pm-ysqb6n](../.agents/pm/issues/pm-ysqb6n.toon); receipt classification by [pm-jtwsct](../.agents/pm/issues/pm-jtwsct.toon); direction-independent item conflict selection by [pm-dlx7v7](../.agents/pm/issues/pm-dlx7v7.toon); corrected reconciliation guidance by [pm-lwmstb](../.agents/pm/issues/pm-lwmstb.toon); cross-branch id collision safety by [pm-pibw](../.agents/pm/issues/pm-pibw.toon); auditable merge history by [pm-9j2r3b](../.agents/pm/tasks/pm-9j2r3b.toon); durable conflict decisions by [pm-rh98vo](../.agents/pm/issues/pm-rh98vo.toon); continuous conformance by [pm-76dnfg](../.agents/pm/tasks/pm-76dnfg.toon); workspace-wide CI enforcement by [pm-pdr8t1](../.agents/pm/tasks/pm-pdr8t1.toon); post-merge reconciliation by [pm-mfkv92](../.agents/pm/issues/pm-mfkv92.toon); linked-command execution trust by [pm-ed28wi](../.agents/pm/issues/pm-ed28wi.toon); this repository's own adoption by [pm-iwsj](../.agents/pm/chores/pm-iwsj.toon).
4
4
 
5
+ Lossless receipt health gating is tracked by
6
+ [pm-baksix](../.agents/pm/issues/pm-baksix.toon).
7
+
5
8
  pm stores project context as reviewable repository files. Concurrent agents can therefore use ordinary branches and worktrees, but tracker artifacts need semantic merge behavior: raw line merging cannot preserve TOON collection counts, JSON object structure, or append-only history hash chains.
6
9
 
7
10
  ## Install the repository merge contract
@@ -118,11 +121,37 @@ pm merge reconcile --force --message "Accept reviewed merge decisions" --json
118
121
  ```
119
122
 
120
123
  The preview reports every drifted stream and pending receipt without mutation.
121
- Lossless receipts are reported as provenance but do not become blocking merge
122
- decisions. Receipts with discarded scalar values remain blocking and the apply
123
- pass refuses them unless the coordinator explicitly supplies `--force` after
124
- review. This prevents a routine history repair from silently accepting data
125
- loss while preserving a zero-noise path for merges that retained both changes.
124
+ Lossless receipts do not become discarded-value decisions and reconcile without
125
+ `--force`, but `pm health` reports `merge_receipts_pending:<n>` and remains
126
+ non-green until the apply pass settles them. `pm history-repair` cannot clear
127
+ that receipt finding. When a drifted item also has a pending receipt, the
128
+ `history_drift` remediation map prioritizes `pm merge reconcile --dry-run` only
129
+ when canonical item path, changed-field, and merged-value hash evidence all
130
+ attribute that finding to one or more receipts loaded from the clone-local Git
131
+ evidence store. Every field declared by each receipt must match its current merged-value
132
+ hash, even when only a subset appears in the history reconciliation diff.
133
+ Disjoint valid receipts may collectively cover a multi-field reconciliation;
134
+ the audit and settlement then retain every individually proven receipt id.
135
+ Serialized source claims are ignored. Receipt readers validate the complete
136
+ bounded schema, safe identifiers, filename and item-path identity, timestamps,
137
+ and bounded decision structure before a sidecar enters health or
138
+ reconciliation. Reads use size-preflighted, no-follow regular-file descriptors;
139
+ durable decisions must retain hash-only values. Legacy or durable-only receipts,
140
+ receipts whose declared fields disagree with their hashes, same-item tampering,
141
+ and drift on unrelated items fail closed to the normal `pm history-repair`
142
+ guidance. Health indexes clone-local evidence once by item and reconciliation
143
+ uses the same per-item groups with a fixed receipt-only worker pool, so committed
144
+ sidecars cannot amplify drift scans into unbounded parallel repair work.
145
+ Apply-mode reconciliation repeats the same proof against the exact
146
+ item snapshot used by the audited history rewrite. The audit event and
147
+ settlement include only the individually proven receipt id, so one valid receipt
148
+ cannot authorize an untrusted same-item sibling. Failed or unproven receipts
149
+ remain pending unless the coordinator explicitly reviews and supplies `--force`.
150
+ Receipts with discarded scalar values retain the distinct
151
+ `merge_decisions_unreviewed:<n>` finding, and the apply pass refuses them unless
152
+ the coordinator explicitly supplies `--force` after review. This prevents a
153
+ routine history repair from hiding unfinished reconciliation or silently
154
+ accepting data loss.
126
155
  It exits nonzero while either merge-critical validation check is non-green, so
127
156
  CI and explicit post-merge hooks cannot approve unresolved receipts or drift.
128
157
  The apply pass uses the audited history rewrite boundary to append a
@@ -16,7 +16,10 @@ selectors are tracked by
16
16
  and canonical TOON tables are tracked by
17
17
  [pm-gjjurs](../.agents/pm/issues/pm-gjjurs.toon) and
18
18
  [pm-5y05kq](../.agents/pm/issues/pm-5y05kq.toon). Nested evidence continuation
19
- is tracked by [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon).
19
+ is tracked by [pm-8nev0o](../.agents/pm/issues/pm-8nev0o.toon) and
20
+ [pm-oahhyc](../.agents/pm/issues/pm-oahhyc.toon). Exact command-local
21
+ projection discovery is tracked by
22
+ [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon).
20
23
 
21
24
  ## Agent Quick Context
22
25
 
@@ -112,6 +115,15 @@ machine-iterable without a command-specific selector. `fields` is always explici
112
115
  shape. NDJSON event streams do not carry an envelope and therefore do not
113
116
  publish a row contract.
114
117
 
118
+ Projection mode discovery is command-local even though the compatibility
119
+ degradation ladder is global. Read
120
+ `output_projection_contracts.commands` from a command-scoped contracts call or
121
+ the full contracts matrix before selecting a whole-result mode. The
122
+ contract labels the global ladder `union_not_per_command`, so clients cannot
123
+ infer that `list` accepts `summary` or that `health` accepts `compact`.
124
+ `PM_READ_OUTPUT_SURFACE_CONTRACTS[].projection_modes` provides the identical
125
+ canonical matrix to SDK and package consumers.
126
+
115
127
  SDK and package authors can import `PM_READ_ROW_CONTRACTS`,
116
128
  `PM_READ_ROW_JQ_SELECTOR`, and `resolveReadRowContract` from
117
129
  `@unbrained/pm-cli/sdk`. Existing package declarations are preserved only
@@ -1,6 +1,6 @@
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-h8tpeh](../.agents/pm/features/pm-h8tpeh.toon), [pm-5t33or](../.agents/pm/features/pm-5t33or.toon), [pm-srns](../.agents/pm/issues/pm-srns.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), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon), and [pm-xam9bt](../.agents/pm/issues/pm-xam9bt.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-srns](../.agents/pm/issues/pm-srns.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-oahhyc](../.agents/pm/issues/pm-oahhyc.toon), [pm-q4isdq](../.agents/pm/issues/pm-q4isdq.toon), [pm-e5gl05](../.agents/pm/issues/pm-e5gl05.toon), [pm-cha95z](../.agents/pm/tasks/pm-cha95z.toon), [pm-2qvq7a](../.agents/pm/issues/pm-2qvq7a.toon), and [pm-xam9bt](../.agents/pm/issues/pm-xam9bt.toon).
4
4
 
5
5
  ## Agent Quick Context
6
6
 
@@ -60,6 +60,17 @@ removing spelling receipts and volatile run metadata. A selector that matches
60
60
  neither a declared mode nor any field on any returned row is refused with the
61
61
  legal domain, rather than returning rows with every field removed.
62
62
 
63
+ Runtime discovery publishes the same exact vocabulary before invocation.
64
+ `pm contracts --command <command> --summary` returns
65
+ `output_projection_contracts.commands`, while
66
+ `output_projection_contracts.global_ladder_scope: "union_not_per_command"`
67
+ explicitly marks `output_policy.degradation_ladder` as a cross-command union,
68
+ not a promise that every member is accepted by the selected command. For
69
+ example, `list` declares `brief`, `compact`, and `full`; `health` declares
70
+ `brief`, `full`, and `summary`. The full `read_output_dimensions` matrix also
71
+ includes `projection_modes` for every canonical read surface, including an
72
+ explicit empty array when a surface has no whole-result modes.
73
+
63
74
  ## Cross-Call Context Sessions
64
75
 
65
76
  `--output-session <json>` / `outputSession` composes the four per-call
@@ -164,6 +175,18 @@ an unbounded multi-megabyte response;
164
175
  `recovery_budget_multiplier: 1` declares that each next page retains the same
165
176
  useful-result ceiling.
166
177
 
178
+ Health continuation fingerprints use a versioned nonvolatile-snapshot policy
179
+ for the `checks` row. Command-lifecycle telemetry may refresh timestamps, queue
180
+ counters, and pending spans between pages, so the policy excludes only those
181
+ explicit direct fields from the `telemetry` row's `details`. The row identity,
182
+ verdict, enabled state, capture level, endpoint, environment overrides, probe
183
+ result, and failure errors remain fingerprinted. Every other health check also
184
+ remains fully fingerprinted; changing storage, integrity, history, or another
185
+ stable check fails closed. `PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES`
186
+ publishes the exact ignored detail fields per dynamic row. Other commands still
187
+ fingerprint every field, including fields with the same spelling, and any
188
+ policy-version change fails closed against an older cursor.
189
+
167
190
  When compaction affects a nested collection that is not declared resumable,
168
191
  the recovery budget is derived from the larger of the binding ceiling plus one
169
192
  and the measured pre-compaction result. The SDK adds a 25% envelope margin and
@@ -221,7 +244,7 @@ const result = await pm.list({
221
244
  });
222
245
  ```
223
246
 
224
- Package authors should use the exported read-output contracts instead of inventing package-local limit or projection vocabularies. `PM_READ_OUTPUT_SURFACE_CONTRACTS` is the machine-readable matrix and `resolveReadOutputDimensions` plus `applyReadOutputDimensions` are the shared execution primitives.
247
+ Package authors should use the exported read-output contracts instead of inventing package-local limit or projection vocabularies. `PM_READ_OUTPUT_SURFACE_CONTRACTS` is the machine-readable matrix, `PM_READ_OUTPUT_CONTINUATION_FINGERPRINT_POLICIES` declares stable-snapshot exceptions, and `resolveReadOutputDimensions` plus `applyReadOutputDimensions` are the shared execution primitives.
225
248
 
226
249
  ## Drift Gates
227
250
 
@@ -4,12 +4,12 @@ Tracker: `pm-f05lsg`.
4
4
 
5
5
  Every catalog code is listed. An `uncovered` row is an explicit closure obligation, never an omission or implied approval.
6
6
 
7
- - Catalog error codes: 338
7
+ - Catalog error codes: 342
8
8
  - Executable error codes: 16
9
9
  - Executable-code ratchet floor: 16
10
10
  - Required executable canonical codes: `bulk_ids_input_empty`, `bulk_ids_input_missing_path`, `bulk_ids_input_unreadable`, `invalid_argument_value`, `missing_lifecycle_target`, `missing_required_argument`, `projection_options_mutually_exclusive`, `tracker_not_initialized`, `tracker_root_missing`, `tracker_root_not_directory`, `tracker_root_unreadable`, `unknown_context_intent`, `unknown_field_projection`, `unknown_option`, `unknown_subcommand`
11
- - Uncovered error codes: 322
12
- - Coverage fraction: 0.047337
11
+ - Uncovered error codes: 326
12
+ - Coverage fraction: 0.046784
13
13
  - Closed-domain probes: 18
14
14
  - Grammar probes: 95
15
15
 
@@ -111,6 +111,7 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
111
111
  | `history_author_acknowledge_target_unreadable` | `history_author_acknowledge_target_unreadable` | uncovered | none | 0 |
112
112
  | `history_drift_chain_mismatch` | `history_drift_chain_mismatch` | uncovered | none | 0 |
113
113
  | `history_drift_hash_mismatch` | `history_drift_hash_mismatch` | uncovered | none | 0 |
114
+ | `history_drift_merge_receipt` | `history_drift_merge_receipt` | uncovered | none | 0 |
114
115
  | `history_drift_missing_stream` | `history_drift_missing_stream` | uncovered | none | 0 |
115
116
  | `history_drift_unreadable_stream` | `history_drift_unreadable_stream` | uncovered | none | 0 |
116
117
  | `history_merge_conflict_markers_detected` | `merge_conflict_markers_detected` | uncovered | none | 0 |
@@ -180,7 +181,10 @@ Every catalog code is listed. An `uncovered` row is an explicit closure obligati
180
181
  | `merge_conflict_markers_detected` | `merge_conflict_markers_detected` | uncovered | none | 0 |
181
182
  | `merge_decisions_unreviewed` | `merge_decisions_unreviewed` | uncovered | none | 0 |
182
183
  | `merge_git_config_unwritable` | `merge_git_config_unwritable` | uncovered | none | 0 |
184
+ | `merge_receipt_evidence_invalid` | `merge_receipt_evidence_invalid` | uncovered | none | 0 |
185
+ | `merge_receipts_pending` | `merge_receipts_pending` | uncovered | none | 0 |
183
186
  | `merge_reconcile_discards_require_acceptance` | `merge_reconcile_discards_require_acceptance` | uncovered | none | 0 |
187
+ | `merge_reconcile_receipt_evidence_untrusted` | `merge_reconcile_receipt_evidence_untrusted` | uncovered | none | 0 |
184
188
  | `merge_root_not_found` | `merge_root_not_found` | uncovered | none | 0 |
185
189
  | `missing_allowed_values` | `missing_allowed_values` | uncovered | none | 0 |
186
190
  | `missing_budget` | `missing_budget` | uncovered | none | 0 |
package/marketplace.json CHANGED
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Official marketplace for pm CLI — native git-based project management for Claude Code and AI coding agents.",
9
- "version": "2026.8.24"
9
+ "version": "2026.8.25"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "pm-claude",
14
14
  "source": "./plugins/pm-claude",
15
15
  "description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents, hybrid TUI task tracking, session context injection, and coordination subagents for git-based project management without leaving Claude Code.",
16
- "version": "2026.8.24",
16
+ "version": "2026.8.25",
17
17
  "author": {
18
18
  "name": "unbrained",
19
19
  "url": "https://github.com/unbraind/pm-cli"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-cli",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "description": "Git-native project management CLI for humans and agents.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.10.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-beads",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for importing Beads JSONL records.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-calendar",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for calendar and agenda views.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-command-kit",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm exemplar package for the commands capability: registerCommand, registerFlags, and registerParser.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-digital-twin",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Beyond-PM exemplar: a temporal production-facility digital twin built entirely on public pm SDK and extension primitives.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-governance-audit",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for governance audit and normalization workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-guide-shell",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for guide and shell completion workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-kanban",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm archetype package: a complete Kanban continuous-flow profile built on public SDK primitives.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-lifecycle-hooks",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package demonstrating safe lifecycle hook registration.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-linked-test-adapters",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for optional linked-test run management adapters and reporters.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-search-advanced",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for semantic, hybrid, and reindex search workflows.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-templates",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for reusable create templates.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-todos",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "First-party pm package for Todo markdown import and export.",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbrained/pm-vcs-sdk-exemplar",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Beyond-PM exemplar: a VCS-style changeset workflow built entirely on public pm SDK and extension primitives.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pm-claude",
3
3
  "description": "Native pm CLI integration for Claude Code — 28 MCP tools, 5 workflow skills, 14 slash commands, 4 subagents (coordinator, delivery-chain, triage, verification), hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and full git-based project management without leaving Claude Code.",
4
- "version": "2026.8.24",
4
+ "version": "2026.8.25",
5
5
  "author": {
6
6
  "name": "unbrained",
7
7
  "url": "https://github.com/unbraind/pm-cli"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pm-codex",
3
- "version": "2026.8.24",
3
+ "version": "2026.8.25",
4
4
  "description": "Native Codex integration for pm-cli with bundled MCP tools, skills, commands, and agent workflows.",
5
5
  "author": {
6
6
  "name": "unbrained",