audit-tools 0.49.0 → 0.50.2

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 (108) hide show
  1. package/README.md +3 -1
  2. package/dist/audit/cli/args.d.ts +27 -0
  3. package/dist/audit/cli/args.d.ts.map +1 -1
  4. package/dist/audit/cli/args.js +32 -2
  5. package/dist/audit/cli/args.js.map +1 -1
  6. package/dist/audit/cli/dispatch/hostHandoff.d.ts +1 -1
  7. package/dist/audit/cli/dispatch/hostHandoff.d.ts.map +1 -1
  8. package/dist/audit/cli/dispatch/hostHandoff.js +32 -55
  9. package/dist/audit/cli/dispatch/hostHandoff.js.map +1 -1
  10. package/dist/audit/cli/nextStepHelpers.d.ts.map +1 -1
  11. package/dist/audit/cli/nextStepHelpers.js +8 -8
  12. package/dist/audit/cli/nextStepHelpers.js.map +1 -1
  13. package/dist/audit/io/artifacts.d.ts +0 -28
  14. package/dist/audit/io/artifacts.d.ts.map +1 -1
  15. package/dist/audit/io/artifacts.js +1 -65
  16. package/dist/audit/io/artifacts.js.map +1 -1
  17. package/dist/audit/orchestrator/advance.d.ts.map +1 -1
  18. package/dist/audit/orchestrator/advance.js +12 -10
  19. package/dist/audit/orchestrator/advance.js.map +1 -1
  20. package/dist/audit/orchestrator/designReviewSnapshot.d.ts.map +1 -1
  21. package/dist/audit/orchestrator/designReviewSnapshot.js +2 -5
  22. package/dist/audit/orchestrator/designReviewSnapshot.js.map +1 -1
  23. package/dist/audit/reporting/mergeFindings.d.ts.map +1 -1
  24. package/dist/audit/reporting/mergeFindings.js +1 -2
  25. package/dist/audit/reporting/mergeFindings.js.map +1 -1
  26. package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts +25 -10
  27. package/dist/remediate/contractPipeline/cyclicSeamResolution.d.ts.map +1 -1
  28. package/dist/remediate/contractPipeline/cyclicSeamResolution.js +35 -88
  29. package/dist/remediate/contractPipeline/cyclicSeamResolution.js.map +1 -1
  30. package/dist/remediate/contractPipeline/idRegistry.d.ts +10 -20
  31. package/dist/remediate/contractPipeline/idRegistry.d.ts.map +1 -1
  32. package/dist/remediate/contractPipeline/idRegistry.js +10 -24
  33. package/dist/remediate/contractPipeline/idRegistry.js.map +1 -1
  34. package/dist/remediate/contractPipeline/obligationKinds.d.ts +27 -0
  35. package/dist/remediate/contractPipeline/obligationKinds.d.ts.map +1 -0
  36. package/dist/remediate/contractPipeline/obligationKinds.js +18 -0
  37. package/dist/remediate/contractPipeline/obligationKinds.js.map +1 -0
  38. package/dist/remediate/dedup/crossLensDedup.d.ts +2 -3
  39. package/dist/remediate/dedup/crossLensDedup.d.ts.map +1 -1
  40. package/dist/remediate/dedup/crossLensDedup.js +2 -4
  41. package/dist/remediate/dedup/crossLensDedup.js.map +1 -1
  42. package/dist/remediate/index.d.ts +38 -8
  43. package/dist/remediate/index.d.ts.map +1 -1
  44. package/dist/remediate/index.js +75 -27
  45. package/dist/remediate/index.js.map +1 -1
  46. package/dist/remediate/steps/contractPipeline.d.ts +6 -62
  47. package/dist/remediate/steps/contractPipeline.d.ts.map +1 -1
  48. package/dist/remediate/steps/contractPipeline.js +11 -80
  49. package/dist/remediate/steps/contractPipeline.js.map +1 -1
  50. package/dist/remediate/steps/dispatch/hostHandoff.d.ts.map +1 -1
  51. package/dist/remediate/steps/dispatch/hostHandoff.js +57 -48
  52. package/dist/remediate/steps/dispatch/hostHandoff.js.map +1 -1
  53. package/dist/remediate/steps/nextStep.d.ts +83 -2
  54. package/dist/remediate/steps/nextStep.d.ts.map +1 -1
  55. package/dist/remediate/steps/nextStep.js +79 -11
  56. package/dist/remediate/steps/nextStep.js.map +1 -1
  57. package/dist/remediate/steps/types.d.ts +1 -1
  58. package/dist/remediate/steps/types.d.ts.map +1 -1
  59. package/dist/remediate/steps/types.js.map +1 -1
  60. package/dist/remediate/utils/fileIntegrity.d.ts.map +1 -1
  61. package/dist/remediate/utils/fileIntegrity.js +123 -30
  62. package/dist/remediate/utils/fileIntegrity.js.map +1 -1
  63. package/dist/remediate/validation/artifacts.d.ts.map +1 -1
  64. package/dist/remediate/validation/artifacts.js +3 -9
  65. package/dist/remediate/validation/artifacts.js.map +1 -1
  66. package/dist/remediate/validation/contractPipeline.d.ts +1 -1
  67. package/dist/remediate/validation/contractPipeline.d.ts.map +1 -1
  68. package/dist/remediate/validation/contractPipeline.js +8 -46
  69. package/dist/remediate/validation/contractPipeline.js.map +1 -1
  70. package/dist/remediate/validation/contractPipelineGates.d.ts +12 -20
  71. package/dist/remediate/validation/contractPipelineGates.d.ts.map +1 -1
  72. package/dist/remediate/validation/contractPipelineGates.js +107 -135
  73. package/dist/remediate/validation/contractPipelineGates.js.map +1 -1
  74. package/dist/shared/engine/obligationEngine.d.ts +32 -0
  75. package/dist/shared/engine/obligationEngine.d.ts.map +1 -1
  76. package/dist/shared/engine/obligationEngine.js +29 -0
  77. package/dist/shared/engine/obligationEngine.js.map +1 -1
  78. package/dist/shared/findings/dedupe.d.ts +4 -11
  79. package/dist/shared/findings/dedupe.d.ts.map +1 -1
  80. package/dist/shared/findings/dedupe.js +196 -163
  81. package/dist/shared/findings/dedupe.js.map +1 -1
  82. package/dist/shared/graph/directedCycles.d.ts +61 -0
  83. package/dist/shared/graph/directedCycles.d.ts.map +1 -0
  84. package/dist/shared/graph/directedCycles.js +190 -0
  85. package/dist/shared/graph/directedCycles.js.map +1 -0
  86. package/dist/shared/index.d.ts +6 -3
  87. package/dist/shared/index.d.ts.map +1 -1
  88. package/dist/shared/index.js +4 -2
  89. package/dist/shared/index.js.map +1 -1
  90. package/dist/shared/io/repoRoot.d.ts +45 -0
  91. package/dist/shared/io/repoRoot.d.ts.map +1 -1
  92. package/dist/shared/io/repoRoot.js +91 -1
  93. package/dist/shared/io/repoRoot.js.map +1 -1
  94. package/dist/shared/submission/submissionScan.d.ts +86 -0
  95. package/dist/shared/submission/submissionScan.d.ts.map +1 -0
  96. package/dist/shared/submission/submissionScan.js +93 -0
  97. package/dist/shared/submission/submissionScan.js.map +1 -0
  98. package/dist/shared/types/obligationLedger.d.ts +7 -3
  99. package/dist/shared/types/obligationLedger.d.ts.map +1 -1
  100. package/dist/shared/types/obligationLedger.js +9 -37
  101. package/dist/shared/types/obligationLedger.js.map +1 -1
  102. package/package.json +3 -2
  103. package/skills/audit-code/audit-code.prompt.md +5 -2
  104. package/wrapper/audit-code-wrapper-install-hosts.mjs +8 -3
  105. package/wrapper/audit-code-wrapper-lib.mjs +10 -3
  106. package/wrapper/installer-verb-help.mjs +3 -1
  107. package/wrapper/remediate-code-wrapper-install-hosts.mjs +8 -3
  108. package/wrapper/repo-root.mjs +80 -0
@@ -24,16 +24,19 @@ import { compareCodeUnits } from "../compareCodeUnits.js";
24
24
  * violated, recorded here so a caller-side check has something to test
25
25
  * against. This is NOT a promise that this module will start enforcing it:
26
26
  * - A missing/unrecognized `policy.categoryGate` (neither `"soft"` nor
27
- * `"hard"`) silently falls through in the PERMISSIVE direction: the
28
- * hard-gate check in `crossLensDedupe` only special-cases the literal
29
- * string `"hard"`, so anything else (including `undefined`) never blocks
30
- * a cross-category pair it falls through to the exact/fuzzy match layers
31
- * as if the gate were absent.
27
+ * `"hard"`) silently falls through in the PERMISSIVE direction, in BOTH
28
+ * places `crossLensDedupe` consults it. The hard-gate refusal lives in the
29
+ * shared `compareFindingPair` and only special-cases the literal string
30
+ * `"hard"`, so anything else (including `undefined`) never blocks a
31
+ * cross-category pair; and the `PairMatchPolicy.titleThreshold`
32
+ * `crossLensDedupe` derives only special-cases `"soft"`, so an unrecognized
33
+ * value takes the LOWER cross-category title floor (0.4, the same-category
34
+ * one) instead of soft's 0.5.
32
35
  * - A `Finding` missing `affected_files` throws an uncaught TypeError inside
33
36
  * `mergeAffectedFiles` (`survivor.affected_files.map(...)` called on
34
37
  * `undefined`) the first time that finding is absorbed or absorbs another.
35
38
  * - Two input findings sharing the same `id` (precondition 2 violated) yield
36
- * an UNSPECIFIED merge-chain target once `crossLensDedupe`'s post-loop
39
+ * an UNSPECIFIED merge-chain target once `crossLensDedupe`'s post-fold
37
40
  * chain-collapse runs: the `visited`-guard there stops the walk instead of
38
41
  * spinning forever on the resulting id cycle, but which of the colliding
39
42
  * ids the chain resolves to is not a contract this module makes.
@@ -46,16 +49,29 @@ import { compareCodeUnits } from "../compareCodeUnits.js";
46
49
  * whoever implements the caller-side check, not settled by this module.
47
50
  */
48
51
  /**
49
- * ONE shared finding-dedup core. There is no auditor-dedup vs remediator-dedup
50
- * there is one skeleton (group-by-primary-path pairwise cross-lens compare
51
- * similarity gate → survivor selection → absorb), and each orchestrator DRAWS it
52
- * with its own POLICY. Audit draws it read-only for the report (mutate survivors
53
- * in place, grounding-precedence merge, cross-category merge allowed at a higher
54
- * threshold); remediate draws it for the auto-apply block machine (clone survivors,
55
- * hard category gate, exact-identity short-circuit, a mergeMap its blocks consume).
56
- * Single-sourcing the skeleton is what stops the two from silently drifting on the
57
- * grouping / thresholds / survivor rule; the divergences are the explicit named
58
- * policy knobs below, not forked code.
52
+ * ONE shared finding-dedup core. There is no auditor-dedup vs remediator-dedup,
53
+ * and no cross-lens-fold vs same-lens-fold there is one skeleton
54
+ * (group → pairwise compare → similarity gate → survivor selection → absorb
55
+ * remove), and every pass DRAWS it with its own POLICY. Two seams carry the whole
56
+ * divergence:
57
+ *
58
+ * - `collapseFindingGroups` the survivor FOLD (grouping, the pair scan, the
59
+ * mid-scan absorbed-survivor conservation guard, absorption, removal, and the
60
+ * mutate-vs-clone survivor axis). Drawn by `crossLensDedupe` AND
61
+ * `sameLensDedupe`.
62
+ * - `compareFindingPair` — the one pair decision, parameterized by
63
+ * `PairMatchPolicy` (lens eligibility, category gate, title floors, what
64
+ * counts as the same place).
65
+ *
66
+ * Audit draws the core read-only for the report (mutate survivors in place,
67
+ * grounding-precedence merge, cross-category merge allowed at a higher threshold);
68
+ * remediate draws it for the auto-apply block machine (clone survivors, hard
69
+ * category gate, exact-identity short-circuit, a mergeMap its blocks consume).
70
+ * Single-sourcing the skeleton is what stops them drifting on the grouping /
71
+ * thresholds / survivor rule; the divergences are the named policy fields, not
72
+ * forked code. What stays per-draw is only what is genuinely terminal: cross-lens
73
+ * merge-chain closure, dispositions, and the evidence-conservation check, all
74
+ * post-fold phases in `crossLensDedupe`.
59
75
  */
60
76
  /**
61
77
  * Consistent lens/category text normalization for BOTH draws (trim + lowercase).
@@ -132,50 +148,104 @@ function discriminatingIdentityKey(finding) {
132
148
  return key;
133
149
  }
134
150
  /**
135
- * Collapse cross-lens duplicate findings within each primary-path group. Only pairs
136
- * of DIFFERENT lenses are considered (same-lens dedup is a separate pass); the
137
- * winner by severity-then-confidence absorbs the loser's files/evidence. All policy
138
- * divergence between the two orchestrators is expressed through `policy`.
151
+ * Do two findings describe the same place? `lineRangeOverlaps` is the finer of
152
+ * the two "same place" signals: the same file AND touching line ranges, with an
153
+ * explicit sentinel two findings that both omit line information (both ends
154
+ * degenerate to 0) are treated as overlapping rather than as disjoint.
139
155
  */
140
- export function crossLensDedupe(findings, policy) {
141
- const evidenceByInputId = new Map();
142
- if (policy.idDiscipline === "global") {
143
- for (const finding of findings) {
144
- if (finding.id.trim().length === 0) {
145
- throw new TypeError("Finding ids must be non-empty before deduplication.");
146
- }
147
- if (evidenceByInputId.has(finding.id)) {
148
- throw new TypeError(`Duplicate finding id "${finding.id}" makes terminal dedupe disposition ambiguous.`);
149
- }
150
- evidenceByInputId.set(finding.id, [...(finding.evidence ?? [])]);
156
+ function lineRangeOverlaps(a, b) {
157
+ const aFile = a.affected_files[0];
158
+ const bFile = b.affected_files[0];
159
+ if (!aFile || !bFile)
160
+ return false;
161
+ if (aFile.path !== bFile.path)
162
+ return false;
163
+ const aStart = aFile.line_start ?? 0;
164
+ const aEnd = aFile.line_end ?? aStart;
165
+ const bStart = bFile.line_start ?? 0;
166
+ const bEnd = bFile.line_end ?? bStart;
167
+ if (aEnd === 0 && bEnd === 0)
168
+ return true;
169
+ return aStart <= bEnd && bStart <= aEnd;
170
+ }
171
+ /**
172
+ * The ONE pairwise comparison: do these two findings merge, and which side
173
+ * survives? Both `crossLensDedupe` and `sameLensDedupe` route their pair decision
174
+ * through here, each with its own `PairMatchPolicy`.
175
+ *
176
+ * Survivor selection is severity-then-confidence with `aConf >= bConf`, so a
177
+ * fully-tied pair keeps the FIRST-SEEN finding — input order is the tiebreak, and
178
+ * that is a pinned property, not an accident.
179
+ */
180
+ function compareFindingPair(a, b, policy) {
181
+ if (policy.lensGate === "different" && normalizeText(a.lens) === normalizeText(b.lens)) {
182
+ return { matched: false, keepA: false };
183
+ }
184
+ const catMatch = normalizeText(a.category) === normalizeText(b.category);
185
+ // Hard category gate applies ahead of both exact-match and fuzzy layers
186
+ if (policy.categoryGate === "hard" && !catMatch) {
187
+ return { matched: false, keepA: false };
188
+ }
189
+ let matched = false;
190
+ if (policy.exactIdentityShortCircuit) {
191
+ const keyA = discriminatingIdentityKey(a);
192
+ const keyB = discriminatingIdentityKey(b);
193
+ matched = keyA !== null && keyA === keyB;
194
+ }
195
+ if (!matched) {
196
+ const titleSim = wordJaccard(a.title, b.title);
197
+ const threshold = catMatch
198
+ ? policy.titleThreshold.sameCategory
199
+ : policy.titleThreshold.crossCategory;
200
+ if (titleSim < threshold) {
201
+ return { matched: false, keepA: false };
202
+ }
203
+ const sameProblemSite = (policy.overlapGate === "line-or-file" && lineRangeOverlaps(a, b)) ||
204
+ filePathOverlap(a, b) >= 0.5;
205
+ if (!sameProblemSite) {
206
+ return { matched: false, keepA: false };
151
207
  }
208
+ matched = true;
152
209
  }
210
+ // Rank by severity then confidence
211
+ const aSev = severityRank(a.severity);
212
+ const bSev = severityRank(b.severity);
213
+ const aConf = confidenceRank(a.confidence);
214
+ const bConf = confidenceRank(b.confidence);
215
+ const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
216
+ return { matched, keepA };
217
+ }
218
+ /**
219
+ * The ONE finding-survivor fold. There is no auditor-fold and remediator-fold:
220
+ * group → pairwise scan → similarity gate → survivor selection → absorb → remove
221
+ * is one skeleton, and both dedup passes DRAW it with their own policy.
222
+ *
223
+ * Removal and clone bookkeeping are BOTH keyed by the caller's ORIGINAL Finding
224
+ * objects (group slots are never rewritten): `removed` holds absorbed originals,
225
+ * and `cloneOf` maps each original survivor to its single canonical clone (clone
226
+ * mode only). Keying by originals is what guarantees conservation — a caller's
227
+ * final filter over its input array sees exactly the objects this fold marked, so
228
+ * a finding is emitted exactly once XOR recorded as absorbed, never both, never
229
+ * neither.
230
+ *
231
+ * ⚠ The clone/canonical accumulation is MID-FOLD state, not a post-fold phase:
232
+ * `matchPair` and `absorbFinding` both read the CANONICAL views, so a later pair
233
+ * compares (and absorbs) everything an earlier merge already accumulated. Lifting
234
+ * it out of the fold changes merge outcomes.
235
+ */
236
+ function collapseFindingGroups(findings, policy) {
153
237
  const groups = new Map();
154
238
  for (const finding of findings) {
155
- const key = primaryPath(finding);
239
+ const key = policy.groupKey(finding);
156
240
  const group = groups.get(key);
157
241
  if (group)
158
242
  group.push(finding);
159
243
  else
160
244
  groups.set(key, [finding]);
161
245
  }
162
- /**
163
- * Removal and clone bookkeeping are BOTH keyed by the caller's ORIGINAL Finding
164
- * objects (group slots are never rewritten): `removed` holds absorbed originals,
165
- * and `cloneOf` maps each original survivor to its single canonical clone (clone
166
- * mode only). Keying by originals is what guarantees conservation — the final
167
- * filter over `findings` sees exactly the objects the loop marked, so a finding
168
- * is emitted exactly once XOR recorded in `mergeMap`, never both, never neither.
169
- */
170
246
  const removed = new Set();
171
- const mergeMap = new Map();
172
247
  const cloneOf = new Map();
173
- /** The accumulated view of a finding: its canonical clone when one exists. */
174
248
  const canonical = (f) => cloneOf.get(f) ?? f;
175
- const absorbOpts = {
176
- mergeGrounding: policy.mergeGrounding,
177
- sortAffectedFiles: policy.sortAffectedFiles,
178
- };
179
249
  for (const group of groups.values()) {
180
250
  if (group.length < 2)
181
251
  continue;
@@ -184,8 +254,11 @@ export function crossLensDedupe(findings, policy) {
184
254
  continue;
185
255
  for (let j = i + 1; j < group.length; j++) {
186
256
  // The i-slot finding may have been absorbed mid-scan (!keepA below): an
187
- // absorbed finding never acts as a survivor, so every remaining (i, j)
188
- // pair is dead stop unconditionally (not policy-gated; conservation).
257
+ // absorbed finding never acts as a survivor again it would re-absorb
258
+ // data already unioned into ITS absorber, and the emission filter then
259
+ // silently drops everything it won. Every remaining (i, j) pair is dead,
260
+ // so stop unconditionally (conservation, never a policy knob). Checked
261
+ // BEFORE the j-slot skip.
189
262
  if (removed.has(group[i]))
190
263
  break;
191
264
  if (removed.has(group[j]))
@@ -196,13 +269,7 @@ export function crossLensDedupe(findings, policy) {
196
269
  // lives on the survivor's single clone, never on the caller's object.
197
270
  const a = canonical(originalA);
198
271
  const b = canonical(originalB);
199
- // crossLensDedupe only pairs findings of DIFFERENT lenses
200
- if (normalizeText(a.lens) === normalizeText(b.lens))
201
- continue;
202
- const comparison = compareFindingPair(a, b, {
203
- categoryGate: policy.categoryGate,
204
- exactIdentityShortCircuit: policy.exactIdentityShortCircuit,
205
- });
272
+ const comparison = policy.matchPair(a, b);
206
273
  if (!comparison.matched)
207
274
  continue;
208
275
  const keepA = comparison.keepA;
@@ -232,16 +299,59 @@ export function crossLensDedupe(findings, policy) {
232
299
  else {
233
300
  survivor = survivorOriginal;
234
301
  }
235
- absorbFinding(survivor, absorbed, absorbOpts);
302
+ absorbFinding(survivor, absorbed, policy.absorb);
236
303
  removed.add(absorbedOriginal);
237
- mergeMap.set(absorbedOriginal.id, survivor.id);
238
- policy.onMerge?.({ absorbed, survivor });
239
- // If the i-slot finding was just absorbed (!keepA), stop the inner loop.
240
- if (policy.breakOnAbsorbedSurvivor && !keepA)
241
- break;
304
+ policy.onAbsorb?.({ absorbedOriginal, absorbed, survivor });
242
305
  }
243
306
  }
244
307
  }
308
+ return { removed, canonical };
309
+ }
310
+ /**
311
+ * Collapse cross-lens duplicate findings within each primary-path group. Only pairs
312
+ * of DIFFERENT lenses are considered (same-lens dedup is a separate pass); the
313
+ * winner by severity-then-confidence absorbs the loser's files/evidence. All policy
314
+ * divergence between the two orchestrators is expressed through `policy`.
315
+ */
316
+ export function crossLensDedupe(findings, policy) {
317
+ const evidenceByInputId = new Map();
318
+ if (policy.idDiscipline === "global") {
319
+ for (const finding of findings) {
320
+ if (finding.id.trim().length === 0) {
321
+ throw new TypeError("Finding ids must be non-empty before deduplication.");
322
+ }
323
+ if (evidenceByInputId.has(finding.id)) {
324
+ throw new TypeError(`Duplicate finding id "${finding.id}" makes terminal dedupe disposition ambiguous.`);
325
+ }
326
+ evidenceByInputId.set(finding.id, [...(finding.evidence ?? [])]);
327
+ }
328
+ }
329
+ const matchPolicy = {
330
+ lensGate: "different",
331
+ categoryGate: policy.categoryGate,
332
+ exactIdentityShortCircuit: policy.exactIdentityShortCircuit,
333
+ // The soft gate keeps cross-category merges but raises their title floor.
334
+ // Under the hard gate a cross-category pair is refused before any floor is
335
+ // consulted, so both entries are the same number there.
336
+ titleThreshold: policy.categoryGate === "soft"
337
+ ? { sameCategory: 0.4, crossCategory: 0.5 }
338
+ : { sameCategory: 0.4, crossCategory: 0.4 },
339
+ overlapGate: "file",
340
+ };
341
+ const mergeMap = new Map();
342
+ const { removed, canonical } = collapseFindingGroups(findings, {
343
+ groupKey: primaryPath,
344
+ matchPair: (a, b) => compareFindingPair(a, b, matchPolicy),
345
+ survivorMutation: policy.survivorMutation,
346
+ absorb: {
347
+ mergeGrounding: policy.mergeGrounding,
348
+ sortAffectedFiles: policy.sortAffectedFiles,
349
+ },
350
+ onAbsorb: ({ absorbedOriginal, absorbed, survivor }) => {
351
+ mergeMap.set(absorbedOriginal.id, survivor.id);
352
+ policy.onMerge?.({ absorbed, survivor });
353
+ },
354
+ });
245
355
  // Preserve the direct edges before terminal collapse so the disposition map can
246
356
  // explain B→A→C rather than reducing all provenance to B→C.
247
357
  const directMergeMap = new Map(mergeMap);
@@ -320,42 +430,6 @@ export function crossLensDedupe(findings, policy) {
320
430
  dispositionById,
321
431
  };
322
432
  }
323
- /**
324
- * Perform pairwise comparison of two findings using similarity metrics.
325
- * Returns whether they match and which should be the survivor.
326
- * This logic is shared by both crossLensDedupe and sameLensDedupe.
327
- */
328
- function compareFindingPair(a, b, options) {
329
- const catMatch = normalizeText(a.category) === normalizeText(b.category);
330
- // Hard category gate applies ahead of both exact-match and fuzzy layers
331
- if (options.categoryGate === "hard" && !catMatch) {
332
- return { matched: false, keepA: false };
333
- }
334
- let matched = false;
335
- if (options.exactIdentityShortCircuit) {
336
- const keyA = discriminatingIdentityKey(a);
337
- const keyB = discriminatingIdentityKey(b);
338
- matched = keyA !== null && keyA === keyB;
339
- }
340
- if (!matched) {
341
- const titleSim = wordJaccard(a.title, b.title);
342
- const threshold = options.categoryGate === "soft" ? (catMatch ? 0.4 : 0.5) : 0.4;
343
- if (titleSim < threshold) {
344
- return { matched: false, keepA: false };
345
- }
346
- if (filePathOverlap(a, b) < 0.5) {
347
- return { matched: false, keepA: false };
348
- }
349
- matched = true;
350
- }
351
- // Rank by severity then confidence
352
- const aSev = severityRank(a.severity);
353
- const bSev = severityRank(b.severity);
354
- const aConf = confidenceRank(a.confidence);
355
- const bConf = confidenceRank(b.confidence);
356
- const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
357
- return { matched, keepA };
358
- }
359
433
  /**
360
434
  * File-independent finding identity for exact re-emission collapse: the same logical
361
435
  * finding (normalized lens + category + title) re-emitted across files / units /
@@ -372,78 +446,37 @@ export function findingReEmissionKey(finding) {
372
446
  normalizeText(finding.title),
373
447
  ].join("|");
374
448
  }
375
- function lineRangeOverlaps(a, b) {
376
- const aFile = a.affected_files[0];
377
- const bFile = b.affected_files[0];
378
- if (!aFile || !bFile)
379
- return false;
380
- if (aFile.path !== bFile.path)
381
- return false;
382
- const aStart = aFile.line_start ?? 0;
383
- const aEnd = aFile.line_end ?? aStart;
384
- const bStart = bFile.line_start ?? 0;
385
- const bEnd = bFile.line_end ?? bStart;
386
- if (aEnd === 0 && bEnd === 0)
387
- return true;
388
- return aStart <= bEnd && bStart <= aEnd;
389
- }
449
+ /**
450
+ * The same-lens draw's matching policy. The group key already fixes the lens, so
451
+ * there is no lens condition; the title floors sit BELOW the cross-lens ones
452
+ * (two findings one lens raised about one place are more often one defect), and
453
+ * "the same place" is additionally satisfied by an overlapping line range.
454
+ */
455
+ const SAME_LENS_MATCH_POLICY = {
456
+ lensGate: "any",
457
+ // `soft`, not "no category gate": a category difference is not fatal here, it
458
+ // only raises the title floor.
459
+ categoryGate: "soft",
460
+ exactIdentityShortCircuit: false,
461
+ titleThreshold: { sameCategory: 0.35, crossCategory: 0.45 },
462
+ overlapGate: "line-or-file",
463
+ };
390
464
  /**
391
465
  * Same-lens dedup: within each (lens, primary-path) group, collapse fuzzily-similar
392
466
  * findings (title Jaccard with a category-lowered threshold, plus line-range OR file
393
467
  * overlap), the higher sev/conf survivor absorbing the loser in place with grounding-
394
- * precedence + sorted files. A core capability only audit currently draws (remediate
395
- * consumes findings the auditor already collapsed), single-sourced here so the whole
396
- * finding-dedup family lives in one place.
468
+ * precedence + sorted files. The audit draw of the shared survivor fold — same
469
+ * skeleton as `crossLensDedupe`, a different `PairMatchPolicy`, mutate-in-place
470
+ * survivors, and no merge record (a human reads the report; nothing consumes an
471
+ * id-keyed same-lens provenance today).
397
472
  */
398
473
  export function sameLensDedupe(findings) {
399
- const groups = new Map();
400
- for (const finding of findings) {
401
- const key = `${normalizeText(finding.lens)}:${primaryPath(finding)}`;
402
- const group = groups.get(key);
403
- if (group)
404
- group.push(finding);
405
- else
406
- groups.set(key, [finding]);
407
- }
408
- const removed = new Set();
409
- for (const group of groups.values()) {
410
- if (group.length < 2)
411
- continue;
412
- for (let i = 0; i < group.length; i++) {
413
- if (removed.has(group[i]))
414
- continue;
415
- for (let j = i + 1; j < group.length; j++) {
416
- // The i-slot finding may have been absorbed mid-scan (as b of an earlier
417
- // pair): an absorbed finding must never act as a survivor again, or it
418
- // re-absorbs data that was already unioned into ITS absorber and the
419
- // final filter silently drops everything it then wins — the same
420
- // conservation guard crossLensDedupe carries. Checked BEFORE the j-slot
421
- // skip, mirroring that pass.
422
- if (removed.has(group[i]))
423
- break;
424
- if (removed.has(group[j]))
425
- continue;
426
- const a = group[i];
427
- const b = group[j];
428
- // sameLensDedupe has different similarity thresholds than crossLensDedupe
429
- const catMatch = normalizeText(a.category) === normalizeText(b.category);
430
- const titleSim = wordJaccard(a.title, b.title);
431
- const threshold = catMatch ? 0.35 : 0.45;
432
- if (titleSim < threshold)
433
- continue;
434
- if (!lineRangeOverlaps(a, b) && filePathOverlap(a, b) < 0.5)
435
- continue;
436
- const aSev = severityRank(a.severity);
437
- const bSev = severityRank(b.severity);
438
- const aConf = confidenceRank(a.confidence);
439
- const bConf = confidenceRank(b.confidence);
440
- const keepA = aSev > bSev || (aSev === bSev && aConf >= bConf);
441
- const [survivor, absorbed] = keepA ? [a, b] : [b, a];
442
- absorbFinding(survivor, absorbed, { mergeGrounding: true, sortAffectedFiles: true });
443
- removed.add(absorbed);
444
- }
445
- }
446
- }
474
+ const { removed } = collapseFindingGroups(findings, {
475
+ groupKey: (finding) => `${normalizeText(finding.lens)}:${primaryPath(finding)}`,
476
+ matchPair: (a, b) => compareFindingPair(a, b, SAME_LENS_MATCH_POLICY),
477
+ survivorMutation: "mutate",
478
+ absorb: { mergeGrounding: true, sortAffectedFiles: true },
479
+ });
447
480
  return findings.filter((f) => !removed.has(f));
448
481
  }
449
482
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"dedupe.js","sourceRoot":"","sources":["../../../src/shared/findings/dedupe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dedupe.js","sourceRoot":"","sources":["../../../src/shared/findings/dedupe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Directed-cycle primitives over an id + dependency-list graph — the ONE core
3
+ * every cycle question in this package draws from.
4
+ *
5
+ * Four call sites used to ask the same question three hand-rolled ways: two
6
+ * Kahn drains (the cyclic-seam detector and the design-spec circular-obligation
7
+ * gate) and a recursive white/gray/black DFS (the obligation-ledger
8
+ * construction guard and the implementation-DAG validator). The Kahn drains
9
+ * were WRONG about membership: a Kahn remainder is "every node that never
10
+ * reached in-degree zero", which includes every node DOWNSTREAM of a cycle, so
11
+ * a tail that merely depends on a cycle member was reported as a member of the
12
+ * cycle it can never be part of. Exact membership is the strongly connected
13
+ * component, and that is what {@link findCyclicComponents} returns.
14
+ *
15
+ * Both traversals are ITERATIVE. A ledger or DAG reaching these functions is
16
+ * host-authored, untrusted input of arbitrary depth; a recursive DFS over one
17
+ * stack-overflows rather than reporting.
18
+ *
19
+ * Determinism is part of the contract — these results reach persisted artifacts
20
+ * and prompt text. Component order, member order and the witness path all
21
+ * follow the caller's input order, never Map/Set iteration accident.
22
+ */
23
+ /** A node in a directed dependency graph: an id and the ids it depends on. */
24
+ interface DirectedGraphNode {
25
+ /** Node identifier. Duplicate ids are normalized away (see below). */
26
+ id: string;
27
+ /** Ids this node depends on. Ids outside the input set are ignored. */
28
+ depends_on: readonly string[];
29
+ }
30
+ interface DirectedCycleOptions {
31
+ /**
32
+ * Treat a self-edge (`id` → `id`) as a cycle: a 1-member component is
33
+ * reported, and the witness may be `["A","A"]`. Default `false` — the
34
+ * implementation-DAG validator deliberately strips self-edges.
35
+ */
36
+ includeSelfLoops?: boolean;
37
+ }
38
+ /**
39
+ * Every CYCLIC strongly connected component of the graph — exact cycle
40
+ * membership, with no downstream tail and no upstream feeder.
41
+ *
42
+ * A component qualifies when it holds two or more mutually reachable nodes, or
43
+ * when it is a single node with a self-edge and `includeSelfLoops` is set.
44
+ * Iterative Tarjan; components are ordered by their first member's input
45
+ * position and members are listed in input order, so the result is stable
46
+ * across runs and platforms.
47
+ */
48
+ export declare function findCyclicComponents(nodes: readonly DirectedGraphNode[], options?: DirectedCycleOptions): string[][];
49
+ /**
50
+ * The first cycle reachable in input order, as a witness PATH with its start
51
+ * repeated at the end — `["A","B","A"]` — or `null` for an acyclic graph.
52
+ *
53
+ * This is the shape callers render into an error message, so it is a path, not
54
+ * a set: it names the edges that close the loop. Iterative white/gray/black
55
+ * DFS, visiting roots and each node's dependencies in input order, so the
56
+ * reported cycle is the same one on every run. A self-edge yields `["A","A"]`
57
+ * when `includeSelfLoops` is set, and is invisible otherwise.
58
+ */
59
+ export declare function findFirstCycleWitness(nodes: readonly DirectedGraphNode[], options?: DirectedCycleOptions): string[] | null;
60
+ export {};
61
+ //# sourceMappingURL=directedCycles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directedCycles.d.ts","sourceRoot":"","sources":["../../../src/shared/graph/directedCycles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,8EAA8E;AAC9E,UAAU,iBAAiB;IACzB,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,UAAU,oBAAoB;IAC5B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AA6DD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,OAAO,GAAE,oBAAyB,GACjC,MAAM,EAAE,EAAE,CAuEZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,iBAAiB,EAAE,EACnC,OAAO,GAAE,oBAAyB,GACjC,MAAM,EAAE,GAAG,IAAI,CAuCjB"}