@unbrained/pm-cli 2026.8.21 → 2026.8.22

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 (158) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +16 -0
  3. package/dist/cli/error-guidance.d.ts +9 -4
  4. package/dist/cli/error-guidance.js +16 -15
  5. package/dist/cli/main.d.ts +3 -0
  6. package/dist/cli/main.js +40 -7
  7. package/dist/cli-bundle/bundle-manifest.json +153 -153
  8. package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-BWX4SK46.js} +48 -48
  9. package/dist/cli-bundle/chunks/chunk-EMWDM5FI.js +13 -0
  10. package/dist/cli-bundle/chunks/chunk-HYG6LRL4.js +200 -0
  11. package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-MYYI3ZOA.js} +2 -2
  12. package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-MZTZQTMS.js} +2 -2
  13. package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-QI2CT3IX.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-SMWXHMVB.js +35 -0
  15. package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-U6GQ4VMV.js} +6 -6
  16. package/dist/cli-bundle/chunks/{chunk-3AFAUHUE.js → chunk-VMMIL3SI.js} +2 -2
  17. package/dist/cli-bundle/chunks/chunk-WG4STC36.js +5 -0
  18. package/dist/cli-bundle/chunks/{chunk-JSLOFXGA.js → chunk-YBPJAOQQ.js} +2 -2
  19. package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-HZKBQNWW.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-mutation-7IY2D5KO.js → register-mutation-HTKEEGRD.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-operations-FALL3YTU.js → register-operations-6EMRWJJY.js} +2 -2
  22. package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-QK4OTOXN.js} +2 -2
  23. package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-2ARQGDDW.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/{chunk-CKKQSJNN.js → chunk-2AZT5WXZ.js} +2 -2
  25. package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-2POVTNLY.js} +2 -2
  26. package/dist/cli-bundle/focused-chunks/chunk-3LKU6PTJ.js +4 -0
  27. package/dist/cli-bundle/focused-chunks/chunk-5SHSBMX2.js +2 -0
  28. package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-6S2MO3Q3.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-A2BC5PQL.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/chunk-C4S4A4JJ.js +5 -0
  31. package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-D6RBZEJJ.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-E2EWYPY6.js +16 -0
  33. package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-GMYPD4FX.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/chunk-L5LDSRO2.js +155 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-ZOSEELYJ.js → chunk-MB37AYN6.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-MCOR37QK.js +2 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-PH2OXXVZ.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-PMGJUFNQ.js} +2 -2
  39. package/dist/cli-bundle/focused-chunks/chunk-R6SR45XU.js +50 -0
  40. package/dist/cli-bundle/focused-chunks/chunk-WZE4LIPW.js +8 -0
  41. package/dist/cli-bundle/main.js +13 -13
  42. package/dist/cli-bundle/sdk-authoring.js +1 -1
  43. package/dist/cli-bundle/sdk-contracts.js +2 -2
  44. package/dist/cli-bundle/sdk-core.js +40 -40
  45. package/dist/cli-bundle/sdk-governance.js +1 -1
  46. package/dist/cli-bundle/sdk-graph.js +1 -1
  47. package/dist/cli-bundle/sdk-merge.js +32 -32
  48. package/dist/cli-bundle/sdk-query.js +1 -1
  49. package/dist/cli-bundle/sdk-runtime.js +1 -1
  50. package/dist/cli-bundle/sdk-testing.js +1 -1
  51. package/dist/cli-bundle/sdk.js +5 -5
  52. package/dist/core/extensions/extension-hook-runtime.js +22 -20
  53. package/dist/core/extensions/extension-types.d.ts +8 -1
  54. package/dist/core/extensions/extension-types.js +2 -2
  55. package/dist/core/extensions/loader.js +7 -3
  56. package/dist/core/extensions/service-ownership.d.ts +8 -0
  57. package/dist/core/extensions/service-ownership.js +20 -0
  58. package/dist/core/item/id.js +20 -5
  59. package/dist/core/item/item-format.js +27 -2
  60. package/dist/core/shared/errors.d.ts +4 -0
  61. package/dist/core/shared/errors.js +2 -2
  62. package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
  63. package/dist/sdk/authoring.d.ts +1 -1
  64. package/dist/sdk/authoring.js +2 -2
  65. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
  66. package/dist/sdk/cli-contracts/agent-output-contracts.js +324 -2
  67. package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
  68. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
  69. package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
  70. package/dist/sdk/cli-contracts.d.ts +1 -1
  71. package/dist/sdk/cli-contracts.js +3 -3
  72. package/dist/sdk/extension/install-sources.d.ts +1 -1
  73. package/dist/sdk/extension/install-sources.js +6 -3
  74. package/dist/sdk/extension/output-ownership.d.ts +1 -0
  75. package/dist/sdk/extension/output-ownership.js +3 -2
  76. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +38 -14
  77. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +14 -2
  78. package/dist/sdk/governance/health.d.ts +3 -0
  79. package/dist/sdk/governance/health.js +39 -7
  80. package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
  81. package/dist/sdk/governance/hierarchy-validation.js +109 -0
  82. package/dist/sdk/governance/validate.d.ts +1 -7
  83. package/dist/sdk/governance/validate.js +47 -99
  84. package/dist/sdk/graph/assembly.d.ts +6 -1
  85. package/dist/sdk/graph/assembly.js +16 -22
  86. package/dist/sdk/graph/governance-contracts.d.ts +1 -1
  87. package/dist/sdk/graph/governance-contracts.js +8 -2
  88. package/dist/sdk/graph/governance.js +46 -2
  89. package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
  90. package/dist/sdk/graph/hierarchy-integrity.js +311 -0
  91. package/dist/sdk/graph/index.d.ts +2 -1
  92. package/dist/sdk/graph/index.js +3 -2
  93. package/dist/sdk/graph/remediation.js +32 -2
  94. package/dist/sdk/graph/run.d.ts +31 -2
  95. package/dist/sdk/graph/run.js +80 -31
  96. package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
  97. package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
  98. package/dist/sdk/index.d.ts +2 -2
  99. package/dist/sdk/index.js +3 -3
  100. package/dist/sdk/item-children.js +21 -8
  101. package/dist/sdk/lifecycle/create.js +125 -96
  102. package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
  103. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
  104. package/dist/sdk/lifecycle/update.d.ts +2 -0
  105. package/dist/sdk/lifecycle/update.js +171 -83
  106. package/dist/sdk/query/complete-list.d.ts +3 -3
  107. package/dist/sdk/query/complete-list.js +46 -3
  108. package/dist/sdk/query/list.d.ts +4 -3
  109. package/dist/sdk/query/list.js +89 -49
  110. package/dist/sdk/read-output-contracts.d.ts +5 -1
  111. package/dist/sdk/read-output-contracts.js +87 -22
  112. package/dist/sdk/relationship-context.js +3 -4
  113. package/dist/sdk/relationships.js +17 -10
  114. package/dist/sdk/runtime.d.ts +3 -2
  115. package/dist/sdk/runtime.js +3 -2
  116. package/dist/sdk/test/batch.js +13 -5
  117. package/dist/sdk/test/execution.js +10 -2
  118. package/dist/types.d.ts +11 -0
  119. package/dist/types.js +2 -2
  120. package/docs/AGENT_UX_CONTRACTS.md +20 -4
  121. package/docs/COMMANDS.md +29 -14
  122. package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
  123. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +98 -0
  124. package/docs/EXTENSIONS.md +2 -1
  125. package/docs/README.md +1 -0
  126. package/docs/READ_OUTPUT_CONTRACTS.md +9 -2
  127. package/docs/RELATIONSHIP_GRAPH.md +6 -3
  128. package/docs/TESTING.md +15 -0
  129. package/marketplace.json +2 -2
  130. package/package.json +1 -1
  131. package/packages/pm-beads/package.json +1 -1
  132. package/packages/pm-calendar/package.json +1 -1
  133. package/packages/pm-command-kit/package.json +1 -1
  134. package/packages/pm-digital-twin/package.json +1 -1
  135. package/packages/pm-governance-audit/package.json +1 -1
  136. package/packages/pm-guide-shell/package.json +1 -1
  137. package/packages/pm-kanban/package.json +1 -1
  138. package/packages/pm-lifecycle-hooks/package.json +1 -1
  139. package/packages/pm-linked-test-adapters/package.json +1 -1
  140. package/packages/pm-search-advanced/package.json +1 -1
  141. package/packages/pm-templates/package.json +1 -1
  142. package/packages/pm-todos/package.json +1 -1
  143. package/packages/pm-vcs/package.json +1 -1
  144. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  145. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  146. package/sdk/public-surface.json +593 -35
  147. package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
  148. package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
  149. package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
  150. package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
  151. package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
  152. package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
  153. package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
  154. package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
  155. package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
  156. package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
  157. package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
  158. package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
@@ -1,8 +1,10 @@
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]="a6fc5da1-b7d1-5b3c-8033-cecccc7861c3")}catch(e){}}();
3
- import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
4
- import { RelationshipGraph, createRelationshipKindRegistry, } from "../relationships.js";
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]="9a6974b3-63d7-5dc7-8329-0f15f0dc83ec")}catch(e){}}();
3
+ import { RelationshipGraph, } from "../relationships.js";
5
4
  import { isExternalDependencySourceKind } from "../dependency-provenance.js";
5
+ import { analyzeHierarchyIntegrity, } from "./hierarchy-integrity.js";
6
+ import { resolveWorkspaceRelationshipKindRegistry } from "./workspace-relationship-kind-registry.js";
7
+ export { resolveWorkspaceRelationshipKindRegistry } from "./workspace-relationship-kind-registry.js";
6
8
  /** Normalize a decoded reference target and reject empty legacy placeholders. */
7
9
  function normalizeDependencyReferenceTarget(target) {
8
10
  if (typeof target !== "string")
@@ -20,23 +22,6 @@ export function normalizeDependencyGraphTarget(target) {
20
22
  ? undefined
21
23
  : normalized;
22
24
  }
23
- /**
24
- * Resolve the default workspace relationship-kind registry: the built-in kinds
25
- * merged with every active extension-contributed relationship-kind
26
- * registration. Assembly, mutation advisories, and standalone graph consumers
27
- * share this resolution so custom ordering semantics apply identically on
28
- * every surface.
29
- */
30
- export function resolveWorkspaceRelationshipKindRegistry() {
31
- const registry = createRelationshipKindRegistry();
32
- for (const registration of getActiveExtensionRegistrations()
33
- ?.relationship_kinds ?? []) {
34
- for (const definition of registration.definitions) {
35
- registry.register(definition);
36
- }
37
- }
38
- return registry;
39
- }
40
25
  /** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */
41
26
  function compareCaseFoldedText(left, right) {
42
27
  const normalizedLeft = left.toLowerCase();
@@ -242,6 +227,11 @@ export function collectExternalDependencyTargetIds(items) {
242
227
  }
243
228
  return [...targets.values()].sort((left, right) => left.localeCompare(right));
244
229
  }
230
+ const hierarchyIntegrityByAssembly = new WeakMap();
231
+ /** Read the hierarchy analysis paired with an assembly created by this module. */
232
+ export function getWorkspaceHierarchyIntegrity(assembly) {
233
+ return assembly.hierarchyIntegrity ?? hierarchyIntegrityByAssembly.get(assembly);
234
+ }
245
235
  /** Count raw dependency rows that use a registered compatibility alias instead of its canonical kind. */
246
236
  export function collectLegacyDependencyAliasCounts(items, registry = resolveWorkspaceRelationshipKindRegistry()) {
247
237
  const counts = {};
@@ -316,7 +306,8 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
316
306
  dependencies,
317
307
  };
318
308
  });
319
- return {
309
+ const hierarchyIntegrity = analyzeHierarchyIntegrity(safeItems, isTerminal, relationshipRegistry);
310
+ const assembly = {
320
311
  graph: RelationshipGraph.fromItems([
321
312
  ...graphItems,
322
313
  ...missingIds.map((id) => ({ id })),
@@ -349,7 +340,10 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
349
340
  duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),
350
341
  orderingContradictions: collectOrderingStorageContradictions(safeItems, isTerminal, relationshipRegistry),
351
342
  legacyAliasCounts: collectLegacyDependencyAliasCounts(safeItems, relationshipRegistry),
343
+ hierarchyIntegrity,
352
344
  };
345
+ hierarchyIntegrityByAssembly.set(assembly, hierarchyIntegrity);
346
+ return assembly;
353
347
  }
354
348
  //# sourceMappingURL=assembly.js.map
355
- //# debugId=a6fc5da1-b7d1-5b3c-8033-cecccc7861c3
349
+ //# debugId=9a6974b3-63d7-5dc7-8329-0f15f0dc83ec
@@ -7,6 +7,6 @@
7
7
  * drifting when a finding family is added.
8
8
  */
9
9
  /** Stable machine-readable relationship audit finding families. */
10
- export declare const RELATIONSHIP_AUDIT_FINDING_CODES: readonly ["missing_reference_active", "missing_reference_terminal", "legacy_no_blocker_sentinel", "ordering_cycle", "legacy_ordering_cycle", "ordering_storage_contradiction", "legacy_ordering_storage_contradiction", "duplicate_edge", "legacy_duplicate_edge", "duplicate_dependency_row", "legacy_duplicate_dependency_row", "stale_lifecycle_block", "isolated_active_node", "sparse_active_node"];
10
+ export declare const RELATIONSHIP_AUDIT_FINDING_CODES: readonly ["missing_reference_active", "missing_reference_terminal", "legacy_no_blocker_sentinel", "ordering_cycle", "legacy_ordering_cycle", "ordering_storage_contradiction", "legacy_ordering_storage_contradiction", "hierarchy_cycle", "legacy_hierarchy_cycle", "hierarchy_cardinality_violation", "legacy_hierarchy_cardinality_violation", "hierarchy_direction_violation", "legacy_hierarchy_direction_violation", "duplicate_edge", "legacy_duplicate_edge", "duplicate_dependency_row", "legacy_duplicate_dependency_row", "stale_lifecycle_block", "isolated_active_node", "sparse_active_node"];
11
11
  /** Machine-readable identifier for one relationship audit finding family. */
12
12
  export type RelationshipAuditFindingCode = (typeof RELATIONSHIP_AUDIT_FINDING_CODES)[number];
@@ -8,7 +8,7 @@
8
8
  */
9
9
  /** Stable machine-readable relationship audit finding families. */
10
10
 
11
- !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]="bc561e73-75b8-5ea7-a18c-da70fb991b69")}catch(e){}}();
11
+ !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]="a8bc0ebd-e5e4-57f3-8e6c-417f9809eb72")}catch(e){}}();
12
12
  export const RELATIONSHIP_AUDIT_FINDING_CODES = [
13
13
  "missing_reference_active",
14
14
  "missing_reference_terminal",
@@ -17,6 +17,12 @@ export const RELATIONSHIP_AUDIT_FINDING_CODES = [
17
17
  "legacy_ordering_cycle",
18
18
  "ordering_storage_contradiction",
19
19
  "legacy_ordering_storage_contradiction",
20
+ "hierarchy_cycle",
21
+ "legacy_hierarchy_cycle",
22
+ "hierarchy_cardinality_violation",
23
+ "legacy_hierarchy_cardinality_violation",
24
+ "hierarchy_direction_violation",
25
+ "legacy_hierarchy_direction_violation",
20
26
  "duplicate_edge",
21
27
  "legacy_duplicate_edge",
22
28
  "duplicate_dependency_row",
@@ -26,4 +32,4 @@ export const RELATIONSHIP_AUDIT_FINDING_CODES = [
26
32
  "sparse_active_node",
27
33
  ];
28
34
  //# sourceMappingURL=governance-contracts.js.map
29
- //# debugId=bc561e73-75b8-5ea7-a18c-da70fb991b69
35
+ //# debugId=a8bc0ebd-e5e4-57f3-8e6c-417f9809eb72
@@ -1,7 +1,8 @@
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]="c5dbaccd-d0e5-5511-b659-4f0a5f45ccaf")}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]="27de9c62-434c-566d-a000-54eddb9a16a9")}catch(e){}}();
3
3
  import { findRedundantRelationshipEdges, isTransitiveKind, orientTransitiveEdge, transitiveFamilyKey, } from "./analytics.js";
4
4
  import { findRelationshipCutStructure } from "./centrality.js";
5
+ import { getWorkspaceHierarchyIntegrity } from "./assembly.js";
5
6
  import { RELATIONSHIP_AUDIT_FINDING_CODES, } from "./governance-contracts.js";
6
7
  /** Default bounded sample size applied to every finding family. */
7
8
  const DEFAULT_MAX_SAMPLE_SIZE = 25;
@@ -53,6 +54,48 @@ function buildFinding(code, severity, policy, describe, subjects, maxSampleSize,
53
54
  }),
54
55
  };
55
56
  }
57
+ function collectHierarchyCycleFindings(analysis, maxSampleSize) {
58
+ return analysis.cycles.map((cycle) => buildFinding(cycle.legacy_terminal ? "legacy_hierarchy_cycle" : "hierarchy_cycle", cycle.legacy_terminal ? "info" : "error", "Structural hierarchy must be acyclic across scalar and registered dependency relationships.", (count) => `${count} items participate in one hierarchy cycle.`, cycle.item_ids, maxSampleSize, cycle.legacy_terminal
59
+ ? "Preserve historical rows unless an explicit legacy repair is approved."
60
+ : "Remove or retype one exact hierarchy relation before continuing mutation."));
61
+ }
62
+ function collectHierarchyCardinalityFindings(analysis, maxSampleSize, legacyTerminal) {
63
+ const rows = analysis.cardinality_violations.filter((finding) => finding.legacy_terminal === legacyTerminal);
64
+ if (rows.length === 0)
65
+ return [];
66
+ return [
67
+ buildFinding(legacyTerminal
68
+ ? "legacy_hierarchy_cardinality_violation"
69
+ : "hierarchy_cardinality_violation", legacyTerminal ? "info" : "error", "Every structural child must resolve to at most one logical parent across all hierarchy spellings.", (count) => `${count} child item${count === 1 ? "" : "s"} resolve to multiple hierarchy parents.`, rows.map((finding) => finding.child_id), maxSampleSize, legacyTerminal
70
+ ? "Preserve historical rows unless an explicit legacy repair is approved."
71
+ : "Remove the exact surplus hierarchy rows so each child has one parent.", rows.map((finding) => `${finding.child_id} <- ${finding.parent_ids.join(", ")}`)),
72
+ ];
73
+ }
74
+ function collectHierarchyDirectionFindings(analysis, maxSampleSize, legacyTerminal) {
75
+ const rows = analysis.divergences.filter((finding) => finding.legacy_terminal === legacyTerminal);
76
+ if (rows.length === 0)
77
+ return [];
78
+ return [
79
+ buildFinding(legacyTerminal
80
+ ? "legacy_hierarchy_direction_violation"
81
+ : "hierarchy_direction_violation", legacyTerminal ? "info" : "error", "Scalar parent metadata and dependency-backed hierarchy rows must resolve to the same logical parent.", (count) => `${count} child item${count === 1 ? "" : "s"} have divergent hierarchy storage surfaces.`, rows.map((finding) => finding.child_id), maxSampleSize, legacyTerminal
82
+ ? "Preserve historical rows unless an explicit legacy repair is approved."
83
+ : "Align the scalar parent and exact dependency rows to one canonical parent.", rows.map((finding) => `${finding.child_id}: scalar=${finding.scalar_parent_id} dependencies=${finding.dependency_parent_ids.join(",")}`)),
84
+ ];
85
+ }
86
+ /** Convert unified hierarchy analysis into lifecycle-aware governance findings. */
87
+ function collectHierarchyIntegrityFindings(assembly, maxSampleSize) {
88
+ const analysis = getWorkspaceHierarchyIntegrity(assembly);
89
+ if (!analysis)
90
+ return [];
91
+ return [
92
+ ...collectHierarchyCycleFindings(analysis, maxSampleSize),
93
+ ...collectHierarchyCardinalityFindings(analysis, maxSampleSize, false),
94
+ ...collectHierarchyCardinalityFindings(analysis, maxSampleSize, true),
95
+ ...collectHierarchyDirectionFindings(analysis, maxSampleSize, false),
96
+ ...collectHierarchyDirectionFindings(analysis, maxSampleSize, true),
97
+ ];
98
+ }
56
99
  /** Resolve the ordering-only successor adjacency for cycle analysis. */
57
100
  function buildOrderingAdjacency(assembly) {
58
101
  const registry = assembly.graph.registry();
@@ -577,6 +620,7 @@ export function auditWorkspaceRelationshipGraph(assembly, options = {}) {
577
620
  for (const edge of assembly.graph.edges())
578
621
  edgesByKind[edge.kind] = (edgesByKind[edge.kind] ?? 0) + 1;
579
622
  const findings = collectIntegrityFindings(assembly, isTerminal, maxSampleSize);
623
+ findings.push(...collectHierarchyIntegrityFindings(assembly, maxSampleSize));
580
624
  options.signal?.throwIfAborted();
581
625
  findings.push(...collectOrderingStorageContradictionFindings(assembly, maxSampleSize));
582
626
  options.signal?.throwIfAborted();
@@ -689,4 +733,4 @@ export function diffRelationshipAuditSnapshots(baseline, current) {
689
733
  };
690
734
  }
691
735
  //# sourceMappingURL=governance.js.map
692
- //# debugId=c5dbaccd-d0e5-5511-b659-4f0a5f45ccaf
736
+ //# debugId=27de9c62-434c-566d-a000-54eddb9a16a9
@@ -0,0 +1,94 @@
1
+ import type { Dependency, ItemStatus } from "../../types/index.js";
2
+ import type { RelationshipKindRegistry } from "../relationships.js";
3
+ /** Storage surface from which one normalized hierarchy relation originated. */
4
+ export type HierarchyRelationSource = "scalar_parent" | "dependency";
5
+ /** Minimal workspace item shape required by hierarchy-integrity analysis. */
6
+ export interface HierarchyIntegrityItem {
7
+ /** Stable item identifier. */
8
+ id: string;
9
+ /** Lifecycle status used to classify historical-only defects. */
10
+ status: ItemStatus;
11
+ /** Optional scalar structural parent. */
12
+ parent?: string;
13
+ /** Structured relationship rows that may carry hierarchy semantics. */
14
+ dependencies?: Dependency[];
15
+ }
16
+ /** One canonical parent-to-child relation with exact stored-row provenance. */
17
+ export interface HierarchyRelation {
18
+ /** Canonical structural parent identifier. */
19
+ parent_id: string;
20
+ /** Canonical structural child identifier. */
21
+ child_id: string;
22
+ /** Storage surface that asserted the relation. */
23
+ source: HierarchyRelationSource;
24
+ /** Canonical relationship kind, or `parent` for the scalar field. */
25
+ kind: string;
26
+ /** Item document that stores the relation. */
27
+ holder_id: string;
28
+ /** Referenced endpoint for dependency-backed relations. */
29
+ target_id?: string;
30
+ /** Registry cardinality at the child endpoint of this relation. */
31
+ child_cardinality: "one" | "many";
32
+ }
33
+ /** One strongly connected hierarchy component. */
34
+ export interface HierarchyCycle {
35
+ /** Deterministically sorted item identifiers in the cycle. */
36
+ item_ids: string[];
37
+ /** Whether every member is in a terminal lifecycle state. */
38
+ legacy_terminal: boolean;
39
+ }
40
+ /** One child assigned to more than one logical parent. */
41
+ export interface HierarchyCardinalityViolation {
42
+ /** Child whose parent cardinality was exceeded. */
43
+ child_id: string;
44
+ /** Deterministically sorted unique parent identifiers. */
45
+ parent_ids: string[];
46
+ /** Whether the child and every asserted parent are terminal. */
47
+ legacy_terminal: boolean;
48
+ }
49
+ /** One scalar parent that disagrees with dependency-backed hierarchy evidence. */
50
+ export interface HierarchyParentDivergence {
51
+ /** Child whose hierarchy storage surfaces disagree. */
52
+ child_id: string;
53
+ /** Parent declared by the scalar metadata field. */
54
+ scalar_parent_id: string;
55
+ /** Different dependency-backed parent identifiers. */
56
+ dependency_parent_ids: string[];
57
+ /** Whether the child and every asserted parent are terminal. */
58
+ legacy_terminal: boolean;
59
+ }
60
+ /** Complete deterministic hierarchy-integrity projection for a workspace. */
61
+ export interface HierarchyIntegrityAnalysis {
62
+ /** Normalized evidence rows retained for exact diagnostics and repair. */
63
+ relations: HierarchyRelation[];
64
+ /** Cyclic structural components. */
65
+ cycles: HierarchyCycle[];
66
+ /** Logical one-parent cardinality violations. */
67
+ cardinality_violations: HierarchyCardinalityViolation[];
68
+ /** Scalar and dependency-backed parent disagreements. */
69
+ divergences: HierarchyParentDivergence[];
70
+ }
71
+ /** Deterministic adjacency indexes derived from normalized hierarchy evidence. */
72
+ export interface HierarchyRelationIndexes {
73
+ /** Unique logical parents keyed by child id. */
74
+ parents_by_child: ReadonlyMap<string, readonly string[]>;
75
+ /** Unique logical children keyed by parent id. */
76
+ children_by_parent: ReadonlyMap<string, readonly string[]>;
77
+ }
78
+ /** Collect normalized hierarchy evidence without running defect analysis. */
79
+ export declare function collectHierarchyRelations(items: readonly HierarchyIntegrityItem[], registry?: RelationshipKindRegistry): HierarchyRelation[];
80
+ /**
81
+ * Analyze all runtime-recognized hierarchy spellings as canonical parent-child
82
+ * relations. Unknown, malformed, and dangling rows are ignored here because
83
+ * dedicated graph-integrity checks own those diagnostics.
84
+ */
85
+ export declare function analyzeHierarchyIntegrity(items: readonly HierarchyIntegrityItem[], isTerminal?: (status: ItemStatus) => boolean, registry?: RelationshipKindRegistry): HierarchyIntegrityAnalysis;
86
+ /** Render exact hierarchy evidence without losing its storage orientation. */
87
+ export declare function formatHierarchyRelation(relation: HierarchyRelation): string;
88
+ /** Index normalized hierarchy evidence for list, tree, and rollup consumers. */
89
+ export declare function indexHierarchyRelations(relations: readonly HierarchyRelation[]): HierarchyRelationIndexes;
90
+ /**
91
+ * Reject a mutation only when it introduces a new hierarchy defect involving
92
+ * the changed item. Existing debt remains repairable without a global bypass.
93
+ */
94
+ export declare function assertHierarchyMutationAllowed(beforeItems: readonly HierarchyIntegrityItem[], afterItems: readonly HierarchyIntegrityItem[], changedItemId: string, isTerminal?: (status: ItemStatus) => boolean, registry?: RelationshipKindRegistry): void;
@@ -0,0 +1,311 @@
1
+ /**
2
+ * @module sdk/graph/hierarchy-integrity
3
+ *
4
+ * Normalizes scalar and dependency-backed hierarchy evidence into one graph,
5
+ * reports structural defects, and rejects mutations that introduce new debt.
6
+ */
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]="924f7718-0527-5967-8ab0-53e8228bd665")}catch(e){}}();
9
+ import { EXIT_CODE } from "../../core/shared/constants.js";
10
+ import { PmCliError } from "../../core/shared/errors.js";
11
+ import { resolveWorkspaceRelationshipKindRegistry } from "./workspace-relationship-kind-registry.js";
12
+ function normalizeItemId(value) {
13
+ if (typeof value !== "string")
14
+ return undefined;
15
+ const normalized = value.trim().toLowerCase();
16
+ return normalized.length > 0 ? normalized : undefined;
17
+ }
18
+ function relationIdentity(relation) {
19
+ return [
20
+ relation.parent_id,
21
+ relation.child_id,
22
+ relation.source,
23
+ relation.kind,
24
+ relation.holder_id,
25
+ relation.target_id ?? "",
26
+ ].join("\u0000");
27
+ }
28
+ function collectHierarchyFinishOrder(nodeIds, childrenByParent) {
29
+ const visited = new Set();
30
+ const finishOrder = [];
31
+ for (const root of [...nodeIds].sort()) {
32
+ if (visited.has(root))
33
+ continue;
34
+ visited.add(root);
35
+ const frames = [
36
+ {
37
+ nodeId: root,
38
+ children: [...(childrenByParent.get(root) ?? [])].sort(),
39
+ nextChild: 0,
40
+ },
41
+ ];
42
+ while (frames.length > 0) {
43
+ const frame = frames.at(-1);
44
+ const childId = frame.children[frame.nextChild];
45
+ if (childId === undefined) {
46
+ finishOrder.push(frame.nodeId);
47
+ frames.pop();
48
+ }
49
+ else {
50
+ frame.nextChild += 1;
51
+ if (!visited.has(childId)) {
52
+ visited.add(childId);
53
+ frames.push({
54
+ nodeId: childId,
55
+ children: [...(childrenByParent.get(childId) ?? [])].sort(),
56
+ nextChild: 0,
57
+ });
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return finishOrder;
63
+ }
64
+ function collectCyclicComponents(nodeIds, childrenByParent) {
65
+ const sortedNodeIds = [...nodeIds].sort();
66
+ const finishOrder = collectHierarchyFinishOrder(sortedNodeIds, childrenByParent);
67
+ const visited = new Set();
68
+ const parentsByChild = reverseHierarchyEdges(sortedNodeIds, childrenByParent);
69
+ const components = [];
70
+ for (const root of finishOrder.reverse()) {
71
+ if (visited.has(root))
72
+ continue;
73
+ const component = collectReverseComponent(root, parentsByChild, visited);
74
+ if (component.length > 1 ||
75
+ childrenByParent.get(component[0])?.has(component[0]))
76
+ components.push(component);
77
+ }
78
+ return components.sort((left, right) => left.join("\u0000").localeCompare(right.join("\u0000")));
79
+ }
80
+ function reverseHierarchyEdges(nodeIds, childrenByParent) {
81
+ const parentsByChild = new Map(nodeIds.map((nodeId) => [nodeId, new Set()]));
82
+ for (const [parentId, childIds] of childrenByParent) {
83
+ for (const childId of childIds)
84
+ parentsByChild.get(childId)?.add(parentId);
85
+ }
86
+ return parentsByChild;
87
+ }
88
+ function collectReverseComponent(root, parentsByChild, visited) {
89
+ const component = [];
90
+ const pending = [root];
91
+ visited.add(root);
92
+ while (pending.length > 0) {
93
+ const nodeId = pending.pop();
94
+ component.push(nodeId);
95
+ for (const parentId of [...parentsByChild.get(nodeId)].sort()) {
96
+ if (visited.has(parentId))
97
+ continue;
98
+ visited.add(parentId);
99
+ pending.push(parentId);
100
+ }
101
+ }
102
+ return component.sort();
103
+ }
104
+ function collectHierarchyItems(items) {
105
+ const itemById = new Map();
106
+ for (const item of items) {
107
+ const itemId = normalizeItemId(item?.id);
108
+ if (itemId && !itemById.has(itemId))
109
+ itemById.set(itemId, item);
110
+ }
111
+ return itemById;
112
+ }
113
+ function buildScalarHierarchyRelation(holderId, item, itemById) {
114
+ const parentId = normalizeItemId(item.parent);
115
+ if (!parentId || !itemById.has(parentId))
116
+ return undefined;
117
+ return {
118
+ parent_id: parentId,
119
+ child_id: holderId,
120
+ source: "scalar_parent",
121
+ kind: "parent",
122
+ holder_id: holderId,
123
+ child_cardinality: "one",
124
+ };
125
+ }
126
+ function buildDependencyHierarchyRelation(holderId, dependency, itemById, registry) {
127
+ const targetId = normalizeItemId(dependency?.id);
128
+ const definition = registry.resolve(dependency?.kind);
129
+ if (!targetId || !itemById.has(targetId) || !definition?.hierarchy)
130
+ return undefined;
131
+ const sourceIsParent = definition.hierarchyDirection === "source_parent";
132
+ return {
133
+ parent_id: sourceIsParent ? holderId : targetId,
134
+ child_id: sourceIsParent ? targetId : holderId,
135
+ source: "dependency",
136
+ kind: definition.kind,
137
+ holder_id: holderId,
138
+ target_id: targetId,
139
+ child_cardinality: sourceIsParent
140
+ ? definition.incoming
141
+ : definition.outgoing,
142
+ };
143
+ }
144
+ function collectHierarchyRelationsFromItemMap(itemById, registry) {
145
+ const relationsByIdentity = new Map();
146
+ for (const [holderId, item] of itemById) {
147
+ const scalarRelation = buildScalarHierarchyRelation(holderId, item, itemById);
148
+ if (scalarRelation)
149
+ relationsByIdentity.set(relationIdentity(scalarRelation), scalarRelation);
150
+ for (const dependency of item.dependencies ?? []) {
151
+ const relation = buildDependencyHierarchyRelation(holderId, dependency, itemById, registry);
152
+ if (!relation)
153
+ continue;
154
+ relationsByIdentity.set(relationIdentity(relation), relation);
155
+ }
156
+ }
157
+ return [...relationsByIdentity.values()].sort((left, right) => relationIdentity(left).localeCompare(relationIdentity(right)));
158
+ }
159
+ /** Collect normalized hierarchy evidence without running defect analysis. */
160
+ export function collectHierarchyRelations(items, registry = resolveWorkspaceRelationshipKindRegistry()) {
161
+ return collectHierarchyRelationsFromItemMap(collectHierarchyItems(items), registry);
162
+ }
163
+ function collectHierarchyCardinalityViolations(relations, parentsByChild, terminalIds) {
164
+ const oneCardinalityChildren = new Set(relations
165
+ .filter((relation) => relation.child_cardinality === "one")
166
+ .map((relation) => relation.child_id));
167
+ return [...parentsByChild]
168
+ .filter(([childId, parentIds]) => parentIds.length > 1 && oneCardinalityChildren.has(childId))
169
+ .map(([childId, parentIds]) => ({
170
+ child_id: childId,
171
+ parent_ids: [...parentIds],
172
+ legacy_terminal: terminalIds.has(childId) &&
173
+ parentIds.every((id) => terminalIds.has(id)),
174
+ }))
175
+ .sort((left, right) => left.child_id.localeCompare(right.child_id));
176
+ }
177
+ function collectHierarchyDivergences(itemById, relations, terminalIds) {
178
+ const dependencyParentsByChild = new Map();
179
+ for (const relation of relations) {
180
+ if (relation.source !== "dependency")
181
+ continue;
182
+ const parents = dependencyParentsByChild.get(relation.child_id) ?? new Set();
183
+ parents.add(relation.parent_id);
184
+ dependencyParentsByChild.set(relation.child_id, parents);
185
+ }
186
+ const divergences = [];
187
+ for (const [childId, item] of itemById) {
188
+ const scalarParentId = normalizeItemId(item.parent);
189
+ if (!scalarParentId || !itemById.has(scalarParentId))
190
+ continue;
191
+ const dependencyParentIds = [
192
+ ...(dependencyParentsByChild.get(childId) ?? []),
193
+ ]
194
+ .filter((parentId) => parentId !== scalarParentId)
195
+ .sort();
196
+ if (dependencyParentIds.length === 0)
197
+ continue;
198
+ divergences.push({
199
+ child_id: childId,
200
+ scalar_parent_id: scalarParentId,
201
+ dependency_parent_ids: dependencyParentIds,
202
+ legacy_terminal: terminalIds.has(childId) &&
203
+ terminalIds.has(scalarParentId) &&
204
+ dependencyParentIds.every((id) => terminalIds.has(id)),
205
+ });
206
+ }
207
+ return divergences.sort((left, right) => left.child_id.localeCompare(right.child_id));
208
+ }
209
+ /**
210
+ * Analyze all runtime-recognized hierarchy spellings as canonical parent-child
211
+ * relations. Unknown, malformed, and dangling rows are ignored here because
212
+ * dedicated graph-integrity checks own those diagnostics.
213
+ */
214
+ export function analyzeHierarchyIntegrity(items, isTerminal = (status) => status === "closed" || status === "canceled", registry = resolveWorkspaceRelationshipKindRegistry()) {
215
+ const itemById = collectHierarchyItems(items);
216
+ const relations = collectHierarchyRelationsFromItemMap(itemById, registry);
217
+ const indexes = indexHierarchyRelations(relations);
218
+ const terminalIds = new Set([...itemById]
219
+ .filter(([, item]) => isTerminal(item.status))
220
+ .map(([id]) => id));
221
+ const cycles = collectCyclicComponents([...itemById.keys()], new Map([...indexes.children_by_parent].map(([id, childIds]) => [
222
+ id,
223
+ new Set(childIds),
224
+ ]))).map((itemIds) => ({
225
+ item_ids: itemIds,
226
+ legacy_terminal: itemIds.every((id) => terminalIds.has(id)),
227
+ }));
228
+ return {
229
+ relations,
230
+ cycles,
231
+ cardinality_violations: collectHierarchyCardinalityViolations(relations, indexes.parents_by_child, terminalIds),
232
+ divergences: collectHierarchyDivergences(itemById, relations, terminalIds),
233
+ };
234
+ }
235
+ /** Render exact hierarchy evidence without losing its storage orientation. */
236
+ export function formatHierarchyRelation(relation) {
237
+ if (relation.source === "scalar_parent")
238
+ return `${relation.parent_id} -> ${relation.child_id} (scalar parent on ${relation.holder_id})`;
239
+ return `${relation.parent_id} -> ${relation.child_id} (${relation.kind} dependency on ${relation.holder_id})`;
240
+ }
241
+ /** Index normalized hierarchy evidence for list, tree, and rollup consumers. */
242
+ export function indexHierarchyRelations(relations) {
243
+ const parentSets = new Map();
244
+ const childSets = new Map();
245
+ for (const relation of relations) {
246
+ const parents = parentSets.get(relation.child_id) ?? new Set();
247
+ parents.add(relation.parent_id);
248
+ parentSets.set(relation.child_id, parents);
249
+ const children = childSets.get(relation.parent_id) ?? new Set();
250
+ children.add(relation.child_id);
251
+ childSets.set(relation.parent_id, children);
252
+ }
253
+ return {
254
+ parents_by_child: new Map([...parentSets].map(([id, values]) => [id, [...values].sort()])),
255
+ children_by_parent: new Map([...childSets].map(([id, values]) => [id, [...values].sort()])),
256
+ };
257
+ }
258
+ /** Return whether every candidate identifier existed in the prior defect. */
259
+ function isIdentifierSubset(candidate, prior) {
260
+ const priorIds = new Set(prior);
261
+ return candidate.every((id) => priorIds.has(id));
262
+ }
263
+ /**
264
+ * Reject a mutation only when it introduces a new hierarchy defect involving
265
+ * the changed item. Existing debt remains repairable without a global bypass.
266
+ */
267
+ export function assertHierarchyMutationAllowed(beforeItems, afterItems, changedItemId, isTerminal, registry) {
268
+ const holderId = normalizeItemId(changedItemId);
269
+ if (!holderId)
270
+ return;
271
+ const before = analyzeHierarchyIntegrity(beforeItems, isTerminal, registry);
272
+ const after = analyzeHierarchyIntegrity(afterItems, isTerminal, registry);
273
+ const divergence = after.divergences.find((finding) => !before.divergences.some((prior) => prior.child_id === finding.child_id &&
274
+ prior.scalar_parent_id === finding.scalar_parent_id &&
275
+ isIdentifierSubset(finding.dependency_parent_ids, prior.dependency_parent_ids)));
276
+ if (divergence) {
277
+ const parentIds = [
278
+ divergence.scalar_parent_id,
279
+ ...divergence.dependency_parent_ids,
280
+ ].sort();
281
+ throw new PmCliError(`Hierarchy mutation would assign ${divergence.child_id} to multiple parents: ${parentIds.join(", ")}.`, EXIT_CODE.CONFLICT, {
282
+ code: "hierarchy_parent_divergence_created",
283
+ source_id: holderId,
284
+ target_id: divergence.child_id,
285
+ verification_errors: parentIds,
286
+ });
287
+ }
288
+ const cardinality = after.cardinality_violations.find((finding) => (finding.child_id === holderId ||
289
+ finding.parent_ids.includes(holderId)) &&
290
+ !before.cardinality_violations.some((prior) => prior.child_id === finding.child_id &&
291
+ isIdentifierSubset(finding.parent_ids, prior.parent_ids)));
292
+ if (cardinality) {
293
+ throw new PmCliError(`Hierarchy mutation would assign ${cardinality.child_id} to multiple parents: ${cardinality.parent_ids.join(", ")}.`, EXIT_CODE.CONFLICT, {
294
+ code: "hierarchy_cardinality_created",
295
+ source_id: holderId,
296
+ target_id: cardinality.child_id,
297
+ verification_errors: cardinality.parent_ids,
298
+ });
299
+ }
300
+ const cycle = after.cycles.find((finding) => finding.item_ids.includes(holderId) &&
301
+ !before.cycles.some((prior) => isIdentifierSubset(finding.item_ids, prior.item_ids)));
302
+ if (cycle) {
303
+ throw new PmCliError(`Hierarchy mutation would create a cycle: ${cycle.item_ids.join(" -> ")}.`, EXIT_CODE.CONFLICT, {
304
+ code: "hierarchy_cycle_created",
305
+ source_id: holderId,
306
+ verification_errors: cycle.item_ids,
307
+ });
308
+ }
309
+ }
310
+ //# sourceMappingURL=hierarchy-integrity.js.map
311
+ //# debugId=924f7718-0527-5967-8ab0-53e8228bd665
@@ -14,9 +14,10 @@ export { assertMemoryRelationshipGraphAdapterConformance, assertRelationshipGrap
14
14
  export { analyzeRelationshipSchedule, type GraphScheduleOptions, type RelationshipScheduleAnalysis, type RelationshipScheduleRow, } from "./scheduling.js";
15
15
  export { assembleWorkspaceRelationshipGraph, collectDanglingDependencyReferences, collectDuplicateDependencyRows, collectMissingDependencyTargetIds, collectOrderingStorageContradictions, normalizeDependencyGraphTarget, resolveWorkspaceRelationshipKindRegistry, type DanglingDependencyReference, type DanglingDependencyReferenceSummary, type DependencyReferenceHolder, type DependencyReferenceSource, type DuplicateDependencyRow, type OrderingStorageContradiction, type WorkspaceRelationshipAssembly, type WorkspaceRelationshipItem, type WorkspaceRelationshipNodeDetails, } from "./assembly.js";
16
16
  export { auditWorkspaceRelationshipGraph, collectDuplicateRelationshipEdgeGroups, collectOrderingCycles, diffRelationshipAuditSnapshots, formatDuplicateEdgeGroup, formatOrderingStorageContradiction, type DuplicateRelationshipEdgeGroup, type RelationshipAuditDelta, type RelationshipAuditFinding, type RelationshipAuditFindingCode, type RelationshipAuditOptions, type RelationshipAuditReport, type RelationshipAuditSeverity, type RelationshipAuditSnapshot, type RelationshipCoverageProfile, type RelationshipCoverageTypeProfile, } from "./governance.js";
17
+ export { analyzeHierarchyIntegrity, assertHierarchyMutationAllowed, collectHierarchyRelations, formatHierarchyRelation, indexHierarchyRelations, type HierarchyCardinalityViolation, type HierarchyCycle, type HierarchyIntegrityAnalysis, type HierarchyIntegrityItem, type HierarchyParentDivergence, type HierarchyRelation, type HierarchyRelationIndexes, type HierarchyRelationSource, } from "./hierarchy-integrity.js";
17
18
  export { clearDurableGraphCache, durableGraphCachePath, durableGraphCacheStatus, GRAPH_DURABLE_CACHE_MIN_ITEMS, GRAPH_DURABLE_CACHE_VERSION, graphAuditBaselinePath, loadGraphAuditBaseline, openDurableGraphCache, persistDurableGraphResult, saveGraphAuditBaseline, shouldPersistDurableGraphCache, type DurableGraphCacheEnvelope, type DurableGraphCacheStatus, type DurableGraphCacheView, } from "./durable-cache.js";
18
19
  export { enumerateRelationshipPaths, hierarchyAncestors, hierarchyDescendants, orderingPredecessors, orderingSuccessors, type GraphPathOptions, type GraphTraversalOptions, type RelationshipPath, } from "./traversal.js";
19
20
  export { computeWorkspaceGraphFingerprint, resetWorkspaceGraphCache, workspaceGraphCache, WorkspaceGraphCache, type GraphCacheMetadata, type WorkspaceGraphCacheLookup, } from "./cache.js";
20
21
  export { planRelationshipRemediation, type RelationshipRemediationCode, type RelationshipRemediationConfidence, type RelationshipRemediationOperation, type RelationshipRemediationPlan, type RelationshipRemediationPlanOptions, type RelationshipRemediationStep, } from "./remediation.js";
21
22
  export { collectNewOrderingCycleWarnings } from "./mutation-advisory.js";
22
- export { GRAPH_SUBCOMMAND_VALUES, parseGraphSubcommand, runGraph, type GraphAnalyzeResult, type GraphArticulationResult, type GraphAuditResult, type GraphBridgeRow, type GraphCentralityResult, type GraphCentralityRow, type GraphCommandOptions, type GraphCommunitiesResult, type GraphCommunityRow, type GraphDominatorRow, type GraphDominatorsResult, type GraphExecutionSummary, type GraphImpactResult, type GraphImpactRow, type GraphIndexResult, type GraphKnowledgeSummary, type GraphPathRow, type GraphPathsResult, type GraphPlanResult, type GraphQueryCost, type GraphRedundancyResult, type GraphRedundancyRow, type GraphResult, type GraphScheduleRow, type GraphSlackResult, type GraphSubcommand, type GraphTraversalResult, } from "./run.js";
23
+ export { GRAPH_SUBCOMMAND_VALUES, parseGraphSubcommand, runGraph, type GraphAnalyzeResult, type GraphArticulationResult, type GraphAuditResult, type GraphBridgeRow, type GraphCentralityResult, type GraphCentralityRow, type GraphCommandOptions, type GraphCommunitiesResult, type GraphCommunityRow, type GraphDominatorRow, type GraphDominatorsResult, type GraphExecutionSummary, type GraphImpactResult, type GraphImpactRow, type GraphHierarchySummary, type GraphIndexResult, type GraphKnowledgeSummary, type GraphPathRow, type GraphPathsResult, type GraphPlanResult, type GraphQueryCost, type GraphRedundancyResult, type GraphRedundancyRow, type GraphResult, type GraphScheduleRow, type GraphSlackResult, type GraphSubcommand, type GraphTraversalResult, } from "./run.js";
@@ -8,7 +8,7 @@
8
8
  * `sdk/relationships` and is safe for CLI, MCP, extension, and non-PM callers.
9
9
  */
10
10
 
11
- !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]="b5509c6e-1431-5316-a563-16681ced4f33")}catch(e){}}();
11
+ !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]="20842b89-cef6-542e-b069-76c22b340f1d")}catch(e){}}();
12
12
  export { computeRelationshipDominators, detectRelationshipCommunities, findRedundantRelationshipEdges, forEachMatchedRelationshipEdge, } from "./analytics.js";
13
13
  export { computeRelationshipCentrality, findRelationshipCutStructure, } from "./centrality.js";
14
14
  export { createRelationshipGraphSnapshot, federateRelationshipGraphSnapshots, loadRelationshipGraphAdapter, MemoryRelationshipGraphAdapter, parseRelationshipGraphSnapshot, RELATIONSHIP_GRAPH_SNAPSHOT_VERSION, syncRelationshipGraphAdapter, } from "./adapter.js";
@@ -16,6 +16,7 @@ export { assertMemoryRelationshipGraphAdapterConformance, assertRelationshipGrap
16
16
  export { analyzeRelationshipSchedule, } from "./scheduling.js";
17
17
  export { assembleWorkspaceRelationshipGraph, collectDanglingDependencyReferences, collectDuplicateDependencyRows, collectMissingDependencyTargetIds, collectOrderingStorageContradictions, normalizeDependencyGraphTarget, resolveWorkspaceRelationshipKindRegistry, } from "./assembly.js";
18
18
  export { auditWorkspaceRelationshipGraph, collectDuplicateRelationshipEdgeGroups, collectOrderingCycles, diffRelationshipAuditSnapshots, formatDuplicateEdgeGroup, formatOrderingStorageContradiction, } from "./governance.js";
19
+ export { analyzeHierarchyIntegrity, assertHierarchyMutationAllowed, collectHierarchyRelations, formatHierarchyRelation, indexHierarchyRelations, } from "./hierarchy-integrity.js";
19
20
  export { clearDurableGraphCache, durableGraphCachePath, durableGraphCacheStatus, GRAPH_DURABLE_CACHE_MIN_ITEMS, GRAPH_DURABLE_CACHE_VERSION, graphAuditBaselinePath, loadGraphAuditBaseline, openDurableGraphCache, persistDurableGraphResult, saveGraphAuditBaseline, shouldPersistDurableGraphCache, } from "./durable-cache.js";
20
21
  export { enumerateRelationshipPaths, hierarchyAncestors, hierarchyDescendants, orderingPredecessors, orderingSuccessors, } from "./traversal.js";
21
22
  export { computeWorkspaceGraphFingerprint, resetWorkspaceGraphCache, workspaceGraphCache, WorkspaceGraphCache, } from "./cache.js";
@@ -23,4 +24,4 @@ export { planRelationshipRemediation, } from "./remediation.js";
23
24
  export { collectNewOrderingCycleWarnings } from "./mutation-advisory.js";
24
25
  export { GRAPH_SUBCOMMAND_VALUES, parseGraphSubcommand, runGraph, } from "./run.js";
25
26
  //# sourceMappingURL=index.js.map
26
- //# debugId=b5509c6e-1431-5316-a563-16681ced4f33
27
+ //# debugId=20842b89-cef6-542e-b069-76c22b340f1d