audit-tools 0.32.54 → 0.32.56

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 (124) hide show
  1. package/dist/audit/cli/auditStep.d.ts +0 -1
  2. package/dist/audit/cli/auditStep.d.ts.map +1 -1
  3. package/dist/audit/cli/dispatch/pausePersist.d.ts +60 -0
  4. package/dist/audit/cli/dispatch/pausePersist.d.ts.map +1 -0
  5. package/dist/audit/cli/dispatch/pausePersist.js +110 -0
  6. package/dist/audit/cli/dispatch/pausePersist.js.map +1 -0
  7. package/dist/audit/cli/dispatch/types.d.ts +12 -0
  8. package/dist/audit/cli/dispatch/types.d.ts.map +1 -1
  9. package/dist/audit/cli/dispatch.d.ts.map +1 -1
  10. package/dist/audit/cli/dispatch.js +64 -1
  11. package/dist/audit/cli/dispatch.js.map +1 -1
  12. package/dist/audit/cli/mergeAndIngestCommand.d.ts +9 -0
  13. package/dist/audit/cli/mergeAndIngestCommand.d.ts.map +1 -1
  14. package/dist/audit/cli/mergeAndIngestCommand.js +2 -27
  15. package/dist/audit/cli/mergeAndIngestCommand.js.map +1 -1
  16. package/dist/audit/cli/nextStepCommand.d.ts +0 -10
  17. package/dist/audit/cli/nextStepCommand.d.ts.map +1 -1
  18. package/dist/audit/cli/nextStepCommand.js +3 -33
  19. package/dist/audit/cli/nextStepCommand.js.map +1 -1
  20. package/dist/audit/cli/rollingAuditDispatch.d.ts.map +1 -1
  21. package/dist/audit/cli/rollingAuditDispatch.js +55 -115
  22. package/dist/audit/cli/rollingAuditDispatch.js.map +1 -1
  23. package/dist/audit/cli/semanticReviewStep.d.ts.map +1 -1
  24. package/dist/audit/cli/semanticReviewStep.js +41 -0
  25. package/dist/audit/cli/semanticReviewStep.js.map +1 -1
  26. package/dist/audit/orchestrator/intentScopeDisposition.d.ts +14 -24
  27. package/dist/audit/orchestrator/intentScopeDisposition.d.ts.map +1 -1
  28. package/dist/audit/orchestrator/intentScopeDisposition.js +17 -35
  29. package/dist/audit/orchestrator/intentScopeDisposition.js.map +1 -1
  30. package/dist/audit/orchestrator/scope.d.ts +0 -1
  31. package/dist/audit/orchestrator/scope.d.ts.map +1 -1
  32. package/dist/audit/orchestrator/scope.js +2 -4
  33. package/dist/audit/orchestrator/scope.js.map +1 -1
  34. package/dist/audit/quota/index.d.ts +81 -76
  35. package/dist/audit/quota/index.d.ts.map +1 -1
  36. package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
  37. package/dist/audit/reporting/mergeFindings.js +17 -222
  38. package/dist/audit/reporting/mergeFindings.js.map +1 -1
  39. package/dist/audit/systemic/systemicChallengeLoop.d.ts.map +1 -1
  40. package/dist/audit/systemic/systemicChallengeLoop.js +3 -8
  41. package/dist/audit/systemic/systemicChallengeLoop.js.map +1 -1
  42. package/dist/audit/types/auditState.d.ts +0 -8
  43. package/dist/audit/types/auditState.d.ts.map +1 -1
  44. package/dist/audit/types/auditState.js +0 -6
  45. package/dist/audit/types/auditState.js.map +1 -1
  46. package/dist/remediate/dedup/crossLensDedup.d.ts +11 -4
  47. package/dist/remediate/dedup/crossLensDedup.d.ts.map +1 -1
  48. package/dist/remediate/dedup/crossLensDedup.js +27 -146
  49. package/dist/remediate/dedup/crossLensDedup.js.map +1 -1
  50. package/dist/remediate/index.d.ts +0 -10
  51. package/dist/remediate/index.d.ts.map +1 -1
  52. package/dist/remediate/index.js +1 -32
  53. package/dist/remediate/index.js.map +1 -1
  54. package/dist/remediate/intent/checkpointFilter.d.ts +4 -3
  55. package/dist/remediate/intent/checkpointFilter.d.ts.map +1 -1
  56. package/dist/remediate/intent/checkpointFilter.js +12 -53
  57. package/dist/remediate/intent/checkpointFilter.js.map +1 -1
  58. package/dist/remediate/steps/dispatch/marshal.d.ts.map +1 -1
  59. package/dist/remediate/steps/dispatch/marshal.js +14 -60
  60. package/dist/remediate/steps/dispatch/marshal.js.map +1 -1
  61. package/dist/remediate/steps/nextStep.d.ts.map +1 -1
  62. package/dist/remediate/steps/nextStep.js +48 -4
  63. package/dist/remediate/steps/nextStep.js.map +1 -1
  64. package/dist/remediate/steps/providerNodeDispatch.d.ts.map +1 -1
  65. package/dist/remediate/steps/providerNodeDispatch.js +12 -53
  66. package/dist/remediate/steps/providerNodeDispatch.js.map +1 -1
  67. package/dist/remediate/steps/rollingSession.d.ts +13 -0
  68. package/dist/remediate/steps/rollingSession.d.ts.map +1 -1
  69. package/dist/remediate/steps/rollingSession.js +35 -1
  70. package/dist/remediate/steps/rollingSession.js.map +1 -1
  71. package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
  72. package/dist/remediate/validation/contractPipelineGates.js +13 -4
  73. package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
  74. package/dist/shared/dispatch/admissionLeaseReconcile.d.ts +20 -0
  75. package/dist/shared/dispatch/admissionLeaseReconcile.d.ts.map +1 -0
  76. package/dist/shared/dispatch/admissionLeaseReconcile.js +36 -0
  77. package/dist/shared/dispatch/admissionLeaseReconcile.js.map +1 -0
  78. package/dist/shared/dispatch/admissionLoop.d.ts +9 -0
  79. package/dist/shared/dispatch/admissionLoop.d.ts.map +1 -1
  80. package/dist/shared/dispatch/admissionLoop.js +13 -1
  81. package/dist/shared/dispatch/admissionLoop.js.map +1 -1
  82. package/dist/shared/dispatch/hostDispatchWall.d.ts +34 -0
  83. package/dist/shared/dispatch/hostDispatchWall.d.ts.map +1 -0
  84. package/dist/shared/dispatch/hostDispatchWall.js +15 -0
  85. package/dist/shared/dispatch/hostDispatchWall.js.map +1 -0
  86. package/dist/shared/dispatch/providerLaunchFinalize.d.ts +49 -0
  87. package/dist/shared/dispatch/providerLaunchFinalize.d.ts.map +1 -0
  88. package/dist/shared/dispatch/providerLaunchFinalize.js +90 -0
  89. package/dist/shared/dispatch/providerLaunchFinalize.js.map +1 -0
  90. package/dist/shared/dispatch/rollingDispatch.d.ts +0 -15
  91. package/dist/shared/dispatch/rollingDispatch.d.ts.map +1 -1
  92. package/dist/shared/dispatch/rollingDispatch.js.map +1 -1
  93. package/dist/shared/findings/dedupe.d.ts +106 -0
  94. package/dist/shared/findings/dedupe.d.ts.map +1 -0
  95. package/dist/shared/findings/dedupe.js +304 -0
  96. package/dist/shared/findings/dedupe.js.map +1 -0
  97. package/dist/shared/friction/blindDispatchFriction.d.ts +26 -0
  98. package/dist/shared/friction/blindDispatchFriction.d.ts.map +1 -0
  99. package/dist/shared/friction/blindDispatchFriction.js +41 -0
  100. package/dist/shared/friction/blindDispatchFriction.js.map +1 -0
  101. package/dist/shared/index.d.ts +9 -0
  102. package/dist/shared/index.d.ts.map +1 -1
  103. package/dist/shared/index.js +7 -0
  104. package/dist/shared/index.js.map +1 -1
  105. package/dist/shared/intake/guidanceBootstrap.d.ts +13 -0
  106. package/dist/shared/intake/guidanceBootstrap.d.ts.map +1 -0
  107. package/dist/shared/intake/guidanceBootstrap.js +36 -0
  108. package/dist/shared/intake/guidanceBootstrap.js.map +1 -0
  109. package/dist/shared/intent/pathScope.d.ts +27 -0
  110. package/dist/shared/intent/pathScope.d.ts.map +1 -0
  111. package/dist/shared/intent/pathScope.js +99 -0
  112. package/dist/shared/intent/pathScope.js.map +1 -0
  113. package/dist/shared/quota/capacity.d.ts +39 -30
  114. package/dist/shared/quota/capacity.d.ts.map +1 -1
  115. package/dist/shared/quota/capacity.js +8 -0
  116. package/dist/shared/quota/capacity.js.map +1 -1
  117. package/dist/shared/quota/quotaSource.d.ts +2 -2
  118. package/dist/shared/quota/scheduler.d.ts.map +1 -1
  119. package/dist/shared/quota/scheduler.js +6 -1
  120. package/dist/shared/quota/scheduler.js.map +1 -1
  121. package/dist/shared/quota/types.d.ts +10 -0
  122. package/dist/shared/quota/types.d.ts.map +1 -1
  123. package/dist/shared/quota/types.js.map +1 -1
  124. package/package.json +1 -1
@@ -1,182 +1,5 @@
1
1
  import { severityRank, confidenceRank } from "./findingRanks.js";
2
- import { wordJaccard, filePathOverlap, primaryPath } from "audit-tools/shared";
3
- function normalizeText(value) {
4
- return (value ?? "").trim().toLowerCase();
5
- }
6
- /**
7
- * File-independent finding identity. Re-emissions of the same logical finding
8
- * (exact normalized lens + category + title) across files, units, and passes
9
- * share one key, so the exact-key merge collapses them into a single finding
10
- * whose affected_files / evidence are the union of every re-emission.
11
- *
12
- * Cross-file merging happens ONLY on this exact equality — the fuzzy
13
- * (Jaccard-title) dedup passes below stay grouped by primary path, which is
14
- * what guarantees that distinct problems in different units never collapse
15
- * on mere similarity.
16
- */
17
- function findingKey(finding) {
18
- return [
19
- normalizeText(finding.lens),
20
- normalizeText(finding.category),
21
- normalizeText(finding.title),
22
- ].join("|");
23
- }
24
- function runtimeSummary(report) {
25
- if (!report) {
26
- return [];
27
- }
28
- return report.results
29
- .filter((result) => result.status !== "pending")
30
- .map((result) => `${result.task_id}: ${result.status} — ${result.summary}`);
31
- }
32
- function mergeAffectedFiles(existing, incoming) {
33
- const seen = new Set(existing.affected_files.map((f) => `${f.path}:${f.line_start ?? ""}:${f.line_end ?? ""}:${f.symbol ?? ""}`));
34
- for (const file of incoming.affected_files) {
35
- const key = `${file.path}:${file.line_start ?? ""}:${file.line_end ?? ""}:${file.symbol ?? ""}`;
36
- if (!seen.has(key)) {
37
- existing.affected_files.push(file);
38
- seen.add(key);
39
- }
40
- }
41
- existing.affected_files.sort((a, b) => a.path.localeCompare(b.path) || (a.line_start ?? 0) - (b.line_start ?? 0));
42
- }
43
- /**
44
- * Merge two grounding verdicts by precedence: grounded > refuted > ungrounded >
45
- * absent (S7). Grounded-wins (a verified span/anchor on ANY pass upgrades the
46
- * survivor — an ungrounded or absent verdict never downgrades it). A refutation
47
- * (anchor DISPROOF) outranks ungrounded/absent, so a finding refuted on any pass
48
- * is quarantined UNLESS another pass grounded it (grounded still wins over
49
- * refuted — B4: "refuted only excludes when nothing grounded it"). Without the
50
- * grounded-wins rule, merging a same-identity re-emission that carried no matching
51
- * quote into a verified survivor would falsely quarantine a finding that DID
52
- * re-verify on another pass.
53
- */
54
- function mergeGrounding(existing, incoming) {
55
- const rank = (g) => g?.status === "grounded" ? 3 : g?.status === "refuted" ? 2 : g?.status === "ungrounded" ? 1 : 0;
56
- const winner = rank(incoming) > rank(existing) ? incoming : existing;
57
- // Normalize a grounded winner to the bare verdict (grounded carries no reason),
58
- // preserving the prior contract; refuted/ungrounded keep their reason.
59
- return winner?.status === "grounded" ? { status: "grounded" } : winner;
60
- }
61
- function absorbFinding(survivor, absorbed) {
62
- mergeAffectedFiles(survivor, absorbed);
63
- survivor.evidence = [
64
- ...new Set([
65
- ...(survivor.evidence ?? []),
66
- ...(absorbed.evidence ?? []),
67
- ]),
68
- ];
69
- survivor.systemic = Boolean(survivor.systemic || absorbed.systemic);
70
- survivor.grounding = mergeGrounding(survivor.grounding, absorbed.grounding);
71
- if (absorbed.summary.length > survivor.summary.length) {
72
- survivor.summary = absorbed.summary;
73
- }
74
- }
75
- function lineRangeOverlaps(a, b) {
76
- const aFile = a.affected_files[0];
77
- const bFile = b.affected_files[0];
78
- if (!aFile || !bFile)
79
- return false;
80
- if (aFile.path !== bFile.path)
81
- return false;
82
- const aStart = aFile.line_start ?? 0;
83
- const aEnd = aFile.line_end ?? aStart;
84
- const bStart = bFile.line_start ?? 0;
85
- const bEnd = bFile.line_end ?? bStart;
86
- if (aEnd === 0 && bEnd === 0)
87
- return true;
88
- return aStart <= bEnd && bStart <= aEnd;
89
- }
90
- function deduplicateSameLens(findings) {
91
- const groups = new Map();
92
- for (const finding of findings) {
93
- const key = `${normalizeText(finding.lens)}:${primaryPath(finding)}`;
94
- const group = groups.get(key);
95
- if (group) {
96
- group.push(finding);
97
- }
98
- else {
99
- groups.set(key, [finding]);
100
- }
101
- }
102
- const removed = new Set();
103
- for (const group of groups.values()) {
104
- if (group.length < 2)
105
- continue;
106
- for (let i = 0; i < group.length; i++) {
107
- if (removed.has(group[i]))
108
- continue;
109
- for (let j = i + 1; j < group.length; j++) {
110
- if (removed.has(group[j]))
111
- continue;
112
- const a = group[i];
113
- const b = group[j];
114
- const titleSim = wordJaccard(a.title, b.title);
115
- const catMatch = normalizeText(a.category) === normalizeText(b.category);
116
- const threshold = catMatch ? 0.35 : 0.45;
117
- if (titleSim < threshold)
118
- continue;
119
- if (!lineRangeOverlaps(a, b) && filePathOverlap(a, b) < 0.5)
120
- continue;
121
- const aSev = severityRank(a.severity);
122
- const bSev = severityRank(b.severity);
123
- const aConf = confidenceRank(a.confidence);
124
- const bConf = confidenceRank(b.confidence);
125
- const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
126
- const [survivor, absorbed] = keepA ? [a, b] : [b, a];
127
- absorbFinding(survivor, absorbed);
128
- removed.add(absorbed);
129
- }
130
- }
131
- }
132
- return findings.filter((f) => !removed.has(f));
133
- }
134
- function deduplicateCrossLens(findings) {
135
- const groups = new Map();
136
- for (const finding of findings) {
137
- const key = primaryPath(finding);
138
- const group = groups.get(key);
139
- if (group) {
140
- group.push(finding);
141
- }
142
- else {
143
- groups.set(key, [finding]);
144
- }
145
- }
146
- const removed = new Set();
147
- for (const group of groups.values()) {
148
- if (group.length < 2)
149
- continue;
150
- for (let i = 0; i < group.length; i++) {
151
- if (removed.has(group[i]))
152
- continue;
153
- for (let j = i + 1; j < group.length; j++) {
154
- if (removed.has(group[j]))
155
- continue;
156
- const a = group[i];
157
- const b = group[j];
158
- if (normalizeText(a.lens) === normalizeText(b.lens))
159
- continue;
160
- const titleSim = wordJaccard(a.title, b.title);
161
- const catMatch = normalizeText(a.category) === normalizeText(b.category);
162
- const threshold = catMatch ? 0.4 : 0.5;
163
- if (titleSim < threshold)
164
- continue;
165
- if (filePathOverlap(a, b) < 0.5)
166
- continue;
167
- const aSev = severityRank(a.severity);
168
- const bSev = severityRank(b.severity);
169
- const aConf = confidenceRank(a.confidence);
170
- const bConf = confidenceRank(b.confidence);
171
- const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
172
- const [survivor, absorbed] = keepA ? [a, b] : [b, a];
173
- absorbFinding(survivor, absorbed);
174
- removed.add(absorbed);
175
- }
176
- }
177
- }
178
- return findings.filter((f) => !removed.has(f));
179
- }
2
+ import { crossLensDedupe, sameLensDedupe, upsertFindingByIdentity, } from "audit-tools/shared";
180
3
  function relevantRuntimeEvidence(finding, report) {
181
4
  if (!report)
182
5
  return [];
@@ -203,45 +26,6 @@ function relevantExternalEvidence(finding, results) {
203
26
  .filter((item) => findingPaths.has(item.path))
204
27
  .map((item) => `external:${tool.tool}:${item.path}:${item.summary}`));
205
28
  }
206
- /**
207
- * Insert a finding into the identity-keyed map, or absorb it into the existing
208
- * finding with the same identity: affected_files and evidence are unioned,
209
- * severity / confidence escalate to the maximum rank seen, `systemic` ORs,
210
- * impact / likelihood backfill, and the longest summary wins.
211
- */
212
- function upsertFinding(merged, finding) {
213
- const key = findingKey(finding);
214
- const existing = merged.get(key);
215
- if (!existing) {
216
- merged.set(key, {
217
- ...finding,
218
- affected_files: [...finding.affected_files],
219
- evidence: [...(finding.evidence ?? [])],
220
- });
221
- return;
222
- }
223
- if (severityRank(finding.severity) > severityRank(existing.severity)) {
224
- existing.severity = finding.severity;
225
- }
226
- if (confidenceRank(finding.confidence) > confidenceRank(existing.confidence)) {
227
- existing.confidence = finding.confidence;
228
- }
229
- existing.systemic = Boolean(existing.systemic || finding.systemic);
230
- existing.grounding = mergeGrounding(existing.grounding, finding.grounding);
231
- existing.impact = existing.impact ?? finding.impact;
232
- existing.likelihood = existing.likelihood ?? finding.likelihood;
233
- existing.summary =
234
- existing.summary.length >= finding.summary.length
235
- ? existing.summary
236
- : finding.summary;
237
- mergeAffectedFiles(existing, finding);
238
- existing.evidence = [
239
- ...new Set([
240
- ...(existing.evidence ?? []),
241
- ...(finding.evidence ?? []),
242
- ]),
243
- ];
244
- }
245
29
  export function mergeFindings(results, runtimeReport, externalAnalyzerResults, designAssessment, structureDecomposition, charterRegister, systemicChallenge) {
246
30
  const merged = new Map();
247
31
  const allDesignFindings = [
@@ -259,12 +43,12 @@ export function mergeFindings(results, runtimeReport, externalAnalyzerResults, d
259
43
  ...(charterRegister?.findings ?? []),
260
44
  // Phase E second-order-adversary improvement leads (systemic layer). These carry
261
45
  // their TRUE lens (tests/performance/operability/…), NOT a hardcoded architecture
262
- // tag — upsertFinding keys on the finding's own lens, so a systemic improvement is
46
+ // tag — upsertFindingByIdentity keys on the finding's own lens, so a systemic improvement is
263
47
  // routed to its real lens rather than collapsed into an architecture bucket.
264
48
  ...(systemicChallenge?.findings ?? []),
265
49
  ];
266
50
  for (const finding of allDesignFindings) {
267
- upsertFinding(merged, finding);
51
+ upsertFindingByIdentity(merged, finding);
268
52
  }
269
53
  // Callers pass the supersession-resolved ledger (`selectCurrentResults`) so a
270
54
  // re-dispatched result's fresh findings have already replaced the stale base
@@ -272,7 +56,7 @@ export function mergeFindings(results, runtimeReport, externalAnalyzerResults, d
272
56
  // result set it is given.
273
57
  for (const result of results) {
274
58
  for (const finding of result.findings) {
275
- upsertFinding(merged, finding);
59
+ upsertFindingByIdentity(merged, finding);
276
60
  }
277
61
  }
278
62
  for (const finding of merged.values()) {
@@ -288,8 +72,19 @@ export function mergeFindings(results, runtimeReport, externalAnalyzerResults, d
288
72
  ];
289
73
  }
290
74
  }
291
- const dedupedSameLens = deduplicateSameLens([...merged.values()]);
292
- return deduplicateCrossLens(dedupedSameLens).sort((a, b) => {
75
+ const dedupedSameLens = sameLensDedupe([...merged.values()]);
76
+ // Audit's DRAW of the shared cross-lens core: read-only report policy — mutate
77
+ // survivors in place, grounding-precedence merge, sort files, and a SOFT category
78
+ // gate (merge cross-category at a higher title threshold). No exact-identity
79
+ // short-circuit / no break; the mergeMap is unused (a human reads the report).
80
+ return crossLensDedupe(dedupedSameLens, {
81
+ categoryGate: "soft",
82
+ exactIdentityShortCircuit: false,
83
+ survivorMutation: "mutate",
84
+ mergeGrounding: true,
85
+ sortAffectedFiles: true,
86
+ breakOnAbsorbedSurvivor: false,
87
+ }).findings.sort((a, b) => {
293
88
  const severityDelta = severityRank(b.severity) - severityRank(a.severity);
294
89
  if (severityDelta !== 0)
295
90
  return severityDelta;
@@ -1 +1 @@
1
- {"version":3,"file":"mergeFindings.js","sourceRoot":"","sources":["../../../src/audit/reporting/mergeFindings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mergeFindings.js","sourceRoot":"","sources":["../../../src/audit/reporting/mergeFindings.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"systemicChallengeLoop.d.ts","sourceRoot":"","sources":["../../../src/audit/systemic/systemicChallengeLoop.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA+BpD,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,gFAAgF;IAChF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iFAAiF;IACjF,GAAG,EAAE,OAAO,CAAC;IACb,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACnD,wEAAwE;IACxE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACvD,GAAG,mBAAmB,CA4CtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,QACO,CAAC"}
1
+ {"version":3,"file":"systemicChallengeLoop.d.ts","sourceRoot":"","sources":["../../../src/audit/systemic/systemicChallengeLoop.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAyBpD,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,gFAAgF;IAChF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iFAAiF;IACjF,GAAG,EAAE,OAAO,CAAC;IACb,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,YAAY,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACnD,wEAAwE;IACxE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;CACvD,GAAG,mBAAmB,CA4CtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,QACO,CAAC"}
@@ -20,14 +20,9 @@
20
20
  // route each improvement to its real lens.
21
21
  //
22
22
  // PURE + deterministic + language-neutral: no IO, no LLM.
23
- import { groundDesignFindings } from "audit-tools/shared";
23
+ import { groundDesignFindings, findingReEmissionKey } from "audit-tools/shared";
24
24
  import { goalBlastRadius } from "../clarification/blastRadius.js";
25
25
  import { DEFAULT_RISK_GATE_THRESHOLDS } from "../clarification/riskGate.js";
26
- /** File-independent finding identity (lens + category + title), lower-cased. */
27
- function findingKey(finding) {
28
- const norm = (v) => (v ?? "").trim().toLowerCase();
29
- return [norm(finding.lens), norm(finding.category), norm(finding.title)].join("|");
30
- }
31
26
  /**
32
27
  * Resolve the blast radius of an improvement finding over the goal DAG. A finding
33
28
  * carrying a `node_id`-style goal linkage (its first affected component maps to a
@@ -64,7 +59,7 @@ export function foldChallengeRound(params) {
64
59
  const grounded = groundDesignFindings(params.submitted, params.repoManifest);
65
60
  const byKey = new Map();
66
61
  for (const finding of params.prior)
67
- byKey.set(findingKey(finding), finding);
62
+ byKey.set(findingReEmissionKey(finding), finding);
68
63
  const new_finding_ids = [];
69
64
  for (const finding of grounded) {
70
65
  if (finding.grounding?.status === "ungrounded") {
@@ -78,7 +73,7 @@ export function foldChallengeRound(params) {
78
73
  lens: finding.lens,
79
74
  blast_radius: resolveBlastRadius(finding, params.goalGraph, goalNodeOf),
80
75
  };
81
- const key = findingKey(enriched);
76
+ const key = findingReEmissionKey(enriched);
82
77
  if (!byKey.has(key)) {
83
78
  new_finding_ids.push(enriched.id);
84
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"systemicChallengeLoop.js","sourceRoot":"","sources":["../../../src/audit/systemic/systemicChallengeLoop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"systemicChallengeLoop.js","sourceRoot":"","sources":["../../../src/audit/systemic/systemicChallengeLoop.ts"],"names":[],"mappings":"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"}
@@ -34,12 +34,6 @@ export declare const AuditStateSchema: z.ZodObject<{
34
34
  state: "blocked" | "missing" | "satisfied" | "present" | "stale";
35
35
  reason?: string | undefined;
36
36
  }>, "many">;
37
- /**
38
- * Set when the rolling dispatch engine fires a partial-completion terminal
39
- * (empty pool or livelock). Allows synthesis to proceed on partial coverage
40
- * without hard-gating on `audit_tasks_completed`.
41
- */
42
- partial_coverage_terminal: z.ZodOptional<z.ZodBoolean>;
43
37
  }, "strict", z.ZodTypeAny, {
44
38
  status: "blocked" | "complete" | "not_started" | "active";
45
39
  obligations: {
@@ -50,7 +44,6 @@ export declare const AuditStateSchema: z.ZodObject<{
50
44
  last_executor?: string | undefined;
51
45
  last_obligation?: string | undefined;
52
46
  blockers?: string[] | undefined;
53
- partial_coverage_terminal?: boolean | undefined;
54
47
  }, {
55
48
  status: "blocked" | "complete" | "not_started" | "active";
56
49
  obligations: {
@@ -61,7 +54,6 @@ export declare const AuditStateSchema: z.ZodObject<{
61
54
  last_executor?: string | undefined;
62
55
  last_obligation?: string | undefined;
63
56
  blockers?: string[] | undefined;
64
- partial_coverage_terminal?: boolean | undefined;
65
57
  }>;
66
58
  export type AuditState = z.infer<typeof AuditStateSchema>;
67
59
  //# sourceMappingURL=auditState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auditState.d.ts","sourceRoot":"","sources":["../../../src/audit/types/auditState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,yBAAyB,6DAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAM5E,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAAmB,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;IAOzB;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;EAGI,CAAC;AACZ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"auditState.d.ts","sourceRoot":"","sources":["../../../src/audit/types/auditState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,yBAAyB,6DAKpC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAM5E,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAAmB,CAAC;AACtD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQlB,CAAC;AACZ,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -14,12 +14,6 @@ export const AuditStateSchema = z
14
14
  last_obligation: z.string().optional(),
15
15
  blockers: z.array(z.string()).optional(),
16
16
  obligations: z.array(AuditObligationSchema),
17
- /**
18
- * Set when the rolling dispatch engine fires a partial-completion terminal
19
- * (empty pool or livelock). Allows synthesis to proceed on partial coverage
20
- * without hard-gating on `audit_tasks_completed`.
21
- */
22
- partial_coverage_terminal: z.boolean().optional(),
23
17
  })
24
18
  .strict();
25
19
  //# sourceMappingURL=auditState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auditState.js","sourceRoot":"","sources":["../../../src/audit/types/auditState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9C,aAAa;IACb,QAAQ;IACR,SAAS;IACT,UAAU;CACX,CAAC,CAAC;AAQH,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAGtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,MAAM,EAAE,yBAAyB;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC3C;;;;OAIG;IACH,yBAAyB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAClD,CAAC;KACD,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"auditState.js","sourceRoot":"","sources":["../../../src/audit/types/auditState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,IAAI,CAAC;IAC9C,aAAa;IACb,QAAQ;IACR,SAAS;IACT,UAAU;CACX,CAAC,CAAC;AAQH,MAAM,CAAC,MAAM,qBAAqB,GAAG,gBAAgB,CAAC;AAGtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACN,MAAM,EAAE,yBAAyB;IACjC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACxC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;CAC5C,CAAC;KACD,MAAM,EAAE,CAAC"}
@@ -1,10 +1,17 @@
1
1
  import { wordJaccard } from "audit-tools/shared";
2
+ import type { CrossLensDedupeResult } from "audit-tools/shared";
2
3
  import type { Finding, RemediationBlock } from "../state/types.js";
3
4
  export { wordJaccard };
4
- export interface CrossLensDedupResult {
5
- findings: Finding[];
6
- mergeMap: Map<string, string>;
7
- }
5
+ export type CrossLensDedupResult = CrossLensDedupeResult;
6
+ /**
7
+ * Remediate's DRAW of the shared cross-lens dedup core (`crossLensDedupe`): the
8
+ * auto-apply block-machine policy — a HARD category gate (never collapse two
9
+ * different-category fixes, OBL-C003-DEDUP), the exact-identity short-circuit
10
+ * (drift-plan R2), CLONE survivors so the caller's Finding objects are never
11
+ * mutated (INV-remediate-state-05), no grounding merge / no file sort, break on an
12
+ * absorbed i-slot, and a structured merge log. The returned `mergeMap` feeds
13
+ * `fixupBlocksAfterDedup`.
14
+ */
8
15
  export declare function deduplicateCrossLensFindings(findings: Finding[]): CrossLensDedupResult;
9
16
  export declare function fixupBlocksAfterDedup(blocks: RemediationBlock[], mergeMap: Map<string, string>): RemediationBlock[];
10
17
  //# sourceMappingURL=crossLensDedup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crossLensDedup.d.ts","sourceRoot":"","sources":["../../../src/remediate/dedup/crossLensDedup.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,WAAW,EAGZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAInE,OAAO,EAAE,WAAW,EAAE,CAAC;AAmBvB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,OAAO,EAAE,GAClB,oBAAoB,CA2ItB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,EAAE,EAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,gBAAgB,EAAE,CAMpB"}
1
+ {"version":3,"file":"crossLensDedup.d.ts","sourceRoot":"","sources":["../../../src/remediate/dedup/crossLensDedup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAInE,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,OAAO,EAAE,GAClB,oBAAoB,CAsBtB;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,gBAAgB,EAAE,EAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,gBAAgB,EAAE,CAMpB"}
@@ -1,155 +1,36 @@
1
- import { severityRank, confidenceRank, findingIdentityKey, wordJaccard, filePathOverlap, primaryPath, } from "audit-tools/shared";
1
+ import { crossLensDedupe, wordJaccard } from "audit-tools/shared";
2
2
  // Re-exported: tests/remediate/cross-lens-dedup.test.ts imports wordJaccard
3
3
  // directly from this module.
4
4
  export { wordJaccard };
5
5
  /**
6
- * The shared finding-identity signature of a finding, but only when it is
7
- * *discriminating* enough to stand on its own as an exact-match key for
8
- * cross-lens dedup. A structural-anchor signature with an empty scope
9
- * (`anchor|<path>|`) means nothing more than "same file" — too coarse to
10
- * collapse two findings by itself, so the fuzzy title/overlap layer must refine
11
- * it. We return `null` in that case so it never short-circuits the heuristic.
12
- * Anchored-with-scope and normalized-title signatures are discriminating and are
13
- * returned verbatim; the rule/category tier embeds the lens, so two cross-lens
14
- * findings never share it (they fall through to the fuzzy layer by design).
6
+ * Remediate's DRAW of the shared cross-lens dedup core (`crossLensDedupe`): the
7
+ * auto-apply block-machine policy — a HARD category gate (never collapse two
8
+ * different-category fixes, OBL-C003-DEDUP), the exact-identity short-circuit
9
+ * (drift-plan R2), CLONE survivors so the caller's Finding objects are never
10
+ * mutated (INV-remediate-state-05), no grounding merge / no file sort, break on an
11
+ * absorbed i-slot, and a structured merge log. The returned `mergeMap` feeds
12
+ * `fixupBlocksAfterDedup`.
15
13
  */
16
- function discriminatingIdentityKey(finding) {
17
- const key = findingIdentityKey(finding);
18
- if (key.startsWith("anchor|") && key.endsWith("|"))
19
- return null;
20
- return key;
21
- }
22
14
  export function deduplicateCrossLensFindings(findings) {
23
- const groups = new Map();
24
- for (const finding of findings) {
25
- const key = primaryPath(finding);
26
- const group = groups.get(key);
27
- if (group) {
28
- group.push(finding);
29
- }
30
- else {
31
- groups.set(key, [finding]);
32
- }
33
- }
34
- const removed = new Set();
35
- const mergeMap = new Map();
36
- /**
37
- * Maps each source finding that participates as a survivor to its cloned
38
- * merged copy. INV-remediate-state-05: survivors are cloned so the caller's
39
- * original Finding objects are never mutated in place.
40
- */
41
- const cloneOf = new Map();
42
- for (const group of groups.values()) {
43
- if (group.length < 2)
44
- continue;
45
- for (let i = 0; i < group.length; i++) {
46
- if (removed.has(group[i]))
47
- continue;
48
- for (let j = i + 1; j < group.length; j++) {
49
- if (removed.has(group[j]))
50
- continue;
51
- const a = group[i];
52
- const b = group[j];
53
- if (a.lens.toLowerCase() === b.lens.toLowerCase())
54
- continue;
55
- // Category is a hard merge-key discriminator, applied ahead of BOTH the
56
- // exact-match and fuzzy layers: two findings that share a file/lens-pair
57
- // but were classified under different categories describe structurally
58
- // different problems and must NEVER be collapsed — e.g. ARC-86b18f1b
59
- // (inferred_contract_gap) vs ARC-86b18f1b-2 (invariant_counterexample)
60
- // stay distinct (OBL-C003-DEDUP / OBL-INV-RPS-07). Category is
61
- // orthogonal to the structural-anchor identity signature (which ignores
62
- // it), so it remains an independent hard gate. A true duplicate keeps the
63
- // same category and still collapses below.
64
- if (a.category.toLowerCase() !== b.category.toLowerCase())
65
- continue;
66
- // Exact-match layer (drift-plan R2): within a matching category, the
67
- // shared finding-identity signature is the one authority for "is this the
68
- // same finding?". When two cross-lens findings share a DISCRIMINATING
69
- // signature they ARE the same defect — collapse even if their titles
70
- // diverged enough to slip under the Jaccard floor (the signature is
71
- // lens-independent at the structural-anchor-with-scope and
72
- // normalized-title tiers). Otherwise fall back to the fuzzy heuristic: a
73
- // moderate title overlap plus a real file overlap.
74
- const keyA = discriminatingIdentityKey(a);
75
- const keyB = discriminatingIdentityKey(b);
76
- const exactIdentityMatch = keyA !== null && keyA === keyB;
77
- if (!exactIdentityMatch) {
78
- const titleSim = wordJaccard(a.title, b.title);
79
- if (titleSim < 0.4)
80
- continue;
81
- if (filePathOverlap(a, b) < 0.5)
82
- continue;
83
- }
84
- const aSev = severityRank(a.severity);
85
- const bSev = severityRank(b.severity);
86
- const aConf = confidenceRank(a.confidence);
87
- const bConf = confidenceRank(b.confidence);
88
- const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
89
- // originalSurvivor is one of the source Finding objects (a or b).
90
- // absorbed is the other source Finding.
91
- const originalSurvivor = keepA ? a : b;
92
- const absorbed = keepA ? b : a;
93
- // Re-use the existing clone if this survivor has already been cloned by
94
- // a prior pair in this group; otherwise create a new clone.
95
- let survivor = cloneOf.get(originalSurvivor);
96
- if (!survivor) {
97
- survivor = {
98
- ...originalSurvivor,
99
- affected_files: [...originalSurvivor.affected_files],
100
- evidence: originalSurvivor.evidence ? [...originalSurvivor.evidence] : [],
101
- };
102
- cloneOf.set(originalSurvivor, survivor);
103
- // Update the group slot so future pair iterations in the same group
104
- // refer to the clone rather than the unmodified source object.
105
- const survivorGroupIdx = keepA ? i : j;
106
- group[survivorGroupIdx] = survivor;
107
- }
108
- const existingPaths = new Set(survivor.affected_files.map((f) => `${f.path}:${f.line_start ?? ""}:${f.line_end ?? ""}:${f.symbol ?? ""}`));
109
- for (const file of absorbed.affected_files) {
110
- const fKey = `${file.path}:${file.line_start ?? ""}:${file.line_end ?? ""}:${file.symbol ?? ""}`;
111
- if (!existingPaths.has(fKey)) {
112
- survivor.affected_files.push(file);
113
- existingPaths.add(fKey);
114
- }
115
- }
116
- survivor.evidence = [
117
- ...new Set([
118
- ...(survivor.evidence ?? []),
119
- ...(absorbed.evidence ?? []),
120
- ]),
121
- ];
122
- survivor.systemic = Boolean(survivor.systemic || absorbed.systemic);
123
- if (absorbed.summary.length > survivor.summary.length) {
124
- survivor.summary = absorbed.summary;
125
- }
126
- removed.add(absorbed);
127
- mergeMap.set(absorbed.id, survivor.id);
128
- process.stderr.write(JSON.stringify({
129
- level: "info",
130
- event: "cross_lens_dedup_merge",
131
- absorbed_id: absorbed.id,
132
- absorbed_lens: absorbed.lens,
133
- survivor_id: survivor.id,
134
- survivor_lens: survivor.lens,
135
- ts: new Date().toISOString(),
136
- }) + "\n");
137
- // If the `i`-slot finding was just absorbed (!keepA), stop the inner
138
- // loop — there is no point comparing an absorbed finding with more
139
- // candidates. The outer loop's guard (removed.has(group[i])) handles
140
- // advancing `i` past it on the next outer iteration.
141
- if (!keepA)
142
- break;
143
- }
144
- }
145
- }
146
- // Return clones for survivors, original objects for untouched findings.
147
- return {
148
- findings: findings
149
- .filter((f) => !removed.has(f))
150
- .map((f) => cloneOf.get(f) ?? f),
151
- mergeMap,
152
- };
15
+ return crossLensDedupe(findings, {
16
+ categoryGate: "hard",
17
+ exactIdentityShortCircuit: true,
18
+ survivorMutation: "clone",
19
+ mergeGrounding: false,
20
+ sortAffectedFiles: false,
21
+ breakOnAbsorbedSurvivor: true,
22
+ onMerge: ({ absorbed, survivor }) => {
23
+ process.stderr.write(JSON.stringify({
24
+ level: "info",
25
+ event: "cross_lens_dedup_merge",
26
+ absorbed_id: absorbed.id,
27
+ absorbed_lens: absorbed.lens,
28
+ survivor_id: survivor.id,
29
+ survivor_lens: survivor.lens,
30
+ ts: new Date().toISOString(),
31
+ }) + "\n");
32
+ },
33
+ });
153
34
  }
154
35
  export function fixupBlocksAfterDedup(blocks, mergeMap) {
155
36
  if (mergeMap.size === 0)