vaspera 2.9.0 → 2.10.0

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 (166) hide show
  1. package/CHANGELOG.md +122 -7
  2. package/README.md +58 -1
  3. package/dist/__tests__/autofix/branch-manager.test.d.ts +2 -0
  4. package/dist/__tests__/autofix/branch-manager.test.d.ts.map +1 -0
  5. package/dist/__tests__/autofix/branch-manager.test.js +60 -0
  6. package/dist/__tests__/autofix/branch-manager.test.js.map +1 -0
  7. package/dist/__tests__/autofix/commit-generator.test.d.ts +2 -0
  8. package/dist/__tests__/autofix/commit-generator.test.d.ts.map +1 -0
  9. package/dist/__tests__/autofix/commit-generator.test.js +147 -0
  10. package/dist/__tests__/autofix/commit-generator.test.js.map +1 -0
  11. package/dist/__tests__/autofix/constitution.test.d.ts +9 -0
  12. package/dist/__tests__/autofix/constitution.test.d.ts.map +1 -0
  13. package/dist/__tests__/autofix/constitution.test.js +421 -0
  14. package/dist/__tests__/autofix/constitution.test.js.map +1 -0
  15. package/dist/__tests__/autofix/pr-generator.test.d.ts +2 -0
  16. package/dist/__tests__/autofix/pr-generator.test.d.ts.map +1 -0
  17. package/dist/__tests__/autofix/pr-generator.test.js +152 -0
  18. package/dist/__tests__/autofix/pr-generator.test.js.map +1 -0
  19. package/dist/__tests__/property-test-helpers.d.ts +87 -0
  20. package/dist/__tests__/property-test-helpers.d.ts.map +1 -0
  21. package/dist/__tests__/property-test-helpers.js +136 -0
  22. package/dist/__tests__/property-test-helpers.js.map +1 -0
  23. package/dist/__tests__/scanners/dast/index.test.d.ts +2 -0
  24. package/dist/__tests__/scanners/dast/index.test.d.ts.map +1 -0
  25. package/dist/__tests__/scanners/dast/index.test.js +183 -0
  26. package/dist/__tests__/scanners/dast/index.test.js.map +1 -0
  27. package/dist/__tests__/scanners/dast/nuclei.test.d.ts +2 -0
  28. package/dist/__tests__/scanners/dast/nuclei.test.d.ts.map +1 -0
  29. package/dist/__tests__/scanners/dast/nuclei.test.js +166 -0
  30. package/dist/__tests__/scanners/dast/nuclei.test.js.map +1 -0
  31. package/dist/__tests__/scanners/dast/zap.test.d.ts +2 -0
  32. package/dist/__tests__/scanners/dast/zap.test.d.ts.map +1 -0
  33. package/dist/__tests__/scanners/dast/zap.test.js +158 -0
  34. package/dist/__tests__/scanners/dast/zap.test.js.map +1 -0
  35. package/dist/__tests__/scanners/fp-feedback.test.d.ts +2 -0
  36. package/dist/__tests__/scanners/fp-feedback.test.d.ts.map +1 -0
  37. package/dist/__tests__/scanners/fp-feedback.test.js +202 -0
  38. package/dist/__tests__/scanners/fp-feedback.test.js.map +1 -0
  39. package/dist/__tests__/scanners/fp-filter.property.test.d.ts +9 -0
  40. package/dist/__tests__/scanners/fp-filter.property.test.d.ts.map +1 -0
  41. package/dist/__tests__/scanners/fp-filter.property.test.js +253 -0
  42. package/dist/__tests__/scanners/fp-filter.property.test.js.map +1 -0
  43. package/dist/__tests__/scanners/fp-filter.test.d.ts +2 -0
  44. package/dist/__tests__/scanners/fp-filter.test.d.ts.map +1 -0
  45. package/dist/__tests__/scanners/fp-filter.test.js +234 -0
  46. package/dist/__tests__/scanners/fp-filter.test.js.map +1 -0
  47. package/dist/__tests__/scanners/fp-tracker.test.d.ts +2 -0
  48. package/dist/__tests__/scanners/fp-tracker.test.d.ts.map +1 -0
  49. package/dist/__tests__/scanners/fp-tracker.test.js +262 -0
  50. package/dist/__tests__/scanners/fp-tracker.test.js.map +1 -0
  51. package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts +10 -0
  52. package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.d.ts.map +1 -0
  53. package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js +238 -0
  54. package/dist/__tests__/scanners/logic/endpoint-analyzer.property.test.js.map +1 -0
  55. package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts +2 -0
  56. package/dist/__tests__/scanners/logic/endpoint-analyzer.test.d.ts.map +1 -0
  57. package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js +55 -0
  58. package/dist/__tests__/scanners/logic/endpoint-analyzer.test.js.map +1 -0
  59. package/dist/__tests__/scanners/logic/index.test.d.ts +2 -0
  60. package/dist/__tests__/scanners/logic/index.test.d.ts.map +1 -0
  61. package/dist/__tests__/scanners/logic/index.test.js +165 -0
  62. package/dist/__tests__/scanners/logic/index.test.js.map +1 -0
  63. package/dist/__tests__/scanners/logic/types.test.d.ts +2 -0
  64. package/dist/__tests__/scanners/logic/types.test.d.ts.map +1 -0
  65. package/dist/__tests__/scanners/logic/types.test.js +85 -0
  66. package/dist/__tests__/scanners/logic/types.test.js.map +1 -0
  67. package/dist/action/pr-comment.test.js +4 -0
  68. package/dist/action/pr-comment.test.js.map +1 -1
  69. package/dist/action/sarif-upload.test.js +4 -0
  70. package/dist/action/sarif-upload.test.js.map +1 -1
  71. package/dist/autofix/branch-manager.d.ts +115 -0
  72. package/dist/autofix/branch-manager.d.ts.map +1 -0
  73. package/dist/autofix/branch-manager.js +308 -0
  74. package/dist/autofix/branch-manager.js.map +1 -0
  75. package/dist/autofix/commit-generator.d.ts +55 -0
  76. package/dist/autofix/commit-generator.d.ts.map +1 -0
  77. package/dist/autofix/commit-generator.js +277 -0
  78. package/dist/autofix/commit-generator.js.map +1 -0
  79. package/dist/autofix/constitution.d.ts +77 -0
  80. package/dist/autofix/constitution.d.ts.map +1 -0
  81. package/dist/autofix/constitution.js +261 -0
  82. package/dist/autofix/constitution.js.map +1 -0
  83. package/dist/autofix/constitution.schema.d.ts +441 -0
  84. package/dist/autofix/constitution.schema.d.ts.map +1 -0
  85. package/dist/autofix/constitution.schema.js +144 -0
  86. package/dist/autofix/constitution.schema.js.map +1 -0
  87. package/dist/autofix/index.d.ts +13 -0
  88. package/dist/autofix/index.d.ts.map +1 -0
  89. package/dist/autofix/index.js +15 -0
  90. package/dist/autofix/index.js.map +1 -0
  91. package/dist/autofix/pr-generator.d.ts +57 -0
  92. package/dist/autofix/pr-generator.d.ts.map +1 -0
  93. package/dist/autofix/pr-generator.js +597 -0
  94. package/dist/autofix/pr-generator.js.map +1 -0
  95. package/dist/autofix/types.d.ts +151 -0
  96. package/dist/autofix/types.d.ts.map +1 -0
  97. package/dist/autofix/types.js +22 -0
  98. package/dist/autofix/types.js.map +1 -0
  99. package/dist/eval/fixtures.d.ts +20 -0
  100. package/dist/eval/fixtures.d.ts.map +1 -1
  101. package/dist/eval/fixtures.js +430 -0
  102. package/dist/eval/fixtures.js.map +1 -1
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +84 -1
  105. package/dist/index.js.map +1 -1
  106. package/dist/scanners/cache.d.ts.map +1 -1
  107. package/dist/scanners/cache.js +4 -0
  108. package/dist/scanners/cache.js.map +1 -1
  109. package/dist/scanners/dast/index.d.ts +39 -0
  110. package/dist/scanners/dast/index.d.ts.map +1 -0
  111. package/dist/scanners/dast/index.js +259 -0
  112. package/dist/scanners/dast/index.js.map +1 -0
  113. package/dist/scanners/dast/nuclei.d.ts +26 -0
  114. package/dist/scanners/dast/nuclei.d.ts.map +1 -0
  115. package/dist/scanners/dast/nuclei.js +354 -0
  116. package/dist/scanners/dast/nuclei.js.map +1 -0
  117. package/dist/scanners/dast/types.d.ts +306 -0
  118. package/dist/scanners/dast/types.d.ts.map +1 -0
  119. package/dist/scanners/dast/types.js +52 -0
  120. package/dist/scanners/dast/types.js.map +1 -0
  121. package/dist/scanners/dast/zap.d.ts +26 -0
  122. package/dist/scanners/dast/zap.d.ts.map +1 -0
  123. package/dist/scanners/dast/zap.js +453 -0
  124. package/dist/scanners/dast/zap.js.map +1 -0
  125. package/dist/scanners/fp-feedback.d.ts +140 -0
  126. package/dist/scanners/fp-feedback.d.ts.map +1 -0
  127. package/dist/scanners/fp-feedback.js +292 -0
  128. package/dist/scanners/fp-feedback.js.map +1 -0
  129. package/dist/scanners/fp-filter.d.ts +94 -0
  130. package/dist/scanners/fp-filter.d.ts.map +1 -0
  131. package/dist/scanners/fp-filter.js +397 -0
  132. package/dist/scanners/fp-filter.js.map +1 -0
  133. package/dist/scanners/fp-tracker.d.ts +125 -0
  134. package/dist/scanners/fp-tracker.d.ts.map +1 -0
  135. package/dist/scanners/fp-tracker.js +330 -0
  136. package/dist/scanners/fp-tracker.js.map +1 -0
  137. package/dist/scanners/index.d.ts.map +1 -1
  138. package/dist/scanners/index.js +56 -0
  139. package/dist/scanners/index.js.map +1 -1
  140. package/dist/scanners/index.test.js +6 -6
  141. package/dist/scanners/index.test.js.map +1 -1
  142. package/dist/scanners/logic/auth-flow-analyzer.d.ts +18 -0
  143. package/dist/scanners/logic/auth-flow-analyzer.d.ts.map +1 -0
  144. package/dist/scanners/logic/auth-flow-analyzer.js +384 -0
  145. package/dist/scanners/logic/auth-flow-analyzer.js.map +1 -0
  146. package/dist/scanners/logic/endpoint-analyzer.d.ts +29 -0
  147. package/dist/scanners/logic/endpoint-analyzer.d.ts.map +1 -0
  148. package/dist/scanners/logic/endpoint-analyzer.js +528 -0
  149. package/dist/scanners/logic/endpoint-analyzer.js.map +1 -0
  150. package/dist/scanners/logic/index.d.ts +41 -0
  151. package/dist/scanners/logic/index.d.ts.map +1 -0
  152. package/dist/scanners/logic/index.js +268 -0
  153. package/dist/scanners/logic/index.js.map +1 -0
  154. package/dist/scanners/logic/types.d.ts +254 -0
  155. package/dist/scanners/logic/types.d.ts.map +1 -0
  156. package/dist/scanners/logic/types.js +142 -0
  157. package/dist/scanners/logic/types.js.map +1 -0
  158. package/dist/scanners/types.d.ts +1 -1
  159. package/dist/scanners/types.d.ts.map +1 -1
  160. package/dist/scanners/types.js +4 -0
  161. package/dist/scanners/types.js.map +1 -1
  162. package/dist/telemetry/usage.d.ts +1 -1
  163. package/dist/telemetry/usage.d.ts.map +1 -1
  164. package/dist/telemetry/usage.js +14 -6
  165. package/dist/telemetry/usage.js.map +1 -1
  166. package/package.json +6 -8
@@ -0,0 +1,397 @@
1
+ /**
2
+ * False Positive Filter
3
+ *
4
+ * Context-aware filtering to reduce false positives from scanners.
5
+ * Analyzes code context, semantic patterns, and historical data.
6
+ *
7
+ * @module scanners/fp-filter
8
+ */
9
+ import { readFile } from "fs/promises";
10
+ import { join, basename } from "path";
11
+ import { logger } from "../logger.js";
12
+ /**
13
+ * Patterns that indicate test files
14
+ */
15
+ const TEST_FILE_PATTERNS = [
16
+ /\.test\.[jt]sx?$/,
17
+ /\.spec\.[jt]sx?$/,
18
+ /__tests__\//,
19
+ /__mocks__\//,
20
+ /(?:^|\/)test\//,
21
+ /(?:^|\/)tests\//,
22
+ /\.stories\.[jt]sx?$/,
23
+ /\.mock\.[jt]sx?$/,
24
+ /(?:^|\/)cypress\//,
25
+ /(?:^|\/)e2e\//,
26
+ /(?:^|\/)playwright\//,
27
+ ];
28
+ /**
29
+ * Patterns that indicate generated code
30
+ */
31
+ const GENERATED_CODE_PATTERNS = [
32
+ /\.generated\.[jt]sx?$/,
33
+ /\.gen\.[jt]sx?$/,
34
+ /generated\//,
35
+ /__generated__\//,
36
+ /\.d\.ts$/,
37
+ /swagger-client/,
38
+ /openapi-client/,
39
+ /graphql\.ts$/,
40
+ /prisma\/client/,
41
+ ];
42
+ /**
43
+ * Patterns that indicate vendored/third-party code
44
+ */
45
+ const VENDOR_PATTERNS = [
46
+ /node_modules\//,
47
+ /vendor\//,
48
+ /third[_-]?party\//,
49
+ /external\//,
50
+ /lib\/vendor/,
51
+ /\.min\.js$/,
52
+ /bundle\.js$/,
53
+ ];
54
+ /**
55
+ * Patterns that indicate fixture/example files
56
+ */
57
+ const FIXTURE_PATTERNS = [
58
+ /fixtures?\//,
59
+ /samples?\//,
60
+ /examples?\//,
61
+ /demo\//,
62
+ /seed\//,
63
+ /seeds\//,
64
+ /mock[_-]?data/,
65
+ ];
66
+ /**
67
+ * Rules that are commonly false positives in certain contexts
68
+ */
69
+ const CONTEXT_SENSITIVE_RULES = {
70
+ "hardcoded-secret": {
71
+ filterInTests: true,
72
+ filterInGenerated: false,
73
+ filterIfConstant: false,
74
+ filterIfEnvVar: true,
75
+ },
76
+ "sql-injection": {
77
+ filterInTests: true,
78
+ filterInGenerated: true,
79
+ filterIfConstant: true,
80
+ filterIfEnvVar: false,
81
+ },
82
+ "xss": {
83
+ filterInTests: true,
84
+ filterInGenerated: true,
85
+ filterIfConstant: true,
86
+ filterIfEnvVar: false,
87
+ },
88
+ "command-injection": {
89
+ filterInTests: true,
90
+ filterInGenerated: true,
91
+ filterIfConstant: true,
92
+ filterIfEnvVar: false,
93
+ },
94
+ "path-traversal": {
95
+ filterInTests: true,
96
+ filterInGenerated: true,
97
+ filterIfConstant: true,
98
+ filterIfEnvVar: false,
99
+ },
100
+ };
101
+ /**
102
+ * Analyze file path to determine code context
103
+ */
104
+ export function analyzeFilePath(filePath) {
105
+ const normalizedPath = filePath.replace(/\\/g, "/");
106
+ const fileName = basename(filePath);
107
+ return {
108
+ isTestFile: TEST_FILE_PATTERNS.some((p) => p.test(normalizedPath)),
109
+ isGeneratedCode: GENERATED_CODE_PATTERNS.some((p) => p.test(normalizedPath)),
110
+ isThirdPartyVendored: VENDOR_PATTERNS.some((p) => p.test(normalizedPath)),
111
+ isMockFile: /\.mock\.[jt]sx?$/.test(fileName) || /mocks?\//i.test(normalizedPath),
112
+ isFixtureFile: FIXTURE_PATTERNS.some((p) => p.test(normalizedPath)),
113
+ isExampleFile: /examples?\//i.test(normalizedPath) || /demo\//i.test(normalizedPath),
114
+ };
115
+ }
116
+ /**
117
+ * Analyze code content for semantic context
118
+ */
119
+ export async function analyzeCodeContext(projectPath, finding) {
120
+ const defaultContext = {
121
+ hasValidation: false,
122
+ hasEncoding: false,
123
+ isSanitized: false,
124
+ isConstant: false,
125
+ isEnvironmentVariable: false,
126
+ };
127
+ if (!finding.file) {
128
+ return defaultContext;
129
+ }
130
+ try {
131
+ const filePath = join(projectPath, finding.file);
132
+ const content = await readFile(filePath, "utf-8");
133
+ const lines = content.split("\n");
134
+ // Get surrounding context (5 lines before and after)
135
+ const startLine = Math.max(0, (finding.line || 1) - 6);
136
+ const endLine = Math.min(lines.length, (finding.line || 1) + 5);
137
+ const context = lines.slice(startLine, endLine).join("\n");
138
+ // Check for validation patterns
139
+ const validationPatterns = [
140
+ /validate/i,
141
+ /sanitize/i,
142
+ /escape/i,
143
+ /encode/i,
144
+ /\.parse\(/,
145
+ /z\.\w+\(/, // Zod validation
146
+ /yup\.\w+/, // Yup validation
147
+ /joi\.\w+/, // Joi validation
148
+ /validator\./,
149
+ ];
150
+ const hasValidation = validationPatterns.some((p) => p.test(context));
151
+ // Check for encoding patterns
152
+ const encodingPatterns = [
153
+ /encodeURIComponent/,
154
+ /encodeURI/,
155
+ /htmlEncode/,
156
+ /escapeHtml/,
157
+ /DOMPurify/,
158
+ /sanitizeHtml/,
159
+ ];
160
+ const hasEncoding = encodingPatterns.some((p) => p.test(context));
161
+ // Check for sanitization
162
+ const sanitizationPatterns = [
163
+ /sanitize/i,
164
+ /clean/i,
165
+ /purify/i,
166
+ /strip/i,
167
+ /filter\s*\(/,
168
+ ];
169
+ const isSanitized = sanitizationPatterns.some((p) => p.test(context));
170
+ // Check if value is constant
171
+ const line = lines[(finding.line || 1) - 1] || "";
172
+ const isConstant = /const\s+\w+\s*=\s*["'`]/.test(line) ||
173
+ /readonly\s/.test(line) ||
174
+ /as\s+const/.test(line);
175
+ // Check if value comes from environment variable
176
+ const isEnvironmentVariable = /process\.env\./i.test(context) ||
177
+ /import\.meta\.env/i.test(context) ||
178
+ /\$\{.*ENV.*\}/i.test(context);
179
+ return {
180
+ hasValidation,
181
+ hasEncoding,
182
+ isSanitized,
183
+ isConstant,
184
+ isEnvironmentVariable,
185
+ };
186
+ }
187
+ catch (error) {
188
+ logger.debug("fp_filter.analyze_failed", {
189
+ file: finding.file,
190
+ error: String(error),
191
+ });
192
+ return defaultContext;
193
+ }
194
+ }
195
+ /**
196
+ * Determine if a finding should be filtered as a false positive
197
+ */
198
+ export function shouldFilter(finding, context) {
199
+ const { codeContext, semanticContext, historicalContext } = context;
200
+ // Always filter vendored/third-party code
201
+ if (codeContext.isThirdPartyVendored) {
202
+ return {
203
+ filter: true,
204
+ reason: "Third-party/vendored code",
205
+ confidence: 95,
206
+ suggestion: "suppress",
207
+ };
208
+ }
209
+ // Get rule-specific filtering rules
210
+ const category = finding.category || extractCategory(finding.ruleId);
211
+ const ruleConfig = CONTEXT_SENSITIVE_RULES[category];
212
+ if (ruleConfig) {
213
+ // Filter in test files for certain rules
214
+ if (ruleConfig.filterInTests && codeContext.isTestFile) {
215
+ return {
216
+ filter: true,
217
+ reason: "Test file - rule typically FP in tests",
218
+ confidence: 85,
219
+ suggestion: "suppress",
220
+ };
221
+ }
222
+ // Filter in generated code
223
+ if (ruleConfig.filterInGenerated && codeContext.isGeneratedCode) {
224
+ return {
225
+ filter: true,
226
+ reason: "Generated code",
227
+ confidence: 90,
228
+ suggestion: "suppress",
229
+ };
230
+ }
231
+ // Filter if value is constant
232
+ if (ruleConfig.filterIfConstant && semanticContext.isConstant) {
233
+ return {
234
+ filter: true,
235
+ reason: "Constant value - not user-controlled",
236
+ confidence: 75,
237
+ suggestion: "review",
238
+ };
239
+ }
240
+ // Filter if environment variable
241
+ if (ruleConfig.filterIfEnvVar && semanticContext.isEnvironmentVariable) {
242
+ return {
243
+ filter: true,
244
+ reason: "Environment variable reference",
245
+ confidence: 80,
246
+ suggestion: "review",
247
+ };
248
+ }
249
+ }
250
+ // Filter fixture/example files with lower confidence
251
+ if (codeContext.isFixtureFile || codeContext.isExampleFile) {
252
+ return {
253
+ filter: true,
254
+ reason: "Fixture/example file",
255
+ confidence: 70,
256
+ suggestion: "review",
257
+ };
258
+ }
259
+ // Check if sanitization is present
260
+ if (semanticContext.isSanitized || semanticContext.hasValidation || semanticContext.hasEncoding) {
261
+ return {
262
+ filter: false,
263
+ reason: "Sanitization detected but manual review recommended",
264
+ confidence: 60,
265
+ suggestion: "review",
266
+ };
267
+ }
268
+ // Check historical suppressions
269
+ if (historicalContext.suppressions.includes(finding.ruleId)) {
270
+ return {
271
+ filter: true,
272
+ reason: "Previously suppressed rule",
273
+ confidence: 70,
274
+ suggestion: "review",
275
+ };
276
+ }
277
+ // Check historical accuracy
278
+ if (historicalContext.ruleAccuracy < 0.3) {
279
+ return {
280
+ filter: false,
281
+ reason: `Low historical accuracy (${Math.round(historicalContext.ruleAccuracy * 100)}%)`,
282
+ confidence: 50,
283
+ suggestion: "review",
284
+ };
285
+ }
286
+ // No filtering
287
+ return {
288
+ filter: false,
289
+ confidence: 100,
290
+ suggestion: "confirm",
291
+ };
292
+ }
293
+ /**
294
+ * Extract category from rule ID
295
+ */
296
+ function extractCategory(ruleId) {
297
+ // Common patterns: "scanner:category.rule" or "category-rule"
298
+ const colonMatch = ruleId.match(/^[^:]+:([^.]+)/);
299
+ if (colonMatch) {
300
+ return colonMatch[1];
301
+ }
302
+ const dashMatch = ruleId.match(/^([a-z-]+)-\d+$/i);
303
+ if (dashMatch) {
304
+ return dashMatch[1];
305
+ }
306
+ return ruleId;
307
+ }
308
+ /**
309
+ * Filter findings and return filtered results with reasons
310
+ */
311
+ export async function filterFindings(projectPath, findings, options) {
312
+ const minConfidence = options?.minConfidence ?? 70;
313
+ const historicalData = options?.historicalData ?? new Map();
314
+ const filtered = [];
315
+ const removed = [];
316
+ const byReason = {};
317
+ for (const finding of findings) {
318
+ // Build context
319
+ const codeContext = analyzeFilePath(finding.file);
320
+ const semanticContext = await analyzeCodeContext(projectPath, finding);
321
+ const ruleHistory = historicalData.get(finding.ruleId);
322
+ const historicalContext = {
323
+ previousFPs: [],
324
+ ruleAccuracy: ruleHistory?.fpRate ?? 1.0,
325
+ suppressions: ruleHistory?.suppressions ?? [],
326
+ };
327
+ const context = {
328
+ codeContext,
329
+ semanticContext,
330
+ historicalContext,
331
+ };
332
+ const result = shouldFilter(finding, context);
333
+ if (result.filter && result.confidence >= minConfidence) {
334
+ removed.push({
335
+ finding,
336
+ reason: result.reason || "Filtered",
337
+ confidence: result.confidence,
338
+ });
339
+ byReason[result.reason || "Unknown"] = (byReason[result.reason || "Unknown"] || 0) + 1;
340
+ }
341
+ else {
342
+ filtered.push(finding);
343
+ }
344
+ }
345
+ logger.info("fp_filter.complete", {
346
+ total: findings.length,
347
+ kept: filtered.length,
348
+ filtered: removed.length,
349
+ });
350
+ return {
351
+ filtered,
352
+ removed,
353
+ stats: {
354
+ total: findings.length,
355
+ kept: filtered.length,
356
+ filtered: removed.length,
357
+ byReason,
358
+ },
359
+ };
360
+ }
361
+ /**
362
+ * Get suggested suppressions for a finding
363
+ */
364
+ export function getSuppressSuggestion(finding, context) {
365
+ const scanner = finding.scanner;
366
+ const ruleId = finding.ruleId;
367
+ // Generate scanner-specific suppression comments
368
+ let inlineComment;
369
+ let fileComment;
370
+ switch (scanner) {
371
+ case "semgrep":
372
+ inlineComment = `// nosemgrep: ${ruleId}`;
373
+ fileComment = `// nosemgrep`;
374
+ break;
375
+ case "eslint":
376
+ inlineComment = `// eslint-disable-next-line ${ruleId}`;
377
+ fileComment = `/* eslint-disable ${ruleId} */`;
378
+ break;
379
+ case "gitleaks":
380
+ inlineComment = `// gitleaks:allow`;
381
+ fileComment = `# gitleaks:allow`;
382
+ break;
383
+ case "bandit":
384
+ inlineComment = `# nosec ${ruleId}`;
385
+ fileComment = `# nosec`;
386
+ break;
387
+ default:
388
+ inlineComment = `// @suppress ${ruleId}`;
389
+ fileComment = `// @suppress-file ${ruleId}`;
390
+ }
391
+ return {
392
+ suppressionComment: `Suppressed: ${finding.message} (${context.codeContext.isTestFile ? "test file" : "reviewed"})`,
393
+ inlineSuppress: inlineComment,
394
+ fileSuppress: fileComment,
395
+ };
396
+ }
397
+ //# sourceMappingURL=fp-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fp-filter.js","sourceRoot":"","sources":["../../src/scanners/fp-filter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAW,MAAM,MAAM,CAAC;AAE/C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAkDtC;;GAEG;AACH,MAAM,kBAAkB,GAAG;IACzB,kBAAkB;IAClB,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,qBAAqB;IACrB,kBAAkB;IAClB,mBAAmB;IACnB,eAAe;IACf,sBAAsB;CACvB,CAAC;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAG;IAC9B,uBAAuB;IACvB,iBAAiB;IACjB,aAAa;IACb,iBAAiB;IACjB,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,eAAe,GAAG;IACtB,gBAAgB;IAChB,UAAU;IACV,mBAAmB;IACnB,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,aAAa;CACd,CAAC;AAEF;;GAEG;AACH,MAAM,gBAAgB,GAAG;IACvB,aAAa;IACb,YAAY;IACZ,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,eAAe;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAKxB;IACH,kBAAkB,EAAE;QAClB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,KAAK;QACxB,gBAAgB,EAAE,KAAK;QACvB,cAAc,EAAE,IAAI;KACrB;IACD,eAAe,EAAE;QACf,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,KAAK;KACtB;IACD,KAAK,EAAE;QACL,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,KAAK;KACtB;IACD,mBAAmB,EAAE;QACnB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,KAAK;KACtB;IACD,gBAAgB,EAAE;QAChB,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE,IAAI;QACvB,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,KAAK;KACtB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEpC,OAAO;QACL,UAAU,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,eAAe,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5E,oBAAoB,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzE,UAAU,EAAE,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC;QACjF,aAAa,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,aAAa,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC;KACrF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,OAA6B;IAE7B,MAAM,cAAc,GAAuC;QACzD,aAAa,EAAE,KAAK;QACpB,WAAW,EAAE,KAAK;QAClB,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,KAAK;QACjB,qBAAqB,EAAE,KAAK;KAC7B,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAElC,qDAAqD;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3D,gCAAgC;QAChC,MAAM,kBAAkB,GAAG;YACzB,WAAW;YACX,WAAW;YACX,SAAS;YACT,SAAS;YACT,WAAW;YACX,UAAU,EAAG,iBAAiB;YAC9B,UAAU,EAAG,iBAAiB;YAC9B,UAAU,EAAG,iBAAiB;YAC9B,aAAa;SACd,CAAC;QACF,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAEtE,8BAA8B;QAC9B,MAAM,gBAAgB,GAAG;YACvB,oBAAoB;YACpB,WAAW;YACX,YAAY;YACZ,YAAY;YACZ,WAAW;YACX,cAAc;SACf,CAAC;QACF,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAElE,yBAAyB;QACzB,MAAM,oBAAoB,GAAG;YAC3B,WAAW;YACX,QAAQ;YACR,SAAS;YACT,QAAQ;YACR,aAAa;SACd,CAAC;QACF,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAEtE,6BAA6B;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3C,iDAAiD;QACjD,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC;YAC9B,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;YAClC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE9D,OAAO;YACL,aAAa;YACb,WAAW;YACX,WAAW;YACX,UAAU;YACV,qBAAqB;SACtB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,0BAA0B,EAAE;YACvC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB,CAAC,CAAC;QACH,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA6B,EAC7B,OAAwB;IAExB,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAEpE,0CAA0C;IAC1C,IAAI,WAAW,CAAC,oBAAoB,EAAE,CAAC;QACrC,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,2BAA2B;YACnC,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,UAAU;SACvB,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAErD,IAAI,UAAU,EAAE,CAAC;QACf,yCAAyC;QACzC,IAAI,UAAU,CAAC,aAAa,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;YACvD,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,wCAAwC;gBAChD,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,UAAU;aACvB,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,IAAI,UAAU,CAAC,iBAAiB,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YAChE,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,gBAAgB;gBACxB,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,UAAU;aACvB,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,IAAI,UAAU,CAAC,gBAAgB,IAAI,eAAe,CAAC,UAAU,EAAE,CAAC;YAC9D,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,sCAAsC;gBAC9C,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,QAAQ;aACrB,CAAC;QACJ,CAAC;QAED,iCAAiC;QACjC,IAAI,UAAU,CAAC,cAAc,IAAI,eAAe,CAAC,qBAAqB,EAAE,CAAC;YACvE,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,gCAAgC;gBACxC,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,QAAQ;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,IAAI,WAAW,CAAC,aAAa,IAAI,WAAW,CAAC,aAAa,EAAE,CAAC;QAC3D,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,sBAAsB;YAC9B,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,QAAQ;SACrB,CAAC;IACJ,CAAC;IAED,mCAAmC;IACnC,IAAI,eAAe,CAAC,WAAW,IAAI,eAAe,CAAC,aAAa,IAAI,eAAe,CAAC,WAAW,EAAE,CAAC;QAChG,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,qDAAqD;YAC7D,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,QAAQ;SACrB,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,IAAI,iBAAiB,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,4BAA4B;YACpC,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,QAAQ;SACrB,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,IAAI,iBAAiB,CAAC,YAAY,GAAG,GAAG,EAAE,CAAC;QACzC,OAAO;YACL,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,4BAA4B,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,YAAY,GAAG,GAAG,CAAC,IAAI;YACxF,UAAU,EAAE,EAAE;YACd,UAAU,EAAE,QAAQ;SACrB,CAAC;IACJ,CAAC;IAED,eAAe;IACf,OAAO;QACL,MAAM,EAAE,KAAK;QACb,UAAU,EAAE,GAAG;QACf,UAAU,EAAE,SAAS;KACtB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,8DAA8D;IAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAClD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,WAAmB,EACnB,QAAgC,EAChC,OAGC;IAWD,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC;IACnD,MAAM,cAAc,GAAG,OAAO,EAAE,cAAc,IAAI,IAAI,GAAG,EAAE,CAAC;IAE5D,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAiF,EAAE,CAAC;IACjG,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAE5C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,gBAAgB;QAChB,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAEvE,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,iBAAiB,GAAyC;YAC9D,WAAW,EAAE,EAAE;YACf,YAAY,EAAE,WAAW,EAAE,MAAM,IAAI,GAAG;YACxC,YAAY,EAAE,WAAW,EAAE,YAAY,IAAI,EAAE;SAC9C,CAAC;QAEF,MAAM,OAAO,GAAoB;YAC/B,WAAW;YACX,eAAe;YACf,iBAAiB;SAClB,CAAC;QAEF,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE9C,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,IAAI,aAAa,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC;gBACX,OAAO;gBACP,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,UAAU;gBACnC,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;YACH,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE;QAChC,KAAK,EAAE,QAAQ,CAAC,MAAM;QACtB,IAAI,EAAE,QAAQ,CAAC,MAAM;QACrB,QAAQ,EAAE,OAAO,CAAC,MAAM;KACzB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,OAAO;QACP,KAAK,EAAE;YACL,KAAK,EAAE,QAAQ,CAAC,MAAM;YACtB,IAAI,EAAE,QAAQ,CAAC,MAAM;YACrB,QAAQ,EAAE,OAAO,CAAC,MAAM;YACxB,QAAQ;SACT;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAA6B,EAC7B,OAAwB;IAMxB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,iDAAiD;IACjD,IAAI,aAAqB,CAAC;IAC1B,IAAI,WAAmB,CAAC;IAExB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,aAAa,GAAG,iBAAiB,MAAM,EAAE,CAAC;YAC1C,WAAW,GAAG,cAAc,CAAC;YAC7B,MAAM;QACR,KAAK,QAAQ;YACX,aAAa,GAAG,+BAA+B,MAAM,EAAE,CAAC;YACxD,WAAW,GAAG,qBAAqB,MAAM,KAAK,CAAC;YAC/C,MAAM;QACR,KAAK,UAAU;YACb,aAAa,GAAG,mBAAmB,CAAC;YACpC,WAAW,GAAG,kBAAkB,CAAC;YACjC,MAAM;QACR,KAAK,QAAQ;YACX,aAAa,GAAG,WAAW,MAAM,EAAE,CAAC;YACpC,WAAW,GAAG,SAAS,CAAC;YACxB,MAAM;QACR;YACE,aAAa,GAAG,gBAAgB,MAAM,EAAE,CAAC;YACzC,WAAW,GAAG,qBAAqB,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,OAAO;QACL,kBAAkB,EAAE,eAAe,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,GAAG;QACnH,cAAc,EAAE,aAAa;QAC7B,YAAY,EAAE,WAAW;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * False Positive Tracker
3
+ *
4
+ * Tracks false positive rates per scanner/rule and adjusts
5
+ * finding confidence accordingly.
6
+ *
7
+ * @module scanners/fp-tracker
8
+ */
9
+ import type { ScannerType, DeterministicFinding } from "./types.js";
10
+ import type { Severity } from "../certification/types.js";
11
+ /**
12
+ * Metrics for a specific rule
13
+ */
14
+ export interface RuleMetrics {
15
+ /** Scanner that generated this rule */
16
+ scanner: ScannerType;
17
+ /** Rule ID */
18
+ ruleId: string;
19
+ /** Total findings reported by this rule */
20
+ totalReported: number;
21
+ /** Number confirmed as true positives */
22
+ confirmedTP: number;
23
+ /** Number confirmed as false positives */
24
+ confirmedFP: number;
25
+ /** Number still pending review */
26
+ pendingReview: number;
27
+ /** Calculated FP rate (0-1) */
28
+ fpRate: number;
29
+ /** Calculated TP rate (0-1) */
30
+ tpRate: number;
31
+ /** Confidence adjustment factor based on history */
32
+ adjustmentFactor: number;
33
+ /** Last updated timestamp */
34
+ lastUpdated: string;
35
+ /** Severity distribution of findings */
36
+ severityDistribution: Partial<Record<Severity, number>>;
37
+ }
38
+ /**
39
+ * Aggregated scanner metrics
40
+ */
41
+ export interface ScannerMetrics {
42
+ scanner: ScannerType;
43
+ totalRules: number;
44
+ totalFindings: number;
45
+ overallFPRate: number;
46
+ overallTPRate: number;
47
+ ruleMetrics: Map<string, RuleMetrics>;
48
+ }
49
+ /**
50
+ * FP tracking data store
51
+ */
52
+ export interface FPTrackingData {
53
+ version: string;
54
+ lastUpdated: string;
55
+ projectPath: string;
56
+ scanners: Record<string, ScannerMetrics>;
57
+ globalStats: {
58
+ totalFindings: number;
59
+ totalTP: number;
60
+ totalFP: number;
61
+ totalPending: number;
62
+ overallAccuracy: number;
63
+ };
64
+ }
65
+ /**
66
+ * Load FP tracking data from disk
67
+ */
68
+ export declare function loadTrackingData(projectPath: string): Promise<FPTrackingData>;
69
+ /**
70
+ * Save FP tracking data to disk
71
+ */
72
+ export declare function saveTrackingData(projectPath: string, data: FPTrackingData): Promise<void>;
73
+ /**
74
+ * Record a new finding for tracking
75
+ */
76
+ export declare function recordFinding(projectPath: string, finding: DeterministicFinding): Promise<void>;
77
+ /**
78
+ * Mark a finding as true positive
79
+ */
80
+ export declare function markTruePositive(projectPath: string, scanner: ScannerType, ruleId: string): Promise<RuleMetrics | undefined>;
81
+ /**
82
+ * Mark a finding as false positive
83
+ */
84
+ export declare function markFalsePositive(projectPath: string, scanner: ScannerType, ruleId: string, reason?: string): Promise<RuleMetrics | undefined>;
85
+ /**
86
+ * Adjust finding confidence based on historical FP rates
87
+ */
88
+ export declare function adjustFindingConfidence(finding: DeterministicFinding, metrics: RuleMetrics | undefined): number;
89
+ /**
90
+ * Get metrics for a specific rule
91
+ */
92
+ export declare function getRuleMetrics(projectPath: string, scanner: ScannerType, ruleId: string): Promise<RuleMetrics | undefined>;
93
+ /**
94
+ * Get all scanner metrics
95
+ */
96
+ export declare function getAllMetrics(projectPath: string): Promise<FPTrackingData>;
97
+ /**
98
+ * Get rules with high FP rates
99
+ */
100
+ export declare function getHighFPRules(projectPath: string, threshold?: number, minSampleSize?: number): Promise<RuleMetrics[]>;
101
+ /**
102
+ * Generate FP tracking report
103
+ */
104
+ export declare function generateFPReport(projectPath: string, options?: {
105
+ minSampleSize?: number;
106
+ includeAllRules?: boolean;
107
+ }): Promise<{
108
+ summary: {
109
+ totalScanners: number;
110
+ totalRules: number;
111
+ totalFindings: number;
112
+ overallAccuracy: number;
113
+ highFPRuleCount: number;
114
+ };
115
+ scannerBreakdown: Array<{
116
+ scanner: ScannerType;
117
+ totalFindings: number;
118
+ fpRate: number;
119
+ tpRate: number;
120
+ ruleCount: number;
121
+ }>;
122
+ highFPRules: RuleMetrics[];
123
+ recommendations: string[];
124
+ }>;
125
+ //# sourceMappingURL=fp-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fp-tracker.d.ts","sourceRoot":"","sources":["../../src/scanners/fp-tracker.ts"],"names":[],"mappings":"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"}