@lbroth/rothunter 1.0.0-rc.1

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 (269) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/adapters/llm.d.ts +68 -0
  4. package/dist/adapters/llm.d.ts.map +1 -0
  5. package/dist/adapters/llm.js +189 -0
  6. package/dist/adapters/llm.js.map +1 -0
  7. package/dist/config.d.ts +37 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +81 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/detector-registry.d.ts +32 -0
  12. package/dist/detector-registry.d.ts.map +1 -0
  13. package/dist/detector-registry.js +74 -0
  14. package/dist/detector-registry.js.map +1 -0
  15. package/dist/detectors/api-race.d.ts +6 -0
  16. package/dist/detectors/api-race.d.ts.map +1 -0
  17. package/dist/detectors/api-race.js +222 -0
  18. package/dist/detectors/api-race.js.map +1 -0
  19. package/dist/detectors/bad-config.d.ts +6 -0
  20. package/dist/detectors/bad-config.d.ts.map +1 -0
  21. package/dist/detectors/bad-config.js +529 -0
  22. package/dist/detectors/bad-config.js.map +1 -0
  23. package/dist/detectors/console-log-prod.d.ts +6 -0
  24. package/dist/detectors/console-log-prod.d.ts.map +1 -0
  25. package/dist/detectors/console-log-prod.js +72 -0
  26. package/dist/detectors/console-log-prod.js.map +1 -0
  27. package/dist/detectors/dead-api.d.ts +10 -0
  28. package/dist/detectors/dead-api.d.ts.map +1 -0
  29. package/dist/detectors/dead-api.js +115 -0
  30. package/dist/detectors/dead-api.js.map +1 -0
  31. package/dist/detectors/dead-export.d.ts +12 -0
  32. package/dist/detectors/dead-export.d.ts.map +1 -0
  33. package/dist/detectors/dead-export.js +140 -0
  34. package/dist/detectors/dead-export.js.map +1 -0
  35. package/dist/detectors/dead-handler.d.ts +12 -0
  36. package/dist/detectors/dead-handler.d.ts.map +1 -0
  37. package/dist/detectors/dead-handler.js +40 -0
  38. package/dist/detectors/dead-handler.js.map +1 -0
  39. package/dist/detectors/dead-module.d.ts +14 -0
  40. package/dist/detectors/dead-module.d.ts.map +1 -0
  41. package/dist/detectors/dead-module.js +50 -0
  42. package/dist/detectors/dead-module.js.map +1 -0
  43. package/dist/detectors/deep-nesting.d.ts +12 -0
  44. package/dist/detectors/deep-nesting.d.ts.map +1 -0
  45. package/dist/detectors/deep-nesting.js +133 -0
  46. package/dist/detectors/deep-nesting.js.map +1 -0
  47. package/dist/detectors/duplicate-function.d.ts +9 -0
  48. package/dist/detectors/duplicate-function.d.ts.map +1 -0
  49. package/dist/detectors/duplicate-function.js +199 -0
  50. package/dist/detectors/duplicate-function.js.map +1 -0
  51. package/dist/detectors/duplicate-type.d.ts +9 -0
  52. package/dist/detectors/duplicate-type.d.ts.map +1 -0
  53. package/dist/detectors/duplicate-type.js +166 -0
  54. package/dist/detectors/duplicate-type.js.map +1 -0
  55. package/dist/detectors/hot-hub-file.d.ts +11 -0
  56. package/dist/detectors/hot-hub-file.d.ts.map +1 -0
  57. package/dist/detectors/hot-hub-file.js +42 -0
  58. package/dist/detectors/hot-hub-file.js.map +1 -0
  59. package/dist/detectors/long-file.d.ts +12 -0
  60. package/dist/detectors/long-file.d.ts.map +1 -0
  61. package/dist/detectors/long-file.js +82 -0
  62. package/dist/detectors/long-file.js.map +1 -0
  63. package/dist/detectors/long-function.d.ts +12 -0
  64. package/dist/detectors/long-function.d.ts.map +1 -0
  65. package/dist/detectors/long-function.js +45 -0
  66. package/dist/detectors/long-function.js.map +1 -0
  67. package/dist/detectors/magic-numbers.d.ts +10 -0
  68. package/dist/detectors/magic-numbers.d.ts.map +1 -0
  69. package/dist/detectors/magic-numbers.js +332 -0
  70. package/dist/detectors/magic-numbers.js.map +1 -0
  71. package/dist/detectors/mutable-globals.d.ts +6 -0
  72. package/dist/detectors/mutable-globals.d.ts.map +1 -0
  73. package/dist/detectors/mutable-globals.js +95 -0
  74. package/dist/detectors/mutable-globals.js.map +1 -0
  75. package/dist/detectors/mutation.d.ts +11 -0
  76. package/dist/detectors/mutation.d.ts.map +1 -0
  77. package/dist/detectors/mutation.js +397 -0
  78. package/dist/detectors/mutation.js.map +1 -0
  79. package/dist/detectors/public-any.d.ts +6 -0
  80. package/dist/detectors/public-any.d.ts.map +1 -0
  81. package/dist/detectors/public-any.js +52 -0
  82. package/dist/detectors/public-any.js.map +1 -0
  83. package/dist/detectors/race-condition.d.ts +6 -0
  84. package/dist/detectors/race-condition.d.ts.map +1 -0
  85. package/dist/detectors/race-condition.js +608 -0
  86. package/dist/detectors/race-condition.js.map +1 -0
  87. package/dist/detectors/shared-db-write.d.ts +6 -0
  88. package/dist/detectors/shared-db-write.d.ts.map +1 -0
  89. package/dist/detectors/shared-db-write.js +656 -0
  90. package/dist/detectors/shared-db-write.js.map +1 -0
  91. package/dist/detectors/silent-catch.d.ts +6 -0
  92. package/dist/detectors/silent-catch.d.ts.map +1 -0
  93. package/dist/detectors/silent-catch.js +167 -0
  94. package/dist/detectors/silent-catch.js.map +1 -0
  95. package/dist/detectors/similar-functions.d.ts +15 -0
  96. package/dist/detectors/similar-functions.d.ts.map +1 -0
  97. package/dist/detectors/similar-functions.js +334 -0
  98. package/dist/detectors/similar-functions.js.map +1 -0
  99. package/dist/detectors/skip-tests.d.ts +6 -0
  100. package/dist/detectors/skip-tests.d.ts.map +1 -0
  101. package/dist/detectors/skip-tests.js +69 -0
  102. package/dist/detectors/skip-tests.js.map +1 -0
  103. package/dist/detectors/todo-comments.d.ts +29 -0
  104. package/dist/detectors/todo-comments.d.ts.map +1 -0
  105. package/dist/detectors/todo-comments.js +154 -0
  106. package/dist/detectors/todo-comments.js.map +1 -0
  107. package/dist/detectors/unused-deps.d.ts +8 -0
  108. package/dist/detectors/unused-deps.d.ts.map +1 -0
  109. package/dist/detectors/unused-deps.js +115 -0
  110. package/dist/detectors/unused-deps.js.map +1 -0
  111. package/dist/extraction/api-race-confirmer.d.ts +31 -0
  112. package/dist/extraction/api-race-confirmer.d.ts.map +1 -0
  113. package/dist/extraction/api-race-confirmer.js +110 -0
  114. package/dist/extraction/api-race-confirmer.js.map +1 -0
  115. package/dist/extraction/llm-confirmer.d.ts +25 -0
  116. package/dist/extraction/llm-confirmer.d.ts.map +1 -0
  117. package/dist/extraction/llm-confirmer.js +118 -0
  118. package/dist/extraction/llm-confirmer.js.map +1 -0
  119. package/dist/extraction/mutation-confirmer.d.ts +30 -0
  120. package/dist/extraction/mutation-confirmer.d.ts.map +1 -0
  121. package/dist/extraction/mutation-confirmer.js +73 -0
  122. package/dist/extraction/mutation-confirmer.js.map +1 -0
  123. package/dist/extraction/prompt-chunking.d.ts +37 -0
  124. package/dist/extraction/prompt-chunking.d.ts.map +1 -0
  125. package/dist/extraction/prompt-chunking.js +61 -0
  126. package/dist/extraction/prompt-chunking.js.map +1 -0
  127. package/dist/extraction/race-confirmer.d.ts +28 -0
  128. package/dist/extraction/race-confirmer.d.ts.map +1 -0
  129. package/dist/extraction/race-confirmer.js +68 -0
  130. package/dist/extraction/race-confirmer.js.map +1 -0
  131. package/dist/extraction/shared-db-write-confirmer.d.ts +31 -0
  132. package/dist/extraction/shared-db-write-confirmer.d.ts.map +1 -0
  133. package/dist/extraction/shared-db-write-confirmer.js +141 -0
  134. package/dist/extraction/shared-db-write-confirmer.js.map +1 -0
  135. package/dist/extraction/triage-confirmer.d.ts +59 -0
  136. package/dist/extraction/triage-confirmer.d.ts.map +1 -0
  137. package/dist/extraction/triage-confirmer.js +104 -0
  138. package/dist/extraction/triage-confirmer.js.map +1 -0
  139. package/dist/graph/cfg.d.ts +45 -0
  140. package/dist/graph/cfg.d.ts.map +1 -0
  141. package/dist/graph/cfg.js +198 -0
  142. package/dist/graph/cfg.js.map +1 -0
  143. package/dist/graph/decorator-entries.d.ts +2 -0
  144. package/dist/graph/decorator-entries.d.ts.map +1 -0
  145. package/dist/graph/decorator-entries.js +89 -0
  146. package/dist/graph/decorator-entries.js.map +1 -0
  147. package/dist/graph/entry-points.d.ts +12 -0
  148. package/dist/graph/entry-points.d.ts.map +1 -0
  149. package/dist/graph/entry-points.js +282 -0
  150. package/dist/graph/entry-points.js.map +1 -0
  151. package/dist/graph/handler-conventions.d.ts +2 -0
  152. package/dist/graph/handler-conventions.d.ts.map +1 -0
  153. package/dist/graph/handler-conventions.js +26 -0
  154. package/dist/graph/handler-conventions.js.map +1 -0
  155. package/dist/graph/iac-entries.d.ts +2 -0
  156. package/dist/graph/iac-entries.d.ts.map +1 -0
  157. package/dist/graph/iac-entries.js +123 -0
  158. package/dist/graph/iac-entries.js.map +1 -0
  159. package/dist/graph/import-graph.d.ts +48 -0
  160. package/dist/graph/import-graph.d.ts.map +1 -0
  161. package/dist/graph/import-graph.js +86 -0
  162. package/dist/graph/import-graph.js.map +1 -0
  163. package/dist/graph/monorepo-detect.d.ts +3 -0
  164. package/dist/graph/monorepo-detect.d.ts.map +1 -0
  165. package/dist/graph/monorepo-detect.js +166 -0
  166. package/dist/graph/monorepo-detect.js.map +1 -0
  167. package/dist/graph/tsconfig-paths.d.ts +23 -0
  168. package/dist/graph/tsconfig-paths.d.ts.map +1 -0
  169. package/dist/graph/tsconfig-paths.js +217 -0
  170. package/dist/graph/tsconfig-paths.js.map +1 -0
  171. package/dist/multi-workspace-scanner.d.ts +13 -0
  172. package/dist/multi-workspace-scanner.d.ts.map +1 -0
  173. package/dist/multi-workspace-scanner.js +130 -0
  174. package/dist/multi-workspace-scanner.js.map +1 -0
  175. package/dist/normalizers/type-normalizer.d.ts +16 -0
  176. package/dist/normalizers/type-normalizer.d.ts.map +1 -0
  177. package/dist/normalizers/type-normalizer.js +189 -0
  178. package/dist/normalizers/type-normalizer.js.map +1 -0
  179. package/dist/parsers/typescript-parser.d.ts +57 -0
  180. package/dist/parsers/typescript-parser.d.ts.map +1 -0
  181. package/dist/parsers/typescript-parser.js +502 -0
  182. package/dist/parsers/typescript-parser.js.map +1 -0
  183. package/dist/reporter/json-reporter.d.ts +12 -0
  184. package/dist/reporter/json-reporter.d.ts.map +1 -0
  185. package/dist/reporter/json-reporter.js +28 -0
  186. package/dist/reporter/json-reporter.js.map +1 -0
  187. package/dist/reporter/markdown-reporter.d.ts +11 -0
  188. package/dist/reporter/markdown-reporter.d.ts.map +1 -0
  189. package/dist/reporter/markdown-reporter.js +77 -0
  190. package/dist/reporter/markdown-reporter.js.map +1 -0
  191. package/dist/rothunter.d.ts +125 -0
  192. package/dist/rothunter.d.ts.map +1 -0
  193. package/dist/rothunter.js +1038 -0
  194. package/dist/rothunter.js.map +1 -0
  195. package/dist/server/false-positives.d.ts +34 -0
  196. package/dist/server/false-positives.d.ts.map +1 -0
  197. package/dist/server/false-positives.js +85 -0
  198. package/dist/server/false-positives.js.map +1 -0
  199. package/dist/server/index.d.ts +2 -0
  200. package/dist/server/index.d.ts.map +1 -0
  201. package/dist/server/index.js +1529 -0
  202. package/dist/server/index.js.map +1 -0
  203. package/dist/server/marked-to-fix.d.ts +16 -0
  204. package/dist/server/marked-to-fix.d.ts.map +1 -0
  205. package/dist/server/marked-to-fix.js +36 -0
  206. package/dist/server/marked-to-fix.js.map +1 -0
  207. package/dist/server/scan-store.d.ts +147 -0
  208. package/dist/server/scan-store.d.ts.map +1 -0
  209. package/dist/server/scan-store.js +291 -0
  210. package/dist/server/scan-store.js.map +1 -0
  211. package/dist/server/settings-store.d.ts +28 -0
  212. package/dist/server/settings-store.d.ts.map +1 -0
  213. package/dist/server/settings-store.js +46 -0
  214. package/dist/server/settings-store.js.map +1 -0
  215. package/dist/server/workspace-store.d.ts +39 -0
  216. package/dist/server/workspace-store.d.ts.map +1 -0
  217. package/dist/server/workspace-store.js +108 -0
  218. package/dist/server/workspace-store.js.map +1 -0
  219. package/dist/types/detector-input.d.ts +37 -0
  220. package/dist/types/detector-input.d.ts.map +1 -0
  221. package/dist/types/detector-input.js +2 -0
  222. package/dist/types/detector-input.js.map +1 -0
  223. package/dist/types.d.ts +110 -0
  224. package/dist/types.d.ts.map +1 -0
  225. package/dist/types.js +2 -0
  226. package/dist/types.js.map +1 -0
  227. package/dist/utils/clustering.d.ts +14 -0
  228. package/dist/utils/clustering.d.ts.map +1 -0
  229. package/dist/utils/clustering.js +56 -0
  230. package/dist/utils/clustering.js.map +1 -0
  231. package/dist/utils/gitignore.d.ts +32 -0
  232. package/dist/utils/gitignore.d.ts.map +1 -0
  233. package/dist/utils/gitignore.js +122 -0
  234. package/dist/utils/gitignore.js.map +1 -0
  235. package/dist/utils/hash.d.ts +11 -0
  236. package/dist/utils/hash.d.ts.map +1 -0
  237. package/dist/utils/hash.js +14 -0
  238. package/dist/utils/hash.js.map +1 -0
  239. package/dist/utils/ignore-annotation.d.ts +28 -0
  240. package/dist/utils/ignore-annotation.d.ts.map +1 -0
  241. package/dist/utils/ignore-annotation.js +46 -0
  242. package/dist/utils/ignore-annotation.js.map +1 -0
  243. package/dist/utils/llm-json.d.ts +2 -0
  244. package/dist/utils/llm-json.d.ts.map +1 -0
  245. package/dist/utils/llm-json.js +53 -0
  246. package/dist/utils/llm-json.js.map +1 -0
  247. package/dist/utils/logger.d.ts +3 -0
  248. package/dist/utils/logger.d.ts.map +1 -0
  249. package/dist/utils/logger.js +4 -0
  250. package/dist/utils/logger.js.map +1 -0
  251. package/dist/utils/project-conventions.d.ts +2 -0
  252. package/dist/utils/project-conventions.d.ts.map +1 -0
  253. package/dist/utils/project-conventions.js +108 -0
  254. package/dist/utils/project-conventions.js.map +1 -0
  255. package/dist/utils/regex.d.ts +9 -0
  256. package/dist/utils/regex.d.ts.map +1 -0
  257. package/dist/utils/regex.js +11 -0
  258. package/dist/utils/regex.js.map +1 -0
  259. package/dist/utils/snippet.d.ts +20 -0
  260. package/dist/utils/snippet.d.ts.map +1 -0
  261. package/dist/utils/snippet.js +28 -0
  262. package/dist/utils/snippet.js.map +1 -0
  263. package/dist/utils/source-reader.d.ts +19 -0
  264. package/dist/utils/source-reader.d.ts.map +1 -0
  265. package/dist/utils/source-reader.js +32 -0
  266. package/dist/utils/source-reader.js.map +1 -0
  267. package/logo.png +0 -0
  268. package/package.json +92 -0
  269. package/scripts/start-llm.mjs +161 -0
@@ -0,0 +1,77 @@
1
+ const SEVERITY_ORDER = { high: 3, medium: 2, low: 1 };
2
+ export function renderMarkdownReport(findings, opts) {
3
+ const visible = findings.filter((f) => f.confidence >= opts.minConfidence);
4
+ const hidden = findings.length - visible.length;
5
+ visible.sort((a, b) => {
6
+ const sev = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity];
7
+ if (sev !== 0)
8
+ return sev;
9
+ return b.confidence - a.confidence;
10
+ });
11
+ const lines = [];
12
+ lines.push('# RotHunter audit');
13
+ lines.push('');
14
+ lines.push(`- Workspace: \`${opts.workspaceRoot}\``);
15
+ lines.push(`- Generated: ${opts.generatedAt.toISOString()}`);
16
+ lines.push(`- Symbols scanned: ${opts.symbolCount}`);
17
+ lines.push(`- Duration: ${(opts.durationMs / 1000).toFixed(1)}s`);
18
+ lines.push(`- Findings: ${visible.length} (shown) / ${findings.length} (total)`);
19
+ lines.push(`- Min confidence: ${opts.minConfidence}`);
20
+ if (hidden > 0) {
21
+ lines.push(`- Hidden by confidence threshold: ${hidden}`);
22
+ }
23
+ lines.push('');
24
+ if (visible.length === 0) {
25
+ lines.push('_No findings above the confidence threshold._');
26
+ return lines.join('\n');
27
+ }
28
+ const byDetector = new Map();
29
+ for (const f of visible) {
30
+ const list = byDetector.get(f.detectorId) ?? [];
31
+ list.push(f);
32
+ byDetector.set(f.detectorId, list);
33
+ }
34
+ for (const [detectorId, list] of byDetector) {
35
+ lines.push(`## ${detectorId} (${list.length})`);
36
+ lines.push('');
37
+ for (const f of list) {
38
+ lines.push(`### ${severityIcon(f.severity)} ${f.title}`);
39
+ lines.push('');
40
+ lines.push(`> confidence ${f.confidence.toFixed(2)} · layer ${f.layer} · fingerprint \`${f.fingerprint}\``);
41
+ lines.push('');
42
+ lines.push(f.description);
43
+ lines.push('');
44
+ if (f.evidence.length > 0) {
45
+ lines.push('**Evidence:**');
46
+ lines.push('');
47
+ for (const ev of f.evidence) {
48
+ lines.push(`- \`${ev.file}:${ev.range.startLine}\``);
49
+ lines.push(' ```typescript');
50
+ for (const line of ev.snippet.split('\n')) {
51
+ lines.push(` ${line}`);
52
+ }
53
+ lines.push(' ```');
54
+ }
55
+ lines.push('');
56
+ }
57
+ if (f.suggestion) {
58
+ lines.push(`**Suggestion:** ${f.suggestion}`);
59
+ lines.push('');
60
+ }
61
+ lines.push('---');
62
+ lines.push('');
63
+ }
64
+ }
65
+ return lines.join('\n');
66
+ }
67
+ function severityIcon(s) {
68
+ switch (s) {
69
+ case 'high':
70
+ return '[high]';
71
+ case 'medium':
72
+ return '[med]';
73
+ case 'low':
74
+ return '[low]';
75
+ }
76
+ }
77
+ //# sourceMappingURL=markdown-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-reporter.js","sourceRoot":"","sources":["../../src/reporter/markdown-reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ import { type ParseOptions } from './parsers/typescript-parser.js';
2
+ import type { Finding, SymbolRecord } from './types.js';
3
+ import type { LlmClient } from './adapters/llm.js';
4
+ export interface RotHunterRunOptions extends ParseOptions {
5
+ /** Drop a finding below `severity:'low'` when post-LLM confidence falls under this threshold. */
6
+ llmRejectionThreshold?: number;
7
+ /** Override the LLM client (tests, alternative model pools). Production uses the default LlmClient. */
8
+ llm?: LlmClient;
9
+ /**
10
+ * Optional allow-list of detector ids. When set, findings from detectors
11
+ * outside this list are dropped BEFORE the LLM confirmation pass — the
12
+ * caller will never see them in the report, so the LLM cost is wasted.
13
+ * Mirrors the `--detectors` CLI flag.
14
+ */
15
+ detectorsAllow?: Set<string>;
16
+ /** Optional deny-list of detector ids — mirrors `--no-detectors`. */
17
+ detectorsDeny?: Set<string>;
18
+ /**
19
+ * Number of LLM verdicts in flight at once. 1 = sequential
20
+ * (original behaviour, safe). 4-8 is a good default on llama.cpp run
21
+ * with `--parallel N -cb` (continuous batching) or on vLLM (dynamic
22
+ * batching is on by default).
23
+ *
24
+ * Defaults to `ROTHUNTER_LLM_CONCURRENCY` env var, then 1.
25
+ */
26
+ llmConcurrency?: number;
27
+ /**
28
+ * Confidence floor at which a negative LLM verdict routes a finding
29
+ * into the auto-FP bucket. Defaults to `LLM_FP_THRESHOLD` (0.6) — set
30
+ * lower to be more aggressive (almost every "intentional" LLM call
31
+ * auto-FPs) or higher (only very-confident verdicts route, the rest
32
+ * stay open at degraded confidence).
33
+ */
34
+ llmAutoFpThreshold?: number;
35
+ /**
36
+ * Optional callback invoked at scan checkpoints. Used by the rothunter
37
+ * HTTP server to stream live progress over SSE. Never throws — exceptions
38
+ * inside the callback are caught and logged.
39
+ */
40
+ onProgress?: (event: ScanProgressEvent) => void;
41
+ /**
42
+ * Optional cooperative cancellation. The orchestrator checks
43
+ * `abortSignal.aborted` between LLM verdict tasks and aborts the
44
+ * worker pool when the signal fires. Used by the HTTP server's
45
+ * /api/scans/:scanId/cancel endpoint to free the scan slot promptly
46
+ * instead of relying on the (lossy) "throw inside onProgress" path.
47
+ */
48
+ abortSignal?: AbortSignal;
49
+ }
50
+ export type ScanProgressEvent = {
51
+ state: 'parsing';
52
+ files?: number;
53
+ symbols?: number;
54
+ } | {
55
+ state: 'detecting';
56
+ detector: string;
57
+ } | {
58
+ state: 'llm-start';
59
+ total: number;
60
+ } | {
61
+ state: 'llm-verdict';
62
+ done: number;
63
+ total: number;
64
+ detectorId: string;
65
+ race: boolean;
66
+ confidence: number;
67
+ reason: string;
68
+ latencyMs: number;
69
+ cluster?: string;
70
+ } | {
71
+ state: 'done';
72
+ findings: number;
73
+ durationMs: number;
74
+ };
75
+ export interface RotHunterResult {
76
+ symbols: SymbolRecord[];
77
+ findings: Finding[];
78
+ durationMs: number;
79
+ }
80
+ export declare class RotHunter {
81
+ private parser;
82
+ private normalizer;
83
+ private detectors;
84
+ run(opts: RotHunterRunOptions): Promise<RotHunterResult>;
85
+ private runLlmConfirmation;
86
+ }
87
+ /**
88
+ * Apply a "cluster-style" LLM verdict to a finding. Used for the four
89
+ * detectors whose LLM confirmer returns a positive/negative boolean
90
+ * with a confidence: api-race / shared-db-write / race-condition (race
91
+ * vs safe) and mutation (bug-shaped vs intentional — caller maps
92
+ * `!intentional` to `positive`). Shared body keeps the score/severity/
93
+ * description bookkeeping in one place. Duplicate-type / duplicate-
94
+ * function use a different formula (1 - conf) and stay inline.
95
+ */
96
+ export declare function applyClusterVerdict(finding: Finding, verdict: {
97
+ positive: boolean;
98
+ confidence: number;
99
+ reason: string;
100
+ }, opts: {
101
+ threshold: number;
102
+ positiveLabel: string;
103
+ negativeLabel: string;
104
+ /** Auto-FP routing floor. Defaults to LLM_FP_THRESHOLD (0.6). */
105
+ autoFpThreshold?: number;
106
+ }): void;
107
+ /**
108
+ * Verdict-confidence floor at which a negative LLM verdict moves a
109
+ * finding into the auto-FP bucket. Set low (0.6) so any reasonably
110
+ * confident "intentional / FP" verdict routes the finding out of the
111
+ * open list — the operator's stated preference is "if the LLM says
112
+ * FP, treat it as auto FP, I'll un-mark if it's wrong". Below 0.6 the
113
+ * LLM is genuinely undecided and the deterministic finding stays in
114
+ * the open list at degraded confidence.
115
+ */
116
+ export declare const LLM_FP_THRESHOLD = 0.6;
117
+ /**
118
+ * Build per-detector structural context to attach to a TriageConfirmer
119
+ * call. The shape is free-form text — the LLM reads it alongside the
120
+ * primary evidence snippet — so we can evolve enrichment without
121
+ * version-coupling the triage schema. Returns `undefined` when no
122
+ * useful context is available so the prompt stays compact.
123
+ */
124
+ export declare function buildTriageContext(finding: Finding, symbolById: Map<string, SymbolRecord>, workspaceRoot?: string): string | undefined;
125
+ //# sourceMappingURL=rothunter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rothunter.d.ts","sourceRoot":"","sources":["../src/rothunter.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAOrF,OAAO,KAAK,EAAY,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAKnD,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,iGAAiG;IACjG,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uGAAuG;IACvG,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,qEAAqE;IACrE,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAChD;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAGD,MAAM,MAAM,iBAAiB,GACzB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACjK;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,SAAS,CAGf;IAEI,GAAG,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;YAoOhD,kBAAkB;CAsTjC;AAgMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAClE,IAAI,EAAE;IACJ,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GACA,IAAI,CA2BN;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACrC,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,GAAG,SAAS,CAuBpB"}