@unbrained/pm-cli 2026.9.4 → 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 (190) 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 +26 -1
  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 +153 -153
  22. package/dist/cli-bundle/chunks/{chunk-RI4XNOYS.js → chunk-3HBDTJRK.js} +2 -2
  23. package/dist/cli-bundle/chunks/chunk-66VPKFP2.js +5 -0
  24. package/dist/cli-bundle/chunks/{chunk-I2AS367G.js → chunk-HUAQITVW.js} +2 -2
  25. package/dist/cli-bundle/chunks/{chunk-HI6BHPCU.js → chunk-IBYREGSP.js} +2 -2
  26. package/dist/cli-bundle/chunks/chunk-LUI4E32I.js +231 -0
  27. package/dist/cli-bundle/chunks/{chunk-YW4QK2G7.js → chunk-QPZHQY2O.js} +2 -2
  28. package/dist/cli-bundle/chunks/{chunk-X6CMGV6L.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-V72UV7QS.js → chunk-WWAEGW4V.js} +57 -57
  32. package/dist/cli-bundle/chunks/{chunk-A24WAVE6.js → chunk-ZRAQS3UA.js} +2 -2
  33. package/dist/cli-bundle/chunks/{register-list-query-Z5YYSJJG.js → register-list-query-AYKGODWT.js} +3 -3
  34. package/dist/cli-bundle/chunks/{register-mutation-ELSP6I4I.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-E2AE72QG.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-53IHPICX.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-7N2TV7WZ.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-AJR3OP2E.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-25UJBH4M.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-6PWPQKDN.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-3646BZ4W.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-NBMJD6MK.js → chunk-WOCIPMW7.js} +2 -2
  54. package/dist/cli-bundle/focused-chunks/{chunk-MHKUIPJW.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 -29
  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 +42 -39
  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 +8 -8
  66. package/dist/core/extensions/extension-types.d.ts +2 -0
  67. package/dist/core/extensions/extension-types.js +2 -2
  68. package/dist/core/history/drift-scan.d.ts +5 -0
  69. package/dist/core/history/drift-scan.js +16 -6
  70. package/dist/core/history/event-classification.d.ts +1 -1
  71. package/dist/core/history/event-classification.js +3 -2
  72. package/dist/core/history/history.js +37 -5
  73. package/dist/core/history/identity.d.ts +15 -0
  74. package/dist/core/history/identity.js +31 -0
  75. package/dist/core/history/projection.js +50 -17
  76. package/dist/core/history/read.js +6 -3
  77. package/dist/core/history/replay.d.ts +1 -2
  78. package/dist/core/history/replay.js +4 -4
  79. package/dist/core/history/version-address.d.ts +13 -0
  80. package/dist/core/history/version-address.js +33 -0
  81. package/dist/core/item/actionability.d.ts +21 -1
  82. package/dist/core/item/actionability.js +45 -10
  83. package/dist/core/item/id.js +8 -4
  84. package/dist/core/item/item-type-definition.d.ts +2 -0
  85. package/dist/core/item/item-type-definition.js +9 -2
  86. package/dist/core/item/type-registry.d.ts +5 -1
  87. package/dist/core/item/type-registry.js +9 -4
  88. package/dist/core/shared/errors.d.ts +8 -0
  89. package/dist/core/shared/errors.js +2 -2
  90. package/dist/core/store/item-store.d.ts +14 -0
  91. package/dist/core/store/item-store.js +48 -10
  92. package/dist/core/store/settings-validator.js +3 -2
  93. package/dist/sdk/actionability.d.ts +1 -1
  94. package/dist/sdk/actionability.js +3 -3
  95. package/dist/sdk/cli-contracts/command-aliases.js +11 -2
  96. package/dist/sdk/cli-contracts/completeness.js +4 -3
  97. package/dist/sdk/cli-contracts/flag-contracts.js +29 -5
  98. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +19 -12
  99. package/dist/sdk/cli-contracts/tool-parameter-tables.js +14 -2
  100. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  101. package/dist/sdk/cli-contracts/tool-schema.js +19 -6
  102. package/dist/sdk/context-intent-contracts.js +3 -3
  103. package/dist/sdk/context-usage.js +9 -11
  104. package/dist/sdk/define.d.ts +1 -1
  105. package/dist/sdk/define.js +2 -2
  106. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +98 -50
  107. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -2
  108. package/dist/sdk/governance/validate-history-drift.js +16 -5
  109. package/dist/sdk/guide-topics.js +116 -2
  110. package/dist/sdk/history/salvage.d.ts +35 -0
  111. package/dist/sdk/history/salvage.js +248 -0
  112. package/dist/sdk/history-compact.js +32 -37
  113. package/dist/sdk/history-read.d.ts +3 -2
  114. package/dist/sdk/history-read.js +6 -3
  115. package/dist/sdk/history-repair.d.ts +5 -0
  116. package/dist/sdk/history-repair.js +14 -2
  117. package/dist/sdk/lifecycle/claim.d.ts +4 -0
  118. package/dist/sdk/lifecycle/claim.js +9 -3
  119. package/dist/sdk/lifecycle/restore.d.ts +1 -0
  120. package/dist/sdk/lifecycle/restore.js +19 -7
  121. package/dist/sdk/output-projection.d.ts +3 -1
  122. package/dist/sdk/output-projection.js +11 -3
  123. package/dist/sdk/public-surface.json +1 -0
  124. package/dist/sdk/query/context.d.ts +9 -0
  125. package/dist/sdk/query/context.js +33 -21
  126. package/dist/sdk/query/get.d.ts +2 -2
  127. package/dist/sdk/query/get.js +4 -3
  128. package/dist/sdk/query/history.d.ts +11 -0
  129. package/dist/sdk/query/history.js +34 -10
  130. package/dist/sdk/query/next.d.ts +15 -1
  131. package/dist/sdk/query/next.js +43 -20
  132. package/dist/sdk/query.d.ts +1 -0
  133. package/dist/sdk/query.js +3 -2
  134. package/dist/sdk/runtime-primitives.d.ts +1 -1
  135. package/dist/sdk/runtime-primitives.js +3 -3
  136. package/dist/types.d.ts +2 -0
  137. package/dist/types.js +2 -2
  138. package/docs/AGENT_GUIDE.md +36 -0
  139. package/docs/HISTORY_RECOVERY.md +146 -0
  140. package/docs/README.md +1 -0
  141. package/docs/RELEASING.md +25 -11
  142. package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +24 -1
  143. package/docs/SDK_EXECUTION_CONTRACTS.md +105 -0
  144. package/docs/TESTING.md +5 -0
  145. package/docs/agent-task-token-baseline.json +17 -17
  146. package/docs/agent-task-transcripts.json +2 -1
  147. package/docs/generated/FLAG_LEXICON_BUDGETS.md +10 -10
  148. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +11 -3
  149. package/marketplace.json +2 -2
  150. package/package.json +4 -5
  151. package/packages/pm-beads/package.json +1 -1
  152. package/packages/pm-calendar/package.json +1 -1
  153. package/packages/pm-command-kit/package.json +1 -1
  154. package/packages/pm-digital-twin/package.json +1 -1
  155. package/packages/pm-governance-audit/package.json +1 -1
  156. package/packages/pm-guide-shell/package.json +1 -1
  157. package/packages/pm-kanban/package.json +1 -1
  158. package/packages/pm-lifecycle-hooks/package.json +1 -1
  159. package/packages/pm-linked-test-adapters/package.json +1 -1
  160. package/packages/pm-search-advanced/package.json +1 -1
  161. package/packages/pm-templates/package.json +1 -1
  162. package/packages/pm-todos/package.json +1 -1
  163. package/packages/pm-vcs/package.json +1 -1
  164. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  165. package/plugins/pm-claude/skills/pm-audit/SKILL.md +2 -2
  166. package/plugins/pm-claude/skills/pm-developer/SKILL.md +2 -2
  167. package/plugins/pm-claude/skills/pm-planner/SKILL.md +2 -2
  168. package/plugins/pm-claude/skills/pm-release/SKILL.md +2 -2
  169. package/plugins/pm-claude/skills/pm-workflow/SKILL.md +3 -3
  170. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  171. package/plugins/pm-codex/skills/pm-auditor/SKILL.md +2 -2
  172. package/plugins/pm-codex/skills/pm-native/SKILL.md +3 -4
  173. package/plugins/pm-codex/skills/pm-release/SKILL.md +2 -2
  174. package/scripts/finalize-build.mjs +13 -1
  175. package/dist/cli-bundle/chunks/chunk-6XSKPNCF.js +0 -230
  176. package/dist/cli-bundle/chunks/chunk-OGBVU67G.js +0 -5
  177. package/dist/cli-bundle/chunks/chunk-TXW6VL33.js +0 -38
  178. package/dist/cli-bundle/chunks/chunk-VGLHECAP.js +0 -9
  179. package/dist/cli-bundle/chunks/register-operations-OH7R3ZT4.js +0 -2
  180. package/dist/cli-bundle/focused-chunks/chunk-4YRAVI43.js +0 -12
  181. package/dist/cli-bundle/focused-chunks/chunk-5P4HVOWG.js +0 -176
  182. package/dist/cli-bundle/focused-chunks/chunk-636VVQ7F.js +0 -54
  183. package/dist/cli-bundle/focused-chunks/chunk-B3A6MJYE.js +0 -2
  184. package/dist/cli-bundle/focused-chunks/chunk-BFDDJ2T2.js +0 -2
  185. package/dist/cli-bundle/focused-chunks/chunk-BHUIRZWQ.js +0 -9
  186. package/dist/cli-bundle/focused-chunks/chunk-JADHHPY6.js +0 -6
  187. package/dist/cli-bundle/focused-chunks/chunk-NSKBLHVI.js +0 -20
  188. package/dist/cli-bundle/focused-chunks/chunk-P2GOAOQN.js +0 -2
  189. package/dist/cli-bundle/focused-chunks/chunk-YARWJM2B.js +0 -2
  190. package/sdk/public-surface.json +0 -33034
@@ -7,7 +7,7 @@
7
7
  * prefer the typed operations exported by the main SDK barrel.
8
8
  */
9
9
 
10
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="aba5403c-0694-5c51-95a8-ae7e7575347b")}catch(e){}}();
10
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="619b20e3-78d9-55bd-9d2d-857a3bc1bee8")}catch(e){}}();
11
11
  export { createCheckpointId, loadMutationCheckpoint, restoreCheckpointItems, writeMutationCheckpoint, } from "../core/checkpoint/mutation-checkpoint.js";
12
12
  export { flattenFlagListValue, resolveFlagValueKind, } from "../core/extensions/flag-value-types.js";
13
13
  export { createUnknownSubcommandError, } from "./agent/subcommand-recovery.js";
@@ -36,7 +36,7 @@ export { isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, } f
36
36
  export { COMMON_MUTATION_COMMAND_OPTION_KEYS, canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveCommandOptionPolicyState, resolveItemTypeRegistry, resolveTypeDefinition, resolveTypeName, validateTypeOptions, } from "../core/item/type-registry.js";
37
37
  export { resolveTypeSynonym } from "../core/item/type-synonyms.js";
38
38
  export { acquireLock } from "../core/lock/lock.js";
39
- export { printError, printResult, writeStdout } from "../core/output/output.js";
39
+ export { printError, printResult, writeStderr, writeStdout } from "../core/output/output.js";
40
40
  export { renderRowsAsCsv, renderRowsAsTable } from "../core/output/tabular.js";
41
41
  export { parseLimit } from "../core/shared/numeric-parsers.js";
42
42
  export { resolveConfiguredPmPackageRoot, resolvePmCliVersion, resolvePmPackageRootFromModule, } from "../core/packages/root.js";
@@ -82,4 +82,4 @@ export { maybeRunFirstUseTelemetryPrompt } from "../core/telemetry/consent.js";
82
82
  export { deriveTelemetryCommandResolution, } from "../core/telemetry/observability.js";
83
83
  export { emitTelemetryErrorEvent, finishTelemetryCommand, startTelemetryCommand, } from "../core/telemetry/runtime.js";
84
84
  //# sourceMappingURL=runtime-primitives.js.map
85
- //# debugId=aba5403c-0694-5c51-95a8-ae7e7575347b
85
+ //# debugId=619b20e3-78d9-55bd-9d2d-857a3bc1bee8
package/dist/types.d.ts CHANGED
@@ -428,6 +428,8 @@ export interface ItemTypeDefinition {
428
428
  description?: string;
429
429
  /** Status assigned to newly created items of this type when `--status` is not provided. Falls back to the workflow's open status when unset or invalid. */
430
430
  default_status?: string;
431
+ /** Agent work can be dispatched automatically; human work needs a decision, and gates track outcomes. Omission inherits the built-in role or defaults custom types to agent work. */
432
+ execution_role?: "agent" | "human" | "gate";
431
433
  /** Value that configures or reports folder for this contract. */
432
434
  folder?: string;
433
435
  /** Value that configures or reports aliases for this contract. */
package/dist/types.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /** Supported values accepted by the builtin item type contract. */
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]="4ee067ac-f28d-5411-9ac7-c92112384a64")}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]="8173bdb0-39c8-56c0-85c2-5c39f5c213cc")}catch(e){}}();
9
9
  export const BUILTIN_ITEM_TYPE_VALUES = [
10
10
  "Epic",
11
11
  "Feature",
@@ -243,4 +243,4 @@ export const CONTEXT_SECTION_VALUES = [
243
243
  "tests",
244
244
  ];
245
245
  //# sourceMappingURL=types.js.map
246
- //# debugId=4ee067ac-f28d-5411-9ac7-c92112384a64
246
+ //# debugId=8173bdb0-39c8-56c0-85c2-5c39f5c213cc
@@ -195,6 +195,32 @@ post-merge observations on GitHub without changing repository state when no
195
195
  tracked closeout update is required. See [Releasing](RELEASING.md#reviewed-delivery-closeout)
196
196
  for the release contract.
197
197
 
198
+ ## Review and Analyzer Proof
199
+
200
+ Use the [review helper](../scripts/reviews/pr-review-loop.mjs) to wait for
201
+ terminal checks, then inspect its paginated inventory of comments, reviews,
202
+ inline threads, edits, reactions, and resolution state. Inspect failed-check
203
+ details in the receipt even when the helper itself exits successfully.
204
+
205
+ ```bash
206
+ node scripts/reviews/pr-review-loop.mjs watch --pr <number> --repo unbraind/pm-cli --interval 60
207
+ node scripts/release/hosted-analysis-gate.mjs --repo unbraind/pm-cli --sha <full-40-character-head-sha> --json
208
+ ```
209
+
210
+ Both receipts must pass for the exact current head before merge. A successful
211
+ CodeFactor check can still contain a notice: the stricter analyzer gate requires
212
+ zero outstanding annotations and verifies DeepScan plus branch protection.
213
+ Do not substitute a green check conclusion for that proof. This escape and its
214
+ correction are recorded in [pm-08mt4k](../.agents/pm/issues/pm-08mt4k.toon).
215
+
216
+ Use the helper's `acknowledge-inline` operation for actionable inline findings
217
+ and `acknowledge` for top-level comments or review summaries. Rate valid feedback
218
+ positively and explain false or stale findings on their actual review surface.
219
+ After each push, request the reviewers again and wait for terminal results;
220
+ provider quota or skipped reviews are limitations, not approvals. Before merge,
221
+ run `inventory` once more to catch new or edited feedback, and require all
222
+ findings to have an explicit disposition.
223
+
198
224
  ## Documentation Rules for Agents
199
225
 
200
226
  - Keep [README](../README.md) short.
@@ -205,6 +231,16 @@ for the release contract.
205
231
  - Link docs back to the active item with `pm docs`.
206
232
  - Do not link public docs to ignored local operations artifacts or private evidence logs.
207
233
 
234
+ ## Scheduling and Handoff
235
+
236
+ Read [SDK execution contracts](SDK_EXECUTION_CONTRACTS.md) before building an
237
+ agent work allocator. Use `next` and `claim --next` for executable work; inspect
238
+ `decision_needed`, `gate_needed`, and `containers` when no recommendation is
239
+ available. Only opt into those buckets when the current task calls for them.
240
+ Use `pause-task` to stop work; `release` alone preserves in-progress status.
241
+ Context summary totals describe the matching population, while `returned_focus`
242
+ describes the bounded selection.
243
+
208
244
  ## Safe Defaults
209
245
 
210
246
  Use these defaults unless the task requires otherwise:
@@ -0,0 +1,146 @@
1
+ # History durability and recovery
2
+
3
+ Tracked by [pm-96fsma](../.agents/pm/issues/pm-96fsma.toon),
4
+ [pm-m0yjtg](../.agents/pm/issues/pm-m0yjtg.toon),
5
+ [pm-qw1uw6](../.agents/pm/issues/pm-qw1uw6.toon),
6
+ [pm-e3gn0z](../.agents/pm/issues/pm-e3gn0z.toon), and
7
+ [pm-wlqxg3](../.agents/pm/tasks/pm-wlqxg3.toon).
8
+
9
+ Project management depends on trustworthy context. History is not just an
10
+ activity feed: it is the reconstructable source for prior item states, including
11
+ their evidence, relationships, and lifecycle transitions. Recovery must not
12
+ manufacture missing context or silently change an item's identity.
13
+
14
+ ## Stable addresses after compaction
15
+
16
+ `pm get <id> --at <version>` and `pm restore <id> <version>` use durable,
17
+ one-based version addresses. Compaction checkpoints the last compacted state
18
+ at its original version. Retained entries keep their addresses, including after
19
+ repeated compactions. Versions before the checkpoint fail with
20
+ `history_version_pruned`; they never select a different retained entry.
21
+
22
+ The checkpoint records `history_compaction.version_offset`. Add that offset to
23
+ a physical one-based stream position to obtain its durable version. `pm history`
24
+ reports `version_addressing`, and compact rows include their `version` alongside
25
+ the physical `index`. Verification error ordinals and diff indices remain
26
+ physical positions in the current stream. The checkpoint timestamp is the last
27
+ compacted entry's timestamp; the maintenance audit event records compaction time.
28
+
29
+ Legacy checkpoints without a recorded offset cannot prove their original
30
+ numeric addresses. Numeric reads fail with `history_version_mapping_unavailable`.
31
+ Use a retained timestamp instead; the SDK then returns `as_of_version: null`.
32
+ SDK consumers must handle this nullable value. `target.historyIndex` is always
33
+ the resolved physical zero-based position, not an original version number.
34
+ Default and timestamp-based compaction remain available for these legacy
35
+ streams. They preserve an unknown offset as `null`, including no-op results;
36
+ compaction never manufactures a numeric mapping from physical positions.
37
+
38
+ ## Recover an unreadable item file
39
+
40
+ ```bash
41
+ pm history <id> --full
42
+ pm restore <id> <version>
43
+ pm history <id> --verify --strict-exit
44
+ ```
45
+
46
+ Restore accepts an absent file or an unparsable item document when intact
47
+ history can reconstruct it. It verifies the history before using the recovered
48
+ state, preserves the original unreadable bytes for rollback, and uses the normal
49
+ ownership and lock checks. Successful recovery reports
50
+ `restore_unreadable_item_recovered`. Permission errors and unresolved merge
51
+ conflicts are not treated as missing files. A missing initial baseline returns
52
+ `history_baseline_unavailable` with recovery guidance rather than inventing
53
+ metadata from a partial patch.
54
+
55
+ CLI shape errors name the item ID, file path, and zero-length files. The SDK
56
+ error context also includes byte length and an explicit empty-file flag.
57
+ `pm health --check-only` names malformed item paths and invalid
58
+ history lines without mutating either file; use those diagnostics to select the
59
+ specific recovery operation above.
60
+
61
+ Invalid UTF-8 is a separate refusal (`item_document_encoding_invalid`), not a
62
+ recoverable text parse failure. Preserve a binary backup before recovering such
63
+ a file; text decoding must never silently replace original bytes.
64
+ Its SDK error context identifies the item ID, path, byte length, and nonempty
65
+ state just as text-shape diagnostics do.
66
+
67
+ ## Recover an invalid history tail
68
+
69
+ Keep a local backup before applying destructive history maintenance. Preview
70
+ exactly one stream, inspect the receipt, then explicitly apply:
71
+
72
+ ```bash
73
+ pm history-repair <id> --salvage-tail --dry-run --json
74
+ pm history-repair <id> --salvage-tail --json
75
+ pm history <id> --verify --strict-exit
76
+ ```
77
+
78
+ Salvage requires a nonempty, hash-verified prefix and retains its bytes unchanged.
79
+ The receipt records the first invalid physical line, discarded UTF-8 byte count,
80
+ discarded-suffix SHA-256, and retained record count. An appended `history_salvage`
81
+ event records that receipt without copying potentially private damaged contents.
82
+ Salvage does not rehash prior entries, reconcile item state, or normalize
83
+ provenance. It refuses bulk selection, conflicting repair modes, merge conflict
84
+ markers, parseable records after corruption, and potentially complete records
85
+ with attached corruption. Recover those cases from version control or a backup.
86
+ Non-UTF-8 streams are also refused, so receipt hashes and rollback snapshots
87
+ always describe the original bytes rather than a lossy decoded approximation.
88
+
89
+ The public SDK uses the same operation:
90
+
91
+ ```ts
92
+ import { PmClient } from "@unbrained/pm-cli";
93
+
94
+ const client = new PmClient({ pmRoot: "/project/.agents/pm" });
95
+ const preview = await client.historyRepair("pm-example", {
96
+ salvageTail: true,
97
+ dryRun: true,
98
+ });
99
+ console.log(preview.salvage);
100
+ ```
101
+
102
+ The CLI and MCP expose this SDK-owned contract; package authors do not need a
103
+ separate recovery implementation.
104
+
105
+ ## Permanent item identities
106
+
107
+ Deleting an item retains its identity reservation through its history file.
108
+ Generated IDs skip those reservations, even under reproducible execution.
109
+ Explicit recreation fails with `item_identity_reserved`; use restore to recover
110
+ the original subject, or create a new ID for unrelated work.
111
+ The first `create` append exclusively creates its effective history file, so
112
+ concurrent SDK callers and extension redirects cannot both reserve it. A failed
113
+ partial first write keeps the reservation for diagnosis; it is never deleted
114
+ to make the identity reusable. Subsequent large-record appenders still need the
115
+ normal item lock or an equivalent caller-owned serialization boundary.
116
+
117
+ Verification refuses a second `create` event, including one imported through
118
+ branch union, and names both physical ordinals. Point-in-time reads cannot cross
119
+ that discontinuity silently. Recover the original streams rather than rehashing
120
+ two unrelated subjects into a single supposedly valid item.
121
+
122
+ `pm validate --check-history-drift` reports this as an error, with item ID,
123
+ original and repeated genesis ordinals, and the observed sequence. The public
124
+ `findHistoryIdentityDiscontinuities` SDK primitive provides the same evidence
125
+ for importers. A delete followed by create is distinguished from multiple creates
126
+ or a checkpoint followed by create; these observations do not prove which
127
+ writer or branch introduced the records. Old drift caches are invalidated, and
128
+ known-invalid streams are reread even in metadata-cache mode.
129
+
130
+ ## Regression verification
131
+
132
+ ```bash
133
+ node scripts/run-tests.mjs test -- tests/integration/history-durability.integration.spec.ts
134
+ node scripts/run-tests.mjs test -- tests/integration/history-maintenance-replay.integration.spec.ts
135
+ ```
136
+
137
+ The fixture drives real CLI lifecycle mutations, independently captures each
138
+ serialized state, removes the live item file, and compares every addressable
139
+ version against those captures. Companion cases exercise repeated compaction,
140
+ legacy mapping refusal, seeded identity reuse, invalid-tail preservation,
141
+ unreadable-file recovery, and missing baselines. Maintenance fixtures additionally
142
+ perform redaction and a real divergent Git merge, compare every version with an
143
+ independent strict patch fold, and compare the final state with a separately
144
+ read item. Concurrent writes and binary corruption are negative controls, not
145
+ mocked successful outcomes. All fixtures use temporary trackers, never repository
146
+ tracker data.
package/docs/README.md CHANGED
@@ -81,6 +81,7 @@ pm guide release --json
81
81
  - [Extension Lifecycle Contracts](EXTENSION_LIFECYCLE.md) - source identity, durable migrations, and scoped preflight ownership.
82
82
  - [Extension Author Contracts](EXTENSION_AUTHOR_CONTRACTS.md) - the stability guarantees and contract surface package authors build against.
83
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.
84
85
  - [Multi-Branch Merge Safety](MERGE_SAFETY.md) - semantic tracker merge drivers, post-merge integrity gates, delete/modify policy, and recovery-receipt retention.
85
86
  - [Codex Plugin](CODEX_PLUGIN.md) - native MCP plugin install, tools, skills, and safety notes.
86
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,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.
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 4,
3
3
  "transcript_version": 2,
4
- "transcript_digest": "sha256:4f9e96bb6ce12bbbeb2514e4bd5958d201c4e62e95083bcbebd749d1e48cc82d",
4
+ "transcript_digest": "sha256:b8a6aea318c41e6a40dbcaf8094da8397ca747515a7df249d35c1f21ad94a307",
5
5
  "estimator": "ceil(utf8_bytes / 4)",
6
6
  "measurement_scope": "output_before_token_accounting",
7
7
  "published_with_release": true,
@@ -12,12 +12,12 @@
12
12
  "active_ownership",
13
13
  "workspace_state"
14
14
  ],
15
- "measured_winner_tokens": 1055,
15
+ "measured_winner_tokens": 1102,
16
16
  "protocols": [
17
17
  {
18
18
  "task_id": "orientation-context-intent",
19
19
  "command_count": 1,
20
- "estimated_tokens": 1055,
20
+ "estimated_tokens": 1102,
21
21
  "capabilities": [
22
22
  "actionable_work",
23
23
  "active_ownership",
@@ -47,7 +47,7 @@
47
47
  {
48
48
  "task_id": "orientation-operating-rules",
49
49
  "command_count": 4,
50
- "estimated_tokens": 2293,
50
+ "estimated_tokens": 2340,
51
51
  "capabilities": [
52
52
  "actionable_work",
53
53
  "active_ownership",
@@ -77,7 +77,7 @@
77
77
  {
78
78
  "task_id": "orientation-contracts-next",
79
79
  "command_count": 2,
80
- "estimated_tokens": 4798,
80
+ "estimated_tokens": 4829,
81
81
  "capabilities": [
82
82
  "actionable_work",
83
83
  "active_ownership",
@@ -109,18 +109,18 @@
109
109
  "tasks": [
110
110
  {
111
111
  "id": "orientation-context-intent",
112
- "max_estimated_tokens": 1055,
112
+ "max_estimated_tokens": 1102,
113
113
  "steps": [
114
114
  {
115
115
  "id": "context",
116
- "max_estimated_tokens": 1055,
116
+ "max_estimated_tokens": 1102,
117
117
  "accounting_mode": "self_reported"
118
118
  }
119
119
  ]
120
120
  },
121
121
  {
122
122
  "id": "orientation-contracts-next",
123
- "max_estimated_tokens": 4798,
123
+ "max_estimated_tokens": 4829,
124
124
  "steps": [
125
125
  {
126
126
  "id": "contracts",
@@ -129,18 +129,18 @@
129
129
  },
130
130
  {
131
131
  "id": "next",
132
- "max_estimated_tokens": 687,
132
+ "max_estimated_tokens": 718,
133
133
  "accounting_mode": "self_reported"
134
134
  }
135
135
  ]
136
136
  },
137
137
  {
138
138
  "id": "orientation-operating-rules",
139
- "max_estimated_tokens": 2293,
139
+ "max_estimated_tokens": 2340,
140
140
  "steps": [
141
141
  {
142
142
  "id": "context",
143
- "max_estimated_tokens": 1055,
143
+ "max_estimated_tokens": 1102,
144
144
  "accounting_mode": "self_reported"
145
145
  },
146
146
  {
@@ -162,7 +162,7 @@
162
162
  },
163
163
  {
164
164
  "id": "context-bootstrap",
165
- "max_estimated_tokens": 1978,
165
+ "max_estimated_tokens": 2025,
166
166
  "steps": [
167
167
  {
168
168
  "id": "triage",
@@ -171,7 +171,7 @@
171
171
  },
172
172
  {
173
173
  "id": "orient",
174
- "max_estimated_tokens": 1055,
174
+ "max_estimated_tokens": 1102,
175
175
  "accounting_mode": "self_reported"
176
176
  },
177
177
  {
@@ -199,12 +199,12 @@
199
199
  },
200
200
  {
201
201
  "id": "unknown-option-recovery",
202
- "max_estimated_tokens": 585,
202
+ "max_estimated_tokens": 603,
203
203
  "steps": [
204
204
  {
205
205
  "id": "refuse-option",
206
- "max_estimated_tokens": 422,
207
- "accounting_mode": "independent_transport"
206
+ "max_estimated_tokens": 440,
207
+ "accounting_mode": "self_reported"
208
208
  },
209
209
  {
210
210
  "id": "retry-option",
@@ -261,5 +261,5 @@
261
261
  ]
262
262
  }
263
263
  ],
264
- "composite_max_estimated_tokens": 12477
264
+ "composite_max_estimated_tokens": 12667
265
265
  }
@@ -186,6 +186,7 @@
186
186
  "expected_accounting_mode": "self_reported",
187
187
  "required_fields": ["code", "refusal", "recovery"],
188
188
  "expected_error_code": "unknown_context_intent",
189
+ "expected_field_values": { "recovery.recovery_mode": "compact" },
189
190
  "expected_refusal_surface": "--for"
190
191
  },
191
192
  {
@@ -216,7 +217,7 @@
216
217
  ],
217
218
  "expected_exit_code": 2,
218
219
  "expected_output_kind": "refusal",
219
- "expected_accounting_mode": "independent_transport",
220
+ "expected_accounting_mode": "self_reported",
220
221
  "required_fields": ["code", "refusal", "recovery"],
221
222
  "expected_error_code": "unknown_option",
222
223
  "expected_refusal_surface": "--include-body"