@kevinrabun/judges 3.44.0 → 3.46.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.
- package/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/audit-bundle.d.ts +29 -0
- package/dist/commands/audit-bundle.d.ts.map +1 -0
- package/dist/commands/audit-bundle.js +235 -0
- package/dist/commands/audit-bundle.js.map +1 -0
- package/dist/commands/compare-runs.d.ts +38 -0
- package/dist/commands/compare-runs.d.ts.map +1 -0
- package/dist/commands/compare-runs.js +229 -0
- package/dist/commands/compare-runs.js.map +1 -0
- package/dist/commands/config-drift.d.ts +25 -0
- package/dist/commands/config-drift.d.ts.map +1 -0
- package/dist/commands/config-drift.js +214 -0
- package/dist/commands/config-drift.js.map +1 -0
- package/dist/commands/correlate.d.ts +28 -0
- package/dist/commands/correlate.d.ts.map +1 -0
- package/dist/commands/correlate.js +242 -0
- package/dist/commands/correlate.js.map +1 -0
- package/dist/commands/dev-score.d.ts +37 -0
- package/dist/commands/dev-score.d.ts.map +1 -0
- package/dist/commands/dev-score.js +204 -0
- package/dist/commands/dev-score.js.map +1 -0
- package/dist/commands/digest.d.ts +20 -0
- package/dist/commands/digest.d.ts.map +1 -0
- package/dist/commands/digest.js +222 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/explain-finding.d.ts +8 -0
- package/dist/commands/explain-finding.d.ts.map +1 -0
- package/dist/commands/explain-finding.js +279 -0
- package/dist/commands/explain-finding.js.map +1 -0
- package/dist/commands/generate.d.ts +8 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +404 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/judge-reputation.d.ts +29 -0
- package/dist/commands/judge-reputation.d.ts.map +1 -0
- package/dist/commands/judge-reputation.js +199 -0
- package/dist/commands/judge-reputation.js.map +1 -0
- package/dist/commands/learn.d.ts +27 -0
- package/dist/commands/learn.d.ts.map +1 -0
- package/dist/commands/learn.js +289 -0
- package/dist/commands/learn.js.map +1 -0
- package/dist/commands/model-risk.d.ts +28 -0
- package/dist/commands/model-risk.d.ts.map +1 -0
- package/dist/commands/model-risk.js +221 -0
- package/dist/commands/model-risk.js.map +1 -0
- package/dist/commands/query.d.ts +20 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +230 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/reg-watch.d.ts +21 -0
- package/dist/commands/reg-watch.d.ts.map +1 -0
- package/dist/commands/reg-watch.js +220 -0
- package/dist/commands/reg-watch.js.map +1 -0
- package/dist/commands/retro.d.ts +23 -0
- package/dist/commands/retro.d.ts.map +1 -0
- package/dist/commands/retro.js +217 -0
- package/dist/commands/retro.js.map +1 -0
- package/dist/commands/rule-share.d.ts +35 -0
- package/dist/commands/rule-share.d.ts.map +1 -0
- package/dist/commands/rule-share.js +203 -0
- package/dist/commands/rule-share.js.map +1 -0
- package/dist/commands/vote.d.ts +32 -0
- package/dist/commands/vote.d.ts.map +1 -0
- package/dist/commands/vote.js +201 -0
- package/dist/commands/vote.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config drift detector — compare team configurations against an
|
|
3
|
+
* organizational baseline to detect policy divergence.
|
|
4
|
+
*
|
|
5
|
+
* Uses local .judgesrc files.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, statSync } from "fs";
|
|
8
|
+
import { join, basename } from "path";
|
|
9
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
10
|
+
function loadConfig(file) {
|
|
11
|
+
if (!existsSync(file))
|
|
12
|
+
return {};
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function detectDrift(baselineFile, configFile) {
|
|
21
|
+
const baseline = loadConfig(baselineFile);
|
|
22
|
+
const config = loadConfig(configFile);
|
|
23
|
+
const items = [];
|
|
24
|
+
// Check disabled rules
|
|
25
|
+
const baselineDisabledRules = new Set(baseline.disabledRules || []);
|
|
26
|
+
const configDisabledRules = new Set(config.disabledRules || []);
|
|
27
|
+
for (const rule of configDisabledRules) {
|
|
28
|
+
if (!baselineDisabledRules.has(rule)) {
|
|
29
|
+
items.push({
|
|
30
|
+
type: "disabled-rule",
|
|
31
|
+
key: rule,
|
|
32
|
+
baselineValue: "enabled",
|
|
33
|
+
actualValue: "disabled",
|
|
34
|
+
impact: rule.startsWith("SEC") || rule.startsWith("AUTH") || rule.startsWith("CRYPTO") ? "high" : "medium",
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Check disabled judges
|
|
39
|
+
const baselineDisabledJudges = new Set(baseline.disabledJudges || []);
|
|
40
|
+
const configDisabledJudges = new Set(config.disabledJudges || []);
|
|
41
|
+
for (const judge of configDisabledJudges) {
|
|
42
|
+
if (!baselineDisabledJudges.has(judge)) {
|
|
43
|
+
items.push({
|
|
44
|
+
type: "disabled-judge",
|
|
45
|
+
key: judge,
|
|
46
|
+
baselineValue: "enabled",
|
|
47
|
+
actualValue: "disabled",
|
|
48
|
+
impact: ["cybersecurity", "authentication", "injection"].includes(judge) ? "high" : "medium",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Check severity overrides
|
|
53
|
+
const baselineOverrides = (baseline.ruleOverrides || {});
|
|
54
|
+
const configOverrides = (config.ruleOverrides || {});
|
|
55
|
+
for (const [ruleId, override] of Object.entries(configOverrides)) {
|
|
56
|
+
const baseOverride = baselineOverrides[ruleId];
|
|
57
|
+
if (override.severity && (!baseOverride || override.severity !== baseOverride.severity)) {
|
|
58
|
+
const severityOrder = ["critical", "high", "medium", "low"];
|
|
59
|
+
const configIdx = severityOrder.indexOf(override.severity);
|
|
60
|
+
const baseIdx = baseOverride ? severityOrder.indexOf(baseOverride.severity) : -1;
|
|
61
|
+
const weakened = configIdx > baseIdx;
|
|
62
|
+
items.push({
|
|
63
|
+
type: "severity-override",
|
|
64
|
+
key: ruleId,
|
|
65
|
+
baselineValue: baseOverride?.severity || "default",
|
|
66
|
+
actualValue: override.severity,
|
|
67
|
+
impact: weakened ? "high" : "low",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Check preset alignment
|
|
72
|
+
if (baseline.preset && config.preset !== baseline.preset) {
|
|
73
|
+
items.push({
|
|
74
|
+
type: "missing-preset",
|
|
75
|
+
key: "preset",
|
|
76
|
+
baselineValue: baseline.preset,
|
|
77
|
+
actualValue: config.preset || "none",
|
|
78
|
+
impact: "medium",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
// Drift score
|
|
82
|
+
const highCount = items.filter((i) => i.impact === "high").length;
|
|
83
|
+
const medCount = items.filter((i) => i.impact === "medium").length;
|
|
84
|
+
const lowCount = items.filter((i) => i.impact === "low").length;
|
|
85
|
+
const driftScore = Math.min(100, highCount * 20 + medCount * 10 + lowCount * 5);
|
|
86
|
+
return {
|
|
87
|
+
configFile,
|
|
88
|
+
baselineFile,
|
|
89
|
+
driftScore,
|
|
90
|
+
items,
|
|
91
|
+
summary: items.length === 0
|
|
92
|
+
? "Configuration is aligned with baseline."
|
|
93
|
+
: `${items.length} deviation(s) detected. Drift score: ${driftScore}/100.`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function scanDirectory(baselineFile, dir) {
|
|
97
|
+
const reports = [];
|
|
98
|
+
function walk(d) {
|
|
99
|
+
for (const entry of readdirSync(d)) {
|
|
100
|
+
const full = join(d, entry);
|
|
101
|
+
try {
|
|
102
|
+
const stat = statSync(full);
|
|
103
|
+
if (stat.isDirectory() && !entry.startsWith(".") && entry !== "node_modules") {
|
|
104
|
+
walk(full);
|
|
105
|
+
}
|
|
106
|
+
else if (entry === ".judgesrc" || entry === ".judgesrc.json") {
|
|
107
|
+
reports.push(detectDrift(baselineFile, full));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Skip inaccessible entries
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
walk(dir);
|
|
116
|
+
return reports;
|
|
117
|
+
}
|
|
118
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
119
|
+
export function runConfigDrift(argv) {
|
|
120
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
121
|
+
console.log(`
|
|
122
|
+
judges config-drift — Detect configuration divergence from baseline
|
|
123
|
+
|
|
124
|
+
Usage:
|
|
125
|
+
judges config-drift --baseline org-baseline.judgesrc --config team/.judgesrc
|
|
126
|
+
judges config-drift --baseline org-baseline.judgesrc --scan ./teams/
|
|
127
|
+
judges config-drift --baseline org-baseline.judgesrc --self
|
|
128
|
+
|
|
129
|
+
Options:
|
|
130
|
+
--baseline <file> Organization baseline config file
|
|
131
|
+
--config <file> Team config to compare
|
|
132
|
+
--scan <dir> Scan directory for .judgesrc files and compare all
|
|
133
|
+
--self Compare local .judgesrc against baseline
|
|
134
|
+
--format json JSON output
|
|
135
|
+
--help, -h Show this help
|
|
136
|
+
`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
140
|
+
const baselineFile = argv.find((_a, i) => argv[i - 1] === "--baseline");
|
|
141
|
+
if (!baselineFile) {
|
|
142
|
+
console.error(" ❌ Provide --baseline <file>. Use --help for usage.");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (!existsSync(baselineFile)) {
|
|
146
|
+
console.error(` ❌ Baseline not found: ${baselineFile}`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
// Scan directory
|
|
150
|
+
const scanDir = argv.find((_a, i) => argv[i - 1] === "--scan");
|
|
151
|
+
if (scanDir) {
|
|
152
|
+
const reports = scanDirectory(baselineFile, scanDir);
|
|
153
|
+
if (format === "json") {
|
|
154
|
+
console.log(JSON.stringify(reports, null, 2));
|
|
155
|
+
}
|
|
156
|
+
else if (reports.length === 0) {
|
|
157
|
+
console.log("\n No .judgesrc files found in scan directory.\n");
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.log(`\n Config Drift Scan (${reports.length} config(s))\n ──────────────────────────────`);
|
|
161
|
+
for (const r of reports) {
|
|
162
|
+
const icon = r.driftScore === 0 ? "✅" : r.driftScore > 50 ? "🚨" : "⚠️";
|
|
163
|
+
console.log(` ${icon} ${basename(r.configFile).padEnd(20)} drift: ${r.driftScore}/100 (${r.items.length} item(s))`);
|
|
164
|
+
}
|
|
165
|
+
console.log("");
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// Compare self
|
|
170
|
+
if (argv.includes("--self")) {
|
|
171
|
+
const localConfig = existsSync(".judgesrc") ? ".judgesrc" : ".judgesrc.json";
|
|
172
|
+
if (!existsSync(localConfig)) {
|
|
173
|
+
console.error(" ❌ No local .judgesrc found");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const report = detectDrift(baselineFile, localConfig);
|
|
177
|
+
printReport(report, format);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Compare specific config
|
|
181
|
+
const configFile = argv.find((_a, i) => argv[i - 1] === "--config");
|
|
182
|
+
if (configFile) {
|
|
183
|
+
if (!existsSync(configFile)) {
|
|
184
|
+
console.error(` ❌ Config not found: ${configFile}`);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const report = detectDrift(baselineFile, configFile);
|
|
188
|
+
printReport(report, format);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
console.error(" ❌ Provide --config, --scan, or --self. Use --help for usage.");
|
|
192
|
+
}
|
|
193
|
+
function printReport(report, format) {
|
|
194
|
+
if (format === "json") {
|
|
195
|
+
console.log(JSON.stringify(report, null, 2));
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const icon = report.driftScore === 0 ? "✅" : report.driftScore > 50 ? "🚨" : "⚠️";
|
|
199
|
+
console.log(`\n ${icon} Config Drift Report`);
|
|
200
|
+
console.log(` Baseline: ${report.baselineFile}`);
|
|
201
|
+
console.log(` Config: ${report.configFile}`);
|
|
202
|
+
console.log(` Drift Score: ${report.driftScore}/100`);
|
|
203
|
+
console.log(` ─────────────────────────`);
|
|
204
|
+
if (report.items.length === 0) {
|
|
205
|
+
console.log(" Configuration is aligned with baseline.\n");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
for (const item of report.items) {
|
|
209
|
+
const impactIcon = item.impact === "high" ? "🔴" : item.impact === "medium" ? "🟡" : "🟢";
|
|
210
|
+
console.log(` ${impactIcon} [${item.type}] ${item.key}: ${item.baselineValue} → ${item.actualValue}`);
|
|
211
|
+
}
|
|
212
|
+
console.log("");
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=config-drift.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-drift.js","sourceRoot":"","sources":["../../src/commands/config-drift.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding correlation — link related findings, identify root causes,
|
|
3
|
+
* and detect systemic patterns across evaluations.
|
|
4
|
+
*
|
|
5
|
+
* Stored locally in .judges-correlations.json.
|
|
6
|
+
*/
|
|
7
|
+
import type { Finding } from "../types.js";
|
|
8
|
+
interface CorrelationLink {
|
|
9
|
+
findingA: string;
|
|
10
|
+
findingB: string;
|
|
11
|
+
relationship: "same-root-cause" | "related" | "prerequisite" | "duplicate";
|
|
12
|
+
notes?: string;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
}
|
|
15
|
+
interface RootCause {
|
|
16
|
+
id: string;
|
|
17
|
+
title: string;
|
|
18
|
+
description: string;
|
|
19
|
+
relatedFindings: string[];
|
|
20
|
+
severity: "critical" | "high" | "medium" | "low";
|
|
21
|
+
createdAt: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function linkFindings(findingA: string, findingB: string, relationship: CorrelationLink["relationship"], notes?: string): CorrelationLink;
|
|
24
|
+
export declare function addRootCause(title: string, description: string, severity: RootCause["severity"], findingIds: string[]): RootCause;
|
|
25
|
+
export declare function autoCorrelate(findings: Finding[]): CorrelationLink[];
|
|
26
|
+
export declare function runCorrelate(argv: string[]): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=correlate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlate.d.ts","sourceRoot":"","sources":["../../src/commands/correlate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,iBAAiB,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,CAAC;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,EAC7C,KAAK,CAAC,EAAE,MAAM,GACb,eAAe,CAuBjB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,EAC/B,UAAU,EAAE,MAAM,EAAE,GACnB,SAAS,CAaX;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,eAAe,EAAE,CA4CpE;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4JjD"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding correlation — link related findings, identify root causes,
|
|
3
|
+
* and detect systemic patterns across evaluations.
|
|
4
|
+
*
|
|
5
|
+
* Stored locally in .judges-correlations.json.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
8
|
+
const CORRELATION_FILE = ".judges-correlations.json";
|
|
9
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
10
|
+
function loadDb() {
|
|
11
|
+
if (!existsSync(CORRELATION_FILE))
|
|
12
|
+
return { links: [], rootCauses: [] };
|
|
13
|
+
return JSON.parse(readFileSync(CORRELATION_FILE, "utf-8"));
|
|
14
|
+
}
|
|
15
|
+
function saveDb(db) {
|
|
16
|
+
writeFileSync(CORRELATION_FILE, JSON.stringify(db, null, 2));
|
|
17
|
+
}
|
|
18
|
+
export function linkFindings(findingA, findingB, relationship, notes) {
|
|
19
|
+
const db = loadDb();
|
|
20
|
+
// Avoid duplicates
|
|
21
|
+
const existing = db.links.find((l) => (l.findingA === findingA && l.findingB === findingB) || (l.findingA === findingB && l.findingB === findingA));
|
|
22
|
+
if (existing) {
|
|
23
|
+
existing.relationship = relationship;
|
|
24
|
+
existing.notes = notes;
|
|
25
|
+
saveDb(db);
|
|
26
|
+
return existing;
|
|
27
|
+
}
|
|
28
|
+
const link = {
|
|
29
|
+
findingA,
|
|
30
|
+
findingB,
|
|
31
|
+
relationship,
|
|
32
|
+
notes,
|
|
33
|
+
createdAt: new Date().toISOString(),
|
|
34
|
+
};
|
|
35
|
+
db.links.push(link);
|
|
36
|
+
saveDb(db);
|
|
37
|
+
return link;
|
|
38
|
+
}
|
|
39
|
+
export function addRootCause(title, description, severity, findingIds) {
|
|
40
|
+
const db = loadDb();
|
|
41
|
+
const rootCause = {
|
|
42
|
+
id: `RC-${Date.now()}`,
|
|
43
|
+
title,
|
|
44
|
+
description,
|
|
45
|
+
relatedFindings: findingIds,
|
|
46
|
+
severity,
|
|
47
|
+
createdAt: new Date().toISOString(),
|
|
48
|
+
};
|
|
49
|
+
db.rootCauses.push(rootCause);
|
|
50
|
+
saveDb(db);
|
|
51
|
+
return rootCause;
|
|
52
|
+
}
|
|
53
|
+
export function autoCorrelate(findings) {
|
|
54
|
+
const newLinks = [];
|
|
55
|
+
const db = loadDb();
|
|
56
|
+
for (let i = 0; i < findings.length; i++) {
|
|
57
|
+
for (let j = i + 1; j < findings.length; j++) {
|
|
58
|
+
const a = findings[i];
|
|
59
|
+
const b = findings[j];
|
|
60
|
+
// Same rule → likely related
|
|
61
|
+
if (a.ruleId === b.ruleId) {
|
|
62
|
+
const link = {
|
|
63
|
+
findingA: `${a.ruleId}:${a.title}`,
|
|
64
|
+
findingB: `${b.ruleId}:${b.title}`,
|
|
65
|
+
relationship: "related",
|
|
66
|
+
notes: "Same rule ID",
|
|
67
|
+
createdAt: new Date().toISOString(),
|
|
68
|
+
};
|
|
69
|
+
newLinks.push(link);
|
|
70
|
+
}
|
|
71
|
+
// Same line range → possibly duplicate
|
|
72
|
+
if (a.lineNumbers &&
|
|
73
|
+
b.lineNumbers &&
|
|
74
|
+
a.lineNumbers.length > 0 &&
|
|
75
|
+
b.lineNumbers.length > 0 &&
|
|
76
|
+
a.lineNumbers[0] === b.lineNumbers[0]) {
|
|
77
|
+
const link = {
|
|
78
|
+
findingA: `${a.ruleId}:${a.title}`,
|
|
79
|
+
findingB: `${b.ruleId}:${b.title}`,
|
|
80
|
+
relationship: "duplicate",
|
|
81
|
+
notes: `Same line: ${a.lineNumbers[0]}`,
|
|
82
|
+
createdAt: new Date().toISOString(),
|
|
83
|
+
};
|
|
84
|
+
newLinks.push(link);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
db.links.push(...newLinks);
|
|
89
|
+
saveDb(db);
|
|
90
|
+
return newLinks;
|
|
91
|
+
}
|
|
92
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
93
|
+
export function runCorrelate(argv) {
|
|
94
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
95
|
+
console.log(`
|
|
96
|
+
judges correlate — Finding correlation and root-cause analysis
|
|
97
|
+
|
|
98
|
+
Usage:
|
|
99
|
+
judges correlate --link <findingA> <findingB> --relationship related
|
|
100
|
+
judges correlate --root-cause "Missing input validation" --severity high --findings "F1,F2,F3"
|
|
101
|
+
judges correlate --auto Auto-correlate from results
|
|
102
|
+
judges correlate --graph Show correlation graph
|
|
103
|
+
judges correlate --root-causes List root causes
|
|
104
|
+
judges correlate --stats Correlation statistics
|
|
105
|
+
|
|
106
|
+
Options:
|
|
107
|
+
--link <A> <B> Link two findings
|
|
108
|
+
--relationship <type> same-root-cause | related | prerequisite | duplicate
|
|
109
|
+
--notes <text> Optional notes on the link
|
|
110
|
+
--root-cause <title> Create a root cause
|
|
111
|
+
--description <text> Root cause description
|
|
112
|
+
--severity <level> Root cause severity
|
|
113
|
+
--findings <csv> Comma-separated finding IDs
|
|
114
|
+
--auto Auto-correlate findings
|
|
115
|
+
--graph Show relationship graph
|
|
116
|
+
--root-causes List all root causes
|
|
117
|
+
--stats Show statistics
|
|
118
|
+
--format json JSON output
|
|
119
|
+
--help, -h Show this help
|
|
120
|
+
`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
124
|
+
// Link findings
|
|
125
|
+
const linkIdx = argv.indexOf("--link");
|
|
126
|
+
if (linkIdx >= 0 && argv[linkIdx + 1] && argv[linkIdx + 2]) {
|
|
127
|
+
const findingA = argv[linkIdx + 1];
|
|
128
|
+
const findingB = argv[linkIdx + 2];
|
|
129
|
+
const rel = argv.find((_a, i) => argv[i - 1] === "--relationship") ||
|
|
130
|
+
"related";
|
|
131
|
+
const notes = argv.find((_a, i) => argv[i - 1] === "--notes");
|
|
132
|
+
const link = linkFindings(findingA, findingB, rel, notes);
|
|
133
|
+
if (format === "json") {
|
|
134
|
+
console.log(JSON.stringify(link, null, 2));
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.log(` ✅ Linked: ${findingA} ↔ ${findingB} (${rel})`);
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// Root cause
|
|
142
|
+
const rootTitle = argv.find((_a, i) => argv[i - 1] === "--root-cause");
|
|
143
|
+
if (rootTitle) {
|
|
144
|
+
const desc = argv.find((_a, i) => argv[i - 1] === "--description") || rootTitle;
|
|
145
|
+
const severity = argv.find((_a, i) => argv[i - 1] === "--severity") || "medium";
|
|
146
|
+
const findingsStr = argv.find((_a, i) => argv[i - 1] === "--findings") || "";
|
|
147
|
+
const findingIds = findingsStr.split(",").filter(Boolean);
|
|
148
|
+
const rc = addRootCause(rootTitle, desc, severity, findingIds);
|
|
149
|
+
if (format === "json") {
|
|
150
|
+
console.log(JSON.stringify(rc, null, 2));
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log(` ✅ Root cause created: ${rc.id} — ${rc.title} (${rc.severity})`);
|
|
154
|
+
console.log(` Related findings: ${rc.relatedFindings.length}`);
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
// Auto correlate
|
|
159
|
+
if (argv.includes("--auto")) {
|
|
160
|
+
const resultsFile = ".judges-results.json";
|
|
161
|
+
if (!existsSync(resultsFile)) {
|
|
162
|
+
console.error(" ❌ No .judges-results.json found. Run an evaluation first.");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const data = JSON.parse(readFileSync(resultsFile, "utf-8"));
|
|
167
|
+
const findings = Array.isArray(data) ? data : data.findings || [];
|
|
168
|
+
const links = autoCorrelate(findings);
|
|
169
|
+
console.log(` ✅ Auto-correlated ${links.length} link(s) from ${findings.length} findings`);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
console.error(" ❌ Failed to parse results file");
|
|
173
|
+
}
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const db = loadDb();
|
|
177
|
+
// Root causes list
|
|
178
|
+
if (argv.includes("--root-causes")) {
|
|
179
|
+
if (format === "json") {
|
|
180
|
+
console.log(JSON.stringify(db.rootCauses, null, 2));
|
|
181
|
+
}
|
|
182
|
+
else if (db.rootCauses.length === 0) {
|
|
183
|
+
console.log("\n No root causes identified.\n");
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
console.log(`\n Root Causes (${db.rootCauses.length})\n ────────────`);
|
|
187
|
+
for (const rc of db.rootCauses) {
|
|
188
|
+
console.log(` [${rc.severity.toUpperCase()}] ${rc.id} — ${rc.title} (${rc.relatedFindings.length} findings)`);
|
|
189
|
+
}
|
|
190
|
+
console.log("");
|
|
191
|
+
}
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
// Stats
|
|
195
|
+
if (argv.includes("--stats")) {
|
|
196
|
+
const stats = {
|
|
197
|
+
totalLinks: db.links.length,
|
|
198
|
+
rootCauses: db.rootCauses.length,
|
|
199
|
+
byRelationship: {
|
|
200
|
+
related: db.links.filter((l) => l.relationship === "related").length,
|
|
201
|
+
duplicate: db.links.filter((l) => l.relationship === "duplicate").length,
|
|
202
|
+
sameRootCause: db.links.filter((l) => l.relationship === "same-root-cause").length,
|
|
203
|
+
prerequisite: db.links.filter((l) => l.relationship === "prerequisite").length,
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
if (format === "json") {
|
|
207
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log(`
|
|
211
|
+
Correlation Statistics
|
|
212
|
+
──────────────────────
|
|
213
|
+
Total links: ${stats.totalLinks}
|
|
214
|
+
Root causes: ${stats.rootCauses}
|
|
215
|
+
Related: ${stats.byRelationship.related}
|
|
216
|
+
Duplicates: ${stats.byRelationship.duplicate}
|
|
217
|
+
Same root cause: ${stats.byRelationship.sameRootCause}
|
|
218
|
+
Prerequisites: ${stats.byRelationship.prerequisite}
|
|
219
|
+
`);
|
|
220
|
+
}
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Default: graph view
|
|
224
|
+
if (db.links.length === 0 && db.rootCauses.length === 0) {
|
|
225
|
+
console.log("\n No correlations. Use --link or --auto to start.\n");
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
console.log(JSON.stringify(db, null, 2));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(`\n Correlation Graph (${db.links.length} links, ${db.rootCauses.length} root causes)\n ────────────────────`);
|
|
233
|
+
for (const l of db.links.slice(0, 20)) {
|
|
234
|
+
const arrow = l.relationship === "prerequisite" ? "→" : "↔";
|
|
235
|
+
console.log(` ${l.findingA} ${arrow} ${l.findingB} [${l.relationship}]`);
|
|
236
|
+
}
|
|
237
|
+
if (db.links.length > 20)
|
|
238
|
+
console.log(` ... and ${db.links.length - 20} more`);
|
|
239
|
+
console.log("");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=correlate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"correlate.js","sourceRoot":"","sources":["../../src/commands/correlate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Developer growth score — track individual developer improvement
|
|
3
|
+
* based on finding patterns over time.
|
|
4
|
+
*
|
|
5
|
+
* Stored locally in .judges-scores/ directory.
|
|
6
|
+
*/
|
|
7
|
+
interface ScoreEntry {
|
|
8
|
+
date: string;
|
|
9
|
+
findingsCount: number;
|
|
10
|
+
criticalCount: number;
|
|
11
|
+
highCount: number;
|
|
12
|
+
resolvedCount: number;
|
|
13
|
+
commitCount: number;
|
|
14
|
+
}
|
|
15
|
+
interface WeaknessArea {
|
|
16
|
+
rulePrefix: string;
|
|
17
|
+
category: string;
|
|
18
|
+
count: number;
|
|
19
|
+
trend: "improving" | "stable" | "worsening";
|
|
20
|
+
}
|
|
21
|
+
export interface DevScore {
|
|
22
|
+
author: string;
|
|
23
|
+
currentScore: number;
|
|
24
|
+
history: ScoreEntry[];
|
|
25
|
+
weaknesses: WeaknessArea[];
|
|
26
|
+
streak: number;
|
|
27
|
+
totalFindings: number;
|
|
28
|
+
totalResolved: number;
|
|
29
|
+
avgFindingsPerCommit: number;
|
|
30
|
+
trend: "improving" | "stable" | "declining";
|
|
31
|
+
lastUpdated: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function recordScan(author: string, findingsCount: number, criticalCount: number, highCount: number, resolvedCount: number, commitCount: number): DevScore;
|
|
34
|
+
export declare function getScore(author: string): DevScore;
|
|
35
|
+
export declare function runDevScore(argv: string[]): void;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=dev-score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-score.d.ts","sourceRoot":"","sources":["../../src/commands/dev-score.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;CAC7C;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB;AAwED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,QAAQ,CAwBV;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+HhD"}
|