@kevinrabun/judges 3.117.2 → 3.117.3

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.
@@ -435,16 +435,8 @@ export function evaluateWithJudge(judge, code, language, context, options) {
435
435
  : undefined;
436
436
  findings.push(...judge.analyze(code, language, analyzeCtx));
437
437
  }
438
- // ── Recall boost: supplementary patterns for weak-recall categories ──
439
- const boostResult = applyRecallBoost(code, language);
440
- if (boostResult.findings.length > 0) {
441
- // Deduplicate: only add boost findings whose ruleId isn't already present
442
- for (const bf of boostResult.findings) {
443
- if (!findings.some((f) => f.ruleId === bf.ruleId)) {
444
- findings.push(bf);
445
- }
446
- }
447
- }
438
+ // NOTE: Recall boost (applyRecallBoost) is applied once in evaluateWithTribunal()
439
+ // rather than per-judge, to avoid generating N duplicate boost findings.
448
440
  // ── Absence gating ──
449
441
  // Absence-based findings ("no rate limiting", "no monitoring", etc.) are
450
442
  // project-level concerns that cannot be accurately assessed from a single
@@ -706,6 +698,18 @@ export function evaluateWithTribunal(code, language, context, options) {
706
698
  ? "warning"
707
699
  : "pass";
708
700
  const rawFindings = evaluations.flatMap((e) => e.findings);
701
+ // ── Recall boost (once, not per-judge) ──
702
+ // Apply supplementary recall-boost patterns a single time and merge into
703
+ // the raw findings before cross-evaluator dedup. Previously this ran
704
+ // inside evaluateWithJudge(), producing N identical copies per judge.
705
+ const boostResult = applyRecallBoost(code, language);
706
+ if (boostResult.findings.length > 0) {
707
+ for (const bf of boostResult.findings) {
708
+ if (!rawFindings.some((f) => f.ruleId === bf.ruleId)) {
709
+ rawFindings.push(bf);
710
+ }
711
+ }
712
+ }
709
713
  const dedupedFindings = crossEvaluatorDedup(rawFindings);
710
714
  const { filtered: fpFiltered } = filterFalsePositiveHeuristics(dedupedFindings, code, language, enrichedOptions?.filePath);
711
715
  const configFiltered = applyConfig(fpFiltered, options?.config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevinrabun/judges",
3
- "version": "3.117.2",
3
+ "version": "3.117.3",
4
4
  "description": "45 specialized judges that evaluate AI-generated code for security, cost, and quality.",
5
5
  "mcpName": "io.github.KevinRabun/judges",
6
6
  "type": "module",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/kevinrabun/judges",
8
8
  "source": "github"
9
9
  },
10
- "version": "3.117.2",
10
+ "version": "3.117.3",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.117.2",
15
+ "version": "3.117.3",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }