@kevinrabun/judges 3.42.0 → 3.43.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 +13 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/assign-findings.d.ts +37 -0
- package/dist/commands/assign-findings.d.ts.map +1 -0
- package/dist/commands/assign-findings.js +178 -0
- package/dist/commands/assign-findings.js.map +1 -0
- package/dist/commands/ci-template.d.ts +15 -0
- package/dist/commands/ci-template.d.ts.map +1 -0
- package/dist/commands/ci-template.js +212 -0
- package/dist/commands/ci-template.js.map +1 -0
- package/dist/commands/false-negatives.d.ts +35 -0
- package/dist/commands/false-negatives.d.ts.map +1 -0
- package/dist/commands/false-negatives.js +166 -0
- package/dist/commands/false-negatives.js.map +1 -0
- package/dist/commands/hook-install.d.ts +22 -0
- package/dist/commands/hook-install.d.ts.map +1 -0
- package/dist/commands/hook-install.js +143 -0
- package/dist/commands/hook-install.js.map +1 -0
- package/dist/commands/policy-audit.d.ts +53 -0
- package/dist/commands/policy-audit.d.ts.map +1 -0
- package/dist/commands/policy-audit.js +161 -0
- package/dist/commands/policy-audit.js.map +1 -0
- package/dist/commands/regression-alert.d.ts +32 -0
- package/dist/commands/regression-alert.d.ts.map +1 -0
- package/dist/commands/regression-alert.js +216 -0
- package/dist/commands/regression-alert.js.map +1 -0
- package/dist/commands/remediation.d.ts +21 -0
- package/dist/commands/remediation.d.ts.map +1 -0
- package/dist/commands/remediation.js +257 -0
- package/dist/commands/remediation.js.map +1 -0
- package/dist/commands/sla-track.d.ts +57 -0
- package/dist/commands/sla-track.d.ts.map +1 -0
- package/dist/commands/sla-track.js +269 -0
- package/dist/commands/sla-track.js.map +1 -0
- package/dist/commands/ticket-sync.d.ts +26 -0
- package/dist/commands/ticket-sync.d.ts.map +1 -0
- package/dist/commands/ticket-sync.js +236 -0
- package/dist/commands/ticket-sync.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy audit trail — record which rules/judges were active at evaluation
|
|
3
|
+
* time, creating an immutable local audit log for compliance proof.
|
|
4
|
+
*
|
|
5
|
+
* Enables SOC2/ISO27001 auditors to verify that security policies were
|
|
6
|
+
* enforced at the time of each evaluation. All data stays local.
|
|
7
|
+
*/
|
|
8
|
+
import type { TribunalVerdict, JudgesConfig } from "../types.js";
|
|
9
|
+
export interface PolicySnapshot {
|
|
10
|
+
/** SHA-256 hash of the combined policy state */
|
|
11
|
+
policyHash: string;
|
|
12
|
+
/** ISO timestamp */
|
|
13
|
+
timestamp: string;
|
|
14
|
+
/** Config file path */
|
|
15
|
+
configPath: string;
|
|
16
|
+
/** Active preset(s) */
|
|
17
|
+
presets: string[];
|
|
18
|
+
/** Judges that were enabled */
|
|
19
|
+
enabledJudges: string[];
|
|
20
|
+
/** Judges that were disabled */
|
|
21
|
+
disabledJudges: string[];
|
|
22
|
+
/** Disabled rules */
|
|
23
|
+
disabledRules: string[];
|
|
24
|
+
/** Rule overrides */
|
|
25
|
+
ruleOverrides: Record<string, unknown>;
|
|
26
|
+
/** Min severity threshold */
|
|
27
|
+
minSeverity: string;
|
|
28
|
+
/** Git commit at evaluation time */
|
|
29
|
+
gitCommit?: string;
|
|
30
|
+
/** Evaluator version */
|
|
31
|
+
version: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AuditEntry {
|
|
34
|
+
id: string;
|
|
35
|
+
timestamp: string;
|
|
36
|
+
policySnapshot: PolicySnapshot;
|
|
37
|
+
verdictSummary: {
|
|
38
|
+
verdict: string;
|
|
39
|
+
score: number;
|
|
40
|
+
criticalCount: number;
|
|
41
|
+
highCount: number;
|
|
42
|
+
totalFindings: number;
|
|
43
|
+
};
|
|
44
|
+
filesEvaluated: number;
|
|
45
|
+
}
|
|
46
|
+
export interface AuditLog {
|
|
47
|
+
entries: AuditEntry[];
|
|
48
|
+
version: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function capturePolicySnapshot(config: JudgesConfig, configPath: string, enabledJudges: string[], version: string): PolicySnapshot;
|
|
51
|
+
export declare function recordAuditEntry(policySnapshot: PolicySnapshot, verdict: TribunalVerdict, filesEvaluated: number): AuditEntry;
|
|
52
|
+
export declare function runPolicyAudit(argv: string[]): void;
|
|
53
|
+
//# sourceMappingURL=policy-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-audit.d.ts","sourceRoot":"","sources":["../../src/commands/policy-audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIjE,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,+BAA+B;IAC/B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gCAAgC;IAChC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAID,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EAAE,EACvB,OAAO,EAAE,MAAM,GACd,cAAc,CAoChB;AAuBD,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,eAAe,EACxB,cAAc,EAAE,MAAM,GACrB,UAAU,CA4BZ;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgFnD"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy audit trail — record which rules/judges were active at evaluation
|
|
3
|
+
* time, creating an immutable local audit log for compliance proof.
|
|
4
|
+
*
|
|
5
|
+
* Enables SOC2/ISO27001 auditors to verify that security policies were
|
|
6
|
+
* enforced at the time of each evaluation. All data stays local.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "crypto";
|
|
9
|
+
// ─── Policy Snapshot ────────────────────────────────────────────────────────
|
|
10
|
+
export function capturePolicySnapshot(config, configPath, enabledJudges, version) {
|
|
11
|
+
const { execSync } = require("child_process");
|
|
12
|
+
let gitCommit;
|
|
13
|
+
try {
|
|
14
|
+
gitCommit = execSync("git rev-parse HEAD", { encoding: "utf-8" }).trim();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
/* not in git */
|
|
18
|
+
}
|
|
19
|
+
const snapshot = {
|
|
20
|
+
policyHash: "",
|
|
21
|
+
timestamp: new Date().toISOString(),
|
|
22
|
+
configPath,
|
|
23
|
+
presets: config.preset ? [config.preset] : [],
|
|
24
|
+
enabledJudges,
|
|
25
|
+
disabledJudges: config.disabledJudges || [],
|
|
26
|
+
disabledRules: config.disabledRules || [],
|
|
27
|
+
ruleOverrides: config.ruleOverrides || {},
|
|
28
|
+
minSeverity: config.minSeverity || "info",
|
|
29
|
+
gitCommit,
|
|
30
|
+
version,
|
|
31
|
+
};
|
|
32
|
+
// Compute deterministic hash of policy state
|
|
33
|
+
const hashInput = JSON.stringify({
|
|
34
|
+
presets: snapshot.presets,
|
|
35
|
+
enabledJudges: snapshot.enabledJudges.sort(),
|
|
36
|
+
disabledJudges: snapshot.disabledJudges.sort(),
|
|
37
|
+
disabledRules: snapshot.disabledRules.sort(),
|
|
38
|
+
ruleOverrides: snapshot.ruleOverrides,
|
|
39
|
+
minSeverity: snapshot.minSeverity,
|
|
40
|
+
});
|
|
41
|
+
snapshot.policyHash = createHash("sha256").update(hashInput).digest("hex").slice(0, 16);
|
|
42
|
+
return snapshot;
|
|
43
|
+
}
|
|
44
|
+
// ─── Audit Log Management ──────────────────────────────────────────────────
|
|
45
|
+
const AUDIT_FILE = ".judges-audit.json";
|
|
46
|
+
function loadAuditLog() {
|
|
47
|
+
const { readFileSync, existsSync } = require("fs");
|
|
48
|
+
if (existsSync(AUDIT_FILE)) {
|
|
49
|
+
try {
|
|
50
|
+
return JSON.parse(readFileSync(AUDIT_FILE, "utf-8"));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
/* corrupt file */
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { entries: [], version: "1.0" };
|
|
57
|
+
}
|
|
58
|
+
function saveAuditLog(log) {
|
|
59
|
+
const { writeFileSync } = require("fs");
|
|
60
|
+
writeFileSync(AUDIT_FILE, JSON.stringify(log, null, 2), "utf-8");
|
|
61
|
+
}
|
|
62
|
+
export function recordAuditEntry(policySnapshot, verdict, filesEvaluated) {
|
|
63
|
+
const entry = {
|
|
64
|
+
id: createHash("sha256")
|
|
65
|
+
.update(policySnapshot.timestamp + policySnapshot.policyHash)
|
|
66
|
+
.digest("hex")
|
|
67
|
+
.slice(0, 12),
|
|
68
|
+
timestamp: policySnapshot.timestamp,
|
|
69
|
+
policySnapshot,
|
|
70
|
+
verdictSummary: {
|
|
71
|
+
verdict: verdict.overallVerdict,
|
|
72
|
+
score: verdict.overallScore,
|
|
73
|
+
criticalCount: verdict.criticalCount,
|
|
74
|
+
highCount: verdict.highCount,
|
|
75
|
+
totalFindings: verdict.findings.length,
|
|
76
|
+
},
|
|
77
|
+
filesEvaluated,
|
|
78
|
+
};
|
|
79
|
+
const log = loadAuditLog();
|
|
80
|
+
log.entries.push(entry);
|
|
81
|
+
// Keep last 1000 entries
|
|
82
|
+
if (log.entries.length > 1000) {
|
|
83
|
+
log.entries = log.entries.slice(-1000);
|
|
84
|
+
}
|
|
85
|
+
saveAuditLog(log);
|
|
86
|
+
return entry;
|
|
87
|
+
}
|
|
88
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
89
|
+
export function runPolicyAudit(argv) {
|
|
90
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
91
|
+
console.log(`
|
|
92
|
+
judges policy-audit — View and manage the policy audit trail
|
|
93
|
+
|
|
94
|
+
Usage:
|
|
95
|
+
judges policy-audit Show recent audit entries
|
|
96
|
+
judges policy-audit --last 10 Show last 10 entries
|
|
97
|
+
judges policy-audit --diff Compare current policy to last evaluation
|
|
98
|
+
judges policy-audit --export audit.json Export full audit log
|
|
99
|
+
|
|
100
|
+
Options:
|
|
101
|
+
--last <n> Show last N entries (default: 5)
|
|
102
|
+
--diff Show policy changes since last evaluation
|
|
103
|
+
--export <path> Export audit log to file
|
|
104
|
+
--format json JSON output
|
|
105
|
+
--help, -h Show this help
|
|
106
|
+
|
|
107
|
+
The audit trail records which rules, judges, and configs were active at
|
|
108
|
+
each evaluation time. Useful for SOC2/ISO27001 compliance proof.
|
|
109
|
+
`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const { readFileSync, existsSync, writeFileSync } = require("fs");
|
|
113
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
114
|
+
const lastN = parseInt(argv.find((_a, i) => argv[i - 1] === "--last") || "5", 10);
|
|
115
|
+
const exportPath = argv.find((_a, i) => argv[i - 1] === "--export");
|
|
116
|
+
if (!existsSync(AUDIT_FILE)) {
|
|
117
|
+
console.log("\n No audit trail found. Run an evaluation first.\n");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const log = JSON.parse(readFileSync(AUDIT_FILE, "utf-8"));
|
|
121
|
+
if (exportPath) {
|
|
122
|
+
writeFileSync(exportPath, JSON.stringify(log, null, 2), "utf-8");
|
|
123
|
+
console.log(` Exported ${log.entries.length} audit entries to ${exportPath}`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const entries = log.entries.slice(-lastN);
|
|
127
|
+
if (format === "json") {
|
|
128
|
+
console.log(JSON.stringify(entries, null, 2));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (argv.includes("--diff") && log.entries.length >= 2) {
|
|
132
|
+
const prev = log.entries[log.entries.length - 2].policySnapshot;
|
|
133
|
+
const curr = log.entries[log.entries.length - 1].policySnapshot;
|
|
134
|
+
console.log("\n Policy Diff (last two evaluations)\n");
|
|
135
|
+
if (prev.policyHash !== curr.policyHash) {
|
|
136
|
+
console.log(" ⚠️ Policy changed!\n");
|
|
137
|
+
const addedJudges = curr.enabledJudges.filter((j) => !prev.enabledJudges.includes(j));
|
|
138
|
+
const removedJudges = prev.enabledJudges.filter((j) => !curr.enabledJudges.includes(j));
|
|
139
|
+
if (addedJudges.length)
|
|
140
|
+
console.log(` + Added judges: ${addedJudges.join(", ")}`);
|
|
141
|
+
if (removedJudges.length)
|
|
142
|
+
console.log(` - Removed judges: ${removedJudges.join(", ")}`);
|
|
143
|
+
if (prev.minSeverity !== curr.minSeverity)
|
|
144
|
+
console.log(` ~ Severity: ${prev.minSeverity} → ${curr.minSeverity}`);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
console.log(" ✅ No policy changes\n");
|
|
148
|
+
}
|
|
149
|
+
console.log("");
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.log(`\n Policy Audit Trail (last ${entries.length} of ${log.entries.length})\n`);
|
|
153
|
+
for (const e of entries) {
|
|
154
|
+
const v = e.verdictSummary;
|
|
155
|
+
console.log(` ${e.id} ${e.timestamp}`);
|
|
156
|
+
console.log(` Policy: ${e.policySnapshot.policyHash} Judges: ${e.policySnapshot.enabledJudges.length} Commit: ${e.policySnapshot.gitCommit?.slice(0, 8) || "N/A"}`);
|
|
157
|
+
console.log(` Verdict: ${v.verdict} Score: ${v.score} Critical: ${v.criticalCount} High: ${v.highCount} Findings: ${v.totalFindings}`);
|
|
158
|
+
console.log("");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=policy-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-audit.js","sourceRoot":"","sources":["../../src/commands/policy-audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression alerting — compare current scan results against a saved
|
|
3
|
+
* baseline snapshot to detect quality regressions.
|
|
4
|
+
*
|
|
5
|
+
* Snapshots are stored locally in .judges-baseline.json.
|
|
6
|
+
*/
|
|
7
|
+
import type { Finding } from "../types.js";
|
|
8
|
+
export interface BaselineSnapshot {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
gitCommit?: string;
|
|
11
|
+
gitBranch?: string;
|
|
12
|
+
totalFindings: number;
|
|
13
|
+
bySeverity: Record<string, number>;
|
|
14
|
+
byRule: Record<string, number>;
|
|
15
|
+
findingIds: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface RegressionReport {
|
|
18
|
+
status: "improved" | "stable" | "regressed";
|
|
19
|
+
newFindings: string[];
|
|
20
|
+
fixedFindings: string[];
|
|
21
|
+
delta: number;
|
|
22
|
+
severityDelta: Record<string, number>;
|
|
23
|
+
ruleDelta: Record<string, number>;
|
|
24
|
+
baseline: BaselineSnapshot;
|
|
25
|
+
current: BaselineSnapshot;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildSnapshot(findings: Finding[]): BaselineSnapshot;
|
|
28
|
+
export declare function saveBaseline(snapshot: BaselineSnapshot, file?: string): void;
|
|
29
|
+
export declare function loadBaseline(file?: string): BaselineSnapshot | null;
|
|
30
|
+
export declare function compareSnapshots(baseline: BaselineSnapshot, current: BaselineSnapshot): RegressionReport;
|
|
31
|
+
export declare function runRegressionAlert(argv: string[]): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=regression-alert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression-alert.d.ts","sourceRoot":"","sources":["../../src/commands/regression-alert.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;IAC5C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAqBD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAqBnE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,EAAE,IAAI,SAAgB,GAAG,IAAI,CAEnF;AAED,wBAAgB,YAAY,CAAC,IAAI,SAAgB,GAAG,gBAAgB,GAAG,IAAI,CAG1E;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAmCxG;AAID,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ItE"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression alerting — compare current scan results against a saved
|
|
3
|
+
* baseline snapshot to detect quality regressions.
|
|
4
|
+
*
|
|
5
|
+
* Snapshots are stored locally in .judges-baseline.json.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
8
|
+
const BASELINE_FILE = ".judges-baseline.json";
|
|
9
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
10
|
+
function makeFindingId(f) {
|
|
11
|
+
return `${f.ruleId}::${f.title}`;
|
|
12
|
+
}
|
|
13
|
+
function getGitInfo() {
|
|
14
|
+
try {
|
|
15
|
+
const { execSync } = require("child_process");
|
|
16
|
+
const commit = execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim();
|
|
17
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
|
|
18
|
+
return { commit, branch };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function buildSnapshot(findings) {
|
|
25
|
+
const git = getGitInfo();
|
|
26
|
+
const bySeverity = {};
|
|
27
|
+
const byRule = {};
|
|
28
|
+
const findingIds = [];
|
|
29
|
+
for (const f of findings) {
|
|
30
|
+
bySeverity[f.severity] = (bySeverity[f.severity] || 0) + 1;
|
|
31
|
+
byRule[f.ruleId] = (byRule[f.ruleId] || 0) + 1;
|
|
32
|
+
findingIds.push(makeFindingId(f));
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
timestamp: new Date().toISOString(),
|
|
36
|
+
gitCommit: git.commit,
|
|
37
|
+
gitBranch: git.branch,
|
|
38
|
+
totalFindings: findings.length,
|
|
39
|
+
bySeverity,
|
|
40
|
+
byRule,
|
|
41
|
+
findingIds,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function saveBaseline(snapshot, file = BASELINE_FILE) {
|
|
45
|
+
writeFileSync(file, JSON.stringify(snapshot, null, 2));
|
|
46
|
+
}
|
|
47
|
+
export function loadBaseline(file = BASELINE_FILE) {
|
|
48
|
+
if (!existsSync(file))
|
|
49
|
+
return null;
|
|
50
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
51
|
+
}
|
|
52
|
+
export function compareSnapshots(baseline, current) {
|
|
53
|
+
const baseSet = new Set(baseline.findingIds);
|
|
54
|
+
const currSet = new Set(current.findingIds);
|
|
55
|
+
const newFindings = current.findingIds.filter((id) => !baseSet.has(id));
|
|
56
|
+
const fixedFindings = baseline.findingIds.filter((id) => !currSet.has(id));
|
|
57
|
+
const delta = current.totalFindings - baseline.totalFindings;
|
|
58
|
+
const severityDelta = {};
|
|
59
|
+
const allSeverities = new Set([...Object.keys(baseline.bySeverity), ...Object.keys(current.bySeverity)]);
|
|
60
|
+
for (const sev of allSeverities) {
|
|
61
|
+
severityDelta[sev] = (current.bySeverity[sev] || 0) - (baseline.bySeverity[sev] || 0);
|
|
62
|
+
}
|
|
63
|
+
const ruleDelta = {};
|
|
64
|
+
const allRules = new Set([...Object.keys(baseline.byRule), ...Object.keys(current.byRule)]);
|
|
65
|
+
for (const rule of allRules) {
|
|
66
|
+
const d = (current.byRule[rule] || 0) - (baseline.byRule[rule] || 0);
|
|
67
|
+
if (d !== 0)
|
|
68
|
+
ruleDelta[rule] = d;
|
|
69
|
+
}
|
|
70
|
+
let status = "stable";
|
|
71
|
+
if (delta > 0 || newFindings.length > 0)
|
|
72
|
+
status = "regressed";
|
|
73
|
+
else if (delta < 0 || fixedFindings.length > 0)
|
|
74
|
+
status = "improved";
|
|
75
|
+
return {
|
|
76
|
+
status,
|
|
77
|
+
newFindings,
|
|
78
|
+
fixedFindings,
|
|
79
|
+
delta,
|
|
80
|
+
severityDelta,
|
|
81
|
+
ruleDelta,
|
|
82
|
+
baseline,
|
|
83
|
+
current,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
87
|
+
export async function runRegressionAlert(argv) {
|
|
88
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
89
|
+
console.log(`
|
|
90
|
+
judges regression-alert — Detect quality regressions between scans
|
|
91
|
+
|
|
92
|
+
Usage:
|
|
93
|
+
judges regression-alert --save --input results.json Save current results as baseline
|
|
94
|
+
judges regression-alert --check --input results.json Compare current results against baseline
|
|
95
|
+
judges regression-alert --show Show current baseline
|
|
96
|
+
|
|
97
|
+
Options:
|
|
98
|
+
--save Save current results as the baseline
|
|
99
|
+
--check Compare against saved baseline
|
|
100
|
+
--show Display stored baseline info
|
|
101
|
+
--input <path> Results JSON file
|
|
102
|
+
--fail-on-regression Exit with code 1 if regressions detected (CI mode)
|
|
103
|
+
--threshold <n> Only alert if >= n new findings (default: 1)
|
|
104
|
+
--format json JSON output
|
|
105
|
+
--help, -h Show this help
|
|
106
|
+
`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
110
|
+
const inputPath = argv.find((_a, i) => argv[i - 1] === "--input");
|
|
111
|
+
const failOnRegression = argv.includes("--fail-on-regression");
|
|
112
|
+
const thresholdStr = argv.find((_a, i) => argv[i - 1] === "--threshold");
|
|
113
|
+
const threshold = thresholdStr ? parseInt(thresholdStr, 10) : 1;
|
|
114
|
+
// Show baseline
|
|
115
|
+
if (argv.includes("--show")) {
|
|
116
|
+
const baseline = loadBaseline();
|
|
117
|
+
if (!baseline) {
|
|
118
|
+
console.log("\n No baseline saved. Run with --save first.\n");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (format === "json") {
|
|
122
|
+
console.log(JSON.stringify(baseline, null, 2));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.log(`
|
|
126
|
+
Baseline Snapshot
|
|
127
|
+
─────────────────
|
|
128
|
+
Saved: ${baseline.timestamp}
|
|
129
|
+
Commit: ${baseline.gitCommit || "unknown"}
|
|
130
|
+
Branch: ${baseline.gitBranch || "unknown"}
|
|
131
|
+
Findings: ${baseline.totalFindings}
|
|
132
|
+
`);
|
|
133
|
+
for (const [sev, count] of Object.entries(baseline.bySeverity)) {
|
|
134
|
+
console.log(` ${sev.padEnd(10)} ${count}`);
|
|
135
|
+
}
|
|
136
|
+
console.log("");
|
|
137
|
+
}
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// Both --save and --check need input
|
|
141
|
+
if (!inputPath) {
|
|
142
|
+
console.error("Error: --input <path> required");
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
if (!existsSync(inputPath)) {
|
|
146
|
+
console.error(`Error: file not found: ${inputPath}`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
const data = JSON.parse(readFileSync(inputPath, "utf-8"));
|
|
150
|
+
const findings = data.evaluations
|
|
151
|
+
? data.evaluations.flatMap((e) => e.findings || [])
|
|
152
|
+
: data.findings || data;
|
|
153
|
+
const snapshot = buildSnapshot(findings);
|
|
154
|
+
// Save baseline
|
|
155
|
+
if (argv.includes("--save")) {
|
|
156
|
+
saveBaseline(snapshot);
|
|
157
|
+
if (format === "json") {
|
|
158
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(`\n Baseline saved: ${snapshot.totalFindings} findings (${snapshot.gitCommit || "no git"})\n`);
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Check against baseline
|
|
166
|
+
if (argv.includes("--check")) {
|
|
167
|
+
const baseline = loadBaseline();
|
|
168
|
+
if (!baseline) {
|
|
169
|
+
console.error("Error: No baseline saved. Run with --save first.");
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
const report = compareSnapshots(baseline, snapshot);
|
|
173
|
+
if (format === "json") {
|
|
174
|
+
console.log(JSON.stringify(report, null, 2));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
const icon = report.status === "improved" ? "✅" : report.status === "regressed" ? "🚨" : "➖";
|
|
178
|
+
console.log(`\n ${icon} Status: ${report.status.toUpperCase()} (delta: ${report.delta >= 0 ? "+" : ""}${report.delta})`);
|
|
179
|
+
console.log(` Baseline: ${baseline.totalFindings} findings (${baseline.gitCommit || "?"})`);
|
|
180
|
+
console.log(` Current: ${snapshot.totalFindings} findings (${snapshot.gitCommit || "?"})\n`);
|
|
181
|
+
if (report.newFindings.length > 0) {
|
|
182
|
+
console.log(` New findings (${report.newFindings.length}):`);
|
|
183
|
+
for (const id of report.newFindings.slice(0, 20)) {
|
|
184
|
+
console.log(` + ${id}`);
|
|
185
|
+
}
|
|
186
|
+
if (report.newFindings.length > 20) {
|
|
187
|
+
console.log(` ... and ${report.newFindings.length - 20} more`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (report.fixedFindings.length > 0) {
|
|
191
|
+
console.log(`\n Fixed findings (${report.fixedFindings.length}):`);
|
|
192
|
+
for (const id of report.fixedFindings.slice(0, 20)) {
|
|
193
|
+
console.log(` - ${id}`);
|
|
194
|
+
}
|
|
195
|
+
if (report.fixedFindings.length > 20) {
|
|
196
|
+
console.log(` ... and ${report.fixedFindings.length - 20} more`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (Object.keys(report.severityDelta).length > 0) {
|
|
200
|
+
console.log("\n By severity:");
|
|
201
|
+
for (const [sev, d] of Object.entries(report.severityDelta)) {
|
|
202
|
+
if (d !== 0)
|
|
203
|
+
console.log(` ${sev.padEnd(10)} ${d >= 0 ? "+" : ""}${d}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
console.log("");
|
|
207
|
+
}
|
|
208
|
+
if (failOnRegression && report.newFindings.length >= threshold) {
|
|
209
|
+
console.error(` ❌ Regression detected: ${report.newFindings.length} new finding(s) (threshold: ${threshold})`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
console.log("Use --save, --check, or --show. See --help for details.");
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=regression-alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regression-alert.js","sourceRoot":"","sources":["../../src/commands/regression-alert.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remediation guides — provide step-by-step fix guidance for common
|
|
3
|
+
* finding categories, linked from finding output.
|
|
4
|
+
*
|
|
5
|
+
* Each guide includes: description, risk level, fix steps,
|
|
6
|
+
* code examples (before/after), and references.
|
|
7
|
+
*/
|
|
8
|
+
export interface RemediationGuide {
|
|
9
|
+
rulePrefix: string;
|
|
10
|
+
title: string;
|
|
11
|
+
category: string;
|
|
12
|
+
risk: string;
|
|
13
|
+
steps: string[];
|
|
14
|
+
beforeCode?: string;
|
|
15
|
+
afterCode?: string;
|
|
16
|
+
references: string[];
|
|
17
|
+
}
|
|
18
|
+
export declare function findGuide(ruleId: string): RemediationGuide | undefined;
|
|
19
|
+
export declare function listGuides(): RemediationGuide[];
|
|
20
|
+
export declare function runRemediationGuide(argv: string[]): void;
|
|
21
|
+
//# sourceMappingURL=remediation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remediation.d.ts","sourceRoot":"","sources":["../../src/commands/remediation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AA6KD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAGtE;AAED,wBAAgB,UAAU,IAAI,gBAAgB,EAAE,CAE/C;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmFxD"}
|