@unbrained/pm-cli 2026.8.21 → 2026.8.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +44 -0
  3. package/dist/cli/error-guidance.d.ts +22 -4
  4. package/dist/cli/error-guidance.js +73 -16
  5. package/dist/cli/main.d.ts +3 -0
  6. package/dist/cli/main.js +51 -9
  7. package/dist/cli/register-mutation.js +6 -6
  8. package/dist/cli/register-operations.d.ts +73 -0
  9. package/dist/cli/register-operations.js +39 -14
  10. package/dist/cli/register-setup.js +3 -3
  11. package/dist/cli/schema-registration-helpers.d.ts +8 -1
  12. package/dist/cli/schema-registration-helpers.js +14 -5
  13. package/dist/cli-bundle/bundle-manifest.json +149 -149
  14. package/dist/cli-bundle/chunks/chunk-3ENVHX6C.js +36 -0
  15. package/dist/cli-bundle/chunks/{chunk-LOVTQ52Z.js → chunk-DW2CGEMU.js} +2 -2
  16. package/dist/cli-bundle/chunks/chunk-EG6CLDZT.js +5 -0
  17. package/dist/cli-bundle/chunks/{chunk-LARJJ3RK.js → chunk-F3AI2JFL.js} +2 -2
  18. package/dist/cli-bundle/chunks/{chunk-N3DSV4CH.js → chunk-HWZ6CELB.js} +8 -8
  19. package/dist/cli-bundle/chunks/chunk-HZBMLSZI.js +201 -0
  20. package/dist/cli-bundle/chunks/chunk-JB4KZWBF.js +3 -0
  21. package/dist/cli-bundle/chunks/chunk-KPH73XXJ.js +2 -0
  22. package/dist/cli-bundle/chunks/{chunk-BKYB45NQ.js → chunk-KXPMB2YL.js} +50 -50
  23. package/dist/cli-bundle/chunks/{chunk-BUNIEJNE.js → chunk-QDVHNHAQ.js} +2 -2
  24. package/dist/cli-bundle/chunks/chunk-TFI5V5N2.js +13 -0
  25. package/dist/cli-bundle/chunks/{register-list-query-F57EWDEF.js → register-list-query-UJB5FMV2.js} +2 -2
  26. package/dist/cli-bundle/chunks/register-mutation-NX5XE4VX.js +20 -0
  27. package/dist/cli-bundle/chunks/register-operations-RXIJIYXC.js +2 -0
  28. package/dist/cli-bundle/chunks/{register-setup-HXU7IZZD.js → register-setup-GFUZEKRE.js} +2 -2
  29. package/dist/cli-bundle/focused-chunks/{chunk-F4YEW5I2.js → chunk-37Z4OEAP.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/chunk-3UPTYG44.js +8 -0
  31. package/dist/cli-bundle/focused-chunks/chunk-5S7E72FY.js +16 -0
  32. package/dist/cli-bundle/focused-chunks/{chunk-4ERLO7QD.js → chunk-AUFH5H35.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-E7X25GC3.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/chunk-FQCSTBWE.js +4 -0
  35. package/dist/cli-bundle/focused-chunks/{chunk-FH6DYED3.js → chunk-FZS4H32O.js} +2 -2
  36. package/dist/cli-bundle/focused-chunks/chunk-IFLWKY2R.js +156 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-YKBKIEAJ.js → chunk-JOWDB2MH.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-LYVSW5VM.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-MRCNF3U6.js +2 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-UZE7XUZK.js → chunk-OFVUGTLJ.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-FJ22HNRP.js → chunk-OGLQBL46.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/chunk-OY7QAV4Y.js +51 -0
  43. package/dist/cli-bundle/focused-chunks/chunk-QGFNI65N.js +26 -0
  44. package/dist/cli-bundle/focused-chunks/{chunk-KDNG7TKQ.js → chunk-R27IDGHD.js} +2 -2
  45. package/dist/cli-bundle/focused-chunks/chunk-UYRFYCDQ.js +5 -0
  46. package/dist/cli-bundle/focused-chunks/{chunk-2NIY5NKG.js → chunk-ZHVA42R5.js} +9 -9
  47. package/dist/cli-bundle/main.js +13 -13
  48. package/dist/cli-bundle/sdk-authoring.js +1 -1
  49. package/dist/cli-bundle/sdk-contracts.js +2 -2
  50. package/dist/cli-bundle/sdk-core.js +40 -40
  51. package/dist/cli-bundle/sdk-governance.js +1 -1
  52. package/dist/cli-bundle/sdk-graph.js +1 -1
  53. package/dist/cli-bundle/sdk-merge.js +33 -32
  54. package/dist/cli-bundle/sdk-query.js +1 -1
  55. package/dist/cli-bundle/sdk-runtime.js +1 -1
  56. package/dist/cli-bundle/sdk-testing.js +1 -1
  57. package/dist/cli-bundle/sdk.js +5 -5
  58. package/dist/core/config/nested-settings.js +8 -2
  59. package/dist/core/config/positional-value.d.ts +1 -1
  60. package/dist/core/config/positional-value.js +5 -2
  61. package/dist/core/extensions/extension-hook-runtime.js +22 -20
  62. package/dist/core/extensions/extension-types.d.ts +8 -1
  63. package/dist/core/extensions/extension-types.js +2 -2
  64. package/dist/core/extensions/loader.js +7 -3
  65. package/dist/core/extensions/service-ownership.d.ts +8 -0
  66. package/dist/core/extensions/service-ownership.js +20 -0
  67. package/dist/core/history/history.js +3 -3
  68. package/dist/core/item/id.js +20 -5
  69. package/dist/core/item/item-format.js +81 -2
  70. package/dist/core/reproducibility/context.d.ts +4 -0
  71. package/dist/core/reproducibility/context.js +14 -8
  72. package/dist/core/shared/author.d.ts +55 -1
  73. package/dist/core/shared/author.js +333 -16
  74. package/dist/core/shared/constants.js +3 -2
  75. package/dist/core/shared/errors.d.ts +4 -0
  76. package/dist/core/shared/errors.js +2 -2
  77. package/dist/core/store/settings-validator.d.ts +1 -0
  78. package/dist/core/store/settings-validator.js +6 -3
  79. package/dist/core/store/settings.js +5 -2
  80. package/dist/mcp/server.d.ts +1 -1
  81. package/dist/mcp/server.js +30 -9
  82. package/dist/sdk/agent/identity-config.d.ts +63 -0
  83. package/dist/sdk/agent/identity-config.js +107 -0
  84. package/dist/sdk/agent/refusal-corpus-contracts.d.ts +76 -0
  85. package/dist/sdk/agent/refusal-corpus-contracts.js +194 -0
  86. package/dist/sdk/agent/refusal-reachability.d.ts +1 -1
  87. package/dist/sdk/authoring.d.ts +1 -1
  88. package/dist/sdk/authoring.js +2 -2
  89. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +77 -0
  90. package/dist/sdk/cli-contracts/agent-output-contracts.js +326 -2
  91. package/dist/sdk/cli-contracts/commander-mutation-options.js +3 -3
  92. package/dist/sdk/cli-contracts/enum-contracts.d.ts +4 -0
  93. package/dist/sdk/cli-contracts/enum-contracts.js +9 -2
  94. package/dist/sdk/cli-contracts/flag-contracts.js +9 -2
  95. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +4 -4
  96. package/dist/sdk/cli-contracts/registration-helpers.js +5 -2
  97. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +3 -1
  98. package/dist/sdk/cli-contracts/runtime-contracts.js +4 -3
  99. package/dist/sdk/cli-contracts/tool-parameter-tables.js +22 -2
  100. package/dist/sdk/cli-contracts/tool-schema.d.ts +1 -1
  101. package/dist/sdk/cli-contracts/tool-schema.js +14 -3
  102. package/dist/sdk/cli-contracts.d.ts +4 -4
  103. package/dist/sdk/cli-contracts.js +5 -5
  104. package/dist/sdk/config.d.ts +6 -1
  105. package/dist/sdk/config.js +119 -14
  106. package/dist/sdk/context-intent-contracts.js +4 -2
  107. package/dist/sdk/core-governance.d.ts +1 -1
  108. package/dist/sdk/core-governance.js +3 -3
  109. package/dist/sdk/extension/install-sources.d.ts +1 -1
  110. package/dist/sdk/extension/install-sources.js +6 -3
  111. package/dist/sdk/extension/output-ownership.d.ts +1 -0
  112. package/dist/sdk/extension/output-ownership.js +3 -2
  113. package/dist/sdk/extension/scaffold.js +11 -5
  114. package/dist/sdk/flag-invocation-contracts.js +4 -2
  115. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +74 -2
  116. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +87 -26
  117. package/dist/sdk/governance/assurance-action.js +30 -10
  118. package/dist/sdk/governance/health.d.ts +3 -0
  119. package/dist/sdk/governance/health.js +39 -7
  120. package/dist/sdk/governance/hierarchy-validation.d.ts +29 -0
  121. package/dist/sdk/governance/hierarchy-validation.js +109 -0
  122. package/dist/sdk/governance/validate.d.ts +3 -9
  123. package/dist/sdk/governance/validate.js +84 -111
  124. package/dist/sdk/graph/assembly.d.ts +6 -1
  125. package/dist/sdk/graph/assembly.js +16 -22
  126. package/dist/sdk/graph/governance-contracts.d.ts +1 -1
  127. package/dist/sdk/graph/governance-contracts.js +8 -2
  128. package/dist/sdk/graph/governance.js +46 -2
  129. package/dist/sdk/graph/hierarchy-integrity.d.ts +94 -0
  130. package/dist/sdk/graph/hierarchy-integrity.js +311 -0
  131. package/dist/sdk/graph/index.d.ts +2 -1
  132. package/dist/sdk/graph/index.js +3 -2
  133. package/dist/sdk/graph/remediation.js +32 -2
  134. package/dist/sdk/graph/run.d.ts +31 -2
  135. package/dist/sdk/graph/run.js +80 -31
  136. package/dist/sdk/graph/workspace-relationship-kind-registry.d.ts +8 -0
  137. package/dist/sdk/graph/workspace-relationship-kind-registry.js +28 -0
  138. package/dist/sdk/index.d.ts +8 -3
  139. package/dist/sdk/index.js +9 -4
  140. package/dist/sdk/item-children.js +21 -8
  141. package/dist/sdk/lifecycle/create.js +129 -97
  142. package/dist/sdk/lifecycle/hierarchy-mutation-lock.d.ts +15 -0
  143. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +25 -0
  144. package/dist/sdk/lifecycle/update.d.ts +2 -0
  145. package/dist/sdk/lifecycle/update.js +174 -84
  146. package/dist/sdk/merge/three-way.js +105 -26
  147. package/dist/sdk/query/complete-list.d.ts +3 -3
  148. package/dist/sdk/query/complete-list.js +46 -3
  149. package/dist/sdk/query/list.d.ts +4 -3
  150. package/dist/sdk/query/list.js +89 -49
  151. package/dist/sdk/read-output-budget.d.ts +21 -0
  152. package/dist/sdk/read-output-budget.js +39 -2
  153. package/dist/sdk/read-output-contracts.d.ts +10 -4
  154. package/dist/sdk/read-output-contracts.js +105 -32
  155. package/dist/sdk/relationship-context.js +3 -4
  156. package/dist/sdk/relationships.js +17 -10
  157. package/dist/sdk/reproducibility/process.d.ts +19 -0
  158. package/dist/sdk/reproducibility/process.js +88 -0
  159. package/dist/sdk/runtime-primitives.d.ts +1 -1
  160. package/dist/sdk/runtime-primitives.js +3 -3
  161. package/dist/sdk/runtime.d.ts +3 -2
  162. package/dist/sdk/runtime.js +7 -5
  163. package/dist/sdk/test/batch.d.ts +6 -0
  164. package/dist/sdk/test/batch.js +26 -6
  165. package/dist/sdk/test/entry.d.ts +1 -1
  166. package/dist/sdk/test/entry.js +3 -2
  167. package/dist/sdk/test/execution.d.ts +28 -3
  168. package/dist/sdk/test/execution.js +201 -34
  169. package/dist/sdk/test/parsers.d.ts +6 -0
  170. package/dist/sdk/test/parsers.js +21 -2
  171. package/dist/sdk/test/trust.d.ts +33 -0
  172. package/dist/sdk/test/trust.js +207 -0
  173. package/dist/types.d.ts +34 -0
  174. package/dist/types.js +2 -2
  175. package/docs/AGENT_PROVENANCE_ADR.md +41 -5
  176. package/docs/AGENT_UX_CONTRACTS.md +20 -4
  177. package/docs/COMMANDS.md +29 -14
  178. package/docs/CONFIGURATION.md +4 -0
  179. package/docs/DEPENDENCY_KIND_CONTRACT.md +31 -3
  180. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +115 -0
  181. package/docs/EXTENSIONS.md +2 -1
  182. package/docs/MERGE_SAFETY.md +15 -1
  183. package/docs/README.md +1 -0
  184. package/docs/READ_OUTPUT_CONTRACTS.md +19 -2
  185. package/docs/RELATIONSHIP_GRAPH.md +6 -3
  186. package/docs/REPRODUCIBLE_WORKSPACES.md +42 -8
  187. package/docs/SDK.md +9 -0
  188. package/docs/SDK_AGENT_SESSION_CONTEXT.md +6 -4
  189. package/docs/SDK_EVIDENCE_TRACEABILITY.md +1 -1
  190. package/docs/TESTING.md +83 -1
  191. package/docs/agent-task-token-baseline.json +2 -2
  192. package/docs/generated/FLAG_LEXICON_BUDGETS.md +2 -2
  193. package/marketplace.json +2 -2
  194. package/package.json +2 -2
  195. package/packages/pm-beads/package.json +1 -1
  196. package/packages/pm-calendar/package.json +1 -1
  197. package/packages/pm-command-kit/package.json +1 -1
  198. package/packages/pm-digital-twin/package.json +1 -1
  199. package/packages/pm-governance-audit/package.json +1 -1
  200. package/packages/pm-guide-shell/package.json +1 -1
  201. package/packages/pm-kanban/package.json +1 -1
  202. package/packages/pm-lifecycle-hooks/package.json +1 -1
  203. package/packages/pm-linked-test-adapters/package.json +1 -1
  204. package/packages/pm-search-advanced/package.json +1 -1
  205. package/packages/pm-templates/package.json +1 -1
  206. package/packages/pm-todos/package.json +1 -1
  207. package/packages/pm-vcs/package.json +1 -1
  208. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  209. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  210. package/sdk/public-surface.json +1021 -53
  211. package/dist/cli-bundle/chunks/chunk-2MA6ZQVZ.js +0 -197
  212. package/dist/cli-bundle/chunks/chunk-3AFAUHUE.js +0 -2
  213. package/dist/cli-bundle/chunks/chunk-7VHZS727.js +0 -5
  214. package/dist/cli-bundle/chunks/chunk-JSLOFXGA.js +0 -3
  215. package/dist/cli-bundle/chunks/chunk-OCLPLFAY.js +0 -35
  216. package/dist/cli-bundle/chunks/chunk-S4IRYKBU.js +0 -13
  217. package/dist/cli-bundle/chunks/register-mutation-7IY2D5KO.js +0 -20
  218. package/dist/cli-bundle/chunks/register-operations-FALL3YTU.js +0 -2
  219. package/dist/cli-bundle/focused-chunks/chunk-7WZRLCYF.js +0 -50
  220. package/dist/cli-bundle/focused-chunks/chunk-CKKQSJNN.js +0 -2
  221. package/dist/cli-bundle/focused-chunks/chunk-EEFKYMDR.js +0 -16
  222. package/dist/cli-bundle/focused-chunks/chunk-F2A56DHV.js +0 -8
  223. package/dist/cli-bundle/focused-chunks/chunk-FV5ACOK7.js +0 -2
  224. package/dist/cli-bundle/focused-chunks/chunk-JEAVFOWM.js +0 -2
  225. package/dist/cli-bundle/focused-chunks/chunk-NJ63LOP6.js +0 -155
  226. package/dist/cli-bundle/focused-chunks/chunk-NXRTQ7HI.js +0 -2
  227. package/dist/cli-bundle/focused-chunks/chunk-TJ7EMJ46.js +0 -4
  228. package/dist/cli-bundle/focused-chunks/chunk-ZOSEELYJ.js +0 -26
@@ -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
@@ -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]="1eb0e2cb-084a-5a54-b41c-29dfdd6d2f34")}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]="7054952e-444a-5be2-b0c1-fcc3b72afde5")}catch(e){}}();
3
3
  import { findRedundantRelationshipEdges } from "./analytics.js";
4
4
  import { auditWorkspaceRelationshipGraph, collectDuplicateRelationshipEdgeGroups, formatDuplicateEdgeGroup, } from "./governance.js";
5
5
  /** Per-finding-code operation template applied to every sampled subject. */
@@ -39,6 +39,36 @@ const FINDING_STEP_TEMPLATES = {
39
39
  confidence: "high",
40
40
  rationale: "The terminal holder contains a proven contradictory structured ordering row; remove it in a dedicated changelog-safe batch while preserving the scalar blocker as history.",
41
41
  },
42
+ hierarchy_cycle: {
43
+ op: "investigate",
44
+ confidence: "low",
45
+ rationale: "Cut or retype one exact structural relation in the cycle; the planner preserves every evidence row because intent determines the correct parent.",
46
+ },
47
+ legacy_hierarchy_cycle: {
48
+ op: "waive",
49
+ confidence: "high",
50
+ rationale: "Terminal-only hierarchy cycles are historical debt; waive them unless an explicit closed-history repair is approved.",
51
+ },
52
+ hierarchy_cardinality_violation: {
53
+ op: "investigate",
54
+ confidence: "medium",
55
+ rationale: "Choose the canonical parent and remove or retype the exact surplus hierarchy rows; the planner cannot infer ownership intent.",
56
+ },
57
+ legacy_hierarchy_cardinality_violation: {
58
+ op: "waive",
59
+ confidence: "high",
60
+ rationale: "Multiple parents confined to terminal items are historical debt; waive them unless a dedicated history repair is approved.",
61
+ },
62
+ hierarchy_direction_violation: {
63
+ op: "investigate",
64
+ confidence: "medium",
65
+ rationale: "Align the scalar parent and dependency-backed hierarchy rows to the intended canonical parent.",
66
+ },
67
+ legacy_hierarchy_direction_violation: {
68
+ op: "waive",
69
+ confidence: "high",
70
+ rationale: "Divergent hierarchy storage confined to terminal items is historical debt; waive it unless a dedicated history repair is approved.",
71
+ },
42
72
  // duplicate_edge findings are expanded into per-stored-edge remove steps by
43
73
  // the planner itself (see stepsFromDuplicateGroup); this template documents
44
74
  // the family for exhaustiveness and backs any future sample-only fallback.
@@ -165,4 +195,4 @@ export function planRelationshipRemediation(assembly, options = {}) {
165
195
  };
166
196
  }
167
197
  //# sourceMappingURL=remediation.js.map
168
- //# debugId=1eb0e2cb-084a-5a54-b41c-29dfdd6d2f34
198
+ //# debugId=7054952e-444a-5be2-b0c1-fcc3b72afde5
@@ -159,6 +159,33 @@ export interface GraphKnowledgeSummary {
159
159
  degree: number;
160
160
  }[];
161
161
  }
162
+ /** Unified hierarchy-integrity projection inside an analyze result. */
163
+ export interface GraphHierarchySummary {
164
+ /** Whether the structural hierarchy is acyclic. */
165
+ acyclic: boolean;
166
+ /** Total canonical parent-child evidence rows. */
167
+ relation_count: number;
168
+ /** Total strongly connected hierarchy components. */
169
+ cycle_count: number;
170
+ /** Active hierarchy cycles that require remediation. */
171
+ active_cycle_count?: number;
172
+ /** Terminal-only hierarchy cycles retained as historical debt. */
173
+ legacy_cycle_count?: number;
174
+ /** Total children that resolve to more than one logical parent. */
175
+ cardinality_violation_count: number;
176
+ /** Active one-parent cardinality violations. */
177
+ active_cardinality_violation_count?: number;
178
+ /** Terminal-only one-parent cardinality violations. */
179
+ legacy_cardinality_violation_count?: number;
180
+ /** Total scalar/dependency parent disagreements. */
181
+ parent_divergence_count: number;
182
+ /** Active scalar/dependency parent disagreements. */
183
+ active_parent_divergence_count?: number;
184
+ /** Terminal-only scalar/dependency parent disagreements. */
185
+ legacy_parent_divergence_count?: number;
186
+ /** Bounded hierarchy-cycle sample; absent with summary. */
187
+ cycles?: string[][];
188
+ }
162
189
  /** Result envelope for the analyze subcommand. */
163
190
  export interface GraphAnalyzeResult {
164
191
  /** Executed graph subcommand. */
@@ -175,6 +202,8 @@ export interface GraphAnalyzeResult {
175
202
  execution: GraphExecutionSummary;
176
203
  /** Structural analytics over every stored edge. */
177
204
  knowledge: GraphKnowledgeSummary;
205
+ /** Registry-driven structural hierarchy integrity across all storage surfaces. */
206
+ hierarchy?: GraphHierarchySummary;
178
207
  /** Cache observability for this invocation. */
179
208
  cache?: GraphCacheMetadata;
180
209
  }
@@ -192,8 +221,8 @@ export interface GraphAuditResult {
192
221
  affected_subjects_by_severity: Record<string, number>;
193
222
  /** Affected-subject counts keyed by finding code. */
194
223
  affected_subjects_by_code: Record<string, number>;
195
- /** Structural coverage metrics computed during the audit. */
196
- profile: RelationshipAuditReport["profile"];
224
+ /** Structural coverage metrics; the duplicated finding census is absent with summary. */
225
+ profile: Omit<RelationshipAuditReport["profile"], "finding_subjects_by_code"> & Partial<Pick<RelationshipAuditReport["profile"], "finding_subjects_by_code">>;
197
226
  /** Stored legacy relationship aliases grouped by spelling; canonical graph counts remain in profile. */
198
227
  legacy_alias_counts?: Record<string, number>;
199
228
  /** Ordered findings with bounded evidence samples; absent with summary. */