@unbrained/pm-cli 2026.9.3 → 2026.9.5

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 (228) 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 +52 -0
  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 +15 -6
  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 +6 -2
  21. package/dist/cli-bundle/bundle-manifest.json +154 -154
  22. package/dist/cli-bundle/chunks/{chunk-EDPIS7EB.js → chunk-3HBDTJRK.js} +2 -2
  23. package/dist/cli-bundle/chunks/chunk-66VPKFP2.js +5 -0
  24. package/dist/cli-bundle/chunks/{chunk-Y4PJ6HPK.js → chunk-HUAQITVW.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-DKGP3QLE.js → chunk-IBYREGSP.js} +2 -2
  26. package/dist/cli-bundle/chunks/chunk-LUI4E32I.js +231 -0
  27. package/dist/cli-bundle/chunks/{chunk-UPPM2FOZ.js → chunk-QPZHQY2O.js} +2 -2
  28. package/dist/cli-bundle/chunks/{chunk-34HASX3S.js → chunk-SF6SM6U5.js} +2 -2
  29. package/dist/cli-bundle/chunks/chunk-SVK5Y64D.js +40 -0
  30. package/dist/cli-bundle/chunks/chunk-V5GBD5KV.js +9 -0
  31. package/dist/cli-bundle/chunks/{chunk-LENC656S.js → chunk-WWAEGW4V.js} +67 -70
  32. package/dist/cli-bundle/chunks/chunk-ZRAQS3UA.js +8 -0
  33. package/dist/cli-bundle/chunks/{register-list-query-W2ZTOMKP.js → register-list-query-AYKGODWT.js} +3 -3
  34. package/dist/cli-bundle/chunks/{register-mutation-RVND5NCG.js → register-mutation-YZYG53SQ.js} +4 -4
  35. package/dist/cli-bundle/chunks/register-operations-KFSCC7QV.js +2 -0
  36. package/dist/cli-bundle/chunks/{register-setup-D3ZFHY3L.js → register-setup-UJCRVGBG.js} +2 -2
  37. package/dist/cli-bundle/focused-chunks/chunk-24IG6ONG.js +2 -0
  38. package/dist/cli-bundle/focused-chunks/{chunk-M5M6SVHS.js → chunk-3ASU6WGI.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/chunk-3ITLIBKS.js +56 -0
  40. package/dist/cli-bundle/focused-chunks/chunk-3NQD5YDG.js +2 -0
  41. package/dist/cli-bundle/focused-chunks/{chunk-S27XMBIN.js → chunk-4OSHLNUE.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/chunk-65N6JHAN.js +2 -0
  43. package/dist/cli-bundle/focused-chunks/{chunk-5RFXUPN5.js → chunk-B2TTQGFG.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/chunk-GUBM3RGY.js +20 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-Q45NHPF2.js → chunk-H5FOGAVD.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/chunk-JX3RCVCX.js +2 -0
  47. package/dist/cli-bundle/focused-chunks/{chunk-D7KXFBXV.js → chunk-KWWCBWFO.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/chunk-MV752SUC.js +12 -0
  49. package/dist/cli-bundle/focused-chunks/chunk-PKIPMCFS.js +6 -0
  50. package/dist/cli-bundle/focused-chunks/{chunk-4HJFY4MB.js → chunk-QL66QNWG.js} +2 -2
  51. package/dist/cli-bundle/focused-chunks/chunk-RJMR2JIF.js +9 -0
  52. package/dist/cli-bundle/focused-chunks/chunk-WIUPWIZR.js +177 -0
  53. package/dist/cli-bundle/focused-chunks/chunk-WOCIPMW7.js +2 -0
  54. package/dist/cli-bundle/focused-chunks/{chunk-GT7MXDLW.js → chunk-YEF5PQQ2.js} +2 -2
  55. package/dist/cli-bundle/main.js +22 -15
  56. package/dist/cli-bundle/sdk-authoring.js +1 -1
  57. package/dist/cli-bundle/sdk-contracts.js +1 -1
  58. package/dist/cli-bundle/sdk-core.js +29 -32
  59. package/dist/cli-bundle/sdk-governance.js +1 -1
  60. package/dist/cli-bundle/sdk-graph.js +1 -1
  61. package/dist/cli-bundle/sdk-merge.js +45 -37
  62. package/dist/cli-bundle/sdk-query.js +1 -1
  63. package/dist/cli-bundle/sdk-runtime.js +1 -1
  64. package/dist/cli-bundle/sdk-testing.js +1 -1
  65. package/dist/cli-bundle/sdk.js +10 -10
  66. package/dist/core/diagnostics/remediation.js +4 -4
  67. package/dist/core/extensions/extension-types.d.ts +2 -0
  68. package/dist/core/extensions/extension-types.js +2 -2
  69. package/dist/core/history/drift-scan.d.ts +5 -0
  70. package/dist/core/history/drift-scan.js +16 -6
  71. package/dist/core/history/event-classification.d.ts +1 -1
  72. package/dist/core/history/event-classification.js +3 -2
  73. package/dist/core/history/history.d.ts +37 -1
  74. package/dist/core/history/history.js +311 -59
  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 +70 -36
  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/lock/lock.d.ts +10 -0
  91. package/dist/core/lock/lock.js +42 -3
  92. package/dist/core/shared/author.d.ts +3 -1
  93. package/dist/core/shared/author.js +111 -23
  94. package/dist/core/shared/errors.d.ts +8 -0
  95. package/dist/core/shared/errors.js +2 -2
  96. package/dist/core/store/item-store.d.ts +14 -0
  97. package/dist/core/store/item-store.js +48 -10
  98. package/dist/core/store/settings-validator.js +3 -2
  99. package/dist/sdk/actionability.d.ts +1 -1
  100. package/dist/sdk/actionability.js +3 -3
  101. package/dist/sdk/cli-contracts/command-aliases.js +11 -2
  102. package/dist/sdk/cli-contracts/completeness.js +4 -3
  103. package/dist/sdk/cli-contracts/flag-contracts.js +29 -5
  104. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +19 -12
  105. package/dist/sdk/cli-contracts/tool-parameter-tables.js +14 -2
  106. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  107. package/dist/sdk/cli-contracts/tool-schema.js +19 -6
  108. package/dist/sdk/context-intent-contracts.js +3 -3
  109. package/dist/sdk/context-usage.js +9 -11
  110. package/dist/sdk/define.d.ts +1 -1
  111. package/dist/sdk/define.js +2 -2
  112. package/dist/sdk/environment/agent-environment.d.ts +296 -0
  113. package/dist/sdk/environment/agent-environment.js +467 -0
  114. package/dist/sdk/environment/project-runtime-compatibility.d.ts +19 -1
  115. package/dist/sdk/environment/project-runtime-compatibility.js +118 -21
  116. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +98 -38
  117. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -2
  118. package/dist/sdk/governance/health.js +13 -44
  119. package/dist/sdk/governance/merge-receipt-history.d.ts +62 -0
  120. package/dist/sdk/governance/merge-receipt-history.js +207 -0
  121. package/dist/sdk/governance/provenance-health.js +9 -3
  122. package/dist/sdk/governance/validate-history-drift.js +16 -5
  123. package/dist/sdk/guide-topics.js +116 -2
  124. package/dist/sdk/history/salvage.d.ts +35 -0
  125. package/dist/sdk/history/salvage.js +248 -0
  126. package/dist/sdk/history-compact.js +41 -37
  127. package/dist/sdk/history-read.d.ts +3 -2
  128. package/dist/sdk/history-read.js +6 -3
  129. package/dist/sdk/history-redact.js +58 -23
  130. package/dist/sdk/history-repair.d.ts +5 -0
  131. package/dist/sdk/history-repair.js +28 -6
  132. package/dist/sdk/index.d.ts +2 -0
  133. package/dist/sdk/index.js +4 -2
  134. package/dist/sdk/lifecycle/claim.d.ts +4 -0
  135. package/dist/sdk/lifecycle/claim.js +9 -3
  136. package/dist/sdk/lifecycle/restore.d.ts +1 -0
  137. package/dist/sdk/lifecycle/restore.js +19 -7
  138. package/dist/sdk/merge/driver.d.ts +3 -1
  139. package/dist/sdk/merge/driver.js +9 -9
  140. package/dist/sdk/merge/index.d.ts +1 -1
  141. package/dist/sdk/merge/index.js +3 -3
  142. package/dist/sdk/merge/receipts.d.ts +17 -6
  143. package/dist/sdk/merge/receipts.js +246 -75
  144. package/dist/sdk/merge/reconcile.d.ts +9 -7
  145. package/dist/sdk/merge/reconcile.js +175 -12
  146. package/dist/sdk/merge/three-way.d.ts +22 -2
  147. package/dist/sdk/merge/three-way.js +92 -25
  148. package/dist/sdk/output-projection.d.ts +3 -1
  149. package/dist/sdk/output-projection.js +11 -3
  150. package/dist/sdk/public-surface.json +1 -0
  151. package/dist/sdk/query/context.d.ts +9 -0
  152. package/dist/sdk/query/context.js +33 -21
  153. package/dist/sdk/query/get.d.ts +2 -2
  154. package/dist/sdk/query/get.js +4 -3
  155. package/dist/sdk/query/history.d.ts +11 -0
  156. package/dist/sdk/query/history.js +34 -10
  157. package/dist/sdk/query/next.d.ts +15 -1
  158. package/dist/sdk/query/next.js +43 -20
  159. package/dist/sdk/query.d.ts +1 -0
  160. package/dist/sdk/query.js +3 -2
  161. package/dist/sdk/runtime-primitives.d.ts +3 -3
  162. package/dist/sdk/runtime-primitives.js +5 -5
  163. package/dist/types.d.ts +27 -0
  164. package/dist/types.js +2 -2
  165. package/docs/AGENT_ENVIRONMENTS.md +47 -0
  166. package/docs/AGENT_GUIDE.md +36 -0
  167. package/docs/AGENT_PROVENANCE_ADR.md +17 -2
  168. package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +38 -1
  169. package/docs/HISTORY_RECOVERY.md +146 -0
  170. package/docs/MERGE_SAFETY.md +119 -23
  171. package/docs/README.md +2 -0
  172. package/docs/RELEASING.md +25 -11
  173. package/docs/SDK_CONTEXT_EVIDENCE_CONTRACTS.md +24 -2
  174. package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +24 -1
  175. package/docs/SDK_EXECUTION_CONTRACTS.md +105 -0
  176. package/docs/SDK_RUNTIME_BOUNDARIES.md +17 -1
  177. package/docs/TESTING.md +5 -0
  178. package/docs/agent-task-token-baseline.json +17 -17
  179. package/docs/agent-task-transcripts.json +2 -1
  180. package/docs/examples/sdk-agent-environment/README.md +14 -0
  181. package/docs/examples/sdk-agent-environment/package.json +8 -0
  182. package/docs/examples/sdk-agent-environment/run-agent-environment.mjs +154 -0
  183. package/docs/generated/FLAG_LEXICON_BUDGETS.md +10 -10
  184. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +12 -3
  185. package/marketplace.json +2 -2
  186. package/package.json +5 -6
  187. package/packages/pm-beads/package.json +1 -1
  188. package/packages/pm-calendar/package.json +1 -1
  189. package/packages/pm-command-kit/package.json +1 -1
  190. package/packages/pm-digital-twin/package.json +1 -1
  191. package/packages/pm-governance-audit/package.json +1 -1
  192. package/packages/pm-guide-shell/package.json +1 -1
  193. package/packages/pm-kanban/package.json +1 -1
  194. package/packages/pm-lifecycle-hooks/package.json +1 -1
  195. package/packages/pm-linked-test-adapters/package.json +1 -1
  196. package/packages/pm-search-advanced/package.json +1 -1
  197. package/packages/pm-templates/package.json +1 -1
  198. package/packages/pm-todos/package.json +1 -1
  199. package/packages/pm-vcs/package.json +1 -1
  200. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  201. package/plugins/pm-claude/skills/pm-audit/SKILL.md +2 -2
  202. package/plugins/pm-claude/skills/pm-developer/SKILL.md +2 -2
  203. package/plugins/pm-claude/skills/pm-planner/SKILL.md +2 -2
  204. package/plugins/pm-claude/skills/pm-release/SKILL.md +2 -2
  205. package/plugins/pm-claude/skills/pm-workflow/SKILL.md +3 -3
  206. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  207. package/plugins/pm-codex/skills/pm-auditor/SKILL.md +2 -2
  208. package/plugins/pm-codex/skills/pm-native/SKILL.md +3 -4
  209. package/plugins/pm-codex/skills/pm-release/SKILL.md +2 -2
  210. package/scripts/finalize-build.mjs +13 -1
  211. package/dist/cli-bundle/chunks/chunk-AY324UJ5.js +0 -9
  212. package/dist/cli-bundle/chunks/chunk-E5RBBCXO.js +0 -230
  213. package/dist/cli-bundle/chunks/chunk-IEHHE6GA.js +0 -5
  214. package/dist/cli-bundle/chunks/chunk-L7B7343B.js +0 -8
  215. package/dist/cli-bundle/chunks/chunk-LISESA7W.js +0 -35
  216. package/dist/cli-bundle/chunks/register-operations-TTROIVC4.js +0 -2
  217. package/dist/cli-bundle/focused-chunks/chunk-3ZBI35HU.js +0 -176
  218. package/dist/cli-bundle/focused-chunks/chunk-4RRHC3S4.js +0 -6
  219. package/dist/cli-bundle/focused-chunks/chunk-4WR46RMG.js +0 -9
  220. package/dist/cli-bundle/focused-chunks/chunk-BWKHEIVF.js +0 -2
  221. package/dist/cli-bundle/focused-chunks/chunk-GHCZ3YFR.js +0 -20
  222. package/dist/cli-bundle/focused-chunks/chunk-KBLZRU62.js +0 -2
  223. package/dist/cli-bundle/focused-chunks/chunk-KZ2NB3ET.js +0 -2
  224. package/dist/cli-bundle/focused-chunks/chunk-OL5EH6I3.js +0 -2
  225. package/dist/cli-bundle/focused-chunks/chunk-QKHCSUGJ.js +0 -51
  226. package/dist/cli-bundle/focused-chunks/chunk-TXE4TSHM.js +0 -12
  227. package/dist/cli-bundle/focused-chunks/chunk-UCLO3XDU.js +0 -2
  228. package/sdk/public-surface.json +0 -32524
@@ -5,7 +5,19 @@ Tracked by [pm-wc1r](../.agents/pm/features/pm-wc1r.toon), with the integrity an
5
5
  Lossless receipt health gating is tracked by
6
6
  [pm-baksix](../.agents/pm/issues/pm-baksix.toon), and executable remediation
7
7
  that performs settlement is tracked by
8
- [pm-r0p3at](../.agents/pm/issues/pm-r0p3at.toon).
8
+ [pm-r0p3at](../.agents/pm/issues/pm-r0p3at.toon). Immutable record sealing and
9
+ retained re-anchor evidence are tracked by
10
+ [pm-javbsq](../.agents/pm/issues/pm-javbsq.toon) and
11
+ [pm-aka8m7](../.agents/pm/issues/pm-aka8m7.toon); preferred-era receipt-summary
12
+ compatibility is tracked by
13
+ [pm-wn3ee5](../.agents/pm/issues/pm-wn3ee5.toon).
14
+ Lossless concurrent acceptance-criteria composition is tracked by
15
+ [pm-inn5y5](../.agents/pm/issues/pm-inn5y5.toon).
16
+ Recency-aware scalar convergence, bounded fresh-clone decision evidence, and
17
+ audited pre-durable receipt dispositions are tracked by
18
+ [pm-7wzb6d](../.agents/pm/issues/pm-7wzb6d.toon),
19
+ [pm-mg13iz](../.agents/pm/issues/pm-mg13iz.toon), and
20
+ [pm-cf4t42](../.agents/pm/issues/pm-cf4t42.toon).
9
21
 
10
22
  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.
11
23
 
@@ -59,12 +71,12 @@ pm merge install --dry-run --json
59
71
 
60
72
  ## Artifact semantics
61
73
 
62
- | Artifact | Driver | Merge behavior |
63
- | ---------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
- | Item `.toon` / `.md` | `pm-item-toon` / `pm-item-markdown` | Three-way field merge; append-like collections use set union, `updated_at` uses latest timestamp, scalar conflicts select a stable direction-independent value, and canonical serialization recomputes TOON counts. |
65
- | `history/*.jsonl` | `pm-history` | Preserves the common prefix and both divergent suffixes, orders deterministically, then re-anchors the resulting hash chain. |
66
- | tracker `**/*.jsonl` except the later `history/*.jsonl` override | `pm-relationship` | Covers default and package-owned custom relationship event paths, unions divergent suffixes by `eventId` (timestamp-ordered, ours-first on ties), and renumbers `sequence` consecutively so the strict-sequence store loader accepts the merged stream. |
67
- | root `settings.json` and nested `**/*.json` | `pm-json` | Recursively merges objects per key. Arrays compose when both branches preserve the base and add distinct entries, so independent extension installs and evaluation additions merge without weakening edit/removal conflict detection. |
74
+ | Artifact | Driver | Merge behavior |
75
+ | ---------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76
+ | Item `.toon` / `.md` | `pm-item-toon` / `pm-item-markdown` | Three-way field merge; append-like collections use set union, `updated_at` uses the latest timestamp, scalar conflicts select the value from the later document update with stable value order as an equal-timestamp tie-break, and canonical serialization recomputes TOON counts. |
77
+ | `history/*.jsonl` | `pm-history` | Preserves the common prefix and both divergent suffixes, orders deterministically, then re-anchors the resulting hash chain. |
78
+ | tracker `**/*.jsonl` except the later `history/*.jsonl` override | `pm-relationship` | Covers default and package-owned custom relationship event paths, unions divergent suffixes by `eventId` (timestamp-ordered, ours-first on ties), and renumbers `sequence` consecutively so the strict-sequence store loader accepts the merged stream. |
79
+ | root `settings.json` and nested `**/*.json` | `pm-json` | Recursively merges objects per key. Arrays compose when both branches preserve the base and add distinct entries, so independent extension installs and evaluation additions merge without weakening edit/removal conflict detection. |
68
80
 
69
81
  The `tests` collection has an additional execution-safety rule. Its semantic
70
82
  identity excludes provenance so the same command/context does not duplicate
@@ -80,17 +92,50 @@ boundary for append-like data that becomes executable after a merge; ordinary
80
92
  notes, files, and other non-executable collections retain normal set-union
81
93
  behavior.
82
94
 
83
- When both sides change the same item scalar differently, the driver writes the same stable value regardless of which branch Git labels ours or theirs, but exits nonzero. Item results and receipts expose the caller's `requested_preference`; the per-decision `retained` and `discarded` values or hashes are authoritative because stable value order can retain either side. Readers normalize the legacy receipt key `preferred`, while new receipts no longer emit it. JSON leaf conflicts retain the explicit preferred-side policy. Git keeps either path conflicted so a human or coordinating agent must review the discarded value and explicitly `git add` the resolution. This correction is tracked by [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon).
95
+ Although `acceptance_criteria` is serialized as a semicolon-delimited scalar
96
+ for backward compatibility, the item driver treats its parsed criteria as a
97
+ collection. Independent additions compose in branch order, removals made by
98
+ either side remain removed, the field is reported in `union_fields`, and a
99
+ lossless merge does not create a scalar conflict decision. This gives repeated
100
+ `pm update --add-ac` mutations the same multi-branch preservation guarantee as
101
+ native append-like metadata without a storage migration.
102
+
103
+ When both sides change the same item scalar differently, the driver retains the
104
+ value from the document with the later `metadata.updated_at` timestamp. Equal
105
+ timestamps fall back to stable value ordering, so reversing Git's ours/theirs
106
+ labels still converges to the same result. Item results, driver results, and
107
+ receipts expose `conflict_resolution: latest_document_update` and
108
+ `requested_preference_applied: false`; each conflict decision adds
109
+ `retained_side` and `resolution_basis` so review automation can distinguish a
110
+ recency decision from the stable tie-break. The caller's
111
+ `requested_preference` remains observable but does not override item scalar
112
+ convergence. Readers continue to accept legacy `preferred_side` and
113
+ `stable_value_order` receipts and normalize the legacy `preferred` key. JSON
114
+ leaf conflicts retain their explicit preferred-side policy. Git keeps the item
115
+ path conflicted so a human or coordinating agent must review the discarded
116
+ value and explicitly `git add` the resolution.
117
+
118
+ The exact object `{ "pm_item_scalar_missing": true }` is reserved for
119
+ JSON-stable missing-value evidence. Item merge inputs reject that object as a
120
+ present metadata value, while the hashing primitive independently separates
121
+ present and missing domains. This prevents extension data from impersonating a
122
+ deletion without wrapping every ordinary scalar in receipt output.
84
123
 
85
124
  The driver result's `guidance` always points unresolved conflicts to `pm merge report`. When a clone-local receipt exists, guidance includes its privacy-safe receipt and item ids for exact correlation; discarded values remain confined to the local receipt and never appear in generic logs or tracker history. Tracked by [pm-fbrz7p](../.agents/pm/issues/pm-fbrz7p.toon).
86
125
 
87
126
  For item conflicts, the driver writes a clone-local receipt below the Git
88
127
  directory and a durable privacy-safe sidecar below `merge-receipts/` in the
89
128
  tracker. The local receipt contains retained and discarded values so recovery
90
- does not depend on a reflog. The tracked sidecar contains only field names and
91
- value hashes, so fresh clones and CI can still fail closed on an unreviewed
92
- decision without publishing either value. When both copies exist the SDK
93
- deduplicates them and prefers the locally recoverable copy:
129
+ does not depend on a reflog. The tracked sidecar applies the versioned
130
+ `bounded_non_sensitive_scalars_v1` policy. Built-in lifecycle statuses,
131
+ priority integers from 0 through 4, bounded risk/confidence/severity ordinals,
132
+ and `null` are stored with both their value and matching hash. All other values
133
+ remain hash-only. `value_availability` distinguishes `bounded_inline`, `mixed`,
134
+ and `hash_only`, while the clone-local receipt remains `clone_local`. This lets
135
+ a fresh-clone reviewer recover ordinary control-plane decisions without
136
+ publishing titles, descriptions, custom statuses, or other potentially private
137
+ content. When both copies exist the SDK deduplicates them and prefers the
138
+ locally recoverable copy:
94
139
 
95
140
  ```bash
96
141
  pm merge report
@@ -108,7 +153,9 @@ that distinction without returning malformed contents.
108
153
  loss-aware contract through `complete`, `invalid_evidence_count`, bounded
109
154
  `invalid_evidence[]`, `invalid_evidence_truncated`, and
110
155
  `clone_local_evidence_resolved`. Each rejected candidate reports a stable
111
- reason plus its `clone_local`, `durable`, or copy-consistency source. A safe
156
+ reason plus its `clone_local`, `durable`, or copy-consistency source. Schema and
157
+ identity failures additionally expose a bounded `validation_error` such as
158
+ `required_fields`, `item_path`, `filename`, or `durable_decisions`. A safe
112
159
  receipt filename is returned as `receipt_id`; unsafe candidate names are
113
160
  represented only by `candidate_name_hash`, and malformed contents are never
114
161
  returned. The detail list is capped at 100 rows while the count remains exact,
@@ -118,13 +165,26 @@ POSIX instead of treating platform-specific `ENOENT`/`ENOTDIR` spellings as
118
165
  equivalent. Full health also cross-checks the privacy-safe receipt summaries in
119
166
  append-only history against valid pending and reconciled evidence. Missing
120
167
  evidence emits `merge_receipt_history_reference_missing:<n>` with bounded item,
121
- history-line, and receipt-id-or-hash coordinates. Its remediation enumerates
122
- the exact references and directs recovery from an authoritative clone or
123
- backup; it never recommends deleting receipts or rewriting history. The CLI
168
+ history-line, and receipt-id-or-hash coordinates. Recover an available receipt
169
+ from an authoritative clone or backup first. For an exact reference whose
170
+ history-event timestamp predates tracked durable receipts, `pm merge reconcile
171
+ --force` can append a `merge_reconcile` audit event containing the original
172
+ item, line, receipt id, timestamp, and the closed
173
+ `legacy_clone_local_only` reason. Health accepts only that exact coordinate and
174
+ reports it through `accepted_missing_merge_receipt_dispositions`; it never
175
+ rewrites or deletes the original history. The audit event must also occur after
176
+ the referenced history line; an earlier event cannot pre-authorize a later
177
+ missing receipt. Missing post-durable evidence remains blocking and cannot be
178
+ dispositioned through this compatibility path. The CLI
124
179
  exits nonzero when evidence is incomplete, even when the valid-receipt count is
125
180
  zero. Current SDK implementations always emit the new field, while its optional
126
181
  type preserves structural compatibility for existing typed adapters and test
127
- fixtures. `runMergeReceiptReport` remains the compatible valid-only report.
182
+ fixtures. A structurally valid preferred-era history summary that contains its
183
+ complete privacy-safe receipt evidence is accepted in place: health counts it
184
+ as `accepted_legacy_merge_receipt_references` and does not demand an external
185
+ receipt file that the older writer never created. Incomplete, contradictory, or
186
+ modern summaries still fail closed. `runMergeReceiptReport` remains the
187
+ compatible valid-only report.
128
188
 
129
189
  ## Cross-branch id collision safety
130
190
 
@@ -165,7 +225,8 @@ Serialized source claims are ignored. Receipt readers validate the complete
165
225
  bounded schema, safe identifiers, filename and item-path identity, timestamps,
166
226
  and bounded decision structure before a sidecar enters health or
167
227
  reconciliation. Reads use size-preflighted, no-follow regular-file descriptors;
168
- durable decisions must retain hash-only values. Qualifying durable-only receipts
228
+ durable decision values must conform to the declared bounded-inline policy or
229
+ remain hash-only. Qualifying durable-only receipts
169
230
  are reloaded from the authoritative store and accepted only after exact canonical
170
231
  item path, declared-field, and merged-value hash verification. Legacy receipts,
171
232
  receipts whose declared fields disagree with their hashes, same-item tampering,
@@ -173,16 +234,19 @@ and drift on unrelated items fail closed to the normal `pm history-repair`
173
234
  guidance. Health indexes authoritative evidence once by item and reconciliation
174
235
  uses the same per-item groups with a fixed receipt-only worker pool, so committed
175
236
  sidecars cannot amplify drift scans into unbounded parallel repair work.
176
- The machine-executable remediation names the apply command because `--dry-run`
177
- returns a successful preview without changing the red health state. Operators
178
- may still run the documented dry-run first; agents that execute the remediation
179
- field verbatim perform the settlement instead of entering a successful no-op
180
- loop.
237
+ The machine-executable remediation for a missing receipt reference names
238
+ `pm merge reconcile --dry-run`. It never publishes `--force` as an executable
239
+ hint: the human-readable summary explains that exact eligible pre-durable
240
+ coordinates may be dispositioned by a separately reviewed force pass. Ordinary
241
+ pending lossless receipts retain their unforced apply remediation.
181
242
  Apply-mode reconciliation repeats the same proof against the exact
182
243
  item snapshot used by the audited history rewrite. The audit event and
183
244
  settlement include only the individually proven receipt id, so one valid receipt
184
245
  cannot authorize an untrusted same-item sibling. Failed or unproven receipts
185
246
  remain pending unless the coordinator explicitly reviews and supplies `--force`.
247
+ Snapshot verification accepts both the current presence-domain digest and the
248
+ legacy version-1 scalar digest, so already-written receipts remain repairable;
249
+ new receipts always use the collision-free presence-domain scheme.
186
250
  Receipts with discarded scalar values retain the distinct
187
251
  `merge_decisions_unreviewed:<n>` finding. Matching authoritative hash proof
188
252
  allows those receipts to settle without `--force`; without qualifying proof,
@@ -192,6 +256,15 @@ an unforced apply command that clears `merge_decisions_unreviewed` when the
192
256
  receipt proves the exact current merged values. This prevents routine repair
193
257
  from hiding unfinished reconciliation while avoiding redundant force for an
194
258
  already-proven canonical snapshot.
259
+ The same `--force` boundary also handles an unrecoverable pre-durable
260
+ clone-local-only history reference. Preview and apply results expose
261
+ `missing_history_references_before`, `legacy_disposition_eligible`,
262
+ `legacy_disposition_recorded`, and `missing_history_references_after`. When
263
+ coordinates exceed the bounded health response, explicit result guidance
264
+ requires repeated dry-run and reviewed force passes until health no longer
265
+ reports truncated coordinate details and the remaining count is zero. An apply
266
+ result cannot return `ok: true` while any missing reference or truncated
267
+ evidence remains.
195
268
  It exits nonzero while either merge-critical validation check is non-green, so
196
269
  CI and explicit post-merge hooks cannot approve unresolved receipts or drift.
197
270
  The apply pass uses the audited history rewrite boundary to append a
@@ -233,6 +306,29 @@ keeps version incompatibility distinct from item corruption and is tracked by
233
306
  [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon) and
234
307
  [pm-2qahia](../.agents/pm/issues/pm-2qahia.toon).
235
308
 
309
+ New history events also carry `record_hash_version` and `record_hash`. Unlike
310
+ the item anchors, the record hash covers the complete immutable event: author
311
+ and agent provenance, timestamp, operation, message, context, patch, item-hash
312
+ epoch, and before/after anchors. A record that carries only one envelope field,
313
+ uses an unsupported record epoch, or changes after sealing fails verification.
314
+ Entries created before this envelope remain readable as explicit
315
+ `item_state_only` coverage; they are not presented as record-authenticated.
316
+
317
+ Every maintenance rewrite verifies a present record hash before changing the
318
+ stream and reseals the output. When anchors or patch representation change, the
319
+ entry's append-only `reanchor_evidence` retains the prior anchors, item epoch,
320
+ patch digest, and prior record envelope. Lenient repair additionally retains
321
+ the complete replaced patch operations. `verifyHistoryRewriteEvidence()`
322
+ reconstructs every available prior envelope and rejects a record that was
323
+ modified and merely resealed after maintenance. Redaction never copies sensitive patch
324
+ values into new evidence: it keeps the digest and drops a retained patch if the
325
+ patch itself matched a redaction rule. Compaction baselines retain the pruned
326
+ entry count and ordered stream digest plus an explicit
327
+ `individual_pruned_entries_require_pre_compaction_stream` limitation. A holder
328
+ of the pre-compaction stream can therefore validate the checkpoint, while the
329
+ post-compaction stream does not falsely claim that it can reconstruct content
330
+ that was intentionally pruned.
331
+
236
332
  ## Delete versus modify policy
237
333
 
238
334
  A delete on one branch and an edit on another is not safely resolvable by a generic file driver. The merged workspace must not silently resurrect the item. `storage_integrity` reports the live document plus delete-terminated history as a hard finding. The coordinator chooses one policy explicitly:
package/docs/README.md CHANGED
@@ -63,6 +63,7 @@ pm guide release --json
63
63
  - [Mutation Integrity](MUTATION_INTEGRITY.md) - shared CLI/SDK/MCP author, secret, append-only disposition, and stale-work guardrails.
64
64
  - [Agent Provenance ADR Amendment](AGENT_PROVENANCE_ADR.md) - extensible model, effort, role, and host provenance with privacy and compatibility boundaries.
65
65
  - [SDK Agent Session and Episode Context](SDK_AGENT_SESSION_CONTEXT.md) - inherited role/topic context, cross-process episode identity, and deterministic history grouping.
66
+ - [SDK Agent Environments](AGENT_ENVIRONMENTS.md) - calibrated observations, total verdicts, isolated episodes, and an executable public-SDK environment.
66
67
  - [Improvement Ledger and History Analytics](IMPROVEMENT_ANALYTICS.md) - audited quantitative observations, live provenance coverage, and bounded observational fleet outcomes.
67
68
  - [Project Assurance Primitives](ASSURANCE.md) - SDK-owned measurements, assertions, lifecycle gates, cost receipts, and durable verdict history shared by CLI and MCP.
68
69
  - [Defect Recurrence and Boundary Evidence](DEFECT_RECURRENCE.md) - captured external samples, structured defect-escape evidence, incremental change-risk indexing, and executable recovery-producer census.
@@ -80,6 +81,7 @@ pm guide release --json
80
81
  - [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md) - source identity, durable migrations, and scoped preflight ownership.
81
82
  - [Extension Author Contracts](EXTENSION_AUTHOR_CONTRACTS.md) - the stability guarantees and contract surface package authors build against.
82
83
  - [SDK](SDK.md) - public import surfaces and typed authoring examples.
84
+ - [SDK execution and recovery contracts](SDK_EXECUTION_CONTRACTS.md): schema-driven scheduling, handoff, and command recovery.
83
85
  - [Multi-Branch Merge Safety](MERGE_SAFETY.md) - semantic tracker merge drivers, post-merge integrity gates, delete/modify policy, and recovery-receipt retention.
84
86
  - [Codex Plugin](CODEX_PLUGIN.md) - native MCP plugin install, tools, skills, and safety notes.
85
87
  - [Native ChatGPT and Codex Plugin Implementation Plan](CHATGPT_CODEX_PLUGIN_IMPLEMENTATION.md) - official-source
package/docs/RELEASING.md CHANGED
@@ -30,7 +30,10 @@ authoritative blocker-recovery run selection by
30
30
  [pm-db8onn](../.agents/pm/issues/pm-db8onn.toon), and queued automatic
31
31
  same-day recovery by [pm-dm2vfz](../.agents/pm/issues/pm-dm2vfz.toon).
32
32
  Bounded Sentry request latency is tracked by
33
- [pm-b9g2cs](../.agents/pm/issues/pm-b9g2cs.toon).
33
+ [pm-b9g2cs](../.agents/pm/issues/pm-b9g2cs.toon), and exact-tag changelog
34
+ stabilization by [pm-e63v1x](../.agents/pm/issues/pm-e63v1x.toon). Dual-phase
35
+ package sizing around Sentry injection is tracked by
36
+ [pm-llbnua](../.agents/pm/issues/pm-llbnua.toon).
34
37
 
35
38
  ## Version Policy
36
39
 
@@ -333,7 +336,12 @@ The static phase includes `pnpm sdk:surface:check`,
333
336
  `pnpm benchmark:transport:check`. The packaging phase runs
334
337
  `pnpm quality:package-artifact`, which evaluates npm's actual packlist against
335
338
  the committed unpacked-size, file-count, required-runtime-file, and forbidden
336
- source-map budgets. Additive SDK exports require a reviewed
339
+ source-map budgets. Release additionally reruns the packlist gate immediately
340
+ after Sentry debug-ID injection and before any Sentry upload or finalization,
341
+ using the separately committed `sentry-injected` ceiling. CI constrains the base
342
+ build, publication constrains the exact mutated artifact users install, and a
343
+ rejected package cannot leave finalized observability artifacts. Additive SDK
344
+ exports require a reviewed
337
345
  snapshot refresh. A removal or semantic signature change fails until the
338
346
  maintainer supplies
339
347
  `pnpm sdk:surface:update -- --acknowledge-breaking "<release rationale>"`;
@@ -353,23 +361,27 @@ git push origin v<version>
353
361
  `.github/workflows/release.yml` runs on `v*.*.*` tags and handles:
354
362
 
355
363
  - full-history checkout
356
- - manual `workflow_dispatch` by tag for recovery. An isolated anonymous exact-version probe keeps already-published recovery on the reviewed dispatch-time `main` source; when the immutable tag exists but npm publication never completed, recovery checks out that exact tagged source and retains the original version guard
364
+ - manual `workflow_dispatch` by tag for recovery. An isolated anonymous exact-version probe keeps already-published recovery on the reviewed dispatch-time `main` source; when the immutable tag exists but npm publication never completed, recovery preserves the reviewed package gate and budget in runner-temporary storage before checking out that exact tagged source. The controls inspect the untouched tagged package without becoming part of it, so recovery applies the current fail-closed distribution policy while retaining the original version guard and immutable package bytes.
357
365
  - pnpm install with frozen lockfile
358
366
  - version policy and tag guard
359
367
  - secret scan
360
368
  - build, clone-local merge-driver installation, typecheck, test, and coverage
361
369
  - generated changelog verification and `pm-changelog` installation before the
362
370
  tracker-bearing static gate, so a clean checkout does not misclassify the
363
- managed extension's linked files as missing. Recovery of an unpublished
364
- immutable tag regenerates only `CHANGELOG.md` with the tagged checkout's
365
- canonical package script and fails if that operation changes any other
366
- tracked source path (apart from managed-extension install metadata).
371
+ managed extension's linked files as missing. Every exact-tag source,
372
+ including an ordinary tag push and recovery of an unpublished immutable tag,
373
+ regenerates only `CHANGELOG.md` with the tagged checkout's canonical package
374
+ script and fails if that operation changes any other tracked source path
375
+ (apart from managed-extension install metadata). Reviewed `main` recovery
376
+ sources retain the non-mutating drift check.
367
377
  - static quality gate (shared complexity, duplication, dead/orphan module, file/folder hygiene, source/exported docstring coverage profile)
368
378
  - temporary-project compatibility gate against latest published tracker data
369
379
  - reliability threshold gate (Sentry severity threshold, bounded to a recent-activity window via `--sentry-window-days` (default `14`, `0` = unbounded) so a stale benign unresolved issue cannot block every scheduled release; Sentry requests use the fail-closed bounded `--sentry-request-timeout-ms` contract (default `120000`, maximum `300000`); `--telemetry-mode` gate policy: `off` | `best-effort` | `required`). Scheduled `auto-release.yml` failures open/update an `Auto Release blocked` GitHub issue so blocked daily releases are never silently skipped.
370
380
  - sandboxed `pm` coverage
371
- - optional Sentry release metadata and sourcemap upload when `SENTRY_AUTH_TOKEN` is configured
372
- - npm pack dry run and npx tarball smoke test
381
+ - a base npm pack dry run, optional Sentry debug-ID injection, a second
382
+ `sentry-injected` packlist budget over the exact publishable bytes, and only
383
+ then optional Sentry release metadata/upload/finalization and the npx tarball
384
+ smoke test
373
385
  - generated release notes from changelog plus sanitized tracker metadata
374
386
  - artifact uploads
375
387
  - `npm publish --access public --provenance --tag latest`, skipped on retry
@@ -458,8 +470,10 @@ Use the npm registry package for maintainer global updates. Do not use `npm inst
458
470
  the existing immutable tag, reapplies the version guard, installs the managed
459
471
  changelog extension, regenerates the package changelog with the tagged
460
472
  checkout's canonical policy under a tracked-path mutation guard, and permits
461
- first publication only from that tagged source. Other registry failures stop
462
- before source selection or publication.
473
+ first publication only from that tagged source. Ordinary tag-push releases
474
+ use the same guarded regeneration because their tag did not exist when the
475
+ release commit's changelog was prepared. Other registry failures stop before
476
+ source selection or publication.
463
477
  - If an immutable published package contains a defect that cannot be repaired
464
478
  by rerunning the same tag workflow, document the incident and ship the code
465
479
  fix in the next UTC day's release.
@@ -1,6 +1,6 @@
1
1
  # SDK Context and Evidence Contracts
2
2
 
3
- Tracked by [pm-gok2km](../.agents/pm/issues/pm-gok2km.toon), [pm-zryb9d](../.agents/pm/issues/pm-zryb9d.toon), [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon), [pm-hfqju5](../.agents/pm/issues/pm-hfqju5.toon), [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon), and [pm-v0a0un](../.agents/pm/issues/pm-v0a0un.toon).
3
+ Tracked by [pm-gok2km](../.agents/pm/issues/pm-gok2km.toon), [pm-zryb9d](../.agents/pm/issues/pm-zryb9d.toon), [pm-qckpnq](../.agents/pm/issues/pm-qckpnq.toon), [pm-hfqju5](../.agents/pm/issues/pm-hfqju5.toon), [pm-2htk4p](../.agents/pm/issues/pm-2htk4p.toon), [pm-v0a0un](../.agents/pm/issues/pm-v0a0un.toon), [pm-7wzb6d](../.agents/pm/issues/pm-7wzb6d.toon), [pm-mg13iz](../.agents/pm/issues/pm-mg13iz.toon), and [pm-cf4t42](../.agents/pm/issues/pm-cf4t42.toon).
4
4
 
5
5
  These contracts keep SDK context truthful, bounded, and reusable across the CLI, MCP, packages, and automation. They are designed around the project principle that project management is context management: a compact response must reveal material omissions, merge evidence must describe what actually survived, and compatibility failures must not masquerade as corruption.
6
6
 
@@ -22,7 +22,29 @@ This keeps health diagnostics and lazy runtime behavior on one ownership contrac
22
22
 
23
23
  ## Merge provenance
24
24
 
25
- Stable-value item merges distinguish a caller request from the outcome. Low-level item results, driver results, clone-local receipts, and privacy-safe summaries expose `requested_preference`. The actual outcome remains in each decision's `retained` and `discarded` values or hashes. New receipts do not emit the ambiguous `preferred` key; readers still ingest legacy schema-v1 receipts and normalize that key to `requested_preference`.
25
+ Item scalar merges distinguish a caller request from the convergent outcome.
26
+ The `latest_document_update` policy selects the branch document with the later
27
+ `metadata.updated_at`; equal timestamps use stable value order. Low-level item
28
+ results, driver results, receipts, and privacy-safe summaries expose
29
+ `requested_preference` plus `requested_preference_applied: false`. Each new
30
+ decision records `retained_side` and `resolution_basis`. New receipts do not
31
+ emit the ambiguous `preferred` key; readers still ingest legacy schema-v1
32
+ receipts and normalize `preferred_side` and `stable_value_order` evidence.
33
+
34
+ Tracked receipt evidence uses `bounded_non_sensitive_scalars_v1`: built-in
35
+ status, priority 0 through 4, risk/confidence/severity ordinals, and `null` may
36
+ be included beside their verifiable hashes. Every other value remains
37
+ hash-only. Fresh-clone consumers must branch on `value_availability` rather than
38
+ assuming raw values exist. Invalid evidence separates `schema_invalid` from
39
+ `identity_invalid` and adds a bounded `validation_error`, while retaining the
40
+ legacy combined reason in the public union for source compatibility.
41
+
42
+ `runMergeReconcile` also reports missing history receipt counts before and
43
+ after the operation. With explicit `force`, it can append a narrowly matched
44
+ audit disposition for a missing reference whose original event predates the
45
+ durable-receipt epoch. The item id, original line, receipt id, and timestamp
46
+ must all match, and the audit event must occur later in that history stream;
47
+ current-era missing evidence remains blocking.
26
48
 
27
49
  ## Claim race classification
28
50
 
@@ -1,7 +1,9 @@
1
1
  # SDK Context Truth Contracts
2
2
 
3
3
  Tracker references: [pm-23xkss](../.agents/pm/issues/pm-23xkss.toon) and
4
- [pm-r8u2g6](../.agents/pm/issues/pm-r8u2g6.toon).
4
+ [pm-r8u2g6](../.agents/pm/issues/pm-r8u2g6.toon),
5
+ [pm-79gv6q](../.agents/pm/issues/pm-79gv6q.toon), and
6
+ [pm-08mt4k](../.agents/pm/issues/pm-08mt4k.toon).
5
7
 
6
8
  ## Agent Quick Context
7
9
 
@@ -68,3 +70,24 @@ silently route tracker files through the wrong merge behavior. Run
68
70
  This policy does not weaken storage, history, merge-fence, or pending-receipt
69
71
  checks. It only distinguishes an optional never-installed clone capability
70
72
  from a broken capability that the repository appears to rely on.
73
+
74
+ ## Population and Focus Are Separate
75
+
76
+ `context.summary.scope` is `matching_items`: lifecycle totals describe all items
77
+ matching the request filters and parent subtree before the focus limit, intent
78
+ projection, and token packing. Without filters this is the workspace population.
79
+ `active_items`, `in_progress`, `open`, and `blocked` use that same population as
80
+ `total_items`, `closed`, and `canceled`. `open` includes active statuses other than
81
+ in-progress; `blocked` is an overlapping classification that includes unresolved
82
+ dependency edges as well as blocked lifecycle states.
83
+
84
+ `summary.returned_focus` reports the bounded focus selection. The existing
85
+ `high_level` and `low_level` counts describe their emitted rows. An orient or
86
+ handoff response limited to one row can therefore still report hundreds of open
87
+ items. `omission_receipt.summary_scope` repeats `matching_items` so a consumer
88
+ reading projection metadata cannot confuse omitted detail with absent work.
89
+
90
+ Never infer a population count from an array length. To visit individual items,
91
+ follow the response's continuation and omission receipts. To schedule work, use
92
+ the shared [execution contracts](SDK_EXECUTION_CONTRACTS.md), which keep human
93
+ input, gates, and containers visible without dispatching them by default.
@@ -0,0 +1,105 @@
1
+ # SDK Execution and Recovery Contracts
2
+
3
+ Tracker references: [pm-08mt4k](../.agents/pm/issues/pm-08mt4k.toon),
4
+ [pm-ugld](../.agents/pm/issues/pm-ugld.toon),
5
+ [pm-2bqgs7](../.agents/pm/issues/pm-2bqgs7.toon),
6
+ [pm-u4t9gp](../.agents/pm/issues/pm-u4t9gp.toon), and
7
+ [pm-bfa1ob](../.agents/pm/issues/pm-bfa1ob.toon).
8
+
9
+ ## Declare Who Can Execute a Type
10
+
11
+ Custom settings definitions and package `defineItemType` definitions accept
12
+ `execution_role: "agent" | "human" | "gate"`. An omitted role defaults to agent
13
+ execution; built-in Decision and Milestone types default to human and gate,
14
+ respectively. A definition can override a built-in role. Aliases resolve through
15
+ the type registry, and invalid roles are rejected rather than silently enabling
16
+ execution.
17
+
18
+ Package authors can declare a review checkpoint alongside the rest of their item
19
+ type definition:
20
+
21
+ ```ts
22
+ import { defineItemType } from "@unbrained/pm-cli/sdk/authoring";
23
+
24
+ export const checkpoint = defineItemType({
25
+ name: "Checkpoint",
26
+ folder: "checkpoints",
27
+ aliases: ["checkpoint"],
28
+ execution_role: "gate",
29
+ });
30
+ ```
31
+
32
+ `computeActionabilityReport` is the pure SDK primitive: it accepts candidates,
33
+ the surrounding item corpus, a status registry, and an optional item type
34
+ registry. It resolves both forward `blocked_by` and reverse `blocks` edges,
35
+ terminal prerequisites, active descendants, and execution roles. Its result
36
+ contains ready leaves, blocked leaves, human decisions, gates, and containers.
37
+ `selectActionableEntries` applies explicit dispatch opt-ins to that report;
38
+ ownership and ranking remain the responsibility of the caller. The selector
39
+ returns `ready`, `decisions`, and `gates`: eligible opted-in containers enter
40
+ `ready`, subject to their execution role. Read `report.containers` for the full
41
+ classified container worklist; the selector does not return a separate
42
+ `containers` property.
43
+
44
+ Integrations that construct an `ActionabilityReport` themselves must now provide
45
+ the `containers`, `decisions`, and `gates` arrays. Prefer computing the report
46
+ through the SDK so these classifications stay consistent with dependency and
47
+ schema rules. Existing callers may omit the new selection options and type
48
+ registry argument.
49
+
50
+ ## Read Every Scheduling Bucket
51
+
52
+ `pm next` exposes `ready`, `decision_needed`, `gate_needed`, `containers`,
53
+ `blocked`, and `held_by_others`. Summary counts describe the full matching
54
+ buckets; each bounded worklist has truncation totals when needed. The row
55
+ contract advertises the new gate and container collections to generic consumers.
56
+ Intent budgets compact these worklists along with the other scheduling rows.
57
+ Final-delivery feedback records their visible identifiers so recursive context
58
+ improvement observes what the caller actually received.
59
+ A workspace containing only outcome gates returns no recommendation and explains
60
+ how to inspect or explicitly include gates.
61
+
62
+ `--include-decisions`, `--include-gates`, and `--include-containers` opt into
63
+ held-out work for both `next` and `claim --next`. The SDK and MCP use
64
+ `includeDecisions`, `includeGates`, and `includeContainers`. These options do not
65
+ bypass unresolved blockers, blocked lifecycle states, or ownership checks.
66
+ Context places gates, human work, and containers in high-level context rather
67
+ than agent execution detail. Population summaries retain all matching work.
68
+
69
+ ## Stop Work Explicitly
70
+
71
+ `release` relinquishes ownership and preserves status. When an in-progress item
72
+ is released (using the configured workflow status), its result includes `released_unclaimed_in_progress` and a concrete
73
+ `pm pause-task <id>` suggestion. Use `pause-task` when the intended operation is
74
+ to stop work and return it to the configured open state. Consumers should not
75
+ interpret an ownership release as evidence that work has stopped.
76
+
77
+ ## Recover from Command Mistakes
78
+
79
+ Unknown commands direct the caller to `pm --help --all`, the complete core
80
+ command surface. `pm tests <id>` is an executable alias of `pm test <id>`.
81
+ Positional item operands are accepted in help requests, including hybrid
82
+ commands such as `pm files <id> --help --json`; invalid child command names still
83
+ produce usage errors.
84
+
85
+ With `--token-accounting`, JSON refusals carry the same serialized-output
86
+ accounting used by successful commands. Accounting is attached after diagnostic
87
+ projection and recalculated if extension failures enrich the refusal. The
88
+ receipt measures the emitted diagnostic, including its own receipt overhead.
89
+ Recovery metadata retains the actual invocation, including the accounting flag.
90
+ The executable transcript gate predicts that transport change independently and
91
+ rejects any other payload drift. It also verifies that the accounting-off
92
+ attempted command agrees with its normalized arguments before projection.
93
+ Detailed recovery evidence must contain argument and provided-field arrays.
94
+ Compact recovery is accepted only when the transcript explicitly declares and
95
+ verifies that mode; its advertised retry still executes as a separate step.
96
+ Serialized JSON refusals use the SDK `writeStderr` transport primitive so an
97
+ `error_format` text override cannot replace a measured machine payload.
98
+ Human-readable error formatting remains customizable through `error_format`.
99
+
100
+ The flag-invocation gate compares registered executable options against SDK
101
+ contracts without filtering out undeclared observations. An option missing from
102
+ the contract and a root command missing a resolver both fail the gate. A seeded
103
+ undeclared option is a mandatory negative control. Contract snapshots, MCP
104
+ parameter declarations, help, and completion are regenerated from the shared
105
+ contract tables.
@@ -2,7 +2,9 @@
2
2
 
3
3
  Tracker: [pm-1eted6](../.agents/pm/issues/pm-1eted6.toon),
4
4
  [pm-3lhth4](../.agents/pm/issues/pm-3lhth4.toon), and
5
- [pm-0xmajx](../.agents/pm/issues/pm-0xmajx.toon). Refusal reachability and
5
+ [pm-0xmajx](../.agents/pm/issues/pm-0xmajx.toon), with forward history-epoch
6
+ protection tracked by
7
+ [pm-aka8m7](../.agents/pm/issues/pm-aka8m7.toon). Refusal reachability and
6
8
  recovery completeness are tracked by
7
9
  [pm-elmpav](../.agents/pm/features/pm-elmpav.toon),
8
10
  [pm-185870](../.agents/pm/issues/pm-185870.toon), and
@@ -29,6 +31,20 @@ package-manager-neutral recovery action. SDK callers receive the same warning
29
31
  inside `ProjectRuntimeCompatibilityResult`. `PM_ALLOW_STALE_CLI=1` is the
30
32
  explicit, auditable emergency override.
31
33
 
34
+ The boundary is bidirectional for history storage. A current runtime also
35
+ refuses a mutation when any package declaration or lockfile pin cannot select a
36
+ runtime that reads the writer epoch. Every manifest section is evaluated, so a
37
+ newer permissive declaration cannot hide an older exact pin. Upper-bounded
38
+ ranges that exclude the first compatible reader also fail closed, including
39
+ inclusive hyphen ranges. Disjunctive ranges evaluate each alternative, so one
40
+ branch that can select a compatible reader keeps the declaration writable. The
41
+ original incompatible declaration is preserved in the diagnostic rather than
42
+ being reduced to its representative lower bound. The typed
43
+ `project_runtime_history_epoch_incompatible` error reports the writer epoch,
44
+ the incompatible declaration, its redaction-safe source, and the minimum
45
+ upgrade. Reads remain available, and the same emergency override is reserved
46
+ for an intentionally coordinated fleet migration.
47
+
32
48
  The public `isProjectMutatingInvocation` classifier applies the same decision
33
49
  to package hosts and the bundled CLI. It resolves mixed command families by
34
50
  their effective action: configuration, merge, schema, profile, package,
package/docs/TESTING.md CHANGED
@@ -146,6 +146,11 @@ boilerplate summaries are rejected.
146
146
 
147
147
  ## TOON Storage Round-Trip Gate
148
148
 
149
+ History-only lifecycle reconstruction and recovery contracts are described in
150
+ [History durability and recovery](HISTORY_RECOVERY.md). Their integration suite
151
+ is part of the required all-source test run and compares historical projections
152
+ against independently captured item files, including after removing those files.
153
+
149
154
  TOON item serialization is a fail-closed storage boundary. Before returning
150
155
  bytes to any create, update, merge, migration, or package caller, pm decodes the
151
156
  new `@toon-format/toon` output and compares it with the JSON-like canonical