@unbrained/pm-cli 2026.9.4 → 2026.9.6

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 (277) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
  2. package/.agents/skills/README.md +2 -2
  3. package/.agents/skills/pm-developer/SKILL.md +4 -1
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +10 -0
  5. package/.agents/skills/pm-developer/references/GRAPH_AND_RELATIONSHIPS.md +3 -1
  6. package/.agents/skills/pm-extensions/SKILL.md +2 -2
  7. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +3 -3
  8. package/.agents/skills/pm-extensions/references/TROUBLESHOOTING.md +3 -3
  9. package/.agents/skills/pm-user/SKILL.md +2 -0
  10. package/.agents/skills/pm-user/references/BACKLOG_SHAPING.md +5 -0
  11. package/.agents/skills/pm-user/references/WORKFLOWS.md +20 -5
  12. package/.claude-plugin/marketplace.json +2 -2
  13. package/CHANGELOG.md +58 -3
  14. package/dist/cli/commander-usage.d.ts +2 -0
  15. package/dist/cli/commander-usage.js +15 -12
  16. package/dist/cli/help-json-payload.js +12 -7
  17. package/dist/cli/main.js +22 -11
  18. package/dist/cli/register-list-query.js +4 -2
  19. package/dist/cli/register-mutation.js +4 -2
  20. package/dist/cli/register-operations.js +17 -8
  21. package/dist/cli-bundle/bundle-manifest.json +153 -161
  22. package/dist/cli-bundle/chunks/chunk-AZDFJGH6.js +9 -0
  23. package/dist/cli-bundle/chunks/{chunk-V72UV7QS.js → chunk-BAX2BYUW.js} +73 -73
  24. package/dist/cli-bundle/chunks/{chunk-HI6BHPCU.js → chunk-CKOL5U7J.js} +51 -51
  25. package/dist/cli-bundle/chunks/{chunk-A24WAVE6.js → chunk-JT6XF6GE.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-I2AS367G.js → chunk-JX4DH4WC.js} +2 -2
  27. package/dist/cli-bundle/chunks/{chunk-YW4QK2G7.js → chunk-NPN5I67J.js} +2 -2
  28. package/dist/cli-bundle/chunks/chunk-OF76PSDQ.js +5 -0
  29. package/dist/cli-bundle/chunks/chunk-QUWFABDM.js +232 -0
  30. package/dist/cli-bundle/chunks/{chunk-RI4XNOYS.js → chunk-RWWBOWJ5.js} +2 -2
  31. package/dist/cli-bundle/chunks/chunk-WGAOYSYH.js +40 -0
  32. package/dist/cli-bundle/chunks/{chunk-X6CMGV6L.js → chunk-WI2AYPA7.js} +2 -2
  33. package/dist/cli-bundle/chunks/{register-list-query-Z5YYSJJG.js → register-list-query-5JL52D33.js} +3 -3
  34. package/dist/cli-bundle/chunks/{register-mutation-ELSP6I4I.js → register-mutation-ZPG7KMVP.js} +4 -4
  35. package/dist/cli-bundle/chunks/register-operations-I5W3KMGB.js +2 -0
  36. package/dist/cli-bundle/chunks/{register-setup-E2AE72QG.js → register-setup-H4SVAVX7.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/{chunk-3646BZ4W.js → chunk-3BZEOXLT.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-AL5ON6K6.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-CHC2IDXA.js +6 -0
  40. package/dist/cli-bundle/focused-chunks/chunk-CK6QFAPZ.js +20 -0
  41. package/dist/cli-bundle/focused-chunks/{chunk-NBMJD6MK.js → chunk-EZR3GHFE.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/chunk-H2WJWK7L.js +56 -0
  43. package/dist/cli-bundle/focused-chunks/{chunk-53IHPICX.js → chunk-LIJIA4TY.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/{chunk-25UJBH4M.js → chunk-M6PBRFSH.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/{chunk-AJR3OP2E.js → chunk-NTPY5GSO.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/chunk-P5O7MP5Y.js +2 -0
  47. package/dist/cli-bundle/focused-chunks/chunk-PDMW2E36.js +177 -0
  48. package/dist/cli-bundle/focused-chunks/{chunk-MHKUIPJW.js → chunk-PEFABF7E.js} +2 -2
  49. package/dist/cli-bundle/focused-chunks/{chunk-6PWPQKDN.js → chunk-QTVCLMSZ.js} +2 -2
  50. package/dist/cli-bundle/focused-chunks/{chunk-7N2TV7WZ.js → chunk-QTZRBUYA.js} +2 -2
  51. package/dist/cli-bundle/focused-chunks/chunk-SGQST3PQ.js +12 -0
  52. package/dist/cli-bundle/focused-chunks/chunk-UKHASMMP.js +10 -0
  53. package/dist/cli-bundle/focused-chunks/chunk-ZPEKQHOC.js +2 -0
  54. package/dist/cli-bundle/main.js +22 -15
  55. package/dist/cli-bundle/sdk-authoring.js +1 -1
  56. package/dist/cli-bundle/sdk-contracts.js +2 -2
  57. package/dist/cli-bundle/sdk-core.js +37 -37
  58. package/dist/cli-bundle/sdk-governance.js +1 -1
  59. package/dist/cli-bundle/sdk-graph.js +1 -1
  60. package/dist/cli-bundle/sdk-merge.js +42 -39
  61. package/dist/cli-bundle/sdk-query.js +1 -1
  62. package/dist/cli-bundle/sdk-runtime.js +1 -1
  63. package/dist/cli-bundle/sdk-testing.js +1 -1
  64. package/dist/cli-bundle/sdk.js +9 -9
  65. package/dist/core/extensions/extension-types.d.ts +2 -0
  66. package/dist/core/extensions/extension-types.js +2 -2
  67. package/dist/core/extensions/module-graph-snapshot.js +5 -4
  68. package/dist/core/fs/host-environment-errors.d.ts +27 -0
  69. package/dist/core/fs/host-environment-errors.js +142 -0
  70. package/dist/core/history/drift-scan.d.ts +5 -0
  71. package/dist/core/history/drift-scan.js +16 -6
  72. package/dist/core/history/event-classification.d.ts +1 -1
  73. package/dist/core/history/event-classification.js +3 -2
  74. package/dist/core/history/history.js +37 -5
  75. package/dist/core/history/identity.d.ts +15 -0
  76. package/dist/core/history/identity.js +31 -0
  77. package/dist/core/history/projection.js +50 -17
  78. package/dist/core/history/read.js +6 -3
  79. package/dist/core/history/replay.d.ts +1 -2
  80. package/dist/core/history/replay.js +4 -4
  81. package/dist/core/history/version-address.d.ts +13 -0
  82. package/dist/core/history/version-address.js +33 -0
  83. package/dist/core/item/actionability.d.ts +21 -1
  84. package/dist/core/item/actionability.js +45 -10
  85. package/dist/core/item/id.js +8 -4
  86. package/dist/core/item/item-type-definition.d.ts +2 -0
  87. package/dist/core/item/item-type-definition.js +9 -2
  88. package/dist/core/item/type-registry.d.ts +5 -1
  89. package/dist/core/item/type-registry.js +9 -4
  90. package/dist/core/output/mutation-projection.js +12 -5
  91. package/dist/core/shared/errors.d.ts +8 -0
  92. package/dist/core/shared/errors.js +2 -2
  93. package/dist/core/store/item-metadata-query-index.js +13 -10
  94. package/dist/core/store/item-metadata-read-work.d.ts +19 -0
  95. package/dist/core/store/item-metadata-read-work.js +44 -0
  96. package/dist/core/store/item-store.d.ts +14 -0
  97. package/dist/core/store/item-store.js +52 -10
  98. package/dist/core/store/settings-validator.js +3 -2
  99. package/dist/core/validate/fix-planning.d.ts +1 -1
  100. package/dist/core/validate/fix-planning.js +2 -2
  101. package/dist/core/validate/missing-link-owners.d.ts +1 -1
  102. package/dist/core/validate/missing-link-owners.js +5 -3
  103. package/dist/core/validate/stale-file-classification.d.ts +6 -4
  104. package/dist/core/validate/stale-file-classification.js +20 -5
  105. package/dist/mcp/server.js +12 -5
  106. package/dist/sdk/actionability.d.ts +1 -1
  107. package/dist/sdk/actionability.js +3 -3
  108. package/dist/sdk/cli-contracts/command-aliases.js +11 -2
  109. package/dist/sdk/cli-contracts/completeness.js +4 -3
  110. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  111. package/dist/sdk/cli-contracts/flag-contracts.js +31 -5
  112. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +21 -13
  113. package/dist/sdk/cli-contracts/grammar-contracts.js +11 -2
  114. package/dist/sdk/cli-contracts/runtime-contracts.js +5 -2
  115. package/dist/sdk/cli-contracts/schemas/assurance-definition.d.ts +254 -5
  116. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +52 -2
  117. package/dist/sdk/cli-contracts/tool-parameter-tables.js +30 -6
  118. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  119. package/dist/sdk/cli-contracts/tool-schema.js +32 -7
  120. package/dist/sdk/context/usage-ledger.d.ts +41 -0
  121. package/dist/sdk/context/usage-ledger.js +186 -0
  122. package/dist/sdk/context-intent-contracts.js +3 -3
  123. package/dist/sdk/context-usage.d.ts +18 -9
  124. package/dist/sdk/context-usage.js +44 -121
  125. package/dist/sdk/define.d.ts +1 -1
  126. package/dist/sdk/define.js +2 -2
  127. package/dist/sdk/dependency-provenance.d.ts +7 -0
  128. package/dist/sdk/dependency-provenance.js +14 -4
  129. package/dist/sdk/duplicates.d.ts +2 -0
  130. package/dist/sdk/duplicates.js +3 -2
  131. package/dist/sdk/environment/host-environment-errors.d.ts +5 -27
  132. package/dist/sdk/environment/host-environment-errors.js +4 -137
  133. package/dist/sdk/extension/install-runtime.js +9 -6
  134. package/dist/sdk/extension/install-snapshot.js +7 -6
  135. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +104 -56
  136. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -2
  137. package/dist/sdk/governance/assurance-action.d.ts +3 -2
  138. package/dist/sdk/governance/assurance-action.js +23 -11
  139. package/dist/sdk/governance/assurance-runtime.d.ts +2 -0
  140. package/dist/sdk/governance/assurance-runtime.js +6 -3
  141. package/dist/sdk/governance/defect-recurrence-coverage.d.ts +93 -0
  142. package/dist/sdk/governance/defect-recurrence-coverage.js +189 -0
  143. package/dist/sdk/governance/defect-recurrence-graph.d.ts +33 -0
  144. package/dist/sdk/governance/defect-recurrence-graph.js +121 -0
  145. package/dist/sdk/governance/defect-recurrence.d.ts +8 -0
  146. package/dist/sdk/governance/defect-recurrence.js +118 -17
  147. package/dist/sdk/governance/health.d.ts +17 -2
  148. package/dist/sdk/governance/health.js +31 -10
  149. package/dist/sdk/governance/linked-file-report.d.ts +41 -0
  150. package/dist/sdk/governance/linked-file-report.js +72 -0
  151. package/dist/sdk/governance/validate-history-drift.js +16 -5
  152. package/dist/sdk/governance/validate.d.ts +5 -2
  153. package/dist/sdk/governance/validate.js +21 -37
  154. package/dist/sdk/governance.d.ts +2 -0
  155. package/dist/sdk/governance.js +4 -2
  156. package/dist/sdk/guide-topics.js +116 -2
  157. package/dist/sdk/history/salvage.d.ts +35 -0
  158. package/dist/sdk/history/salvage.js +248 -0
  159. package/dist/sdk/history-compact.js +32 -37
  160. package/dist/sdk/history-read.d.ts +3 -2
  161. package/dist/sdk/history-read.js +6 -3
  162. package/dist/sdk/history-repair.d.ts +12 -0
  163. package/dist/sdk/history-repair.js +60 -13
  164. package/dist/sdk/lifecycle/claim.d.ts +4 -0
  165. package/dist/sdk/lifecycle/claim.js +9 -3
  166. package/dist/sdk/lifecycle/close.d.ts +8 -0
  167. package/dist/sdk/lifecycle/close.js +16 -8
  168. package/dist/sdk/lifecycle/create.js +9 -12
  169. package/dist/sdk/lifecycle/restore.d.ts +1 -0
  170. package/dist/sdk/lifecycle/restore.js +19 -7
  171. package/dist/sdk/lifecycle/update.js +12 -12
  172. package/dist/sdk/lifecycle-policy.d.ts +3 -0
  173. package/dist/sdk/lifecycle-policy.js +2 -2
  174. package/dist/sdk/merge/abandoned-receipts.d.ts +15 -0
  175. package/dist/sdk/merge/abandoned-receipts.js +47 -0
  176. package/dist/sdk/merge/driver.js +4 -2
  177. package/dist/sdk/merge/index.d.ts +1 -0
  178. package/dist/sdk/merge/index.js +2 -2
  179. package/dist/sdk/merge/receipt-operation.d.ts +15 -0
  180. package/dist/sdk/merge/receipt-operation.js +97 -0
  181. package/dist/sdk/merge/receipt-schema.d.ts +20 -0
  182. package/dist/sdk/merge/receipt-schema.js +398 -0
  183. package/dist/sdk/merge/receipts.d.ts +16 -7
  184. package/dist/sdk/merge/receipts.js +54 -340
  185. package/dist/sdk/merge/reconcile.d.ts +2 -0
  186. package/dist/sdk/merge/reconcile.js +11 -4
  187. package/dist/sdk/output-projection.d.ts +3 -1
  188. package/dist/sdk/output-projection.js +11 -3
  189. package/dist/sdk/public-surface.json +1 -0
  190. package/dist/sdk/query/context.d.ts +9 -0
  191. package/dist/sdk/query/context.js +33 -21
  192. package/dist/sdk/query/duplicate-candidates.d.ts +7 -0
  193. package/dist/sdk/query/duplicate-candidates.js +71 -0
  194. package/dist/sdk/query/get.d.ts +2 -2
  195. package/dist/sdk/query/get.js +9 -8
  196. package/dist/sdk/query/history.d.ts +11 -0
  197. package/dist/sdk/query/history.js +34 -10
  198. package/dist/sdk/query/next.d.ts +15 -1
  199. package/dist/sdk/query/next.js +43 -20
  200. package/dist/sdk/query.d.ts +3 -0
  201. package/dist/sdk/query.js +5 -2
  202. package/dist/sdk/read-output-session.js +5 -3
  203. package/dist/sdk/runtime-primitives.d.ts +1 -1
  204. package/dist/sdk/runtime-primitives.js +3 -3
  205. package/dist/sdk/runtime.js +4 -2
  206. package/dist/sdk/similarity.d.ts +24 -3
  207. package/dist/sdk/similarity.js +50 -55
  208. package/dist/types.d.ts +2 -0
  209. package/dist/types.js +2 -2
  210. package/docs/AGENT_GUIDE.md +58 -1
  211. package/docs/BOUNDED_CONTEXT_READS.md +185 -0
  212. package/docs/CLOSE_EVIDENCE_RECOVERY.md +35 -0
  213. package/docs/COMMANDS.md +30 -8
  214. package/docs/CONTEXT_RELEVANCE.md +16 -4
  215. package/docs/DEFECT_RECURRENCE.md +80 -6
  216. package/docs/EXTENSIONS.md +18 -19
  217. package/docs/HISTORY_RECOVERY.md +146 -0
  218. package/docs/MERGE_SAFETY.md +50 -0
  219. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +66 -0
  220. package/docs/PR_REVIEW_LOOP.md +18 -3
  221. package/docs/README.md +19 -1
  222. package/docs/RELEASING.md +31 -13
  223. package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +24 -1
  224. package/docs/SDK_EXECUTION_CONTRACTS.md +105 -0
  225. package/docs/SDK_LIFECYCLE.md +27 -0
  226. package/docs/SDK_RUNTIME_BOUNDARIES.md +11 -0
  227. package/docs/TESTING.md +5 -0
  228. package/docs/agent-task-token-baseline.json +17 -17
  229. package/docs/agent-task-transcripts.json +2 -1
  230. package/docs/generated/FLAG_LEXICON_BUDGETS.md +11 -11
  231. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +11 -3
  232. package/marketplace.json +2 -2
  233. package/package.json +8 -6
  234. package/packages/pm-beads/package.json +1 -1
  235. package/packages/pm-calendar/package.json +1 -1
  236. package/packages/pm-command-kit/package.json +1 -1
  237. package/packages/pm-digital-twin/package.json +1 -1
  238. package/packages/pm-governance-audit/README.md +10 -1
  239. package/packages/pm-governance-audit/extensions/governance-audit/dedupe-audit.ts +50 -65
  240. package/packages/pm-governance-audit/extensions/governance-audit/index.ts +2 -2
  241. package/packages/pm-governance-audit/extensions/governance-audit/sdk.ts +1 -0
  242. package/packages/pm-governance-audit/package.json +1 -1
  243. package/packages/pm-guide-shell/package.json +1 -1
  244. package/packages/pm-kanban/package.json +1 -1
  245. package/packages/pm-lifecycle-hooks/package.json +1 -1
  246. package/packages/pm-linked-test-adapters/package.json +1 -1
  247. package/packages/pm-search-advanced/package.json +1 -1
  248. package/packages/pm-templates/package.json +1 -1
  249. package/packages/pm-todos/package.json +1 -1
  250. package/packages/pm-vcs/package.json +1 -1
  251. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  252. package/plugins/pm-claude/skills/pm-audit/SKILL.md +2 -2
  253. package/plugins/pm-claude/skills/pm-developer/SKILL.md +2 -2
  254. package/plugins/pm-claude/skills/pm-planner/SKILL.md +2 -2
  255. package/plugins/pm-claude/skills/pm-release/SKILL.md +2 -2
  256. package/plugins/pm-claude/skills/pm-workflow/SKILL.md +3 -3
  257. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  258. package/plugins/pm-codex/skills/pm-auditor/SKILL.md +2 -2
  259. package/plugins/pm-codex/skills/pm-native/SKILL.md +3 -4
  260. package/plugins/pm-codex/skills/pm-release/SKILL.md +2 -2
  261. package/scripts/finalize-build.mjs +13 -1
  262. package/dist/cli-bundle/chunks/chunk-6XSKPNCF.js +0 -230
  263. package/dist/cli-bundle/chunks/chunk-OGBVU67G.js +0 -5
  264. package/dist/cli-bundle/chunks/chunk-TXW6VL33.js +0 -38
  265. package/dist/cli-bundle/chunks/chunk-VGLHECAP.js +0 -9
  266. package/dist/cli-bundle/chunks/register-operations-OH7R3ZT4.js +0 -2
  267. package/dist/cli-bundle/focused-chunks/chunk-4YRAVI43.js +0 -12
  268. package/dist/cli-bundle/focused-chunks/chunk-5P4HVOWG.js +0 -176
  269. package/dist/cli-bundle/focused-chunks/chunk-636VVQ7F.js +0 -54
  270. package/dist/cli-bundle/focused-chunks/chunk-B3A6MJYE.js +0 -2
  271. package/dist/cli-bundle/focused-chunks/chunk-BFDDJ2T2.js +0 -2
  272. package/dist/cli-bundle/focused-chunks/chunk-BHUIRZWQ.js +0 -9
  273. package/dist/cli-bundle/focused-chunks/chunk-JADHHPY6.js +0 -6
  274. package/dist/cli-bundle/focused-chunks/chunk-NSKBLHVI.js +0 -20
  275. package/dist/cli-bundle/focused-chunks/chunk-P2GOAOQN.js +0 -2
  276. package/dist/cli-bundle/focused-chunks/chunk-YARWJM2B.js +0 -2
  277. package/sdk/public-surface.json +0 -33034
@@ -1,3 +1,4 @@
1
+ import { type HistorySalvageReceipt } from "./history/salvage.js";
1
2
  import { type ReplayDocument } from "../core/history/replay.js";
2
3
  import type { GlobalOptions } from "../core/shared/command-types.js";
3
4
  import type { HistoryEntry } from "../types/index.js";
@@ -5,6 +6,8 @@ import { type MergeDecisionReceipt } from "./merge/receipts.js";
5
6
  import { type ProvenanceNormalizationReceipt } from "./governance/provenance-health.js";
6
7
  /** Documents the history repair command options payload exchanged by command, SDK, and package integrations. */
7
8
  export interface HistoryRepairCommandOptions {
9
+ /** Remove only an invalid trailing suffix after a verified prefix; never re-anchor or reconcile. */
10
+ salvageTail?: boolean;
8
11
  /** Value that configures or reports dry run for this contract. */
9
12
  dryRun?: boolean;
10
13
  /** Value that configures or reports author for this contract. */
@@ -33,9 +36,18 @@ export interface HistoryRepairCommandOptions {
33
36
  gitWorkspaceRoot: string | null;
34
37
  receipts: MergeDecisionReceipt[];
35
38
  }>;
39
+ /** Restored-origin evidence checked against the same item snapshot protected by the rewrite transaction. */
40
+ mergeAbandonmentProof?: {
41
+ /** Git workspace containing the tracked item. */
42
+ gitWorkspaceRoot: string;
43
+ /** Authoritative receipt whose original rebase state must match. */
44
+ receipt: MergeDecisionReceipt;
45
+ };
36
46
  }
37
47
  /** Documents the history repair result payload exchanged by command, SDK, and package integrations. */
38
48
  export interface HistoryRepairResult {
49
+ /** Present when invalid trailing bytes were selected for explicit salvage. */
50
+ salvage?: HistorySalvageReceipt;
39
51
  /** Stable identifier used to reference this record across commands and storage. */
40
52
  id: string;
41
53
  /** Value that configures or reports dry run for this contract. */
@@ -4,8 +4,9 @@
4
4
  * Implements the pm history repair command surface and its agent-facing runtime behavior.
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]="cb0b0e36-3135-5fc4-a0ae-f4e5b974e57f")}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]="9f91f2ee-cebe-592c-92ee-717301fa96ca")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "./environment/tracker-preflight.js";
9
+ import { salvageHistoryTail } from "./history/salvage.js";
9
10
  import { realpath } from "node:fs/promises";
10
11
  import path from "node:path";
11
12
  import jsonPatch from "fast-json-patch";
@@ -29,6 +30,7 @@ import { listAllItemMetadataWithBody, readLocatedItem, } from "../core/store/ite
29
30
  import { resolvePmRoot } from "../core/store/paths.js";
30
31
  import { readSettings } from "../core/store/settings.js";
31
32
  import { resolveHistorySubject } from "./history-redact.js";
33
+ import { isOriginalGitStateRestored } from "./merge/receipt-operation.js";
32
34
  import { inspectMergeReceiptEvidence, summarizeMergeReceipt, } from "./merge/receipts.js";
33
35
  import { encodeItemScalarDecisionValue, hashItemScalarDecisionValue, } from "./merge/three-way.js";
34
36
  import { listInvalidProvenanceHistoryStreamIds, normalizeInvalidHistoryProvenance, } from "./governance/provenance-health.js";
@@ -228,6 +230,24 @@ async function verifyMergeReceiptProof(params) {
228
230
  receipt_ids: [],
229
231
  };
230
232
  }
233
+ /** Refuse a restored-origin audit when its exact item snapshot or clean history has changed. */
234
+ async function assertHistoryRepairAbandonmentProof(proof, context, chainOk, reanchor) {
235
+ if (proof === undefined)
236
+ return;
237
+ const { receipt, gitWorkspaceRoot } = proof;
238
+ const canonicalPath = context.currentItemPath === null ? null
239
+ : path.relative(gitWorkspaceRoot, context.currentItemPath).split(path.sep).join("/");
240
+ if (!chainOk || reanchor.entriesRehashed !== 0 || reanchor.entriesPatchRepaired !== 0 || context.matchedChainBefore !== true ||
241
+ context.currentItemRawBeforeLock === null || canonicalPath !== receipt.item_path ||
242
+ receipt.operation === undefined ||
243
+ !await isOriginalGitStateRestored(gitWorkspaceRoot, receipt.item_path, receipt.operation, context.currentItemRawBeforeLock)) {
244
+ throw new PmCliError("Restored-origin receipt evidence no longer proves the exact clean item snapshot.", EXIT_CODE.CONFLICT, {
245
+ code: "merge_reconcile_receipt_evidence_untrusted",
246
+ recovery: { suggested_retry: "pm merge reconcile --dry-run" },
247
+ });
248
+ }
249
+ }
250
+ /** Resolve and verify receipt candidates against loaded item evidence, refusing untrusted preview and apply requests alike. */
231
251
  async function resolveHistoryRepairMergeEvidence(params) {
232
252
  const requestedReceiptIds = new Set(params.options.mergeReceiptProof?.receipts
233
253
  .filter((receipt) => receipt.item_id === params.subjectId)
@@ -255,7 +275,6 @@ async function resolveHistoryRepairMergeEvidence(params) {
255
275
  : undefined;
256
276
  if (mergeReceiptProof &&
257
277
  !mergeReceiptProof.trusted &&
258
- params.options.dryRun !== true &&
259
278
  params.options.force !== true) {
260
279
  throw new PmCliError(`Merge receipt evidence for ${params.subjectId} does not prove the exact item snapshot (${mergeReceiptProof.reason}).`, EXIT_CODE.CONFLICT, {
261
280
  code: "merge_reconcile_receipt_evidence_untrusted",
@@ -358,6 +377,7 @@ function collectHistoryRepairWarnings(changed, skippedOps, reconciliation) {
358
377
  }
359
378
  return warnings;
360
379
  }
380
+ /** Revalidate item/history bytes and restored-origin Git proof under the rewrite lock before persisting. */
361
381
  async function applyHistoryRepairRewrite(params) {
362
382
  return executeHistoryRewrite({
363
383
  pmRoot: params.pmRoot,
@@ -365,16 +385,19 @@ async function applyHistoryRepairRewrite(params) {
365
385
  settings: params.settings,
366
386
  typeRegistry: params.typeRegistry,
367
387
  historyRawBeforeLock: params.historyRawBeforeLock,
368
- currentItemRawBeforeLock: params.currentItemRawBeforeLock,
388
+ currentItemRawBeforeLock: params.itemReplayContext.currentItemRawBeforeLock,
369
389
  operation: "history-repair",
370
390
  author: params.author,
371
391
  force: params.force,
372
- itemDocument: params.loadedItem?.document ?? null,
373
- applyRewrite: async ({ historyRawUnderLock }) => writeHistoryRawWithRollback({
374
- historyPath: params.historyPath,
375
- nextHistoryRaw: historyEntriesToRaw(params.rewrittenEntries),
376
- historyRawUnderLock,
377
- }),
392
+ itemDocument: params.itemReplayContext.loadedItem?.document ?? null,
393
+ applyRewrite: async ({ historyRawUnderLock }) => {
394
+ await assertHistoryRepairAbandonmentProof(params.mergeAbandonmentProof, params.itemReplayContext, params.chainOk, params.reanchor);
395
+ await writeHistoryRawWithRollback({
396
+ historyPath: params.historyPath,
397
+ nextHistoryRaw: historyEntriesToRaw(params.rewrittenEntries),
398
+ historyRawUnderLock,
399
+ });
400
+ },
378
401
  applyPostRewrite: async () => runActiveOnWriteHooks({
379
402
  path: params.historyPath,
380
403
  scope: "project",
@@ -389,6 +412,24 @@ export async function runHistoryRepair(id, options, global) {
389
412
  const settings = await readSettings(pmRoot);
390
413
  const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
391
414
  const subject = await resolveHistorySubject(pmRoot, id, settings, typeRegistry.type_to_folder);
415
+ if (options.salvageTail === true) {
416
+ return salvageHistoryTail({ pmRoot, subject, settings, typeRegistry, options, author: resolveAuthor(options.author, settings.author_default) });
417
+ }
418
+ return repairHistorySubject({ pmRoot, subject, settings, typeRegistry, options });
419
+ }
420
+ /** Preserve explicit audit requests while reusing exact restored-origin dispositions in verified history. */
421
+ function shouldAppendForcedHistoryAudit(options, historyEntries) {
422
+ // Receipt persistence can fail after the audited history transaction commits.
423
+ // Only an identical disposition satisfies a retry; unrelated audits do not.
424
+ const alreadyRecorded = options.mergeAbandonmentProof !== undefined &&
425
+ options.auditContext !== undefined &&
426
+ historyEntries.some((entry) => entry.op === "merge_reconcile" &&
427
+ stableStringify(entry.context) === stableStringify(options.auditContext));
428
+ return options.forceAuditEntry === true && !alreadyRecorded;
429
+ }
430
+ /** Reanchor or reconcile one resolved subject, separately from byte-preserving salvage. */
431
+ async function repairHistorySubject(params) {
432
+ const { pmRoot, subject, settings, typeRegistry, options } = params;
392
433
  if (!(await pathExists(subject.historyPath))) {
393
434
  throw new PmCliError(`No history stream exists for ${subject.id}.`, EXIT_CODE.NOT_FOUND);
394
435
  }
@@ -416,6 +457,7 @@ export async function runHistoryRepair(id, options, global) {
416
457
  .filter((version) => version !== undefined));
417
458
  const reanchor = reanchorHistoryEntries(provenanceNormalization.entries, itemHashVersion);
418
459
  const itemReplayContext = await loadHistoryRepairItemReplay(subject, settings, historyEntries, itemHashVersion);
460
+ await assertHistoryRepairAbandonmentProof(options.mergeAbandonmentProof, itemReplayContext, chainBefore.ok, reanchor);
419
461
  const finalReplay = reanchor.finalDocument;
420
462
  const finalReplayHashes = replayHashVerificationCandidates(finalReplay, itemHashVersion);
421
463
  let reconcileNeeded = false;
@@ -440,7 +482,7 @@ export async function runHistoryRepair(id, options, global) {
440
482
  reanchor.entriesRehashed > 0,
441
483
  reanchor.entriesPatchRepaired > 0,
442
484
  reconcileNeeded,
443
- options.forceAuditEntry === true,
485
+ shouldAppendForcedHistoryAudit(options, historyEntries),
444
486
  provenanceNormalization.receipt.changed,
445
487
  ].some(Boolean);
446
488
  const author = resolveAuthor(options.author, settings.author_default);
@@ -481,10 +523,12 @@ export async function runHistoryRepair(id, options, global) {
481
523
  settings,
482
524
  typeRegistry,
483
525
  historyRawBeforeLock,
484
- currentItemRawBeforeLock: itemReplayContext.currentItemRawBeforeLock,
526
+ itemReplayContext,
527
+ mergeAbandonmentProof: options.mergeAbandonmentProof,
528
+ chainOk: chainBefore.ok,
529
+ reanchor,
485
530
  author,
486
531
  force: options.force,
487
- loadedItem: itemReplayContext.loadedItem,
488
532
  historyPath: subject.historyPath,
489
533
  rewrittenEntries,
490
534
  })));
@@ -537,6 +581,9 @@ export function assertHistoryRepairTarget(id, all) {
537
581
  }
538
582
  /** Bulk drift repair: scan every item's history stream with the same drift scan `pm health` uses, then run the audited single-stream repair (ownership check, lock, no-drift verification, audit marker) for each drifted stream. One failing stream never aborts the rest; failures are collected per row and the caller decides the exit code from `totals.failed`. */
539
583
  export async function runHistoryRepairAll(options, global) {
584
+ if (options.salvageTail === true) {
585
+ throw new PmCliError("Tail salvage requires one explicit item ID; --all is not supported.", EXIT_CODE.USAGE);
586
+ }
540
587
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
541
588
  await assertInitializedTracker(pmRoot);
542
589
  const settings = await readSettings(pmRoot);
@@ -608,4 +655,4 @@ export async function runHistoryRepairAll(options, global) {
608
655
  };
609
656
  }
610
657
  //# sourceMappingURL=history-repair.js.map
611
- //# debugId=cb0b0e36-3135-5fc4-a0ae-f4e5b974e57f
658
+ //# debugId=9f91f2ee-cebe-592c-92ee-717301fa96ca
@@ -62,6 +62,10 @@ export interface ReleaseResult {
62
62
  previous_assignee: string | null;
63
63
  /** Value that configures or reports forced for this contract. */
64
64
  forced: boolean;
65
+ /** Stable handoff diagnostics shared by CLI and MCP consumers. */
66
+ warnings?: string[];
67
+ /** Concrete recovery commands when releasing ownership leaves work in progress. */
68
+ suggestions?: string[];
65
69
  }
66
70
  /** Documents the claim mutation options payload exchanged by command, SDK, and package integrations. */
67
71
  export interface ClaimMutationOptions {
@@ -4,9 +4,9 @@
4
4
  * Implements the pm claim command surface and its agent-facing runtime behavior.
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]="1a61bf25-e320-5adc-8f5a-a427bc89af1a")}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]="a4d95016-05b9-5272-8044-2649da644e98")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
- import { resolveRuntimeStatusRegistry, statusIsTerminal, EXIT_CODE, PmCliError, toItemRecord, mutateItem, resolvePmRoot, readSettings, resolveAuthor, resolveClaimPrincipal, } from "../runtime-primitives.js";
9
+ import { resolveRuntimeStatusRegistry, statusIsTerminal, EXIT_CODE, PmCliError, toItemRecord, mutateItem, resolvePmRoot, readSettings, resolveAuthor, resolveClaimPrincipal, normalizeStatusForRegistry, } from "../runtime-primitives.js";
10
10
  import { wrapOwnershipConflict } from "../annotations.js";
11
11
  import { describeItemOwnershipConflict } from "../ownership-source.js";
12
12
  import { runNext, } from "../query/next.js";
@@ -226,12 +226,18 @@ export async function runRelease(id, force, global, options = {}) {
226
226
  principal: claimPrincipal,
227
227
  itemId: result.item.id,
228
228
  });
229
+ const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
230
+ const stillInProgress = normalizeStatusForRegistry(result.item.status, statusRegistry) === normalizeStatusForRegistry(statusRegistry.in_progress_status, statusRegistry);
229
231
  return {
230
232
  item: toItemRecord(result.item),
231
233
  released_by: author,
232
234
  previous_assignee: previousAssignee,
233
235
  forced: force,
236
+ ...(stillInProgress ? {
237
+ warnings: ["released_unclaimed_in_progress"],
238
+ suggestions: [`${result.item.id} remains ${result.item.status} and unclaimed. If work is paused, run pm pause-task ${result.item.id} to move it to ${statusRegistry.open_status}.`],
239
+ } : {}),
234
240
  };
235
241
  }
236
242
  //# sourceMappingURL=claim.js.map
237
- //# debugId=1a61bf25-e320-5adc-8f5a-a427bc89af1a
243
+ //# debugId=a4d95016-05b9-5272-8044-2649da644e98
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @module sdk/lifecycle/close
3
+ *
4
+ * Implements the pm close command surface and its agent-facing runtime behavior.
5
+ */
6
+ import type { PmCliErrorRecoveryPayload } from "../../core/shared/errors.js";
1
7
  import { type GlobalOptions } from "../runtime-primitives.js";
2
8
  import { collectBlockedByIds } from "../actionability.js";
3
9
  import { type CloseOperationOptions, type CloseOperationResult } from "../lifecycle-policy.js";
@@ -28,6 +34,8 @@ export interface CloseResult {
28
34
  item: Record<string, unknown>;
29
35
  /** Changed metadata fields. */
30
36
  changed_fields: string[];
37
+ /** Evidence-only update guidance when acceptance fields are missing. */
38
+ recovery?: PmCliErrorRecoveryPayload;
31
39
  /** Validation and lifecycle receipts. */
32
40
  warnings: string[];
33
41
  }
@@ -1,10 +1,5 @@
1
- /**
2
- * @module sdk/lifecycle/close
3
- *
4
- * Implements the pm close command surface and its agent-facing runtime behavior.
5
- */
6
1
 
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]="9f28f7d8-993b-5201-b606-d1eab0c3ff5c")}catch(e){}}();
2
+ !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]="0e166cbb-ef9c-5016-89a6-07f287e00a2e")}catch(e){}}();
8
3
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
4
  import { toItemRecord, isTerminalStatus, resolveItemTypeRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, PmCliError, buildItemNotFoundError, listAllItemMetadataLight, locateItem, mutateItem, readLocatedItem, resolvePmRoot, readSettings, resolveAuthor, resolveIsoOrRelative, shouldCompletePlanOnClose, getActiveExtensionRegistrations, } from "../runtime-primitives.js";
10
5
  import { collectBlockedByIds, indexBlockedByIds } from "../actionability.js";
@@ -47,6 +42,16 @@ function findMissingCloseValidationFields(itemMetadata) {
47
42
  }
48
43
  return missing;
49
44
  }
45
+ /** Build an argv-safe update that appends acceptance evidence without repeating a terminal transition. */
46
+ function closeEvidenceRecovery(metadata, pmRoot, options = {}) {
47
+ const missing = findMissingCloseValidationFields(metadata);
48
+ if (missing.length === 0)
49
+ return undefined;
50
+ const values = { resolution: options.resolution, expected_result: options.expectedResult, actual_result: options.actualResult };
51
+ const missingFlags = missing.map((field) => `--${field.key.replaceAll("_", "-")}`);
52
+ const args = ["--pm-path", pmRoot, "update", metadata.id, ...missing.flatMap((field, index) => [missingFlags[index], values[field.key]?.trim() || "<value>"])];
53
+ return { missing: missingFlags, suggested_retry: renderPmCommand(args), suggested_retry_args: args };
54
+ }
50
55
  async function duplicateChainReferencesClosingItem(loadItemById, initialDuplicateOf, closingId) {
51
56
  const visited = new Set();
52
57
  let current = initialDuplicateOf;
@@ -317,10 +322,11 @@ function clearCloseAssignee(metadata) {
317
322
  delete metadata.assignee;
318
323
  return ["assignee"];
319
324
  }
325
+ /** Enforce terminal and closure policies before applying acceptance fields and the atomic lifecycle transition. */
320
326
  function mutateCloseMetadata(metadata, context) {
321
327
  if (isTerminalStatus(metadata.status, context.statusRegistry) &&
322
328
  !context.force) {
323
- throw new PmCliError(`Item ${metadata.id} is already terminal; use --force to close again.`, EXIT_CODE.CONFLICT);
329
+ throw new PmCliError(`Item ${metadata.id} is already terminal; use pm update to append acceptance evidence, or --force only for an intentional repeat closure.`, EXIT_CODE.CONFLICT, { recovery: closeEvidenceRecovery(metadata, context.pmRoot, context.options) });
324
330
  }
325
331
  const inlineChangedFields = applyInlineCloseFields(metadata, context.options);
326
332
  const duplicateFallbackFields = applyDuplicateCloseMetadata(metadata, context.duplicateOf);
@@ -444,9 +450,11 @@ export async function closeItem(id, closeReasonText, options, global) {
444
450
  });
445
451
  },
446
452
  });
453
+ const recovery = validateCloseMode === "warn" ? closeEvidenceRecovery(result.item, pmRoot) : undefined;
447
454
  return {
448
455
  item: toItemRecord(result.item),
449
456
  changed_fields: result.changedFields,
457
+ ...(recovery ? { recovery } : {}),
450
458
  warnings: [
451
459
  ...result.warnings,
452
460
  ...(await autoUnblockResolvedDependents(pmRoot, settings, trackerItems, located.id, author, statusRegistry)),
@@ -458,4 +466,4 @@ export function runClose(id, closeReasonText, options, global) {
458
466
  return closeItem(id, closeReasonText, options, global);
459
467
  }
460
468
  //# sourceMappingURL=close.js.map
461
- //# debugId=9f28f7d8-993b-5201-b606-d1eab0c3ff5c
469
+ //# debugId=0e166cbb-ef9c-5016-89a6-07f287e00a2e
@@ -4,7 +4,7 @@
4
4
  * Implements the pm create command surface and its agent-facing runtime behavior.
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]="c9bfbfd4-3d34-5fa7-b264-6bf9ed5f7f81")}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]="44240cea-9996-5f86-acc5-ac0cfa71c586")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { assertNoAmbiguousBareCommaEntry, looksLikeStructuredKeyValueEntry, resolveMutationStdinTokenFields, } from "../../core/item/parse.js";
10
10
  import { removeFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, generateItemId, normalizeItemId, canonicalDocument, normalizeItemMetadata, serializeItemDocument, assertParentReferenceIsNotSelf, isPlaceholderReferenceToken, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, assertNoUnknownCsvKeys, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, shouldResolveMutationStdinTokens, transferMutationStdinTokenPolicy, resolvePriority, getFocusedItem, normalizeStatusInput, isTerminalStatus, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, acquireLock, printError, buildInvalidTypeError, resolveTypeSynonym, collectRuntimeCreateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, EXIT_CODE, ITEM_METADATA_KEY_ORDER, PmCliError, nowIso, resolveIsoOrRelative, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveCommandHandler, runActiveBeforeMutationHooks, runActiveOnWriteHooks, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, listAllItemMetadataLight, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
@@ -24,7 +24,7 @@ import { attachLinkedTestMutationProvenance } from "../test/trust.js";
24
24
  import { COMMON_UNSET_FIELD_DEFINITIONS_AFTER_AUTHOR, COMMON_UNSET_FIELD_DEFINITIONS_BEFORE_AUTHOR, parseCommandUnsetTargets, resolveRuntimeUnsetFieldDefinition, } from "./shared-unset-fields.js";
25
25
  import { ensureEnumValue } from "./recurrence-parsers.js";
26
26
  import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
27
- import { normalizeDependencySeedId, normalizeDependencySourceKind, } from "../dependency-provenance.js";
27
+ import { normalizeDependencySeedId, normalizeItemReference, isExternalDependencyReference, normalizeDependencySourceKind, } from "../dependency-provenance.js";
28
28
  import { resolveCanonicalRelationshipKind } from "../relationships.js";
29
29
  import { supportsCreateExplicitEmpty } from "../agent/create-option-policy.js";
30
30
  import { parseEventEntries, parseReminderEntries, parseTypeOptionEntries, } from "./repeatable-metadata-parsers.js";
@@ -767,9 +767,6 @@ export function requireStringOption(value, flag) {
767
767
  }
768
768
  return normalized;
769
769
  }
770
- function ensurePriority(rawPriority) {
771
- return resolvePriority(rawPriority);
772
- }
773
770
  function mergeCreateOptionsWithTemplate(templateOptions, explicitOptions) {
774
771
  const merged = {};
775
772
  for (const [key, value] of Object.entries(templateOptions)) {
@@ -847,9 +844,6 @@ async function loadCreateTemplateOptionsFromRuntime(templateName, global, pmRoot
847
844
  /* c8 ignore next -- template runtime success path is covered by package-level integration tests. */
848
845
  return readTemplateOptionsFromRuntimeResult(handlerResult.result, templateName);
849
846
  }
850
- function ensureInitHasRun(pmRoot) {
851
- return assertInitializedTracker(pmRoot);
852
- }
853
847
  /**
854
848
  * Resolve an optional string item-metadata field for {@link runCreate}: yields
855
849
  * `undefined` when the field is being cleared via `--unset <key>` or was never
@@ -913,7 +907,10 @@ async function inheritFocusedParent(parent, resolvedOptions, unsetKeys, pmRoot)
913
907
  }
914
908
  /** Normalize and locate a new item's parent reference, returning the normalized value plus any never-blocking missing-parent warnings the configured `parent_reference` policy produces when the target does not resolve. */
915
909
  async function validateCreateParentReference(pmRoot, settings, typeRegistry, itemId, parent, policy) {
916
- const normalized = normalizeParentReferenceValue(parent);
910
+ const normalized = normalizeItemReference(normalizeParentReferenceValue(parent), settings.id_prefix);
911
+ if (isExternalDependencyReference(normalized)) {
912
+ return { parent: normalized, warnings: [] };
913
+ }
917
914
  assertParentReferenceIsNotSelf(itemId, normalized, settings.id_prefix);
918
915
  const parentLocated = await locateItem(pmRoot, normalized, settings.id_prefix, settings.item_format, typeRegistry.type_to_folder);
919
916
  if (parentLocated) {
@@ -1618,7 +1615,7 @@ async function writeCreatedItem(params) {
1618
1615
  export async function runCreate(options, global) {
1619
1616
  let resolvedOptions = normalizeLegacyNoneCreateOptions(await resolveCreateTransportInputs(options));
1620
1617
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
1621
- await ensureInitHasRun(pmRoot);
1618
+ await assertInitializedTracker(pmRoot);
1622
1619
  const settings = await readSettings(pmRoot);
1623
1620
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
1624
1621
  const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
@@ -1683,7 +1680,7 @@ export async function runCreate(options, global) {
1683
1680
  ? parseStatusValue(resolvedOptions.status, statusRegistry)
1684
1681
  : resolveCreateDefaultStatus(typeDefinition, statusRegistry);
1685
1682
  const priority = resolvedOptions.priority !== undefined
1686
- ? ensurePriority(resolvedOptions.priority)
1683
+ ? resolvePriority(resolvedOptions.priority)
1687
1684
  : 2;
1688
1685
  const unsetKeys = unsetTargets.metadataKeys;
1689
1686
  const tags = resolveCreateTags(unsetKeys, resolvedOptions);
@@ -1950,4 +1947,4 @@ export const _testOnlyCreateCommand = {
1950
1947
  typeOptionExampleValue,
1951
1948
  };
1952
1949
  //# sourceMappingURL=create.js.map
1953
- //# debugId=c9bfbfd4-3d34-5fa7-b264-6bf9ed5f7f81
1950
+ //# debugId=44240cea-9996-5f86-acc5-ac0cfa71c586
@@ -25,6 +25,7 @@ export interface RestoreResult {
25
25
  kind: "version" | "timestamp";
26
26
  target: string;
27
27
  history_index: number;
28
+ version: number | null;
28
29
  entry_ts: string;
29
30
  entry_op: string;
30
31
  };
@@ -4,13 +4,22 @@
4
4
  * Implements the SDK-owned restore lifecycle operation shared by every surface.
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]="db5f3a6d-9ae5-5f9b-bedf-766b2b79324c")}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]="7a3effef-6ba8-51ba-ae99-436d4ef69813")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import jsonPatch from "fast-json-patch";
10
10
  import fs from "node:fs/promises";
11
- import { pathExists, readFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, enforceHistoryStreamPolicyForItem, normalizeItemId, normalizeRawItemId, canonicalDocument, serializeItemDocument, resolveItemTypeRegistry, acquireLock, EXIT_CODE, PmCliError, nowIso, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveOnWriteHooks, runActiveBeforeMutationHooks, locateItem, createMutationGuardSdk, readLocatedItem, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
11
+ import { readLocatedItemSnapshot } from "../../core/store/item-store.js";
12
+ import { historyVersionOffset } from "../../core/history/version-address.js";
13
+ import { pathExists, readFileIfExists, writeFileAtomic, appendHistoryEntry, createHistoryEntry, replayToCanonicalItemDocument, replayToItemDocument, toReplayDocument, enforceHistoryStreamPolicyForItem, normalizeItemId, normalizeRawItemId, canonicalDocument, serializeItemDocument, resolveItemTypeRegistry, acquireLock, EXIT_CODE, PmCliError, nowIso, getActiveExtensionRegistrations, projectAfterCommandItemSnapshot, recordAfterCommandAffectedItem, runActiveOnWriteHooks, runActiveBeforeMutationHooks, locateItem, createMutationGuardSdk, getHistoryPath, getItemPath, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
12
14
  import { applyHistoryPatch, ensureMaterializedHistoryTarget as ensureMaterializedRestoreTarget, extractPatchFailureContext, readHistoryEntries, replayHistoryToTarget as replayToTarget, resolveHistoryTarget, } from "../history-read.js";
13
15
  import { acquireItemMetadataDerivedIndexLock, refreshItemMetadataDerivedIndex, } from "../item-metadata-index.js";
16
+ /** Read a restore input without discarding unreadable bytes needed for rollback. */
17
+ async function readRestoreItem(located, settings, history) {
18
+ const snapshot = await readLocatedItemSnapshot(located, { schema: settings.schema });
19
+ return snapshot.error === null
20
+ ? { raw: snapshot.raw, document: snapshot.document }
21
+ : { raw: snapshot.raw, document: replayCurrentDocument(history), recovered: true };
22
+ }
14
23
  /** Resolve restore targets with the command's established wording and at-or-before timestamp semantics. */
15
24
  function ensureReplayTarget(target, history) {
16
25
  return resolveHistoryTarget(target, history, {
@@ -82,6 +91,7 @@ function changedFields(beforeDocument, afterDocument) {
82
91
  }
83
92
  return Array.from(fields).sort((a, b) => a.localeCompare(b));
84
93
  }
94
+ /** Reload item and history under the caller's lock, refusing changes since the recovery snapshot. */
85
95
  async function loadRestoreStateUnderLock(params) {
86
96
  const historyRawUnderLock = await readFileIfExists(params.subject.historyPath);
87
97
  if (historyRawUnderLock !== params.historyRawBeforeLock) {
@@ -89,9 +99,7 @@ async function loadRestoreStateUnderLock(params) {
89
99
  }
90
100
  const locatedUnderLock = await locateItem(params.pmRoot, params.resolvedId, params.settings.id_prefix, params.settings.item_format, params.typeToFolder);
91
101
  const loadedItemUnderLock = locatedUnderLock
92
- ? await readLocatedItem(locatedUnderLock, {
93
- schema: params.settings.schema,
94
- })
102
+ ? await readRestoreItem(locatedUnderLock, params.settings, params.history)
95
103
  : null;
96
104
  if ((loadedItemUnderLock?.raw ?? null) !== params.currentItemRawBeforeLock) {
97
105
  throw new PmCliError(`Item ${params.resolvedId} changed while waiting for lock; retry restore.`, EXIT_CODE.CONFLICT);
@@ -183,7 +191,7 @@ export async function runRestore(id, target, options, global) {
183
191
  throw new PmCliError(`Restore target resolved to item ${restoredDocument.metadata.id}, expected ${resolvedId}.`, EXIT_CODE.GENERIC_FAILURE);
184
192
  }
185
193
  const loadedItemBeforeLock = subject.located
186
- ? await readLocatedItem(subject.located, { schema: settings.schema })
194
+ ? await readRestoreItem(subject.located, settings, history)
187
195
  : null;
188
196
  const currentItemRawBeforeLock = loadedItemBeforeLock?.raw ?? null;
189
197
  const author = resolveAuthor(options.author, settings.author_default);
@@ -197,6 +205,7 @@ export async function runRestore(id, target, options, global) {
197
205
  typeToFolder: typeRegistry.type_to_folder,
198
206
  historyRawBeforeLock,
199
207
  currentItemRawBeforeLock,
208
+ history,
200
209
  });
201
210
  const itemFormat = "toon";
202
211
  const currentState = resolveRestoreCurrentState(loadedItemUnderLock, history);
@@ -282,17 +291,20 @@ export async function runRestore(id, target, options, global) {
282
291
  changed_fields: restoreChangedFields,
283
292
  });
284
293
  const targetEntry = history[resolvedTarget.historyIndex];
294
+ const offset = historyVersionOffset(history, true);
285
295
  return {
286
296
  item: restoredDocument.metadata,
287
297
  restored_from: {
288
298
  kind: resolvedTarget.kind,
289
299
  target: resolvedTarget.raw,
290
300
  history_index: resolvedTarget.historyIndex + 1,
301
+ version: offset === null ? null : offset + resolvedTarget.historyIndex + 1,
291
302
  entry_ts: targetEntry.ts,
292
303
  entry_op: targetEntry.op,
293
304
  },
294
305
  changed_fields: restoreChangedFields,
295
306
  warnings: [
307
+ ...(loadedItemUnderLock?.recovered ? ["restore_unreadable_item_recovered"] : []),
296
308
  ...subject.historyPolicyWarnings,
297
309
  ...ownershipWarnings,
298
310
  ...derivedIndexWarnings,
@@ -316,4 +328,4 @@ export const _testOnlyRestoreCommand = {
316
328
  resolveRestoreSubject,
317
329
  };
318
330
  //# sourceMappingURL=restore.js.map
319
- //# debugId=db5f3a6d-9ae5-5f9b-bedf-766b2b79324c
331
+ //# debugId=7a3effef-6ba8-51ba-ae99-436d4ef69813
@@ -4,7 +4,7 @@
4
4
  * Implements the pm update command surface and its agent-facing runtime behavior.
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]="78f8b369-1802-555d-a8cc-0147c0d8fb08")}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]="5a6614ac-62fd-5680-9eed-447bfb7a167f")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { resolveMutationStdinTokenFields } from "../../core/item/parse.js";
10
10
  import { COMMON_MUTATION_COMMAND_OPTION_KEYS, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, normalizeItemId, toItemRecord, buildInvalidTypeError, assertParentReferenceIsNotSelf, normalizeParentReferenceValue, validateMissingParentReference, validateSprintOrReleaseValue, applyAcceptanceCriteriaMutations, applyTagRemovals, assertNoUnknownCsvKeys, looksLikeGenericKeyValueEntry, mergeAdditiveTags, parseCsvKv, parseOptionalNonNegativeInteger, parseOptionalNumber, parseTags, shouldResolveMutationStdinTokens, transferMutationStdinTokenPolicy, splitAcceptanceCriteria, resolvePriority, normalizeStatusInput, isTerminalStatus, collectRuntimeUpdateFieldValues, resolveItemTypesFilePath, resolveRuntimeFieldRegistry, resolveRuntimeStatusRegistry, describeAllowedTransitions, evaluateTransition, resolveTypeWorkflows, EXIT_CODE, PmCliError, stableValueEquals, resolveIsoOrRelative, getActiveExtensionRegistrations, collectRegisteredItemFieldNames, applyRegisteredItemFieldDefaultsAndValidation, parseRegisteredItemFieldAssignments, buildItemNotFoundError, listAllItemMetadataLight, locateItem, readLocatedItem, resolvePmRoot, readSettings, resolveAuthor, } from "../runtime-primitives.js";
@@ -15,7 +15,7 @@ import { applyLegacyNoneCollectionNormalizers, createLegacyNoneCollectionNormali
15
15
  import { ensureEnumValue as ensureEnum } from "./recurrence-parsers.js";
16
16
  import { parseEventEntries, parseReminderEntries, parseTypeOptionEntries, } from "./repeatable-metadata-parsers.js";
17
17
  import { assertDependencyEdgesAllowed, assertDependencyTargetsResolvable, assertValidBareDependencyFlagValue, } from "../dependency-flag-validation.js";
18
- import { normalizeDependencySeedId, normalizeDependencySourceKind, } from "../dependency-provenance.js";
18
+ import { normalizeDependencySeedId, normalizeItemReference, isExternalDependencyReference, normalizeDependencySourceKind, } from "../dependency-provenance.js";
19
19
  import { resolveCanonicalRelationshipKind } from "../relationships.js";
20
20
  import { collectNewOrderingCycleWarnings } from "../graph/mutation-advisory.js";
21
21
  import { assertHierarchyMutationAllowed } from "../graph/hierarchy-integrity.js";
@@ -619,9 +619,6 @@ function matchesDependencySelector(value, selector) {
619
619
  }
620
620
  return true;
621
621
  }
622
- function ensurePriority(raw) {
623
- return resolvePriority(raw);
624
- }
625
622
  function normalizeUpdatePolicyOptionKey(raw, typeName) {
626
623
  const canonical = canonicalizeCommandOptionKey("update", raw);
627
624
  if (!canonical) {
@@ -1152,9 +1149,6 @@ function assertUpdateHierarchyIntegrity(params) {
1152
1149
  return;
1153
1150
  assertHierarchyMutationAllowed(params.before, params.before.map((item) => item.id === params.document.metadata.id ? params.document.metadata : item), params.document.metadata.id, (status) => isTerminalStatus(status, params.statusRegistry), resolveWorkspaceRelationshipKindRegistry());
1154
1151
  }
1155
- async function assertUpdateTrackerInitialized(pmRoot) {
1156
- await assertInitializedTracker(pmRoot);
1157
- }
1158
1152
  function assertMatchingOrderRank(options) {
1159
1153
  if (options.order !== undefined &&
1160
1154
  options.rank !== undefined &&
@@ -1162,12 +1156,16 @@ function assertMatchingOrderRank(options) {
1162
1156
  throw new PmCliError("--order and --rank must match when both are provided", EXIT_CODE.USAGE);
1163
1157
  }
1164
1158
  }
1159
+ /** Canonicalize local parent input before self/existence checks; preserve explicit remote locators and explicit unsets. */
1165
1160
  async function resolveParentReferenceForUpdate(params) {
1166
1161
  if (params.options.parent === undefined ||
1167
1162
  params.unsetTargets.metadataKeys.has("parent")) {
1168
1163
  return { resolvedParentValue: undefined, warnings: [] };
1169
1164
  }
1170
- const resolvedParentValue = normalizeParentReferenceValue(params.options.parent);
1165
+ const resolvedParentValue = normalizeItemReference(normalizeParentReferenceValue(params.options.parent), params.settings.id_prefix);
1166
+ if (isExternalDependencyReference(resolvedParentValue)) {
1167
+ return { resolvedParentValue, warnings: [] };
1168
+ }
1171
1169
  assertParentReferenceIsNotSelf(params.id, resolvedParentValue, params.settings.id_prefix);
1172
1170
  const parentLocated = await locateItem(params.pmRoot, resolvedParentValue, params.settings.id_prefix, params.settings.item_format, params.typeRegistry.type_to_folder);
1173
1171
  if (parentLocated) {
@@ -1212,6 +1210,7 @@ async function collectWorkflowTransitionWarnings(params) {
1212
1210
  });
1213
1211
  return warning ? [warning] : [];
1214
1212
  }
1213
+ /** Delegate the configured close transition to the closure writer, applying other requested fields first and retaining its evidence. */
1215
1214
  async function routeCloseStatusUpdate(context) {
1216
1215
  if (!context.fieldFlags.status) {
1217
1216
  return undefined;
@@ -1349,11 +1348,12 @@ function applyStatusAndCloseReasonMutations(document, context, previousStatusNor
1349
1348
  applyStatusAndCompletionMutations(document, context, previousStatusNormalized, changedFields);
1350
1349
  applyCloseReasonMutations(document, context, previousStatusNormalized, changedFields);
1351
1350
  }
1351
+ /** Resolve priority and type changes against runtime registries before enforcing type-specific options and recording changed fields. */
1352
1352
  function applyPriorityTypeAndOptions(document, context, changedFields) {
1353
1353
  let activeTypeName = resolveTypeName(document.metadata.type, context.typeRegistry) ??
1354
1354
  document.metadata.type;
1355
1355
  if (context.options.priority !== undefined) {
1356
- document.metadata.priority = ensurePriority(context.options.priority);
1356
+ document.metadata.priority = resolvePriority(context.options.priority);
1357
1357
  changedFields.push("priority");
1358
1358
  }
1359
1359
  if (context.options.type !== undefined) {
@@ -1829,7 +1829,7 @@ function mutateUpdateDocument(document, context) {
1829
1829
  async function runUpdateWithContext(id, options, global, execution = {}) {
1830
1830
  options = await resolveUpdateTransportOptions(options);
1831
1831
  const pmRoot = resolvePmRoot(process.cwd(), global.path);
1832
- await assertUpdateTrackerInitialized(pmRoot);
1832
+ await assertInitializedTracker(pmRoot);
1833
1833
  const settings = await readSettings(pmRoot);
1834
1834
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
1835
1835
  const runtimeFieldRegistry = resolveRuntimeFieldRegistry(settings.schema);
@@ -2134,4 +2134,4 @@ export const _testOnlyUpdateCommand = {
2134
2134
  resolveRuntimeUnsetDefinition: (token, registry) => resolveRuntimeUnsetFieldDefinition(token, "update", registry),
2135
2135
  };
2136
2136
  //# sourceMappingURL=update.js.map
2137
- //# debugId=78f8b369-1802-555d-a8cc-0147c0d8fb08
2137
+ //# debugId=5a6614ac-62fd-5680-9eed-447bfb7a167f
@@ -1,3 +1,4 @@
1
+ import { type PmCliErrorRecoveryPayload } from "../core/shared/errors.js";
1
2
  import type { ItemMetadata } from "../types/index.js";
2
3
  /** The author-controlled field from which a terminal reason was derived. */
3
4
  export type TerminalReasonSource = "explicit" | "duplicate" | "resolution" | "message" | "none";
@@ -37,6 +38,8 @@ export interface CloseOperationResult {
37
38
  item: Record<string, unknown>;
38
39
  /** Metadata fields changed by the transition. */
39
40
  changed_fields: string[];
41
+ /** Evidence-only update guidance when a successful warning close leaves acceptance fields missing. */
42
+ recovery?: PmCliErrorRecoveryPayload;
40
43
  /** Validation and lifecycle policy receipts. */
41
44
  warnings: string[];
42
45
  }
@@ -5,7 +5,7 @@
5
5
  * item enters a terminal lifecycle state.
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]="a7ae3c89-b50b-5e4f-8273-8318bc976d84")}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]="89e3f65e-8455-5921-bcc1-45cf572d8585")}catch(e){}}();
9
9
  import { EXIT_CODE } from "../core/shared/constants.js";
10
10
  import { PmCliError } from "../core/shared/errors.js";
11
11
  /** Default terminal policy shared by CLI, SDK, and MCP operations. */
@@ -118,4 +118,4 @@ export function applyTerminalOrderingPolicy(metadata, policy) {
118
118
  };
119
119
  }
120
120
  //# sourceMappingURL=lifecycle-policy.js.map
121
- //# debugId=a7ae3c89-b50b-5e4f-8273-8318bc976d84
121
+ //# debugId=89e3f65e-8455-5921-bcc1-45cf572d8585
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @module sdk/merge/abandoned-receipts
3
+ * Settles verified restored-origin receipts through an explicit history event.
4
+ */
5
+ import type { GlobalOptions } from "../../core/shared/command-types.js";
6
+ import { type MergeDecisionReceipt } from "./receipts.js";
7
+ /** Preview or record restored-origin dispositions without treating them as applied merges. */
8
+ export declare function settleAbandonedMergeReceipts(params: {
9
+ cwd: string | null;
10
+ receipts: readonly MergeDecisionReceipt[];
11
+ dryRun: boolean;
12
+ author?: string;
13
+ message?: string;
14
+ global: GlobalOptions;
15
+ }): Promise<string[]>;