@unbrained/pm-cli 2026.8.15 → 2026.8.17

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/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +56 -12
  3. package/README.md +13 -13
  4. package/dist/cli/error-guidance.d.ts +5 -0
  5. package/dist/cli/error-guidance.js +15 -2
  6. package/dist/cli/public.d.ts +2 -0
  7. package/dist/cli/public.js +21 -0
  8. package/dist/cli/register-history-author.js +16 -11
  9. package/dist/cli/register-mutation.js +4 -4
  10. package/dist/cli-bundle/bundle-manifest.json +143 -143
  11. package/dist/cli-bundle/chunks/{chunk-J42EGKDK.js → chunk-2QLOXC3V.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-LJHOAVGI.js → chunk-3UEGXBMR.js} +49 -43
  13. package/dist/cli-bundle/chunks/chunk-4JPYF536.js +35 -0
  14. package/dist/cli-bundle/chunks/chunk-6VDLG2FC.js +13 -0
  15. package/dist/cli-bundle/chunks/chunk-7IBRGCHX.js +2 -0
  16. package/dist/cli-bundle/chunks/chunk-HBJAS566.js +8 -0
  17. package/dist/cli-bundle/chunks/chunk-ION3E43Q.js +197 -0
  18. package/dist/cli-bundle/chunks/{chunk-WLPDLNEZ.js → chunk-JOKATURE.js} +4 -4
  19. package/dist/cli-bundle/chunks/{chunk-MEM2ZS3O.js → chunk-TPXZIBIV.js} +5 -5
  20. package/dist/cli-bundle/chunks/chunk-YM2YAMF7.js +2 -0
  21. package/dist/cli-bundle/chunks/{register-list-query-CT3LFDDN.js → register-list-query-Q7KII4G5.js} +2 -2
  22. package/dist/cli-bundle/chunks/{register-mutation-NWEVA5YS.js → register-mutation-4WBRPXLV.js} +3 -3
  23. package/dist/cli-bundle/chunks/{register-operations-AHIAG5KM.js → register-operations-SSENDH5B.js} +2 -2
  24. package/dist/cli-bundle/chunks/{register-setup-ZJZFVAKE.js → register-setup-DOSFBGKE.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-WTSER4WJ.js → chunk-267MUUS6.js} +11 -11
  26. package/dist/cli-bundle/focused-chunks/chunk-2NNFLLNG.js +2 -0
  27. package/dist/cli-bundle/focused-chunks/chunk-2QSAKMIH.js +2 -0
  28. package/dist/cli-bundle/focused-chunks/{chunk-ZMFXQ7VF.js → chunk-ATEY76SX.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/chunk-BUCG4ZI2.js +2 -0
  30. package/dist/cli-bundle/focused-chunks/{chunk-M67F5AIN.js → chunk-CYFK5UPB.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/chunk-EHXIKD6K.js +2 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-EXZA4257.js → chunk-KGEXTMPG.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-KP2VQQVQ.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-MHPIL773.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-POEEAD2V.js +4 -0
  36. package/dist/cli-bundle/focused-chunks/{chunk-ITAUHSO6.js → chunk-SALH6B6K.js} +47 -47
  37. package/dist/cli-bundle/focused-chunks/{chunk-KLVUMNXJ.js → chunk-SYZENPIT.js} +3 -3
  38. package/dist/cli-bundle/focused-chunks/{chunk-KTKH4IMG.js → chunk-XKAMP5OU.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/{chunk-NSPYTG6G.js → chunk-XPIC53VA.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-6XKF3PGV.js → chunk-ZQPGZZWQ.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/chunk-ZT2DJS27.js +155 -0
  42. package/dist/cli-bundle/main.js +10 -10
  43. package/dist/cli-bundle/sdk-authoring.js +1 -1
  44. package/dist/cli-bundle/sdk-contracts.js +1 -1
  45. package/dist/cli-bundle/sdk-core.js +31 -31
  46. package/dist/cli-bundle/sdk-governance.js +1 -1
  47. package/dist/cli-bundle/sdk-graph.js +1 -1
  48. package/dist/cli-bundle/sdk-merge.js +32 -32
  49. package/dist/cli-bundle/sdk-query.js +1 -1
  50. package/dist/cli-bundle/sdk-runtime.js +1 -1
  51. package/dist/cli-bundle/sdk-testing.js +1 -1
  52. package/dist/cli-bundle/sdk.js +4 -2
  53. package/dist/core/extensions/loader.js +10 -6
  54. package/dist/core/extensions/manifest-schema.d.ts +20 -0
  55. package/dist/core/extensions/manifest-schema.js +52 -0
  56. package/dist/core/history/replay.js +32 -14
  57. package/dist/core/history/workspace-history.js +32 -10
  58. package/dist/core/output/output.js +6 -3
  59. package/dist/core/schema/fields-file.d.ts +1 -1
  60. package/dist/core/schema/fields-file.js +2 -2
  61. package/dist/core/schema/runtime-field-values.js +115 -9
  62. package/dist/core/schema/runtime-schema.d.ts +3 -1
  63. package/dist/core/schema/runtime-schema.js +124 -3
  64. package/dist/core/shared/errors.d.ts +12 -0
  65. package/dist/core/shared/errors.js +2 -2
  66. package/dist/core/shared/time.d.ts +2 -0
  67. package/dist/core/shared/time.js +27 -2
  68. package/dist/core/store/item-store.js +28 -2
  69. package/dist/sdk/agent/refusal-reachability.d.ts +56 -8
  70. package/dist/sdk/agent/refusal-reachability.js +414 -4
  71. package/dist/sdk/author-attribution.d.ts +56 -11
  72. package/dist/sdk/author-attribution.js +174 -50
  73. package/dist/sdk/cli-contracts/flag-contracts.js +5 -2
  74. package/dist/sdk/cli-contracts/tool-parameter-tables.js +12 -4
  75. package/dist/sdk/cli-contracts/tool-schema.js +12 -4
  76. package/dist/sdk/completion.js +11 -4
  77. package/dist/sdk/compose.d.ts +6 -2
  78. package/dist/sdk/compose.js +33 -3
  79. package/dist/sdk/context-intent-contracts.d.ts +8 -4
  80. package/dist/sdk/context-intent-contracts.js +76 -31
  81. package/dist/sdk/dependency-flag-validation.d.ts +9 -2
  82. package/dist/sdk/dependency-flag-validation.js +101 -35
  83. package/dist/sdk/environment/host-environment-errors.js +25 -7
  84. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +62 -14
  85. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -2
  86. package/dist/sdk/governance/assurance-action.d.ts +3 -7
  87. package/dist/sdk/governance/assurance-action.js +97 -2
  88. package/dist/sdk/governance/boundary-fixtures.d.ts +86 -0
  89. package/dist/sdk/governance/boundary-fixtures.js +201 -0
  90. package/dist/sdk/governance/coverage-assurance.d.ts +24 -0
  91. package/dist/sdk/governance/coverage-assurance.js +61 -0
  92. package/dist/sdk/governance/defect-recurrence-signals.d.ts +10 -0
  93. package/dist/sdk/governance/defect-recurrence-signals.js +25 -0
  94. package/dist/sdk/governance/defect-recurrence.d.ts +242 -0
  95. package/dist/sdk/governance/defect-recurrence.js +523 -0
  96. package/dist/sdk/governance/extension-host-version.js +20 -9
  97. package/dist/sdk/governance.d.ts +2 -0
  98. package/dist/sdk/governance.js +4 -2
  99. package/dist/sdk/graph/governance.js +3 -2
  100. package/dist/sdk/guide-topics.js +191 -2
  101. package/dist/sdk/index.d.ts +5 -1
  102. package/dist/sdk/index.js +6 -3
  103. package/dist/sdk/lifecycle/create.js +4 -2
  104. package/dist/sdk/lifecycle/update-many.js +15 -2
  105. package/dist/sdk/lifecycle/update.js +5 -2
  106. package/dist/sdk/linked-artifacts.js +63 -14
  107. package/dist/sdk/query/get.d.ts +2 -0
  108. package/dist/sdk/query/get.js +32 -7
  109. package/dist/sdk/read-output-contracts.js +5 -3
  110. package/dist/sdk/relationship-analytics.js +90 -14
  111. package/dist/sdk/relationship-kinds/contract.d.ts +4 -0
  112. package/dist/sdk/relationship-kinds/contract.js +3 -2
  113. package/dist/sdk/relationships.d.ts +1 -1
  114. package/dist/sdk/relationships.js +11 -2
  115. package/dist/sdk/runtime.d.ts +2 -5
  116. package/dist/sdk/runtime.js +3 -2
  117. package/dist/sdk/schema.d.ts +1 -0
  118. package/dist/sdk/schema.js +2 -2
  119. package/dist/sdk/test/execution.d.ts +6 -2
  120. package/dist/sdk/test/execution.js +39 -13
  121. package/dist/types.d.ts +29 -2
  122. package/dist/types.js +4 -2
  123. package/docs/CONFIGURATION.md +58 -1
  124. package/docs/CONTEXT_INTEGRITY_CONTRACTS.md +58 -0
  125. package/docs/DEFECT_RECURRENCE.md +134 -0
  126. package/docs/DEPENDENCY_KIND_CONTRACT.md +12 -2
  127. package/docs/README.md +2 -0
  128. package/docs/READ_OUTPUT_CONTRACTS.md +7 -1
  129. package/docs/RELATIONSHIP_GRAPH.md +16 -2
  130. package/docs/RELEASING.md +13 -7
  131. package/docs/SDK.md +38 -5
  132. package/docs/SDK_CONTEXT_INTEGRITY.md +33 -5
  133. package/docs/SDK_CONTEXT_TRUTH_CONTRACTS.md +13 -5
  134. package/docs/SDK_RUNTIME_BOUNDARIES.md +9 -1
  135. package/docs/TESTING.md +18 -1
  136. package/docs/TRUSTWORTHY_CONTEXT_EVIDENCE.md +1 -1
  137. package/marketplace.json +2 -2
  138. package/package.json +6 -4
  139. package/packages/pm-beads/package.json +1 -1
  140. package/packages/pm-calendar/package.json +1 -1
  141. package/packages/pm-command-kit/package.json +1 -1
  142. package/packages/pm-digital-twin/package.json +1 -1
  143. package/packages/pm-governance-audit/package.json +1 -1
  144. package/packages/pm-guide-shell/package.json +1 -1
  145. package/packages/pm-kanban/package.json +1 -1
  146. package/packages/pm-lifecycle-hooks/package.json +1 -1
  147. package/packages/pm-linked-test-adapters/package.json +1 -1
  148. package/packages/pm-search-advanced/package.json +1 -1
  149. package/packages/pm-templates/package.json +1 -1
  150. package/packages/pm-todos/package.json +1 -1
  151. package/packages/pm-vcs/package.json +1 -1
  152. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  153. package/plugins/pm-claude/skills/pm-audit/SKILL.md +26 -0
  154. package/plugins/pm-claude/skills/pm-developer/SKILL.md +26 -0
  155. package/plugins/pm-claude/skills/pm-planner/SKILL.md +26 -0
  156. package/plugins/pm-claude/skills/pm-release/SKILL.md +26 -0
  157. package/plugins/pm-claude/skills/pm-workflow/SKILL.md +26 -0
  158. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  159. package/plugins/pm-codex/skills/pm-auditor/SKILL.md +26 -0
  160. package/plugins/pm-codex/skills/pm-native/SKILL.md +26 -0
  161. package/plugins/pm-codex/skills/pm-release/SKILL.md +26 -0
  162. package/sdk/public-surface.json +716 -33
  163. package/dist/cli-bundle/chunks/chunk-24GAV7XL.js +0 -8
  164. package/dist/cli-bundle/chunks/chunk-AIM6VT2N.js +0 -13
  165. package/dist/cli-bundle/chunks/chunk-DSWDLTDR.js +0 -197
  166. package/dist/cli-bundle/chunks/chunk-KIEGUBYQ.js +0 -2
  167. package/dist/cli-bundle/chunks/chunk-KLKYLSDX.js +0 -2
  168. package/dist/cli-bundle/chunks/chunk-QHPCJWEJ.js +0 -35
  169. package/dist/cli-bundle/focused-chunks/chunk-4X57RE4U.js +0 -2
  170. package/dist/cli-bundle/focused-chunks/chunk-7NJ4QYQ2.js +0 -2
  171. package/dist/cli-bundle/focused-chunks/chunk-KT5XMYSX.js +0 -4
  172. package/dist/cli-bundle/focused-chunks/chunk-OKA6ELTL.js +0 -2
  173. package/dist/cli-bundle/focused-chunks/chunk-PUISBOPP.js +0 -2
  174. package/dist/cli-bundle/focused-chunks/chunk-QLNMCESQ.js +0 -155
  175. package/dist/cli-bundle/focused-chunks/chunk-SLKC6QLJ.js +0 -2
  176. package/dist/cli-bundle/focused-chunks/chunk-U65UC4G3.js +0 -2
@@ -1,5 +1,5 @@
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]="3a33af50-3d2c-57bb-884a-4d5394599ba2")}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]="3167c288-0bcc-5a66-8aa0-ca5876ed7d36")}catch(e){}}();
3
3
  import { createQueryFingerprint, decodeQueryCursor, encodeQueryCursor, } from "./pagination.js";
4
4
  import { createRelationshipKindRegistry, } from "./relationships.js";
5
5
  function visitImpactNeighbor(state, id, parent, root, after, limit) {
@@ -216,12 +216,80 @@ export function analyzeRelationshipExecution(graph, options = {}) {
216
216
  provenance: { algorithm: "kahn-longest-path", edgeFamily: "ordering" },
217
217
  };
218
218
  }
219
- /** Compute bounded impact rows and exact shortest explanation paths. */
220
- export function analyzeGraphImpact(graph, root, options = {}) {
221
- const direction = options.direction ?? "outgoing";
219
+ /** Build impact-only adjacency from stored source-to-target orientation. */
220
+ function buildImpactAdjacency(graph, direction, kinds) {
221
+ const adjacency = createAdjacency(graph.nodes());
222
+ const selectedKinds = kinds === undefined
223
+ ? undefined
224
+ : new Set(kinds.map((kind) => graph.registry().require(kind).kind));
225
+ const edges = graph.edges();
226
+ for (const edge of edges) {
227
+ const definition = graph.registry().require(edge.kind);
228
+ if (selectedKinds !== undefined &&
229
+ !selectedKinds.has(edge.kind) &&
230
+ (definition.inverse === undefined ||
231
+ !selectedKinds.has(definition.inverse))) {
232
+ continue;
233
+ }
234
+ appendNeighbor(adjacency, direction === "incoming" ? edge.target : edge.source, direction === "incoming" ? edge.source : edge.target);
235
+ }
236
+ return { adjacency, inspectedEdges: edges.length };
237
+ }
238
+ /** Combine complete direction-locked incoming and outgoing impact traversals. */
239
+ function analyzeBidirectionalGraphImpact(graph, root, options, after, limit, cursorFingerprint) {
240
+ const incoming = analyzeGraphImpact(graph, root, {
241
+ ...options,
242
+ after: undefined,
243
+ direction: "incoming",
244
+ limit: undefined,
245
+ });
246
+ const outgoing = analyzeGraphImpact(graph, root, {
247
+ ...options,
248
+ after: undefined,
249
+ direction: "outgoing",
250
+ limit: undefined,
251
+ });
252
+ const rows = new Map();
253
+ const candidates = [...incoming.affected, ...outgoing.affected].sort((left, right) => left.distance - right.distance ||
254
+ left.id.localeCompare(right.id) ||
255
+ left.path.join("\u0000").localeCompare(right.path.join("\u0000")));
256
+ for (const row of candidates) {
257
+ if (!rows.has(row.id)) {
258
+ rows.set(row.id, row);
259
+ }
260
+ }
261
+ const ordered = [...rows.values()].sort((left, right) => left.distance - right.distance || left.id.localeCompare(right.id));
262
+ const afterIndex = after === undefined || after === root
263
+ ? -1
264
+ : ordered.findIndex((row) => row.id === after);
265
+ if (after !== undefined && after !== root && afterIndex < 0) {
266
+ throw new TypeError(`Unknown impact cursor item: ${after}`);
267
+ }
268
+ const affected = ordered.slice(afterIndex + 1, afterIndex + 1 + limit);
269
+ const rowLimitTruncated = afterIndex + 1 + affected.length < ordered.length;
270
+ return {
271
+ root,
272
+ affected,
273
+ exact: true,
274
+ truncated: incoming.truncated || outgoing.truncated || rowLimitTruncated,
275
+ ...(rowLimitTruncated
276
+ ? {
277
+ nextCursor: encodeQueryCursor(cursorFingerprint, affected.at(-1)?.id ?? root),
278
+ }
279
+ : {}),
280
+ cost: {
281
+ visitedNodes: incoming.cost.visitedNodes + outgoing.cost.visitedNodes,
282
+ inspectedEdges: incoming.cost.inspectedEdges + outgoing.cost.inspectedEdges,
283
+ },
284
+ };
285
+ }
286
+ /** Compute one stored-direction impact traversal and exact shortest explanation paths. */
287
+ function analyzeUnidirectionalGraphImpact(graph, root, options) {
288
+ const direction = options.direction;
222
289
  const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
223
290
  const limit = options.limit ?? Number.POSITIVE_INFINITY;
224
291
  const { fingerprint: cursorFingerprint, after } = resolveImpactCursor(root, options, direction, maxDepth);
292
+ const { adjacency, inspectedEdges } = buildImpactAdjacency(graph, direction, options.kinds);
225
293
  const state = {
226
294
  queue: [{ id: root, depth: 0 }],
227
295
  seen: new Set([root]),
@@ -230,25 +298,19 @@ export function analyzeGraphImpact(graph, root, options = {}) {
230
298
  cursorFound: after === undefined || after === root,
231
299
  };
232
300
  let visitedNodes = 0;
233
- let inspectedEdges = 0;
234
301
  let truncated = false;
235
302
  let rowLimitTruncated = false;
236
303
  traversal: for (let index = 0; index < state.queue.length; index += 1) {
237
304
  options.signal?.throwIfAborted();
238
305
  const current = state.queue[index];
239
306
  visitedNodes += 1;
240
- const adjacent = graph.adjacency(current.id, {
241
- direction,
242
- kinds: options.kinds,
243
- signal: options.signal,
244
- });
245
- inspectedEdges += adjacent.meta.inspectedEdges;
307
+ const adjacent = [...adjacency.get(current.id)].sort();
246
308
  if (current.depth >= maxDepth) {
247
- if (adjacent.value.some((id) => !state.seen.has(id)))
309
+ if (adjacent.some((id) => !state.seen.has(id)))
248
310
  truncated = true;
249
311
  continue;
250
312
  }
251
- for (const id of adjacent.value) {
313
+ for (const id of adjacent) {
252
314
  const outcome = visitImpactNeighbor(state, id, current, root, after, limit);
253
315
  if (outcome === "truncate") {
254
316
  truncated = true;
@@ -273,6 +335,20 @@ export function analyzeGraphImpact(graph, root, options = {}) {
273
335
  cost: { visitedNodes, inspectedEdges },
274
336
  };
275
337
  }
338
+ /** Compute bounded impact rows and exact shortest explanation paths. */
339
+ export function analyzeGraphImpact(graph, root, options = {}) {
340
+ const direction = options.direction ?? "outgoing";
341
+ if (direction !== "both") {
342
+ return analyzeUnidirectionalGraphImpact(graph, root, {
343
+ ...options,
344
+ direction,
345
+ });
346
+ }
347
+ const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
348
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
349
+ const { fingerprint, after } = resolveImpactCursor(root, options, direction, maxDepth);
350
+ return analyzeBidirectionalGraphImpact(graph, root, options, after, limit, fingerprint);
351
+ }
276
352
  /** Analyze weak/strong components, isolates, and exact unique-neighbor hubs. */
277
353
  export function analyzeKnowledgeGraph(graph) {
278
354
  const nodes = [...graph.nodes()];
@@ -332,4 +408,4 @@ export function compareRelationshipSnapshots(before, after) {
332
408
  };
333
409
  }
334
410
  //# sourceMappingURL=relationship-analytics.js.map
335
- //# debugId=3a33af50-3d2c-57bb-884a-4d5394599ba2
411
+ //# debugId=3167c288-0bcc-5a66-8aa0-ca5876ed7d36
@@ -9,6 +9,8 @@ export type RelationshipDirection = "directed" | "undirected";
9
9
  export type RelationshipCardinality = "one" | "many";
10
10
  /** Lifecycle policy for a relationship kind. */
11
11
  export type RelationshipLifecycle = "persistent" | "supersedable" | "ephemeral";
12
+ /** Temporal meaning carried by a directed relationship independently of execution precedence. */
13
+ export type RelationshipTemporalOrder = "source_after_target";
12
14
  /** Direction in which an ordering edge contributes to execution precedence. */
13
15
  export type RelationshipPrecedence = "source_before_target" | "target_before_source";
14
16
  /** Endpoint that represents the structural parent for hierarchy kinds. */
@@ -23,6 +25,8 @@ export interface RelationshipKindDefinition {
23
25
  inverse?: string;
24
26
  /** Whether the kind participates in execution-order cycle checks. */
25
27
  ordering: boolean;
28
+ /** Optional chronological constraint; recurrence uses source-after-target without becoming scheduling precedence. */
29
+ temporalOrder?: RelationshipTemporalOrder;
26
30
  /** Execution direction for ordering kinds; defaults to source before target. */
27
31
  precedence?: RelationshipPrecedence;
28
32
  /** Whether the kind contributes to structural ancestry. */
@@ -5,7 +5,7 @@
5
5
  */
6
6
  /** Stable built-in relationship ontology without graph or storage dependencies. */
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]="49a83ce3-4c55-5b3f-b061-bc21b716d498")}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]="825e1dd9-4168-56f6-9183-b8cf75314b73")}catch(e){}}();
9
9
  export const BUILTIN_RELATIONSHIP_KINDS = [
10
10
  { kind: "blocked_by", direction: "directed", inverse: "blocks", ordering: true, precedence: "target_before_source", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", aliases: ["depends_on"], compatibilityVersion: 1, allowSelf: false },
11
11
  { kind: "blocks", direction: "directed", inverse: "blocked_by", ordering: true, precedence: "source_before_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
@@ -15,8 +15,9 @@ export const BUILTIN_RELATIONSHIP_KINDS = [
15
15
  { kind: "discovered_from", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
16
16
  { kind: "incident_from", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
17
17
  { kind: "implements", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
18
+ { kind: "recurs_from", direction: "directed", ordering: false, temporalOrder: "source_after_target", hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
18
19
  { kind: "verifies", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "persistent", compatibilityVersion: 1, allowSelf: false },
19
20
  { kind: "supersedes", direction: "directed", ordering: false, hierarchy: false, outgoing: "many", incoming: "many", lifecycle: "supersedable", compatibilityVersion: 1, allowSelf: false },
20
21
  ];
21
22
  //# sourceMappingURL=contract.js.map
22
- //# debugId=49a83ce3-4c55-5b3f-b061-bc21b716d498
23
+ //# debugId=825e1dd9-4168-56f6-9183-b8cf75314b73
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { Dependency, ItemMetadata } from "../types/index.js";
8
8
  import { type RelationshipKindDefinition } from "./relationship-kinds/contract.js";
9
- export { BUILTIN_RELATIONSHIP_KINDS, type RelationshipCardinality, type RelationshipDirection, type RelationshipHierarchyDirection, type RelationshipKindDefinition, type RelationshipLifecycle, type RelationshipPrecedence, } from "./relationship-kinds/contract.js";
9
+ export { BUILTIN_RELATIONSHIP_KINDS, type RelationshipCardinality, type RelationshipDirection, type RelationshipHierarchyDirection, type RelationshipKindDefinition, type RelationshipLifecycle, type RelationshipPrecedence, type RelationshipTemporalOrder, } from "./relationship-kinds/contract.js";
10
10
  /** One normalized relationship edge indexed by the graph kernel. */
11
11
  export interface RelationshipEdge {
12
12
  /** Source node identifier. */
@@ -1,5 +1,5 @@
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]="05e01593-acb6-5e28-a5ac-8c8f74359c62")}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]="7f733de4-104b-50a9-9c0a-cd9850bfcd78")}catch(e){}}();
3
3
  import { BUILTIN_RELATIONSHIP_KINDS, } from "./relationship-kinds/contract.js";
4
4
  export { BUILTIN_RELATIONSHIP_KINDS, } from "./relationship-kinds/contract.js";
5
5
  function normalizeKind(kind) {
@@ -36,6 +36,14 @@ function assertRelationshipPrecedence(definition, kind) {
36
36
  if (!definition.ordering && definition.precedence !== undefined)
37
37
  throw new TypeError(`Non-ordering relationship kind cannot declare precedence: ${kind}`);
38
38
  }
39
+ function assertRelationshipTemporalOrder(definition, kind) {
40
+ if (definition.temporalOrder !== undefined &&
41
+ definition.temporalOrder !== "source_after_target")
42
+ throw new TypeError(`Invalid relationship temporal order for ${kind}`);
43
+ if (definition.direction !== "directed" &&
44
+ definition.temporalOrder !== undefined)
45
+ throw new TypeError(`Undirected relationship kind cannot declare temporal order: ${kind}`);
46
+ }
39
47
  function assertRelationshipHierarchyDirection(definition, kind) {
40
48
  if (definition.hierarchyDirection !== undefined &&
41
49
  definition.hierarchyDirection !== "source_parent" &&
@@ -102,6 +110,7 @@ export class RelationshipKindRegistry {
102
110
  assertRelationshipKindSemantics(definition, kind);
103
111
  assertRelationshipKindPayload(definition, kind);
104
112
  assertRelationshipPrecedence(definition, kind);
113
+ assertRelationshipTemporalOrder(definition, kind);
105
114
  assertRelationshipHierarchyDirection(definition, kind);
106
115
  if (this.#definitions.has(kind) || this.#aliases.has(kind))
107
116
  throw new TypeError(`Relationship kind already registered: ${kind}`);
@@ -543,4 +552,4 @@ export function dependencyToRelationship(source, dependency, registry = defaultR
543
552
  };
544
553
  }
545
554
  //# sourceMappingURL=relationships.js.map
546
- //# debugId=05e01593-acb6-5e28-a5ac-8c8f74359c62
555
+ //# debugId=7f733de4-104b-50a9-9c0a-cd9850bfcd78
@@ -33,7 +33,7 @@ import { type GcCommandOptions, type GcResult } from "./governance/gc.js";
33
33
  import { type HealthResult, type RunHealthOptions } from "./governance/health.js";
34
34
  import { type ValidateCommandOptions, type ValidateCountsResult, type ValidateResult } from "./governance/validate.js";
35
35
  import { type ExtensionCommandOptions, type ExtensionCommandResult } from "./extension.js";
36
- import { type AcknowledgeUnknownAuthorEventsOptions } from "./author-attribution.js";
36
+ import { type AcknowledgeUnknownAuthorEventsOptions, type UnknownAuthorAcknowledgmentResult } from "./author-attribution.js";
37
37
  import { type HistoryCompactBulkCommandOptions, type HistoryCompactBulkResult, type HistoryCompactCommandOptions, type HistoryCompactResult } from "./history-compact.js";
38
38
  import { type HistoryRedactCommandOptions, type HistoryRedactResult } from "./history-redact.js";
39
39
  import { type HistoryRepairAllResult, type HistoryRepairCommandOptions, type HistoryRepairResult } from "./history-repair.js";
@@ -250,10 +250,7 @@ export declare class PmClient {
250
250
  /** Compact an explicit or policy-selected set of history streams. */
251
251
  historyCompactBulk(options: HistoryCompactBulkCommandOptions): Promise<HistoryCompactBulkResult>;
252
252
  /** Disposition immutable unknown-author events through append-only audit history. */
253
- historyAuthorAcknowledge(options: AcknowledgeUnknownAuthorEventsOptions): Promise<{
254
- acknowledged: number;
255
- history_path: string;
256
- }>;
253
+ historyAuthorAcknowledge(options: AcknowledgeUnknownAuthorEventsOptions): Promise<UnknownAuthorAcknowledgmentResult>;
257
254
  /** Run any typed plan workflow primitive through the shared CLI/MCP engine. */
258
255
  plan(subcommand: PlanSubcommand, id?: string, options?: PlanCommandOptions, stepRef?: string, reorderTo?: number): Promise<PlanCommandResult>;
259
256
  /** Create a durable plan with optional ordered seed steps. */
@@ -4,7 +4,7 @@
4
4
  * Defines public SDK APIs and package-author helpers for Runtime.
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]="a387cd7a-cb16-5082-80e1-9632ebd02480")}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]="bedbe090-60c3-5935-a656-da4997cd80f7")}catch(e){}}();
8
8
  export { PM_GITIGNORE_END, PM_GITIGNORE_START, ensurePmGitignore, getPmGitignoreBlock, } from "./workspace.js";
9
9
  export { SEARCH_EXTENSION_FLAG_DEFINITIONS } from "./extension-contracts.js";
10
10
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -442,6 +442,7 @@ export class PmClient {
442
442
  return this.runTyped("history-author-acknowledge", {
443
443
  historyEvent: (options.events ?? []).map((event) => `${event.item_id}:${String(event.line)}`),
444
444
  allActionable: options.all_actionable === true,
445
+ dryRun: options.dry_run === true, planFingerprint: options.plan_fingerprint, limit: options.coordinate_limit,
445
446
  attributedAuthor: options.attributed_author,
446
447
  reviewer: options.reviewer,
447
448
  reason: options.reason,
@@ -1932,4 +1933,4 @@ async function loadWorkspaceExtensionRegistrations(pmRoot, settings, cwd) {
1932
1933
  }
1933
1934
  }
1934
1935
  //# sourceMappingURL=runtime.js.map
1935
- //# debugId=a387cd7a-cb16-5082-80e1-9632ebd02480
1936
+ //# debugId=bedbe090-60c3-5935-a656-da4997cd80f7
@@ -500,6 +500,7 @@ export declare function formatSchemaApplyPresetHuman(result: SchemaApplyPresetRe
500
500
  export declare function formatSchemaInferTypesHuman(result: SchemaAddTypeInferResult): string;
501
501
  /** Re-export so register-mutation can surface the hint in usage examples without importing the core module directly. */
502
502
  export { buildInvalidTypeHint };
503
+ export type { RuntimeFieldDefinition, RuntimeFieldValueSchema, } from "../core/schema/fields-file.js";
503
504
  /** Public contract for test only schema command, shared by SDK and presentation-layer consumers. */
504
505
  export declare const _testOnlySchemaCommand: {
505
506
  workflowSlotsReferencing: typeof workflowSlotsReferencing;
@@ -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]="1a035e10-b8fe-52cd-a9c7-0762dd0ab160")}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]="2ab8a5a9-dbea-526f-a541-b7ca2b106ac5")}catch(e){}}();
8
8
  import path from "node:path";
9
9
  import { mkdir } from "node:fs/promises";
10
10
  import { resolveAuthor } from "../core/shared/author.js";
@@ -1365,4 +1365,4 @@ export const _testOnlySchemaCommand = {
1365
1365
  workflowSlotsReferencing,
1366
1366
  };
1367
1367
  //# sourceMappingURL=schema.js.map
1368
- //# debugId=1a035e10-b8fe-52cd-a9c7-0762dd0ab160
1368
+ //# debugId=2ab8a5a9-dbea-526f-a541-b7ca2b106ac5
@@ -201,7 +201,9 @@ declare function formatLinkedTestExecutionError(result: LinkedTestExecutionResul
201
201
  export declare function classifyLinkedTestFailure(result: Pick<LinkedTestExecutionResult, "stdout" | "stderr" | "spawnError" | "signal" | "timedOut" | "maxBufferExceeded">): LinkedTestFailureCategory;
202
202
  /** Implements count failure categories for the public runtime surface of this module. */
203
203
  export declare function countFailureCategories(runResults: TestRunResult[]): Record<LinkedTestFailureCategory, number>;
204
- declare function copyIntoSandboxIfPresent(sourcePath: string, targetPath: string, recursive?: boolean): Promise<void>;
204
+ declare function copyIntoSandboxIfPresent(sourcePath: string, targetPath: string, recursive?: boolean, makeDirectory?: (targetPath: string, options: {
205
+ recursive: true;
206
+ }) => Promise<unknown>): Promise<void>;
205
207
  declare function seedLinkedTestSandbox(sandboxPmPath: string, sandboxGlobalPath: string, sourceRoots: LinkedTestSandboxSourceRoots): Promise<void>;
206
208
  declare function seedLinkedTestTrackerData(sourceRoot: string, sandboxRoot: string): Promise<void>;
207
209
  declare function countLinkedTestItemFiles(pmRoot: string): Promise<number>;
@@ -242,7 +244,8 @@ interface LinkedTestSandboxCounts {
242
244
  trackerProjectItemCount: number;
243
245
  trackerGlobalItemCount: number;
244
246
  }
245
- declare function initializeLinkedTestSandboxes(layout: LinkedTestSandboxLayout, initialize?: (...args: Parameters<typeof runInit>) => Promise<unknown>): Promise<void>;
247
+ declare function initializeLinkedTestSandboxes(layout: LinkedTestSandboxLayout, initialize?: (...args: Parameters<typeof runInit>) => Promise<unknown>, includeTrackerData?: boolean): Promise<void>;
248
+ declare function linkedTestsRequireTrackerData(tests: LinkedTest[], runLevelPmContextMode: LinkedTestPmContextMode, options: RunLinkedTestsOptions | undefined): boolean;
246
249
  declare function buildLinkedTestExecutionContext(params: {
247
250
  layout: LinkedTestSandboxLayout;
248
251
  counts: LinkedTestSandboxCounts;
@@ -280,6 +283,7 @@ export declare const _testOnlyTestCommand: {
280
283
  formatLinkedTestExecutionError: typeof formatLinkedTestExecutionError;
281
284
  hasLinkedTestAssertions: typeof hasLinkedTestAssertions;
282
285
  initializeLinkedTestSandboxes: typeof initializeLinkedTestSandboxes;
286
+ linkedTestsRequireTrackerData: typeof linkedTestsRequireTrackerData;
283
287
  parseAddJsonEntries: typeof parseAddJsonEntries;
284
288
  parseLinkedTestTimeoutSeconds: typeof parseLinkedTestTimeoutSeconds;
285
289
  parsePmContextMode: typeof parsePmContextMode;
@@ -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]="76053150-cc55-57e0-80d6-369196284cd0")}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]="4322c352-6b95-5796-94eb-5a68745d53bc")}catch(e){}}();
8
8
  import { spawn } from "node:child_process";
9
9
  import { cp, mkdir, mkdtemp, open, readdir, rm } from "node:fs/promises";
10
10
  import { tmpdir } from "node:os";
@@ -28,6 +28,7 @@ import { LINKED_TEST_PM_CONTEXT_MODE_VALUES as PM_CONTEXT_MODE_VALUES, LINKED_TE
28
28
  import { parseOnlyIndexValue, resolveLinkedTestRunSelection, } from "../../core/test/run-selectors.js";
29
29
  import { SCOPE_VALUES } from "../../types/index.js";
30
30
  import { diffTestRunMeasurements, parseTestRunMeasurements, queryTestRunMeasurementsBelow, } from "./measurements.js";
31
+ import { withHostEnvironmentBoundary } from "../environment/host-environment-errors.js";
31
32
  import { SOURCE_CONTEXT_ACCESS_ENV } from "../environment/source-context.js";
32
33
  const TEST_OUTPUT_MAX_BUFFER_BYTES = 20 * 1024 * 1024;
33
34
  const DEFAULT_LINKED_TEST_TIMEOUT_FORCE_KILL_DELAY_MS = 3000;
@@ -973,17 +974,24 @@ function resolveRuntimeDirectives(envSetEntries, envClearEntries, sharedHostSafe
973
974
  };
974
975
  }
975
976
  /* c8 ignore start -- sandbox copy race/path permutations are covered by filesystem integration suites */
976
- async function copyIntoSandboxIfPresent(sourcePath, targetPath, recursive = false) {
977
+ async function copyIntoSandboxIfPresent(sourcePath, targetPath, recursive = false, makeDirectory = mkdir) {
977
978
  if (!(await pathExists(sourcePath))) {
978
979
  return;
979
980
  }
980
- await mkdir(path.dirname(targetPath), { recursive: true });
981
981
  try {
982
- if (recursive) {
983
- await cp(sourcePath, targetPath, { recursive: true, force: true });
984
- return;
985
- }
986
- await cp(sourcePath, targetPath, { force: true });
982
+ await withHostEnvironmentBoundary("seed_linked_test", async () => {
983
+ await makeDirectory(path.dirname(targetPath), { recursive: true });
984
+ if (recursive) {
985
+ await cp(sourcePath, targetPath, { recursive: true, force: true });
986
+ return;
987
+ }
988
+ await cp(sourcePath, targetPath, { force: true });
989
+ }, {
990
+ why: "Linked tests need an isolated PM context without mutating the source tracker.",
991
+ nextSteps: [
992
+ "Reclaim capacity on the filesystem that hosts the linked-test temporary directory.",
993
+ ],
994
+ });
987
995
  }
988
996
  catch (error) {
989
997
  if (typeof error === "object" &&
@@ -1257,22 +1265,38 @@ function createLinkedTestSandboxLayout(sandboxRoot) {
1257
1265
  trackerGlobalPmPath: path.join(sandboxRoot, "tracker", "global"),
1258
1266
  };
1259
1267
  }
1260
- async function initializeLinkedTestSandboxes(layout, initialize = runInit) {
1268
+ async function initializeLinkedTestSandboxes(layout, initialize = runInit, includeTrackerData = true) {
1261
1269
  const initOptions = { defaults: true, agentGuidance: "skip" };
1262
1270
  await initialize(undefined, { path: layout.schemaProjectPmPath }, initOptions);
1263
1271
  await initialize(undefined, { path: layout.schemaGlobalPmPath }, initOptions);
1272
+ if (!includeTrackerData) {
1273
+ return;
1274
+ }
1264
1275
  await initialize(undefined, { path: layout.trackerProjectPmPath }, initOptions);
1265
1276
  await initialize(undefined, { path: layout.trackerGlobalPmPath }, initOptions);
1266
1277
  }
1267
- async function seedLinkedTestSandboxesFromSource(layout, sourceRoots) {
1278
+ async function seedLinkedTestSandboxesFromSource(layout, sourceRoots, includeTrackerData) {
1268
1279
  if (!sourceRoots) {
1269
1280
  return;
1270
1281
  }
1271
1282
  await seedLinkedTestSandbox(layout.schemaProjectPmPath, layout.schemaGlobalPmPath, sourceRoots);
1283
+ if (!includeTrackerData) {
1284
+ return;
1285
+ }
1272
1286
  await seedLinkedTestSandbox(layout.trackerProjectPmPath, layout.trackerGlobalPmPath, sourceRoots);
1273
1287
  await seedLinkedTestTrackerData(sourceRoots.projectPmRoot, layout.trackerProjectPmPath);
1274
1288
  await seedLinkedTestTrackerData(sourceRoots.globalPmRoot, layout.trackerGlobalPmPath);
1275
1289
  }
1290
+ function linkedTestsRequireTrackerData(tests, runLevelPmContextMode, options) {
1291
+ return tests.some((linkedTest) => {
1292
+ const command = linkedTest.command ?? "";
1293
+ const isPmTrackerReadCommand = command.length > 0 && commandInvokesPmTrackerReadCommand(command);
1294
+ const requestedPmContextMode = options?.autoPmContext === true && isPmTrackerReadCommand
1295
+ ? "auto"
1296
+ : resolveLinkedTestRequestedContextMode(linkedTest, runLevelPmContextMode, options?.overrideLinkedPmContext === true);
1297
+ return (resolveLinkedTestEffectiveContextMode(requestedPmContextMode, isPmTrackerReadCommand) === "tracker");
1298
+ });
1299
+ }
1276
1300
  async function countLinkedTestSandboxItems(layout, sourceRoots) {
1277
1301
  return {
1278
1302
  sourceProjectItemCount: sourceRoots
@@ -1510,9 +1534,10 @@ export async function runLinkedTests(tests, defaultTimeoutSeconds, options) {
1510
1534
  const progressMode = options?.progress === true ? "always" : "auto";
1511
1535
  const runtimeDirectives = resolveRuntimeDirectives(options?.envSet, options?.envClear, options?.sharedHostSafe);
1512
1536
  const sourceRoots = options?.sourceRoots;
1537
+ const includeTrackerData = linkedTestsRequireTrackerData(tests, runLevelPmContextMode, options);
1513
1538
  try {
1514
- await initializeLinkedTestSandboxes(layout);
1515
- await seedLinkedTestSandboxesFromSource(layout, sourceRoots);
1539
+ await initializeLinkedTestSandboxes(layout, runInit, includeTrackerData);
1540
+ await seedLinkedTestSandboxesFromSource(layout, sourceRoots, includeTrackerData);
1516
1541
  const counts = await countLinkedTestSandboxItems(layout, sourceRoots);
1517
1542
  for (let index = 0; index < tests.length; index += 1) {
1518
1543
  const linkedTest = tests[index];
@@ -1920,6 +1945,7 @@ export const _testOnlyTestCommand = {
1920
1945
  formatLinkedTestExecutionError,
1921
1946
  hasLinkedTestAssertions,
1922
1947
  initializeLinkedTestSandboxes,
1948
+ linkedTestsRequireTrackerData,
1923
1949
  parseAddJsonEntries,
1924
1950
  parseLinkedTestTimeoutSeconds,
1925
1951
  parsePmContextMode,
@@ -1939,4 +1965,4 @@ export const _testOnlyTestCommand = {
1939
1965
  summarizeRunResultStatuses,
1940
1966
  };
1941
1967
  //# sourceMappingURL=execution.js.map
1942
- //# debugId=76053150-cc55-57e0-80d6-369196284cd0
1968
+ //# debugId=4322c352-6b95-5796-94eb-5a68745d53bc
package/dist/types.d.ts CHANGED
@@ -32,7 +32,7 @@ export declare const RUNTIME_UNKNOWN_FIELD_POLICY_VALUES: readonly ["allow", "wa
32
32
  /** Restricts runtime unknown field policy values accepted by command, SDK, and storage contracts. */
33
33
  export type RuntimeUnknownFieldPolicy = (typeof RUNTIME_UNKNOWN_FIELD_POLICY_VALUES)[number];
34
34
  /** Supported values accepted by the dependency kind contract. */
35
- export declare const DEPENDENCY_KIND_VALUES: readonly ["blocks", "parent", "child", "parent_child", "child_of", "related", "related_to", "discovered_from", "blocked_by", "incident_from", "epic", "implements", "supersedes", "task", "verifies"];
35
+ export declare const DEPENDENCY_KIND_VALUES: readonly ["blocks", "parent", "child", "parent_child", "child_of", "related", "related_to", "discovered_from", "blocked_by", "incident_from", "epic", "implements", "recurs_from", "supersedes", "task", "verifies"];
36
36
  /** Restricts dependency kind values accepted by command, SDK, and storage contracts. */
37
37
  export type DependencyKind = (typeof DEPENDENCY_KIND_VALUES)[number];
38
38
  /** Supported values accepted by the scope contract. */
@@ -266,7 +266,7 @@ export declare const PLAN_HARNESS_VALUES: readonly ["codex", "claude-code", "cur
266
266
  /** Restricts plan harness values accepted by command, SDK, and storage contracts. */
267
267
  export type PlanHarness = (typeof PLAN_HARNESS_VALUES)[number];
268
268
  /** Supported values accepted by the plan step link kind contract. */
269
- export declare const PLAN_STEP_LINK_KIND_VALUES: readonly ["related", "blocks", "blocked_by", "depends_on", "discovered_from", "implements", "verifies", "supersedes"];
269
+ export declare const PLAN_STEP_LINK_KIND_VALUES: readonly ["related", "blocks", "blocked_by", "depends_on", "discovered_from", "implements", "recurs_from", "verifies", "supersedes"];
270
270
  /** Restricts plan step link kind values accepted by command, SDK, and storage contracts. */
271
271
  export type PlanStepLinkKind = (typeof PLAN_STEP_LINK_KIND_VALUES)[number];
272
272
  /** Documents the plan step link payload exchanged by command, SDK, and package integrations. */
@@ -437,6 +437,31 @@ export interface RuntimeStatusDefinition {
437
437
  /** Value that configures or reports order for this contract. */
438
438
  order?: number;
439
439
  }
440
+ /** Declarative JSON-value constraints enforced before custom-field persistence. */
441
+ export interface RuntimeFieldValueSchema {
442
+ /** Optional JSON value type constraint. */
443
+ type?: "string" | "number" | "boolean" | "array" | "object";
444
+ /** Exact JSON value required by this schema branch. */
445
+ const?: StructuredJsonValue;
446
+ /** Complete allowed JSON value set. */
447
+ enum?: StructuredJsonValue[];
448
+ /** Minimum accepted string length. */
449
+ min_length?: number;
450
+ /** Minimum accepted array length. */
451
+ min_items?: number;
452
+ /** Optional semantic string format. */
453
+ format?: "date-time";
454
+ /** Object-property schemas keyed by the persisted property name. */
455
+ properties?: Record<string, RuntimeFieldValueSchema>;
456
+ /** Object properties that must be present. */
457
+ required?: string[];
458
+ /** Whether properties absent from `properties` are accepted. */
459
+ additional_properties?: boolean;
460
+ /** Schema applied to every array element. */
461
+ items?: RuntimeFieldValueSchema;
462
+ /** Alternative schemas of which exactly one must match. */
463
+ one_of?: RuntimeFieldValueSchema[];
464
+ }
440
465
  /** Documents the runtime field definition payload exchanged by command, SDK, and package integrations. */
441
466
  export interface RuntimeFieldDefinition {
442
467
  /** Value that configures or reports key for this contract. */
@@ -467,6 +492,8 @@ export interface RuntimeFieldDefinition {
467
492
  required_types?: string[];
468
493
  /** Value that configures or reports allow unset for this contract. */
469
494
  allow_unset?: boolean;
495
+ /** Optional semantic JSON-value constraints enforced on create and update. */
496
+ value_schema?: RuntimeFieldValueSchema;
470
497
  }
471
498
  /** Documents the runtime workflow definition payload exchanged by command, SDK, and package integrations. */
472
499
  export interface RuntimeWorkflowDefinition {
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]="8b39bc01-0325-5dc6-8492-585c98608076")}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]="4e2028b3-6718-509a-b687-d1df58962387")}catch(e){}}();
9
9
  export const BUILTIN_ITEM_TYPE_VALUES = [
10
10
  "Epic",
11
11
  "Feature",
@@ -81,6 +81,7 @@ export const DEPENDENCY_KIND_VALUES = [
81
81
  "incident_from",
82
82
  "epic",
83
83
  "implements",
84
+ "recurs_from",
84
85
  "supersedes",
85
86
  "task",
86
87
  "verifies",
@@ -217,6 +218,7 @@ export const PLAN_STEP_LINK_KIND_VALUES = [
217
218
  "depends_on",
218
219
  "discovered_from",
219
220
  "implements",
221
+ "recurs_from",
220
222
  "verifies",
221
223
  "supersedes",
222
224
  ];
@@ -241,4 +243,4 @@ export const CONTEXT_SECTION_VALUES = [
241
243
  "tests",
242
244
  ];
243
245
  //# sourceMappingURL=types.js.map
244
- //# debugId=8b39bc01-0325-5dc6-8492-585c98608076
246
+ //# debugId=4e2028b3-6718-509a-b687-d1df58962387
@@ -156,7 +156,7 @@ Telemetry is opt-in via `pm config set telemetry-tracking on` (see [Common Setti
156
156
  | `PM_TELEMETRY_OTEL_DISABLED` | boolean | Disable only OTLP trace-span export; the event queue still flushes. |
157
157
  | `PM_TELEMETRY_INLINE_FLUSH` | boolean | Flush the queue and OTLP spans inline instead of dispatching the detached worker. Mainly for tests; normal use relies on the background worker. |
158
158
  | `PM_TELEMETRY_SOURCE_CONTEXT` | `user` \| `automation` \| `test` \| `dogfood` | Override the inferred source context recorded on each event. Any other value is ignored and the context is inferred. |
159
- | `PM_TELEMETRY_HTTP_TIMEOUT_MS` | integer milliseconds | Bound each background event or OTLP request (default `20000`, clamped to `1000`–`25000` to stay below the worker lock TTL). |
159
+ | `PM_TELEMETRY_HTTP_TIMEOUT_MS` | integer milliseconds | Bound each background event or OTLP request (default `20000`, clamped to `1000`–`25000` to stay below the worker lock TTL). |
160
160
  | `PM_TELEMETRY_INGEST_KEY` | string | Sent as the `x-pm-telemetry-key` header on queue flushes; never logged. |
161
161
  | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | URL | OTLP/HTTP traces endpoint for command spans. Takes precedence over the base endpoint. |
162
162
  | `OTEL_EXPORTER_OTLP_ENDPOINT` | URL | Base OTLP endpoint; the traces endpoint is derived by appending `/v1/traces`. |
@@ -523,6 +523,11 @@ Fields live in `.agents/pm/schema/fields.json` with the shape `{ "fields": [Runt
523
523
  "required_on_create": false, // required only on create
524
524
  "allow_unset": true, // allow clearing via --component "" / --no-component
525
525
  "required_types": ["Task"], // only required for these item types (subset of required*)
526
+ "value_schema": {
527
+ // optional recursive semantic constraints
528
+ "type": "string",
529
+ "enum": ["frontend", "backend", "operations"],
530
+ },
526
531
  },
527
532
  ],
528
533
  }
@@ -541,6 +546,7 @@ Fields live in `.agents/pm/schema/fields.json` with the shape `{ "fields": [Runt
541
546
  - `allow_unset` — when `true` (default), the field can be cleared; when `false`, an explicit unset is rejected.
542
547
  - `required_types` — narrows `required`/`required_on_create` to only the listed item types.
543
548
  - `description` — surfaced in `--help`.
549
+ - `value_schema` — optional recursive JSON-value validation applied after CLI coercion and before create/update persistence. It supports `type`, `const`, `enum`, `min_length`, `min_items`, `format: "date-time"`, object `properties`/`required`/`additional_properties`, array `items`, and exact-one `one_of` variants. This lets project-defined fields enforce domain semantics without custom command code.
544
550
 
545
551
  End-to-end example — add a required-on-create `component` string field on `Task` items:
546
552
 
@@ -561,6 +567,57 @@ End-to-end example — add a required-on-create `component` string field on `Tas
561
567
  }
562
568
  ```
563
569
 
570
+ Object schemas can model discriminated evidence contracts. The following accepts either complete gate proof or an expiring waiver and rejects unknown keys:
571
+
572
+ ```jsonc
573
+ {
574
+ "key": "gate_evidence",
575
+ "type": "object",
576
+ "value_schema": {
577
+ "type": "object",
578
+ "required": ["disposition", "owner"],
579
+ "additional_properties": false,
580
+ "properties": {
581
+ "disposition": {
582
+ "enum": ["gate_added", "gate_strengthened", "explicit_waiver"],
583
+ },
584
+ "owner": { "type": "string", "min_length": 1 },
585
+ "gate_id": { "type": "string", "min_length": 1 },
586
+ "negative_control": { "type": "string", "min_length": 1 },
587
+ "local_checks": {
588
+ "type": "array",
589
+ "min_items": 1,
590
+ "items": { "type": "string", "min_length": 1 },
591
+ },
592
+ "hosted_checks": {
593
+ "type": "array",
594
+ "min_items": 1,
595
+ "items": { "type": "string", "min_length": 1 },
596
+ },
597
+ "waiver_reason": { "type": "string", "min_length": 1 },
598
+ "waiver_expires_at": { "type": "string", "format": "date-time" },
599
+ },
600
+ "one_of": [
601
+ {
602
+ "properties": {
603
+ "disposition": { "enum": ["gate_added", "gate_strengthened"] },
604
+ },
605
+ "required": [
606
+ "gate_id",
607
+ "negative_control",
608
+ "local_checks",
609
+ "hosted_checks",
610
+ ],
611
+ },
612
+ {
613
+ "properties": { "disposition": { "const": "explicit_waiver" } },
614
+ "required": ["waiver_reason", "waiver_expires_at"],
615
+ },
616
+ ],
617
+ },
618
+ }
619
+ ```
620
+
564
621
  ```bash
565
622
  pm create Task "Fix token refresh" --component auth # stored in item metadata
566
623
  pm list --component auth # filter by the custom field