@kevinrabun/judges 3.38.0 → 3.40.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 (331) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +5 -4
  3. package/dist/api.d.ts +5 -2
  4. package/dist/api.d.ts.map +1 -1
  5. package/dist/api.js +5 -1
  6. package/dist/api.js.map +1 -1
  7. package/dist/ast/structural-parser.js +3 -3
  8. package/dist/ast/structural-parser.js.map +1 -1
  9. package/dist/calibration.d.ts +35 -0
  10. package/dist/calibration.d.ts.map +1 -1
  11. package/dist/calibration.js +52 -0
  12. package/dist/calibration.js.map +1 -1
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +307 -16
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/benchmark-languages.js +4 -4
  17. package/dist/commands/benchmark.d.ts +2 -1
  18. package/dist/commands/benchmark.d.ts.map +1 -1
  19. package/dist/commands/benchmark.js +67 -2
  20. package/dist/commands/benchmark.js.map +1 -1
  21. package/dist/commands/calibration-dashboard.d.ts.map +1 -1
  22. package/dist/commands/calibration-dashboard.js +198 -0
  23. package/dist/commands/calibration-dashboard.js.map +1 -1
  24. package/dist/commands/calibration-share.d.ts +31 -0
  25. package/dist/commands/calibration-share.d.ts.map +1 -0
  26. package/dist/commands/calibration-share.js +183 -0
  27. package/dist/commands/calibration-share.js.map +1 -0
  28. package/dist/commands/compliance-report.d.ts +35 -0
  29. package/dist/commands/compliance-report.d.ts.map +1 -0
  30. package/dist/commands/compliance-report.js +162 -0
  31. package/dist/commands/compliance-report.js.map +1 -0
  32. package/dist/commands/diff.d.ts.map +1 -1
  33. package/dist/commands/diff.js +8 -3
  34. package/dist/commands/diff.js.map +1 -1
  35. package/dist/commands/feedback-rules.d.ts +29 -0
  36. package/dist/commands/feedback-rules.d.ts.map +1 -0
  37. package/dist/commands/feedback-rules.js +174 -0
  38. package/dist/commands/feedback-rules.js.map +1 -0
  39. package/dist/commands/feedback.d.ts +12 -0
  40. package/dist/commands/feedback.d.ts.map +1 -1
  41. package/dist/commands/feedback.js +16 -0
  42. package/dist/commands/feedback.js.map +1 -1
  43. package/dist/commands/fix.d.ts.map +1 -1
  44. package/dist/commands/fix.js +33 -1
  45. package/dist/commands/fix.js.map +1 -1
  46. package/dist/commands/governance.d.ts +32 -0
  47. package/dist/commands/governance.d.ts.map +1 -0
  48. package/dist/commands/governance.js +203 -0
  49. package/dist/commands/governance.js.map +1 -0
  50. package/dist/commands/help.d.ts +8 -0
  51. package/dist/commands/help.d.ts.map +1 -0
  52. package/dist/commands/help.js +303 -0
  53. package/dist/commands/help.js.map +1 -0
  54. package/dist/commands/hook.d.ts.map +1 -1
  55. package/dist/commands/hook.js +17 -20
  56. package/dist/commands/hook.js.map +1 -1
  57. package/dist/commands/llm-benchmark.d.ts +119 -0
  58. package/dist/commands/llm-benchmark.d.ts.map +1 -0
  59. package/dist/commands/llm-benchmark.js +396 -0
  60. package/dist/commands/llm-benchmark.js.map +1 -0
  61. package/dist/commands/metrics-dashboard.d.ts +22 -0
  62. package/dist/commands/metrics-dashboard.d.ts.map +1 -0
  63. package/dist/commands/metrics-dashboard.js +335 -0
  64. package/dist/commands/metrics-dashboard.js.map +1 -0
  65. package/dist/commands/metrics.d.ts +58 -0
  66. package/dist/commands/metrics.d.ts.map +1 -0
  67. package/dist/commands/metrics.js +242 -0
  68. package/dist/commands/metrics.js.map +1 -0
  69. package/dist/commands/onboard.d.ts +13 -0
  70. package/dist/commands/onboard.d.ts.map +1 -0
  71. package/dist/commands/onboard.js +179 -0
  72. package/dist/commands/onboard.js.map +1 -0
  73. package/dist/commands/org-metrics.d.ts +24 -0
  74. package/dist/commands/org-metrics.d.ts.map +1 -0
  75. package/dist/commands/org-metrics.js +238 -0
  76. package/dist/commands/org-metrics.js.map +1 -0
  77. package/dist/commands/override.d.ts +62 -0
  78. package/dist/commands/override.d.ts.map +1 -0
  79. package/dist/commands/override.js +264 -0
  80. package/dist/commands/override.js.map +1 -0
  81. package/dist/commands/parity.d.ts +31 -0
  82. package/dist/commands/parity.d.ts.map +1 -0
  83. package/dist/commands/parity.js +213 -0
  84. package/dist/commands/parity.js.map +1 -0
  85. package/dist/commands/plugin-search.d.ts +40 -0
  86. package/dist/commands/plugin-search.d.ts.map +1 -0
  87. package/dist/commands/plugin-search.js +328 -0
  88. package/dist/commands/plugin-search.js.map +1 -0
  89. package/dist/commands/plugins.d.ts +13 -0
  90. package/dist/commands/plugins.d.ts.map +1 -0
  91. package/dist/commands/plugins.js +105 -0
  92. package/dist/commands/plugins.js.map +1 -0
  93. package/dist/commands/review.js +1 -1
  94. package/dist/commands/review.js.map +1 -1
  95. package/dist/commands/snapshot.d.ts +27 -0
  96. package/dist/commands/snapshot.d.ts.map +1 -1
  97. package/dist/commands/snapshot.js +99 -0
  98. package/dist/commands/snapshot.js.map +1 -1
  99. package/dist/commands/trace.d.ts +65 -0
  100. package/dist/commands/trace.d.ts.map +1 -0
  101. package/dist/commands/trace.js +246 -0
  102. package/dist/commands/trace.js.map +1 -0
  103. package/dist/commands/trust-ramp.d.ts +30 -0
  104. package/dist/commands/trust-ramp.d.ts.map +1 -0
  105. package/dist/commands/trust-ramp.js +190 -0
  106. package/dist/commands/trust-ramp.js.map +1 -0
  107. package/dist/config.d.ts +5 -0
  108. package/dist/config.d.ts.map +1 -1
  109. package/dist/config.js +65 -0
  110. package/dist/config.js.map +1 -1
  111. package/dist/data-adapter.d.ts +124 -0
  112. package/dist/data-adapter.d.ts.map +1 -0
  113. package/dist/data-adapter.js +213 -0
  114. package/dist/data-adapter.js.map +1 -0
  115. package/dist/evaluators/accessibility.js +1 -1
  116. package/dist/evaluators/accessibility.js.map +1 -1
  117. package/dist/evaluators/ai-code-safety.d.ts.map +1 -1
  118. package/dist/evaluators/ai-code-safety.js +1 -4
  119. package/dist/evaluators/ai-code-safety.js.map +1 -1
  120. package/dist/evaluators/cost-effectiveness.js +1 -1
  121. package/dist/evaluators/cost-effectiveness.js.map +1 -1
  122. package/dist/evaluators/false-positive-review.js +4 -4
  123. package/dist/evaluators/false-positive-review.js.map +1 -1
  124. package/dist/evaluators/iac-security.js +1 -1
  125. package/dist/evaluators/iac-security.js.map +1 -1
  126. package/dist/evaluators/index.d.ts.map +1 -1
  127. package/dist/evaluators/index.js +59 -10
  128. package/dist/evaluators/index.js.map +1 -1
  129. package/dist/evaluators/intent-alignment.d.ts +4 -0
  130. package/dist/evaluators/intent-alignment.d.ts.map +1 -1
  131. package/dist/evaluators/intent-alignment.js +163 -0
  132. package/dist/evaluators/intent-alignment.js.map +1 -1
  133. package/dist/evaluators/logic-review.js +1 -1
  134. package/dist/evaluators/logic-review.js.map +1 -1
  135. package/dist/evaluators/maintainability.js +1 -1
  136. package/dist/evaluators/maintainability.js.map +1 -1
  137. package/dist/evaluators/over-engineering.js +3 -3
  138. package/dist/evaluators/over-engineering.js.map +1 -1
  139. package/dist/evaluators/project.d.ts +12 -0
  140. package/dist/evaluators/project.d.ts.map +1 -1
  141. package/dist/evaluators/project.js +86 -0
  142. package/dist/evaluators/project.js.map +1 -1
  143. package/dist/evaluators/security.js +2 -2
  144. package/dist/evaluators/security.js.map +1 -1
  145. package/dist/evaluators/ux.js +1 -1
  146. package/dist/evaluators/ux.js.map +1 -1
  147. package/dist/finding-lifecycle.d.ts +9 -0
  148. package/dist/finding-lifecycle.d.ts.map +1 -1
  149. package/dist/finding-lifecycle.js +15 -0
  150. package/dist/finding-lifecycle.js.map +1 -1
  151. package/dist/fix-history.d.ts +9 -0
  152. package/dist/fix-history.d.ts.map +1 -1
  153. package/dist/fix-history.js +15 -0
  154. package/dist/fix-history.js.map +1 -1
  155. package/dist/formatters/sarif.d.ts +3 -0
  156. package/dist/formatters/sarif.d.ts.map +1 -1
  157. package/dist/formatters/sarif.js +36 -12
  158. package/dist/formatters/sarif.js.map +1 -1
  159. package/dist/github-app.d.ts +16 -1
  160. package/dist/github-app.d.ts.map +1 -1
  161. package/dist/github-app.js +85 -2
  162. package/dist/github-app.js.map +1 -1
  163. package/dist/index.js +5 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/judge-registry.d.ts +157 -0
  166. package/dist/judge-registry.d.ts.map +1 -0
  167. package/dist/judge-registry.js +273 -0
  168. package/dist/judge-registry.js.map +1 -0
  169. package/dist/judges/accessibility.d.ts.map +1 -1
  170. package/dist/judges/accessibility.js +4 -0
  171. package/dist/judges/accessibility.js.map +1 -1
  172. package/dist/judges/agent-instructions.d.ts.map +1 -1
  173. package/dist/judges/agent-instructions.js +4 -0
  174. package/dist/judges/agent-instructions.js.map +1 -1
  175. package/dist/judges/ai-code-safety.d.ts.map +1 -1
  176. package/dist/judges/ai-code-safety.js +4 -0
  177. package/dist/judges/ai-code-safety.js.map +1 -1
  178. package/dist/judges/api-contract.d.ts.map +1 -1
  179. package/dist/judges/api-contract.js +4 -0
  180. package/dist/judges/api-contract.js.map +1 -1
  181. package/dist/judges/api-design.d.ts.map +1 -1
  182. package/dist/judges/api-design.js +4 -0
  183. package/dist/judges/api-design.js.map +1 -1
  184. package/dist/judges/authentication.d.ts.map +1 -1
  185. package/dist/judges/authentication.js +4 -0
  186. package/dist/judges/authentication.js.map +1 -1
  187. package/dist/judges/backwards-compatibility.d.ts.map +1 -1
  188. package/dist/judges/backwards-compatibility.js +4 -0
  189. package/dist/judges/backwards-compatibility.js.map +1 -1
  190. package/dist/judges/caching.d.ts.map +1 -1
  191. package/dist/judges/caching.js +4 -0
  192. package/dist/judges/caching.js.map +1 -1
  193. package/dist/judges/ci-cd.d.ts.map +1 -1
  194. package/dist/judges/ci-cd.js +4 -0
  195. package/dist/judges/ci-cd.js.map +1 -1
  196. package/dist/judges/cloud-readiness.d.ts.map +1 -1
  197. package/dist/judges/cloud-readiness.js +4 -0
  198. package/dist/judges/cloud-readiness.js.map +1 -1
  199. package/dist/judges/code-structure.d.ts.map +1 -1
  200. package/dist/judges/code-structure.js +4 -0
  201. package/dist/judges/code-structure.js.map +1 -1
  202. package/dist/judges/compliance.d.ts.map +1 -1
  203. package/dist/judges/compliance.js +4 -0
  204. package/dist/judges/compliance.js.map +1 -1
  205. package/dist/judges/concurrency.d.ts.map +1 -1
  206. package/dist/judges/concurrency.js +4 -0
  207. package/dist/judges/concurrency.js.map +1 -1
  208. package/dist/judges/configuration-management.d.ts.map +1 -1
  209. package/dist/judges/configuration-management.js +4 -0
  210. package/dist/judges/configuration-management.js.map +1 -1
  211. package/dist/judges/cost-effectiveness.d.ts.map +1 -1
  212. package/dist/judges/cost-effectiveness.js +4 -0
  213. package/dist/judges/cost-effectiveness.js.map +1 -1
  214. package/dist/judges/cybersecurity.d.ts.map +1 -1
  215. package/dist/judges/cybersecurity.js +4 -0
  216. package/dist/judges/cybersecurity.js.map +1 -1
  217. package/dist/judges/data-security.d.ts.map +1 -1
  218. package/dist/judges/data-security.js +4 -0
  219. package/dist/judges/data-security.js.map +1 -1
  220. package/dist/judges/data-sovereignty.d.ts.map +1 -1
  221. package/dist/judges/data-sovereignty.js +4 -0
  222. package/dist/judges/data-sovereignty.js.map +1 -1
  223. package/dist/judges/database.d.ts.map +1 -1
  224. package/dist/judges/database.js +4 -0
  225. package/dist/judges/database.js.map +1 -1
  226. package/dist/judges/dependency-health.d.ts.map +1 -1
  227. package/dist/judges/dependency-health.js +4 -0
  228. package/dist/judges/dependency-health.js.map +1 -1
  229. package/dist/judges/documentation.d.ts.map +1 -1
  230. package/dist/judges/documentation.js +4 -0
  231. package/dist/judges/documentation.js.map +1 -1
  232. package/dist/judges/error-handling.d.ts.map +1 -1
  233. package/dist/judges/error-handling.js +4 -0
  234. package/dist/judges/error-handling.js.map +1 -1
  235. package/dist/judges/ethics-bias.d.ts.map +1 -1
  236. package/dist/judges/ethics-bias.js +4 -0
  237. package/dist/judges/ethics-bias.js.map +1 -1
  238. package/dist/judges/false-positive-review.d.ts.map +1 -1
  239. package/dist/judges/false-positive-review.js +2 -0
  240. package/dist/judges/false-positive-review.js.map +1 -1
  241. package/dist/judges/framework-safety.d.ts.map +1 -1
  242. package/dist/judges/framework-safety.js +4 -0
  243. package/dist/judges/framework-safety.js.map +1 -1
  244. package/dist/judges/hallucination-detection.d.ts.map +1 -1
  245. package/dist/judges/hallucination-detection.js +4 -0
  246. package/dist/judges/hallucination-detection.js.map +1 -1
  247. package/dist/judges/iac-security.d.ts.map +1 -1
  248. package/dist/judges/iac-security.js +4 -0
  249. package/dist/judges/iac-security.js.map +1 -1
  250. package/dist/judges/index.d.ts +59 -0
  251. package/dist/judges/index.d.ts.map +1 -1
  252. package/dist/judges/index.js +65 -189
  253. package/dist/judges/index.js.map +1 -1
  254. package/dist/judges/intent-alignment.d.ts.map +1 -1
  255. package/dist/judges/intent-alignment.js +4 -0
  256. package/dist/judges/intent-alignment.js.map +1 -1
  257. package/dist/judges/internationalization.d.ts.map +1 -1
  258. package/dist/judges/internationalization.js +4 -0
  259. package/dist/judges/internationalization.js.map +1 -1
  260. package/dist/judges/logging-privacy.d.ts.map +1 -1
  261. package/dist/judges/logging-privacy.js +4 -0
  262. package/dist/judges/logging-privacy.js.map +1 -1
  263. package/dist/judges/logic-review.d.ts.map +1 -1
  264. package/dist/judges/logic-review.js +4 -0
  265. package/dist/judges/logic-review.js.map +1 -1
  266. package/dist/judges/maintainability.d.ts.map +1 -1
  267. package/dist/judges/maintainability.js +4 -0
  268. package/dist/judges/maintainability.js.map +1 -1
  269. package/dist/judges/model-fingerprint.d.ts.map +1 -1
  270. package/dist/judges/model-fingerprint.js +4 -0
  271. package/dist/judges/model-fingerprint.js.map +1 -1
  272. package/dist/judges/multi-turn-coherence.d.ts.map +1 -1
  273. package/dist/judges/multi-turn-coherence.js +4 -0
  274. package/dist/judges/multi-turn-coherence.js.map +1 -1
  275. package/dist/judges/observability.d.ts.map +1 -1
  276. package/dist/judges/observability.js +4 -0
  277. package/dist/judges/observability.js.map +1 -1
  278. package/dist/judges/over-engineering.d.ts.map +1 -1
  279. package/dist/judges/over-engineering.js +4 -0
  280. package/dist/judges/over-engineering.js.map +1 -1
  281. package/dist/judges/performance.d.ts.map +1 -1
  282. package/dist/judges/performance.js +4 -0
  283. package/dist/judges/performance.js.map +1 -1
  284. package/dist/judges/portability.d.ts.map +1 -1
  285. package/dist/judges/portability.js +4 -0
  286. package/dist/judges/portability.js.map +1 -1
  287. package/dist/judges/rate-limiting.d.ts.map +1 -1
  288. package/dist/judges/rate-limiting.js +4 -0
  289. package/dist/judges/rate-limiting.js.map +1 -1
  290. package/dist/judges/reliability.d.ts.map +1 -1
  291. package/dist/judges/reliability.js +4 -0
  292. package/dist/judges/reliability.js.map +1 -1
  293. package/dist/judges/scalability.d.ts.map +1 -1
  294. package/dist/judges/scalability.js +4 -0
  295. package/dist/judges/scalability.js.map +1 -1
  296. package/dist/judges/security.d.ts.map +1 -1
  297. package/dist/judges/security.js +4 -0
  298. package/dist/judges/security.js.map +1 -1
  299. package/dist/judges/software-practices.d.ts.map +1 -1
  300. package/dist/judges/software-practices.js +4 -0
  301. package/dist/judges/software-practices.js.map +1 -1
  302. package/dist/judges/testing.d.ts.map +1 -1
  303. package/dist/judges/testing.js +4 -0
  304. package/dist/judges/testing.js.map +1 -1
  305. package/dist/judges/ux.d.ts.map +1 -1
  306. package/dist/judges/ux.js +4 -0
  307. package/dist/judges/ux.js.map +1 -1
  308. package/dist/plugins.d.ts +8 -51
  309. package/dist/plugins.d.ts.map +1 -1
  310. package/dist/plugins.js +16 -125
  311. package/dist/plugins.js.map +1 -1
  312. package/dist/security-ids.d.ts +24 -0
  313. package/dist/security-ids.d.ts.map +1 -0
  314. package/dist/security-ids.js +240 -0
  315. package/dist/security-ids.js.map +1 -0
  316. package/dist/tools/prompts.d.ts +4 -0
  317. package/dist/tools/prompts.d.ts.map +1 -1
  318. package/dist/tools/prompts.js +6 -4
  319. package/dist/tools/prompts.js.map +1 -1
  320. package/dist/tools/register-scaffold.d.ts +3 -0
  321. package/dist/tools/register-scaffold.d.ts.map +1 -0
  322. package/dist/tools/register-scaffold.js +399 -0
  323. package/dist/tools/register-scaffold.js.map +1 -0
  324. package/dist/tools/register.d.ts +1 -1
  325. package/dist/tools/register.d.ts.map +1 -1
  326. package/dist/tools/register.js +3 -1
  327. package/dist/tools/register.js.map +1 -1
  328. package/dist/types.d.ts +75 -0
  329. package/dist/types.d.ts.map +1 -1
  330. package/package.json +3 -2
  331. package/server.json +2 -2
@@ -0,0 +1,246 @@
1
+ // ─── Trace Mode — Show Your Work ─────────────────────────────────────────────
2
+ // Renders a detailed, human-readable trace of exactly how the evaluation
3
+ // pipeline reached its decision for every finding. Each finding's journey
4
+ // through the pipeline is shown: detection → FP filters → dedup → calibration
5
+ // → confidence scoring → final disposition.
6
+ //
7
+ // All data is computed locally from the evaluation result — no external
8
+ // services or data storage involved.
9
+ //
10
+ // Usage:
11
+ // judges eval src/app.ts --trace # text trace to stdout
12
+ // judges eval src/app.ts --trace --format json # structured trace
13
+ // ──────────────────────────────────────────────────────────────────────────────
14
+ // ─── Trace Builder ──────────────────────────────────────────────────────────
15
+ /**
16
+ * Build an evaluation trace from a tribunal verdict.
17
+ *
18
+ * This reconstructs the pipeline journey from the data available on the
19
+ * verdict — it does not require runtime hooks in the evaluator. The trace
20
+ * is approximate but highly informative for understanding why findings
21
+ * were kept or dropped.
22
+ */
23
+ export function buildEvaluationTrace(verdict, filePath, language) {
24
+ const judgeSummaries = verdict.evaluations.map((e) => ({
25
+ judgeId: e.judgeId,
26
+ judgeName: e.judgeName,
27
+ findingsProduced: e.findings.length,
28
+ durationMs: e.durationMs ?? 0,
29
+ }));
30
+ const rawFindingCount = verdict.evaluations.reduce((sum, e) => sum + e.findings.length, 0);
31
+ // Build per-finding traces from what we can infer
32
+ const findingTraces = [];
33
+ // Track what the final set contains
34
+ const finalRuleIds = new Set(verdict.findings.map((f) => `${f.ruleId}:${f.lineNumbers?.[0] ?? 0}`));
35
+ // Process each judge's findings
36
+ for (const evaluation of verdict.evaluations) {
37
+ for (const finding of evaluation.findings) {
38
+ const key = `${finding.ruleId}:${finding.lineNumbers?.[0] ?? 0}`;
39
+ const steps = [];
40
+ // Step 1: Detection
41
+ steps.push({
42
+ stage: "detection",
43
+ action: "kept",
44
+ reason: `Detected by ${evaluation.judgeName} (${evaluation.judgeId}) via ${finding.provenance ?? "pattern-match"}`,
45
+ });
46
+ // Step 2: Evidence basis
47
+ if (finding.evidenceBasis) {
48
+ steps.push({
49
+ stage: "confidence-scoring",
50
+ action: finding.confidence && finding.confidence >= 0.7 ? "boosted" : "kept",
51
+ reason: `Evidence: ${finding.evidenceBasis}`,
52
+ });
53
+ }
54
+ // Step 3: Evidence chain
55
+ if (finding.evidenceChain) {
56
+ const chainDesc = finding.evidenceChain.steps
57
+ .map((s) => `${s.source}${s.line ? ` L${s.line}` : ""}: ${s.observation}`)
58
+ .join(" → ");
59
+ steps.push({
60
+ stage: "evidence-chain",
61
+ action: "kept",
62
+ reason: chainDesc,
63
+ });
64
+ }
65
+ // Step 4: Absence gating
66
+ if (finding.isAbsenceBased) {
67
+ steps.push({
68
+ stage: "absence-gating",
69
+ action: "demoted",
70
+ reason: "Absence-based finding — severity capped at medium, confidence capped at 0.6",
71
+ });
72
+ }
73
+ // Step 5: Confidence tier
74
+ if (finding.confidenceTier) {
75
+ steps.push({
76
+ stage: "confidence-tiering",
77
+ action: "kept",
78
+ reason: `Classified as "${finding.confidenceTier}" (confidence: ${((finding.confidence ?? 0.5) * 100).toFixed(0)}%)`,
79
+ });
80
+ }
81
+ // Step 6: Check if it survived to final output
82
+ const inFinal = finalRuleIds.has(key);
83
+ if (!inFinal) {
84
+ // Determine likely suppression reason
85
+ if (finding.isAbsenceBased) {
86
+ steps.push({
87
+ stage: "pipeline-filter",
88
+ action: "suppressed",
89
+ reason: "Suppressed: absence-based finding in single-file mode",
90
+ });
91
+ }
92
+ else {
93
+ steps.push({
94
+ stage: "pipeline-filter",
95
+ action: "suppressed",
96
+ reason: "Suppressed: likely removed by FP heuristics, dedup, or config filter",
97
+ });
98
+ }
99
+ }
100
+ // Step 7: OWASP LLM mapping
101
+ if (finding.owaspLlmTop10) {
102
+ steps.push({
103
+ stage: "ai-risk-mapping",
104
+ action: "kept",
105
+ reason: `Mapped to ${finding.owaspLlmTop10}`,
106
+ });
107
+ }
108
+ // Step 8: Patch availability
109
+ if (finding.patch) {
110
+ steps.push({
111
+ stage: "auto-fix",
112
+ action: "added",
113
+ reason: `Auto-fix available: L${finding.patch.startLine}-${finding.patch.endLine}`,
114
+ });
115
+ }
116
+ const confidenceJourney = finding.evidenceBasis
117
+ ? {
118
+ initial: 0.5,
119
+ final: finding.confidence ?? 0.5,
120
+ adjustments: finding.evidenceBasis.split(", "),
121
+ }
122
+ : undefined;
123
+ findingTraces.push({
124
+ ruleId: finding.ruleId,
125
+ title: finding.title,
126
+ severity: finding.severity,
127
+ disposition: inFinal ? "reported" : "suppressed",
128
+ steps,
129
+ confidenceJourney,
130
+ });
131
+ }
132
+ }
133
+ // Add traces for suppressed findings (from inline suppression audit trail)
134
+ if (verdict.suppressions) {
135
+ for (const s of verdict.suppressions) {
136
+ findingTraces.push({
137
+ ruleId: s.ruleId,
138
+ title: s.title,
139
+ severity: s.severity,
140
+ disposition: "suppressed",
141
+ steps: [
142
+ { stage: "detection", action: "kept", reason: "Detected by pattern match" },
143
+ {
144
+ stage: "inline-suppression",
145
+ action: "suppressed",
146
+ reason: `Suppressed by ${s.kind} comment at L${s.commentLine}${s.reason ? `: ${s.reason}` : ""}`,
147
+ },
148
+ ],
149
+ });
150
+ }
151
+ }
152
+ // Compute suppression summary by stage
153
+ const suppressionMap = new Map();
154
+ for (const trace of findingTraces) {
155
+ if (trace.disposition === "suppressed") {
156
+ const lastStep = trace.steps[trace.steps.length - 1];
157
+ const stage = lastStep?.stage ?? "unknown";
158
+ suppressionMap.set(stage, (suppressionMap.get(stage) ?? 0) + 1);
159
+ }
160
+ }
161
+ const suppressionSummary = [...suppressionMap.entries()]
162
+ .map(([stage, count]) => ({ stage, count }))
163
+ .sort((a, b) => b.count - a.count);
164
+ return {
165
+ filePath,
166
+ language: language ?? "unknown",
167
+ judgesRun: verdict.evaluations.length,
168
+ rawFindingCount,
169
+ finalFindingCount: verdict.findings.length,
170
+ suppressionSummary,
171
+ findings: findingTraces,
172
+ judgeSummaries,
173
+ };
174
+ }
175
+ // ─── Text Formatter ─────────────────────────────────────────────────────────
176
+ /**
177
+ * Format an evaluation trace as human-readable text output.
178
+ */
179
+ export function formatTraceText(trace) {
180
+ const lines = [];
181
+ lines.push("");
182
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
183
+ lines.push("║ Judges Panel — Evaluation Trace ║");
184
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
185
+ lines.push("");
186
+ if (trace.filePath)
187
+ lines.push(` File : ${trace.filePath}`);
188
+ lines.push(` Language : ${trace.language}`);
189
+ lines.push(` Judges : ${trace.judgesRun}`);
190
+ lines.push(` Raw : ${trace.rawFindingCount} findings detected`);
191
+ lines.push(` Final : ${trace.finalFindingCount} findings reported`);
192
+ lines.push(` Filtered : ${trace.rawFindingCount - trace.finalFindingCount} findings suppressed`);
193
+ lines.push("");
194
+ // Judge timing breakdown
195
+ lines.push(" ─── Judge Execution ────────────────────────────────────────");
196
+ lines.push("");
197
+ for (const j of trace.judgeSummaries) {
198
+ const icon = j.findingsProduced > 0 ? "🔍" : "✅";
199
+ lines.push(` ${icon} ${j.judgeName.padEnd(35)} ${j.findingsProduced} finding(s) ${j.durationMs}ms`);
200
+ }
201
+ lines.push("");
202
+ // Suppression summary
203
+ if (trace.suppressionSummary.length > 0) {
204
+ lines.push(" ─── Suppression Summary ────────────────────────────────────");
205
+ lines.push("");
206
+ for (const s of trace.suppressionSummary) {
207
+ lines.push(` ⊘ ${s.stage.padEnd(30)} ${s.count} finding(s) removed`);
208
+ }
209
+ lines.push("");
210
+ }
211
+ // Per-finding traces
212
+ lines.push(" ─── Finding Decision Traces ────────────────────────────────");
213
+ lines.push("");
214
+ for (const f of trace.findings) {
215
+ const icon = f.disposition === "reported" ? "📋" : f.disposition === "merged" ? "🔀" : "⊘";
216
+ lines.push(` ${icon} [${f.severity.toUpperCase().padEnd(8)}] ${f.ruleId}: ${f.title}`);
217
+ lines.push(` Disposition: ${f.disposition.toUpperCase()}`);
218
+ for (const step of f.steps) {
219
+ const actionIcon = step.action === "kept"
220
+ ? " →"
221
+ : step.action === "suppressed"
222
+ ? " ✗"
223
+ : step.action === "demoted"
224
+ ? " ↓"
225
+ : step.action === "boosted"
226
+ ? " ↑"
227
+ : step.action === "merged"
228
+ ? " ⊕"
229
+ : step.action === "added"
230
+ ? " +"
231
+ : step.action === "capped"
232
+ ? " ⌐"
233
+ : " ?";
234
+ lines.push(` ${actionIcon} [${step.stage}] ${step.reason}`);
235
+ }
236
+ if (f.confidenceJourney) {
237
+ lines.push(` Confidence: ${(f.confidenceJourney.initial * 100).toFixed(0)}% → ${(f.confidenceJourney.final * 100).toFixed(0)}%`);
238
+ for (const adj of f.confidenceJourney.adjustments) {
239
+ lines.push(` ${adj.trim()}`);
240
+ }
241
+ }
242
+ lines.push("");
243
+ }
244
+ return lines.join("\n");
245
+ }
246
+ //# sourceMappingURL=trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/commands/trace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `judges trust-ramp` — Generate a graduated trust configuration.
3
+ *
4
+ * Produces a phased .judgesrc progression that starts with advisory-only
5
+ * (no CI gating) and ramps up to full enforcement over 30/60/90 days.
6
+ * All data stays local — phases are encoded as config files you commit.
7
+ *
8
+ * Phases:
9
+ * 1. Advisory (days 0-30) — high+critical only, no fail, baseline created
10
+ * 2. Selective (days 30-60) — medium+, fail on critical, auto-fix enabled
11
+ * 3. Enforcing (days 60-90) — all severities, fail on findings, score gate
12
+ * 4. Full trust (day 90+) — strict preset, full gating, baseline removed
13
+ */
14
+ import type { JudgesConfig } from "../types.js";
15
+ export interface TrustPhase {
16
+ /** Phase number (1-4) */
17
+ phase: number;
18
+ /** Human-readable name */
19
+ name: string;
20
+ /** Day range description */
21
+ days: string;
22
+ /** What this phase enables */
23
+ description: string;
24
+ /** The generated .judgesrc config */
25
+ config: JudgesConfig;
26
+ /** CI workflow snippet (optional) */
27
+ ciTip: string;
28
+ }
29
+ export declare function runTrustRamp(argv: string[]): void;
30
+ //# sourceMappingURL=trust-ramp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-ramp.d.ts","sourceRoot":"","sources":["../../src/commands/trust-ramp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,aAAa,CAAC;AAI1D,MAAM,WAAW,UAAU;IACzB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,MAAM,EAAE,YAAY,CAAC;IACrB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf;AA2HD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+BjD"}
@@ -0,0 +1,190 @@
1
+ /**
2
+ * `judges trust-ramp` — Generate a graduated trust configuration.
3
+ *
4
+ * Produces a phased .judgesrc progression that starts with advisory-only
5
+ * (no CI gating) and ramps up to full enforcement over 30/60/90 days.
6
+ * All data stays local — phases are encoded as config files you commit.
7
+ *
8
+ * Phases:
9
+ * 1. Advisory (days 0-30) — high+critical only, no fail, baseline created
10
+ * 2. Selective (days 30-60) — medium+, fail on critical, auto-fix enabled
11
+ * 3. Enforcing (days 60-90) — all severities, fail on findings, score gate
12
+ * 4. Full trust (day 90+) — strict preset, full gating, baseline removed
13
+ */
14
+ import { writeFileSync } from "fs";
15
+ import { join, resolve } from "path";
16
+ function buildPhases(basePreset) {
17
+ return [
18
+ {
19
+ phase: 1,
20
+ name: "Advisory",
21
+ days: "Days 0–30",
22
+ description: "Report only critical and high severity findings. No CI gating. " +
23
+ "Creates a baseline of existing issues so new introductions are visible.",
24
+ config: {
25
+ ...(basePreset ? { preset: basePreset } : {}),
26
+ minSeverity: "high",
27
+ failOnFindings: false,
28
+ },
29
+ ciTip: "# Phase 1: advisory only — do NOT add --fail-on-findings to CI",
30
+ },
31
+ {
32
+ phase: 2,
33
+ name: "Selective Enforcement",
34
+ days: "Days 30–60",
35
+ description: "Lower threshold to medium severity. Gate CI on critical findings only " +
36
+ "via failOnScoreBelow. Auto-fix suggestions become available.",
37
+ config: {
38
+ ...(basePreset ? { preset: basePreset } : {}),
39
+ minSeverity: "medium",
40
+ failOnFindings: false,
41
+ failOnScoreBelow: 3,
42
+ },
43
+ ciTip: "# Phase 2: gate on score — blocks PRs scoring below 3/10",
44
+ },
45
+ {
46
+ phase: 3,
47
+ name: "Enforcing",
48
+ days: "Days 60–90",
49
+ description: "Report all severities. Fail on any findings. Score gate raised to 6. " +
50
+ "Team should be comfortable with judges output by now.",
51
+ config: {
52
+ ...(basePreset ? { preset: basePreset } : {}),
53
+ minSeverity: "low",
54
+ failOnFindings: true,
55
+ failOnScoreBelow: 6,
56
+ },
57
+ ciTip: "# Phase 3: enforcing — PR merges blocked on findings or low score",
58
+ },
59
+ {
60
+ phase: 4,
61
+ name: "Full Trust",
62
+ days: "Day 90+",
63
+ description: "Strict mode with all judges and all severities. Full gating enabled. " +
64
+ "Remove the baseline file — all findings are real.",
65
+ config: {
66
+ preset: "strict",
67
+ failOnFindings: true,
68
+ failOnScoreBelow: 7,
69
+ },
70
+ ciTip: "# Phase 4: full trust — judges is your primary reviewer",
71
+ },
72
+ ];
73
+ }
74
+ // ─── Output Formats ─────────────────────────────────────────────────────────
75
+ function formatPhasesText(phases) {
76
+ const lines = [
77
+ "╔══════════════════════════════════════════════════════════════╗",
78
+ "║ Judges — Graduated Trust Ramp Plan ║",
79
+ "╚══════════════════════════════════════════════════════════════╝",
80
+ "",
81
+ ];
82
+ for (const p of phases) {
83
+ lines.push(`── Phase ${p.phase}: ${p.name} (${p.days}) ${"─".repeat(Math.max(0, 40 - p.name.length - p.days.length))}`);
84
+ lines.push(` ${p.description}`);
85
+ lines.push("");
86
+ lines.push(" .judgesrc:");
87
+ lines.push(` ${JSON.stringify(p.config, null, 2).replace(/\n/g, "\n ")}`);
88
+ lines.push("");
89
+ lines.push(` ${p.ciTip}`);
90
+ lines.push("");
91
+ }
92
+ lines.push("── Getting Started ──────────────────────────────────────────");
93
+ lines.push(" 1. Run: judges trust-ramp --emit phase-1");
94
+ lines.push(" 2. Commit the generated .judgesrc to your repo");
95
+ lines.push(" 3. When ready to advance, run: judges trust-ramp --emit phase-2");
96
+ lines.push(" 4. Repeat until full trust is achieved");
97
+ lines.push("");
98
+ return lines.join("\n");
99
+ }
100
+ function formatPhasesJson(phases) {
101
+ return JSON.stringify(phases.map((p) => ({
102
+ phase: p.phase,
103
+ name: p.name,
104
+ days: p.days,
105
+ description: p.description,
106
+ config: p.config,
107
+ })), null, 2);
108
+ }
109
+ // ─── Emit a Phase Config ─────────────────────────────────────────────────
110
+ function emitPhaseConfig(phase, targetDir) {
111
+ const configPath = join(targetDir, ".judgesrc");
112
+ const content = JSON.stringify(phase.config, null, 2);
113
+ writeFileSync(configPath, content + "\n", "utf-8");
114
+ return configPath;
115
+ }
116
+ // ─── CLI Entry ──────────────────────────────────────────────────────────────
117
+ export function runTrustRamp(argv) {
118
+ const args = parseArgs(argv);
119
+ const phases = buildPhases(args.preset);
120
+ if (args.emit) {
121
+ const match = /^phase-?(\d)$/i.exec(args.emit);
122
+ if (!match) {
123
+ console.error(`Error: --emit expects "phase-1" through "phase-4", got "${args.emit}"`);
124
+ process.exit(1);
125
+ }
126
+ const num = parseInt(match[1], 10);
127
+ const phase = phases.find((p) => p.phase === num);
128
+ if (!phase) {
129
+ console.error(`Error: no phase ${num}. Valid: 1-4`);
130
+ process.exit(1);
131
+ }
132
+ const dir = resolve(args.dir || ".");
133
+ const path = emitPhaseConfig(phase, dir);
134
+ console.log(`✔ Phase ${num} (${phase.name}) config written to ${path}`);
135
+ console.log(` ${phase.ciTip}`);
136
+ return;
137
+ }
138
+ // Default: show the plan
139
+ if (args.format === "json") {
140
+ console.log(formatPhasesJson(phases));
141
+ }
142
+ else {
143
+ console.log(formatPhasesText(phases));
144
+ }
145
+ }
146
+ function parseArgs(argv) {
147
+ const result = { format: "text" };
148
+ for (let i = 0; i < argv.length; i++) {
149
+ const arg = argv[i];
150
+ if (arg === "--emit" && argv[i + 1]) {
151
+ result.emit = argv[++i];
152
+ }
153
+ else if (arg === "--preset" && argv[i + 1]) {
154
+ result.preset = argv[++i];
155
+ }
156
+ else if (arg === "--format" && argv[i + 1]) {
157
+ const fmt = argv[++i];
158
+ if (fmt === "json" || fmt === "text")
159
+ result.format = fmt;
160
+ }
161
+ else if (arg === "--dir" && argv[i + 1]) {
162
+ result.dir = argv[++i];
163
+ }
164
+ else if (arg === "--help" || arg === "-h") {
165
+ printHelp();
166
+ process.exit(0);
167
+ }
168
+ }
169
+ return result;
170
+ }
171
+ function printHelp() {
172
+ console.log(`
173
+ judges trust-ramp — Generate a graduated trust configuration
174
+
175
+ Usage:
176
+ judges trust-ramp Show the 4-phase ramp plan
177
+ judges trust-ramp --format json Output plan as JSON
178
+ judges trust-ramp --emit phase-1 Write Phase 1 .judgesrc to cwd
179
+ judges trust-ramp --emit phase-2 --dir . Write Phase 2 .judgesrc to dir
180
+ judges trust-ramp --preset security-only Base phases on a preset
181
+
182
+ Options:
183
+ --emit <phase> Emit a phase config: phase-1, phase-2, phase-3, phase-4
184
+ --preset <name> Base the ramp on a named preset (e.g. security-only)
185
+ --format <fmt> Output format: text (default), json
186
+ --dir <path> Target directory for --emit (default: cwd)
187
+ -h, --help Show this help
188
+ `);
189
+ }
190
+ //# sourceMappingURL=trust-ramp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-ramp.js","sourceRoot":"","sources":["../../src/commands/trust-ramp.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -18,6 +18,11 @@ export declare function discoverCascadingConfigs(startDir: string, rootDir?: str
18
18
  * concatenated (union). Scalars (minSeverity, maxFiles, preset, failOnFindings,
19
19
  * baseline, format) use the leaf value.
20
20
  * ruleOverrides are deep-merged.
21
+ *
22
+ * Org-level policy enforcement:
23
+ * - `lockedRules`: locked rules cannot be added to `disabledRules`
24
+ * - `lockedJudges`: locked judges cannot be added to `disabledJudges`
25
+ * - `lockedMinSeverity`: child configs cannot set a more lenient minSeverity
21
26
  */
22
27
  export declare function mergeConfigs(...configs: JudgesConfig[]): JudgesConfig;
23
28
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAY,eAAe,EAAE,MAAM,YAAY,CAAC;AAS1E;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAkQzD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,YAAY,CAE5C;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAkC3F;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,CAkDrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5B,YAAY,CAiCd;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAIpF;AAID;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAY3E;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAoB,GAC9C,OAAO,CAAC,eAAe,EAAE,CAAC,CAyD5B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgBvE;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAwB1F;AAsCD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CASzF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAY,eAAe,EAAE,MAAM,YAAY,CAAC;AAe1E;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CA0RzD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,YAAY,CAE5C;AAOD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAkC3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,GAAG,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,CAoFrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAC5B,YAAY,CAiCd;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAIpF;AAID;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAY3E;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,gBAAgB,CACpC,gBAAgB,EAAE,MAAM,EAAE,EAC1B,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAoB,GAC9C,OAAO,CAAC,eAAe,EAAE,CAAC,CAyD5B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgBvE;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAwB1F;AAsCD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CASzF"}
package/dist/config.js CHANGED
@@ -9,6 +9,11 @@ import { ConfigError } from "./errors.js";
9
9
  import { normalizeLanguage } from "./language-patterns.js";
10
10
  const VALID_SEVERITIES = new Set(["critical", "high", "medium", "low", "info"]);
11
11
  const VALID_FORMATS = new Set(["text", "json", "sarif", "markdown", "html", "junit", "codeclimate"]);
12
+ /** Numeric rank for severity comparison (lower = stricter). */
13
+ const SEVERITY_RANK = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
14
+ function severityRank(s) {
15
+ return SEVERITY_RANK[s] ?? 4;
16
+ }
12
17
  /**
13
18
  * Parse a JSON string into a JudgesConfig, with validation.
14
19
  */
@@ -243,6 +248,27 @@ export function parseConfig(jsonStr) {
243
248
  }
244
249
  config.customRules = obj.customRules;
245
250
  }
251
+ // lockedRules
252
+ if (obj.lockedRules !== undefined) {
253
+ if (!Array.isArray(obj.lockedRules) || !obj.lockedRules.every((r) => typeof r === "string")) {
254
+ throw new ConfigError('Invalid .judgesrc: "lockedRules" must be an array of strings');
255
+ }
256
+ config.lockedRules = obj.lockedRules;
257
+ }
258
+ // lockedJudges
259
+ if (obj.lockedJudges !== undefined) {
260
+ if (!Array.isArray(obj.lockedJudges) || !obj.lockedJudges.every((r) => typeof r === "string")) {
261
+ throw new ConfigError('Invalid .judgesrc: "lockedJudges" must be an array of strings');
262
+ }
263
+ config.lockedJudges = obj.lockedJudges;
264
+ }
265
+ // lockedMinSeverity
266
+ if (obj.lockedMinSeverity !== undefined) {
267
+ if (typeof obj.lockedMinSeverity !== "string" || !VALID_SEVERITIES.has(obj.lockedMinSeverity)) {
268
+ throw new ConfigError('Invalid .judgesrc: "lockedMinSeverity" must be one of critical, high, medium, low, info');
269
+ }
270
+ config.lockedMinSeverity = obj.lockedMinSeverity;
271
+ }
246
272
  return config;
247
273
  }
248
274
  /**
@@ -298,10 +324,28 @@ export function discoverCascadingConfigs(startDir, rootDir) {
298
324
  * concatenated (union). Scalars (minSeverity, maxFiles, preset, failOnFindings,
299
325
  * baseline, format) use the leaf value.
300
326
  * ruleOverrides are deep-merged.
327
+ *
328
+ * Org-level policy enforcement:
329
+ * - `lockedRules`: locked rules cannot be added to `disabledRules`
330
+ * - `lockedJudges`: locked judges cannot be added to `disabledJudges`
331
+ * - `lockedMinSeverity`: child configs cannot set a more lenient minSeverity
301
332
  */
302
333
  export function mergeConfigs(...configs) {
303
334
  const merged = {};
304
335
  for (const cfg of configs) {
336
+ // Accumulate locked fields (union across all configs — once locked, always locked)
337
+ if (cfg.lockedRules) {
338
+ merged.lockedRules = [...new Set([...(merged.lockedRules ?? []), ...cfg.lockedRules])];
339
+ }
340
+ if (cfg.lockedJudges) {
341
+ merged.lockedJudges = [...new Set([...(merged.lockedJudges ?? []), ...cfg.lockedJudges])];
342
+ }
343
+ if (cfg.lockedMinSeverity !== undefined) {
344
+ // Keep the strictest lock (lowest severity index = strictest)
345
+ if (!merged.lockedMinSeverity || severityRank(cfg.lockedMinSeverity) < severityRank(merged.lockedMinSeverity)) {
346
+ merged.lockedMinSeverity = cfg.lockedMinSeverity;
347
+ }
348
+ }
305
349
  // Concatenate arrays (deduplicated)
306
350
  if (cfg.disabledRules) {
307
351
  merged.disabledRules = [...new Set([...(merged.disabledRules ?? []), ...cfg.disabledRules])];
@@ -349,6 +393,27 @@ export function mergeConfigs(...configs) {
349
393
  merged.overrides = [...(merged.overrides ?? []), ...cfg.overrides];
350
394
  }
351
395
  }
396
+ // ── Enforce org-level locked policies ──────────────────────────────
397
+ // Remove locked rules from disabledRules (they must stay enabled)
398
+ if (merged.lockedRules?.length && merged.disabledRules?.length) {
399
+ const locked = new Set(merged.lockedRules);
400
+ merged.disabledRules = merged.disabledRules.filter((r) => !locked.has(r));
401
+ if (merged.disabledRules.length === 0)
402
+ delete merged.disabledRules;
403
+ }
404
+ // Remove locked judges from disabledJudges (they must stay enabled)
405
+ if (merged.lockedJudges?.length && merged.disabledJudges?.length) {
406
+ const locked = new Set(merged.lockedJudges);
407
+ merged.disabledJudges = merged.disabledJudges.filter((j) => !locked.has(j));
408
+ if (merged.disabledJudges.length === 0)
409
+ delete merged.disabledJudges;
410
+ }
411
+ // Enforce minSeverity floor — child cannot be more lenient than the lock
412
+ if (merged.lockedMinSeverity && merged.minSeverity) {
413
+ if (severityRank(merged.minSeverity) > severityRank(merged.lockedMinSeverity)) {
414
+ merged.minSeverity = merged.lockedMinSeverity;
415
+ }
416
+ }
352
417
  return merged;
353
418
  }
354
419
  /**