@unbrained/pm-cli 2026.8.30 → 2026.9.1

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 (176) hide show
  1. package/.agents/skills/HARNESS_COMPATIBILITY.md +1 -1
  2. package/.agents/skills/README.md +1 -1
  3. package/.agents/skills/pm-developer/SKILL.md +1 -1
  4. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +2 -2
  5. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +1 -1
  6. package/.agents/skills/pm-developer/references/TOKEN_BUDGETS.md +1 -1
  7. package/.agents/skills/pm-extensions/SKILL.md +2 -2
  8. package/.agents/skills/pm-extensions/references/AUTHORING.md +1 -1
  9. package/.agents/skills/pm-extensions/references/LIFECYCLE.md +1 -1
  10. package/.agents/skills/pm-sdk/SKILL.md +1 -1
  11. package/.agents/skills/pm-user/SKILL.md +2 -2
  12. package/.agents/skills/pm-user/references/WORKFLOWS.md +2 -2
  13. package/.claude-plugin/marketplace.json +2 -2
  14. package/AGENTS.md +16 -14
  15. package/CHANGELOG.md +41 -6
  16. package/README.md +3 -3
  17. package/dist/cli/commands/merge.d.ts +1 -1
  18. package/dist/cli/commands/merge.js +3 -3
  19. package/dist/cli/register-list-query.js +32 -17
  20. package/dist/cli/register-mutation.js +8 -5
  21. package/dist/cli/register-operations.d.ts +2 -0
  22. package/dist/cli/register-operations.js +20 -9
  23. package/dist/cli-bundle/bundle-manifest.json +144 -144
  24. package/dist/cli-bundle/chunks/{chunk-CMIEDWAY.js → chunk-2MC2LCXZ.js} +41 -41
  25. package/dist/cli-bundle/chunks/{chunk-WS2GJQVG.js → chunk-3WICXLVT.js} +2 -2
  26. package/dist/cli-bundle/chunks/{chunk-7SKMLSMX.js → chunk-6XIIGE7U.js} +2 -2
  27. package/dist/cli-bundle/chunks/chunk-ALKKAUFN.js +35 -0
  28. package/dist/cli-bundle/chunks/{chunk-MTTKAUBX.js → chunk-DTGWEL23.js} +2 -2
  29. package/dist/cli-bundle/chunks/chunk-GOACULJW.js +13 -0
  30. package/dist/cli-bundle/chunks/chunk-NOPL37X4.js +205 -0
  31. package/dist/cli-bundle/chunks/{chunk-2UETTHY6.js → chunk-TAG4VC22.js} +30 -30
  32. package/dist/cli-bundle/chunks/{chunk-3TEF3HM5.js → chunk-U45JXJCC.js} +2 -2
  33. package/dist/cli-bundle/chunks/{chunk-TGNAA66W.js → chunk-X4RCGLTX.js} +2 -2
  34. package/dist/cli-bundle/chunks/{chunk-2MKLQL2E.js → chunk-Y7VOMSZT.js} +2 -2
  35. package/dist/cli-bundle/chunks/{register-list-query-OMKJ5ONN.js → register-list-query-XYNX4ASQ.js} +11 -11
  36. package/dist/cli-bundle/chunks/register-mutation-2MVLRS3J.js +20 -0
  37. package/dist/cli-bundle/chunks/register-operations-WCIDXBU3.js +2 -0
  38. package/dist/cli-bundle/chunks/{register-setup-GLQ5SYV3.js → register-setup-KVNC5KPL.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-HVQ22RC4.js → chunk-2FEZ5SKM.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-Y3JJXRVK.js → chunk-4O4CJAR6.js} +5 -5
  41. package/dist/cli-bundle/focused-chunks/chunk-7VATS5QY.js +16 -0
  42. package/dist/cli-bundle/focused-chunks/{chunk-LYFWQMVC.js → chunk-BEVHCEWG.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/{chunk-TDK3OCX3.js → chunk-FWPLDEXF.js} +2 -2
  44. package/dist/cli-bundle/focused-chunks/chunk-JEFKLWMM.js +2 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-JZYPPMXF.js → chunk-KB5OFSFD.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-73EDXGYE.js → chunk-MKHG3T76.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-3AVAWVZA.js → chunk-PF3E6Q36.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-AD6ULRAF.js → chunk-QDFJIRKN.js} +4 -4
  49. package/dist/cli-bundle/focused-chunks/{chunk-RKOKG43G.js → chunk-RMRCQPWU.js} +2 -2
  50. package/dist/cli-bundle/focused-chunks/{chunk-XXOWRJZ5.js → chunk-S4U5CN5Q.js} +2 -2
  51. package/dist/cli-bundle/focused-chunks/{chunk-THEPQMLX.js → chunk-SVXJYD6G.js} +2 -2
  52. package/dist/cli-bundle/focused-chunks/chunk-T2LXXSOD.js +158 -0
  53. package/dist/cli-bundle/focused-chunks/chunk-Y6JJIX6I.js +51 -0
  54. package/dist/cli-bundle/main.js +2 -2
  55. package/dist/cli-bundle/sdk-authoring.js +1 -1
  56. package/dist/cli-bundle/sdk-contracts.js +1 -1
  57. package/dist/cli-bundle/sdk-core.js +27 -27
  58. package/dist/cli-bundle/sdk-governance.js +1 -1
  59. package/dist/cli-bundle/sdk-graph.js +1 -1
  60. package/dist/cli-bundle/sdk-merge.js +33 -33
  61. package/dist/cli-bundle/sdk-query.js +1 -1
  62. package/dist/cli-bundle/sdk-runtime.js +1 -1
  63. package/dist/cli-bundle/sdk-testing.js +1 -1
  64. package/dist/cli-bundle/sdk.js +10 -10
  65. package/dist/core/history/drift-scan.js +6 -6
  66. package/dist/core/history/history.d.ts +6 -0
  67. package/dist/core/history/history.js +47 -5
  68. package/dist/core/history/replay.d.ts +12 -1
  69. package/dist/core/history/replay.js +60 -39
  70. package/dist/core/schema/runtime-schema.d.ts +4 -0
  71. package/dist/core/schema/runtime-schema.js +60 -48
  72. package/dist/core/schema/status-defs-file.js +5 -2
  73. package/dist/mcp/legacy-adapter.d.ts +11 -2
  74. package/dist/mcp/legacy-adapter.js +26 -12
  75. package/dist/mcp/server.d.ts +2 -2
  76. package/dist/mcp/server.js +78 -15
  77. package/dist/mcp/tool-definitions.js +56 -2
  78. package/dist/sdk/agent-capability-contracts.js +4 -2
  79. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  80. package/dist/sdk/cli-contracts/flag-contracts.js +6 -2
  81. package/dist/sdk/cli-contracts/grammar-contracts.d.ts +1 -1
  82. package/dist/sdk/cli-contracts/grammar-contracts.js +12 -2
  83. package/dist/sdk/cli-contracts/runtime-contracts.js +3 -2
  84. package/dist/sdk/cli-contracts/tool-schema.js +11 -3
  85. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
  86. package/dist/sdk/governance/health.js +17 -6
  87. package/dist/sdk/governance/status-role-diagnostics.d.ts +27 -0
  88. package/dist/sdk/governance/status-role-diagnostics.js +36 -0
  89. package/dist/sdk/governance/validate-normalization.d.ts +6 -0
  90. package/dist/sdk/governance/validate-normalization.js +37 -0
  91. package/dist/sdk/governance/validate.d.ts +1 -1
  92. package/dist/sdk/governance/validate.js +20 -35
  93. package/dist/sdk/governance/workspace-position.d.ts +69 -0
  94. package/dist/sdk/governance/workspace-position.js +164 -0
  95. package/dist/sdk/governance.d.ts +2 -0
  96. package/dist/sdk/governance.js +4 -2
  97. package/dist/sdk/history-read.js +14 -6
  98. package/dist/sdk/history-repair.js +17 -10
  99. package/dist/sdk/index.d.ts +2 -1
  100. package/dist/sdk/index.js +4 -3
  101. package/dist/sdk/init-agent-guidance.js +4 -4
  102. package/dist/sdk/lifecycle/update.js +23 -10
  103. package/dist/sdk/mcp/discovery.d.ts +152 -0
  104. package/dist/sdk/mcp/discovery.js +495 -0
  105. package/dist/sdk/mcp/protocol.d.ts +10 -2
  106. package/dist/sdk/mcp/protocol.js +15 -4
  107. package/dist/sdk/merge/index.d.ts +1 -1
  108. package/dist/sdk/merge/index.js +3 -3
  109. package/dist/sdk/merge/receipts.d.ts +27 -1
  110. package/dist/sdk/merge/receipts.js +27 -8
  111. package/dist/sdk/merge/three-way.d.ts +3 -1
  112. package/dist/sdk/merge/three-way.js +9 -7
  113. package/dist/sdk/query/context.js +11 -14
  114. package/dist/sdk/query/list.d.ts +2 -0
  115. package/dist/sdk/query/list.js +33 -12
  116. package/dist/sdk/runtime-extended-actions.js +10 -6
  117. package/dist/sdk/schema.js +12 -2
  118. package/dist/sdk/test/execution.d.ts +15 -0
  119. package/dist/sdk/test/execution.js +35 -27
  120. package/docs/AGENT_GUIDE.md +12 -4
  121. package/docs/AGENT_PROVENANCE_ADR.md +1 -1
  122. package/docs/AGENT_RUNTIME_PRIMITIVES.md +2 -2
  123. package/docs/ARCHITECTURE.md +5 -0
  124. package/docs/CLAUDE_CODE_PLUGIN.md +5 -5
  125. package/docs/COMMANDS.md +12 -12
  126. package/docs/CONFIGURATION.md +1 -1
  127. package/docs/CONTEXT_RECOVERY_PRIMITIVES.md +14 -5
  128. package/docs/DEFECT_RECURRENCE.md +2 -0
  129. package/docs/MCP_2026_07_28.md +33 -9
  130. package/docs/MCP_2026_07_28_CONFORMANCE.md +1 -0
  131. package/docs/MCP_CAPABILITY_SURFACES.md +7 -1
  132. package/docs/MCP_REMOTE_TRANSPORT_SECURITY.md +15 -3
  133. package/docs/MERGE_SAFETY.md +30 -2
  134. package/docs/ONBOARDING.md +1 -1
  135. package/docs/OUTPUT_TOKEN_ACCOUNTING.md +5 -3
  136. package/docs/PROGRESSIVE_TOOL_DISCOVERY.md +42 -0
  137. package/docs/README.md +3 -1
  138. package/docs/READ_OUTPUT_CONTRACTS.md +1 -1
  139. package/docs/RECURRENCE_RECOVERY_CONTRACTS.md +1 -1
  140. package/docs/SDK.md +3 -3
  141. package/docs/TESTING.md +23 -14
  142. package/docs/WORKSPACE_POSITION_AND_LIFECYCLE.md +113 -0
  143. package/docs/agent-task-token-baseline.json +157 -3
  144. package/docs/agent-task-transcripts.json +143 -0
  145. package/docs/examples/policy-restricted-extension/README.md +2 -2
  146. package/docs/examples/starter-extension/README.md +1 -1
  147. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +4 -3
  148. package/docs/performance/cli-transport-overhead.md +8 -6
  149. package/marketplace.json +2 -2
  150. package/package.json +4 -4
  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/README.md +4 -3
  166. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  167. package/sdk/public-surface.json +314 -10
  168. package/dist/cli-bundle/chunks/chunk-7X6OZEIV.js +0 -34
  169. package/dist/cli-bundle/chunks/chunk-GNWPTEBW.js +0 -205
  170. package/dist/cli-bundle/chunks/chunk-N6OR6FAR.js +0 -13
  171. package/dist/cli-bundle/chunks/register-mutation-QBSNCOY3.js +0 -20
  172. package/dist/cli-bundle/chunks/register-operations-UC77FQZC.js +0 -2
  173. package/dist/cli-bundle/focused-chunks/chunk-3UMBF26I.js +0 -158
  174. package/dist/cli-bundle/focused-chunks/chunk-AXZ5AJAF.js +0 -50
  175. package/dist/cli-bundle/focused-chunks/chunk-G6PATS5E.js +0 -16
  176. package/dist/cli-bundle/focused-chunks/chunk-LLNTHF5X.js +0 -2
@@ -7,13 +7,13 @@
7
7
  * value for the coordinator that performed the merge.
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]="145a6d31-5e14-5b0b-95fb-6f837d11e2f4")}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]="624fc190-4c46-5a55-b757-72e621aec35d")}catch(e){}}();
11
11
  import { execFile } from "node:child_process";
12
12
  import { randomUUID } from "node:crypto";
13
13
  import { readdir } from "node:fs/promises";
14
14
  import path from "node:path";
15
15
  import { promisify } from "node:util";
16
- import { ensureDir, isFileAbsentError, pathExists, writeFileAtomic, } from "../../core/fs/fs-utils.js";
16
+ import { ensureDir, isFileAbsentError, isFileMissingError, pathExists, writeFileAtomic, } from "../../core/fs/fs-utils.js";
17
17
  import { sha256Hex, stableStringify } from "../../core/shared/serialization.js";
18
18
  import { isRfc3339DateTime, nowIso } from "../../core/shared/time.js";
19
19
  import { readBoundedRegularFile } from "./receipt-file-boundary.js";
@@ -367,15 +367,15 @@ export async function writeMergeReceipt(params) {
367
367
  return receipt;
368
368
  }
369
369
  async function readReceiptsFromDirectory(directory, evidenceSource) {
370
- if (!(await pathExists(directory))) {
371
- return { receipts: [], invalid_evidence_count: 0 };
372
- }
373
370
  let names;
374
371
  try {
375
372
  names = await readdir(directory);
376
373
  }
377
- catch {
378
- return { receipts: [], invalid_evidence_count: 1 };
374
+ catch (error) {
375
+ return {
376
+ receipts: [],
377
+ invalid_evidence_count: isFileMissingError(error) ? 0 : 1,
378
+ };
379
379
  }
380
380
  const receipts = [];
381
381
  let invalidEvidenceCount = 0;
@@ -441,6 +441,7 @@ export async function inspectMergeReceiptEvidence(cwd, options = {}) {
441
441
  invalid_evidence_count: local.invalid_evidence_count +
442
442
  durable.invalid_evidence_count +
443
443
  divergentCopyCount,
444
+ clone_local_evidence_resolved: directory !== null,
444
445
  };
445
446
  }
446
447
  /** Read clone-local receipts with explicit reconciled/lossless classification controls. */
@@ -524,7 +525,25 @@ export async function runMergeReceiptReport(options) {
524
525
  generated_at: nowIso(),
525
526
  };
526
527
  }
528
+ /** Inspect every receipt candidate and retain completeness diagnostics without exposing rejected file contents. */
529
+ export async function runMergeReceiptEvidenceReport(options) {
530
+ const evidence = await inspectMergeReceiptEvidence(options.cwd ?? process.cwd(), {
531
+ ...options,
532
+ includeLossless: true,
533
+ });
534
+ const complete = evidence.clone_local_evidence_resolved === true &&
535
+ evidence.invalid_evidence_count === 0;
536
+ return {
537
+ ok: complete,
538
+ complete,
539
+ count: evidence.receipts.length,
540
+ invalid_evidence_count: evidence.invalid_evidence_count,
541
+ clone_local_evidence_resolved: evidence.clone_local_evidence_resolved,
542
+ receipts: evidence.receipts,
543
+ generated_at: nowIso(),
544
+ };
545
+ }
527
546
  /** Test-only seams for deterministic receipt-boundary fault coverage. */
528
547
  export const _testOnlyMergeReceipts = { prepareReceiptSettlement };
529
548
  //# sourceMappingURL=receipts.js.map
530
- //# debugId=145a6d31-5e14-5b0b-95fb-6f837d11e2f4
549
+ //# debugId=624fc190-4c46-5a55-b757-72e621aec35d
@@ -28,7 +28,9 @@ export interface HistoryMergeResult {
28
28
  * hash re-anchored so the resulting chain verifies again. No side's events are
29
29
  * ever discarded: content divergence is preserved for the post-merge
30
30
  * reconciliation pass (`pm validate` + `pm history-repair`) instead of being
31
- * silently resolved by last-writer-wins.
31
+ * silently resolved by last-writer-wins. If either suffix cannot apply after
32
+ * deterministic ordering, the merge fails closed instead of publishing a
33
+ * hash-valid stream that omitted a branch effect.
32
34
  */
33
35
  export declare function mergeHistoryStreams(baseRaw: string, oursRaw: string, theirsRaw: string): HistoryMergeResult;
34
36
  /** Documents the relationship event stream merge result payload exchanged by command, SDK, and package integrations. */
@@ -9,7 +9,7 @@
9
9
  * definition for multi-branch agent workflows.
10
10
  */
11
11
 
12
- !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]="393f6460-bf8b-5479-8e3e-cac6f2680823")}catch(e){}}();
12
+ !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]="7e8fcddf-09fe-5979-b23a-78915bf7f896")}catch(e){}}();
13
13
  import { historyEntriesToRaw, reanchorHistoryEntries, } from "../../core/history/replay.js";
14
14
  import { canonicalDocument, parseItemDocument, serializeItemDocument, } from "../../core/item/item-format.js";
15
15
  import { EXIT_CODE } from "../../core/shared/constants.js";
@@ -69,7 +69,9 @@ function commonHistoryPrefixLength(ours, theirs) {
69
69
  * hash re-anchored so the resulting chain verifies again. No side's events are
70
70
  * ever discarded: content divergence is preserved for the post-merge
71
71
  * reconciliation pass (`pm validate` + `pm history-repair`) instead of being
72
- * silently resolved by last-writer-wins.
72
+ * silently resolved by last-writer-wins. If either suffix cannot apply after
73
+ * deterministic ordering, the merge fails closed instead of publishing a
74
+ * hash-valid stream that omitted a branch effect.
73
75
  */
74
76
  export function mergeHistoryStreams(baseRaw, oursRaw, theirsRaw) {
75
77
  parseHistoryJsonl(baseRaw, "base");
@@ -126,10 +128,10 @@ export function mergeHistoryStreams(baseRaw, oursRaw, theirsRaw) {
126
128
  }
127
129
  return historyEntryIdentity(left).localeCompare(historyEntryIdentity(right));
128
130
  });
129
- const reanchored = reanchorHistoryEntries([
130
- ...ours.slice(0, shared),
131
- ...mergedSuffix,
132
- ]);
131
+ const reanchored = reanchorHistoryEntries([...ours.slice(0, shared), ...mergedSuffix], undefined, { continuousHashSurface: true });
132
+ if (reanchored.skippedOps > 0) {
133
+ throw new PmCliError(`History union cannot preserve ${reanchored.skippedOps} patch operation(s) after deterministic suffix ordering; leave the file unresolved for manual recovery.`, EXIT_CODE.GENERIC_FAILURE);
134
+ }
133
135
  return {
134
136
  merged: historyEntriesToRaw(reanchored.entries),
135
137
  strategy: "union_reanchor",
@@ -704,4 +706,4 @@ export function mergeJsonDocuments(baseRaw, oursRaw, theirsRaw, options = {}) {
704
706
  };
705
707
  }
706
708
  //# sourceMappingURL=three-way.js.map
707
- //# debugId=393f6460-bf8b-5479-8e3e-cac6f2680823
709
+ //# debugId=7e8fcddf-09fe-5979-b23a-78915bf7f896
@@ -4,7 +4,7 @@
4
4
  * Implements the pm context command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ee5279f2-7489-59fb-8f96-f2e035434cce")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a870e3ac-f731-5cbf-a66e-38d1d5b1d0aa")}catch(e){}}();
8
8
  import { SETTINGS_DEFAULTS, EXIT_CODE, PmCliError, compareTimestampStrings, nowIso, isTerminalStatus, normalizeStatusForRegistry, normalizeStatusInput, resolveRuntimeStatusRegistry, resolvePmRoot, readSettings, resolveAuthor, discoverExtensions, } from "../runtime-primitives.js";
9
9
  import { collectDependencyBlockedIds, resolveItemBlockers, } from "../actionability.js";
10
10
  import { CONTEXT_DEPTH_VALUES, CONTEXT_SECTION_VALUES, } from "../../types/index.js";
@@ -221,20 +221,16 @@ function parseStaleThresholdDays(raw, settings) {
221
221
  // ---------------------------------------------------------------------------
222
222
  function statusRank(status, statusRegistry) {
223
223
  const normalizedStatus = normalizeStatusForRegistry(status, statusRegistry);
224
- const inProgressStatus = normalizeStatusInput("in_progress", statusRegistry);
225
- const openStatus = normalizeStatusInput("open", statusRegistry);
226
224
  const blockedStatus = normalizeStatusInput("blocked", statusRegistry);
227
225
  const draftStatus = normalizeStatusInput("draft", statusRegistry);
228
- if (inProgressStatus && normalizedStatus === inProgressStatus)
226
+ if (normalizedStatus === statusRegistry.in_progress_status)
229
227
  return 0;
230
- if (openStatus && normalizedStatus === openStatus)
228
+ if (statusRegistry.active_statuses.has(normalizedStatus))
231
229
  return 1;
232
230
  if (blockedStatus && normalizedStatus === blockedStatus)
233
231
  return 2;
234
232
  if (draftStatus && normalizedStatus === draftStatus)
235
233
  return 3;
236
- if (statusRegistry.active_statuses.has(normalizedStatus))
237
- return 4;
238
234
  if (statusRegistry.blocked_statuses.has(normalizedStatus))
239
235
  return 5;
240
236
  if (statusRegistry.terminal_statuses.has(normalizedStatus))
@@ -246,12 +242,13 @@ function isClosedStatus(status, statusRegistry) {
246
242
  return normalizeStatusForRegistry(status, statusRegistry) === closeStatus;
247
243
  }
248
244
  function isInProgressStatus(status, statusRegistry) {
249
- const inProgressStatus = normalizeStatusInput("in_progress", statusRegistry);
250
- return (normalizeStatusForRegistry(status, statusRegistry) === inProgressStatus);
245
+ return (normalizeStatusForRegistry(status, statusRegistry) ===
246
+ statusRegistry.in_progress_status);
251
247
  }
252
248
  function isOpenStatus(status, statusRegistry) {
253
- const openStatus = normalizeStatusInput("open", statusRegistry);
254
- return normalizeStatusForRegistry(status, statusRegistry) === openStatus;
249
+ const normalizedStatus = normalizeStatusForRegistry(status, statusRegistry);
250
+ return (normalizedStatus !== statusRegistry.in_progress_status &&
251
+ statusRegistry.active_statuses.has(normalizedStatus));
255
252
  }
256
253
  function isBlockedStatus(status, statusRegistry) {
257
254
  return statusRegistry.blocked_statuses.has(normalizeStatusForRegistry(status, statusRegistry));
@@ -1598,8 +1595,8 @@ export async function runContext(options, global) {
1598
1595
  now: agendaContext.agenda.now,
1599
1596
  });
1600
1597
  const warnings = mergeSortedWarnings(corpus.listed.warnings, agendaContext.agenda.warnings, focusGroups.ranking.warnings, [...focusGroups.featureStore.warnings], workspaceMemory.warnings);
1601
- const inProgressCount = countContextStatus(focusGroups.activeItems, normalizeStatusInput("in_progress", runtime.statusRegistry), runtime.statusRegistry);
1602
- const openCount = countContextStatus(focusGroups.activeItems, normalizeStatusInput("open", runtime.statusRegistry), runtime.statusRegistry);
1598
+ const inProgressCount = countContextStatus(focusGroups.activeItems, runtime.statusRegistry.in_progress_status, runtime.statusRegistry);
1599
+ const openCount = focusGroups.activeItems.length - inProgressCount;
1603
1600
  const sections = await buildOptionalContextSections({
1604
1601
  runtime,
1605
1602
  allItems: corpus.allItems,
@@ -1679,4 +1676,4 @@ export async function runContext(options, global) {
1679
1676
  return result;
1680
1677
  }
1681
1678
  //# sourceMappingURL=context.js.map
1682
- //# debugId=ee5279f2-7489-59fb-8f96-f2e035434cce
1679
+ //# debugId=a870e3ac-f731-5cbf-a66e-38d1d5b1d0aa
@@ -56,6 +56,8 @@ export interface ListOptions extends SharedItemFilterOptions {
56
56
  * lifecycle-status filter.
57
57
  */
58
58
  dependencyBlocked?: boolean;
59
+ /** Select a role-derived active lifecycle bucket instead of one literal status id. */
60
+ lifecycleBucket?: "open" | "in_progress";
59
61
  /** Value that configures or reports filter ac missing for this contract. */
60
62
  filterAcMissing?: boolean;
61
63
  /** Value that configures or reports filter estimates missing for this contract. */
@@ -4,7 +4,7 @@
4
4
  * Implements the pm list command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="93e8c187-e198-50fc-bf2c-7dae2ea42219")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="ccdb7d16-4f38-58d4-a19d-4ab1516cb1d7")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { getActiveExtensionRegistrations, hasActiveOnReadHooks, } from "../../core/extensions/index.js";
10
10
  import { toItemRecord } from "../../core/item/item-record.js";
@@ -978,20 +978,40 @@ function resolveListOrderingOptions(options) {
978
978
  }
979
979
  function resolveListStatusSelection(status, options, statusRegistry) {
980
980
  const explicitStatus = resolveStatusFilter(options.status, statusRegistry);
981
- const resolvedStatus = explicitStatus ?? resolveStatusFilter(status, statusRegistry);
981
+ let lifecycleStatus;
982
+ if (options.lifecycleBucket === "in_progress") {
983
+ lifecycleStatus = [statusRegistry.in_progress_status];
984
+ }
985
+ else if (options.lifecycleBucket === "open") {
986
+ lifecycleStatus = [...statusRegistry.active_statuses]
987
+ .filter((entry) => entry !== statusRegistry.in_progress_status)
988
+ .sort((left, right) => left.localeCompare(right));
989
+ }
990
+ const resolvedStatus = explicitStatus ??
991
+ lifecycleStatus ??
992
+ resolveStatusFilter(status, statusRegistry);
982
993
  const explicitAllStatuses = isStatusAllFilterInput(options.status);
983
994
  const effectiveOptions = explicitStatus || explicitAllStatuses
984
995
  ? { ...options, excludeTerminal: false }
985
996
  : options;
986
- const filtersStatus = explicitAllStatuses
987
- ? "all"
988
- : resolvedStatus === undefined
989
- ? effectiveOptions.excludeTerminal === true
990
- ? null
991
- : "all"
992
- : resolvedStatus.length === 1
993
- ? resolvedStatus[0]
994
- : resolvedStatus;
997
+ let filtersStatus = "all";
998
+ if (explicitAllStatuses) {
999
+ filtersStatus = "all";
1000
+ }
1001
+ else if (explicitStatus !== undefined) {
1002
+ filtersStatus =
1003
+ explicitStatus.length === 1 ? explicitStatus[0] : explicitStatus;
1004
+ }
1005
+ else if (options.lifecycleBucket !== undefined) {
1006
+ filtersStatus = options.lifecycleBucket;
1007
+ }
1008
+ else if (resolvedStatus !== undefined) {
1009
+ filtersStatus =
1010
+ resolvedStatus.length === 1 ? resolvedStatus[0] : resolvedStatus;
1011
+ }
1012
+ else if (effectiveOptions.excludeTerminal === true) {
1013
+ filtersStatus = null;
1014
+ }
995
1015
  return {
996
1016
  resolvedStatus,
997
1017
  explicitAllStatuses,
@@ -1045,6 +1065,7 @@ async function tryLoadIndexedListPage(params) {
1045
1065
  "includeBody",
1046
1066
  "excludeTerminal",
1047
1067
  "dependencyBlocked",
1068
+ "lifecycleBucket",
1048
1069
  "noTruncate",
1049
1070
  "projectionCommand",
1050
1071
  "truncate",
@@ -1281,4 +1302,4 @@ export const _testOnly = {
1281
1302
  withTreeMetadata,
1282
1303
  };
1283
1304
  //# sourceMappingURL=list.js.map
1284
- //# debugId=93e8c187-e198-50fc-bf2c-7dae2ea42219
1305
+ //# debugId=ccdb7d16-4f38-58d4-a19d-4ab1516cb1d7
@@ -1,19 +1,20 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8a3a82a1-9e3d-555f-9111-3c3e19887f75")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="41227e35-6354-5208-997b-e8a1cf696bf9")}catch(e){}}();
3
3
  import { EXIT_CODE } from "../core/shared/constants.js";
4
4
  import { PmCliError } from "../core/shared/errors.js";
5
- import { transferMutationStdinTokenPolicy, } from "./runtime-primitives.js";
5
+ import { transferMutationStdinTokenPolicy } from "./runtime-primitives.js";
6
6
  import { createUnknownSubcommandError } from "./agent/subcommand-recovery.js";
7
7
  import { resolvePmRoot } from "../core/store/paths.js";
8
8
  import { runEval } from "./eval.js";
9
9
  import { runMergeDriver } from "./merge/driver.js";
10
10
  import { runMergeInstall } from "./merge/install.js";
11
11
  import { runMergeReconcile } from "./merge/reconcile.js";
12
- import { runMergeReceiptReport } from "./merge/receipts.js";
12
+ import { runMergeReceiptEvidenceReport } from "./merge/receipts.js";
13
13
  import { listMutationEvents } from "./mutation-events.js";
14
14
  import { parseRuntimeInteger, readRuntimeString, readRuntimeStringArray, } from "./runtime-input.js";
15
15
  import { runEvent, runMeet, runRemind, } from "./scheduling-shortcuts.js";
16
16
  import { createWorkspaceSnapshot, deleteWorkspaceSnapshot, inspectWorkspaceSnapshot, listWorkspaceSnapshots, planWorkspaceSnapshotRestore, restoreWorkspaceSnapshotWithRecovery, } from "./workspace-snapshot.js";
17
+ import { readWorkspacePosition } from "./governance/workspace-position.js";
17
18
  function mergedInput(context) {
18
19
  const input = { ...context.args, ...context.options };
19
20
  return transferMutationStdinTokenPolicy(context.options, input);
@@ -86,7 +87,7 @@ export function runRuntimeMergeAction(context) {
86
87
  }, context.global);
87
88
  }
88
89
  if (subcommand === "report") {
89
- return runMergeReceiptReport({
90
+ return runMergeReceiptEvidenceReport({
90
91
  includeReconciled: input.includeReconciled === true,
91
92
  cwd: readRuntimeString(input, "cwd"),
92
93
  });
@@ -114,11 +115,14 @@ export function runRuntimeMergeAction(context) {
114
115
  export function runRuntimeWorkspaceAction(context) {
115
116
  const input = mergedInput(context);
116
117
  const subcommand = requiredString(input, "subcommand");
118
+ if (subcommand === "position") {
119
+ return readWorkspacePosition(context.global);
120
+ }
117
121
  if (subcommand !== "snapshot") {
118
122
  throw createUnknownSubcommandError({
119
123
  command_path: "workspace",
120
124
  token: subcommand,
121
- allowed: ["snapshot"],
125
+ allowed: ["position", "snapshot"],
122
126
  display_name: "workspace",
123
127
  });
124
128
  }
@@ -171,4 +175,4 @@ export function runRuntimeSchedulingAction(context) {
171
175
  return runRemind(title, input, context.global);
172
176
  }
173
177
  //# sourceMappingURL=runtime-extended-actions.js.map
174
- //# debugId=8a3a82a1-9e3d-555f-9111-3c3e19887f75
178
+ //# debugId=41227e35-6354-5208-997b-e8a1cf696bf9
@@ -4,7 +4,7 @@
4
4
  * Owns typed schema customization primitives shared by SDK, CLI, and MCP consumers.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6112923d-5e06-5839-b452-a32818c6398d")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="264088a5-09d1-52ed-8b12-af00392e1a5f")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "./environment/tracker-preflight.js";
9
9
  import path from "node:path";
10
10
  import { mkdir } from "node:fs/promises";
@@ -422,6 +422,16 @@ export async function runSchemaAddStatus(id, options, global) {
422
422
  // --role/--alias preserves metadata defined in settings.schema.statuses, not
423
423
  // only what is already in statuses.json.
424
424
  const baseDefinition = toExistingStatusDefinition(statusRegistry.by_id.get(normalized.id));
425
+ const effectiveRoles = normalized.roles ?? baseDefinition?.roles ?? [];
426
+ if (effectiveRoles.length === 0) {
427
+ throw new PmCliError(`Status "${normalized.id}" requires at least one lifecycle role. Re-run with --role active, --role blocked, --role draft, or an appropriate terminal/default role.`, EXIT_CODE.USAGE, {
428
+ code: "status_lifecycle_role_required",
429
+ examples: [
430
+ `pm schema add-status "${escapeForDoubleQuotes(normalized.id)}" --role active`,
431
+ `pm schema add-status "${escapeForDoubleQuotes(normalized.id)}" --role blocked`,
432
+ ],
433
+ });
434
+ }
425
435
  const warnings = [];
426
436
  const author = resolveAuthor(options.author, settings.author_default);
427
437
  const governance = resolveGovernanceKnobs(settings);
@@ -1364,4 +1374,4 @@ export const _testOnlySchemaCommand = {
1364
1374
  workflowSlotsReferencing,
1365
1375
  };
1366
1376
  //# sourceMappingURL=schema.js.map
1367
- //# debugId=6112923d-5e06-5839-b452-a32818c6398d
1377
+ //# debugId=264088a5-09d1-52ed-8b12-af00392e1a5f
@@ -206,6 +206,21 @@ declare function resolveDirectRunnerSubcommand(parsed: {
206
206
  } | null): string | undefined;
207
207
  declare function firstDirectTestRunnerSubcommand(executable: string, args: string[]): string | undefined;
208
208
  declare function segmentInvokesRecursiveTestAll(segment: string): boolean;
209
+ /** Describes the SDK-owned safety policy applied when a linked command is recorded. */
210
+ export interface LinkedTestCommandSafetyClassification {
211
+ /** Whether intake accepts the command before provenance checks at execution time. */
212
+ accepted: true;
213
+ /** Capability-oriented command family, independent of shell wrapping. */
214
+ command_kind: "direct_runner" | "sandbox_runner" | "other";
215
+ /** Tracker isolation is injected by the linked-test runtime for every command. */
216
+ tracker_isolation: "runtime_injected";
217
+ /** Stored-command provenance and explicit acknowledgment form the execution trust boundary. */
218
+ trust_boundary: "provenance";
219
+ /** Human guidance for reproducible execution without presenting string shape as enforcement. */
220
+ advisory: string;
221
+ }
222
+ /** Classify linked-test commands without pretending string shape is a security boundary. */
223
+ export declare function classifyLinkedTestCommandSafety(command: string): LinkedTestCommandSafetyClassification;
209
224
  declare function parseLinkedTestTimeoutSeconds(timeoutSecondsRaw: string | undefined, timeoutAliasRaw: string | undefined): number | undefined;
210
225
  declare function parseAddJsonEntries(raw: string[] | undefined): LinkedTest[];
211
226
  declare function endLinkedTestProgress(context: LinkedTestProgressContext, executionResult: Pick<LinkedTestExecutionResult, "timedOut" | "maxBufferExceeded" | "outputTruncated" | "exitCode" | "signal">, startedAt: number, mode: LinkedTestProgressMode): void;
@@ -4,7 +4,7 @@
4
4
  * Implements the pm test command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="de5bc6bf-fe31-5643-a809-ee9ca52aac48")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="03f2f710-3b96-5671-85fa-d8ea4726ee86")}catch(e){}}();
8
8
  import { assertInitializedTracker } from "../environment/tracker-preflight.js";
9
9
  import { spawn } from "node:child_process";
10
10
  import { cp, mkdir, mkdtemp, open, readdir, rm, symlink, } from "node:fs/promises";
@@ -388,14 +388,7 @@ function commandUsesSandboxRunner(normalizedCommand) {
388
388
  normalizedCommand.includes("node ./scripts/run-tests.mjs ") ||
389
389
  normalizedCommand.endsWith("node ./scripts/run-tests.mjs"));
390
390
  }
391
- function segmentHasExplicitSandboxEnv(normalizedSegment) {
392
- const hasExplicitPmPath = /\bpm_path\s*=/.test(normalizedSegment) ||
393
- /\$env:pm_path\s*=/.test(normalizedSegment);
394
- const hasExplicitPmGlobalPath = /\bpm_global_path\s*=/.test(normalizedSegment) ||
395
- /\$env:pm_global_path\s*=/.test(normalizedSegment);
396
- return hasExplicitPmPath && hasExplicitPmGlobalPath;
397
- }
398
- function segmentInvokesUnsafeDirectTestRunner(normalizedSegment) {
391
+ function segmentInvokesDirectTestRunner(normalizedSegment) {
399
392
  const rawTokens = normalizedSegment
400
393
  .split(" ")
401
394
  .filter((token) => token.length > 0);
@@ -404,45 +397,62 @@ function segmentInvokesUnsafeDirectTestRunner(normalizedSegment) {
404
397
  return false;
405
398
  }
406
399
  const [executable, ...args] = tokens;
400
+ const shellCommandFlagPattern = SHELL_COMMAND_FLAG_PATTERNS.get(executable);
401
+ if (shellCommandFlagPattern) {
402
+ const commandFlagIndex = args.findIndex((argument) => shellCommandFlagPattern.test(argument));
403
+ return (commandFlagIndex >= 0 &&
404
+ segmentInvokesDirectTestRunner(args.slice(commandFlagIndex + 1).join(" ")));
405
+ }
407
406
  if (executable === "vitest" ||
408
407
  executable.endsWith("/vitest") ||
409
408
  executable.endsWith("/vitest.mjs")) {
410
409
  return true;
411
410
  }
412
411
  if (executable === "node") {
413
- return nodeArgsInvokeUnsafeDirectTestRunner(args);
412
+ return nodeArgsInvokeDirectTestRunner(args);
414
413
  }
415
- return packageManagerInvokesUnsafeDirectTestRunner(executable, args);
414
+ return packageManagerInvokesDirectTestRunner(executable, args);
416
415
  }
417
- function nodeArgsInvokeUnsafeDirectTestRunner(args) {
416
+ function nodeArgsInvokeDirectTestRunner(args) {
418
417
  return (args.includes("--test") ||
419
418
  args.some((arg) => arg === "vitest" ||
420
419
  arg === "vitest.mjs" ||
421
420
  arg.endsWith("/vitest") ||
422
421
  arg.endsWith("/vitest.mjs")));
423
422
  }
424
- function packageManagerInvokesUnsafeDirectTestRunner(executable, args) {
423
+ function packageManagerInvokesDirectTestRunner(executable, args) {
425
424
  if (executable === "npx" || executable === "bunx") {
426
425
  return isDirectTestRunnerSubcommand(parseNpxCommand(args)?.command);
427
426
  }
428
427
  if (executable === "pnpm" || executable === "npm") {
429
428
  return (isDirectTestRunnerSubcommand((executable === "pnpm"
430
429
  ? parsePnpmDlxCommand(args)
431
- : parseNpmExecCommand(args))?.command) || firstDirectTestRunnerSubcommand(executable, args) === "vitest");
430
+ : parseNpmExecCommand(args))?.command) ||
431
+ isDirectTestRunnerSubcommand(firstDirectTestRunnerSubcommand(executable, args)));
432
432
  }
433
433
  return ((executable === "yarn" || executable === "bun") &&
434
- firstDirectTestRunnerSubcommand(executable, args) === "vitest");
434
+ isDirectTestRunnerSubcommand(firstDirectTestRunnerSubcommand(executable, args)));
435
435
  }
436
- function assertSandboxSafeTestRunnerCommand(command) {
436
+ /** Classify linked-test commands without pretending string shape is a security boundary. */
437
+ export function classifyLinkedTestCommandSafety(command) {
437
438
  const normalized = normalizeCommandForValidation(command);
438
439
  const segments = splitNormalizedCommandSegments(normalized);
439
- const hasUnsafeDirectRunnerSegment = segments.some((segment) => !commandUsesSandboxRunner(segment) &&
440
- segmentInvokesUnsafeDirectTestRunner(segment) &&
441
- !segmentHasExplicitSandboxEnv(segment));
442
- if (!hasUnsafeDirectRunnerSegment) {
443
- return;
444
- }
445
- throw new PmCliError('Linked test runner commands must be sandbox-safe: use "node scripts/run-tests.mjs <test|coverage>", use a package-manager script such as "pnpm test", or include PM_PATH=... PM_GLOBAL_PATH=... INLINE in the command string (exporting them in your shell environment is not checked). Example: "PM_PATH=/tmp/pm-x PM_GLOBAL_PATH=/tmp/pm-x-g vitest run".', EXIT_CODE.USAGE);
440
+ const directRunner = segments.some((segment) => !commandUsesSandboxRunner(segment) &&
441
+ segmentInvokesDirectTestRunner(segment));
442
+ const sandboxRunner = segments.some(commandUsesSandboxRunner);
443
+ return {
444
+ accepted: true,
445
+ command_kind: directRunner
446
+ ? "direct_runner"
447
+ : sandboxRunner
448
+ ? "sandbox_runner"
449
+ : "other",
450
+ tracker_isolation: "runtime_injected",
451
+ trust_boundary: "provenance",
452
+ advisory: directRunner
453
+ ? "Accepted with runtime-injected tracker isolation. Prefer the repository sandbox runner when available for reproducible build and coverage setup."
454
+ : "Accepted with runtime-injected tracker isolation and provenance checks before execution.",
455
+ };
446
456
  }
447
457
  function getRuntimeSafetySkipReason(command) {
448
458
  if (!invokesRecursiveTestAllCommand(command))
@@ -464,7 +474,6 @@ function parseAddEntry(entry) {
464
474
  throw new PmCliError("--add requires command=<value> or a bare command (path=<value> is optional metadata)", EXIT_CODE.USAGE);
465
475
  }
466
476
  assertNoRecursiveTestAllCommand(command);
467
- assertSandboxSafeTestRunnerCommand(command);
468
477
  return {
469
478
  command,
470
479
  path: trimLinkedTestEntryField(kv.path),
@@ -516,7 +525,6 @@ function parseAddJsonEntries(raw) {
516
525
  throw new PmCliError("--add-json requires a non-empty command string", EXIT_CODE.USAGE);
517
526
  }
518
527
  assertNoRecursiveTestAllCommand(command);
519
- assertSandboxSafeTestRunnerCommand(command);
520
528
  }
521
529
  return parsed;
522
530
  });
@@ -1325,7 +1333,7 @@ function commandUsesTestNameFilter(command) {
1325
1333
  return true;
1326
1334
  }
1327
1335
  return splitNormalizedCommandSegments(normalized).some((segment) => /(?:^|\s)-t(?:=|\s)/u.test(segment) &&
1328
- segmentInvokesUnsafeDirectTestRunner(segment));
1336
+ segmentInvokesDirectTestRunner(segment));
1329
1337
  }
1330
1338
  function createLinkedTestSandboxLayout(sandboxRoot) {
1331
1339
  return {
@@ -2201,4 +2209,4 @@ export const _testOnlyTestCommand = {
2201
2209
  summarizeRunResultStatuses,
2202
2210
  };
2203
2211
  //# sourceMappingURL=execution.js.map
2204
- //# debugId=de5bc6bf-fe31-5643-a809-ee9ca52aac48
2212
+ //# debugId=03f2f710-3b96-5671-85fa-d8ea4726ee86
@@ -4,18 +4,25 @@ This guide is optimized for coding agents that need to understand and mutate rep
4
4
 
5
5
  ## Agent Quick Context
6
6
 
7
- Run this before heavy work:
7
+ Run this before heavy work. The first call is the canonical cold start. Then run the request-specific duplicate and ownership checks before item mutation:
8
8
 
9
9
  ```bash
10
- pm context --limit 10
10
+ pm context --limit 10 --for orient
11
11
  pm search "<request keywords>" --limit 10
12
12
  pm list --status open --limit 20
13
13
  pm list --status in_progress --limit 20
14
+ ```
15
+
16
+ Run the optional guidance setup commands only when needed:
17
+
18
+ ```bash
14
19
  pm init --agent-guidance status
15
- pm install guide-shell --project
20
+ pm package install guide-shell --project
16
21
  pm guide workflows
17
22
  ```
18
23
 
24
+ The completed-task replay gate selects that one-call protocol from equivalent fixed-corpus candidates: 1,055 estimated tokens versus 2,293 for the historical four-read sequence and 4,798 for `contracts --summary` plus `next`. The reviewed numbers and per-step receipts live in [the published token baseline](agent-task-token-baseline.json).
25
+
19
26
  If a relevant item exists, reuse it. If not, create a parent lineage, then create and claim the child implementation item.
20
27
  When AGENTS/CLAUDE guidance is missing, use `pm init --agent-guidance add` to inject compact workflow guardrails, or `pm init --agent-guidance skip` to persist an explicit decline.
21
28
 
@@ -26,7 +33,7 @@ Tracked documentation work: [pm-u9d0](../.agents/pm/epics/pm-u9d0.toon).
26
33
  1. **Orient**
27
34
 
28
35
  ```bash
29
- pm context --limit 10
36
+ pm context --limit 10 --for orient
30
37
  pm search "<keywords>" --limit 10
31
38
  pm list --status open --limit 20
32
39
  pm list --status in_progress --limit 20
@@ -108,6 +115,7 @@ pm release <item-id>
108
115
  | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
109
116
  | The single next action + why | `pm next` (concrete ready leaves first; completed-container closeout rows surface only when no leaf work is ready; `--ready-only` for the tightest output) |
110
117
  | Next ready work in one epic | `pm next --parent <id>` |
118
+ | Canonical cold-start orientation | `pm context --limit 10 --for orient` (1,055 estimated tokens on the fixed 101-item replay corpus) |
111
119
  | Next work and agenda | `pm context --limit 10` |
112
120
  | Comprehensive whole-tracker snapshot | `pm context --depth full` (every section, no per-section row cap) |
113
121
  | Status of one epic/subtree | `pm context --parent <id> --depth deep` |
@@ -84,7 +84,7 @@ Modern MCP clients may supply a bounded
84
84
  `io.modelcontextprotocol/clientInfo.provenance` map in each request's `_meta`.
85
85
  The server retains only valid dimension names and trimmed values, then resolves
86
86
  that map inside the invocation-scoped identity context for that request. The
87
- bounded `2025-06-18` adapter accepts the same map during legacy `initialize`.
87
+ bounded initialize-era adapter accepts the same map during legacy `initialize`.
88
88
  A missing MCP signal is recorded as explicit `null`; it is never confused with
89
89
  a legacy entry that predates the dimension.
90
90
 
@@ -158,8 +158,8 @@ summary. No history entry is rewritten.
158
158
 
159
159
  MCP 2026-07-28 reads `io.modelcontextprotocol/clientInfo` independently from
160
160
  every request's `_meta` and scopes only that request to the client signal. The
161
- bounded legacy adapter still reads `clientInfo` during `2025-06-18`
162
- `initialize`. Optional host-provided `model`, `session`, `provenance`, and
161
+ bounded legacy adapter still reads `clientInfo` during an initialize-era
162
+ handshake. Optional host-provided `model`, `session`, `provenance`, and
163
163
  `episode` fields are supported, but version is not misclassified as a model or
164
164
  session. Provenance keys must use the bounded
165
165
  lowercase dimension vocabulary; blank, malformed, and oversized data is
@@ -56,9 +56,12 @@ src/
56
56
  shared/
57
57
  mcp/
58
58
  server.ts
59
+ tool-definitions.ts
59
60
  sdk/
60
61
  cli-contracts.ts
61
62
  index.ts
63
+ mcp/
64
+ discovery.ts
62
65
  types/
63
66
  tests/
64
67
  unit/
@@ -287,6 +290,8 @@ allowance file:
287
290
  Do not add new CLI/MCP behavior by deep-importing `src/core`. Add or extend an
288
291
  SDK primitive first, then consume that SDK surface from the presentation layer.
289
292
 
293
+ Progressive tool discovery follows this boundary directly: `src/sdk/mcp/discovery.ts` owns ranking, authorization filtering, budgets, cursors, omissions, cache identity, and the canonical result contract. `src/mcp/server.ts` only negotiates the extension, selects the entry catalog, and adapts compatibility text. See [Progressive Tool Discovery](PROGRESSIVE_TOOL_DISCOVERY.md).
294
+
290
295
  ## Telemetry Schema Negotiation
291
296
 
292
297
  Telemetry preserves wire compatibility through an explicit client/server negotiation split: