@unbrained/pm-cli 2026.8.13 → 2026.8.15

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 (194) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +165 -113
  3. package/dist/cli/commander-usage.js +17 -4
  4. package/dist/cli/error-guidance.d.ts +2 -0
  5. package/dist/cli/error-guidance.js +52 -25
  6. package/dist/cli/main.js +40 -3
  7. package/dist/cli/register-mutation.js +4 -2
  8. package/dist/cli/register-operations.js +5 -5
  9. package/dist/cli-bundle/bundle-manifest.json +146 -178
  10. package/dist/cli-bundle/chunks/{chunk-F7FJYGK3.js → chunk-24GAV7XL.js} +2 -2
  11. package/dist/cli-bundle/chunks/chunk-AIM6VT2N.js +13 -0
  12. package/dist/cli-bundle/chunks/chunk-DSWDLTDR.js +197 -0
  13. package/dist/cli-bundle/chunks/{chunk-Q47C67TQ.js → chunk-J42EGKDK.js} +2 -2
  14. package/dist/cli-bundle/chunks/chunk-KIEGUBYQ.js +2 -0
  15. package/dist/cli-bundle/chunks/{chunk-3ZMOWAFM.js → chunk-KLKYLSDX.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-QGTUPEU5.js → chunk-LJHOAVGI.js} +59 -59
  17. package/dist/cli-bundle/chunks/chunk-MEM2ZS3O.js +5 -0
  18. package/dist/cli-bundle/chunks/chunk-QHPCJWEJ.js +35 -0
  19. package/dist/cli-bundle/chunks/{chunk-YLBAPY22.js → chunk-WLPDLNEZ.js} +2 -2
  20. package/dist/cli-bundle/chunks/{register-list-query-4HIZ7EA3.js → register-list-query-CT3LFDDN.js} +2 -2
  21. package/dist/cli-bundle/chunks/{register-mutation-W64FZ5HN.js → register-mutation-NWEVA5YS.js} +3 -3
  22. package/dist/cli-bundle/chunks/register-operations-AHIAG5KM.js +2 -0
  23. package/dist/cli-bundle/chunks/{register-setup-634MFRXU.js → register-setup-ZJZFVAKE.js} +2 -2
  24. package/dist/cli-bundle/focused-chunks/chunk-4X57RE4U.js +2 -0
  25. package/dist/cli-bundle/focused-chunks/chunk-6XKF3PGV.js +18 -0
  26. package/dist/cli-bundle/focused-chunks/chunk-7NJ4QYQ2.js +2 -0
  27. package/dist/cli-bundle/focused-chunks/{chunk-I75MANL7.js → chunk-EXZA4257.js} +2 -2
  28. package/dist/cli-bundle/focused-chunks/chunk-ITAUHSO6.js +50 -0
  29. package/dist/cli-bundle/focused-chunks/{chunk-OOYYKQWX.js → chunk-KLVUMNXJ.js} +2 -2
  30. package/dist/cli-bundle/focused-chunks/{chunk-2RI2FESN.js → chunk-KT5XMYSX.js} +2 -2
  31. package/dist/cli-bundle/focused-chunks/{chunk-E3AVJ655.js → chunk-KTKH4IMG.js} +2 -2
  32. package/dist/cli-bundle/focused-chunks/chunk-M67F5AIN.js +8 -0
  33. package/dist/cli-bundle/focused-chunks/{chunk-3DJSGWVB.js → chunk-NSPYTG6G.js} +2 -2
  34. package/dist/cli-bundle/focused-chunks/chunk-OKA6ELTL.js +2 -0
  35. package/dist/cli-bundle/focused-chunks/chunk-PUISBOPP.js +2 -0
  36. package/dist/cli-bundle/focused-chunks/chunk-QLNMCESQ.js +155 -0
  37. package/dist/cli-bundle/focused-chunks/{chunk-IIS2FRKL.js → chunk-SLKC6QLJ.js} +2 -2
  38. package/dist/cli-bundle/focused-chunks/chunk-U65UC4G3.js +2 -0
  39. package/dist/cli-bundle/focused-chunks/chunk-WTSER4WJ.js +16 -0
  40. package/dist/cli-bundle/focused-chunks/{chunk-2JP7W7GO.js → chunk-ZMFXQ7VF.js} +2 -2
  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 +1 -1
  44. package/dist/cli-bundle/sdk-core.js +41 -41
  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 +110 -1
  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 +2 -2
  52. package/dist/core/diagnostics/remediation.js +7 -2
  53. package/dist/core/extensions/reserved-host-flags.js +3 -2
  54. package/dist/core/history/drift-scan.d.ts +6 -0
  55. package/dist/core/history/drift-scan.js +74 -50
  56. package/dist/core/history/replay.d.ts +14 -1
  57. package/dist/core/history/replay.js +45 -8
  58. package/dist/core/history/workspace-history.d.ts +59 -0
  59. package/dist/core/history/workspace-history.js +197 -10
  60. package/dist/core/output/output.d.ts +2 -0
  61. package/dist/core/output/output.js +13 -4
  62. package/dist/core/shared/command-types.d.ts +2 -0
  63. package/dist/core/shared/command-types.js +2 -2
  64. package/dist/core/shared/errors.d.ts +12 -0
  65. package/dist/core/shared/errors.js +2 -2
  66. package/dist/mcp/tool-definitions.js +9 -5
  67. package/dist/sdk/agent/refusal-reachability.d.ts +61 -0
  68. package/dist/sdk/agent/refusal-reachability.js +91 -3
  69. package/dist/sdk/cli-bootstrap.d.ts +2 -0
  70. package/dist/sdk/cli-bootstrap.js +7 -2
  71. package/dist/sdk/cli-contracts/completeness.js +3 -2
  72. package/dist/sdk/cli-contracts/flag-contracts.js +3 -2
  73. package/dist/sdk/cli-contracts/registration-helpers.js +3 -2
  74. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +11 -1
  75. package/dist/sdk/cli-contracts/runtime-contracts.js +176 -65
  76. package/dist/sdk/cli-contracts/tool-parameter-tables.js +15 -5
  77. package/dist/sdk/cli-contracts/tool-schema.js +10 -3
  78. package/dist/sdk/cli-program.js +4 -3
  79. package/dist/sdk/context-relevance.js +12 -4
  80. package/dist/sdk/core.d.ts +2 -2
  81. package/dist/sdk/core.js +3 -3
  82. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +26 -2
  83. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +50 -26
  84. package/dist/sdk/governance/assurance-action.d.ts +7 -1
  85. package/dist/sdk/governance/assurance-action.js +7 -6
  86. package/dist/sdk/governance/assurance-mutation-error.d.ts +42 -1
  87. package/dist/sdk/governance/assurance-mutation-error.js +27 -3
  88. package/dist/sdk/governance/assurance-runtime.js +12 -11
  89. package/dist/sdk/governance/assurance.d.ts +9 -0
  90. package/dist/sdk/governance/assurance.js +82 -16
  91. package/dist/sdk/governance/extension-host-version.d.ts +25 -0
  92. package/dist/sdk/governance/extension-host-version.js +105 -0
  93. package/dist/sdk/governance/health.d.ts +32 -1
  94. package/dist/sdk/governance/health.js +132 -28
  95. package/dist/sdk/governance/provenance-health.d.ts +27 -0
  96. package/dist/sdk/governance/provenance-health.js +95 -3
  97. package/dist/sdk/governance/validate-history-drift.d.ts +7 -0
  98. package/dist/sdk/governance/validate-history-drift.js +68 -0
  99. package/dist/sdk/governance/validate.js +9 -52
  100. package/dist/sdk/governance.d.ts +6 -0
  101. package/dist/sdk/governance.js +8 -2
  102. package/dist/sdk/graph/assembly.d.ts +23 -0
  103. package/dist/sdk/graph/assembly.js +54 -2
  104. package/dist/sdk/graph/durable-cache.js +50 -20
  105. package/dist/sdk/graph/governance-contracts.d.ts +1 -1
  106. package/dist/sdk/graph/governance-contracts.js +4 -2
  107. package/dist/sdk/graph/governance.d.ts +21 -1
  108. package/dist/sdk/graph/governance.js +94 -32
  109. package/dist/sdk/graph/index.d.ts +2 -2
  110. package/dist/sdk/graph/index.js +4 -4
  111. package/dist/sdk/graph/mutation-advisory.js +15 -7
  112. package/dist/sdk/graph/remediation.js +12 -2
  113. package/dist/sdk/history-read.d.ts +8 -0
  114. package/dist/sdk/history-read.js +2 -2
  115. package/dist/sdk/history-repair.d.ts +13 -1
  116. package/dist/sdk/history-repair.js +62 -18
  117. package/dist/sdk/index.d.ts +1 -1
  118. package/dist/sdk/index.js +3 -3
  119. package/dist/sdk/linked-artifacts.js +16 -5
  120. package/dist/sdk/pagination.d.ts +15 -0
  121. package/dist/sdk/pagination.js +9 -5
  122. package/dist/sdk/query/context.d.ts +5 -1
  123. package/dist/sdk/query/context.js +14 -5
  124. package/dist/sdk/query/history.js +20 -3
  125. package/dist/sdk/read-output/continuation.d.ts +11 -0
  126. package/dist/sdk/read-output/continuation.js +132 -0
  127. package/dist/sdk/read-output-budget.d.ts +3 -1
  128. package/dist/sdk/read-output-budget.js +24 -13
  129. package/dist/sdk/read-output-contracts.d.ts +127 -7
  130. package/dist/sdk/read-output-contracts.js +381 -35
  131. package/dist/sdk/read-output-rows.d.ts +13 -0
  132. package/dist/sdk/read-output-rows.js +60 -2
  133. package/dist/sdk/runtime-input.js +4 -2
  134. package/dist/sdk/runtime-primitives.d.ts +1 -1
  135. package/dist/sdk/runtime-primitives.js +3 -3
  136. package/dist/sdk/runtime.js +5 -3
  137. package/docs/ASSURANCE.md +68 -2
  138. package/docs/COMMANDS.md +39 -4
  139. package/docs/READ_OUTPUT_CONTRACTS.md +85 -8
  140. package/docs/RELATIONSHIP_GRAPH.md +20 -5
  141. package/docs/RELEASING.md +42 -5
  142. package/docs/SDK.md +12 -5
  143. package/docs/SDK_CONTEXT_INTEGRITY.md +94 -1
  144. package/docs/TESTING.md +23 -1
  145. package/docs/performance/sdk-entrypoint-import-costs.md +20 -13
  146. package/marketplace.json +2 -2
  147. package/package.json +7 -7
  148. package/packages/pm-beads/extensions/beads/index.ts +1 -0
  149. package/packages/pm-beads/package.json +1 -1
  150. package/packages/pm-calendar/extensions/calendar/index.ts +1 -0
  151. package/packages/pm-calendar/package.json +1 -1
  152. package/packages/pm-command-kit/package.json +1 -1
  153. package/packages/pm-digital-twin/extensions/digital-twin/index.ts +7 -0
  154. package/packages/pm-digital-twin/package.json +1 -1
  155. package/packages/pm-governance-audit/extensions/governance-audit/index.ts +4 -0
  156. package/packages/pm-governance-audit/package.json +1 -1
  157. package/packages/pm-guide-shell/extensions/guide-shell/index.ts +5 -0
  158. package/packages/pm-guide-shell/package.json +1 -1
  159. package/packages/pm-kanban/package.json +1 -1
  160. package/packages/pm-lifecycle-hooks/package.json +1 -1
  161. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/index.ts +6 -0
  162. package/packages/pm-linked-test-adapters/package.json +1 -1
  163. package/packages/pm-search-advanced/extensions/search-advanced/index.ts +2 -0
  164. package/packages/pm-search-advanced/package.json +1 -1
  165. package/packages/pm-templates/extensions/templates/index.ts +4 -0
  166. package/packages/pm-templates/package.json +1 -1
  167. package/packages/pm-todos/extensions/todos/index.ts +2 -0
  168. package/packages/pm-todos/package.json +1 -1
  169. package/packages/pm-vcs/extensions/vcs/index.ts +7 -0
  170. package/packages/pm-vcs/package.json +1 -1
  171. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  172. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  173. package/scripts/bundle-cli.mjs +17 -4
  174. package/sdk/public-surface.json +1283 -157
  175. package/dist/cli-bundle/chunks/chunk-DEDU3DG7.js +0 -196
  176. package/dist/cli-bundle/chunks/chunk-DL5M5J3V.js +0 -13
  177. package/dist/cli-bundle/chunks/chunk-HIUZVCMN.js +0 -5
  178. package/dist/cli-bundle/chunks/chunk-IMGIN7R6.js +0 -2
  179. package/dist/cli-bundle/chunks/chunk-TF3TPKPR.js +0 -34
  180. package/dist/cli-bundle/chunks/register-operations-C44ET7R5.js +0 -2
  181. package/dist/cli-bundle/focused-chunks/chunk-27N23W6M.js +0 -31
  182. package/dist/cli-bundle/focused-chunks/chunk-3BNVU6LC.js +0 -8
  183. package/dist/cli-bundle/focused-chunks/chunk-6MLIRBLV.js +0 -5
  184. package/dist/cli-bundle/focused-chunks/chunk-6XYLENDV.js +0 -155
  185. package/dist/cli-bundle/focused-chunks/chunk-CP4K4WFS.js +0 -2
  186. package/dist/cli-bundle/focused-chunks/chunk-EBTNSFYE.js +0 -2
  187. package/dist/cli-bundle/focused-chunks/chunk-HC2OL2H2.js +0 -2
  188. package/dist/cli-bundle/focused-chunks/chunk-NFHFZH2Z.js +0 -2
  189. package/dist/cli-bundle/focused-chunks/chunk-OGC4XSBC.js +0 -17
  190. package/dist/cli-bundle/focused-chunks/chunk-PKPOZXLL.js +0 -2
  191. package/dist/cli-bundle/focused-chunks/chunk-QDZUABWL.js +0 -2
  192. package/dist/cli-bundle/focused-chunks/chunk-QQX5TDFT.js +0 -16
  193. package/dist/cli-bundle/focused-chunks/chunk-TEZIXMTH.js +0 -2
  194. package/dist/cli-bundle/focused-chunks/chunk-WEH6NSL6.js +0 -18
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @module sdk/governance/validate-history-drift
3
+ *
4
+ * Projects append-only item and workspace singleton drift into the validation
5
+ * check contract without adding history-specific weight to the main validate
6
+ * orchestration module.
7
+ */
8
+
9
+ !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]="a1261d65-222c-5c6c-8634-a4413a91aba9")}catch(e){}}();
10
+ import { scanHistoryDrift } from "../../core/history/drift-scan.js";
11
+ const DEFAULT_DIAGNOSTIC_LIMIT = 5;
12
+ /** Build the validation warning and bounded evidence projection for history drift. */
13
+ export async function buildValidateHistoryDriftCheck(pmRoot, items, verboseDiagnostics) {
14
+ const drift = await scanHistoryDrift(pmRoot, items);
15
+ const warningCounts = [
16
+ ["validate_history_drift_missing_streams", drift.missingStreams.length],
17
+ ["validate_history_drift_unreadable_streams", drift.unreadableStreams.length],
18
+ ["validate_history_drift_hash_mismatches", drift.hashMismatches.length],
19
+ ["validate_history_drift_chain_mismatches", drift.chainMismatches.length],
20
+ [
21
+ "validate_history_drift_workspace_state_mismatches",
22
+ drift.workspaceStateMismatches.length,
23
+ ],
24
+ [
25
+ "validate_history_drift_workspace_state_missing",
26
+ drift.workspaceStateMissing.length,
27
+ ],
28
+ [
29
+ "validate_history_drift_workspace_state_unreadable",
30
+ drift.workspaceStateUnreadable.length,
31
+ ],
32
+ ];
33
+ const warnings = warningCounts
34
+ .filter(([, count]) => count > 0)
35
+ .map(([code, count]) => `${code}:${count}`);
36
+ const diagnosticLimit = verboseDiagnostics
37
+ ? Number.POSITIVE_INFINITY
38
+ : DEFAULT_DIAGNOSTIC_LIMIT;
39
+ const driftedItems = drift.driftedItems.slice(0, diagnosticLimit);
40
+ return {
41
+ check: {
42
+ name: "history_drift",
43
+ status: warnings.length === 0 ? "ok" : "warn",
44
+ ok: warnings.length === 0,
45
+ details: {
46
+ checked_items: items.length,
47
+ drifted_items_count: drift.driftedItems.length,
48
+ drifted_items: driftedItems,
49
+ drifted_items_truncated: driftedItems.length < drift.driftedItems.length,
50
+ counts: {
51
+ missing_streams: drift.missingStreams.length,
52
+ unreadable_streams: drift.unreadableStreams.length,
53
+ hash_mismatches: drift.hashMismatches.length,
54
+ chain_mismatches: drift.chainMismatches.length,
55
+ workspace_state_mismatches: drift.workspaceStateMismatches.length,
56
+ workspace_state_missing: drift.workspaceStateMissing.length,
57
+ workspace_state_unreadable: drift.workspaceStateUnreadable.length,
58
+ },
59
+ workspace_state_mismatches: drift.workspaceStateMismatches,
60
+ workspace_state_missing: drift.workspaceStateMissing,
61
+ workspace_state_unreadable: drift.workspaceStateUnreadable,
62
+ },
63
+ },
64
+ warnings,
65
+ };
66
+ }
67
+ //# sourceMappingURL=validate-history-drift.js.map
68
+ //# debugId=a1261d65-222c-5c6c-8634-a4413a91aba9
@@ -4,7 +4,7 @@
4
4
  * Implements the pm validate command surface and its agent-facing runtime behavior.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7dd04a2f-1798-5c16-8740-5b7094f81cc0")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b8c4707f-5445-5079-96e5-dc0dbd649b34")}catch(e){}}();
8
8
  import fs from "node:fs/promises";
9
9
  import { realpathSync } from "node:fs";
10
10
  import { execFile } from "node:child_process";
@@ -14,7 +14,6 @@ import { buildRemediationCommands } from "../../core/diagnostics/remediation.js"
14
14
  import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
15
15
  import { collectRegisteredItemFieldNames } from "../../core/extensions/item-fields.js";
16
16
  import { isFileMissingError, pathExists } from "../../core/fs/fs-utils.js";
17
- import { scanHistoryDrift } from "../../core/history/drift-scan.js";
18
17
  import { normalizeStatusInput } from "../../core/item/status.js";
19
18
  import { resolveItemTypeRegistry } from "../../core/item/type-registry.js";
20
19
  import { resolveRuntimeStatusRegistry, } from "../../core/schema/runtime-schema.js";
@@ -43,6 +42,7 @@ import { runDocs } from "../docs.js";
43
42
  import { runFiles } from "../files.js";
44
43
  import { extractReferencedPmItemIdsFromCommand } from "../test/linked-command-detection.js";
45
44
  import { readValidateItems, } from "./validate-item-reader.js";
45
+ import { buildValidateHistoryDriftCheck } from "./validate-history-drift.js";
46
46
  const FILE_SCAN_DIRECTORIES = ["src", "tests", "docs"];
47
47
  const FILE_SCAN_ROOT_FILES = [
48
48
  "README.md",
@@ -778,9 +778,7 @@ function buildMetadataCounts(metadataPolicy, missingByField) {
778
778
  const missing = missingByField[field];
779
779
  const value = missing ? missing.length : 0;
780
780
  const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
781
- if (value > 0 && countKey) {
782
- counts[countKey] = value;
783
- }
781
+ counts[countKey] = value;
784
782
  }
785
783
  return counts;
786
784
  }
@@ -858,9 +856,10 @@ function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagno
858
856
  const duplicateIssueCodes = findDuplicateIssueCodes(items);
859
857
  const duplicateIssueCodeSummary = summarizeDuplicateIssueCodes(duplicateIssueCodes, verboseDiagnostics);
860
858
  const warningTokens = buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateIssueCodeSummary.warnings);
861
- // Zero-suppress counts to reduce agent token cost (telemetry pm-tylj).
862
- // Only emit counts for the ACTIVE required fields of the resolved profile so a
863
- // looser profile (e.g. core) never reports missing reviewer/risk/sprint/etc.
859
+ // Emit an explicit numeric predicate for every ACTIVE required field. Stable
860
+ // zeroes let assurance consumers distinguish a passing metric from an absent
861
+ // contract key without exposing any per-item diagnostic rows.
862
+ // A looser profile (e.g. core) still never reports reviewer/risk/sprint/etc.
864
863
  // Defensive guards (Gemini high #1, PR #78 follow-up): a future settings
865
864
  // shape could include an unsupported field in required_fields — fall back
866
865
  // to 0 instead of throwing TypeError, and skip writing when the count-key
@@ -1767,48 +1766,6 @@ async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, inclu
1767
1766
  };
1768
1767
  }
1769
1768
  /* c8 ignore stop */
1770
- /* c8 ignore start -- history-drift warning/count projection permutations are covered by drift integration tests */
1771
- async function buildHistoryDriftCheck(pmRoot, items, verboseDiagnostics) {
1772
- const { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems, } = await scanHistoryDrift(pmRoot, items);
1773
- const warnings = [];
1774
- if (missingStreams.length > 0) {
1775
- warnings.push(`validate_history_drift_missing_streams:${missingStreams.length}`);
1776
- }
1777
- if (unreadableStreams.length > 0) {
1778
- warnings.push(`validate_history_drift_unreadable_streams:${unreadableStreams.length}`);
1779
- }
1780
- if (hashMismatches.length > 0) {
1781
- warnings.push(`validate_history_drift_hash_mismatches:${hashMismatches.length}`);
1782
- }
1783
- if (chainMismatches.length > 0) {
1784
- warnings.push(`validate_history_drift_chain_mismatches:${chainMismatches.length}`);
1785
- }
1786
- const diagnosticLimit = verboseDiagnostics
1787
- ? Number.POSITIVE_INFINITY
1788
- : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1789
- const summarizedDrifted = summarizeList(driftedItems, diagnosticLimit);
1790
- return {
1791
- check: {
1792
- name: "history_drift",
1793
- status: warnings.length === 0 ? "ok" : "warn",
1794
- ok: warnings.length === 0,
1795
- details: {
1796
- checked_items: items.length,
1797
- drifted_items_count: driftedItems.length,
1798
- drifted_items: summarizedDrifted.values,
1799
- drifted_items_truncated: summarizedDrifted.truncated,
1800
- counts: {
1801
- missing_streams: missingStreams.length,
1802
- unreadable_streams: unreadableStreams.length,
1803
- hash_mismatches: hashMismatches.length,
1804
- chain_mismatches: chainMismatches.length,
1805
- },
1806
- },
1807
- },
1808
- warnings,
1809
- };
1810
- }
1811
- /* c8 ignore stop */
1812
1769
  /* c8 ignore start -- command preview truncation formatting is covered by command-reference integration fixtures */
1813
1770
  function summarizeCommandReferenceRow(ownerId, referencedId, command) {
1814
1771
  const normalizedCommand = command.trim().replaceAll(/\s+/g, " ");
@@ -2195,7 +2152,7 @@ async function executeRequestedValidateChecks(params) {
2195
2152
  recordValidateCheck(state, buildCommandReferencesCheck(params.items, params.settings.id_prefix, fullDiagnostics), fixHintsEnabled);
2196
2153
  }
2197
2154
  if (params.requestedChecks.has("history_drift")) {
2198
- recordValidateCheck(state, await buildHistoryDriftCheck(params.pmRoot, params.items, fullDiagnostics), fixHintsEnabled);
2155
+ recordValidateCheck(state, await buildValidateHistoryDriftCheck(params.pmRoot, params.items, fullDiagnostics), fixHintsEnabled);
2199
2156
  }
2200
2157
  if (params.requestedChecks.has("format_version")) {
2201
2158
  recordValidateCheck(state, buildFormatVersionCheck(params.items, fullDiagnostics), fixHintsEnabled);
@@ -2356,4 +2313,4 @@ export async function runValidate(options, global, services = {}) {
2356
2313
  }
2357
2314
  /* c8 ignore stop */
2358
2315
  //# sourceMappingURL=validate.js.map
2359
- //# debugId=7dd04a2f-1798-5c16-8740-5b7094f81cc0
2316
+ //# debugId=b8c4707f-5445-5079-96e5-dc0dbd649b34
@@ -5,6 +5,12 @@
5
5
  */
6
6
  export * from "./governance/gc.js";
7
7
  export * from "./governance/health.js";
8
+ export * from "./governance/extension-host-version.js";
9
+ export * from "./governance/assurance.js";
10
+ export * from "./governance/assurance-action.js";
11
+ export * from "./governance/assurance-mutation-error.js";
12
+ export * from "./governance/assurance-presets.js";
13
+ export * from "./governance/assurance-runtime.js";
8
14
  export { runReindex, type ReindexOptions, type ReindexResult, } from "./governance/reindex.js";
9
15
  export * from "./governance/stale-work.js";
10
16
  export * from "./governance/storage-integrity.js";
@@ -4,9 +4,15 @@
4
4
  * Provides validation, health, integrity, and mutation-policy primitives.
5
5
  */
6
6
 
7
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8e8c2de1-7bff-57c6-8e71-9c27e9e76eaa")}catch(e){}}();
7
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="0baaaf38-2a32-5d6e-92bc-9919d2393f86")}catch(e){}}();
8
8
  export * from "./governance/gc.js";
9
9
  export * from "./governance/health.js";
10
+ export * from "./governance/extension-host-version.js";
11
+ export * from "./governance/assurance.js";
12
+ export * from "./governance/assurance-action.js";
13
+ export * from "./governance/assurance-mutation-error.js";
14
+ export * from "./governance/assurance-presets.js";
15
+ export * from "./governance/assurance-runtime.js";
10
16
  export { runReindex, } from "./governance/reindex.js";
11
17
  export * from "./governance/stale-work.js";
12
18
  export * from "./governance/storage-integrity.js";
@@ -17,4 +23,4 @@ export * from "./mutation-guard.js";
17
23
  export * from "./governance/provenance-health.js";
18
24
  export * from "./similarity.js";
19
25
  //# sourceMappingURL=governance.js.map
20
- //# debugId=8e8c2de1-7bff-57c6-8e71-9c27e9e76eaa
26
+ //# debugId=0baaaf38-2a32-5d6e-92bc-9919d2393f86
@@ -77,6 +77,19 @@ export interface DuplicateDependencyRow {
77
77
  /** Whether the holder is terminal and the duplication is historical debt. */
78
78
  legacy_terminal: boolean;
79
79
  }
80
+ /** One holder whose scalar blocker and structured ordering row assert opposite precedence. */
81
+ export interface OrderingStorageContradiction {
82
+ /** Item storing both contradictory representations. */
83
+ holder_id: string;
84
+ /** Target named by both the scalar blocker and structured dependency row. */
85
+ target_id: string;
86
+ /** Structured ordering kind that places the holder before the target. */
87
+ dependency_kind: string;
88
+ /** Current lifecycle status of the holder. */
89
+ holder_status: ItemStatus;
90
+ /** Whether the holder is terminal and the contradiction is historical debt. */
91
+ legacy_terminal: boolean;
92
+ }
80
93
  /**
81
94
  * Collect raw stored dependency rows whose exact identity — holder, kind, and
82
95
  * case-insensitive target — appears more than once on one item. Graph
@@ -85,6 +98,14 @@ export interface DuplicateDependencyRow {
85
98
  * only surface that reports the storage-layer defect.
86
99
  */
87
100
  export declare function collectDuplicateDependencyRows(items: readonly DependencyReferenceHolder[], isTerminal?: (status: ItemStatus) => boolean): DuplicateDependencyRow[];
101
+ /**
102
+ * Collect storage rows where `blocked_by: target` places the target before the
103
+ * holder while a same-target structured ordering dependency places the holder
104
+ * before the target. The contradictory rows form an artificial two-node cycle
105
+ * after graph assembly, so this pre-assembly evidence identifies the exact row
106
+ * to remove instead of reporting only strongly connected component members.
107
+ */
108
+ export declare function collectOrderingStorageContradictions(items: readonly DependencyReferenceHolder[], isTerminal?: (status: ItemStatus) => boolean, registry?: RelationshipKindRegistry): OrderingStorageContradiction[];
88
109
  /**
89
110
  * Classify missing hierarchy and dependency targets without mutating their holders.
90
111
  *
@@ -127,6 +148,8 @@ export interface WorkspaceRelationshipAssembly {
127
148
  dangling: DanglingDependencyReferenceSummary;
128
149
  /** Raw same-identity duplicated dependency rows found before graph dedup. */
129
150
  duplicateRows: DuplicateDependencyRow[];
151
+ /** Scalar-versus-structured ordering contradictions found before graph normalization. */
152
+ orderingContradictions?: OrderingStorageContradiction[];
130
153
  /** Raw legacy alias rows grouped by accepted spelling before graph canonicalization. */
131
154
  legacyAliasCounts: Record<string, number>;
132
155
  }
@@ -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]="62ec8e0e-658e-5a32-b458-439d5ffd1229")}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]="a6fc5da1-b7d1-5b3c-8033-cecccc7861c3")}catch(e){}}();
3
3
  import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
4
4
  import { RelationshipGraph, createRelationshipKindRegistry, } from "../relationships.js";
5
5
  import { isExternalDependencySourceKind } from "../dependency-provenance.js";
@@ -104,6 +104,57 @@ export function collectDuplicateDependencyRows(items, isTerminal = (status) => s
104
104
  return compareCaseFoldedText(left.kind, right.kind);
105
105
  });
106
106
  }
107
+ /** Decode one dependency row only when it contradicts the holder's scalar blocker. */
108
+ function decodeOrderingStorageContradiction(item, blocker, dependency, isTerminal, registry) {
109
+ if (typeof dependency !== "object" || dependency === null)
110
+ return undefined;
111
+ const target = normalizeDependencyReferenceTarget(dependency.id);
112
+ if (!target || target.toLowerCase() !== blocker.toLowerCase())
113
+ return undefined;
114
+ const definition = registry.resolve(typeof dependency.kind === "string" ? dependency.kind : "related");
115
+ if (definition?.ordering !== true ||
116
+ (definition.precedence ?? "source_before_target") !== "source_before_target")
117
+ return undefined;
118
+ return {
119
+ holder_id: item.id.trim(),
120
+ target_id: target,
121
+ dependency_kind: definition.kind,
122
+ holder_status: item.status,
123
+ legacy_terminal: isTerminal(item.status),
124
+ };
125
+ }
126
+ /**
127
+ * Collect storage rows where `blocked_by: target` places the target before the
128
+ * holder while a same-target structured ordering dependency places the holder
129
+ * before the target. The contradictory rows form an artificial two-node cycle
130
+ * after graph assembly, so this pre-assembly evidence identifies the exact row
131
+ * to remove instead of reporting only strongly connected component members.
132
+ */
133
+ export function collectOrderingStorageContradictions(items, isTerminal = (status) => status === "closed" || status === "canceled", registry = resolveWorkspaceRelationshipKindRegistry()) {
134
+ const contradictions = new Map();
135
+ for (const item of items) {
136
+ if (typeof item?.id !== "string" || item.id.trim().length === 0)
137
+ continue;
138
+ const blocker = normalizeDependencyReferenceTarget(item.blocked_by);
139
+ if (!blocker)
140
+ continue;
141
+ for (const dependency of item.dependencies ?? []) {
142
+ const row = decodeOrderingStorageContradiction(item, blocker, dependency, isTerminal, registry);
143
+ if (!row)
144
+ continue;
145
+ contradictions.set(`${row.holder_id.toLowerCase()}\u0000${row.target_id.toLowerCase()}\u0000${row.dependency_kind}`, row);
146
+ }
147
+ }
148
+ return [...contradictions.values()].sort((left, right) => {
149
+ const holderCompare = compareCaseFoldedText(left.holder_id, right.holder_id);
150
+ if (holderCompare !== 0)
151
+ return holderCompare;
152
+ const targetCompare = compareCaseFoldedText(left.target_id, right.target_id);
153
+ if (targetCompare !== 0)
154
+ return targetCompare;
155
+ return compareCaseFoldedText(left.dependency_kind, right.dependency_kind);
156
+ });
157
+ }
107
158
  /**
108
159
  * Classify missing hierarchy and dependency targets without mutating their holders.
109
160
  *
@@ -296,8 +347,9 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
296
347
  missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),
297
348
  dangling,
298
349
  duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),
350
+ orderingContradictions: collectOrderingStorageContradictions(safeItems, isTerminal, relationshipRegistry),
299
351
  legacyAliasCounts: collectLegacyDependencyAliasCounts(safeItems, relationshipRegistry),
300
352
  };
301
353
  }
302
354
  //# sourceMappingURL=assembly.js.map
303
- //# debugId=62ec8e0e-658e-5a32-b458-439d5ffd1229
355
+ //# debugId=a6fc5da1-b7d1-5b3c-8033-cecccc7861c3
@@ -15,7 +15,7 @@
15
15
  * threshold or after an explicit `pm graph index --rebuild` opt-in.
16
16
  */
17
17
 
18
- !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]="2f7f14e3-6d41-5f45-a560-ebfbb8aa5828")}catch(e){}}();
18
+ !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]="9e4aa41d-fca4-5e55-ab2b-d99f06d90ae2")}catch(e){}}();
19
19
  import path from "node:path";
20
20
  import { readFileIfExists, removeFileIfExists, writeFileAtomic, } from "../../core/fs/fs-utils.js";
21
21
  import { acquireLock } from "../../core/lock/lock.js";
@@ -174,8 +174,52 @@ function isNonnegativeCoverageByTypeRecord(value) {
174
174
  return Object.values(value).every((entry) => isRecord(entry) &&
175
175
  [entry.active, entry.isolated, entry.degree_leq_one].every(isNonnegativeInteger));
176
176
  }
177
+ /** Decode the additive information-bearing census as one coherent field group. */
178
+ function decodeInformativeProfile(profile, nodes, edges) {
179
+ const fields = [
180
+ "recorded_nodes",
181
+ "informative_edges",
182
+ "redundant_edges",
183
+ "ordering_contradiction_edges",
184
+ ];
185
+ const presentCount = fields.filter((field) => profile[field] !== undefined).length;
186
+ if (presentCount !== 0 && presentCount !== fields.length)
187
+ return undefined;
188
+ if (!fields.every((field) => isOptionalValid(profile[field], isNonnegativeInteger)))
189
+ return undefined;
190
+ const decoded = {
191
+ recorded_nodes: profile.recorded_nodes ?? nodes,
192
+ informative_edges: profile.informative_edges ?? edges,
193
+ redundant_edges: profile.redundant_edges ?? 0,
194
+ ordering_contradiction_edges: profile.ordering_contradiction_edges ?? 0,
195
+ };
196
+ return decoded.recorded_nodes <= nodes &&
197
+ decoded.informative_edges <= edges &&
198
+ decoded.redundant_edges <= edges &&
199
+ decoded.ordering_contradiction_edges <= edges
200
+ ? decoded
201
+ : undefined;
202
+ }
203
+ /** Validate the optional structural census fields as one complete version group. */
204
+ function hasValidStructuralFields(profile, countFields, rateFields) {
205
+ const introducedFields = [
206
+ ...countFields,
207
+ ...rateFields,
208
+ "finding_subjects_by_code",
209
+ ];
210
+ const presentCount = introducedFields.filter((field) => profile[field] !== undefined).length;
211
+ if (presentCount !== 0 && presentCount !== introducedFields.length)
212
+ return false;
213
+ return (countFields.every((field) => isOptionalValid(profile[field], isNonnegativeInteger)) &&
214
+ rateFields.every((field) => isOptionalValid(profile[field], isNonnegativeInteger) &&
215
+ (profile[field] === undefined || Number(profile[field]) <= 10_000)) &&
216
+ isOptionalValid(profile.finding_subjects_by_code, isNonnegativeCountRecord));
217
+ }
177
218
  /** Decode optional structural fields while normalizing pre-structure baselines. */
178
- function decodeStructuralProfile(profile, affectedSubjectsByCode) {
219
+ function decodeStructuralProfile(profile, affectedSubjectsByCode, nodes, edges) {
220
+ const informative = decodeInformativeProfile(profile, nodes, edges);
221
+ if (informative === undefined)
222
+ return undefined;
179
223
  const countFields = [
180
224
  "articulation_points",
181
225
  "bridge_edges",
@@ -193,31 +237,17 @@ function decodeStructuralProfile(profile, affectedSubjectsByCode) {
193
237
  "terminal_outcome_reachability_basis_points",
194
238
  "outcome_reachability_basis_points",
195
239
  ];
196
- const introducedStructuralFields = [
197
- ...countFields,
198
- ...rateFields,
199
- "finding_subjects_by_code",
200
- ];
201
- const introducedStructuralFieldCount = introducedStructuralFields.filter((field) => profile[field] !== undefined).length;
202
- if (introducedStructuralFieldCount !== 0 &&
203
- introducedStructuralFieldCount !== introducedStructuralFields.length) {
204
- return undefined;
205
- }
206
- const validCounts = countFields.every((field) => profile[field] === undefined || isNonnegativeInteger(profile[field]));
207
- const validRates = rateFields.every((field) => profile[field] === undefined ||
208
- (isNonnegativeInteger(profile[field]) && Number(profile[field]) <= 10_000));
209
- if (!validCounts || !validRates)
240
+ if (!hasValidStructuralFields(profile, countFields, rateFields))
210
241
  return undefined;
211
242
  if (profile.edge_basis !== undefined &&
212
243
  profile.edge_basis !== "deduplicated_directed")
213
244
  return undefined;
214
- if (!isOptionalValid(profile.finding_subjects_by_code, isNonnegativeCountRecord))
215
- return undefined;
216
245
  const findingSubjects = isNonnegativeCountRecord(profile.finding_subjects_by_code)
217
246
  ? profile.finding_subjects_by_code
218
247
  : {};
219
248
  return {
220
249
  edge_basis: "deduplicated_directed",
250
+ ...informative,
221
251
  ...Object.fromEntries(countFields.map((field) => [field, profile[field] ?? 0])),
222
252
  ...Object.fromEntries(rateFields.map((field) => [field, profile[field] ?? 0])),
223
253
  finding_subjects_by_code: Object.fromEntries(RELATIONSHIP_AUDIT_FINDING_CODES.map((code) => [
@@ -302,7 +332,7 @@ function decodeBaseline(raw) {
302
332
  const composition = decodeGraphComposition(profile.edges, profile.edges_by_kind, profile.edge_share_by_kind, profile.semantic_edges, profile.semantic_edge_share);
303
333
  if (composition === undefined)
304
334
  return undefined;
305
- const structural = decodeStructuralProfile(profile, affectedSubjectsByCode);
335
+ const structural = decodeStructuralProfile(profile, affectedSubjectsByCode, profile.nodes, profile.edges);
306
336
  if (structural === undefined)
307
337
  return undefined;
308
338
  const { coverage_by_type = {} } = profile;
@@ -329,4 +359,4 @@ export async function saveGraphAuditBaseline(pmRoot, snapshot) {
329
359
  await writeFileAtomic(graphAuditBaselinePath(pmRoot), JSON.stringify(snapshot));
330
360
  }
331
361
  //# sourceMappingURL=durable-cache.js.map
332
- //# debugId=2f7f14e3-6d41-5f45-a560-ebfbb8aa5828
362
+ //# debugId=9e4aa41d-fca4-5e55-ab2b-d99f06d90ae2
@@ -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", "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", "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,13 +8,15 @@
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]="a2043b27-3dfe-5da8-a10f-d92ff33f3c28")}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]="bc561e73-75b8-5ea7-a18c-da70fb991b69")}catch(e){}}();
12
12
  export const RELATIONSHIP_AUDIT_FINDING_CODES = [
13
13
  "missing_reference_active",
14
14
  "missing_reference_terminal",
15
15
  "legacy_no_blocker_sentinel",
16
16
  "ordering_cycle",
17
17
  "legacy_ordering_cycle",
18
+ "ordering_storage_contradiction",
19
+ "legacy_ordering_storage_contradiction",
18
20
  "duplicate_edge",
19
21
  "legacy_duplicate_edge",
20
22
  "duplicate_dependency_row",
@@ -24,4 +26,4 @@ export const RELATIONSHIP_AUDIT_FINDING_CODES = [
24
26
  "sparse_active_node",
25
27
  ];
26
28
  //# sourceMappingURL=governance-contracts.js.map
27
- //# debugId=a2043b27-3dfe-5da8-a10f-d92ff33f3c28
29
+ //# debugId=bc561e73-75b8-5ea7-a18c-da70fb991b69
@@ -13,7 +13,7 @@
13
13
  * agents can plan remediation without re-deriving context.
14
14
  */
15
15
  import type { RelationshipEdge } from "../relationships.js";
16
- import type { WorkspaceRelationshipAssembly } from "./assembly.js";
16
+ import type { OrderingStorageContradiction, WorkspaceRelationshipAssembly } from "./assembly.js";
17
17
  import { type RelationshipAuditFindingCode } from "./governance-contracts.js";
18
18
  export type { RelationshipAuditFindingCode } from "./governance-contracts.js";
19
19
  /** Severity ladder shared by every relationship audit finding. */
@@ -32,6 +32,8 @@ export interface RelationshipAuditFinding {
32
32
  count: number;
33
33
  /** Deterministic bounded sample of affected subjects. */
34
34
  sample: string[];
35
+ /** Optional exact evidence that explains why the sampled subjects were selected. */
36
+ evidence?: string[];
35
37
  /** Whether {@link sample} was truncated by the configured sample bound. */
36
38
  sample_truncated: boolean;
37
39
  /** Safe machine-actionable next step; audits never invent or auto-apply edges. */
@@ -50,8 +52,16 @@ export interface RelationshipCoverageTypeProfile {
50
52
  export interface RelationshipCoverageProfile {
51
53
  /** Total indexed nodes including materialized missing placeholders. */
52
54
  nodes: number;
55
+ /** Tracker-recorded nodes, excluding synthesized missing and external placeholders. */
56
+ recorded_nodes?: number;
53
57
  /** Total deduplicated indexed edges. */
54
58
  edges: number;
59
+ /** Edges that remain after excluding redundant and contradictory storage rows. */
60
+ informative_edges?: number;
61
+ /** Stored edges implied by a bounded longer path in the same semantic family. */
62
+ redundant_edges?: number;
63
+ /** Structured ordering edges that contradict a same-target scalar blocker. */
64
+ ordering_contradiction_edges?: number;
55
65
  /** Counting convention used by edges and edges_by_kind. */
56
66
  edge_basis: "deduplicated_directed";
57
67
  /** Deterministic per-kind edge counts. */
@@ -134,6 +144,8 @@ export declare function isSemanticContextKind(kind: string): boolean;
134
144
  * advisories) share one cycle semantics with the workspace audit.
135
145
  */
136
146
  export declare function collectOrderingCycles(successors: Map<string, string[]>): string[][];
147
+ /** Format the exact contradictory storage pair that manufactures an ordering cycle. */
148
+ export declare function formatOrderingStorageContradiction(contradiction: Pick<OrderingStorageContradiction, "holder_id" | "target_id" | "dependency_kind">): string;
137
149
  /** One duplicate-edge group in semantic orientation with its stored spellings. */
138
150
  export interface DuplicateRelationshipEdgeGroup {
139
151
  /** Semantic tail node shared by every stored spelling. */
@@ -189,8 +201,16 @@ export interface RelationshipAuditDelta {
189
201
  profile: {
190
202
  /** Node-count change including missing placeholders. */
191
203
  nodes: number;
204
+ /** Tracker-recorded node-count change excluding synthesized placeholders. */
205
+ recorded_nodes?: number;
192
206
  /** Deduplicated edge-count change. */
193
207
  edges: number;
208
+ /** Informative edge-count change after non-information deductions. */
209
+ informative_edges?: number;
210
+ /** Redundant edge-count change. */
211
+ redundant_edges?: number;
212
+ /** Ordering contradiction edge-count change. */
213
+ ordering_contradiction_edges?: number;
194
214
  /** Active-node-count change. */
195
215
  active_nodes: number;
196
216
  /** Missing-placeholder-count change. */