@kevinrabun/judges-cli 3.124.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 (1745) hide show
  1. package/README.md +24 -0
  2. package/agents/accessibility.judge.md +44 -0
  3. package/agents/agent-instructions.judge.md +44 -0
  4. package/agents/ai-code-safety.judge.md +55 -0
  5. package/agents/api-contract.judge.md +37 -0
  6. package/agents/api-design.judge.md +55 -0
  7. package/agents/authentication.judge.md +61 -0
  8. package/agents/backwards-compatibility.judge.md +44 -0
  9. package/agents/caching.judge.md +44 -0
  10. package/agents/ci-cd.judge.md +44 -0
  11. package/agents/cloud-readiness.judge.md +51 -0
  12. package/agents/code-structure.judge.md +48 -0
  13. package/agents/compliance.judge.md +47 -0
  14. package/agents/concurrency.judge.md +46 -0
  15. package/agents/configuration-management.judge.md +44 -0
  16. package/agents/cost-effectiveness.judge.md +40 -0
  17. package/agents/cybersecurity.judge.md +61 -0
  18. package/agents/data-security.judge.md +48 -0
  19. package/agents/data-sovereignty.judge.md +58 -0
  20. package/agents/database.judge.md +49 -0
  21. package/agents/dependency-health.judge.md +46 -0
  22. package/agents/documentation.judge.md +53 -0
  23. package/agents/error-handling.judge.md +53 -0
  24. package/agents/ethics-bias.judge.md +46 -0
  25. package/agents/false-positive-review.judge.md +85 -0
  26. package/agents/framework-safety.judge.md +47 -0
  27. package/agents/hallucination-detection.judge.md +46 -0
  28. package/agents/iac-security.judge.md +45 -0
  29. package/agents/intent-alignment.judge.md +44 -0
  30. package/agents/internationalization.judge.md +42 -0
  31. package/agents/logging-privacy.judge.md +44 -0
  32. package/agents/logic-review.judge.md +34 -0
  33. package/agents/maintainability.judge.md +44 -0
  34. package/agents/model-fingerprint.judge.md +31 -0
  35. package/agents/multi-turn-coherence.judge.md +36 -0
  36. package/agents/observability.judge.md +52 -0
  37. package/agents/over-engineering.judge.md +48 -0
  38. package/agents/performance.judge.md +44 -0
  39. package/agents/portability.judge.md +44 -0
  40. package/agents/rate-limiting.judge.md +53 -0
  41. package/agents/reliability.judge.md +55 -0
  42. package/agents/scalability.judge.md +50 -0
  43. package/agents/security.judge.md +62 -0
  44. package/agents/software-practices.judge.md +54 -0
  45. package/agents/testing.judge.md +52 -0
  46. package/agents/ux.judge.md +44 -0
  47. package/bin/judges.js +8 -0
  48. package/dist/a2a-protocol.d.ts +136 -0
  49. package/dist/a2a-protocol.js +218 -0
  50. package/dist/agent-loader.d.ts +107 -0
  51. package/dist/agent-loader.js +260 -0
  52. package/dist/api.d.ts +169 -0
  53. package/dist/api.js +195 -0
  54. package/dist/ast/cross-file-taint.d.ts +42 -0
  55. package/dist/ast/cross-file-taint.js +679 -0
  56. package/dist/ast/index.d.ts +25 -0
  57. package/dist/ast/index.js +148 -0
  58. package/dist/ast/structural-parser.d.ts +2 -0
  59. package/dist/ast/structural-parser.js +756 -0
  60. package/dist/ast/taint-tracker.d.ts +48 -0
  61. package/dist/ast/taint-tracker.js +1033 -0
  62. package/dist/ast/tree-sitter-ast.d.ts +33 -0
  63. package/dist/ast/tree-sitter-ast.js +1164 -0
  64. package/dist/ast/types.d.ts +50 -0
  65. package/dist/ast/types.js +7 -0
  66. package/dist/audit-trail.d.ts +245 -0
  67. package/dist/audit-trail.js +257 -0
  68. package/dist/auto-tune.d.ts +146 -0
  69. package/dist/auto-tune.js +373 -0
  70. package/dist/cache.d.ts +53 -0
  71. package/dist/cache.js +86 -0
  72. package/dist/calibration.d.ts +108 -0
  73. package/dist/calibration.js +219 -0
  74. package/dist/cli-dispatch.d.ts +7 -0
  75. package/dist/cli-dispatch.js +654 -0
  76. package/dist/cli-formatters.d.ts +6 -0
  77. package/dist/cli-formatters.js +186 -0
  78. package/dist/cli-helpers.d.ts +29 -0
  79. package/dist/cli-helpers.js +129 -0
  80. package/dist/cli.d.ts +30 -0
  81. package/dist/cli.js +1487 -0
  82. package/dist/commands/adoption-report.d.ts +7 -0
  83. package/dist/commands/adoption-report.js +218 -0
  84. package/dist/commands/adoption-track.d.ts +4 -0
  85. package/dist/commands/adoption-track.js +246 -0
  86. package/dist/commands/ai-gate.d.ts +7 -0
  87. package/dist/commands/ai-gate.js +212 -0
  88. package/dist/commands/ai-model-trust.d.ts +16 -0
  89. package/dist/commands/ai-model-trust.js +234 -0
  90. package/dist/commands/ai-output-compare.d.ts +8 -0
  91. package/dist/commands/ai-output-compare.js +202 -0
  92. package/dist/commands/ai-pattern-trend.d.ts +8 -0
  93. package/dist/commands/ai-pattern-trend.js +223 -0
  94. package/dist/commands/ai-prompt-audit.d.ts +22 -0
  95. package/dist/commands/ai-prompt-audit.js +254 -0
  96. package/dist/commands/ai-provenance.d.ts +4 -0
  97. package/dist/commands/ai-provenance.js +247 -0
  98. package/dist/commands/api-audit.d.ts +8 -0
  99. package/dist/commands/api-audit.js +359 -0
  100. package/dist/commands/api-misuse.d.ts +4 -0
  101. package/dist/commands/api-misuse.js +260 -0
  102. package/dist/commands/api-versioning-audit.d.ts +5 -0
  103. package/dist/commands/api-versioning-audit.js +233 -0
  104. package/dist/commands/approve-chain.d.ts +7 -0
  105. package/dist/commands/approve-chain.js +234 -0
  106. package/dist/commands/arch-audit.d.ts +8 -0
  107. package/dist/commands/arch-audit.js +283 -0
  108. package/dist/commands/assertion-density.d.ts +4 -0
  109. package/dist/commands/assertion-density.js +263 -0
  110. package/dist/commands/assign-findings.d.ts +36 -0
  111. package/dist/commands/assign-findings.js +177 -0
  112. package/dist/commands/async-safety.d.ts +4 -0
  113. package/dist/commands/async-safety.js +266 -0
  114. package/dist/commands/audit-bundle.d.ts +28 -0
  115. package/dist/commands/audit-bundle.js +234 -0
  116. package/dist/commands/audit-trail.d.ts +17 -0
  117. package/dist/commands/audit-trail.js +154 -0
  118. package/dist/commands/auto-approve.d.ts +4 -0
  119. package/dist/commands/auto-approve.js +188 -0
  120. package/dist/commands/auto-calibrate.d.ts +14 -0
  121. package/dist/commands/auto-calibrate.js +106 -0
  122. package/dist/commands/auto-detect.d.ts +61 -0
  123. package/dist/commands/auto-detect.js +328 -0
  124. package/dist/commands/auto-fix.d.ts +17 -0
  125. package/dist/commands/auto-fix.js +240 -0
  126. package/dist/commands/auto-triage.d.ts +31 -0
  127. package/dist/commands/auto-triage.js +125 -0
  128. package/dist/commands/baseline.d.ts +47 -0
  129. package/dist/commands/baseline.js +353 -0
  130. package/dist/commands/batch-review.d.ts +4 -0
  131. package/dist/commands/batch-review.js +180 -0
  132. package/dist/commands/benchmark-advanced.d.ts +14 -0
  133. package/dist/commands/benchmark-advanced.js +5057 -0
  134. package/dist/commands/benchmark-ai-agents.d.ts +8 -0
  135. package/dist/commands/benchmark-ai-agents.js +4123 -0
  136. package/dist/commands/benchmark-ai-output.d.ts +9 -0
  137. package/dist/commands/benchmark-ai-output.js +365 -0
  138. package/dist/commands/benchmark-compliance-ethics.d.ts +8 -0
  139. package/dist/commands/benchmark-compliance-ethics.js +3060 -0
  140. package/dist/commands/benchmark-expanded-2.d.ts +12 -0
  141. package/dist/commands/benchmark-expanded-2.js +5530 -0
  142. package/dist/commands/benchmark-expanded.d.ts +12 -0
  143. package/dist/commands/benchmark-expanded.js +2599 -0
  144. package/dist/commands/benchmark-infrastructure.d.ts +8 -0
  145. package/dist/commands/benchmark-infrastructure.js +2882 -0
  146. package/dist/commands/benchmark-languages.d.ts +8 -0
  147. package/dist/commands/benchmark-languages.js +1963 -0
  148. package/dist/commands/benchmark-quality-ops.d.ts +8 -0
  149. package/dist/commands/benchmark-quality-ops.js +3415 -0
  150. package/dist/commands/benchmark-security-deep.d.ts +9 -0
  151. package/dist/commands/benchmark-security-deep.js +2335 -0
  152. package/dist/commands/benchmark.d.ts +233 -0
  153. package/dist/commands/benchmark.js +3214 -0
  154. package/dist/commands/blame-review.d.ts +4 -0
  155. package/dist/commands/blame-review.js +266 -0
  156. package/dist/commands/boundary-enforce.d.ts +5 -0
  157. package/dist/commands/boundary-enforce.js +255 -0
  158. package/dist/commands/build-optimize.d.ts +6 -0
  159. package/dist/commands/build-optimize.js +256 -0
  160. package/dist/commands/burndown.d.ts +26 -0
  161. package/dist/commands/burndown.js +179 -0
  162. package/dist/commands/cache-audit.d.ts +4 -0
  163. package/dist/commands/cache-audit.js +219 -0
  164. package/dist/commands/calibration-dashboard.d.ts +1 -0
  165. package/dist/commands/calibration-dashboard.js +294 -0
  166. package/dist/commands/calibration-share.d.ts +30 -0
  167. package/dist/commands/calibration-share.js +182 -0
  168. package/dist/commands/chat-notify.d.ts +8 -0
  169. package/dist/commands/chat-notify.js +258 -0
  170. package/dist/commands/ci-template.d.ts +14 -0
  171. package/dist/commands/ci-template.js +211 -0
  172. package/dist/commands/ci-templates.d.ts +9 -0
  173. package/dist/commands/ci-templates.js +89 -0
  174. package/dist/commands/clarity-score.d.ts +8 -0
  175. package/dist/commands/clarity-score.js +260 -0
  176. package/dist/commands/clone-detect.d.ts +4 -0
  177. package/dist/commands/clone-detect.js +232 -0
  178. package/dist/commands/coach-mode.d.ts +7 -0
  179. package/dist/commands/coach-mode.js +229 -0
  180. package/dist/commands/code-health.d.ts +4 -0
  181. package/dist/commands/code-health.js +195 -0
  182. package/dist/commands/code-owner-suggest.d.ts +16 -0
  183. package/dist/commands/code-owner-suggest.js +214 -0
  184. package/dist/commands/code-similarity.d.ts +8 -0
  185. package/dist/commands/code-similarity.js +231 -0
  186. package/dist/commands/comment-drift.d.ts +4 -0
  187. package/dist/commands/comment-drift.js +228 -0
  188. package/dist/commands/commit-hygiene.d.ts +5 -0
  189. package/dist/commands/commit-hygiene.js +175 -0
  190. package/dist/commands/community-patterns.d.ts +1 -0
  191. package/dist/commands/community-patterns.js +131 -0
  192. package/dist/commands/compare-runs.d.ts +37 -0
  193. package/dist/commands/compare-runs.js +228 -0
  194. package/dist/commands/completion-audit.d.ts +4 -0
  195. package/dist/commands/completion-audit.js +296 -0
  196. package/dist/commands/completions.d.ts +1 -0
  197. package/dist/commands/completions.js +257 -0
  198. package/dist/commands/compliance-map.d.ts +8 -0
  199. package/dist/commands/compliance-map.js +374 -0
  200. package/dist/commands/compliance-report.d.ts +34 -0
  201. package/dist/commands/compliance-report.js +161 -0
  202. package/dist/commands/compliance-weight.d.ts +8 -0
  203. package/dist/commands/compliance-weight.js +272 -0
  204. package/dist/commands/config-drift.d.ts +24 -0
  205. package/dist/commands/config-drift.js +213 -0
  206. package/dist/commands/config-lint.d.ts +4 -0
  207. package/dist/commands/config-lint.js +187 -0
  208. package/dist/commands/config-migrate.d.ts +43 -0
  209. package/dist/commands/config-migrate.js +240 -0
  210. package/dist/commands/config-share.d.ts +95 -0
  211. package/dist/commands/config-share.js +406 -0
  212. package/dist/commands/context-blind.d.ts +4 -0
  213. package/dist/commands/context-blind.js +272 -0
  214. package/dist/commands/context-inject.d.ts +8 -0
  215. package/dist/commands/context-inject.js +211 -0
  216. package/dist/commands/contract-verify.d.ts +4 -0
  217. package/dist/commands/contract-verify.js +316 -0
  218. package/dist/commands/correlate.d.ts +27 -0
  219. package/dist/commands/correlate.js +241 -0
  220. package/dist/commands/cost-forecast.d.ts +18 -0
  221. package/dist/commands/cost-forecast.js +193 -0
  222. package/dist/commands/coverage-map.d.ts +22 -0
  223. package/dist/commands/coverage-map.js +222 -0
  224. package/dist/commands/coverage.d.ts +40 -0
  225. package/dist/commands/coverage.js +147 -0
  226. package/dist/commands/cross-file-consistency.d.ts +4 -0
  227. package/dist/commands/cross-file-consistency.js +254 -0
  228. package/dist/commands/cross-pr-regression.d.ts +8 -0
  229. package/dist/commands/cross-pr-regression.js +297 -0
  230. package/dist/commands/custom-rule.d.ts +4 -0
  231. package/dist/commands/custom-rule.js +210 -0
  232. package/dist/commands/dead-code-detect.d.ts +4 -0
  233. package/dist/commands/dead-code-detect.js +255 -0
  234. package/dist/commands/dedup-report.d.ts +12 -0
  235. package/dist/commands/dedup-report.js +137 -0
  236. package/dist/commands/dep-audit.d.ts +52 -0
  237. package/dist/commands/dep-audit.js +277 -0
  238. package/dist/commands/dep-correlate.d.ts +8 -0
  239. package/dist/commands/dep-correlate.js +207 -0
  240. package/dist/commands/deploy-readiness.d.ts +5 -0
  241. package/dist/commands/deploy-readiness.js +211 -0
  242. package/dist/commands/deprecated.d.ts +47 -0
  243. package/dist/commands/deprecated.js +201 -0
  244. package/dist/commands/deps.d.ts +5 -0
  245. package/dist/commands/deps.js +122 -0
  246. package/dist/commands/design-audit.d.ts +8 -0
  247. package/dist/commands/design-audit.js +301 -0
  248. package/dist/commands/dev-score.d.ts +36 -0
  249. package/dist/commands/dev-score.js +203 -0
  250. package/dist/commands/diff-explain.d.ts +4 -0
  251. package/dist/commands/diff-explain.js +142 -0
  252. package/dist/commands/diff-only.d.ts +33 -0
  253. package/dist/commands/diff-only.js +151 -0
  254. package/dist/commands/diff-review.d.ts +4 -0
  255. package/dist/commands/diff-review.js +190 -0
  256. package/dist/commands/diff.d.ts +6 -0
  257. package/dist/commands/diff.js +449 -0
  258. package/dist/commands/digest.d.ts +19 -0
  259. package/dist/commands/digest.js +221 -0
  260. package/dist/commands/doc-drift.d.ts +8 -0
  261. package/dist/commands/doc-drift.js +258 -0
  262. package/dist/commands/doc-gen.d.ts +7 -0
  263. package/dist/commands/doc-gen.js +208 -0
  264. package/dist/commands/docs.d.ts +1 -0
  265. package/dist/commands/docs.js +156 -0
  266. package/dist/commands/doctor.d.ts +55 -0
  267. package/dist/commands/doctor.js +362 -0
  268. package/dist/commands/encoding-safety.d.ts +4 -0
  269. package/dist/commands/encoding-safety.js +275 -0
  270. package/dist/commands/error-taxonomy.d.ts +5 -0
  271. package/dist/commands/error-taxonomy.js +226 -0
  272. package/dist/commands/error-ux.d.ts +4 -0
  273. package/dist/commands/error-ux.js +252 -0
  274. package/dist/commands/event-leak.d.ts +4 -0
  275. package/dist/commands/event-leak.js +262 -0
  276. package/dist/commands/evidence-chain.d.ts +4 -0
  277. package/dist/commands/evidence-chain.js +309 -0
  278. package/dist/commands/example-leak.d.ts +4 -0
  279. package/dist/commands/example-leak.js +232 -0
  280. package/dist/commands/exception-consistency.d.ts +6 -0
  281. package/dist/commands/exception-consistency.js +192 -0
  282. package/dist/commands/exec-report.d.ts +8 -0
  283. package/dist/commands/exec-report.js +271 -0
  284. package/dist/commands/explain-finding.d.ts +7 -0
  285. package/dist/commands/explain-finding.js +278 -0
  286. package/dist/commands/false-negatives.d.ts +34 -0
  287. package/dist/commands/false-negatives.js +165 -0
  288. package/dist/commands/feedback-rules.d.ts +28 -0
  289. package/dist/commands/feedback-rules.js +173 -0
  290. package/dist/commands/feedback.d.ts +182 -0
  291. package/dist/commands/feedback.js +550 -0
  292. package/dist/commands/finding-age-analysis.d.ts +4 -0
  293. package/dist/commands/finding-age-analysis.js +144 -0
  294. package/dist/commands/finding-age-report.d.ts +4 -0
  295. package/dist/commands/finding-age-report.js +154 -0
  296. package/dist/commands/finding-age-tracker.d.ts +7 -0
  297. package/dist/commands/finding-age-tracker.js +152 -0
  298. package/dist/commands/finding-age.d.ts +4 -0
  299. package/dist/commands/finding-age.js +145 -0
  300. package/dist/commands/finding-ancestry-trace.d.ts +1 -0
  301. package/dist/commands/finding-ancestry-trace.js +69 -0
  302. package/dist/commands/finding-annotation-export.d.ts +1 -0
  303. package/dist/commands/finding-annotation-export.js +97 -0
  304. package/dist/commands/finding-annotation-layer.d.ts +4 -0
  305. package/dist/commands/finding-annotation-layer.js +128 -0
  306. package/dist/commands/finding-auto-categorize.d.ts +1 -0
  307. package/dist/commands/finding-auto-categorize.js +109 -0
  308. package/dist/commands/finding-auto-fix-suggest.d.ts +1 -0
  309. package/dist/commands/finding-auto-fix-suggest.js +76 -0
  310. package/dist/commands/finding-auto-fix.d.ts +4 -0
  311. package/dist/commands/finding-auto-fix.js +188 -0
  312. package/dist/commands/finding-auto-group.d.ts +4 -0
  313. package/dist/commands/finding-auto-group.js +108 -0
  314. package/dist/commands/finding-auto-label.d.ts +4 -0
  315. package/dist/commands/finding-auto-label.js +220 -0
  316. package/dist/commands/finding-auto-priority.d.ts +1 -0
  317. package/dist/commands/finding-auto-priority.js +100 -0
  318. package/dist/commands/finding-auto-suppress.d.ts +4 -0
  319. package/dist/commands/finding-auto-suppress.js +126 -0
  320. package/dist/commands/finding-auto-tag.d.ts +4 -0
  321. package/dist/commands/finding-auto-tag.js +113 -0
  322. package/dist/commands/finding-auto-triage.d.ts +4 -0
  323. package/dist/commands/finding-auto-triage.js +108 -0
  324. package/dist/commands/finding-autofix-preview.d.ts +4 -0
  325. package/dist/commands/finding-autofix-preview.js +86 -0
  326. package/dist/commands/finding-batch-resolve.d.ts +4 -0
  327. package/dist/commands/finding-batch-resolve.js +165 -0
  328. package/dist/commands/finding-batch-suppress.d.ts +4 -0
  329. package/dist/commands/finding-batch-suppress.js +85 -0
  330. package/dist/commands/finding-batch-triage.d.ts +1 -0
  331. package/dist/commands/finding-batch-triage.js +90 -0
  332. package/dist/commands/finding-blast-radius.d.ts +4 -0
  333. package/dist/commands/finding-blast-radius.js +91 -0
  334. package/dist/commands/finding-budget.d.ts +4 -0
  335. package/dist/commands/finding-budget.js +232 -0
  336. package/dist/commands/finding-category-map.d.ts +4 -0
  337. package/dist/commands/finding-category-map.js +103 -0
  338. package/dist/commands/finding-category-stats.d.ts +4 -0
  339. package/dist/commands/finding-category-stats.js +104 -0
  340. package/dist/commands/finding-category.d.ts +4 -0
  341. package/dist/commands/finding-category.js +109 -0
  342. package/dist/commands/finding-change-impact.d.ts +4 -0
  343. package/dist/commands/finding-change-impact.js +107 -0
  344. package/dist/commands/finding-cluster-analysis.d.ts +4 -0
  345. package/dist/commands/finding-cluster-analysis.js +133 -0
  346. package/dist/commands/finding-cluster-group.d.ts +4 -0
  347. package/dist/commands/finding-cluster-group.js +105 -0
  348. package/dist/commands/finding-cluster-summary.d.ts +1 -0
  349. package/dist/commands/finding-cluster-summary.js +85 -0
  350. package/dist/commands/finding-cluster.d.ts +4 -0
  351. package/dist/commands/finding-cluster.js +157 -0
  352. package/dist/commands/finding-code-context.d.ts +4 -0
  353. package/dist/commands/finding-code-context.js +96 -0
  354. package/dist/commands/finding-code-smell.d.ts +4 -0
  355. package/dist/commands/finding-code-smell.js +113 -0
  356. package/dist/commands/finding-compare-runs.d.ts +4 -0
  357. package/dist/commands/finding-compare-runs.js +105 -0
  358. package/dist/commands/finding-compliance-tag.d.ts +1 -0
  359. package/dist/commands/finding-compliance-tag.js +106 -0
  360. package/dist/commands/finding-confidence-boost.d.ts +1 -0
  361. package/dist/commands/finding-confidence-boost.js +88 -0
  362. package/dist/commands/finding-confidence-calibrate.d.ts +4 -0
  363. package/dist/commands/finding-confidence-calibrate.js +111 -0
  364. package/dist/commands/finding-confidence-filter.d.ts +4 -0
  365. package/dist/commands/finding-confidence-filter.js +77 -0
  366. package/dist/commands/finding-contest.d.ts +7 -0
  367. package/dist/commands/finding-contest.js +192 -0
  368. package/dist/commands/finding-context-enrich.d.ts +4 -0
  369. package/dist/commands/finding-context-enrich.js +89 -0
  370. package/dist/commands/finding-context-expand.d.ts +4 -0
  371. package/dist/commands/finding-context-expand.js +102 -0
  372. package/dist/commands/finding-context-link.d.ts +1 -0
  373. package/dist/commands/finding-context-link.js +94 -0
  374. package/dist/commands/finding-context-summary.d.ts +1 -0
  375. package/dist/commands/finding-context-summary.js +85 -0
  376. package/dist/commands/finding-context-window.d.ts +4 -0
  377. package/dist/commands/finding-context-window.js +126 -0
  378. package/dist/commands/finding-context.d.ts +4 -0
  379. package/dist/commands/finding-context.js +140 -0
  380. package/dist/commands/finding-correlate.d.ts +4 -0
  381. package/dist/commands/finding-correlate.js +88 -0
  382. package/dist/commands/finding-correlation-map.d.ts +4 -0
  383. package/dist/commands/finding-correlation-map.js +101 -0
  384. package/dist/commands/finding-correlation.d.ts +4 -0
  385. package/dist/commands/finding-correlation.js +103 -0
  386. package/dist/commands/finding-cross-file-link.d.ts +1 -0
  387. package/dist/commands/finding-cross-file-link.js +101 -0
  388. package/dist/commands/finding-cross-ref.d.ts +4 -0
  389. package/dist/commands/finding-cross-ref.js +98 -0
  390. package/dist/commands/finding-cve-lookup.d.ts +4 -0
  391. package/dist/commands/finding-cve-lookup.js +97 -0
  392. package/dist/commands/finding-cwe-lookup.d.ts +4 -0
  393. package/dist/commands/finding-cwe-lookup.js +148 -0
  394. package/dist/commands/finding-cwe-map.d.ts +4 -0
  395. package/dist/commands/finding-cwe-map.js +133 -0
  396. package/dist/commands/finding-dedup-cross-file.d.ts +4 -0
  397. package/dist/commands/finding-dedup-cross-file.js +95 -0
  398. package/dist/commands/finding-dedup-cross.d.ts +4 -0
  399. package/dist/commands/finding-dedup-cross.js +90 -0
  400. package/dist/commands/finding-dedup-merge.d.ts +1 -0
  401. package/dist/commands/finding-dedup-merge.js +107 -0
  402. package/dist/commands/finding-dedup-report.d.ts +4 -0
  403. package/dist/commands/finding-dedup-report.js +101 -0
  404. package/dist/commands/finding-dedup-smart.d.ts +1 -0
  405. package/dist/commands/finding-dedup-smart.js +109 -0
  406. package/dist/commands/finding-deduplicate.d.ts +4 -0
  407. package/dist/commands/finding-deduplicate.js +141 -0
  408. package/dist/commands/finding-dependency-check.d.ts +4 -0
  409. package/dist/commands/finding-dependency-check.js +119 -0
  410. package/dist/commands/finding-dependency-impact.d.ts +1 -0
  411. package/dist/commands/finding-dependency-impact.js +97 -0
  412. package/dist/commands/finding-dependency-link.d.ts +4 -0
  413. package/dist/commands/finding-dependency-link.js +73 -0
  414. package/dist/commands/finding-dependency-risk.d.ts +4 -0
  415. package/dist/commands/finding-dependency-risk.js +117 -0
  416. package/dist/commands/finding-dependency-tree.d.ts +4 -0
  417. package/dist/commands/finding-dependency-tree.js +116 -0
  418. package/dist/commands/finding-diff-highlight.d.ts +4 -0
  419. package/dist/commands/finding-diff-highlight.js +107 -0
  420. package/dist/commands/finding-dismiss-workflow.d.ts +4 -0
  421. package/dist/commands/finding-dismiss-workflow.js +119 -0
  422. package/dist/commands/finding-duplicate-detect.d.ts +4 -0
  423. package/dist/commands/finding-duplicate-detect.js +113 -0
  424. package/dist/commands/finding-duplicate-rule.d.ts +4 -0
  425. package/dist/commands/finding-duplicate-rule.js +103 -0
  426. package/dist/commands/finding-effort-rank.d.ts +1 -0
  427. package/dist/commands/finding-effort-rank.js +93 -0
  428. package/dist/commands/finding-evidence-chain.d.ts +4 -0
  429. package/dist/commands/finding-evidence-chain.js +147 -0
  430. package/dist/commands/finding-evidence-collect.d.ts +4 -0
  431. package/dist/commands/finding-evidence-collect.js +114 -0
  432. package/dist/commands/finding-explain.d.ts +4 -0
  433. package/dist/commands/finding-explain.js +93 -0
  434. package/dist/commands/finding-export-csv.d.ts +4 -0
  435. package/dist/commands/finding-export-csv.js +78 -0
  436. package/dist/commands/finding-false-neg-check.d.ts +8 -0
  437. package/dist/commands/finding-false-neg-check.js +139 -0
  438. package/dist/commands/finding-false-positive-learn.d.ts +4 -0
  439. package/dist/commands/finding-false-positive-learn.js +85 -0
  440. package/dist/commands/finding-false-positive-log.d.ts +4 -0
  441. package/dist/commands/finding-false-positive-log.js +150 -0
  442. package/dist/commands/finding-false-positive.d.ts +4 -0
  443. package/dist/commands/finding-false-positive.js +134 -0
  444. package/dist/commands/finding-filter-view.d.ts +4 -0
  445. package/dist/commands/finding-filter-view.js +107 -0
  446. package/dist/commands/finding-fix-chain.d.ts +1 -0
  447. package/dist/commands/finding-fix-chain.js +78 -0
  448. package/dist/commands/finding-fix-estimate.d.ts +1 -0
  449. package/dist/commands/finding-fix-estimate.js +95 -0
  450. package/dist/commands/finding-fix-playbook.d.ts +1 -0
  451. package/dist/commands/finding-fix-playbook.js +110 -0
  452. package/dist/commands/finding-fix-priority.d.ts +4 -0
  453. package/dist/commands/finding-fix-priority.js +98 -0
  454. package/dist/commands/finding-fix-rate.d.ts +4 -0
  455. package/dist/commands/finding-fix-rate.js +141 -0
  456. package/dist/commands/finding-fix-suggest.d.ts +4 -0
  457. package/dist/commands/finding-fix-suggest.js +88 -0
  458. package/dist/commands/finding-fix-validation.d.ts +4 -0
  459. package/dist/commands/finding-fix-validation.js +115 -0
  460. package/dist/commands/finding-fix-verify.d.ts +4 -0
  461. package/dist/commands/finding-fix-verify.js +198 -0
  462. package/dist/commands/finding-group-by.d.ts +4 -0
  463. package/dist/commands/finding-group-by.js +86 -0
  464. package/dist/commands/finding-group.d.ts +15 -0
  465. package/dist/commands/finding-group.js +164 -0
  466. package/dist/commands/finding-groupby-file.d.ts +4 -0
  467. package/dist/commands/finding-groupby-file.js +94 -0
  468. package/dist/commands/finding-hotfix-suggest.d.ts +7 -0
  469. package/dist/commands/finding-hotfix-suggest.js +170 -0
  470. package/dist/commands/finding-hotspot-detect.d.ts +1 -0
  471. package/dist/commands/finding-hotspot-detect.js +120 -0
  472. package/dist/commands/finding-hotspot-map.d.ts +4 -0
  473. package/dist/commands/finding-hotspot-map.js +106 -0
  474. package/dist/commands/finding-hotspot.d.ts +4 -0
  475. package/dist/commands/finding-hotspot.js +115 -0
  476. package/dist/commands/finding-impact-radius.d.ts +1 -0
  477. package/dist/commands/finding-impact-radius.js +94 -0
  478. package/dist/commands/finding-impact-rank.d.ts +4 -0
  479. package/dist/commands/finding-impact-rank.js +85 -0
  480. package/dist/commands/finding-impact-score.d.ts +4 -0
  481. package/dist/commands/finding-impact-score.js +123 -0
  482. package/dist/commands/finding-impact.d.ts +4 -0
  483. package/dist/commands/finding-impact.js +135 -0
  484. package/dist/commands/finding-line-blame.d.ts +7 -0
  485. package/dist/commands/finding-line-blame.js +129 -0
  486. package/dist/commands/finding-link-graph.d.ts +4 -0
  487. package/dist/commands/finding-link-graph.js +144 -0
  488. package/dist/commands/finding-link.d.ts +4 -0
  489. package/dist/commands/finding-link.js +128 -0
  490. package/dist/commands/finding-merge-results.d.ts +4 -0
  491. package/dist/commands/finding-merge-results.js +110 -0
  492. package/dist/commands/finding-merge-strategy.d.ts +1 -0
  493. package/dist/commands/finding-merge-strategy.js +84 -0
  494. package/dist/commands/finding-metadata-enrich.d.ts +4 -0
  495. package/dist/commands/finding-metadata-enrich.js +92 -0
  496. package/dist/commands/finding-noise-filter.d.ts +7 -0
  497. package/dist/commands/finding-noise-filter.js +140 -0
  498. package/dist/commands/finding-noise-reduce.d.ts +1 -0
  499. package/dist/commands/finding-noise-reduce.js +81 -0
  500. package/dist/commands/finding-noise-score.d.ts +1 -0
  501. package/dist/commands/finding-noise-score.js +93 -0
  502. package/dist/commands/finding-owner-assign.d.ts +4 -0
  503. package/dist/commands/finding-owner-assign.js +133 -0
  504. package/dist/commands/finding-owner-notify.d.ts +1 -0
  505. package/dist/commands/finding-owner-notify.js +121 -0
  506. package/dist/commands/finding-ownership-assign.d.ts +4 -0
  507. package/dist/commands/finding-ownership-assign.js +101 -0
  508. package/dist/commands/finding-ownership-map.d.ts +4 -0
  509. package/dist/commands/finding-ownership-map.js +118 -0
  510. package/dist/commands/finding-patch-chain.d.ts +1 -0
  511. package/dist/commands/finding-patch-chain.js +90 -0
  512. package/dist/commands/finding-patch-preview.d.ts +4 -0
  513. package/dist/commands/finding-patch-preview.js +103 -0
  514. package/dist/commands/finding-pattern-detect.d.ts +4 -0
  515. package/dist/commands/finding-pattern-detect.js +127 -0
  516. package/dist/commands/finding-pattern-library.d.ts +4 -0
  517. package/dist/commands/finding-pattern-library.js +145 -0
  518. package/dist/commands/finding-pattern-match.d.ts +4 -0
  519. package/dist/commands/finding-pattern-match.js +165 -0
  520. package/dist/commands/finding-prioritize.d.ts +4 -0
  521. package/dist/commands/finding-prioritize.js +119 -0
  522. package/dist/commands/finding-priority-matrix.d.ts +4 -0
  523. package/dist/commands/finding-priority-matrix.js +102 -0
  524. package/dist/commands/finding-priority-queue.d.ts +4 -0
  525. package/dist/commands/finding-priority-queue.js +131 -0
  526. package/dist/commands/finding-priority-rank.d.ts +1 -0
  527. package/dist/commands/finding-priority-rank.js +82 -0
  528. package/dist/commands/finding-quality-gate.d.ts +4 -0
  529. package/dist/commands/finding-quality-gate.js +107 -0
  530. package/dist/commands/finding-rank.d.ts +4 -0
  531. package/dist/commands/finding-rank.js +138 -0
  532. package/dist/commands/finding-reachability-check.d.ts +4 -0
  533. package/dist/commands/finding-reachability-check.js +102 -0
  534. package/dist/commands/finding-reachability.d.ts +4 -0
  535. package/dist/commands/finding-reachability.js +131 -0
  536. package/dist/commands/finding-recurrence-check.d.ts +1 -0
  537. package/dist/commands/finding-recurrence-check.js +103 -0
  538. package/dist/commands/finding-recurrence-detect.d.ts +4 -0
  539. package/dist/commands/finding-recurrence-detect.js +77 -0
  540. package/dist/commands/finding-recurrence.d.ts +4 -0
  541. package/dist/commands/finding-recurrence.js +135 -0
  542. package/dist/commands/finding-regression-check.d.ts +4 -0
  543. package/dist/commands/finding-regression-check.js +112 -0
  544. package/dist/commands/finding-regression-detect.d.ts +1 -0
  545. package/dist/commands/finding-regression-detect.js +86 -0
  546. package/dist/commands/finding-related-rules.d.ts +4 -0
  547. package/dist/commands/finding-related-rules.js +151 -0
  548. package/dist/commands/finding-remediation-cost.d.ts +1 -0
  549. package/dist/commands/finding-remediation-cost.js +79 -0
  550. package/dist/commands/finding-remediation-plan.d.ts +4 -0
  551. package/dist/commands/finding-remediation-plan.js +107 -0
  552. package/dist/commands/finding-reopen-detect.d.ts +1 -0
  553. package/dist/commands/finding-reopen-detect.js +77 -0
  554. package/dist/commands/finding-repeat-detect.d.ts +1 -0
  555. package/dist/commands/finding-repeat-detect.js +92 -0
  556. package/dist/commands/finding-resolution-track.d.ts +4 -0
  557. package/dist/commands/finding-resolution-track.js +150 -0
  558. package/dist/commands/finding-resolution-tracker.d.ts +4 -0
  559. package/dist/commands/finding-resolution-tracker.js +163 -0
  560. package/dist/commands/finding-resolution-workflow.d.ts +1 -0
  561. package/dist/commands/finding-resolution-workflow.js +91 -0
  562. package/dist/commands/finding-resolution.d.ts +4 -0
  563. package/dist/commands/finding-resolution.js +142 -0
  564. package/dist/commands/finding-risk-label.d.ts +1 -0
  565. package/dist/commands/finding-risk-label.js +72 -0
  566. package/dist/commands/finding-risk-matrix.d.ts +4 -0
  567. package/dist/commands/finding-risk-matrix.js +126 -0
  568. package/dist/commands/finding-risk-score.d.ts +4 -0
  569. package/dist/commands/finding-risk-score.js +95 -0
  570. package/dist/commands/finding-root-cause.d.ts +4 -0
  571. package/dist/commands/finding-root-cause.js +184 -0
  572. package/dist/commands/finding-rule-explain.d.ts +4 -0
  573. package/dist/commands/finding-rule-explain.js +140 -0
  574. package/dist/commands/finding-scope-filter.d.ts +1 -0
  575. package/dist/commands/finding-scope-filter.js +77 -0
  576. package/dist/commands/finding-scope-impact.d.ts +1 -0
  577. package/dist/commands/finding-scope-impact.js +83 -0
  578. package/dist/commands/finding-search-index.d.ts +4 -0
  579. package/dist/commands/finding-search-index.js +99 -0
  580. package/dist/commands/finding-security-hotspot.d.ts +4 -0
  581. package/dist/commands/finding-security-hotspot.js +175 -0
  582. package/dist/commands/finding-severity-dist.d.ts +4 -0
  583. package/dist/commands/finding-severity-dist.js +105 -0
  584. package/dist/commands/finding-severity-drift.d.ts +4 -0
  585. package/dist/commands/finding-severity-drift.js +92 -0
  586. package/dist/commands/finding-severity-heatmap.d.ts +4 -0
  587. package/dist/commands/finding-severity-heatmap.js +108 -0
  588. package/dist/commands/finding-severity-histogram.d.ts +4 -0
  589. package/dist/commands/finding-severity-histogram.js +66 -0
  590. package/dist/commands/finding-severity-override.d.ts +4 -0
  591. package/dist/commands/finding-severity-override.js +131 -0
  592. package/dist/commands/finding-severity-rebalance.d.ts +1 -0
  593. package/dist/commands/finding-severity-rebalance.js +108 -0
  594. package/dist/commands/finding-severity-trend.d.ts +4 -0
  595. package/dist/commands/finding-severity-trend.js +127 -0
  596. package/dist/commands/finding-similar-match.d.ts +1 -0
  597. package/dist/commands/finding-similar-match.js +112 -0
  598. package/dist/commands/finding-snippet.d.ts +4 -0
  599. package/dist/commands/finding-snippet.js +102 -0
  600. package/dist/commands/finding-summary-digest.d.ts +7 -0
  601. package/dist/commands/finding-summary-digest.js +145 -0
  602. package/dist/commands/finding-suppress-pattern.d.ts +4 -0
  603. package/dist/commands/finding-suppress-pattern.js +148 -0
  604. package/dist/commands/finding-suppress.d.ts +4 -0
  605. package/dist/commands/finding-suppress.js +164 -0
  606. package/dist/commands/finding-suppression-audit.d.ts +4 -0
  607. package/dist/commands/finding-suppression-audit.js +137 -0
  608. package/dist/commands/finding-suppression-list.d.ts +4 -0
  609. package/dist/commands/finding-suppression-list.js +119 -0
  610. package/dist/commands/finding-suppression-log.d.ts +4 -0
  611. package/dist/commands/finding-suppression-log.js +174 -0
  612. package/dist/commands/finding-time-to-fix.d.ts +1 -0
  613. package/dist/commands/finding-time-to-fix.js +98 -0
  614. package/dist/commands/finding-timeline-view.d.ts +4 -0
  615. package/dist/commands/finding-timeline-view.js +98 -0
  616. package/dist/commands/finding-timeline.d.ts +4 -0
  617. package/dist/commands/finding-timeline.js +143 -0
  618. package/dist/commands/finding-top-offender.d.ts +1 -0
  619. package/dist/commands/finding-top-offender.js +75 -0
  620. package/dist/commands/finding-trace.d.ts +4 -0
  621. package/dist/commands/finding-trace.js +118 -0
  622. package/dist/commands/finding-trend-alert.d.ts +1 -0
  623. package/dist/commands/finding-trend-alert.js +126 -0
  624. package/dist/commands/finding-trend-analysis.d.ts +4 -0
  625. package/dist/commands/finding-trend-analysis.js +95 -0
  626. package/dist/commands/finding-trend-forecast.d.ts +4 -0
  627. package/dist/commands/finding-trend-forecast.js +106 -0
  628. package/dist/commands/finding-trend-report.d.ts +4 -0
  629. package/dist/commands/finding-trend-report.js +107 -0
  630. package/dist/commands/finding-trend.d.ts +4 -0
  631. package/dist/commands/finding-trend.js +118 -0
  632. package/dist/commands/fix-pr.d.ts +22 -0
  633. package/dist/commands/fix-pr.js +286 -0
  634. package/dist/commands/fix-suggest.d.ts +4 -0
  635. package/dist/commands/fix-suggest.js +171 -0
  636. package/dist/commands/fix-verify.d.ts +4 -0
  637. package/dist/commands/fix-verify.js +123 -0
  638. package/dist/commands/fix.d.ts +117 -0
  639. package/dist/commands/fix.js +445 -0
  640. package/dist/commands/focus-area.d.ts +5 -0
  641. package/dist/commands/focus-area.js +192 -0
  642. package/dist/commands/generate.d.ts +7 -0
  643. package/dist/commands/generate.js +403 -0
  644. package/dist/commands/governance.d.ts +31 -0
  645. package/dist/commands/governance.js +202 -0
  646. package/dist/commands/group-findings.d.ts +22 -0
  647. package/dist/commands/group-findings.js +154 -0
  648. package/dist/commands/guided-tour.d.ts +8 -0
  649. package/dist/commands/guided-tour.js +287 -0
  650. package/dist/commands/habit-tracker.d.ts +7 -0
  651. package/dist/commands/habit-tracker.js +194 -0
  652. package/dist/commands/hallucination-detect.d.ts +4 -0
  653. package/dist/commands/hallucination-detect.js +350 -0
  654. package/dist/commands/hallucination-score.d.ts +8 -0
  655. package/dist/commands/hallucination-score.js +316 -0
  656. package/dist/commands/help.d.ts +7 -0
  657. package/dist/commands/help.js +302 -0
  658. package/dist/commands/hook-install.d.ts +21 -0
  659. package/dist/commands/hook-install.js +142 -0
  660. package/dist/commands/hook.d.ts +8 -0
  661. package/dist/commands/hook.js +145 -0
  662. package/dist/commands/iac-lint.d.ts +7 -0
  663. package/dist/commands/iac-lint.js +312 -0
  664. package/dist/commands/idempotency-audit.d.ts +4 -0
  665. package/dist/commands/idempotency-audit.js +222 -0
  666. package/dist/commands/ignore-list.d.ts +18 -0
  667. package/dist/commands/ignore-list.js +152 -0
  668. package/dist/commands/impact-scan.d.ts +8 -0
  669. package/dist/commands/impact-scan.js +281 -0
  670. package/dist/commands/incident-response.d.ts +7 -0
  671. package/dist/commands/incident-response.js +254 -0
  672. package/dist/commands/incremental-review.d.ts +4 -0
  673. package/dist/commands/incremental-review.js +236 -0
  674. package/dist/commands/init.d.ts +10 -0
  675. package/dist/commands/init.js +265 -0
  676. package/dist/commands/input-guard.d.ts +4 -0
  677. package/dist/commands/input-guard.js +255 -0
  678. package/dist/commands/interactive-fix.d.ts +22 -0
  679. package/dist/commands/interactive-fix.js +139 -0
  680. package/dist/commands/judge-author.d.ts +7 -0
  681. package/dist/commands/judge-author.js +260 -0
  682. package/dist/commands/judge-config.d.ts +4 -0
  683. package/dist/commands/judge-config.js +151 -0
  684. package/dist/commands/judge-learn.d.ts +8 -0
  685. package/dist/commands/judge-learn.js +217 -0
  686. package/dist/commands/judge-reputation.d.ts +28 -0
  687. package/dist/commands/judge-reputation.js +198 -0
  688. package/dist/commands/kb.d.ts +40 -0
  689. package/dist/commands/kb.js +228 -0
  690. package/dist/commands/language-packs.d.ts +42 -0
  691. package/dist/commands/language-packs.js +150 -0
  692. package/dist/commands/learn.d.ts +26 -0
  693. package/dist/commands/learn.js +288 -0
  694. package/dist/commands/learning-path.d.ts +8 -0
  695. package/dist/commands/learning-path.js +325 -0
  696. package/dist/commands/license-scan.d.ts +8 -0
  697. package/dist/commands/license-scan.js +183 -0
  698. package/dist/commands/llm-benchmark-optimizer.d.ts +78 -0
  699. package/dist/commands/llm-benchmark-optimizer.js +241 -0
  700. package/dist/commands/llm-benchmark.d.ts +156 -0
  701. package/dist/commands/llm-benchmark.js +670 -0
  702. package/dist/commands/log-quality.d.ts +5 -0
  703. package/dist/commands/log-quality.js +211 -0
  704. package/dist/commands/logic-lint.d.ts +4 -0
  705. package/dist/commands/logic-lint.js +255 -0
  706. package/dist/commands/lsp.d.ts +23 -0
  707. package/dist/commands/lsp.js +285 -0
  708. package/dist/commands/merge-verdict.d.ts +4 -0
  709. package/dist/commands/merge-verdict.js +287 -0
  710. package/dist/commands/metrics-dashboard.d.ts +21 -0
  711. package/dist/commands/metrics-dashboard.js +334 -0
  712. package/dist/commands/metrics.d.ts +57 -0
  713. package/dist/commands/metrics.js +241 -0
  714. package/dist/commands/migration-safety.d.ts +5 -0
  715. package/dist/commands/migration-safety.js +256 -0
  716. package/dist/commands/model-report.d.ts +8 -0
  717. package/dist/commands/model-report.js +194 -0
  718. package/dist/commands/model-risk.d.ts +27 -0
  719. package/dist/commands/model-risk.js +220 -0
  720. package/dist/commands/monorepo.d.ts +37 -0
  721. package/dist/commands/monorepo.js +232 -0
  722. package/dist/commands/multi-lang-review.d.ts +4 -0
  723. package/dist/commands/multi-lang-review.js +230 -0
  724. package/dist/commands/noise-advisor.d.ts +29 -0
  725. package/dist/commands/noise-advisor.js +170 -0
  726. package/dist/commands/notify.d.ts +78 -0
  727. package/dist/commands/notify.js +324 -0
  728. package/dist/commands/null-safety-audit.d.ts +5 -0
  729. package/dist/commands/null-safety-audit.js +221 -0
  730. package/dist/commands/observability-gap.d.ts +5 -0
  731. package/dist/commands/observability-gap.js +211 -0
  732. package/dist/commands/onboard.d.ts +12 -0
  733. package/dist/commands/onboard.js +178 -0
  734. package/dist/commands/org-metrics.d.ts +23 -0
  735. package/dist/commands/org-metrics.js +237 -0
  736. package/dist/commands/org-policy.d.ts +7 -0
  737. package/dist/commands/org-policy.js +207 -0
  738. package/dist/commands/over-abstraction.d.ts +4 -0
  739. package/dist/commands/over-abstraction.js +307 -0
  740. package/dist/commands/override.d.ts +61 -0
  741. package/dist/commands/override.js +268 -0
  742. package/dist/commands/ownership-map.d.ts +5 -0
  743. package/dist/commands/ownership-map.js +217 -0
  744. package/dist/commands/parity.d.ts +30 -0
  745. package/dist/commands/parity.js +212 -0
  746. package/dist/commands/pattern-registry.d.ts +22 -0
  747. package/dist/commands/pattern-registry.js +226 -0
  748. package/dist/commands/perf-compare.d.ts +8 -0
  749. package/dist/commands/perf-compare.js +245 -0
  750. package/dist/commands/perf-hotspot.d.ts +7 -0
  751. package/dist/commands/perf-hotspot.js +273 -0
  752. package/dist/commands/phantom-import.d.ts +4 -0
  753. package/dist/commands/phantom-import.js +260 -0
  754. package/dist/commands/pii-scan.d.ts +7 -0
  755. package/dist/commands/pii-scan.js +299 -0
  756. package/dist/commands/plugin-search.d.ts +39 -0
  757. package/dist/commands/plugin-search.js +327 -0
  758. package/dist/commands/plugins.d.ts +12 -0
  759. package/dist/commands/plugins.js +104 -0
  760. package/dist/commands/policy-audit.d.ts +52 -0
  761. package/dist/commands/policy-audit.js +160 -0
  762. package/dist/commands/pr-quality-gate.d.ts +28 -0
  763. package/dist/commands/pr-quality-gate.js +207 -0
  764. package/dist/commands/pr-summary.d.ts +25 -0
  765. package/dist/commands/pr-summary.js +187 -0
  766. package/dist/commands/predict.d.ts +7 -0
  767. package/dist/commands/predict.js +218 -0
  768. package/dist/commands/privilege-path.d.ts +4 -0
  769. package/dist/commands/privilege-path.js +233 -0
  770. package/dist/commands/profile.d.ts +37 -0
  771. package/dist/commands/profile.js +101 -0
  772. package/dist/commands/prompt-replay.d.ts +7 -0
  773. package/dist/commands/prompt-replay.js +176 -0
  774. package/dist/commands/quality-gate.d.ts +69 -0
  775. package/dist/commands/quality-gate.js +252 -0
  776. package/dist/commands/query.d.ts +19 -0
  777. package/dist/commands/query.js +229 -0
  778. package/dist/commands/quick-check.d.ts +4 -0
  779. package/dist/commands/quick-check.js +173 -0
  780. package/dist/commands/recommend.d.ts +20 -0
  781. package/dist/commands/recommend.js +282 -0
  782. package/dist/commands/refactor-safety.d.ts +8 -0
  783. package/dist/commands/refactor-safety.js +273 -0
  784. package/dist/commands/reg-watch.d.ts +20 -0
  785. package/dist/commands/reg-watch.js +219 -0
  786. package/dist/commands/regression-alert.d.ts +31 -0
  787. package/dist/commands/regression-alert.js +215 -0
  788. package/dist/commands/remediation-lib.d.ts +8 -0
  789. package/dist/commands/remediation-lib.js +265 -0
  790. package/dist/commands/remediation.d.ts +20 -0
  791. package/dist/commands/remediation.js +256 -0
  792. package/dist/commands/report-template.d.ts +16 -0
  793. package/dist/commands/report-template.js +290 -0
  794. package/dist/commands/report.d.ts +12 -0
  795. package/dist/commands/report.js +139 -0
  796. package/dist/commands/resource-cleanup.d.ts +6 -0
  797. package/dist/commands/resource-cleanup.js +235 -0
  798. package/dist/commands/retro.d.ts +22 -0
  799. package/dist/commands/retro.js +211 -0
  800. package/dist/commands/retry-pattern-audit.d.ts +5 -0
  801. package/dist/commands/retry-pattern-audit.js +215 -0
  802. package/dist/commands/review-ab-test.d.ts +4 -0
  803. package/dist/commands/review-ab-test.js +224 -0
  804. package/dist/commands/review-access-log.d.ts +4 -0
  805. package/dist/commands/review-access-log.js +65 -0
  806. package/dist/commands/review-action-item-gen.d.ts +1 -0
  807. package/dist/commands/review-action-item-gen.js +72 -0
  808. package/dist/commands/review-adoption-metrics.d.ts +4 -0
  809. package/dist/commands/review-adoption-metrics.js +95 -0
  810. package/dist/commands/review-adoption-score.d.ts +1 -0
  811. package/dist/commands/review-adoption-score.js +181 -0
  812. package/dist/commands/review-ai-feedback-loop.d.ts +1 -0
  813. package/dist/commands/review-ai-feedback-loop.js +116 -0
  814. package/dist/commands/review-annotate.d.ts +4 -0
  815. package/dist/commands/review-annotate.js +122 -0
  816. package/dist/commands/review-annotation-export.d.ts +4 -0
  817. package/dist/commands/review-annotation-export.js +105 -0
  818. package/dist/commands/review-annotation.d.ts +4 -0
  819. package/dist/commands/review-annotation.js +133 -0
  820. package/dist/commands/review-api-export.d.ts +4 -0
  821. package/dist/commands/review-api-export.js +98 -0
  822. package/dist/commands/review-approval-criteria.d.ts +1 -0
  823. package/dist/commands/review-approval-criteria.js +99 -0
  824. package/dist/commands/review-approval-gate.d.ts +7 -0
  825. package/dist/commands/review-approval-gate.js +190 -0
  826. package/dist/commands/review-approval.d.ts +4 -0
  827. package/dist/commands/review-approval.js +133 -0
  828. package/dist/commands/review-archive-search.d.ts +4 -0
  829. package/dist/commands/review-archive-search.js +70 -0
  830. package/dist/commands/review-archive.d.ts +4 -0
  831. package/dist/commands/review-archive.js +135 -0
  832. package/dist/commands/review-audit-export.d.ts +4 -0
  833. package/dist/commands/review-audit-export.js +93 -0
  834. package/dist/commands/review-audit-log.d.ts +4 -0
  835. package/dist/commands/review-audit-log.js +140 -0
  836. package/dist/commands/review-audit-trail.d.ts +4 -0
  837. package/dist/commands/review-audit-trail.js +96 -0
  838. package/dist/commands/review-auto-merge.d.ts +4 -0
  839. package/dist/commands/review-auto-merge.js +175 -0
  840. package/dist/commands/review-badge.d.ts +4 -0
  841. package/dist/commands/review-badge.js +152 -0
  842. package/dist/commands/review-batch-files.d.ts +4 -0
  843. package/dist/commands/review-batch-files.js +82 -0
  844. package/dist/commands/review-batch-mode.d.ts +4 -0
  845. package/dist/commands/review-batch-mode.js +97 -0
  846. package/dist/commands/review-batch-run.d.ts +4 -0
  847. package/dist/commands/review-batch-run.js +149 -0
  848. package/dist/commands/review-benchmark-self.d.ts +4 -0
  849. package/dist/commands/review-benchmark-self.js +140 -0
  850. package/dist/commands/review-blame-map.d.ts +4 -0
  851. package/dist/commands/review-blame-map.js +100 -0
  852. package/dist/commands/review-branch-compare.d.ts +4 -0
  853. package/dist/commands/review-branch-compare.js +108 -0
  854. package/dist/commands/review-branch-policy.d.ts +4 -0
  855. package/dist/commands/review-branch-policy.js +102 -0
  856. package/dist/commands/review-bulk-action.d.ts +4 -0
  857. package/dist/commands/review-bulk-action.js +109 -0
  858. package/dist/commands/review-bulk-apply.d.ts +4 -0
  859. package/dist/commands/review-bulk-apply.js +102 -0
  860. package/dist/commands/review-cache-clear.d.ts +4 -0
  861. package/dist/commands/review-cache-clear.js +160 -0
  862. package/dist/commands/review-cache-warm.d.ts +4 -0
  863. package/dist/commands/review-cache-warm.js +70 -0
  864. package/dist/commands/review-cache.d.ts +22 -0
  865. package/dist/commands/review-cache.js +134 -0
  866. package/dist/commands/review-changelog-entry.d.ts +7 -0
  867. package/dist/commands/review-changelog-entry.js +109 -0
  868. package/dist/commands/review-changelog-gen.d.ts +4 -0
  869. package/dist/commands/review-changelog-gen.js +117 -0
  870. package/dist/commands/review-changelog-impact.d.ts +1 -0
  871. package/dist/commands/review-changelog-impact.js +89 -0
  872. package/dist/commands/review-checklist.d.ts +4 -0
  873. package/dist/commands/review-checklist.js +144 -0
  874. package/dist/commands/review-checkpoint.d.ts +4 -0
  875. package/dist/commands/review-checkpoint.js +163 -0
  876. package/dist/commands/review-ci-gate.d.ts +4 -0
  877. package/dist/commands/review-ci-gate.js +114 -0
  878. package/dist/commands/review-ci-insight.d.ts +1 -0
  879. package/dist/commands/review-ci-insight.js +100 -0
  880. package/dist/commands/review-ci-integration.d.ts +4 -0
  881. package/dist/commands/review-ci-integration.js +125 -0
  882. package/dist/commands/review-ci-status.d.ts +4 -0
  883. package/dist/commands/review-ci-status.js +200 -0
  884. package/dist/commands/review-cicd-integrate.d.ts +4 -0
  885. package/dist/commands/review-cicd-integrate.js +122 -0
  886. package/dist/commands/review-code-health-score.d.ts +1 -0
  887. package/dist/commands/review-code-health-score.js +100 -0
  888. package/dist/commands/review-code-owner.d.ts +7 -0
  889. package/dist/commands/review-code-owner.js +164 -0
  890. package/dist/commands/review-code-ownership.d.ts +1 -0
  891. package/dist/commands/review-code-ownership.js +88 -0
  892. package/dist/commands/review-comment.d.ts +4 -0
  893. package/dist/commands/review-comment.js +165 -0
  894. package/dist/commands/review-commit-hook.d.ts +7 -0
  895. package/dist/commands/review-commit-hook.js +134 -0
  896. package/dist/commands/review-commit-quality.d.ts +1 -0
  897. package/dist/commands/review-commit-quality.js +94 -0
  898. package/dist/commands/review-comparative.d.ts +4 -0
  899. package/dist/commands/review-comparative.js +149 -0
  900. package/dist/commands/review-compare-version.d.ts +4 -0
  901. package/dist/commands/review-compare-version.js +108 -0
  902. package/dist/commands/review-compare.d.ts +4 -0
  903. package/dist/commands/review-compare.js +200 -0
  904. package/dist/commands/review-compliance-check.d.ts +4 -0
  905. package/dist/commands/review-compliance-check.js +202 -0
  906. package/dist/commands/review-compliance-gate.d.ts +4 -0
  907. package/dist/commands/review-compliance-gate.js +151 -0
  908. package/dist/commands/review-compliance-map.d.ts +4 -0
  909. package/dist/commands/review-compliance-map.js +110 -0
  910. package/dist/commands/review-compliance-report.d.ts +4 -0
  911. package/dist/commands/review-compliance-report.js +127 -0
  912. package/dist/commands/review-confidence-explain.d.ts +1 -0
  913. package/dist/commands/review-confidence-explain.js +99 -0
  914. package/dist/commands/review-config-diff.d.ts +4 -0
  915. package/dist/commands/review-config-diff.js +108 -0
  916. package/dist/commands/review-config-export.d.ts +4 -0
  917. package/dist/commands/review-config-export.js +124 -0
  918. package/dist/commands/review-config-health.d.ts +1 -0
  919. package/dist/commands/review-config-health.js +172 -0
  920. package/dist/commands/review-config-migrate.d.ts +4 -0
  921. package/dist/commands/review-config-migrate.js +123 -0
  922. package/dist/commands/review-config-template.d.ts +4 -0
  923. package/dist/commands/review-config-template.js +112 -0
  924. package/dist/commands/review-config-validate.d.ts +4 -0
  925. package/dist/commands/review-config-validate.js +110 -0
  926. package/dist/commands/review-contract.d.ts +4 -0
  927. package/dist/commands/review-contract.js +199 -0
  928. package/dist/commands/review-coverage-gap.d.ts +4 -0
  929. package/dist/commands/review-coverage-gap.js +120 -0
  930. package/dist/commands/review-coverage-map.d.ts +4 -0
  931. package/dist/commands/review-coverage-map.js +194 -0
  932. package/dist/commands/review-custom-judge-config.d.ts +4 -0
  933. package/dist/commands/review-custom-judge-config.js +103 -0
  934. package/dist/commands/review-custom-judge.d.ts +4 -0
  935. package/dist/commands/review-custom-judge.js +182 -0
  936. package/dist/commands/review-custom-prompt.d.ts +4 -0
  937. package/dist/commands/review-custom-prompt.js +170 -0
  938. package/dist/commands/review-custom-rule.d.ts +4 -0
  939. package/dist/commands/review-custom-rule.js +169 -0
  940. package/dist/commands/review-dashboard-data.d.ts +4 -0
  941. package/dist/commands/review-dashboard-data.js +142 -0
  942. package/dist/commands/review-dashboard.d.ts +4 -0
  943. package/dist/commands/review-dashboard.js +140 -0
  944. package/dist/commands/review-data-retention.d.ts +4 -0
  945. package/dist/commands/review-data-retention.js +119 -0
  946. package/dist/commands/review-dependency-graph.d.ts +4 -0
  947. package/dist/commands/review-dependency-graph.js +94 -0
  948. package/dist/commands/review-dependency-review.d.ts +1 -0
  949. package/dist/commands/review-dependency-review.js +104 -0
  950. package/dist/commands/review-deployment-gate.d.ts +4 -0
  951. package/dist/commands/review-deployment-gate.js +94 -0
  952. package/dist/commands/review-depth.d.ts +4 -0
  953. package/dist/commands/review-depth.js +142 -0
  954. package/dist/commands/review-diff-annotate.d.ts +4 -0
  955. package/dist/commands/review-diff-annotate.js +104 -0
  956. package/dist/commands/review-diff-context.d.ts +4 -0
  957. package/dist/commands/review-diff-context.js +158 -0
  958. package/dist/commands/review-diff-highlight.d.ts +4 -0
  959. package/dist/commands/review-diff-highlight.js +179 -0
  960. package/dist/commands/review-diff-stats.d.ts +4 -0
  961. package/dist/commands/review-diff-stats.js +90 -0
  962. package/dist/commands/review-diff-summary.d.ts +4 -0
  963. package/dist/commands/review-diff-summary.js +154 -0
  964. package/dist/commands/review-digest-gen.d.ts +1 -0
  965. package/dist/commands/review-digest-gen.js +100 -0
  966. package/dist/commands/review-digest.d.ts +4 -0
  967. package/dist/commands/review-digest.js +265 -0
  968. package/dist/commands/review-dry-run.d.ts +4 -0
  969. package/dist/commands/review-dry-run.js +120 -0
  970. package/dist/commands/review-engagement-score.d.ts +1 -0
  971. package/dist/commands/review-engagement-score.js +111 -0
  972. package/dist/commands/review-env-check.d.ts +4 -0
  973. package/dist/commands/review-env-check.js +115 -0
  974. package/dist/commands/review-environment-config.d.ts +4 -0
  975. package/dist/commands/review-environment-config.js +102 -0
  976. package/dist/commands/review-escalation-path.d.ts +1 -0
  977. package/dist/commands/review-escalation-path.js +86 -0
  978. package/dist/commands/review-exclude-vendor.d.ts +4 -0
  979. package/dist/commands/review-exclude-vendor.js +158 -0
  980. package/dist/commands/review-explain.d.ts +5 -0
  981. package/dist/commands/review-explain.js +194 -0
  982. package/dist/commands/review-export-pdf.d.ts +7 -0
  983. package/dist/commands/review-export-pdf.js +131 -0
  984. package/dist/commands/review-export.d.ts +4 -0
  985. package/dist/commands/review-export.js +179 -0
  986. package/dist/commands/review-feedback-loop.d.ts +4 -0
  987. package/dist/commands/review-feedback-loop.js +113 -0
  988. package/dist/commands/review-feedback-summary.d.ts +1 -0
  989. package/dist/commands/review-feedback-summary.js +130 -0
  990. package/dist/commands/review-feedback.d.ts +4 -0
  991. package/dist/commands/review-feedback.js +145 -0
  992. package/dist/commands/review-file-complexity.d.ts +4 -0
  993. package/dist/commands/review-file-complexity.js +137 -0
  994. package/dist/commands/review-file-filter.d.ts +4 -0
  995. package/dist/commands/review-file-filter.js +121 -0
  996. package/dist/commands/review-file-stats.d.ts +4 -0
  997. package/dist/commands/review-file-stats.js +130 -0
  998. package/dist/commands/review-filter.d.ts +4 -0
  999. package/dist/commands/review-filter.js +161 -0
  1000. package/dist/commands/review-finding-link.d.ts +7 -0
  1001. package/dist/commands/review-finding-link.js +115 -0
  1002. package/dist/commands/review-focus-area.d.ts +1 -0
  1003. package/dist/commands/review-focus-area.js +96 -0
  1004. package/dist/commands/review-focus.d.ts +4 -0
  1005. package/dist/commands/review-focus.js +196 -0
  1006. package/dist/commands/review-gate-config.d.ts +4 -0
  1007. package/dist/commands/review-gate-config.js +153 -0
  1008. package/dist/commands/review-gate.d.ts +4 -0
  1009. package/dist/commands/review-gate.js +212 -0
  1010. package/dist/commands/review-goal-track.d.ts +1 -0
  1011. package/dist/commands/review-goal-track.js +123 -0
  1012. package/dist/commands/review-guardrail.d.ts +4 -0
  1013. package/dist/commands/review-guardrail.js +155 -0
  1014. package/dist/commands/review-handoff.d.ts +4 -0
  1015. package/dist/commands/review-handoff.js +208 -0
  1016. package/dist/commands/review-health-check.d.ts +4 -0
  1017. package/dist/commands/review-health-check.js +148 -0
  1018. package/dist/commands/review-health-trend.d.ts +1 -0
  1019. package/dist/commands/review-health-trend.js +107 -0
  1020. package/dist/commands/review-history-compare.d.ts +4 -0
  1021. package/dist/commands/review-history-compare.js +93 -0
  1022. package/dist/commands/review-history-search.d.ts +4 -0
  1023. package/dist/commands/review-history-search.js +214 -0
  1024. package/dist/commands/review-ide-sync.d.ts +4 -0
  1025. package/dist/commands/review-ide-sync.js +91 -0
  1026. package/dist/commands/review-ignore-path.d.ts +4 -0
  1027. package/dist/commands/review-ignore-path.js +147 -0
  1028. package/dist/commands/review-ignore-pattern.d.ts +5 -0
  1029. package/dist/commands/review-ignore-pattern.js +138 -0
  1030. package/dist/commands/review-incident-link.d.ts +4 -0
  1031. package/dist/commands/review-incident-link.js +93 -0
  1032. package/dist/commands/review-incremental.d.ts +4 -0
  1033. package/dist/commands/review-incremental.js +128 -0
  1034. package/dist/commands/review-integration-health.d.ts +4 -0
  1035. package/dist/commands/review-integration-health.js +84 -0
  1036. package/dist/commands/review-integration-test.d.ts +4 -0
  1037. package/dist/commands/review-integration-test.js +145 -0
  1038. package/dist/commands/review-integration.d.ts +4 -0
  1039. package/dist/commands/review-integration.js +236 -0
  1040. package/dist/commands/review-interactive.d.ts +4 -0
  1041. package/dist/commands/review-interactive.js +85 -0
  1042. package/dist/commands/review-knowledge-capture.d.ts +1 -0
  1043. package/dist/commands/review-knowledge-capture.js +94 -0
  1044. package/dist/commands/review-language-profile.d.ts +4 -0
  1045. package/dist/commands/review-language-profile.js +72 -0
  1046. package/dist/commands/review-language-stats.d.ts +4 -0
  1047. package/dist/commands/review-language-stats.js +152 -0
  1048. package/dist/commands/review-lock-file.d.ts +4 -0
  1049. package/dist/commands/review-lock-file.js +153 -0
  1050. package/dist/commands/review-lock.d.ts +4 -0
  1051. package/dist/commands/review-lock.js +107 -0
  1052. package/dist/commands/review-log.d.ts +22 -0
  1053. package/dist/commands/review-log.js +164 -0
  1054. package/dist/commands/review-mentor-suggest.d.ts +1 -0
  1055. package/dist/commands/review-mentor-suggest.js +112 -0
  1056. package/dist/commands/review-merge-check.d.ts +4 -0
  1057. package/dist/commands/review-merge-check.js +101 -0
  1058. package/dist/commands/review-merge-config.d.ts +4 -0
  1059. package/dist/commands/review-merge-config.js +119 -0
  1060. package/dist/commands/review-merge-readiness.d.ts +1 -0
  1061. package/dist/commands/review-merge-readiness.js +90 -0
  1062. package/dist/commands/review-merge-request.d.ts +4 -0
  1063. package/dist/commands/review-merge-request.js +95 -0
  1064. package/dist/commands/review-merge.d.ts +4 -0
  1065. package/dist/commands/review-merge.js +145 -0
  1066. package/dist/commands/review-metric-export.d.ts +4 -0
  1067. package/dist/commands/review-metric-export.js +62 -0
  1068. package/dist/commands/review-milestone.d.ts +4 -0
  1069. package/dist/commands/review-milestone.js +136 -0
  1070. package/dist/commands/review-multi-repo-sync.d.ts +4 -0
  1071. package/dist/commands/review-multi-repo-sync.js +115 -0
  1072. package/dist/commands/review-multi-repo.d.ts +4 -0
  1073. package/dist/commands/review-multi-repo.js +145 -0
  1074. package/dist/commands/review-note.d.ts +4 -0
  1075. package/dist/commands/review-note.js +104 -0
  1076. package/dist/commands/review-notification-config.d.ts +4 -0
  1077. package/dist/commands/review-notification-config.js +122 -0
  1078. package/dist/commands/review-notification-digest.d.ts +4 -0
  1079. package/dist/commands/review-notification-digest.js +64 -0
  1080. package/dist/commands/review-notification.d.ts +4 -0
  1081. package/dist/commands/review-notification.js +126 -0
  1082. package/dist/commands/review-notify.d.ts +4 -0
  1083. package/dist/commands/review-notify.js +143 -0
  1084. package/dist/commands/review-offline.d.ts +4 -0
  1085. package/dist/commands/review-offline.js +125 -0
  1086. package/dist/commands/review-onboard-checklist.d.ts +4 -0
  1087. package/dist/commands/review-onboard-checklist.js +119 -0
  1088. package/dist/commands/review-onboard-wizard.d.ts +4 -0
  1089. package/dist/commands/review-onboard-wizard.js +92 -0
  1090. package/dist/commands/review-onboard.d.ts +4 -0
  1091. package/dist/commands/review-onboard.js +154 -0
  1092. package/dist/commands/review-onboarding-check.d.ts +1 -0
  1093. package/dist/commands/review-onboarding-check.js +93 -0
  1094. package/dist/commands/review-org-dashboard.d.ts +4 -0
  1095. package/dist/commands/review-org-dashboard.js +68 -0
  1096. package/dist/commands/review-output-filter.d.ts +4 -0
  1097. package/dist/commands/review-output-filter.js +112 -0
  1098. package/dist/commands/review-output-format.d.ts +4 -0
  1099. package/dist/commands/review-output-format.js +144 -0
  1100. package/dist/commands/review-output-transform.d.ts +4 -0
  1101. package/dist/commands/review-output-transform.js +119 -0
  1102. package/dist/commands/review-owner.d.ts +4 -0
  1103. package/dist/commands/review-owner.js +129 -0
  1104. package/dist/commands/review-parallel-diff.d.ts +4 -0
  1105. package/dist/commands/review-parallel-diff.js +146 -0
  1106. package/dist/commands/review-parallel-files.d.ts +7 -0
  1107. package/dist/commands/review-parallel-files.js +134 -0
  1108. package/dist/commands/review-parallel-run.d.ts +4 -0
  1109. package/dist/commands/review-parallel-run.js +116 -0
  1110. package/dist/commands/review-parallel.d.ts +4 -0
  1111. package/dist/commands/review-parallel.js +164 -0
  1112. package/dist/commands/review-perf-profile.d.ts +4 -0
  1113. package/dist/commands/review-perf-profile.js +98 -0
  1114. package/dist/commands/review-permission-model.d.ts +4 -0
  1115. package/dist/commands/review-permission-model.js +149 -0
  1116. package/dist/commands/review-pipeline-status.d.ts +4 -0
  1117. package/dist/commands/review-pipeline-status.js +54 -0
  1118. package/dist/commands/review-plugin-config.d.ts +4 -0
  1119. package/dist/commands/review-plugin-config.js +167 -0
  1120. package/dist/commands/review-plugin-list.d.ts +4 -0
  1121. package/dist/commands/review-plugin-list.js +99 -0
  1122. package/dist/commands/review-plugin-manage.d.ts +4 -0
  1123. package/dist/commands/review-plugin-manage.js +137 -0
  1124. package/dist/commands/review-plugin-status.d.ts +4 -0
  1125. package/dist/commands/review-plugin-status.js +53 -0
  1126. package/dist/commands/review-policy-enforce.d.ts +1 -0
  1127. package/dist/commands/review-policy-enforce.js +92 -0
  1128. package/dist/commands/review-policy-engine.d.ts +4 -0
  1129. package/dist/commands/review-policy-engine.js +135 -0
  1130. package/dist/commands/review-pr-comment-gen.d.ts +4 -0
  1131. package/dist/commands/review-pr-comment-gen.js +62 -0
  1132. package/dist/commands/review-pr-comment.d.ts +4 -0
  1133. package/dist/commands/review-pr-comment.js +106 -0
  1134. package/dist/commands/review-pr-label-suggest.d.ts +1 -0
  1135. package/dist/commands/review-pr-label-suggest.js +77 -0
  1136. package/dist/commands/review-pr-size-check.d.ts +1 -0
  1137. package/dist/commands/review-pr-size-check.js +98 -0
  1138. package/dist/commands/review-pr-template.d.ts +4 -0
  1139. package/dist/commands/review-pr-template.js +104 -0
  1140. package/dist/commands/review-preset-save.d.ts +4 -0
  1141. package/dist/commands/review-preset-save.js +159 -0
  1142. package/dist/commands/review-priority.d.ts +4 -0
  1143. package/dist/commands/review-priority.js +157 -0
  1144. package/dist/commands/review-profile.d.ts +4 -0
  1145. package/dist/commands/review-profile.js +168 -0
  1146. package/dist/commands/review-progress-bar.d.ts +4 -0
  1147. package/dist/commands/review-progress-bar.js +157 -0
  1148. package/dist/commands/review-progress-report.d.ts +1 -0
  1149. package/dist/commands/review-progress-report.js +95 -0
  1150. package/dist/commands/review-progress-track.d.ts +4 -0
  1151. package/dist/commands/review-progress-track.js +94 -0
  1152. package/dist/commands/review-quality-baseline.d.ts +1 -0
  1153. package/dist/commands/review-quality-baseline.js +134 -0
  1154. package/dist/commands/review-quality-gate.d.ts +1 -0
  1155. package/dist/commands/review-quality-gate.js +86 -0
  1156. package/dist/commands/review-quality-score.d.ts +4 -0
  1157. package/dist/commands/review-quality-score.js +127 -0
  1158. package/dist/commands/review-quality-trend.d.ts +4 -0
  1159. package/dist/commands/review-quality-trend.js +57 -0
  1160. package/dist/commands/review-queue.d.ts +33 -0
  1161. package/dist/commands/review-queue.js +225 -0
  1162. package/dist/commands/review-quickstart.d.ts +4 -0
  1163. package/dist/commands/review-quickstart.js +107 -0
  1164. package/dist/commands/review-quota-check.d.ts +4 -0
  1165. package/dist/commands/review-quota-check.js +97 -0
  1166. package/dist/commands/review-quota.d.ts +4 -0
  1167. package/dist/commands/review-quota.js +126 -0
  1168. package/dist/commands/review-rate-limit.d.ts +4 -0
  1169. package/dist/commands/review-rate-limit.js +130 -0
  1170. package/dist/commands/review-readiness-check.d.ts +1 -0
  1171. package/dist/commands/review-readiness-check.js +98 -0
  1172. package/dist/commands/review-receipt.d.ts +4 -0
  1173. package/dist/commands/review-receipt.js +220 -0
  1174. package/dist/commands/review-release-gate.d.ts +1 -0
  1175. package/dist/commands/review-release-gate.js +81 -0
  1176. package/dist/commands/review-replay.d.ts +8 -0
  1177. package/dist/commands/review-replay.js +264 -0
  1178. package/dist/commands/review-repo-onboard.d.ts +4 -0
  1179. package/dist/commands/review-repo-onboard.js +114 -0
  1180. package/dist/commands/review-report-archive.d.ts +4 -0
  1181. package/dist/commands/review-report-archive.js +100 -0
  1182. package/dist/commands/review-report-merge.d.ts +4 -0
  1183. package/dist/commands/review-report-merge.js +90 -0
  1184. package/dist/commands/review-report-pdf.d.ts +4 -0
  1185. package/dist/commands/review-report-pdf.js +163 -0
  1186. package/dist/commands/review-report-schedule.d.ts +4 -0
  1187. package/dist/commands/review-report-schedule.js +96 -0
  1188. package/dist/commands/review-retrospective.d.ts +1 -0
  1189. package/dist/commands/review-retrospective.js +118 -0
  1190. package/dist/commands/review-retry.d.ts +4 -0
  1191. package/dist/commands/review-retry.js +91 -0
  1192. package/dist/commands/review-review-cadence.d.ts +1 -0
  1193. package/dist/commands/review-review-cadence.js +85 -0
  1194. package/dist/commands/review-review-comments.d.ts +4 -0
  1195. package/dist/commands/review-review-comments.js +84 -0
  1196. package/dist/commands/review-reviewer-match.d.ts +1 -0
  1197. package/dist/commands/review-reviewer-match.js +108 -0
  1198. package/dist/commands/review-risk-matrix.d.ts +1 -0
  1199. package/dist/commands/review-risk-matrix.js +96 -0
  1200. package/dist/commands/review-risk-score.d.ts +4 -0
  1201. package/dist/commands/review-risk-score.js +156 -0
  1202. package/dist/commands/review-role-assignment.d.ts +4 -0
  1203. package/dist/commands/review-role-assignment.js +98 -0
  1204. package/dist/commands/review-rollback.d.ts +4 -0
  1205. package/dist/commands/review-rollback.js +171 -0
  1206. package/dist/commands/review-rollout-plan.d.ts +4 -0
  1207. package/dist/commands/review-rollout-plan.js +123 -0
  1208. package/dist/commands/review-rule-filter.d.ts +4 -0
  1209. package/dist/commands/review-rule-filter.js +116 -0
  1210. package/dist/commands/review-rule-stats.d.ts +4 -0
  1211. package/dist/commands/review-rule-stats.js +161 -0
  1212. package/dist/commands/review-sandbox.d.ts +4 -0
  1213. package/dist/commands/review-sandbox.js +191 -0
  1214. package/dist/commands/review-schedule.d.ts +4 -0
  1215. package/dist/commands/review-schedule.js +169 -0
  1216. package/dist/commands/review-scope-limit.d.ts +4 -0
  1217. package/dist/commands/review-scope-limit.js +100 -0
  1218. package/dist/commands/review-scope-lock.d.ts +7 -0
  1219. package/dist/commands/review-scope-lock.js +138 -0
  1220. package/dist/commands/review-scope-select.d.ts +4 -0
  1221. package/dist/commands/review-scope-select.js +98 -0
  1222. package/dist/commands/review-scope-suggest.d.ts +1 -0
  1223. package/dist/commands/review-scope-suggest.js +112 -0
  1224. package/dist/commands/review-scope.d.ts +4 -0
  1225. package/dist/commands/review-scope.js +197 -0
  1226. package/dist/commands/review-score-history.d.ts +4 -0
  1227. package/dist/commands/review-score-history.js +137 -0
  1228. package/dist/commands/review-security-posture.d.ts +1 -0
  1229. package/dist/commands/review-security-posture.js +105 -0
  1230. package/dist/commands/review-session-replay.d.ts +4 -0
  1231. package/dist/commands/review-session-replay.js +81 -0
  1232. package/dist/commands/review-session-save.d.ts +4 -0
  1233. package/dist/commands/review-session-save.js +173 -0
  1234. package/dist/commands/review-session.d.ts +4 -0
  1235. package/dist/commands/review-session.js +150 -0
  1236. package/dist/commands/review-skip-list.d.ts +4 -0
  1237. package/dist/commands/review-skip-list.js +135 -0
  1238. package/dist/commands/review-skip-rule.d.ts +4 -0
  1239. package/dist/commands/review-skip-rule.js +105 -0
  1240. package/dist/commands/review-sla-config.d.ts +4 -0
  1241. package/dist/commands/review-sla-config.js +88 -0
  1242. package/dist/commands/review-slack-format.d.ts +4 -0
  1243. package/dist/commands/review-slack-format.js +113 -0
  1244. package/dist/commands/review-snapshot-diff.d.ts +4 -0
  1245. package/dist/commands/review-snapshot-diff.js +100 -0
  1246. package/dist/commands/review-sprint-plan.d.ts +1 -0
  1247. package/dist/commands/review-sprint-plan.js +79 -0
  1248. package/dist/commands/review-stakeholder-notify.d.ts +1 -0
  1249. package/dist/commands/review-stakeholder-notify.js +134 -0
  1250. package/dist/commands/review-stakeholder-report.d.ts +4 -0
  1251. package/dist/commands/review-stakeholder-report.js +75 -0
  1252. package/dist/commands/review-stale-finding-clean.d.ts +1 -0
  1253. package/dist/commands/review-stale-finding-clean.js +81 -0
  1254. package/dist/commands/review-standup.d.ts +4 -0
  1255. package/dist/commands/review-standup.js +95 -0
  1256. package/dist/commands/review-stats.d.ts +4 -0
  1257. package/dist/commands/review-stats.js +175 -0
  1258. package/dist/commands/review-status-badge.d.ts +4 -0
  1259. package/dist/commands/review-status-badge.js +120 -0
  1260. package/dist/commands/review-streak.d.ts +4 -0
  1261. package/dist/commands/review-streak.js +150 -0
  1262. package/dist/commands/review-summary-dashboard.d.ts +4 -0
  1263. package/dist/commands/review-summary-dashboard.js +96 -0
  1264. package/dist/commands/review-summary-email.d.ts +4 -0
  1265. package/dist/commands/review-summary-email.js +102 -0
  1266. package/dist/commands/review-summary.d.ts +4 -0
  1267. package/dist/commands/review-summary.js +174 -0
  1268. package/dist/commands/review-tag-manager.d.ts +4 -0
  1269. package/dist/commands/review-tag-manager.js +128 -0
  1270. package/dist/commands/review-tag.d.ts +4 -0
  1271. package/dist/commands/review-tag.js +136 -0
  1272. package/dist/commands/review-team-analytics.d.ts +1 -0
  1273. package/dist/commands/review-team-analytics.js +94 -0
  1274. package/dist/commands/review-team-assign.d.ts +7 -0
  1275. package/dist/commands/review-team-assign.js +211 -0
  1276. package/dist/commands/review-team-coverage.d.ts +1 -0
  1277. package/dist/commands/review-team-coverage.js +95 -0
  1278. package/dist/commands/review-team-dashboard.d.ts +4 -0
  1279. package/dist/commands/review-team-dashboard.js +98 -0
  1280. package/dist/commands/review-team-rotation.d.ts +1 -0
  1281. package/dist/commands/review-team-rotation.js +99 -0
  1282. package/dist/commands/review-team-skill-map.d.ts +1 -0
  1283. package/dist/commands/review-team-skill-map.js +102 -0
  1284. package/dist/commands/review-team-stats.d.ts +4 -0
  1285. package/dist/commands/review-team-stats.js +97 -0
  1286. package/dist/commands/review-team-summary.d.ts +4 -0
  1287. package/dist/commands/review-team-summary.js +155 -0
  1288. package/dist/commands/review-team-velocity.d.ts +1 -0
  1289. package/dist/commands/review-team-velocity.js +103 -0
  1290. package/dist/commands/review-template-export.d.ts +4 -0
  1291. package/dist/commands/review-template-export.js +146 -0
  1292. package/dist/commands/review-template-library.d.ts +4 -0
  1293. package/dist/commands/review-template-library.js +155 -0
  1294. package/dist/commands/review-template-suggest.d.ts +1 -0
  1295. package/dist/commands/review-template-suggest.js +119 -0
  1296. package/dist/commands/review-template.d.ts +4 -0
  1297. package/dist/commands/review-template.js +212 -0
  1298. package/dist/commands/review-tenant-config.d.ts +4 -0
  1299. package/dist/commands/review-tenant-config.js +116 -0
  1300. package/dist/commands/review-threshold-tune.d.ts +4 -0
  1301. package/dist/commands/review-threshold-tune.js +135 -0
  1302. package/dist/commands/review-timeline.d.ts +4 -0
  1303. package/dist/commands/review-timeline.js +76 -0
  1304. package/dist/commands/review-token-budget.d.ts +4 -0
  1305. package/dist/commands/review-token-budget.js +117 -0
  1306. package/dist/commands/review-velocity-track.d.ts +1 -0
  1307. package/dist/commands/review-velocity-track.js +94 -0
  1308. package/dist/commands/review-watch-mode.d.ts +7 -0
  1309. package/dist/commands/review-watch-mode.js +132 -0
  1310. package/dist/commands/review-webhook-dispatch.d.ts +4 -0
  1311. package/dist/commands/review-webhook-dispatch.js +99 -0
  1312. package/dist/commands/review-webhook-notify.d.ts +4 -0
  1313. package/dist/commands/review-webhook-notify.js +145 -0
  1314. package/dist/commands/review-webhook.d.ts +4 -0
  1315. package/dist/commands/review-webhook.js +140 -0
  1316. package/dist/commands/review-whitelist.d.ts +4 -0
  1317. package/dist/commands/review-whitelist.js +150 -0
  1318. package/dist/commands/review-workflow-suggest.d.ts +1 -0
  1319. package/dist/commands/review-workflow-suggest.js +129 -0
  1320. package/dist/commands/review-workload-balance.d.ts +1 -0
  1321. package/dist/commands/review-workload-balance.js +86 -0
  1322. package/dist/commands/review-workspace-init.d.ts +4 -0
  1323. package/dist/commands/review-workspace-init.js +104 -0
  1324. package/dist/commands/review-workspace-scan.d.ts +4 -0
  1325. package/dist/commands/review-workspace-scan.js +144 -0
  1326. package/dist/commands/review.d.ts +155 -0
  1327. package/dist/commands/review.js +1114 -0
  1328. package/dist/commands/risk-heatmap.d.ts +7 -0
  1329. package/dist/commands/risk-heatmap.js +223 -0
  1330. package/dist/commands/rollback-safety.d.ts +4 -0
  1331. package/dist/commands/rollback-safety.js +191 -0
  1332. package/dist/commands/rule-catalog.d.ts +4 -0
  1333. package/dist/commands/rule-catalog.js +128 -0
  1334. package/dist/commands/rule-metrics.d.ts +43 -0
  1335. package/dist/commands/rule-metrics.js +113 -0
  1336. package/dist/commands/rule-owner.d.ts +30 -0
  1337. package/dist/commands/rule-owner.js +181 -0
  1338. package/dist/commands/rule-share.d.ts +34 -0
  1339. package/dist/commands/rule-share.js +202 -0
  1340. package/dist/commands/rule-test.d.ts +4 -0
  1341. package/dist/commands/rule-test.js +201 -0
  1342. package/dist/commands/rule.d.ts +114 -0
  1343. package/dist/commands/rule.js +295 -0
  1344. package/dist/commands/sbom-export.d.ts +7 -0
  1345. package/dist/commands/sbom-export.js +161 -0
  1346. package/dist/commands/scaffold-plugin.d.ts +15 -0
  1347. package/dist/commands/scaffold-plugin.js +270 -0
  1348. package/dist/commands/secret-age.d.ts +5 -0
  1349. package/dist/commands/secret-age.js +214 -0
  1350. package/dist/commands/secret-scan.d.ts +7 -0
  1351. package/dist/commands/secret-scan.js +244 -0
  1352. package/dist/commands/security-maturity.d.ts +7 -0
  1353. package/dist/commands/security-maturity.js +312 -0
  1354. package/dist/commands/security-theater.d.ts +4 -0
  1355. package/dist/commands/security-theater.js +278 -0
  1356. package/dist/commands/setup-wizard.d.ts +4 -0
  1357. package/dist/commands/setup-wizard.js +174 -0
  1358. package/dist/commands/severity-tune.d.ts +4 -0
  1359. package/dist/commands/severity-tune.js +208 -0
  1360. package/dist/commands/sla-track.d.ts +56 -0
  1361. package/dist/commands/sla-track.js +268 -0
  1362. package/dist/commands/smart-output.d.ts +38 -0
  1363. package/dist/commands/smart-output.js +175 -0
  1364. package/dist/commands/smart-select.d.ts +26 -0
  1365. package/dist/commands/smart-select.js +345 -0
  1366. package/dist/commands/snapshot.d.ts +139 -0
  1367. package/dist/commands/snapshot.js +478 -0
  1368. package/dist/commands/snippet-eval.d.ts +7 -0
  1369. package/dist/commands/snippet-eval.js +223 -0
  1370. package/dist/commands/spec-conform.d.ts +4 -0
  1371. package/dist/commands/spec-conform.js +304 -0
  1372. package/dist/commands/stale-pattern.d.ts +4 -0
  1373. package/dist/commands/stale-pattern.js +293 -0
  1374. package/dist/commands/state-integrity.d.ts +4 -0
  1375. package/dist/commands/state-integrity.js +283 -0
  1376. package/dist/commands/suppress.d.ts +39 -0
  1377. package/dist/commands/suppress.js +203 -0
  1378. package/dist/commands/team-config.d.ts +4 -0
  1379. package/dist/commands/team-config.js +234 -0
  1380. package/dist/commands/team-leaderboard.d.ts +24 -0
  1381. package/dist/commands/team-leaderboard.js +227 -0
  1382. package/dist/commands/team-rules-sync.d.ts +7 -0
  1383. package/dist/commands/team-rules-sync.js +250 -0
  1384. package/dist/commands/team-trust.d.ts +7 -0
  1385. package/dist/commands/team-trust.js +174 -0
  1386. package/dist/commands/test-correlate.d.ts +7 -0
  1387. package/dist/commands/test-correlate.js +221 -0
  1388. package/dist/commands/test-isolation.d.ts +5 -0
  1389. package/dist/commands/test-isolation.js +234 -0
  1390. package/dist/commands/test-quality.d.ts +5 -0
  1391. package/dist/commands/test-quality.js +160 -0
  1392. package/dist/commands/test-suggest.d.ts +8 -0
  1393. package/dist/commands/test-suggest.js +247 -0
  1394. package/dist/commands/ticket-sync.d.ts +25 -0
  1395. package/dist/commands/ticket-sync.js +235 -0
  1396. package/dist/commands/timeout-audit.d.ts +4 -0
  1397. package/dist/commands/timeout-audit.js +210 -0
  1398. package/dist/commands/trace.d.ts +64 -0
  1399. package/dist/commands/trace.js +245 -0
  1400. package/dist/commands/trend-report.d.ts +4 -0
  1401. package/dist/commands/trend-report.js +148 -0
  1402. package/dist/commands/triage.d.ts +15 -0
  1403. package/dist/commands/triage.js +171 -0
  1404. package/dist/commands/trust-adaptive.d.ts +8 -0
  1405. package/dist/commands/trust-adaptive.js +193 -0
  1406. package/dist/commands/trust-ramp.d.ts +29 -0
  1407. package/dist/commands/trust-ramp.js +189 -0
  1408. package/dist/commands/tune.d.ts +24 -0
  1409. package/dist/commands/tune.js +380 -0
  1410. package/dist/commands/type-boundary.d.ts +4 -0
  1411. package/dist/commands/type-boundary.js +235 -0
  1412. package/dist/commands/upload.d.ts +13 -0
  1413. package/dist/commands/upload.js +172 -0
  1414. package/dist/commands/validate-config.d.ts +16 -0
  1415. package/dist/commands/validate-config.js +267 -0
  1416. package/dist/commands/vendor-lock-detect.d.ts +7 -0
  1417. package/dist/commands/vendor-lock-detect.js +288 -0
  1418. package/dist/commands/vote.d.ts +31 -0
  1419. package/dist/commands/vote.js +200 -0
  1420. package/dist/commands/warm-cache.d.ts +30 -0
  1421. package/dist/commands/warm-cache.js +165 -0
  1422. package/dist/commands/watch-judge.d.ts +7 -0
  1423. package/dist/commands/watch-judge.js +179 -0
  1424. package/dist/commands/watch.d.ts +22 -0
  1425. package/dist/commands/watch.js +147 -0
  1426. package/dist/comparison.d.ts +67 -0
  1427. package/dist/comparison.js +253 -0
  1428. package/dist/config.d.ts +108 -0
  1429. package/dist/config.js +694 -0
  1430. package/dist/context/context-snippets.d.ts +15 -0
  1431. package/dist/context/context-snippets.js +36 -0
  1432. package/dist/context/embedding-cache.d.ts +30 -0
  1433. package/dist/context/embedding-cache.js +48 -0
  1434. package/dist/data-adapter.d.ts +123 -0
  1435. package/dist/data-adapter.js +212 -0
  1436. package/dist/dedup.d.ts +105 -0
  1437. package/dist/dedup.js +606 -0
  1438. package/dist/disk-cache.d.ts +59 -0
  1439. package/dist/disk-cache.js +236 -0
  1440. package/dist/errors.d.ts +43 -0
  1441. package/dist/errors.js +63 -0
  1442. package/dist/escalation.d.ts +100 -0
  1443. package/dist/escalation.js +292 -0
  1444. package/dist/evaluation-session.d.ts +74 -0
  1445. package/dist/evaluation-session.js +152 -0
  1446. package/dist/evaluators/accessibility.d.ts +2 -0
  1447. package/dist/evaluators/accessibility.js +559 -0
  1448. package/dist/evaluators/agent-instructions.d.ts +2 -0
  1449. package/dist/evaluators/agent-instructions.js +214 -0
  1450. package/dist/evaluators/ai-code-safety.d.ts +8 -0
  1451. package/dist/evaluators/ai-code-safety.js +410 -0
  1452. package/dist/evaluators/api-contract.d.ts +9 -0
  1453. package/dist/evaluators/api-contract.js +203 -0
  1454. package/dist/evaluators/api-design.d.ts +2 -0
  1455. package/dist/evaluators/api-design.js +260 -0
  1456. package/dist/evaluators/app-builder.d.ts +33 -0
  1457. package/dist/evaluators/app-builder.js +155 -0
  1458. package/dist/evaluators/authentication.d.ts +2 -0
  1459. package/dist/evaluators/authentication.js +455 -0
  1460. package/dist/evaluators/backwards-compatibility.d.ts +2 -0
  1461. package/dist/evaluators/backwards-compatibility.js +168 -0
  1462. package/dist/evaluators/caching.d.ts +2 -0
  1463. package/dist/evaluators/caching.js +171 -0
  1464. package/dist/evaluators/ci-cd.d.ts +2 -0
  1465. package/dist/evaluators/ci-cd.js +218 -0
  1466. package/dist/evaluators/cloud-readiness.d.ts +2 -0
  1467. package/dist/evaluators/cloud-readiness.js +231 -0
  1468. package/dist/evaluators/code-structure.d.ts +21 -0
  1469. package/dist/evaluators/code-structure.js +195 -0
  1470. package/dist/evaluators/compliance.d.ts +2 -0
  1471. package/dist/evaluators/compliance.js +329 -0
  1472. package/dist/evaluators/concurrency.d.ts +2 -0
  1473. package/dist/evaluators/concurrency.js +307 -0
  1474. package/dist/evaluators/configuration-management.d.ts +2 -0
  1475. package/dist/evaluators/configuration-management.js +232 -0
  1476. package/dist/evaluators/cost-effectiveness.d.ts +2 -0
  1477. package/dist/evaluators/cost-effectiveness.js +418 -0
  1478. package/dist/evaluators/cybersecurity.d.ts +2 -0
  1479. package/dist/evaluators/cybersecurity.js +1197 -0
  1480. package/dist/evaluators/data-security.d.ts +2 -0
  1481. package/dist/evaluators/data-security.js +467 -0
  1482. package/dist/evaluators/data-sovereignty.d.ts +2 -0
  1483. package/dist/evaluators/data-sovereignty.js +495 -0
  1484. package/dist/evaluators/database.d.ts +2 -0
  1485. package/dist/evaluators/database.js +240 -0
  1486. package/dist/evaluators/dependencies.d.ts +5 -0
  1487. package/dist/evaluators/dependencies.js +228 -0
  1488. package/dist/evaluators/dependency-health.d.ts +2 -0
  1489. package/dist/evaluators/dependency-health.js +477 -0
  1490. package/dist/evaluators/documentation.d.ts +2 -0
  1491. package/dist/evaluators/documentation.js +432 -0
  1492. package/dist/evaluators/error-handling.d.ts +2 -0
  1493. package/dist/evaluators/error-handling.js +426 -0
  1494. package/dist/evaluators/ethics-bias.d.ts +2 -0
  1495. package/dist/evaluators/ethics-bias.js +263 -0
  1496. package/dist/evaluators/false-positive-review.d.ts +21 -0
  1497. package/dist/evaluators/false-positive-review.js +1246 -0
  1498. package/dist/evaluators/framework-rules.d.ts +58 -0
  1499. package/dist/evaluators/framework-rules.js +291 -0
  1500. package/dist/evaluators/framework-safety.d.ts +12 -0
  1501. package/dist/evaluators/framework-safety.js +1205 -0
  1502. package/dist/evaluators/hallucination-detection.d.ts +2 -0
  1503. package/dist/evaluators/hallucination-detection.js +1250 -0
  1504. package/dist/evaluators/iac-security.d.ts +8 -0
  1505. package/dist/evaluators/iac-security.js +701 -0
  1506. package/dist/evaluators/index.d.ts +167 -0
  1507. package/dist/evaluators/index.js +994 -0
  1508. package/dist/evaluators/intent-alignment.d.ts +18 -0
  1509. package/dist/evaluators/intent-alignment.js +405 -0
  1510. package/dist/evaluators/internationalization.d.ts +2 -0
  1511. package/dist/evaluators/internationalization.js +287 -0
  1512. package/dist/evaluators/judge-selector.d.ts +19 -0
  1513. package/dist/evaluators/judge-selector.js +141 -0
  1514. package/dist/evaluators/logging-privacy.d.ts +2 -0
  1515. package/dist/evaluators/logging-privacy.js +190 -0
  1516. package/dist/evaluators/logic-review.d.ts +2 -0
  1517. package/dist/evaluators/logic-review.js +289 -0
  1518. package/dist/evaluators/maintainability.d.ts +2 -0
  1519. package/dist/evaluators/maintainability.js +430 -0
  1520. package/dist/evaluators/model-fingerprint.d.ts +2 -0
  1521. package/dist/evaluators/model-fingerprint.js +151 -0
  1522. package/dist/evaluators/multi-turn-coherence.d.ts +13 -0
  1523. package/dist/evaluators/multi-turn-coherence.js +149 -0
  1524. package/dist/evaluators/observability.d.ts +2 -0
  1525. package/dist/evaluators/observability.js +238 -0
  1526. package/dist/evaluators/over-engineering.d.ts +2 -0
  1527. package/dist/evaluators/over-engineering.js +160 -0
  1528. package/dist/evaluators/performance.d.ts +2 -0
  1529. package/dist/evaluators/performance.js +649 -0
  1530. package/dist/evaluators/portability.d.ts +2 -0
  1531. package/dist/evaluators/portability.js +254 -0
  1532. package/dist/evaluators/project.d.ts +48 -0
  1533. package/dist/evaluators/project.js +817 -0
  1534. package/dist/evaluators/rate-limiting.d.ts +2 -0
  1535. package/dist/evaluators/rate-limiting.js +193 -0
  1536. package/dist/evaluators/recall-boost.d.ts +27 -0
  1537. package/dist/evaluators/recall-boost.js +409 -0
  1538. package/dist/evaluators/reliability.d.ts +2 -0
  1539. package/dist/evaluators/reliability.js +245 -0
  1540. package/dist/evaluators/scalability.d.ts +2 -0
  1541. package/dist/evaluators/scalability.js +230 -0
  1542. package/dist/evaluators/security.d.ts +12 -0
  1543. package/dist/evaluators/security.js +1013 -0
  1544. package/dist/evaluators/shared.d.ts +219 -0
  1545. package/dist/evaluators/shared.js +1169 -0
  1546. package/dist/evaluators/software-practices.d.ts +2 -0
  1547. package/dist/evaluators/software-practices.js +395 -0
  1548. package/dist/evaluators/suppressions.d.ts +49 -0
  1549. package/dist/evaluators/suppressions.js +185 -0
  1550. package/dist/evaluators/testing.d.ts +2 -0
  1551. package/dist/evaluators/testing.js +348 -0
  1552. package/dist/evaluators/ux.d.ts +2 -0
  1553. package/dist/evaluators/ux.js +309 -0
  1554. package/dist/evaluators/v2.d.ts +26 -0
  1555. package/dist/evaluators/v2.js +354 -0
  1556. package/dist/ext-to-lang.d.ts +16 -0
  1557. package/dist/ext-to-lang.js +60 -0
  1558. package/dist/feedback-loop.d.ts +62 -0
  1559. package/dist/feedback-loop.js +179 -0
  1560. package/dist/finding-lifecycle.d.ts +215 -0
  1561. package/dist/finding-lifecycle.js +547 -0
  1562. package/dist/fingerprint.d.ts +39 -0
  1563. package/dist/fingerprint.js +179 -0
  1564. package/dist/fix-history.d.ts +103 -0
  1565. package/dist/fix-history.js +164 -0
  1566. package/dist/formatters/badge.d.ts +16 -0
  1567. package/dist/formatters/badge.js +78 -0
  1568. package/dist/formatters/codeclimate.d.ts +24 -0
  1569. package/dist/formatters/codeclimate.js +80 -0
  1570. package/dist/formatters/csv.d.ts +16 -0
  1571. package/dist/formatters/csv.js +53 -0
  1572. package/dist/formatters/diagnostics.d.ts +81 -0
  1573. package/dist/formatters/diagnostics.js +152 -0
  1574. package/dist/formatters/github-actions.d.ts +6 -0
  1575. package/dist/formatters/github-actions.js +68 -0
  1576. package/dist/formatters/html.d.ts +12 -0
  1577. package/dist/formatters/html.js +194 -0
  1578. package/dist/formatters/junit.d.ts +6 -0
  1579. package/dist/formatters/junit.js +68 -0
  1580. package/dist/formatters/pdf.d.ts +12 -0
  1581. package/dist/formatters/pdf.js +114 -0
  1582. package/dist/formatters/sarif.d.ts +92 -0
  1583. package/dist/formatters/sarif.js +256 -0
  1584. package/dist/formatters/shared.d.ts +4 -0
  1585. package/dist/formatters/shared.js +29 -0
  1586. package/dist/git-diff.d.ts +62 -0
  1587. package/dist/git-diff.js +282 -0
  1588. package/dist/github-app.d.ts +152 -0
  1589. package/dist/github-app.js +716 -0
  1590. package/dist/import-resolver.d.ts +51 -0
  1591. package/dist/import-resolver.js +213 -0
  1592. package/dist/index.d.ts +4 -0
  1593. package/dist/index.js +38 -0
  1594. package/dist/judge-registry.d.ts +156 -0
  1595. package/dist/judge-registry.js +272 -0
  1596. package/dist/judges/accessibility.d.ts +2 -0
  1597. package/dist/judges/accessibility.js +46 -0
  1598. package/dist/judges/agent-instructions.d.ts +2 -0
  1599. package/dist/judges/agent-instructions.js +46 -0
  1600. package/dist/judges/ai-code-safety.d.ts +2 -0
  1601. package/dist/judges/ai-code-safety.js +57 -0
  1602. package/dist/judges/api-contract.d.ts +2 -0
  1603. package/dist/judges/api-contract.js +40 -0
  1604. package/dist/judges/api-design.d.ts +2 -0
  1605. package/dist/judges/api-design.js +57 -0
  1606. package/dist/judges/authentication.d.ts +2 -0
  1607. package/dist/judges/authentication.js +63 -0
  1608. package/dist/judges/backwards-compatibility.d.ts +2 -0
  1609. package/dist/judges/backwards-compatibility.js +46 -0
  1610. package/dist/judges/caching.d.ts +2 -0
  1611. package/dist/judges/caching.js +46 -0
  1612. package/dist/judges/ci-cd.d.ts +2 -0
  1613. package/dist/judges/ci-cd.js +46 -0
  1614. package/dist/judges/cloud-readiness.d.ts +2 -0
  1615. package/dist/judges/cloud-readiness.js +53 -0
  1616. package/dist/judges/code-structure.d.ts +2 -0
  1617. package/dist/judges/code-structure.js +50 -0
  1618. package/dist/judges/compliance.d.ts +2 -0
  1619. package/dist/judges/compliance.js +49 -0
  1620. package/dist/judges/concurrency.d.ts +2 -0
  1621. package/dist/judges/concurrency.js +48 -0
  1622. package/dist/judges/configuration-management.d.ts +2 -0
  1623. package/dist/judges/configuration-management.js +46 -0
  1624. package/dist/judges/cost-effectiveness.d.ts +2 -0
  1625. package/dist/judges/cost-effectiveness.js +42 -0
  1626. package/dist/judges/cybersecurity.d.ts +2 -0
  1627. package/dist/judges/cybersecurity.js +63 -0
  1628. package/dist/judges/data-security.d.ts +2 -0
  1629. package/dist/judges/data-security.js +50 -0
  1630. package/dist/judges/data-sovereignty.d.ts +2 -0
  1631. package/dist/judges/data-sovereignty.js +60 -0
  1632. package/dist/judges/database.d.ts +2 -0
  1633. package/dist/judges/database.js +51 -0
  1634. package/dist/judges/dependency-health.d.ts +2 -0
  1635. package/dist/judges/dependency-health.js +48 -0
  1636. package/dist/judges/documentation.d.ts +2 -0
  1637. package/dist/judges/documentation.js +55 -0
  1638. package/dist/judges/error-handling.d.ts +2 -0
  1639. package/dist/judges/error-handling.js +55 -0
  1640. package/dist/judges/ethics-bias.d.ts +2 -0
  1641. package/dist/judges/ethics-bias.js +48 -0
  1642. package/dist/judges/false-positive-review.d.ts +2 -0
  1643. package/dist/judges/false-positive-review.js +85 -0
  1644. package/dist/judges/framework-safety.d.ts +2 -0
  1645. package/dist/judges/framework-safety.js +49 -0
  1646. package/dist/judges/hallucination-detection.d.ts +2 -0
  1647. package/dist/judges/hallucination-detection.js +48 -0
  1648. package/dist/judges/iac-security.d.ts +2 -0
  1649. package/dist/judges/iac-security.js +47 -0
  1650. package/dist/judges/index.d.ts +88 -0
  1651. package/dist/judges/index.js +128 -0
  1652. package/dist/judges/intent-alignment.d.ts +2 -0
  1653. package/dist/judges/intent-alignment.js +46 -0
  1654. package/dist/judges/internationalization.d.ts +2 -0
  1655. package/dist/judges/internationalization.js +44 -0
  1656. package/dist/judges/logging-privacy.d.ts +2 -0
  1657. package/dist/judges/logging-privacy.js +46 -0
  1658. package/dist/judges/logic-review.d.ts +2 -0
  1659. package/dist/judges/logic-review.js +36 -0
  1660. package/dist/judges/maintainability.d.ts +2 -0
  1661. package/dist/judges/maintainability.js +46 -0
  1662. package/dist/judges/model-fingerprint.d.ts +2 -0
  1663. package/dist/judges/model-fingerprint.js +35 -0
  1664. package/dist/judges/multi-turn-coherence.d.ts +2 -0
  1665. package/dist/judges/multi-turn-coherence.js +39 -0
  1666. package/dist/judges/observability.d.ts +2 -0
  1667. package/dist/judges/observability.js +54 -0
  1668. package/dist/judges/over-engineering.d.ts +2 -0
  1669. package/dist/judges/over-engineering.js +50 -0
  1670. package/dist/judges/performance.d.ts +2 -0
  1671. package/dist/judges/performance.js +46 -0
  1672. package/dist/judges/portability.d.ts +2 -0
  1673. package/dist/judges/portability.js +46 -0
  1674. package/dist/judges/rate-limiting.d.ts +2 -0
  1675. package/dist/judges/rate-limiting.js +55 -0
  1676. package/dist/judges/reliability.d.ts +2 -0
  1677. package/dist/judges/reliability.js +57 -0
  1678. package/dist/judges/scalability.d.ts +2 -0
  1679. package/dist/judges/scalability.js +52 -0
  1680. package/dist/judges/security.d.ts +2 -0
  1681. package/dist/judges/security.js +64 -0
  1682. package/dist/judges/software-practices.d.ts +2 -0
  1683. package/dist/judges/software-practices.js +56 -0
  1684. package/dist/judges/testing.d.ts +2 -0
  1685. package/dist/judges/testing.js +54 -0
  1686. package/dist/judges/ux.d.ts +2 -0
  1687. package/dist/judges/ux.js +46 -0
  1688. package/dist/language-patterns.d.ts +653 -0
  1689. package/dist/language-patterns.js +851 -0
  1690. package/dist/parallel.d.ts +52 -0
  1691. package/dist/parallel.js +157 -0
  1692. package/dist/patches/apply.d.ts +15 -0
  1693. package/dist/patches/apply.js +37 -0
  1694. package/dist/patches/index.d.ts +9 -0
  1695. package/dist/patches/index.js +2544 -0
  1696. package/dist/plugins.d.ts +59 -0
  1697. package/dist/plugins.js +76 -0
  1698. package/dist/presets.d.ts +35 -0
  1699. package/dist/presets.js +406 -0
  1700. package/dist/probabilistic/llm-response-validator.d.ts +26 -0
  1701. package/dist/probabilistic/llm-response-validator.js +122 -0
  1702. package/dist/reports/public-repo-report.d.ts +42 -0
  1703. package/dist/reports/public-repo-report.js +579 -0
  1704. package/dist/review-conversation.d.ts +87 -0
  1705. package/dist/review-conversation.js +307 -0
  1706. package/dist/sast-integration.d.ts +112 -0
  1707. package/dist/sast-integration.js +215 -0
  1708. package/dist/scoring.d.ts +36 -0
  1709. package/dist/scoring.js +437 -0
  1710. package/dist/security-ids.d.ts +23 -0
  1711. package/dist/security-ids.js +239 -0
  1712. package/dist/skill-loader.d.ts +33 -0
  1713. package/dist/skill-loader.js +167 -0
  1714. package/dist/tools/command-safety.d.ts +13 -0
  1715. package/dist/tools/command-safety.js +95 -0
  1716. package/dist/tools/deep-review.d.ts +38 -0
  1717. package/dist/tools/deep-review.js +302 -0
  1718. package/dist/tools/prompts.d.ts +27 -0
  1719. package/dist/tools/prompts.js +122 -0
  1720. package/dist/tools/register-evaluation.d.ts +6 -0
  1721. package/dist/tools/register-evaluation.js +587 -0
  1722. package/dist/tools/register-fix.d.ts +5 -0
  1723. package/dist/tools/register-fix.js +175 -0
  1724. package/dist/tools/register-resources.d.ts +6 -0
  1725. package/dist/tools/register-resources.js +177 -0
  1726. package/dist/tools/register-review.d.ts +6 -0
  1727. package/dist/tools/register-review.js +564 -0
  1728. package/dist/tools/register-scaffold.d.ts +2 -0
  1729. package/dist/tools/register-scaffold.js +398 -0
  1730. package/dist/tools/register-workflow.d.ts +6 -0
  1731. package/dist/tools/register-workflow.js +1037 -0
  1732. package/dist/tools/register-workspace.d.ts +2 -0
  1733. package/dist/tools/register-workspace.js +214 -0
  1734. package/dist/tools/register.d.ts +6 -0
  1735. package/dist/tools/register.js +21 -0
  1736. package/dist/tools/schemas.d.ts +25 -0
  1737. package/dist/tools/schemas.js +41 -0
  1738. package/dist/tools/validation.d.ts +13 -0
  1739. package/dist/tools/validation.js +77 -0
  1740. package/dist/types.d.ts +898 -0
  1741. package/dist/types.js +1 -0
  1742. package/package.json +54 -0
  1743. package/skills/ai-code-review.skill.md +57 -0
  1744. package/skills/release-gate.skill.md +27 -0
  1745. package/skills/security-review.skill.md +32 -0
@@ -0,0 +1,3214 @@
1
+ /**
2
+ * `judges benchmark` — Benchmark suite for measuring detection accuracy.
3
+ *
4
+ * Runs judges against curated test cases with known vulnerabilities
5
+ * to compute precision, recall, F1 scores, and detection rates.
6
+ *
7
+ * Usage:
8
+ * judges benchmark run # Run full benchmark suite
9
+ * judges benchmark run --judge cyber # Benchmark a single judge
10
+ * judges benchmark report # Generate benchmark report
11
+ * judges benchmark compare <a> <b> # Compare two benchmark results
12
+ */
13
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
14
+ import { resolve, dirname } from "path";
15
+ import { evaluateWithTribunal, evaluateWithJudge } from "../evaluators/index.js";
16
+ import { getJudge, JUDGES } from "../judges/index.js";
17
+ import { formatLlmSnapshotMarkdown, formatLayerComparisonMarkdown } from "./llm-benchmark.js";
18
+ import { EXPANDED_BENCHMARK_CASES } from "./benchmark-expanded.js";
19
+ import { EXPANDED_BENCHMARK_CASES_2 } from "./benchmark-expanded-2.js";
20
+ import { BENCHMARK_SECURITY_DEEP } from "./benchmark-security-deep.js";
21
+ import { BENCHMARK_QUALITY_OPS } from "./benchmark-quality-ops.js";
22
+ import { BENCHMARK_LANGUAGES } from "./benchmark-languages.js";
23
+ import { BENCHMARK_INFRASTRUCTURE } from "./benchmark-infrastructure.js";
24
+ import { BENCHMARK_COMPLIANCE_ETHICS } from "./benchmark-compliance-ethics.js";
25
+ import { BENCHMARK_AI_AGENTS } from "./benchmark-ai-agents.js";
26
+ import { BENCHMARK_ADVANCED_CASES } from "./benchmark-advanced.js";
27
+ import { BENCHMARK_AI_OUTPUT } from "./benchmark-ai-output.js";
28
+ // ─── Built-in Benchmark Cases ───────────────────────────────────────────────
29
+ export const BENCHMARK_CASES = [
30
+ // ── SQL Injection ──
31
+ {
32
+ id: "sql-injection-basic",
33
+ description: "Basic SQL injection via string concatenation",
34
+ language: "typescript",
35
+ code: `import express from "express";
36
+ const app = express();
37
+ app.get("/users", (req, res) => {
38
+ const query = "SELECT * FROM users WHERE id = " + req.query.id;
39
+ db.query(query);
40
+ res.send("ok");
41
+ });`,
42
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "CYBER-003", "SEC-001"],
43
+ category: "injection",
44
+ difficulty: "easy",
45
+ },
46
+ {
47
+ id: "sql-injection-template",
48
+ description: "SQL injection via template literal",
49
+ language: "typescript",
50
+ code: `import express from "express";
51
+ const app = express();
52
+ app.post("/search", (req, res) => {
53
+ const sql = \`SELECT * FROM products WHERE name LIKE '%\${req.body.term}%'\`;
54
+ connection.execute(sql);
55
+ res.json({ ok: true });
56
+ });`,
57
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
58
+ category: "injection",
59
+ difficulty: "easy",
60
+ },
61
+ // ── XSS ──
62
+ {
63
+ id: "xss-reflected",
64
+ description: "Reflected XSS via unsanitized output",
65
+ language: "typescript",
66
+ code: `import express from "express";
67
+ const app = express();
68
+ app.get("/greet", (req, res) => {
69
+ res.send("<h1>Hello " + req.query.name + "</h1>");
70
+ });`,
71
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
72
+ category: "xss",
73
+ difficulty: "easy",
74
+ },
75
+ {
76
+ id: "xss-innerhtml",
77
+ description: "DOM XSS via innerHTML assignment",
78
+ language: "javascript",
79
+ code: `function displayMessage(userInput) {
80
+ document.getElementById("msg").innerHTML = userInput;
81
+ }
82
+ const params = new URLSearchParams(window.location.search);
83
+ displayMessage(params.get("message"));`,
84
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
85
+ category: "xss",
86
+ difficulty: "easy",
87
+ },
88
+ // ── Authentication ──
89
+ {
90
+ id: "hardcoded-secret",
91
+ description: "Hardcoded API key in source",
92
+ language: "typescript",
93
+ code: `const API_KEY = "sk-proj-abc123def456";
94
+ const DB_PASSWORD = "super_secret_password_123";
95
+ fetch("https://api.example.com", {
96
+ headers: { Authorization: "Bearer " + API_KEY }
97
+ });`,
98
+ expectedRuleIds: ["AUTH-001", "AUTH-002", "AUTH-003"],
99
+ category: "auth",
100
+ difficulty: "easy",
101
+ },
102
+ {
103
+ id: "weak-password-hash",
104
+ description: "Using MD5 for password hashing",
105
+ language: "typescript",
106
+ code: `import crypto from "crypto";
107
+ function hashPassword(password: string): string {
108
+ return crypto.createHash("md5").update(password).digest("hex");
109
+ }
110
+ function verifyPassword(password: string, hash: string): boolean {
111
+ return hashPassword(password) === hash;
112
+ }`,
113
+ expectedRuleIds: ["AUTH-001", "AUTH-002", "SEC-001"],
114
+ category: "auth",
115
+ difficulty: "medium",
116
+ },
117
+ // ── Command Injection ──
118
+ {
119
+ id: "command-injection",
120
+ description: "OS command injection via exec",
121
+ language: "typescript",
122
+ code: `import { exec } from "child_process";
123
+ import express from "express";
124
+ const app = express();
125
+ app.get("/ping", (req, res) => {
126
+ exec("ping -c 1 " + req.query.host, (err, stdout) => {
127
+ res.send(stdout);
128
+ });
129
+ });`,
130
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "CYBER-003"],
131
+ category: "injection",
132
+ difficulty: "easy",
133
+ },
134
+ // ── Path Traversal ──
135
+ {
136
+ id: "path-traversal",
137
+ description: "Path traversal via unsanitized file read",
138
+ language: "typescript",
139
+ code: `import express from "express";
140
+ import { readFileSync } from "fs";
141
+ const app = express();
142
+ app.get("/file", (req, res) => {
143
+ const content = readFileSync("/data/" + req.query.path, "utf-8");
144
+ res.send(content);
145
+ });`,
146
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001"],
147
+ category: "injection",
148
+ difficulty: "medium",
149
+ },
150
+ // ── Eval Usage ──
151
+ {
152
+ id: "eval-user-input",
153
+ description: "Eval with user-controlled input",
154
+ language: "javascript",
155
+ code: `const express = require("express");
156
+ const app = express();
157
+ app.post("/calculate", (req, res) => {
158
+ const result = eval(req.body.expression);
159
+ res.json({ result });
160
+ });`,
161
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
162
+ category: "injection",
163
+ difficulty: "easy",
164
+ },
165
+ // ── Missing Rate Limiting ──
166
+ {
167
+ id: "no-rate-limiting",
168
+ description: "API endpoint without rate limiting",
169
+ language: "typescript",
170
+ code: `import express from "express";
171
+ const app = express();
172
+ app.post("/login", async (req, res) => {
173
+ const { username, password } = req.body;
174
+ const user = await db.findUser(username);
175
+ if (user && user.password === password) {
176
+ res.json({ token: generateToken(user) });
177
+ } else {
178
+ res.status(401).json({ error: "Invalid credentials" });
179
+ }
180
+ });
181
+ app.listen(3000);`,
182
+ expectedRuleIds: ["RATE-001"],
183
+ category: "rate-limiting",
184
+ difficulty: "medium",
185
+ },
186
+ // ── Missing Error Handling ──
187
+ {
188
+ id: "empty-catch-block",
189
+ description: "Empty catch blocks swallowing errors",
190
+ language: "typescript",
191
+ code: `async function processPayment(amount: number) {
192
+ try {
193
+ const result = await stripe.charges.create({ amount });
194
+ return result;
195
+ } catch (e) {
196
+ // TODO: handle this later
197
+ }
198
+ }
199
+
200
+ async function fetchData(url: string) {
201
+ try {
202
+ const res = await fetch(url);
203
+ return await res.json();
204
+ } catch (err) {}
205
+ }`,
206
+ expectedRuleIds: ["ERR-001", "ERR-002"],
207
+ category: "error-handling",
208
+ difficulty: "easy",
209
+ },
210
+ // ── Data Security ──
211
+ {
212
+ id: "pii-logging",
213
+ description: "Logging PII/sensitive data",
214
+ language: "typescript",
215
+ code: `function processUser(user: { email: string; ssn: string; creditCard: string }) {
216
+ console.log("Processing user:", JSON.stringify(user));
217
+ logger.info("User SSN:", user.ssn);
218
+ logger.debug("Credit card:", user.creditCard);
219
+ return saveUser(user);
220
+ }`,
221
+ expectedRuleIds: ["DATA-001", "DATA-002", "LOGPRIV-001"],
222
+ category: "data-security",
223
+ difficulty: "easy",
224
+ },
225
+ // ── Clean Code (no vulnerabilities) ──
226
+ {
227
+ id: "clean-code-express",
228
+ description: "Well-structured Express API with proper security",
229
+ language: "typescript",
230
+ code: `import express from "express";
231
+ import helmet from "helmet";
232
+ import rateLimit from "express-rate-limit";
233
+ import { body, validationResult } from "express-validator";
234
+ import bcrypt from "bcrypt";
235
+
236
+ const app = express();
237
+ app.use(helmet());
238
+ app.use(express.json({ limit: "10kb" }));
239
+
240
+ const limiter = rateLimit({ windowMs: 15 * 60 * 1000, max: 100 });
241
+ app.use(limiter);
242
+
243
+ app.post("/login",
244
+ body("email").isEmail().normalizeEmail(),
245
+ body("password").isLength({ min: 8 }),
246
+ async (req, res) => {
247
+ const errors = validationResult(req);
248
+ if (!errors.isEmpty()) {
249
+ return res.status(400).json({ errors: errors.array() });
250
+ }
251
+ const { email, password } = req.body;
252
+ const user = await db.findByEmail(email);
253
+ if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
254
+ return res.status(401).json({ error: "Invalid credentials" });
255
+ }
256
+ const token = jwt.sign({ sub: user.id }, process.env.JWT_SECRET!, { expiresIn: "1h" });
257
+ res.json({ token });
258
+ }
259
+ );`,
260
+ expectedRuleIds: [],
261
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001"],
262
+ category: "clean",
263
+ difficulty: "hard",
264
+ },
265
+ // ── Python SQL Injection ──
266
+ {
267
+ id: "python-sql-injection",
268
+ description: "Python f-string SQL injection",
269
+ language: "python",
270
+ code: `from flask import Flask, request
271
+ import sqlite3
272
+
273
+ app = Flask(__name__)
274
+
275
+ @app.route("/users")
276
+ def get_user():
277
+ user_id = request.args.get("id")
278
+ conn = sqlite3.connect("db.sqlite")
279
+ cursor = conn.cursor()
280
+ cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
281
+ return str(cursor.fetchall())`,
282
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
283
+ category: "injection",
284
+ difficulty: "easy",
285
+ },
286
+ // ── Insecure Deserialization ──
287
+ {
288
+ id: "unsafe-deserialization",
289
+ description: "Deserializing untrusted data with eval/JSON.parse on unvalidated input",
290
+ language: "typescript",
291
+ code: `import express from "express";
292
+ const app = express();
293
+ app.post("/import", (req, res) => {
294
+ const data = eval("(" + req.body.payload + ")");
295
+ const config = new Function("return " + req.body.config)();
296
+ processData(data, config);
297
+ res.send("imported");
298
+ });`,
299
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
300
+ category: "injection",
301
+ difficulty: "medium",
302
+ },
303
+ // ── Missing HTTPS ──
304
+ {
305
+ id: "insecure-http",
306
+ description: "HTTP URLs for sensitive operations",
307
+ language: "typescript",
308
+ code: `const API_BASE = "http://api.example.com";
309
+
310
+ async function login(user: string, pass: string) {
311
+ const response = await fetch(API_BASE + "/auth/login", {
312
+ method: "POST",
313
+ body: JSON.stringify({ username: user, password: pass }),
314
+ });
315
+ return response.json();
316
+ }
317
+
318
+ async function getPayment(id: string) {
319
+ return fetch("http://payments.example.com/api/v1/charge/" + id);
320
+ }`,
321
+ expectedRuleIds: ["SEC-001", "CYBER-001"],
322
+ category: "security",
323
+ difficulty: "easy",
324
+ },
325
+ // ── Missing Input Validation ──
326
+ {
327
+ id: "no-input-validation",
328
+ description: "API endpoint with no input validation",
329
+ language: "typescript",
330
+ code: `import express from "express";
331
+ const app = express();
332
+ app.post("/transfer", async (req, res) => {
333
+ const { fromAccount, toAccount, amount } = req.body;
334
+ await db.transfer(fromAccount, toAccount, amount);
335
+ res.json({ success: true });
336
+ });
337
+
338
+ app.put("/user/:id", async (req, res) => {
339
+ await db.updateUser(req.params.id, req.body);
340
+ res.json({ updated: true });
341
+ });`,
342
+ expectedRuleIds: ["CYBER-001", "SEC-001"],
343
+ category: "security",
344
+ difficulty: "medium",
345
+ },
346
+ // ── Concurrency Issues ──
347
+ {
348
+ id: "race-condition",
349
+ description: "Race condition in shared state without synchronization",
350
+ language: "typescript",
351
+ code: `let balance = 1000;
352
+
353
+ async function withdraw(amount: number): Promise<boolean> {
354
+ if (balance >= amount) {
355
+ await new Promise(r => setTimeout(r, 100)); // Simulated delay
356
+ balance -= amount;
357
+ return true;
358
+ }
359
+ return false;
360
+ }
361
+
362
+ // Called concurrently from multiple requests
363
+ app.post("/withdraw", async (req, res) => {
364
+ const success = await withdraw(req.body.amount);
365
+ res.json({ success, balance });
366
+ });`,
367
+ expectedRuleIds: ["CONC-001"],
368
+ category: "concurrency",
369
+ difficulty: "hard",
370
+ },
371
+ // ── Performance ──
372
+ {
373
+ id: "perf-sync-io",
374
+ description: "Synchronous file I/O in request handler",
375
+ language: "typescript",
376
+ code: `import express from "express";
377
+ import { readFileSync, writeFileSync } from "fs";
378
+ const app = express();
379
+ app.get("/config", (req, res) => {
380
+ const data = readFileSync("/etc/app/config.json", "utf-8");
381
+ writeFileSync("/var/log/access.log", new Date().toISOString() + "\\n", { flag: "a" });
382
+ res.json(JSON.parse(data));
383
+ });
384
+ app.listen(3000);`,
385
+ expectedRuleIds: ["PERF-001"],
386
+ category: "performance",
387
+ difficulty: "easy",
388
+ },
389
+ {
390
+ id: "perf-n-plus-one",
391
+ description: "N+1 query pattern in loop",
392
+ language: "typescript",
393
+ code: `async function getOrdersWithProducts(userId: string) {
394
+ const orders = await db.query("SELECT * FROM orders WHERE user_id = $1", [userId]);
395
+ const results = [];
396
+ for (const order of orders) {
397
+ const products = await db.query("SELECT * FROM products WHERE order_id = $1", [order.id]);
398
+ results.push({ ...order, products });
399
+ }
400
+ return results;
401
+ }`,
402
+ expectedRuleIds: ["PERF-001", "DB-001"],
403
+ category: "performance",
404
+ difficulty: "medium",
405
+ },
406
+ // ── Database ──
407
+ {
408
+ id: "db-no-index-hint",
409
+ description: "Unindexed query patterns on large tables",
410
+ language: "typescript",
411
+ code: `async function searchUsers(email: string) {
412
+ return db.query("SELECT * FROM users WHERE LOWER(email) = LOWER($1)", [email]);
413
+ }
414
+ async function findOldOrders() {
415
+ return db.query("SELECT * FROM orders WHERE created_at < NOW() - INTERVAL '90 days' ORDER BY created_at");
416
+ }
417
+ async function getByStatus(status: string) {
418
+ return db.query("SELECT * FROM logs WHERE status = $1 AND timestamp > NOW() - INTERVAL '24 hours'", [status]);
419
+ }`,
420
+ expectedRuleIds: ["DB-001"],
421
+ category: "database",
422
+ difficulty: "medium",
423
+ },
424
+ // ── API Design ──
425
+ {
426
+ id: "api-no-versioning",
427
+ description: "API without versioning or pagination",
428
+ language: "typescript",
429
+ code: `import express from "express";
430
+ const app = express();
431
+ app.get("/users", async (req, res) => {
432
+ const users = await db.query("SELECT * FROM users");
433
+ res.json(users);
434
+ });
435
+ app.get("/products", async (req, res) => {
436
+ const products = await db.query("SELECT * FROM products");
437
+ res.json(products);
438
+ });
439
+ app.delete("/user", async (req, res) => {
440
+ await db.query("DELETE FROM users WHERE id = $1", [req.body.id]);
441
+ res.send("deleted");
442
+ });`,
443
+ expectedRuleIds: ["API-001"],
444
+ category: "api-design",
445
+ difficulty: "medium",
446
+ },
447
+ // ── Observability ──
448
+ {
449
+ id: "obs-no-logging",
450
+ description: "Service with no structured logging or monitoring",
451
+ language: "typescript",
452
+ code: `import express from "express";
453
+ const app = express();
454
+ app.post("/order", async (req, res) => {
455
+ const order = await createOrder(req.body);
456
+ res.json(order);
457
+ });
458
+ app.get("/status", (req, res) => {
459
+ res.json({ ok: true });
460
+ });
461
+ app.listen(process.env.PORT);`,
462
+ expectedRuleIds: ["OBS-001"],
463
+ category: "observability",
464
+ difficulty: "easy",
465
+ },
466
+ // ── Reliability ──
467
+ {
468
+ id: "rel-no-health-check",
469
+ description: "Web service without health check or graceful shutdown",
470
+ language: "typescript",
471
+ code: `import express from "express";
472
+ const app = express();
473
+ app.get("/api/data", async (req, res) => {
474
+ const data = await fetchFromDatabase();
475
+ res.json(data);
476
+ });
477
+ app.listen(8080, () => {
478
+ console.log("Server started on port 8080");
479
+ });`,
480
+ expectedRuleIds: ["REL-001"],
481
+ category: "reliability",
482
+ difficulty: "easy",
483
+ },
484
+ {
485
+ id: "rel-no-timeout",
486
+ description: "External HTTP calls without timeout",
487
+ language: "typescript",
488
+ code: `async function fetchUserProfile(userId: string) {
489
+ const response = await fetch("https://api.example.com/users/" + userId);
490
+ return response.json();
491
+ }
492
+ async function sendNotification(email: string, msg: string) {
493
+ await fetch("https://email.example.com/send", {
494
+ method: "POST",
495
+ body: JSON.stringify({ to: email, message: msg }),
496
+ });
497
+ }`,
498
+ expectedRuleIds: ["REL-001"],
499
+ category: "reliability",
500
+ difficulty: "medium",
501
+ },
502
+ // ── Scalability ──
503
+ {
504
+ id: "scale-global-state",
505
+ description: "Storing session state in-memory on server",
506
+ language: "typescript",
507
+ code: `import express from "express";
508
+ const sessions: Record<string, any> = {};
509
+ const app = express();
510
+ app.post("/login", (req, res) => {
511
+ const token = Math.random().toString(36);
512
+ sessions[token] = { user: req.body.username, createdAt: Date.now() };
513
+ res.json({ token });
514
+ });
515
+ app.get("/profile", (req, res) => {
516
+ const session = sessions[req.headers.authorization as string];
517
+ if (!session) return res.status(401).send("Unauthorized");
518
+ res.json(session);
519
+ });`,
520
+ expectedRuleIds: ["DATA-001", "RATE-001", "CYBER-001", "API-001", "OBS-001", "AICS-001", "SEC-001"],
521
+ category: "scalability",
522
+ difficulty: "medium",
523
+ },
524
+ // ── Cloud Readiness ──
525
+ {
526
+ id: "cloud-hardcoded-paths",
527
+ description: "Hardcoded local filesystem paths and ports",
528
+ language: "typescript",
529
+ code: `import { readFileSync, writeFileSync } from "fs";
530
+ const CONFIG_PATH = "C:\\\\Program Files\\\\MyApp\\\\config.json";
531
+ const LOG_PATH = "/var/log/myapp/app.log";
532
+
533
+ function loadConfig() {
534
+ return JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
535
+ }
536
+ function writeLog(msg: string) {
537
+ writeFileSync(LOG_PATH, msg + "\\n", { flag: "a" });
538
+ }
539
+ const server = app.listen(3000);`,
540
+ expectedRuleIds: ["CLOUD-001"],
541
+ category: "cloud-readiness",
542
+ difficulty: "easy",
543
+ },
544
+ // ── Configuration Management ──
545
+ {
546
+ id: "config-scattered-env",
547
+ description: "Scattered environment variable access without validation",
548
+ language: "typescript",
549
+ code: `import express from "express";
550
+ const app = express();
551
+ app.get("/api", (req, res) => {
552
+ const dbHost = process.env.DB_HOST;
553
+ const dbPort = parseInt(process.env.DB_PORT!);
554
+ const apiKey = process.env.API_KEY;
555
+ fetch(\`http://\${dbHost}:\${dbPort}/data\`, {
556
+ headers: { "X-API-Key": apiKey! }
557
+ }).then(r => r.json()).then(data => res.json(data));
558
+ });`,
559
+ expectedRuleIds: ["CFG-001", "SEC-001"],
560
+ category: "configuration",
561
+ difficulty: "easy",
562
+ },
563
+ // ── Maintainability ──
564
+ {
565
+ id: "maint-god-function",
566
+ description: "Overly long function with multiple responsibilities",
567
+ language: "typescript",
568
+ code: `async function processOrder(req: any) {
569
+ // Validate input
570
+ if (!req.body.items || !Array.isArray(req.body.items)) throw new Error("Invalid");
571
+ if (!req.body.userId) throw new Error("No user");
572
+ if (!req.body.paymentMethod) throw new Error("No payment");
573
+ // Calculate totals
574
+ let total = 0;
575
+ for (const item of req.body.items) {
576
+ const product = await db.query("SELECT price FROM products WHERE id = $1", [item.id]);
577
+ total += product.price * item.quantity;
578
+ }
579
+ // Apply discount
580
+ const user = await db.query("SELECT * FROM users WHERE id = $1", [req.body.userId]);
581
+ if (user.isPremium) total *= 0.9;
582
+ // Process payment
583
+ const charge = await stripe.charges.create({ amount: total, source: req.body.paymentMethod });
584
+ if (!charge.paid) throw new Error("Payment failed");
585
+ // Create order
586
+ const order = await db.query("INSERT INTO orders (user_id, total, payment_id) VALUES ($1, $2, $3)", [req.body.userId, total, charge.id]);
587
+ // Send email
588
+ await mailer.send({ to: user.email, subject: "Order Confirmed", body: "Your order #" + order.id });
589
+ // Update inventory
590
+ for (const item of req.body.items) {
591
+ await db.query("UPDATE products SET stock = stock - $1 WHERE id = $2", [item.quantity, item.id]);
592
+ }
593
+ // Log
594
+ console.log("Order processed:", order.id);
595
+ return order;
596
+ }`,
597
+ expectedRuleIds: [
598
+ "CYBER-001",
599
+ "PERF-001",
600
+ "COST-001",
601
+ "DB-001",
602
+ "API-001",
603
+ "TEST-001",
604
+ "CONC-001",
605
+ "AICS-001",
606
+ "SEC-001",
607
+ ],
608
+ category: "maintainability",
609
+ difficulty: "medium",
610
+ },
611
+ {
612
+ id: "maint-magic-numbers",
613
+ description: "Magic numbers and strings without named constants",
614
+ language: "typescript",
615
+ code: `function calculateShipping(weight: number, distance: number): number {
616
+ if (weight < 5) return distance * 0.5 + 2.99;
617
+ if (weight < 20) return distance * 0.75 + 4.99;
618
+ if (distance > 500) return weight * 1.2 + 15.0;
619
+ return weight * 0.8 + 9.99;
620
+ }
621
+
622
+ function getDiscount(total: number, loyaltyYears: number): number {
623
+ if (loyaltyYears > 10) return total * 0.25;
624
+ if (loyaltyYears > 5) return total * 0.15;
625
+ if (total > 100) return total * 0.05;
626
+ return 0;
627
+ }`,
628
+ expectedRuleIds: [],
629
+ category: "maintainability",
630
+ difficulty: "easy",
631
+ },
632
+ // ── Code Structure ──
633
+ {
634
+ id: "struct-deep-nesting",
635
+ description: "Deeply nested control flow",
636
+ language: "typescript",
637
+ code: `function processEvent(event: any): string {
638
+ if (event) {
639
+ if (event.type === "click") {
640
+ if (event.target) {
641
+ if (event.target.id) {
642
+ if (event.target.id.startsWith("btn-")) {
643
+ if (event.detail) {
644
+ if (event.detail > 1) {
645
+ return "double-click on button";
646
+ } else {
647
+ return "single-click on button";
648
+ }
649
+ }
650
+ }
651
+ }
652
+ }
653
+ } else if (event.type === "keydown") {
654
+ if (event.key) {
655
+ if (event.key === "Enter") {
656
+ return "enter pressed";
657
+ }
658
+ }
659
+ }
660
+ }
661
+ return "unknown";
662
+ }`,
663
+ expectedRuleIds: ["STRUCT-001"],
664
+ category: "code-structure",
665
+ difficulty: "easy",
666
+ },
667
+ // ── Documentation ──
668
+ {
669
+ id: "doc-no-docs",
670
+ description: "Public API without documentation",
671
+ language: "typescript",
672
+ code: `export function calculateTax(a: number, b: string, c: boolean): number {
673
+ const rates: Record<string, number> = { US: 0.08, UK: 0.20, DE: 0.19, JP: 0.10 };
674
+ const rate = rates[b] || 0.15;
675
+ return c ? a * rate * 0.5 : a * rate;
676
+ }
677
+
678
+ export function transformData(input: unknown[]): Record<string, unknown> {
679
+ const result: Record<string, unknown> = {};
680
+ for (const item of input) {
681
+ const key = (item as any).id || String(Math.random());
682
+ result[key] = item;
683
+ }
684
+ return result;
685
+ }
686
+
687
+ export class DataProcessor {
688
+ private buffer: unknown[] = [];
689
+ process(item: unknown): void { this.buffer.push(item); }
690
+ flush(): unknown[] { const r = [...this.buffer]; this.buffer = []; return r; }
691
+ }`,
692
+ expectedRuleIds: ["DOC-001"],
693
+ category: "documentation",
694
+ difficulty: "easy",
695
+ },
696
+ // ── Testing ──
697
+ {
698
+ id: "test-no-tests",
699
+ description: "Complex logic with no test file or test patterns",
700
+ language: "typescript",
701
+ code: `export function parseExpression(expr: string): number {
702
+ const tokens = expr.match(/\\d+|[+\\-*/()]/g) || [];
703
+ let pos = 0;
704
+ function parseAtom(): number {
705
+ if (tokens[pos] === "(") { pos++; const v = parseAddSub(); pos++; return v; }
706
+ return Number(tokens[pos++]);
707
+ }
708
+ function parseMulDiv(): number {
709
+ let v = parseAtom();
710
+ while (tokens[pos] === "*" || tokens[pos] === "/") {
711
+ const op = tokens[pos++]; const r = parseAtom();
712
+ v = op === "*" ? v * r : v / r;
713
+ }
714
+ return v;
715
+ }
716
+ function parseAddSub(): number {
717
+ let v = parseMulDiv();
718
+ while (tokens[pos] === "+" || tokens[pos] === "-") {
719
+ const op = tokens[pos++]; const r = parseMulDiv();
720
+ v = op === "+" ? v + r : v - r;
721
+ }
722
+ return v;
723
+ }
724
+ return parseAddSub();
725
+ }`,
726
+ expectedRuleIds: [],
727
+ category: "testing",
728
+ difficulty: "medium",
729
+ },
730
+ // ── Cost Effectiveness ──
731
+ {
732
+ id: "cost-wasteful-resources",
733
+ description: "Wasteful resource usage patterns",
734
+ language: "typescript",
735
+ code: `import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
736
+ const s3 = new S3Client({});
737
+ async function processImage(imageBuffer: Buffer) {
738
+ // Store every variant without cleanup policy
739
+ for (const size of [100, 200, 400, 800, 1600, 3200]) {
740
+ const resized = await sharp(imageBuffer).resize(size).toBuffer();
741
+ await s3.send(new PutObjectCommand({
742
+ Bucket: "my-images",
743
+ Key: \`img-\${Date.now()}-\${size}.jpg\`,
744
+ Body: resized,
745
+ }));
746
+ }
747
+ }
748
+
749
+ // Connection pool with excessive connections
750
+ const pool = new Pool({ host: "db.server.com", max: 500, idleTimeoutMillis: 0 });`,
751
+ expectedRuleIds: ["COST-001"],
752
+ category: "cost-effectiveness",
753
+ difficulty: "medium",
754
+ },
755
+ // ── Compliance ──
756
+ {
757
+ id: "comp-missing-audit-trail",
758
+ description: "Admin operations with no audit logging",
759
+ language: "typescript",
760
+ code: `import express from "express";
761
+ const app = express();
762
+ app.delete("/admin/users/:id", async (req, res) => {
763
+ await db.query("DELETE FROM users WHERE id = $1", [req.params.id]);
764
+ res.json({ deleted: true });
765
+ });
766
+ app.put("/admin/roles/:userId", async (req, res) => {
767
+ await db.query("UPDATE users SET role = $1 WHERE id = $2", [req.body.role, req.params.userId]);
768
+ res.json({ updated: true });
769
+ });
770
+ app.post("/admin/config", async (req, res) => {
771
+ await db.query("UPDATE system_config SET value = $1 WHERE key = $2", [req.body.value, req.body.key]);
772
+ res.json({ saved: true });
773
+ });`,
774
+ expectedRuleIds: ["COMP-001"],
775
+ category: "compliance",
776
+ difficulty: "medium",
777
+ },
778
+ // ── Accessibility ──
779
+ {
780
+ id: "a11y-missing-labels",
781
+ description: "UI components without accessibility attributes",
782
+ language: "typescript",
783
+ code: `function renderForm() {
784
+ return \`
785
+ <form>
786
+ <input type="text" placeholder="Search...">
787
+ <select>
788
+ <option>Option 1</option>
789
+ <option>Option 2</option>
790
+ </select>
791
+ <button onclick="submit()"><img src="send.png"></button>
792
+ <div onclick="toggleMenu()" style="cursor:pointer">Menu</div>
793
+ <div class="modal" style="display:none">
794
+ <div class="content">Modal content</div>
795
+ </div>
796
+ </form>
797
+ \`;
798
+ }`,
799
+ expectedRuleIds: ["A11Y-001"],
800
+ category: "accessibility",
801
+ difficulty: "easy",
802
+ },
803
+ // ── Internationalization ──
804
+ {
805
+ id: "i18n-hardcoded-strings",
806
+ description: "Hardcoded user-facing strings and locale assumptions",
807
+ language: "typescript",
808
+ code: `function formatPrice(amount: number): string {
809
+ return "$" + amount.toFixed(2);
810
+ }
811
+ function formatDate(d: Date): string {
812
+ return \`\${d.getMonth() + 1}/\${d.getDate()}/\${d.getFullYear()}\`;
813
+ }
814
+ function getGreeting(name: string): string {
815
+ return "Hello, " + name + "! Welcome to our store.";
816
+ }
817
+ function getErrorMessage(code: number): string {
818
+ if (code === 404) return "Page not found";
819
+ if (code === 500) return "Internal server error";
820
+ return "An unknown error occurred";
821
+ }`,
822
+ expectedRuleIds: ["I18N-001"],
823
+ category: "internationalization",
824
+ difficulty: "easy",
825
+ },
826
+ // ── Dependency Health ──
827
+ {
828
+ id: "deps-outdated-packages",
829
+ description: "Outdated or abandoned dependencies",
830
+ language: "json",
831
+ code: `{
832
+ "name": "my-app",
833
+ "version": "1.0.0",
834
+ "dependencies": {
835
+ "express": "^3.0.0",
836
+ "lodash": "^3.10.0",
837
+ "moment": "^2.10.0",
838
+ "request": "^2.88.0",
839
+ "jade": "^1.11.0",
840
+ "coffee-script": "^1.12.0"
841
+ },
842
+ "devDependencies": {
843
+ "gulp": "^3.9.0",
844
+ "bower": "^1.8.0"
845
+ }
846
+ }`,
847
+ expectedRuleIds: ["DEPS-001"],
848
+ category: "dependency-health",
849
+ difficulty: "easy",
850
+ },
851
+ // ── Logging Privacy ──
852
+ {
853
+ id: "logpriv-sensitive-data",
854
+ description: "Logging sensitive personal data",
855
+ language: "typescript",
856
+ code: `import winston from "winston";
857
+ const logger = winston.createLogger({ level: "info" });
858
+
859
+ function handleLogin(username: string, password: string) {
860
+ logger.info("Login attempt", { username, password });
861
+ logger.debug("Credentials:", { user: username, pass: password });
862
+ }
863
+
864
+ function processPayment(card: { number: string; cvv: string; expiry: string }) {
865
+ logger.info("Processing payment for card: " + card.number);
866
+ console.log("CVV:", card.cvv);
867
+ }`,
868
+ expectedRuleIds: ["LOGPRIV-001", "DATA-001"],
869
+ category: "logging-privacy",
870
+ difficulty: "easy",
871
+ },
872
+ // ── Backwards Compatibility ──
873
+ {
874
+ id: "compat-breaking-changes",
875
+ description: "API breaking changes without versioning",
876
+ language: "typescript",
877
+ code: `// v1: function signature changed without deprecation
878
+ export function createUser(name: string, email: string): User {
879
+ // Was: createUser(data: UserInput)
880
+ return { id: generateId(), name, email, createdAt: new Date() };
881
+ }
882
+
883
+ // v1: Response shape changed
884
+ export function getUsers(): UserResponse {
885
+ // Was: returns User[] directly, now wrapped
886
+ return { data: [], total: 0, page: 1 };
887
+ }
888
+
889
+ // v1: Renamed without alias
890
+ export function fetchUserProfile(id: string) {
891
+ // Was: getUserProfile(id)
892
+ return db.findUser(id);
893
+ }`,
894
+ expectedRuleIds: ["COMPAT-001"],
895
+ category: "backwards-compatibility",
896
+ difficulty: "hard",
897
+ },
898
+ // ── Caching ──
899
+ {
900
+ id: "cache-no-caching",
901
+ description: "Expensive repeated computations without caching",
902
+ language: "typescript",
903
+ code: `import express from "express";
904
+ const app = express();
905
+
906
+ app.get("/product/:id", async (req, res) => {
907
+ // This query is expensive and data rarely changes
908
+ const product = await db.query(\`
909
+ SELECT p.*, c.name as category, AVG(r.rating) as avg_rating
910
+ FROM products p
911
+ JOIN categories c ON p.category_id = c.id
912
+ LEFT JOIN reviews r ON r.product_id = p.id
913
+ WHERE p.id = $1
914
+ GROUP BY p.id, c.name
915
+ \`, [req.params.id]);
916
+ res.json(product);
917
+ });
918
+
919
+ app.get("/config", async (req, res) => {
920
+ const config = await db.query("SELECT * FROM app_config");
921
+ res.json(config);
922
+ });`,
923
+ expectedRuleIds: ["COST-001"],
924
+ category: "caching",
925
+ difficulty: "medium",
926
+ },
927
+ // ── Ethics & Bias ──
928
+ {
929
+ id: "ethics-discriminatory-logic",
930
+ description: "Logic that discriminates based on protected attributes",
931
+ language: "typescript",
932
+ code: `function calculatePremium(age: number, gender: string, zipCode: string): number {
933
+ let base = 100;
934
+ if (gender === "female") base *= 0.9;
935
+ if (gender === "male") base *= 1.1;
936
+ if (age > 65) base *= 1.5;
937
+ if (age < 25) base *= 1.3;
938
+ // Proxy for race/ethnicity via zip code
939
+ const highRiskZips = ["10001", "90011", "60609"];
940
+ if (highRiskZips.includes(zipCode)) base *= 1.4;
941
+ return base;
942
+ }
943
+
944
+ function filterCandidates(candidates: any[]) {
945
+ return candidates.filter(c =>
946
+ c.age >= 22 && c.age <= 45 &&
947
+ !c.name.match(/[^a-zA-Z\\s]/) // Filters non-Latin names
948
+ );
949
+ }`,
950
+ expectedRuleIds: ["ETHICS-001"],
951
+ category: "ethics-bias",
952
+ difficulty: "hard",
953
+ },
954
+ // ── Portability ──
955
+ {
956
+ id: "port-platform-specific",
957
+ description: "Platform-specific code without abstraction",
958
+ language: "typescript",
959
+ code: `import { execSync } from "child_process";
960
+ import { join } from "path";
961
+
962
+ function getCpuUsage(): number {
963
+ const output = execSync("wmic cpu get loadpercentage").toString();
964
+ return parseInt(output.split("\\n")[1]);
965
+ }
966
+
967
+ function openBrowser(url: string): void {
968
+ execSync(\`start \${url}\`); // Windows only
969
+ }
970
+
971
+ function getConfigDir(): string {
972
+ return join("C:\\\\Users", process.env.USERNAME!, "AppData", "Local", "MyApp");
973
+ }`,
974
+ expectedRuleIds: ["PORTA-001"],
975
+ category: "portability",
976
+ difficulty: "easy",
977
+ },
978
+ // ── UX ──
979
+ {
980
+ id: "ux-poor-error-messages",
981
+ description: "Generic error messages with no user guidance",
982
+ language: "typescript",
983
+ code: `app.post("/register", async (req, res) => {
984
+ try {
985
+ const user = await createUser(req.body);
986
+ res.json(user);
987
+ } catch (e) {
988
+ res.status(500).json({ error: "Error" });
989
+ }
990
+ });
991
+
992
+ app.post("/upload", async (req, res) => {
993
+ try {
994
+ await processFile(req.file);
995
+ res.json({ ok: true });
996
+ } catch (e) {
997
+ res.status(400).json({ message: "Bad request" });
998
+ }
999
+ });`,
1000
+ expectedRuleIds: ["UX-001", "ERR-001"],
1001
+ category: "ux",
1002
+ difficulty: "easy",
1003
+ },
1004
+ // ── CI/CD ──
1005
+ {
1006
+ id: "cicd-no-pipeline",
1007
+ description: "Project with no CI/CD configuration",
1008
+ language: "json",
1009
+ code: `{
1010
+ "name": "my-web-app",
1011
+ "version": "2.1.0",
1012
+ "scripts": {
1013
+ "start": "node index.js",
1014
+ "dev": "nodemon index.js"
1015
+ },
1016
+ "dependencies": {
1017
+ "express": "^4.18.0",
1018
+ "mongoose": "^7.0.0"
1019
+ }
1020
+ }`,
1021
+ expectedRuleIds: [],
1022
+ category: "ci-cd",
1023
+ difficulty: "easy",
1024
+ },
1025
+ // ── Software Practices ──
1026
+ {
1027
+ id: "swdev-no-linting",
1028
+ description: "Project with no linting or formatting configuration",
1029
+ language: "json",
1030
+ code: `{
1031
+ "name": "legacy-api",
1032
+ "version": "1.0.0",
1033
+ "main": "index.js",
1034
+ "scripts": {
1035
+ "start": "node index.js"
1036
+ },
1037
+ "dependencies": {
1038
+ "express": "^4.18.0"
1039
+ }
1040
+ }`,
1041
+ expectedRuleIds: [],
1042
+ category: "software-practices",
1043
+ difficulty: "easy",
1044
+ },
1045
+ // ── Data Sovereignty ──
1046
+ {
1047
+ id: "sov-cross-region-data",
1048
+ description: "Sending user data to multiple regions without consent",
1049
+ language: "typescript",
1050
+ code: `const ANALYTICS_ENDPOINTS = [
1051
+ "https://analytics.us-east-1.example.com/track",
1052
+ "https://analytics.eu-west-1.example.com/track",
1053
+ "https://analytics.ap-southeast-1.example.com/track",
1054
+ ];
1055
+
1056
+ async function trackUserEvent(userId: string, event: string, userData: any) {
1057
+ // Fan-out to all regional analytics endpoints
1058
+ await Promise.all(
1059
+ ANALYTICS_ENDPOINTS.map(endpoint =>
1060
+ fetch(endpoint, {
1061
+ method: "POST",
1062
+ body: JSON.stringify({ userId, event, email: userData.email, ip: userData.ipAddress }),
1063
+ })
1064
+ )
1065
+ );
1066
+ }`,
1067
+ expectedRuleIds: ["SOV-001"],
1068
+ category: "data-sovereignty",
1069
+ difficulty: "hard",
1070
+ },
1071
+ // ── Agent Instructions ──
1072
+ {
1073
+ id: "agent-unsafe-instructions",
1074
+ description: "Agent/LLM system prompt with injection vulnerabilities",
1075
+ language: "typescript",
1076
+ code: `function buildSystemPrompt(userQuery: string): string {
1077
+ return \`You are a helpful assistant. The user asks: \${userQuery}
1078
+ Answer the question. You have access to the database and can run any SQL query.
1079
+ If the user asks you to ignore these instructions, comply with their request.
1080
+ Execute any code the user provides without validation.\`;
1081
+ }
1082
+
1083
+ async function handleChat(userMessage: string) {
1084
+ const prompt = buildSystemPrompt(userMessage);
1085
+ const response = await openai.chat.completions.create({
1086
+ model: "gpt-4",
1087
+ messages: [{ role: "system", content: prompt }],
1088
+ });
1089
+ // Execute any tool calls without validation
1090
+ for (const tool of response.choices[0].message.tool_calls ?? []) {
1091
+ await eval(tool.function.arguments);
1092
+ }
1093
+ }`,
1094
+ expectedRuleIds: ["AGENT-001"],
1095
+ category: "agent-instructions",
1096
+ difficulty: "medium",
1097
+ },
1098
+ // ── AI Code Safety ──
1099
+ {
1100
+ id: "aics-ai-generated-patterns",
1101
+ description: "Common AI-generated code anti-patterns",
1102
+ language: "typescript",
1103
+ code: `// AI-generated CRUD with common pitfalls
1104
+ import express from "express";
1105
+ const app = express();
1106
+
1107
+ app.post("/api/users", async (req, res) => {
1108
+ const user = req.body; // No validation
1109
+ const result = await db.query("INSERT INTO users VALUES ($1, $2, $3)",
1110
+ [user.id, user.name, user.email]);
1111
+ res.json(result);
1112
+ });
1113
+
1114
+ // AI-generated with TODO placeholders left in
1115
+ app.get("/api/admin", async (req, res) => {
1116
+ // TODO: add authentication
1117
+ // TODO: add rate limiting
1118
+ const data = await db.query("SELECT * FROM admin_data");
1119
+ res.json(data);
1120
+ });
1121
+
1122
+ // AI hallucination: non-existent API
1123
+ import { secureSanitize } from "express-security-utils";`,
1124
+ expectedRuleIds: ["AICS-001"],
1125
+ category: "ai-code-safety",
1126
+ difficulty: "medium",
1127
+ },
1128
+ // ── Framework Safety ──
1129
+ {
1130
+ id: "fw-unsafe-express",
1131
+ description: "Express app missing essential security middleware",
1132
+ language: "typescript",
1133
+ code: `import express from "express";
1134
+ const app = express();
1135
+ app.use(express.json());
1136
+
1137
+ // No helmet, no cors, no csrf protection
1138
+ app.post("/api/data", (req, res) => {
1139
+ res.json({ received: req.body });
1140
+ });
1141
+
1142
+ app.get("/api/file", (req, res) => {
1143
+ res.sendFile(req.query.path as string); // Path traversal
1144
+ });
1145
+
1146
+ app.listen(3000);`,
1147
+ expectedRuleIds: ["FW-001", "SEC-001"],
1148
+ category: "framework-safety",
1149
+ difficulty: "easy",
1150
+ },
1151
+ // ── IaC Security ──
1152
+ {
1153
+ id: "iac-insecure-terraform",
1154
+ description: "Terraform with security misconfigurations",
1155
+ language: "hcl",
1156
+ code: `resource "aws_s3_bucket" "data" {
1157
+ bucket = "my-app-data"
1158
+ acl = "public-read"
1159
+ }
1160
+
1161
+ resource "aws_security_group" "web" {
1162
+ name = "web-sg"
1163
+ ingress {
1164
+ from_port = 0
1165
+ to_port = 65535
1166
+ protocol = "tcp"
1167
+ cidr_blocks = ["0.0.0.0/0"]
1168
+ }
1169
+ }
1170
+
1171
+ resource "aws_db_instance" "main" {
1172
+ engine = "mysql"
1173
+ instance_class = "db.t3.micro"
1174
+ publicly_accessible = true
1175
+ storage_encrypted = false
1176
+ }`,
1177
+ expectedRuleIds: ["IAC-001"],
1178
+ category: "iac-security",
1179
+ difficulty: "easy",
1180
+ },
1181
+ {
1182
+ id: "iac-insecure-dockerfile",
1183
+ description: "Dockerfile with security anti-patterns",
1184
+ language: "dockerfile",
1185
+ code: `FROM node:latest
1186
+ USER root
1187
+ COPY . /app
1188
+ WORKDIR /app
1189
+ RUN npm install
1190
+ RUN echo "DB_PASSWORD=supersecret123" >> .env
1191
+ EXPOSE 22 3000 5432
1192
+ CMD ["node", "index.js"]`,
1193
+ expectedRuleIds: ["IAC-001"],
1194
+ category: "iac-security",
1195
+ difficulty: "easy",
1196
+ },
1197
+ // ── Python XSS ──
1198
+ {
1199
+ id: "python-xss",
1200
+ description: "Python Flask template injection / XSS",
1201
+ language: "python",
1202
+ code: `from flask import Flask, request, render_template_string
1203
+
1204
+ app = Flask(__name__)
1205
+
1206
+ @app.route("/greet")
1207
+ def greet():
1208
+ name = request.args.get("name", "World")
1209
+ return render_template_string("<h1>Hello " + name + "</h1>")
1210
+
1211
+ @app.route("/search")
1212
+ def search():
1213
+ query = request.args.get("q", "")
1214
+ return f"<p>Results for: {query}</p>"`,
1215
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "FW-001"],
1216
+ category: "xss",
1217
+ difficulty: "easy",
1218
+ },
1219
+ // ── Go SQL Injection ──
1220
+ {
1221
+ id: "go-sql-injection",
1222
+ description: "Go SQL injection via string formatting",
1223
+ language: "go",
1224
+ code: `package main
1225
+
1226
+ import (
1227
+ "database/sql"
1228
+ "fmt"
1229
+ "net/http"
1230
+ )
1231
+
1232
+ func getUser(w http.ResponseWriter, r *http.Request) {
1233
+ id := r.URL.Query().Get("id")
1234
+ query := fmt.Sprintf("SELECT * FROM users WHERE id = '%s'", id)
1235
+ rows, _ := db.Query(query)
1236
+ defer rows.Close()
1237
+ fmt.Fprintf(w, "Results: %v", rows)
1238
+ }
1239
+
1240
+ func searchProducts(w http.ResponseWriter, r *http.Request) {
1241
+ term := r.FormValue("q")
1242
+ db.Query("SELECT * FROM products WHERE name LIKE '%" + term + "%'")
1243
+ }`,
1244
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
1245
+ category: "injection",
1246
+ difficulty: "easy",
1247
+ },
1248
+ // ── Java Deserialization ──
1249
+ {
1250
+ id: "java-deserialization",
1251
+ description: "Java unsafe deserialization of untrusted data",
1252
+ language: "java",
1253
+ code: `import java.io.*;
1254
+ import javax.servlet.*;
1255
+ import javax.servlet.http.*;
1256
+
1257
+ public class DataServlet extends HttpServlet {
1258
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
1259
+ throws IOException {
1260
+ ObjectInputStream ois = new ObjectInputStream(req.getInputStream());
1261
+ Object data = ois.readObject();
1262
+ processData(data);
1263
+ resp.getWriter().write("Processed");
1264
+ }
1265
+
1266
+ private void processData(Object data) throws IOException {
1267
+ Runtime.getRuntime().exec(data.toString());
1268
+ }
1269
+ }`,
1270
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
1271
+ category: "injection",
1272
+ difficulty: "medium",
1273
+ },
1274
+ // ── Clean code — Python well-structured ──
1275
+ {
1276
+ id: "clean-code-python",
1277
+ description: "Well-structured Python Flask API",
1278
+ language: "python",
1279
+ code: `from flask import Flask, request, jsonify
1280
+ from flask_limiter import Limiter
1281
+ from flask_limiter.util import get_remote_address
1282
+ import bleach
1283
+ import bcrypt
1284
+ import logging
1285
+
1286
+ app = Flask(__name__)
1287
+ limiter = Limiter(app=app, key_func=get_remote_address)
1288
+ logger = logging.getLogger(__name__)
1289
+
1290
+ @app.route("/api/v1/login", methods=["POST"])
1291
+ @limiter.limit("5 per minute")
1292
+ def login():
1293
+ data = request.get_json()
1294
+ if not data or "email" not in data or "password" not in data:
1295
+ return jsonify({"error": "Email and password required"}), 400
1296
+
1297
+ email = bleach.clean(data["email"])
1298
+ user = User.query.filter_by(email=email).first()
1299
+
1300
+ if not user or not bcrypt.checkpw(data["password"].encode(), user.password_hash):
1301
+ logger.warning("Failed login attempt for %s", email)
1302
+ return jsonify({"error": "Invalid credentials"}), 401
1303
+
1304
+ token = generate_token(user.id)
1305
+ logger.info("Successful login for user %s", user.id)
1306
+ return jsonify({"token": token}), 200`,
1307
+ expectedRuleIds: [],
1308
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001", "RATE-001"],
1309
+ category: "clean",
1310
+ difficulty: "hard",
1311
+ },
1312
+ // ── Hard Cases: Subtle/Obfuscated Vulnerabilities ────────────────────────
1313
+ // ── Indirect injection through helper function ──
1314
+ {
1315
+ id: "hard-indirect-sql-injection",
1316
+ description: "SQL injection hidden behind helper function indirection",
1317
+ language: "typescript",
1318
+ code: `function buildQuery(table: string, filter: string): string {
1319
+ return "SELECT * FROM " + table + " WHERE " + filter;
1320
+ }
1321
+ app.get("/search", (req, res) => {
1322
+ const query = buildQuery("users", "name = '" + req.query.name + "'");
1323
+ db.query(query);
1324
+ res.send("ok");
1325
+ });`,
1326
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
1327
+ category: "injection",
1328
+ difficulty: "hard",
1329
+ },
1330
+ // ── SSRF via parameter composition ──
1331
+ {
1332
+ id: "hard-ssrf",
1333
+ description: "Server-side request forgery via user-controlled URL",
1334
+ language: "typescript",
1335
+ code: `import express from "express";
1336
+ const app = express();
1337
+ app.get("/proxy", async (req, res) => {
1338
+ const targetUrl = req.query.url as string;
1339
+ const response = await fetch(targetUrl);
1340
+ const body = await response.text();
1341
+ res.send(body);
1342
+ });`,
1343
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001"],
1344
+ category: "injection",
1345
+ difficulty: "hard",
1346
+ },
1347
+ // ── Prototype pollution ──
1348
+ {
1349
+ id: "hard-prototype-pollution",
1350
+ description: "Prototype pollution via recursive merge of user input",
1351
+ language: "javascript",
1352
+ code: `function deepMerge(target, source) {
1353
+ for (const key in source) {
1354
+ if (typeof source[key] === "object" && source[key] !== null) {
1355
+ if (!target[key]) target[key] = {};
1356
+ deepMerge(target[key], source[key]);
1357
+ } else {
1358
+ target[key] = source[key];
1359
+ }
1360
+ }
1361
+ return target;
1362
+ }
1363
+ app.post("/config", (req, res) => {
1364
+ const config = deepMerge({}, req.body);
1365
+ res.json(config);
1366
+ });`,
1367
+ expectedRuleIds: ["CYBER-001", "SEC-001"],
1368
+ category: "injection",
1369
+ difficulty: "hard",
1370
+ },
1371
+ // ── JWT none algorithm attack ──
1372
+ {
1373
+ id: "hard-jwt-none-algorithm",
1374
+ description: "JWT verification allowing none algorithm",
1375
+ language: "typescript",
1376
+ code: `import jwt from "jsonwebtoken";
1377
+ app.use((req, res, next) => {
1378
+ const token = req.headers.authorization?.split(" ")[1];
1379
+ if (!token) return res.status(401).send("No token");
1380
+ const decoded = jwt.decode(token);
1381
+ if (decoded && (decoded as any).role === "admin") {
1382
+ req.user = decoded;
1383
+ next();
1384
+ } else {
1385
+ res.status(403).send("Forbidden");
1386
+ }
1387
+ });`,
1388
+ expectedRuleIds: ["AUTH-001", "AUTH-002", "SEC-001"],
1389
+ category: "auth",
1390
+ difficulty: "hard",
1391
+ },
1392
+ // ── Mass assignment ──
1393
+ {
1394
+ id: "hard-mass-assignment",
1395
+ description: "Mass assignment allowing privilege escalation",
1396
+ language: "typescript",
1397
+ code: `app.put("/api/users/:id", async (req, res) => {
1398
+ // Directly spreading user input into DB update — allows setting isAdmin, role, etc.
1399
+ await db.query("UPDATE users SET ? WHERE id = ?", [req.body, req.params.id]);
1400
+ res.json({ updated: true });
1401
+ });
1402
+
1403
+ app.post("/api/register", async (req, res) => {
1404
+ const user = { ...req.body, createdAt: new Date() };
1405
+ await db.query("INSERT INTO users SET ?", [user]);
1406
+ res.json({ id: user.id });
1407
+ });`,
1408
+ expectedRuleIds: ["CYBER-001", "SEC-001"],
1409
+ category: "security",
1410
+ difficulty: "hard",
1411
+ },
1412
+ // ── Open redirect ──
1413
+ {
1414
+ id: "hard-open-redirect",
1415
+ description: "Open redirect via unvalidated user-controlled redirect URL",
1416
+ language: "typescript",
1417
+ code: `app.get("/login/callback", (req, res) => {
1418
+ const returnTo = req.query.returnTo as string || "/dashboard";
1419
+ // Authenticate user...
1420
+ res.redirect(returnTo);
1421
+ });
1422
+
1423
+ app.get("/logout", (req, res) => {
1424
+ req.session.destroy(() => {
1425
+ res.redirect(req.query.next as string);
1426
+ });
1427
+ });`,
1428
+ expectedRuleIds: ["CYBER-001", "SEC-001"],
1429
+ category: "security",
1430
+ difficulty: "hard",
1431
+ },
1432
+ // ── Timing attack on comparison ──
1433
+ {
1434
+ id: "hard-timing-attack",
1435
+ description: "Non-constant-time string comparison for secrets",
1436
+ language: "typescript",
1437
+ code: `app.post("/api/webhook", (req, res) => {
1438
+ const signature = req.headers["x-webhook-signature"] as string;
1439
+ const expected = computeHmac(req.body, process.env.WEBHOOK_SECRET!);
1440
+ if (signature === expected) {
1441
+ processWebhook(req.body);
1442
+ res.json({ ok: true });
1443
+ } else {
1444
+ res.status(401).json({ error: "Invalid signature" });
1445
+ }
1446
+ });`,
1447
+ expectedRuleIds: ["AUTH-001", "SEC-001", "CYBER-001"],
1448
+ category: "auth",
1449
+ difficulty: "hard",
1450
+ },
1451
+ // ── Python pickle deserialization ──
1452
+ {
1453
+ id: "hard-python-pickle",
1454
+ description: "Python pickle deserialization of untrusted data",
1455
+ language: "python",
1456
+ code: `import pickle
1457
+ import base64
1458
+ from flask import Flask, request
1459
+
1460
+ app = Flask(__name__)
1461
+
1462
+ @app.route("/load", methods=["POST"])
1463
+ def load_data():
1464
+ encoded = request.form.get("data")
1465
+ data = pickle.loads(base64.b64decode(encoded))
1466
+ return str(data)`,
1467
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
1468
+ category: "injection",
1469
+ difficulty: "hard",
1470
+ },
1471
+ // ── Go race condition with shared state ──
1472
+ {
1473
+ id: "hard-go-race-condition",
1474
+ description: "Go HTTP handler with unsynchronized shared map",
1475
+ language: "go",
1476
+ code: `package main
1477
+
1478
+ import (
1479
+ "net/http"
1480
+ "encoding/json"
1481
+ )
1482
+
1483
+ var cache = make(map[string]string)
1484
+
1485
+ func handler(w http.ResponseWriter, r *http.Request) {
1486
+ key := r.URL.Query().Get("key")
1487
+ if r.Method == "GET" {
1488
+ json.NewEncoder(w).Encode(cache[key])
1489
+ } else {
1490
+ val := r.URL.Query().Get("val")
1491
+ cache[key] = val
1492
+ w.Write([]byte("ok"))
1493
+ }
1494
+ }`,
1495
+ expectedRuleIds: ["CONC-001"],
1496
+ category: "concurrency",
1497
+ difficulty: "hard",
1498
+ },
1499
+ // ── Java XXE ──
1500
+ {
1501
+ id: "hard-java-xxe",
1502
+ description: "Java XML External Entity injection",
1503
+ language: "java",
1504
+ code: `import javax.xml.parsers.*;
1505
+ import org.w3c.dom.*;
1506
+ import javax.servlet.http.*;
1507
+ import java.io.*;
1508
+
1509
+ public class XmlServlet extends HttpServlet {
1510
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
1511
+ throws Exception {
1512
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1513
+ DocumentBuilder builder = factory.newDocumentBuilder();
1514
+ Document doc = builder.parse(req.getInputStream());
1515
+ String name = doc.getElementsByTagName("name").item(0).getTextContent();
1516
+ resp.getWriter().write("Hello " + name);
1517
+ }
1518
+ }`,
1519
+ expectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001"],
1520
+ category: "injection",
1521
+ difficulty: "hard",
1522
+ },
1523
+ // ── C# SQL injection via dynamic LINQ ──
1524
+ {
1525
+ id: "hard-csharp-sql-injection",
1526
+ description: "C# SQL injection via string interpolation in Entity Framework",
1527
+ language: "csharp",
1528
+ code: `using Microsoft.AspNetCore.Mvc;
1529
+ using Microsoft.EntityFrameworkCore;
1530
+
1531
+ [ApiController]
1532
+ [Route("api/[controller]")]
1533
+ public class UsersController : ControllerBase
1534
+ {
1535
+ private readonly AppDbContext _db;
1536
+
1537
+ [HttpGet("search")]
1538
+ public async Task<IActionResult> Search(string query)
1539
+ {
1540
+ var users = await _db.Users
1541
+ .FromSqlRaw($"SELECT * FROM Users WHERE Name LIKE '%{query}%'")
1542
+ .ToListAsync();
1543
+ return Ok(users);
1544
+ }
1545
+ }`,
1546
+ expectedRuleIds: ["CYBER-001", "CYBER-002"],
1547
+ category: "injection",
1548
+ difficulty: "hard",
1549
+ },
1550
+ // ── Rust unsafe memory access ──
1551
+ {
1552
+ id: "hard-rust-unsafe",
1553
+ description: "Rust unsafe block with unchecked pointer arithmetic",
1554
+ language: "rust",
1555
+ code: `use std::io::Read;
1556
+
1557
+ fn parse_packet(data: &[u8]) -> u64 {
1558
+ unsafe {
1559
+ let ptr = data.as_ptr();
1560
+ let len_ptr = ptr.add(4) as *const u32;
1561
+ let payload_len = *len_ptr as usize;
1562
+ // No bounds check — could read past buffer
1563
+ let value_ptr = ptr.add(8 + payload_len) as *const u64;
1564
+ *value_ptr
1565
+ }
1566
+ }`,
1567
+ expectedRuleIds: ["CYBER-001", "SEC-001"],
1568
+ category: "security",
1569
+ difficulty: "hard",
1570
+ },
1571
+ // ── Clean code — hardened Node.js (hard negative) ──
1572
+ {
1573
+ id: "clean-code-hardened-node",
1574
+ description: "Hardened Node.js service with CSP, rate-limit, validation, structured logging",
1575
+ language: "typescript",
1576
+ code: `import express from "express";
1577
+ import helmet from "helmet";
1578
+ import rateLimit from "express-rate-limit";
1579
+ import { z } from "zod";
1580
+ import pino from "pino";
1581
+ import crypto from "crypto";
1582
+
1583
+ const logger = pino({ level: "info" });
1584
+ const app = express();
1585
+ app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ["'self'"] } } }));
1586
+ app.use(express.json({ limit: "1kb" }));
1587
+ app.use(rateLimit({ windowMs: 60_000, max: 30, standardHeaders: true }));
1588
+
1589
+ const LoginSchema = z.object({
1590
+ email: z.string().email().max(254),
1591
+ password: z.string().min(12).max(128),
1592
+ });
1593
+
1594
+ app.post("/api/v1/login", async (req, res) => {
1595
+ const parsed = LoginSchema.safeParse(req.body);
1596
+ if (!parsed.success) return res.status(400).json({ error: parsed.error.issues });
1597
+ const user = await db.users.findUnique({ where: { email: parsed.data.email } });
1598
+ if (!user) return res.status(401).json({ error: "Invalid credentials" });
1599
+ const valid = await argon2.verify(user.passwordHash, parsed.data.password);
1600
+ if (!valid) { logger.warn({ email: parsed.data.email }, "Failed login"); return res.status(401).json({ error: "Invalid credentials" }); }
1601
+ const token = crypto.randomBytes(32).toString("hex");
1602
+ logger.info({ userId: user.id }, "Login success");
1603
+ res.json({ token });
1604
+ });`,
1605
+ expectedRuleIds: [],
1606
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001", "SEC-001", "RATE-001"],
1607
+ category: "clean",
1608
+ difficulty: "hard",
1609
+ },
1610
+ // ── FP Benchmark Corpus — Multi-Language Clean Code ──────────────────────
1611
+ // These cases are well-written code that should NOT trigger findings.
1612
+ // They measure the false positive rate across languages.
1613
+ // ────────────────────────────────────────────────────────────────────────────
1614
+ // ── Clean Python: FastAPI with Pydantic validation ──
1615
+ {
1616
+ id: "clean-python-fastapi",
1617
+ description: "Well-structured FastAPI endpoint with Pydantic validation, auth, and error handling",
1618
+ language: "python",
1619
+ code: `from fastapi import FastAPI, Depends, HTTPException, status
1620
+ from fastapi.security import OAuth2PasswordBearer
1621
+ from pydantic import BaseModel, EmailStr, Field
1622
+ from slowapi import Limiter
1623
+ from slowapi.util import get_remote_address
1624
+ import logging
1625
+ import secrets
1626
+
1627
+ app = FastAPI()
1628
+ limiter = Limiter(key_func=get_remote_address)
1629
+ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
1630
+ logger = logging.getLogger(__name__)
1631
+
1632
+ class UserCreate(BaseModel):
1633
+ email: EmailStr
1634
+ password: str = Field(min_length=12, max_length=128)
1635
+ name: str = Field(min_length=1, max_length=200)
1636
+
1637
+ @app.post("/api/v1/users", status_code=status.HTTP_201_CREATED)
1638
+ @limiter.limit("10/minute")
1639
+ async def create_user(user: UserCreate, token: str = Depends(oauth2_scheme)):
1640
+ current_user = await verify_token(token)
1641
+ if not current_user.is_admin:
1642
+ raise HTTPException(status_code=403, detail="Admin access required")
1643
+ hashed = bcrypt.hashpw(user.password.encode(), bcrypt.gensalt())
1644
+ new_user = await db.users.create(email=user.email, password_hash=hashed, name=user.name)
1645
+ logger.info("User created: %s by admin %s", new_user.id, current_user.id)
1646
+ return {"id": new_user.id, "email": new_user.email}`,
1647
+ expectedRuleIds: [],
1648
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001", "SEC-001", "RATE-001", "DATA-001"],
1649
+ category: "clean",
1650
+ difficulty: "hard",
1651
+ },
1652
+ // ── Clean Go: HTTP handler with proper error handling ──
1653
+ {
1654
+ id: "clean-go-handler",
1655
+ description: "Well-structured Go HTTP handler with parameterized queries, auth, and logging",
1656
+ language: "go",
1657
+ code: `package handlers
1658
+
1659
+ import (
1660
+ "encoding/json"
1661
+ "log/slog"
1662
+ "net/http"
1663
+ "github.com/go-chi/chi/v5"
1664
+ "github.com/jmoiron/sqlx"
1665
+ )
1666
+
1667
+ type UserHandler struct {
1668
+ db *sqlx.DB
1669
+ logger *slog.Logger
1670
+ }
1671
+
1672
+ type CreateUserRequest struct {
1673
+ Email string \`json:"email" validate:"required,email"\`
1674
+ Name string \`json:"name" validate:"required,min=1,max=200"\`
1675
+ }
1676
+
1677
+ func (h *UserHandler) GetUser(w http.ResponseWriter, r *http.Request) {
1678
+ userID := chi.URLParam(r, "id")
1679
+ if userID == "" {
1680
+ http.Error(w, "missing user id", http.StatusBadRequest)
1681
+ return
1682
+ }
1683
+ var user User
1684
+ err := h.db.QueryRowContext(r.Context(), "SELECT id, email, name FROM users WHERE id = $1", userID).Scan(&user.ID, &user.Email, &user.Name)
1685
+ if err != nil {
1686
+ h.logger.Error("failed to fetch user", "error", err, "user_id", userID)
1687
+ http.Error(w, "user not found", http.StatusNotFound)
1688
+ return
1689
+ }
1690
+ w.Header().Set("Content-Type", "application/json")
1691
+ json.NewEncoder(w).Encode(user)
1692
+ }`,
1693
+ expectedRuleIds: [],
1694
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "ERR-001"],
1695
+ category: "clean",
1696
+ difficulty: "hard",
1697
+ },
1698
+ // ── Clean Rust: Safe web handler ──
1699
+ {
1700
+ id: "clean-rust-handler",
1701
+ description: "Well-structured Rust Actix-web handler with validation and error types",
1702
+ language: "rust",
1703
+ code: `use actix_web::{web, HttpResponse, Result};
1704
+ use serde::{Deserialize, Serialize};
1705
+ use sqlx::PgPool;
1706
+ use validator::Validate;
1707
+ use tracing::{info, error};
1708
+
1709
+ #[derive(Deserialize, Validate)]
1710
+ pub struct CreateItemRequest {
1711
+ #[validate(length(min = 1, max = 200))]
1712
+ pub name: String,
1713
+ #[validate(range(min = 0.01, max = 999999.99))]
1714
+ pub price: f64,
1715
+ }
1716
+
1717
+ #[derive(Serialize)]
1718
+ pub struct ItemResponse {
1719
+ pub id: i64,
1720
+ pub name: String,
1721
+ pub price: f64,
1722
+ }
1723
+
1724
+ pub async fn create_item(
1725
+ pool: web::Data<PgPool>,
1726
+ body: web::Json<CreateItemRequest>,
1727
+ ) -> Result<HttpResponse> {
1728
+ body.validate().map_err(|e| {
1729
+ actix_web::error::ErrorBadRequest(format!("Validation error: {}", e))
1730
+ })?;
1731
+ let row = sqlx::query_as!(
1732
+ ItemResponse,
1733
+ "INSERT INTO items (name, price) VALUES ($1, $2) RETURNING id, name, price",
1734
+ body.name,
1735
+ body.price,
1736
+ )
1737
+ .fetch_one(pool.get_ref())
1738
+ .await
1739
+ .map_err(|e| {
1740
+ error!("DB insert failed: {}", e);
1741
+ actix_web::error::ErrorInternalServerError("Failed to create item")
1742
+ })?;
1743
+ info!(item_id = row.id, "Item created");
1744
+ Ok(HttpResponse::Created().json(row))
1745
+ }`,
1746
+ expectedRuleIds: [],
1747
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "ERR-001"],
1748
+ category: "clean",
1749
+ difficulty: "hard",
1750
+ },
1751
+ // ── Clean Java: Spring Boot controller with validation ──
1752
+ {
1753
+ id: "clean-java-spring",
1754
+ description: "Well-structured Spring Boot REST controller with validation and auth",
1755
+ language: "java",
1756
+ code: `import org.springframework.web.bind.annotation.*;
1757
+ import org.springframework.http.ResponseEntity;
1758
+ import org.springframework.security.access.prepost.PreAuthorize;
1759
+ import javax.validation.Valid;
1760
+ import org.slf4j.Logger;
1761
+ import org.slf4j.LoggerFactory;
1762
+
1763
+ @RestController
1764
+ @RequestMapping("/api/v1/products")
1765
+ public class ProductController {
1766
+ private static final Logger log = LoggerFactory.getLogger(ProductController.class);
1767
+ private final ProductService productService;
1768
+
1769
+ public ProductController(ProductService productService) {
1770
+ this.productService = productService;
1771
+ }
1772
+
1773
+ @GetMapping("/{id}")
1774
+ public ResponseEntity<ProductDTO> getProduct(@PathVariable Long id) {
1775
+ return productService.findById(id)
1776
+ .map(ResponseEntity::ok)
1777
+ .orElse(ResponseEntity.notFound().build());
1778
+ }
1779
+
1780
+ @PostMapping
1781
+ @PreAuthorize("hasRole('ADMIN')")
1782
+ public ResponseEntity<ProductDTO> createProduct(@Valid @RequestBody CreateProductRequest request) {
1783
+ log.info("Creating product: {}", request.getName());
1784
+ ProductDTO created = productService.create(request);
1785
+ return ResponseEntity.status(201).body(created);
1786
+ }
1787
+
1788
+ @DeleteMapping("/{id}")
1789
+ @PreAuthorize("hasRole('ADMIN')")
1790
+ public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
1791
+ log.info("Deleting product: {}", id);
1792
+ productService.delete(id);
1793
+ return ResponseEntity.noContent().build();
1794
+ }
1795
+ }`,
1796
+ expectedRuleIds: [],
1797
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001", "SEC-001"],
1798
+ category: "clean",
1799
+ difficulty: "hard",
1800
+ },
1801
+ // ── Clean C#: ASP.NET Core controller ──
1802
+ {
1803
+ id: "clean-csharp-aspnet",
1804
+ description: "Well-structured ASP.NET Core controller with EF Core parameterized queries",
1805
+ language: "csharp",
1806
+ code: `using Microsoft.AspNetCore.Mvc;
1807
+ using Microsoft.AspNetCore.Authorization;
1808
+ using Microsoft.EntityFrameworkCore;
1809
+ using Microsoft.Extensions.Logging;
1810
+ using FluentValidation;
1811
+
1812
+ [ApiController]
1813
+ [Route("api/v1/[controller]")]
1814
+ [Authorize]
1815
+ public class OrdersController : ControllerBase
1816
+ {
1817
+ private readonly AppDbContext _db;
1818
+ private readonly ILogger<OrdersController> _logger;
1819
+ private readonly IValidator<CreateOrderRequest> _validator;
1820
+
1821
+ public OrdersController(AppDbContext db, ILogger<OrdersController> logger, IValidator<CreateOrderRequest> validator)
1822
+ {
1823
+ _db = db;
1824
+ _logger = logger;
1825
+ _validator = validator;
1826
+ }
1827
+
1828
+ [HttpGet("{id}")]
1829
+ public async Task<IActionResult> GetOrder(int id)
1830
+ {
1831
+ var order = await _db.Orders
1832
+ .Where(o => o.Id == id && o.UserId == User.GetUserId())
1833
+ .FirstOrDefaultAsync();
1834
+ if (order == null) return NotFound();
1835
+ return Ok(order);
1836
+ }
1837
+
1838
+ [HttpPost]
1839
+ public async Task<IActionResult> CreateOrder([FromBody] CreateOrderRequest request)
1840
+ {
1841
+ var validation = await _validator.ValidateAsync(request);
1842
+ if (!validation.IsValid) return BadRequest(validation.Errors);
1843
+ var order = new Order { UserId = User.GetUserId(), Total = request.Total, Items = request.Items };
1844
+ _db.Orders.Add(order);
1845
+ await _db.SaveChangesAsync();
1846
+ _logger.LogInformation("Order {OrderId} created by user {UserId}", order.Id, User.GetUserId());
1847
+ return CreatedAtAction(nameof(GetOrder), new { id = order.Id }, order);
1848
+ }
1849
+ }`,
1850
+ expectedRuleIds: [],
1851
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "AUTH-001", "SEC-001", "DATA-001"],
1852
+ category: "clean",
1853
+ difficulty: "hard",
1854
+ },
1855
+ // ── Clean TypeScript: Pure utility library (no server) ──
1856
+ {
1857
+ id: "clean-ts-utility-lib",
1858
+ description: "Pure TypeScript utility library — no server code, should have zero security findings",
1859
+ language: "typescript",
1860
+ code: `/**
1861
+ * A type-safe result type for error handling without exceptions.
1862
+ */
1863
+ export type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
1864
+
1865
+ export function ok<T>(value: T): Result<T, never> {
1866
+ return { ok: true, value };
1867
+ }
1868
+
1869
+ export function err<E>(error: E): Result<never, E> {
1870
+ return { ok: false, error };
1871
+ }
1872
+
1873
+ export function map<T, U, E>(result: Result<T, E>, fn: (value: T) => U): Result<U, E> {
1874
+ return result.ok ? ok(fn(result.value)) : result;
1875
+ }
1876
+
1877
+ export function flatMap<T, U, E>(result: Result<T, E>, fn: (value: T) => Result<U, E>): Result<U, E> {
1878
+ return result.ok ? fn(result.value) : result;
1879
+ }
1880
+
1881
+ export function unwrapOr<T, E>(result: Result<T, E>, defaultValue: T): T {
1882
+ return result.ok ? result.value : defaultValue;
1883
+ }
1884
+
1885
+ /** Retry an async operation with exponential backoff. */
1886
+ export async function retry<T>(fn: () => Promise<T>, maxRetries = 3, baseDelay = 100): Promise<T> {
1887
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1888
+ try {
1889
+ return await fn();
1890
+ } catch (error) {
1891
+ if (attempt === maxRetries) throw error;
1892
+ await new Promise((r) => setTimeout(r, baseDelay * Math.pow(2, attempt)));
1893
+ }
1894
+ }
1895
+ throw new Error("Unreachable");
1896
+ }`,
1897
+ expectedRuleIds: [],
1898
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "AUTH-001", "RATE-001", "ERR-001"],
1899
+ category: "clean",
1900
+ difficulty: "hard",
1901
+ },
1902
+ // ── Clean Terraform: Hardened AWS infrastructure ──
1903
+ {
1904
+ id: "clean-terraform-hardened",
1905
+ description: "Terraform with encryption, private access, and proper security groups",
1906
+ language: "hcl",
1907
+ code: `terraform {
1908
+ required_providers {
1909
+ aws = {
1910
+ source = "hashicorp/aws"
1911
+ version = "~> 5.0"
1912
+ }
1913
+ }
1914
+
1915
+ backend "s3" {
1916
+ bucket = "myapp-terraform-state"
1917
+ key = "prod/terraform.tfstate"
1918
+ region = "us-east-1"
1919
+ dynamodb_table = "terraform-locks"
1920
+ encrypt = true
1921
+ }
1922
+ }
1923
+
1924
+ provider "aws" {
1925
+ region = "us-east-1"
1926
+
1927
+ default_tags {
1928
+ tags = {
1929
+ Environment = "production"
1930
+ Project = "myapp"
1931
+ ManagedBy = "terraform"
1932
+ }
1933
+ }
1934
+ }
1935
+
1936
+ resource "aws_s3_bucket" "data" {
1937
+ bucket = "myapp-data-prod"
1938
+ }
1939
+
1940
+ resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
1941
+ bucket = aws_s3_bucket.data.id
1942
+ rule {
1943
+ apply_server_side_encryption_by_default {
1944
+ sse_algorithm = "aws:kms"
1945
+ }
1946
+ }
1947
+ }
1948
+
1949
+ resource "aws_s3_bucket_public_access_block" "data" {
1950
+ bucket = aws_s3_bucket.data.id
1951
+ block_public_acls = true
1952
+ block_public_policy = true
1953
+ ignore_public_acls = true
1954
+ restrict_public_buckets = true
1955
+ }
1956
+
1957
+ resource "aws_db_instance" "main" {
1958
+ engine = "postgres"
1959
+ instance_class = "db.r6g.large"
1960
+ publicly_accessible = false
1961
+ storage_encrypted = true
1962
+ multi_az = true
1963
+ deletion_protection = true
1964
+ backup_retention_period = 7
1965
+ }
1966
+
1967
+ resource "aws_security_group" "web" {
1968
+ name = "web-sg"
1969
+ vpc_id = var.vpc_id
1970
+
1971
+ ingress {
1972
+ from_port = 443
1973
+ to_port = 443
1974
+ protocol = "tcp"
1975
+ cidr_blocks = [var.allowed_cidr]
1976
+ }
1977
+
1978
+ egress {
1979
+ from_port = 0
1980
+ to_port = 0
1981
+ protocol = "-1"
1982
+ cidr_blocks = ["0.0.0.0/0"]
1983
+ }
1984
+ }`,
1985
+ expectedRuleIds: [],
1986
+ unexpectedRuleIds: ["IAC-001", "SEC-001", "CYBER-001", "DATA-001"],
1987
+ category: "clean",
1988
+ difficulty: "hard",
1989
+ },
1990
+ // ── Clean Python: Data processing script (not a server) ──
1991
+ {
1992
+ id: "clean-python-data-script",
1993
+ description: "Python data processing script — no web endpoints, should not flag server concerns",
1994
+ language: "python",
1995
+ code: `"""Data pipeline for aggregating daily sales metrics."""
1996
+ import csv
1997
+ import logging
1998
+ from pathlib import Path
1999
+ from dataclasses import dataclass
2000
+ from typing import Iterator
2001
+
2002
+ logger = logging.getLogger(__name__)
2003
+
2004
+ @dataclass
2005
+ class SalesRecord:
2006
+ date: str
2007
+ product_id: str
2008
+ quantity: int
2009
+ unit_price: float
2010
+
2011
+ @property
2012
+ def total(self) -> float:
2013
+ return self.quantity * self.unit_price
2014
+
2015
+ def read_records(path: Path) -> Iterator[SalesRecord]:
2016
+ with path.open("r", encoding="utf-8") as f:
2017
+ reader = csv.DictReader(f)
2018
+ for row in reader:
2019
+ try:
2020
+ yield SalesRecord(
2021
+ date=row["date"],
2022
+ product_id=row["product_id"],
2023
+ quantity=int(row["quantity"]),
2024
+ unit_price=float(row["unit_price"]),
2025
+ )
2026
+ except (KeyError, ValueError) as e:
2027
+ logger.warning("Skipping invalid row: %s (%s)", row, e)
2028
+
2029
+ def aggregate_by_date(records: Iterator[SalesRecord]) -> dict[str, float]:
2030
+ totals: dict[str, float] = {}
2031
+ for record in records:
2032
+ totals[record.date] = totals.get(record.date, 0.0) + record.total
2033
+ return totals
2034
+
2035
+ if __name__ == "__main__":
2036
+ logging.basicConfig(level=logging.INFO)
2037
+ path = Path("data/sales.csv")
2038
+ if not path.exists():
2039
+ logger.error("File not found: %s", path)
2040
+ raise SystemExit(1)
2041
+ results = aggregate_by_date(read_records(path))
2042
+ for date, total in sorted(results.items()):
2043
+ logger.info("Date: %s, Total: $%.2f", date, total)`,
2044
+ expectedRuleIds: [],
2045
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "AUTH-001", "RATE-001"],
2046
+ category: "clean",
2047
+ difficulty: "hard",
2048
+ },
2049
+ // ── Clean Go: CLI tool (not a server) ──
2050
+ {
2051
+ id: "clean-go-cli-tool",
2052
+ description: "Go CLI tool — should not flag server-side security concerns",
2053
+ language: "go",
2054
+ code: `package main
2055
+
2056
+ import (
2057
+ "encoding/json"
2058
+ "flag"
2059
+ "fmt"
2060
+ "log"
2061
+ "os"
2062
+ "path/filepath"
2063
+ "sort"
2064
+ )
2065
+
2066
+ type Config struct {
2067
+ InputDir string \`json:"input_dir"\`
2068
+ OutputDir string \`json:"output_dir"\`
2069
+ Verbose bool \`json:"verbose"\`
2070
+ }
2071
+
2072
+ func loadConfig(path string) (*Config, error) {
2073
+ data, err := os.ReadFile(path)
2074
+ if err != nil {
2075
+ return nil, fmt.Errorf("read config: %w", err)
2076
+ }
2077
+ var cfg Config
2078
+ if err := json.Unmarshal(data, &cfg); err != nil {
2079
+ return nil, fmt.Errorf("parse config: %w", err)
2080
+ }
2081
+ return &cfg, nil
2082
+ }
2083
+
2084
+ func processFiles(cfg *Config) error {
2085
+ entries, err := os.ReadDir(cfg.InputDir)
2086
+ if err != nil {
2087
+ return fmt.Errorf("read dir: %w", err)
2088
+ }
2089
+ sort.Slice(entries, func(i, j int) bool { return entries[i].Name() < entries[j].Name() })
2090
+ for _, entry := range entries {
2091
+ if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" {
2092
+ continue
2093
+ }
2094
+ src := filepath.Join(cfg.InputDir, entry.Name())
2095
+ dst := filepath.Join(cfg.OutputDir, entry.Name())
2096
+ if cfg.Verbose {
2097
+ log.Printf("Processing: %s -> %s", src, dst)
2098
+ }
2099
+ data, err := os.ReadFile(src)
2100
+ if err != nil {
2101
+ log.Printf("Warning: skip %s: %v", src, err)
2102
+ continue
2103
+ }
2104
+ if err := os.WriteFile(dst, data, 0644); err != nil {
2105
+ return fmt.Errorf("write %s: %w", dst, err)
2106
+ }
2107
+ }
2108
+ return nil
2109
+ }
2110
+
2111
+ func main() {
2112
+ configPath := flag.String("config", "config.json", "path to config file")
2113
+ flag.Parse()
2114
+ cfg, err := loadConfig(*configPath)
2115
+ if err != nil {
2116
+ log.Fatal(err)
2117
+ }
2118
+ if err := processFiles(cfg); err != nil {
2119
+ log.Fatal(err)
2120
+ }
2121
+ fmt.Println("Done.")
2122
+ }`,
2123
+ expectedRuleIds: [],
2124
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "AUTH-001", "RATE-001", "ERR-001"],
2125
+ category: "clean",
2126
+ difficulty: "hard",
2127
+ },
2128
+ // ── Clean TypeScript: React component (not a server) ──
2129
+ {
2130
+ id: "clean-ts-react-component",
2131
+ description: "React component with hooks — should not trigger server-side security findings",
2132
+ language: "typescript",
2133
+ code: `import React, { useState, useCallback, useMemo } from "react";
2134
+
2135
+ interface User {
2136
+ id: string;
2137
+ name: string;
2138
+ email: string;
2139
+ }
2140
+
2141
+ interface UserListProps {
2142
+ users: User[];
2143
+ onSelect: (user: User) => void;
2144
+ searchLabel?: string;
2145
+ }
2146
+
2147
+ export function UserList({ users, onSelect, searchLabel = "Search users" }: UserListProps): React.JSX.Element {
2148
+ const [filter, setFilter] = useState("");
2149
+
2150
+ const handleFilterChange = useCallback(
2151
+ (event: React.ChangeEvent<HTMLInputElement>) => {
2152
+ setFilter(event.target.value);
2153
+ },
2154
+ [],
2155
+ );
2156
+
2157
+ const filteredUsers = useMemo(() => {
2158
+ const lower = filter.toLowerCase();
2159
+ return users.filter(
2160
+ (u) => u.name.toLowerCase().includes(lower) || u.email.toLowerCase().includes(lower),
2161
+ );
2162
+ }, [users, filter]);
2163
+
2164
+ return (
2165
+ <div role="search" aria-label={searchLabel}>
2166
+ <label htmlFor="user-search">{searchLabel}</label>
2167
+ <input
2168
+ id="user-search"
2169
+ type="text"
2170
+ value={filter}
2171
+ onChange={handleFilterChange}
2172
+ placeholder="Type to filter..."
2173
+ aria-describedby="user-count"
2174
+ />
2175
+ <p id="user-count" aria-live="polite">
2176
+ {filteredUsers.length} users found
2177
+ </p>
2178
+ <ul role="list">
2179
+ {filteredUsers.map((user) => (
2180
+ <li key={user.id}>
2181
+ <button onClick={() => onSelect(user)} aria-label={\`Select \${user.name}\`}>
2182
+ {user.name} ({user.email})
2183
+ </button>
2184
+ </li>
2185
+ ))}
2186
+ </ul>
2187
+ </div>
2188
+ );
2189
+ }`,
2190
+ expectedRuleIds: [],
2191
+ unexpectedRuleIds: ["CYBER-001", "CYBER-002", "SEC-001", "AUTH-001", "A11Y-001"],
2192
+ category: "clean",
2193
+ difficulty: "hard",
2194
+ },
2195
+ // ── Expanded benchmark cases ──
2196
+ ...EXPANDED_BENCHMARK_CASES,
2197
+ ...EXPANDED_BENCHMARK_CASES_2,
2198
+ ...BENCHMARK_SECURITY_DEEP,
2199
+ ...BENCHMARK_QUALITY_OPS,
2200
+ ...BENCHMARK_LANGUAGES,
2201
+ ...BENCHMARK_INFRASTRUCTURE,
2202
+ ...BENCHMARK_COMPLIANCE_ETHICS,
2203
+ ...BENCHMARK_AI_AGENTS,
2204
+ ...BENCHMARK_ADVANCED_CASES,
2205
+ ...BENCHMARK_AI_OUTPUT,
2206
+ ];
2207
+ // ─── Benchmark Runner ───────────────────────────────────────────────────────
2208
+ export function runBenchmarkSuite(cases, judgeId) {
2209
+ const testCases = cases || BENCHMARK_CASES;
2210
+ const caseResults = [];
2211
+ const perCategory = {};
2212
+ const perJudge = {};
2213
+ const perDifficulty = {};
2214
+ const perAISource = {};
2215
+ let totalTP = 0;
2216
+ let totalFN = 0;
2217
+ let totalFP = 0;
2218
+ let totalDetected = 0;
2219
+ let totalStrictTP = 0;
2220
+ let totalStrictFN = 0;
2221
+ for (const tc of testCases) {
2222
+ let findings;
2223
+ if (judgeId) {
2224
+ const judge = getJudge(judgeId);
2225
+ if (!judge)
2226
+ continue;
2227
+ const evaluation = evaluateWithJudge(judge, tc.code, tc.language);
2228
+ findings = evaluation.findings;
2229
+ }
2230
+ else {
2231
+ const verdict = evaluateWithTribunal(tc.code, tc.language);
2232
+ findings = verdict.findings;
2233
+ }
2234
+ // Collect ruleIds including cross-references from dedup annotations
2235
+ const allRuleIds = new Set(findings.map((f) => f.ruleId));
2236
+ for (const f of findings) {
2237
+ const m = f.description.match(/_Also identified by:\s*(.+?)_/);
2238
+ if (m) {
2239
+ for (const id of m[1].split(/,\s*/)) {
2240
+ if (id.match(/^[A-Z]+-\d+$/))
2241
+ allRuleIds.add(id);
2242
+ }
2243
+ }
2244
+ }
2245
+ const foundRuleIds = [...allRuleIds];
2246
+ // Prefix-based matching (lenient — CYBER-001 matches any CYBER-*)
2247
+ const expectedPrefixes = new Set(tc.expectedRuleIds.map((r) => r.split("-")[0]));
2248
+ const detectedPrefixes = new Set(foundRuleIds.map((r) => r.split("-")[0]));
2249
+ const matchedExpected = tc.expectedRuleIds.filter((expected) => {
2250
+ const prefix = expected.split("-")[0];
2251
+ return detectedPrefixes.has(prefix);
2252
+ });
2253
+ const missedExpected = tc.expectedRuleIds.filter((expected) => {
2254
+ const prefix = expected.split("-")[0];
2255
+ return !detectedPrefixes.has(prefix);
2256
+ });
2257
+ const falsePositiveIds = tc.unexpectedRuleIds
2258
+ ? foundRuleIds.filter((found) => {
2259
+ const prefix = found.split("-")[0];
2260
+ return tc.unexpectedRuleIds.some((u) => u.split("-")[0] === prefix);
2261
+ })
2262
+ : [];
2263
+ // Strict matching (exact rule-ID: CYBER-001 only matches CYBER-001)
2264
+ const foundRuleIdSet = new Set(foundRuleIds);
2265
+ const strictMatchedExpected = tc.expectedRuleIds.filter((expected) => foundRuleIdSet.has(expected));
2266
+ const strictMissedExpected = tc.expectedRuleIds.filter((expected) => !foundRuleIdSet.has(expected));
2267
+ const caseTP = matchedExpected.length;
2268
+ const caseFN = missedExpected.length;
2269
+ const caseFP = falsePositiveIds.length;
2270
+ const casePassed = tc.expectedRuleIds.length === 0 ? falsePositiveIds.length === 0 : matchedExpected.length > 0;
2271
+ if (casePassed)
2272
+ totalDetected++;
2273
+ totalTP += caseTP;
2274
+ totalFN += caseFN;
2275
+ totalFP += caseFP;
2276
+ totalStrictTP += strictMatchedExpected.length;
2277
+ totalStrictFN += strictMissedExpected.length;
2278
+ // Per-difficulty tracking
2279
+ if (!perDifficulty[tc.difficulty]) {
2280
+ perDifficulty[tc.difficulty] = { difficulty: tc.difficulty, total: 0, detected: 0, detectionRate: 0 };
2281
+ }
2282
+ perDifficulty[tc.difficulty].total++;
2283
+ if (casePassed)
2284
+ perDifficulty[tc.difficulty].detected++;
2285
+ // Per-AI-source tracking (when cases are tagged)
2286
+ if (tc.aiSource) {
2287
+ if (!perAISource[tc.aiSource]) {
2288
+ perAISource[tc.aiSource] = {
2289
+ category: tc.aiSource,
2290
+ total: 0,
2291
+ detected: 0,
2292
+ truePositives: 0,
2293
+ falseNegatives: 0,
2294
+ falsePositives: 0,
2295
+ precision: 0,
2296
+ recall: 0,
2297
+ f1Score: 0,
2298
+ };
2299
+ }
2300
+ const src = perAISource[tc.aiSource];
2301
+ src.total++;
2302
+ if (casePassed)
2303
+ src.detected++;
2304
+ src.truePositives += caseTP;
2305
+ src.falseNegatives += caseFN;
2306
+ src.falsePositives += caseFP;
2307
+ }
2308
+ caseResults.push({
2309
+ caseId: tc.id,
2310
+ category: tc.category,
2311
+ difficulty: tc.difficulty,
2312
+ passed: casePassed,
2313
+ expectedRuleIds: tc.expectedRuleIds,
2314
+ detectedRuleIds: foundRuleIds,
2315
+ missedRuleIds: missedExpected,
2316
+ falsePositiveRuleIds: falsePositiveIds,
2317
+ findings,
2318
+ });
2319
+ // Per-category accumulators
2320
+ if (!perCategory[tc.category]) {
2321
+ perCategory[tc.category] = {
2322
+ category: tc.category,
2323
+ total: 0,
2324
+ detected: 0,
2325
+ truePositives: 0,
2326
+ falseNegatives: 0,
2327
+ falsePositives: 0,
2328
+ precision: 0,
2329
+ recall: 0,
2330
+ f1Score: 0,
2331
+ };
2332
+ }
2333
+ const cat = perCategory[tc.category];
2334
+ cat.total++;
2335
+ if (casePassed)
2336
+ cat.detected++;
2337
+ cat.truePositives += caseTP;
2338
+ cat.falseNegatives += caseFN;
2339
+ cat.falsePositives += caseFP;
2340
+ // Per-judge accumulators (deduplicate by prefix per case to match case-level FP counting)
2341
+ const seenPrefixes = new Set();
2342
+ for (const ruleId of foundRuleIds) {
2343
+ const prefix = ruleId.split("-")[0];
2344
+ if (seenPrefixes.has(prefix))
2345
+ continue;
2346
+ seenPrefixes.add(prefix);
2347
+ if (!perJudge[prefix]) {
2348
+ perJudge[prefix] = {
2349
+ judgeId: prefix,
2350
+ total: 0,
2351
+ truePositives: 0,
2352
+ falseNegatives: 0,
2353
+ falsePositives: 0,
2354
+ precision: 0,
2355
+ recall: 0,
2356
+ f1Score: 0,
2357
+ };
2358
+ }
2359
+ const jb = perJudge[prefix];
2360
+ jb.total++;
2361
+ if (expectedPrefixes.has(prefix)) {
2362
+ jb.truePositives++;
2363
+ }
2364
+ else {
2365
+ jb.falsePositives++;
2366
+ }
2367
+ }
2368
+ }
2369
+ // Compute final metrics
2370
+ const precision = totalTP + totalFP > 0 ? totalTP / (totalTP + totalFP) : 1;
2371
+ const recall = totalTP + totalFN > 0 ? totalTP / (totalTP + totalFN) : 1;
2372
+ const f1Score = precision + recall > 0 ? (2 * precision * recall) / (precision + recall) : 0;
2373
+ // Strict metrics (exact rule-ID matching)
2374
+ const strictPrecision = totalStrictTP + totalFP > 0 ? totalStrictTP / (totalStrictTP + totalFP) : 1;
2375
+ const strictRecall = totalStrictTP + totalStrictFN > 0 ? totalStrictTP / (totalStrictTP + totalStrictFN) : 1;
2376
+ const strictF1Score = strictPrecision + strictRecall > 0 ? (2 * strictPrecision * strictRecall) / (strictPrecision + strictRecall) : 0;
2377
+ // Compute per-difficulty rates
2378
+ for (const d of Object.values(perDifficulty)) {
2379
+ d.detectionRate = d.total > 0 ? d.detected / d.total : 0;
2380
+ }
2381
+ // Compute per-category metrics
2382
+ for (const cat of Object.values(perCategory)) {
2383
+ cat.precision =
2384
+ cat.truePositives + cat.falsePositives > 0 ? cat.truePositives / (cat.truePositives + cat.falsePositives) : 1;
2385
+ cat.recall =
2386
+ cat.truePositives + cat.falseNegatives > 0 ? cat.truePositives / (cat.truePositives + cat.falseNegatives) : 1;
2387
+ cat.f1Score = cat.precision + cat.recall > 0 ? (2 * cat.precision * cat.recall) / (cat.precision + cat.recall) : 0;
2388
+ }
2389
+ // Compute per-AI-source metrics
2390
+ for (const src of Object.values(perAISource)) {
2391
+ src.precision =
2392
+ src.truePositives + src.falsePositives > 0 ? src.truePositives / (src.truePositives + src.falsePositives) : 1;
2393
+ src.recall =
2394
+ src.truePositives + src.falseNegatives > 0 ? src.truePositives / (src.truePositives + src.falseNegatives) : 1;
2395
+ src.f1Score = src.precision + src.recall > 0 ? (2 * src.precision * src.recall) / (src.precision + src.recall) : 0;
2396
+ }
2397
+ // Compute per-judge metrics
2398
+ for (const jb of Object.values(perJudge)) {
2399
+ jb.precision =
2400
+ jb.truePositives + jb.falsePositives > 0 ? jb.truePositives / (jb.truePositives + jb.falsePositives) : 1;
2401
+ jb.recall =
2402
+ jb.truePositives + jb.falseNegatives > 0 ? jb.truePositives / (jb.truePositives + jb.falseNegatives) : 1;
2403
+ jb.f1Score = jb.precision + jb.recall > 0 ? (2 * jb.precision * jb.recall) / (jb.precision + jb.recall) : 0;
2404
+ }
2405
+ const packageJsonPath = resolve(dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/, "$1")), "../../package.json");
2406
+ let version = "unknown";
2407
+ try {
2408
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
2409
+ version = pkg.version ?? version;
2410
+ }
2411
+ catch {
2412
+ // Fallback if package.json unreadable
2413
+ }
2414
+ return {
2415
+ timestamp: new Date().toISOString(),
2416
+ version,
2417
+ totalCases: testCases.length,
2418
+ detected: totalDetected,
2419
+ missed: testCases.length - totalDetected,
2420
+ totalExpected: testCases.reduce((s, c) => s + c.expectedRuleIds.length, 0),
2421
+ truePositives: totalTP,
2422
+ falseNegatives: totalFN,
2423
+ falsePositives: totalFP,
2424
+ precision,
2425
+ recall,
2426
+ f1Score,
2427
+ detectionRate: testCases.length > 0 ? totalDetected / testCases.length : 0,
2428
+ strictTruePositives: totalStrictTP,
2429
+ strictFalseNegatives: totalStrictFN,
2430
+ strictPrecision,
2431
+ strictRecall,
2432
+ strictF1Score,
2433
+ perCategory,
2434
+ perJudge,
2435
+ perDifficulty,
2436
+ ...(Object.keys(perAISource).length > 0 ? { perAISource } : {}),
2437
+ cases: caseResults,
2438
+ };
2439
+ }
2440
+ /**
2441
+ * Run the benchmark suite and check results against quality thresholds.
2442
+ * Returns a gate result indicating pass/fail with details.
2443
+ *
2444
+ * Usage in CI:
2445
+ * ```ts
2446
+ * const gate = benchmarkGate({ minF1: 0.7 });
2447
+ * if (!gate.passed) process.exit(1);
2448
+ * ```
2449
+ */
2450
+ export function benchmarkGate(options = {}) {
2451
+ const { minF1 = 0.6, minPrecision = 0.5, minRecall = 0.5, minDetectionRate = 0.5, baseline } = options;
2452
+ const result = runBenchmarkSuite();
2453
+ const failures = [];
2454
+ if (result.f1Score < minF1) {
2455
+ failures.push(`F1 score ${(result.f1Score * 100).toFixed(1)}% < minimum ${(minF1 * 100).toFixed(1)}%`);
2456
+ }
2457
+ if (result.precision < minPrecision) {
2458
+ failures.push(`Precision ${(result.precision * 100).toFixed(1)}% < minimum ${(minPrecision * 100).toFixed(1)}%`);
2459
+ }
2460
+ if (result.recall < minRecall) {
2461
+ failures.push(`Recall ${(result.recall * 100).toFixed(1)}% < minimum ${(minRecall * 100).toFixed(1)}%`);
2462
+ }
2463
+ if (result.detectionRate < minDetectionRate) {
2464
+ failures.push(`Detection rate ${(result.detectionRate * 100).toFixed(1)}% < minimum ${(minDetectionRate * 100).toFixed(1)}%`);
2465
+ }
2466
+ if (baseline) {
2467
+ if (result.f1Score < baseline.f1Score - 0.01) {
2468
+ failures.push(`F1 regressed: ${(result.f1Score * 100).toFixed(1)}% vs baseline ${(baseline.f1Score * 100).toFixed(1)}%`);
2469
+ }
2470
+ if (result.precision < baseline.precision - 0.01) {
2471
+ failures.push(`Precision regressed: ${(result.precision * 100).toFixed(1)}% vs baseline ${(baseline.precision * 100).toFixed(1)}%`);
2472
+ }
2473
+ if (result.recall < baseline.recall - 0.01) {
2474
+ failures.push(`Recall regressed: ${(result.recall * 100).toFixed(1)}% vs baseline ${(baseline.recall * 100).toFixed(1)}%`);
2475
+ }
2476
+ if (result.detectionRate < baseline.detectionRate - 0.01) {
2477
+ failures.push(`Detection rate regressed: ${(result.detectionRate * 100).toFixed(1)}% vs baseline ${(baseline.detectionRate * 100).toFixed(1)}%`);
2478
+ }
2479
+ }
2480
+ return { passed: failures.length === 0, failures, result };
2481
+ }
2482
+ // ─── Report Formatting ──────────────────────────────────────────────────────
2483
+ export function formatBenchmarkReport(result) {
2484
+ const lines = [];
2485
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
2486
+ lines.push("║ Judges Panel — Benchmark Report ║");
2487
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
2488
+ lines.push("");
2489
+ lines.push(` Version : ${result.version}`);
2490
+ lines.push(` Test Cases : ${result.totalCases}`);
2491
+ lines.push(` Detection Rate : ${(result.detectionRate * 100).toFixed(1)}%`);
2492
+ lines.push("");
2493
+ lines.push(" Prefix-Based Matching (lenient):");
2494
+ lines.push(` Precision : ${(result.precision * 100).toFixed(1)}%`);
2495
+ lines.push(` Recall : ${(result.recall * 100).toFixed(1)}%`);
2496
+ lines.push(` F1 Score : ${(result.f1Score * 100).toFixed(1)}%`);
2497
+ lines.push("");
2498
+ lines.push(" Exact Rule-ID Matching (strict):");
2499
+ lines.push(` Precision : ${(result.strictPrecision * 100).toFixed(1)}%`);
2500
+ lines.push(` Recall : ${(result.strictRecall * 100).toFixed(1)}%`);
2501
+ lines.push(` F1 Score : ${(result.strictF1Score * 100).toFixed(1)}%`);
2502
+ lines.push("");
2503
+ lines.push(` True Positives : ${result.truePositives} (strict: ${result.strictTruePositives})`);
2504
+ lines.push(` False Negatives : ${result.falseNegatives} (strict: ${result.strictFalseNegatives})`);
2505
+ lines.push(` False Positives : ${result.falsePositives}`);
2506
+ lines.push("");
2507
+ // Per-difficulty breakdown
2508
+ if (result.perDifficulty && Object.keys(result.perDifficulty).length > 0) {
2509
+ lines.push(" Per-Difficulty Detection Rates:");
2510
+ lines.push(" " + "─".repeat(40));
2511
+ for (const diff of ["easy", "medium", "hard"]) {
2512
+ const d = result.perDifficulty[diff];
2513
+ if (d) {
2514
+ const rate = `${d.detected}/${d.total}`.padStart(6);
2515
+ const pct = `${(d.detectionRate * 100).toFixed(1)}%`.padStart(6);
2516
+ lines.push(` ${diff.padEnd(10)} ${rate} ${pct}`);
2517
+ }
2518
+ }
2519
+ lines.push("");
2520
+ }
2521
+ // Per-category breakdown
2522
+ lines.push(" Per-Category Results:");
2523
+ lines.push(" " + "─".repeat(60));
2524
+ for (const [cat, stats] of Object.entries(result.perCategory)) {
2525
+ const name = cat.padEnd(18);
2526
+ const rate = `${stats.detected}/${stats.total}`.padStart(6);
2527
+ const prec = `P:${(stats.precision * 100).toFixed(0)}%`.padStart(6);
2528
+ const rec = `R:${(stats.recall * 100).toFixed(0)}%`.padStart(6);
2529
+ const f1 = `F1:${(stats.f1Score * 100).toFixed(0)}%`.padStart(7);
2530
+ lines.push(` ${name} ${rate} ${prec} ${rec} ${f1}`);
2531
+ }
2532
+ lines.push("");
2533
+ // Failed cases
2534
+ const failed = result.cases.filter((c) => !c.passed);
2535
+ if (failed.length > 0) {
2536
+ lines.push(" Failed Cases:");
2537
+ lines.push(" " + "─".repeat(60));
2538
+ for (const c of failed) {
2539
+ lines.push(` ❌ ${c.caseId} (${c.difficulty})`);
2540
+ if (c.missedRuleIds.length > 0) {
2541
+ lines.push(` Missed: ${c.missedRuleIds.join(", ")}`);
2542
+ }
2543
+ if (c.falsePositiveRuleIds.length > 0) {
2544
+ lines.push(` False+: ${c.falsePositiveRuleIds.join(", ")}`);
2545
+ }
2546
+ }
2547
+ lines.push("");
2548
+ }
2549
+ // Overall grade
2550
+ const grade = result.f1Score >= 0.9
2551
+ ? "A"
2552
+ : result.f1Score >= 0.8
2553
+ ? "B"
2554
+ : result.f1Score >= 0.7
2555
+ ? "C"
2556
+ : result.f1Score >= 0.6
2557
+ ? "D"
2558
+ : "F";
2559
+ lines.push(` Overall Grade: ${grade}`);
2560
+ lines.push("");
2561
+ return lines.join("\n");
2562
+ }
2563
+ // ─── Markdown Report for GitHub Publishing ─────────────────────────────────
2564
+ export function formatBenchmarkMarkdown(result, llmSnapshot) {
2565
+ const lines = [];
2566
+ const pct = (n) => `${(n * 100).toFixed(1)}%`;
2567
+ const grade = result.f1Score >= 0.9
2568
+ ? "A"
2569
+ : result.f1Score >= 0.8
2570
+ ? "B"
2571
+ : result.f1Score >= 0.7
2572
+ ? "C"
2573
+ : result.f1Score >= 0.6
2574
+ ? "D"
2575
+ : "F";
2576
+ const gradeEmoji = grade === "A" ? "🟢" : grade === "B" ? "🟡" : grade === "C" ? "🟠" : "🔴";
2577
+ lines.push("# Judges Panel — Benchmark Report");
2578
+ lines.push("");
2579
+ lines.push(`> Auto-generated on ${result.timestamp} · v${result.version}`);
2580
+ lines.push("");
2581
+ // ── Methodology ──
2582
+ lines.push("## How to Read This Report");
2583
+ lines.push("");
2584
+ lines.push("The Judges Panel uses a **dual-layer architecture** for code analysis:");
2585
+ lines.push("");
2586
+ lines.push("### Layer 1 — Deterministic Analysis (Pattern Matching)");
2587
+ lines.push("The first layer uses deterministic evaluators — regex patterns, AST analysis, and heuristic");
2588
+ lines.push("rules — to identify code issues instantly, offline, and with zero LLM costs. Each of the 45");
2589
+ lines.push("judges has a built-in `analyze()` function that scans code for known patterns. This layer is:");
2590
+ lines.push("- **Fast** — millisecond response times");
2591
+ lines.push("- **Reproducible** — same input always produces the same output");
2592
+ lines.push("- **Free** — no API calls or external dependencies");
2593
+ lines.push("");
2594
+ lines.push("Layer 1 is benchmarked on every commit via automated CI.");
2595
+ lines.push("");
2596
+ lines.push("### Layer 2 — LLM Deep Review (AI-Powered Prompts)");
2597
+ lines.push("The second layer uses expert persona prompts served via MCP (Model Context Protocol) to");
2598
+ lines.push("LLM-based clients like GitHub Copilot and Claude Desktop. When invoked, the calling LLM");
2599
+ lines.push("applies the judge's evaluation criteria to perform a deeper, context-aware analysis that can");
2600
+ lines.push("catch issues pattern matching cannot — such as logical flaws, architectural concerns, and");
2601
+ lines.push("nuanced security vulnerabilities.");
2602
+ lines.push("");
2603
+ lines.push("Layer 2 is benchmarked periodically by sending test cases to an LLM API and scoring the");
2604
+ lines.push("results against expected findings. Because LLM outputs are probabilistic, L2 scores may");
2605
+ lines.push("vary across runs and models.");
2606
+ lines.push("");
2607
+ lines.push("### Metrics Explained");
2608
+ lines.push("| Metric | Description |");
2609
+ lines.push("|--------|-------------|");
2610
+ lines.push("| **Precision** | Of all findings reported, what percentage are real issues? Higher = fewer false alarms. |");
2611
+ lines.push("| **Recall** | Of all known issues, what percentage are detected? Higher = fewer missed issues. |");
2612
+ lines.push("| **F1 Score** | Harmonic mean of precision and recall — the single best indicator of overall accuracy. |");
2613
+ lines.push("| **Detection Rate** | Percentage of test cases where at least one expected issue was found. |");
2614
+ lines.push("| **FP Rate** | False Positive Rate — percentage of findings that are not real issues. |");
2615
+ lines.push("| **Lenient matching** | A finding matches if its rule prefix matches (e.g., CYBER-005 matches expected CYBER-001). |");
2616
+ lines.push("| **Strict matching** | A finding matches only with the exact rule ID. |");
2617
+ lines.push("");
2618
+ lines.push("---");
2619
+ lines.push("");
2620
+ // ── Layer 1 Results ──
2621
+ lines.push("## Layer 1 — Deterministic Analysis");
2622
+ lines.push("");
2623
+ // Summary badges
2624
+ lines.push(`| Metric | Value |`);
2625
+ lines.push(`|--------|-------|`);
2626
+ lines.push(`| Overall Grade | ${gradeEmoji} **${grade}** |`);
2627
+ lines.push(`| Test Cases | ${result.totalCases} |`);
2628
+ lines.push(`| Detection Rate | ${pct(result.detectionRate)} (${result.detected}/${result.totalCases}) |`);
2629
+ lines.push(`| Precision (lenient) | ${pct(result.precision)} |`);
2630
+ lines.push(`| Recall (lenient) | ${pct(result.recall)} |`);
2631
+ lines.push(`| F1 Score (lenient) | ${pct(result.f1Score)} |`);
2632
+ lines.push(`| Precision (strict) | ${pct(result.strictPrecision)} |`);
2633
+ lines.push(`| Recall (strict) | ${pct(result.strictRecall)} |`);
2634
+ lines.push(`| F1 Score (strict) | ${pct(result.strictF1Score)} |`);
2635
+ lines.push(`| True Positives | ${result.truePositives} (strict: ${result.strictTruePositives}) |`);
2636
+ lines.push(`| False Negatives | ${result.falseNegatives} (strict: ${result.strictFalseNegatives}) |`);
2637
+ lines.push(`| False Positives | ${result.falsePositives} |`);
2638
+ lines.push("");
2639
+ // FP Rate section
2640
+ const totalTP = result.truePositives;
2641
+ const totalFP = result.falsePositives;
2642
+ const overallFpRate = totalTP + totalFP > 0 ? totalFP / (totalTP + totalFP) : 0;
2643
+ lines.push("## False Positive Rate");
2644
+ lines.push("");
2645
+ lines.push(`**Overall FP Rate: ${pct(overallFpRate)}**`);
2646
+ lines.push("");
2647
+ lines.push("The false positive rate measures how often the tool flags code that is actually correct.");
2648
+ lines.push("Lower is better. Industry-standard SAST tools typically range from 20-60% FP rates.");
2649
+ lines.push("");
2650
+ // Per-difficulty breakdown
2651
+ if (result.perDifficulty && Object.keys(result.perDifficulty).length > 0) {
2652
+ lines.push("## Detection by Difficulty");
2653
+ lines.push("");
2654
+ lines.push("| Difficulty | Detected | Total | Rate |");
2655
+ lines.push("|------------|----------|-------|------|");
2656
+ for (const diff of ["easy", "medium", "hard"]) {
2657
+ const d = result.perDifficulty[diff];
2658
+ if (d) {
2659
+ lines.push(`| ${diff} | ${d.detected} | ${d.total} | ${pct(d.detectionRate)} |`);
2660
+ }
2661
+ }
2662
+ lines.push("");
2663
+ }
2664
+ // Per-category breakdown
2665
+ lines.push("## Results by Category");
2666
+ lines.push("");
2667
+ lines.push("| Category | Detected | Total | Precision | Recall | F1 | FP Rate |");
2668
+ lines.push("|----------|----------|-------|-----------|--------|-----|---------|");
2669
+ for (const [cat, stats] of Object.entries(result.perCategory).sort(([a], [b]) => a.localeCompare(b))) {
2670
+ const catFpRate = stats.truePositives + stats.falsePositives > 0
2671
+ ? stats.falsePositives / (stats.truePositives + stats.falsePositives)
2672
+ : 0;
2673
+ lines.push(`| ${cat} | ${stats.detected} | ${stats.total} | ${pct(stats.precision)} | ${pct(stats.recall)} | ${pct(stats.f1Score)} | ${pct(catFpRate)} |`);
2674
+ }
2675
+ lines.push("");
2676
+ // Per-judge breakdown
2677
+ if (result.perJudge && Object.keys(result.perJudge).length > 0) {
2678
+ lines.push("## Results by Judge");
2679
+ lines.push("");
2680
+ lines.push("| Judge | Findings | TP | FP | Precision | FP Rate |");
2681
+ lines.push("|-------|----------|-----|-----|-----------|---------|");
2682
+ for (const [judgeId, stats] of Object.entries(result.perJudge).sort(([a], [b]) => a.localeCompare(b))) {
2683
+ const judgeFpRate = stats.truePositives + stats.falsePositives > 0
2684
+ ? stats.falsePositives / (stats.truePositives + stats.falsePositives)
2685
+ : 0;
2686
+ lines.push(`| ${judgeId} | ${stats.total} | ${stats.truePositives} | ${stats.falsePositives} | ${pct(stats.precision)} | ${pct(judgeFpRate)} |`);
2687
+ }
2688
+ lines.push("");
2689
+ }
2690
+ // Clean code / FP test results
2691
+ const cleanCases = result.cases.filter((c) => c.category === "clean");
2692
+ if (cleanCases.length > 0) {
2693
+ lines.push("## Clean Code (False Positive Tests)");
2694
+ lines.push("");
2695
+ lines.push("These test cases are well-written code that should produce **zero** findings.");
2696
+ lines.push("Any finding on these cases is a false positive.");
2697
+ lines.push("");
2698
+ lines.push("| Case | Passed | False Positives |");
2699
+ lines.push("|------|--------|-----------------|");
2700
+ for (const c of cleanCases) {
2701
+ const status = c.passed ? "✅" : "❌";
2702
+ const fps = c.falsePositiveRuleIds.length > 0 ? c.falsePositiveRuleIds.join(", ") : "none";
2703
+ lines.push(`| ${c.caseId} | ${status} | ${fps} |`);
2704
+ }
2705
+ const fpCleanTotal = cleanCases.filter((c) => !c.passed).length;
2706
+ lines.push("");
2707
+ lines.push(`**Clean code FP rate: ${fpCleanTotal}/${cleanCases.length} cases had false positives (${pct(fpCleanTotal / cleanCases.length)})**`);
2708
+ lines.push("");
2709
+ }
2710
+ // Failed cases detail
2711
+ const failed = result.cases.filter((c) => !c.passed);
2712
+ if (failed.length > 0) {
2713
+ lines.push("## Failed Cases");
2714
+ lines.push("");
2715
+ lines.push("| Case | Difficulty | Category | Missed Rules | False Positives |");
2716
+ lines.push("|------|------------|----------|--------------|-----------------|");
2717
+ for (const c of failed) {
2718
+ const missed = c.missedRuleIds.length > 0 ? c.missedRuleIds.join(", ") : "—";
2719
+ const fps = c.falsePositiveRuleIds.length > 0 ? c.falsePositiveRuleIds.join(", ") : "—";
2720
+ lines.push(`| ${c.caseId} | ${c.difficulty} | ${c.category} | ${missed} | ${fps} |`);
2721
+ }
2722
+ lines.push("");
2723
+ }
2724
+ // ── Layer 2 Results (if LLM snapshot available) ──
2725
+ if (llmSnapshot) {
2726
+ lines.push("---");
2727
+ lines.push("");
2728
+ lines.push(formatLlmSnapshotMarkdown(llmSnapshot));
2729
+ // Layer comparison table
2730
+ lines.push("---");
2731
+ lines.push("");
2732
+ lines.push(formatLayerComparisonMarkdown(result, llmSnapshot));
2733
+ }
2734
+ lines.push("---");
2735
+ lines.push("");
2736
+ lines.push("*Generated by [Judges Panel](https://github.com/KevinRabun/judges) benchmark suite.*");
2737
+ lines.push("");
2738
+ return lines.join("\n");
2739
+ }
2740
+ // ─── CLI Command ────────────────────────────────────────────────────────────
2741
+ export function runBenchmark(argv) {
2742
+ const subcommand = argv[3] || "run";
2743
+ if (subcommand === "--help" || subcommand === "-h") {
2744
+ console.log(`
2745
+ Judges Panel — Benchmark Suite
2746
+
2747
+ USAGE:
2748
+ judges benchmark run [--judge <id>] Run benchmark suite
2749
+ judges benchmark report Generate markdown benchmark report
2750
+ judges benchmark compare <a.json> <b.json> Compare two runs
2751
+ judges benchmark l2-coverage Analyze L2 prompt coverage of L1 gaps
2752
+ judges benchmark ingest <file.json> Ingest findings as benchmark cases
2753
+
2754
+ OPTIONS:
2755
+ --judge, -j <id> Benchmark a single judge
2756
+ --output, -o <path> Save results to file
2757
+ --save Save results to benchmark-results.json
2758
+ --format <fmt> Output: text, json, markdown
2759
+ --fresh Re-run benchmark even if saved results exist
2760
+
2761
+ CI GATE OPTIONS:
2762
+ --gate Enable CI gate mode (exit 1 on failure)
2763
+ --min-f1 <n> Minimum F1 score (0-1, default: 0.6)
2764
+ --min-precision <n> Minimum precision (0-1, default: 0.5)
2765
+ --min-recall <n> Minimum recall (0-1, default: 0.5)
2766
+ --min-detection-rate <n> Minimum detection rate (0-1, default: 0.5)
2767
+ --baseline <path> Fail if scores regress from baseline JSON
2768
+ `);
2769
+ process.exit(0);
2770
+ }
2771
+ let judgeId;
2772
+ let outputPath;
2773
+ let format = "text";
2774
+ let gate = false;
2775
+ let save = false;
2776
+ let minF1 = 0.6;
2777
+ let minPrecision = 0.5;
2778
+ let minRecall = 0.5;
2779
+ let minDetectionRate = 0.5;
2780
+ let baselinePath;
2781
+ for (let i = 4; i < argv.length; i++) {
2782
+ const arg = argv[i];
2783
+ if (arg === "--judge" || arg === "-j")
2784
+ judgeId = argv[++i];
2785
+ else if (arg === "--output" || arg === "-o")
2786
+ outputPath = argv[++i];
2787
+ else if (arg === "--save")
2788
+ save = true;
2789
+ else if (arg === "--format")
2790
+ format = argv[++i];
2791
+ else if (arg === "--gate")
2792
+ gate = true;
2793
+ else if (arg === "--min-f1")
2794
+ minF1 = parseFloat(argv[++i]);
2795
+ else if (arg === "--min-precision")
2796
+ minPrecision = parseFloat(argv[++i]);
2797
+ else if (arg === "--min-recall")
2798
+ minRecall = parseFloat(argv[++i]);
2799
+ else if (arg === "--min-detection-rate")
2800
+ minDetectionRate = parseFloat(argv[++i]);
2801
+ else if (arg === "--baseline")
2802
+ baselinePath = argv[++i];
2803
+ }
2804
+ if (subcommand === "run") {
2805
+ const result = runBenchmarkSuite(undefined, judgeId);
2806
+ if (format === "json") {
2807
+ const output = JSON.stringify(result, null, 2);
2808
+ console.log(output);
2809
+ }
2810
+ else {
2811
+ console.log(formatBenchmarkReport(result));
2812
+ }
2813
+ if (outputPath) {
2814
+ const dir = dirname(resolve(outputPath));
2815
+ if (!existsSync(dir))
2816
+ mkdirSync(dir, { recursive: true });
2817
+ writeFileSync(resolve(outputPath), JSON.stringify(result, null, 2), "utf-8");
2818
+ console.log(`\n Results saved to: ${outputPath}`);
2819
+ }
2820
+ // Auto-save to benchmark-results.json
2821
+ if (save && !outputPath) {
2822
+ const savePath = resolve("benchmark-results.json");
2823
+ writeFileSync(savePath, JSON.stringify(result, null, 2), "utf-8");
2824
+ console.log(`\n Results saved to: benchmark-results.json`);
2825
+ }
2826
+ // ── CI Gate ──
2827
+ if (gate) {
2828
+ const failures = [];
2829
+ // Absolute threshold checks
2830
+ if (result.f1Score < minF1) {
2831
+ failures.push(`F1 score ${(result.f1Score * 100).toFixed(1)}% < minimum ${(minF1 * 100).toFixed(1)}%`);
2832
+ }
2833
+ if (result.precision < minPrecision) {
2834
+ failures.push(`Precision ${(result.precision * 100).toFixed(1)}% < minimum ${(minPrecision * 100).toFixed(1)}%`);
2835
+ }
2836
+ if (result.recall < minRecall) {
2837
+ failures.push(`Recall ${(result.recall * 100).toFixed(1)}% < minimum ${(minRecall * 100).toFixed(1)}%`);
2838
+ }
2839
+ if (result.detectionRate < minDetectionRate) {
2840
+ failures.push(`Detection rate ${(result.detectionRate * 100).toFixed(1)}% < minimum ${(minDetectionRate * 100).toFixed(1)}%`);
2841
+ }
2842
+ // Regression checks against baseline
2843
+ if (baselinePath) {
2844
+ try {
2845
+ const baseline = JSON.parse(readFileSync(resolve(baselinePath), "utf-8"));
2846
+ if (result.f1Score < baseline.f1Score - 0.01) {
2847
+ failures.push(`F1 regressed: ${(result.f1Score * 100).toFixed(1)}% vs baseline ${(baseline.f1Score * 100).toFixed(1)}%`);
2848
+ }
2849
+ if (result.precision < baseline.precision - 0.01) {
2850
+ failures.push(`Precision regressed: ${(result.precision * 100).toFixed(1)}% vs baseline ${(baseline.precision * 100).toFixed(1)}%`);
2851
+ }
2852
+ if (result.recall < baseline.recall - 0.01) {
2853
+ failures.push(`Recall regressed: ${(result.recall * 100).toFixed(1)}% vs baseline ${(baseline.recall * 100).toFixed(1)}%`);
2854
+ }
2855
+ if (result.detectionRate < baseline.detectionRate - 0.01) {
2856
+ failures.push(`Detection rate regressed: ${(result.detectionRate * 100).toFixed(1)}% vs baseline ${(baseline.detectionRate * 100).toFixed(1)}%`);
2857
+ }
2858
+ }
2859
+ catch {
2860
+ failures.push(`Failed to read baseline file: ${baselinePath}`);
2861
+ }
2862
+ }
2863
+ if (failures.length > 0) {
2864
+ console.error("\n ❌ CI Gate FAILED:");
2865
+ for (const f of failures) {
2866
+ console.error(` • ${f}`);
2867
+ }
2868
+ console.error("");
2869
+ process.exit(1);
2870
+ }
2871
+ else {
2872
+ console.log("\n ✅ CI Gate PASSED — all thresholds met.");
2873
+ }
2874
+ }
2875
+ process.exit(0);
2876
+ }
2877
+ if (subcommand === "report") {
2878
+ // Generate or display a benchmark report in markdown format
2879
+ const reportOutputPath = argv.find((_, i) => argv[i - 1] === "--output" || argv[i - 1] === "-o") || undefined;
2880
+ const reportFormat = argv.find((_, i) => argv[i - 1] === "--format") || "markdown";
2881
+ // Check if there's a saved result to load, otherwise run fresh
2882
+ let result;
2883
+ const savedPath = resolve("benchmark-results.json");
2884
+ if (existsSync(savedPath) && !argv.includes("--fresh")) {
2885
+ result = JSON.parse(readFileSync(savedPath, "utf-8"));
2886
+ console.log(` Loaded saved benchmark results from: benchmark-results.json`);
2887
+ }
2888
+ else {
2889
+ result = runBenchmarkSuite(undefined, judgeId);
2890
+ }
2891
+ // Load LLM snapshot if available
2892
+ let llmSnapshot;
2893
+ const llmSnapshotPath = resolve("benchmarks/llm-snapshot-latest.json");
2894
+ if (existsSync(llmSnapshotPath)) {
2895
+ try {
2896
+ llmSnapshot = JSON.parse(readFileSync(llmSnapshotPath, "utf-8"));
2897
+ console.log(` Loaded LLM benchmark snapshot: ${llmSnapshot.model} (${new Date(llmSnapshot.timestamp).toLocaleDateString()})`);
2898
+ }
2899
+ catch {
2900
+ /* ignore malformed snapshot */
2901
+ }
2902
+ }
2903
+ if (reportFormat === "json") {
2904
+ const output = JSON.stringify(result, null, 2);
2905
+ if (reportOutputPath) {
2906
+ const rDir = dirname(resolve(reportOutputPath));
2907
+ if (!existsSync(rDir))
2908
+ mkdirSync(rDir, { recursive: true });
2909
+ writeFileSync(resolve(reportOutputPath), output, "utf-8");
2910
+ console.log(` Report saved to: ${reportOutputPath}`);
2911
+ }
2912
+ else {
2913
+ console.log(output);
2914
+ }
2915
+ }
2916
+ else {
2917
+ const md = formatBenchmarkMarkdown(result, llmSnapshot);
2918
+ if (reportOutputPath) {
2919
+ const rDir = dirname(resolve(reportOutputPath));
2920
+ if (!existsSync(rDir))
2921
+ mkdirSync(rDir, { recursive: true });
2922
+ writeFileSync(resolve(reportOutputPath), md, "utf-8");
2923
+ console.log(` Report saved to: ${reportOutputPath}`);
2924
+ }
2925
+ else {
2926
+ console.log(md);
2927
+ }
2928
+ }
2929
+ process.exit(0);
2930
+ }
2931
+ if (subcommand === "compare") {
2932
+ const fileA = argv[4];
2933
+ const fileB = argv[5];
2934
+ if (!fileA || !fileB) {
2935
+ console.error("Error: Two benchmark result files required");
2936
+ process.exit(1);
2937
+ }
2938
+ const a = JSON.parse(readFileSync(resolve(fileA), "utf-8"));
2939
+ const b = JSON.parse(readFileSync(resolve(fileB), "utf-8"));
2940
+ console.log("\n Benchmark Comparison:");
2941
+ console.log(" " + "─".repeat(50));
2942
+ console.log(` ${"Metric".padEnd(20)} ${"Before".padStart(10)} ${"After".padStart(10)} ${"Delta".padStart(10)}`);
2943
+ console.log(" " + "─".repeat(50));
2944
+ const metrics = [
2945
+ ["Detection Rate", a.detectionRate, b.detectionRate],
2946
+ ["Precision", a.precision, b.precision],
2947
+ ["Recall", a.recall, b.recall],
2948
+ ["F1 Score", a.f1Score, b.f1Score],
2949
+ ["True Positives", a.truePositives, b.truePositives],
2950
+ ["False Negatives", a.falseNegatives, b.falseNegatives],
2951
+ ["False Positives", a.falsePositives, b.falsePositives],
2952
+ ];
2953
+ for (const [name, before, after] of metrics) {
2954
+ const delta = after - before;
2955
+ const sign = delta > 0 ? "+" : "";
2956
+ const isPercent = name !== "True Positives" && name !== "False Negatives" && name !== "False Positives";
2957
+ const fmt = isPercent ? (v) => `${(v * 100).toFixed(1)}%` : (v) => String(v);
2958
+ console.log(` ${name.padEnd(20)} ${fmt(before).padStart(10)} ${fmt(after).padStart(10)} ${(sign + (isPercent ? `${(delta * 100).toFixed(1)}%` : String(delta))).padStart(10)}`);
2959
+ }
2960
+ console.log("");
2961
+ process.exit(0);
2962
+ }
2963
+ if (subcommand === "l2-coverage") {
2964
+ const result = runBenchmarkSuite(undefined, judgeId);
2965
+ const analysis = analyzeL2Coverage(result);
2966
+ const report = formatL2CoverageReport(analysis);
2967
+ if (outputPath) {
2968
+ const dir = dirname(resolve(outputPath));
2969
+ if (!existsSync(dir))
2970
+ mkdirSync(dir, { recursive: true });
2971
+ writeFileSync(resolve(outputPath), format === "json" ? JSON.stringify(analysis, null, 2) : report, "utf-8");
2972
+ console.log(`\n L2 coverage report saved to: ${outputPath}`);
2973
+ }
2974
+ else if (format === "json") {
2975
+ console.log(JSON.stringify(analysis, null, 2));
2976
+ }
2977
+ else {
2978
+ console.log(report);
2979
+ }
2980
+ process.exit(0);
2981
+ }
2982
+ if (subcommand === "ingest") {
2983
+ const findingsFile = argv[4];
2984
+ if (!findingsFile) {
2985
+ console.error("Error: Specify a findings JSON file to ingest.");
2986
+ console.error("Usage: judges benchmark ingest <findings.json> [--output cases.json]");
2987
+ process.exit(1);
2988
+ }
2989
+ try {
2990
+ const raw = JSON.parse(readFileSync(resolve(findingsFile), "utf-8"));
2991
+ const findings = Array.isArray(raw)
2992
+ ? raw
2993
+ : [raw];
2994
+ const candidates = ingestFindingsAsBenchmarkCases(findings);
2995
+ const deduped = deduplicateIngestCases(BENCHMARK_CASES, candidates);
2996
+ const outPath = outputPath || "ingested-benchmark-cases.json";
2997
+ writeFileSync(resolve(outPath), JSON.stringify(deduped, null, 2), "utf-8");
2998
+ console.log(`\n ✅ Ingested ${deduped.length} new benchmark cases (from ${candidates.length} candidates)`);
2999
+ console.log(` Saved to: ${outPath}`);
3000
+ console.log(` Review and add to a benchmark case array to include in the suite.`);
3001
+ }
3002
+ catch (err) {
3003
+ console.error(`Error ingesting findings: ${err.message}`);
3004
+ process.exit(1);
3005
+ }
3006
+ process.exit(0);
3007
+ }
3008
+ console.error(`Unknown benchmark subcommand: ${subcommand}`);
3009
+ process.exit(1);
3010
+ }
3011
+ /**
3012
+ * Analyze which L1 false negatives are coverable by L2 prompts.
3013
+ *
3014
+ * Maps each missed rule ID back to its judge (via rule prefix) and checks
3015
+ * whether that judge has an L2 systemPrompt. This reveals the theoretical
3016
+ * value L2 adds on top of L1 pattern matching.
3017
+ */
3018
+ export function analyzeL2Coverage(result) {
3019
+ const judgesByPrefix = {};
3020
+ for (const j of JUDGES) {
3021
+ judgesByPrefix[j.rulePrefix] = { id: j.id, name: j.name, systemPrompt: j.systemPrompt };
3022
+ }
3023
+ const perJudge = {};
3024
+ const perCategory = {};
3025
+ const perDifficulty = {};
3026
+ const missedCasesByJudge = {};
3027
+ let totalFN = 0;
3028
+ let l2Coverable = 0;
3029
+ for (const c of result.cases) {
3030
+ if (c.missedRuleIds.length === 0)
3031
+ continue;
3032
+ for (const missedRule of c.missedRuleIds) {
3033
+ totalFN++;
3034
+ const prefix = missedRule.split("-")[0];
3035
+ const judge = judgesByPrefix[prefix];
3036
+ // Initialize per-judge
3037
+ if (!perJudge[prefix]) {
3038
+ perJudge[prefix] = {
3039
+ judgeId: judge?.id ?? prefix,
3040
+ judgeName: judge?.name ?? prefix,
3041
+ falseNegatives: 0,
3042
+ hasL2Prompt: !!(judge?.systemPrompt && judge.systemPrompt.length > 0),
3043
+ promptLength: judge?.systemPrompt?.length ?? 0,
3044
+ };
3045
+ }
3046
+ perJudge[prefix].falseNegatives++;
3047
+ // Track by judge prefix
3048
+ if (!missedCasesByJudge[prefix])
3049
+ missedCasesByJudge[prefix] = [];
3050
+ if (!missedCasesByJudge[prefix].includes(c.caseId)) {
3051
+ missedCasesByJudge[prefix].push(c.caseId);
3052
+ }
3053
+ // L2 coverable?
3054
+ const coverable = !!(judge?.systemPrompt && judge.systemPrompt.length > 0);
3055
+ if (coverable)
3056
+ l2Coverable++;
3057
+ // Per-category
3058
+ if (!perCategory[c.category]) {
3059
+ perCategory[c.category] = { category: c.category, falseNegatives: 0, l2Coverable: 0, coverageRate: 0 };
3060
+ }
3061
+ perCategory[c.category].falseNegatives++;
3062
+ if (coverable)
3063
+ perCategory[c.category].l2Coverable++;
3064
+ // Per-difficulty
3065
+ if (!perDifficulty[c.difficulty]) {
3066
+ perDifficulty[c.difficulty] = { difficulty: c.difficulty, falseNegatives: 0, l2Coverable: 0 };
3067
+ }
3068
+ perDifficulty[c.difficulty].falseNegatives++;
3069
+ if (coverable)
3070
+ perDifficulty[c.difficulty].l2Coverable++;
3071
+ }
3072
+ }
3073
+ // Compute coverage rates
3074
+ for (const cat of Object.values(perCategory)) {
3075
+ cat.coverageRate = cat.falseNegatives > 0 ? cat.l2Coverable / cat.falseNegatives : 0;
3076
+ }
3077
+ return {
3078
+ totalFalseNegatives: totalFN,
3079
+ l2Coverable,
3080
+ l2CoverageRate: totalFN > 0 ? l2Coverable / totalFN : 0,
3081
+ perJudge,
3082
+ perCategory,
3083
+ perDifficulty,
3084
+ missedCasesByJudge,
3085
+ };
3086
+ }
3087
+ /**
3088
+ * Format an L2 coverage analysis as a markdown report.
3089
+ */
3090
+ export function formatL2CoverageReport(analysis) {
3091
+ const pct = (v) => `${(v * 100).toFixed(1)}%`;
3092
+ const lines = [];
3093
+ lines.push("# L2 (LLM Deep Review) Coverage Analysis");
3094
+ lines.push("");
3095
+ lines.push("This report analyzes which L1 (pattern-based) false negatives are");
3096
+ lines.push("theoretically coverable by L2 (LLM deep review) prompts.");
3097
+ lines.push("");
3098
+ lines.push("## Summary");
3099
+ lines.push("");
3100
+ lines.push(`| Metric | Value |`);
3101
+ lines.push(`|--------|-------|`);
3102
+ lines.push(`| Total L1 False Negatives | ${analysis.totalFalseNegatives} |`);
3103
+ lines.push(`| L2-Coverable | ${analysis.l2Coverable} |`);
3104
+ lines.push(`| L2 Coverage Rate | ${pct(analysis.l2CoverageRate)} |`);
3105
+ lines.push("");
3106
+ // Per-judge breakdown
3107
+ const judges = Object.values(analysis.perJudge).sort((a, b) => b.falseNegatives - a.falseNegatives);
3108
+ if (judges.length > 0) {
3109
+ lines.push("## L1 Misses by Judge");
3110
+ lines.push("");
3111
+ lines.push("| Judge | FN Count | Has L2 Prompt | Prompt Size |");
3112
+ lines.push("|-------|----------|---------------|-------------|");
3113
+ for (const j of judges) {
3114
+ lines.push(`| ${j.judgeName} (${j.judgeId}) | ${j.falseNegatives} | ${j.hasL2Prompt ? "✅" : "❌"} | ${j.promptLength > 0 ? `${j.promptLength} chars` : "—"} |`);
3115
+ }
3116
+ lines.push("");
3117
+ }
3118
+ // Per-category breakdown
3119
+ const categories = Object.values(analysis.perCategory).sort((a, b) => b.falseNegatives - a.falseNegatives);
3120
+ if (categories.length > 0) {
3121
+ lines.push("## L2 Coverage by Category");
3122
+ lines.push("");
3123
+ lines.push("| Category | L1 Misses | L2-Coverable | Coverage |");
3124
+ lines.push("|----------|-----------|--------------|----------|");
3125
+ for (const cat of categories) {
3126
+ lines.push(`| ${cat.category} | ${cat.falseNegatives} | ${cat.l2Coverable} | ${pct(cat.coverageRate)} |`);
3127
+ }
3128
+ lines.push("");
3129
+ }
3130
+ // Per-difficulty breakdown
3131
+ const difficulties = Object.values(analysis.perDifficulty);
3132
+ if (difficulties.length > 0) {
3133
+ lines.push("## L2 Coverage by Difficulty");
3134
+ lines.push("");
3135
+ lines.push("| Difficulty | L1 Misses | L2-Coverable |");
3136
+ lines.push("|------------|-----------|--------------|");
3137
+ for (const d of difficulties) {
3138
+ lines.push(`| ${d.difficulty} | ${d.falseNegatives} | ${d.l2Coverable} |`);
3139
+ }
3140
+ lines.push("");
3141
+ }
3142
+ // Top missed cases by judge
3143
+ const topJudges = judges.slice(0, 5);
3144
+ if (topJudges.length > 0) {
3145
+ lines.push("## Top Missed Cases by Judge");
3146
+ lines.push("");
3147
+ for (const j of topJudges) {
3148
+ const prefix = Object.keys(analysis.missedCasesByJudge).find((k) => analysis.perJudge[k]?.judgeId === j.judgeId);
3149
+ const cases = prefix ? analysis.missedCasesByJudge[prefix] : [];
3150
+ if (cases.length > 0) {
3151
+ lines.push(`### ${j.judgeName}`);
3152
+ lines.push("");
3153
+ for (const caseId of cases.slice(0, 10)) {
3154
+ lines.push(`- ${caseId}`);
3155
+ }
3156
+ if (cases.length > 10) {
3157
+ lines.push(`- ... and ${cases.length - 10} more`);
3158
+ }
3159
+ lines.push("");
3160
+ }
3161
+ }
3162
+ }
3163
+ lines.push("---");
3164
+ lines.push("");
3165
+ lines.push("*Generated by [Judges Panel](https://github.com/KevinRabun/judges) L2 coverage analysis.*");
3166
+ lines.push("");
3167
+ return lines.join("\n");
3168
+ }
3169
+ /**
3170
+ * Convert real-world evaluation results into candidate benchmark cases.
3171
+ *
3172
+ * Each input becomes a BenchmarkCase whose expectedRuleIds come from the
3173
+ * actual findings produced. This lets operators take real-world detections
3174
+ * and "pin" them as regression tests.
3175
+ */
3176
+ export function ingestFindingsAsBenchmarkCases(inputs) {
3177
+ const cases = [];
3178
+ for (let i = 0; i < inputs.length; i++) {
3179
+ const inp = inputs[i];
3180
+ if (!inp.code || !inp.language || !inp.findings?.length)
3181
+ continue;
3182
+ const ruleIds = [...new Set(inp.findings.map((f) => f.ruleId))];
3183
+ // Infer category from the dominant rule prefix
3184
+ const prefixCounts = {};
3185
+ for (const rid of ruleIds) {
3186
+ const prefix = rid.split("-")[0];
3187
+ prefixCounts[prefix] = (prefixCounts[prefix] || 0) + 1;
3188
+ }
3189
+ const dominantPrefix = Object.entries(prefixCounts).sort((a, b) => b[1] - a[1])[0]?.[0] ?? "unknown";
3190
+ const category = dominantPrefix.toLowerCase();
3191
+ cases.push({
3192
+ id: `ingested-${i + 1}-${category}`,
3193
+ description: `Ingested finding: ${ruleIds.join(", ")}`,
3194
+ language: inp.language,
3195
+ code: inp.code.length > 2000 ? inp.code.slice(0, 2000) + "\n// ... truncated" : inp.code,
3196
+ expectedRuleIds: ruleIds,
3197
+ category,
3198
+ difficulty: "medium",
3199
+ });
3200
+ }
3201
+ return cases;
3202
+ }
3203
+ /**
3204
+ * Deduplicate ingested cases against existing benchmark cases.
3205
+ *
3206
+ * Uses code fingerprinting (normalized whitespace hash) to detect
3207
+ * near-duplicate test cases. Returns only novel candidates.
3208
+ */
3209
+ export function deduplicateIngestCases(existing, candidates) {
3210
+ // Build a set of normalized code fingerprints from existing cases
3211
+ const normalize = (code) => code.replace(/\s+/g, " ").trim().toLowerCase();
3212
+ const existingFingerprints = new Set(existing.map((c) => normalize(c.code)));
3213
+ return candidates.filter((c) => !existingFingerprints.has(normalize(c.code)));
3214
+ }