@kevinrabun/judges 3.42.0 → 3.44.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 +25 -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/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/burndown.d.ts +27 -0
- package/dist/commands/burndown.d.ts.map +1 -0
- package/dist/commands/burndown.js +180 -0
- package/dist/commands/burndown.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/kb.d.ts +41 -0
- package/dist/commands/kb.d.ts.map +1 -0
- package/dist/commands/kb.js +231 -0
- package/dist/commands/kb.js.map +1 -0
- package/dist/commands/noise-advisor.d.ts +30 -0
- package/dist/commands/noise-advisor.d.ts.map +1 -0
- package/dist/commands/noise-advisor.js +171 -0
- package/dist/commands/noise-advisor.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/recommend.d.ts +21 -0
- package/dist/commands/recommend.d.ts.map +1 -0
- package/dist/commands/recommend.js +283 -0
- package/dist/commands/recommend.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/report-template.d.ts +17 -0
- package/dist/commands/report-template.d.ts.map +1 -0
- package/dist/commands/report-template.js +291 -0
- package/dist/commands/report-template.js.map +1 -0
- package/dist/commands/review-queue.d.ts +34 -0
- package/dist/commands/review-queue.d.ts.map +1 -0
- package/dist/commands/review-queue.js +226 -0
- package/dist/commands/review-queue.js.map +1 -0
- package/dist/commands/rule-owner.d.ts +31 -0
- package/dist/commands/rule-owner.d.ts.map +1 -0
- package/dist/commands/rule-owner.js +182 -0
- package/dist/commands/rule-owner.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/suppress.d.ts +40 -0
- package/dist/commands/suppress.d.ts.map +1 -0
- package/dist/commands/suppress.js +209 -0
- package/dist/commands/suppress.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,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule ownership — map rules/categories to team owners for
|
|
3
|
+
* accountability, escalation, and expertise routing.
|
|
4
|
+
*
|
|
5
|
+
* Stored locally in .judges-owners.json.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
8
|
+
const OWNER_FILE = ".judges-owners.json";
|
|
9
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
10
|
+
function loadDb(file = OWNER_FILE) {
|
|
11
|
+
if (!existsSync(file))
|
|
12
|
+
return { owners: [] };
|
|
13
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
14
|
+
}
|
|
15
|
+
function saveDb(db, file = OWNER_FILE) {
|
|
16
|
+
writeFileSync(file, JSON.stringify(db, null, 2));
|
|
17
|
+
}
|
|
18
|
+
export function assignOwner(pattern, owner, opts) {
|
|
19
|
+
const db = loadDb();
|
|
20
|
+
const existing = db.owners.find((o) => o.pattern === pattern);
|
|
21
|
+
const entry = {
|
|
22
|
+
pattern,
|
|
23
|
+
owner,
|
|
24
|
+
contact: opts?.contact,
|
|
25
|
+
expertise: opts?.expertise || "familiar",
|
|
26
|
+
assignedIso: new Date().toISOString(),
|
|
27
|
+
};
|
|
28
|
+
if (existing) {
|
|
29
|
+
Object.assign(existing, entry);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
db.owners.push(entry);
|
|
33
|
+
}
|
|
34
|
+
saveDb(db);
|
|
35
|
+
return entry;
|
|
36
|
+
}
|
|
37
|
+
export function removeOwner(pattern) {
|
|
38
|
+
const db = loadDb();
|
|
39
|
+
const idx = db.owners.findIndex((o) => o.pattern === pattern);
|
|
40
|
+
if (idx < 0)
|
|
41
|
+
return false;
|
|
42
|
+
db.owners.splice(idx, 1);
|
|
43
|
+
saveDb(db);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
export function findOwner(ruleId) {
|
|
47
|
+
const db = loadDb();
|
|
48
|
+
// Exact match first, then prefix match (longest prefix wins)
|
|
49
|
+
const exact = db.owners.find((o) => o.pattern === ruleId);
|
|
50
|
+
if (exact)
|
|
51
|
+
return exact;
|
|
52
|
+
let best;
|
|
53
|
+
for (const o of db.owners) {
|
|
54
|
+
if (ruleId.startsWith(o.pattern) && (!best || o.pattern.length > best.pattern.length)) {
|
|
55
|
+
best = o;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return best;
|
|
59
|
+
}
|
|
60
|
+
export function getOwnerStats() {
|
|
61
|
+
const db = loadDb();
|
|
62
|
+
const byOwner = {};
|
|
63
|
+
const byExpertise = {};
|
|
64
|
+
for (const o of db.owners) {
|
|
65
|
+
byOwner[o.owner] = (byOwner[o.owner] || 0) + 1;
|
|
66
|
+
byExpertise[o.expertise] = (byExpertise[o.expertise] || 0) + 1;
|
|
67
|
+
}
|
|
68
|
+
return { totalPatterns: db.owners.length, byOwner, byExpertise };
|
|
69
|
+
}
|
|
70
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
71
|
+
export function runRuleOwner(argv) {
|
|
72
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
73
|
+
console.log(`
|
|
74
|
+
judges rule-owner — Map rules to team owners for accountability
|
|
75
|
+
|
|
76
|
+
Usage:
|
|
77
|
+
judges rule-owner --set SEC --owner "Security Team" --contact "#sec-channel"
|
|
78
|
+
judges rule-owner --set AUTH-003 --owner "Alice" --expertise expert
|
|
79
|
+
judges rule-owner --find SEC-001 Find who owns a rule
|
|
80
|
+
judges rule-owner --list List all ownership mappings
|
|
81
|
+
judges rule-owner --remove SEC Remove ownership
|
|
82
|
+
judges rule-owner --stats Show ownership statistics
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
--set <pattern> Rule ID or prefix to assign
|
|
86
|
+
--owner <name> Owner name or team (required with --set)
|
|
87
|
+
--contact <info> Contact info (email/Slack)
|
|
88
|
+
--expertise <level> expert | familiar | learning
|
|
89
|
+
--find <rule-id> Find owner for a rule
|
|
90
|
+
--remove <pattern> Remove ownership mapping
|
|
91
|
+
--list List all mappings
|
|
92
|
+
--stats Show statistics
|
|
93
|
+
--format json JSON output
|
|
94
|
+
--help, -h Show this help
|
|
95
|
+
`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
99
|
+
// Set ownership
|
|
100
|
+
const setPattern = argv.find((_a, i) => argv[i - 1] === "--set");
|
|
101
|
+
if (setPattern) {
|
|
102
|
+
const owner = argv.find((_a, i) => argv[i - 1] === "--owner");
|
|
103
|
+
if (!owner) {
|
|
104
|
+
console.error("Error: --owner required with --set");
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
const contact = argv.find((_a, i) => argv[i - 1] === "--contact");
|
|
108
|
+
const expertise = argv.find((_a, i) => argv[i - 1] === "--expertise");
|
|
109
|
+
const entry = assignOwner(setPattern, owner, { contact, expertise });
|
|
110
|
+
if (format === "json") {
|
|
111
|
+
console.log(JSON.stringify(entry, null, 2));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
console.log(` ✅ ${entry.pattern} → ${entry.owner} (${entry.expertise})`);
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Find owner
|
|
119
|
+
const findRule = argv.find((_a, i) => argv[i - 1] === "--find");
|
|
120
|
+
if (findRule) {
|
|
121
|
+
const owner = findOwner(findRule);
|
|
122
|
+
if (!owner) {
|
|
123
|
+
console.log(` No owner found for ${findRule}`);
|
|
124
|
+
}
|
|
125
|
+
else if (format === "json") {
|
|
126
|
+
console.log(JSON.stringify(owner, null, 2));
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log(` ${findRule} → ${owner.owner} (${owner.expertise})${owner.contact ? ` — ${owner.contact}` : ""}`);
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Remove
|
|
134
|
+
const removePattern = argv.find((_a, i) => argv[i - 1] === "--remove");
|
|
135
|
+
if (removePattern) {
|
|
136
|
+
if (removeOwner(removePattern)) {
|
|
137
|
+
console.log(` Removed: ${removePattern}`);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.error(` Not found: ${removePattern}`);
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Stats
|
|
145
|
+
if (argv.includes("--stats")) {
|
|
146
|
+
const s = getOwnerStats();
|
|
147
|
+
if (format === "json") {
|
|
148
|
+
console.log(JSON.stringify(s, null, 2));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
console.log(`\n Rule Ownership\n ──────────────`);
|
|
152
|
+
console.log(` Total mappings: ${s.totalPatterns}\n`);
|
|
153
|
+
console.log(" By owner:");
|
|
154
|
+
for (const [name, count] of Object.entries(s.byOwner)) {
|
|
155
|
+
console.log(` ${name.padEnd(20)} ${count} rule(s)`);
|
|
156
|
+
}
|
|
157
|
+
console.log("\n By expertise:");
|
|
158
|
+
for (const [level, count] of Object.entries(s.byExpertise)) {
|
|
159
|
+
console.log(` ${level.padEnd(12)} ${count}`);
|
|
160
|
+
}
|
|
161
|
+
console.log("");
|
|
162
|
+
}
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Default: list all
|
|
166
|
+
const db = loadDb();
|
|
167
|
+
if (db.owners.length === 0) {
|
|
168
|
+
console.log("\n No ownership mappings. Use --set to add one.\n");
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (format === "json") {
|
|
172
|
+
console.log(JSON.stringify(db.owners, null, 2));
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
console.log("\n Rule Ownership Mappings\n ──────────────────────");
|
|
176
|
+
for (const o of db.owners) {
|
|
177
|
+
console.log(` ${o.pattern.padEnd(15)} → ${o.owner} (${o.expertise})${o.contact ? ` — ${o.contact}` : ""}`);
|
|
178
|
+
}
|
|
179
|
+
console.log("");
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=rule-owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-owner.js","sourceRoot":"","sources":["../../src/commands/rule-owner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLA tracking — define response-time SLAs per severity and track
|
|
3
|
+
* violation rates across runs.
|
|
4
|
+
*
|
|
5
|
+
* Data is stored locally in .judges-sla.json — no remote storage.
|
|
6
|
+
*/
|
|
7
|
+
import type { Finding } from "../types.js";
|
|
8
|
+
export interface SlaPolicy {
|
|
9
|
+
severity: string;
|
|
10
|
+
/** Max hours to first response/triage */
|
|
11
|
+
responseHours: number;
|
|
12
|
+
/** Max hours to remediation */
|
|
13
|
+
resolutionHours: number;
|
|
14
|
+
}
|
|
15
|
+
export interface SlaEntry {
|
|
16
|
+
findingId: string;
|
|
17
|
+
ruleId: string;
|
|
18
|
+
severity: string;
|
|
19
|
+
title: string;
|
|
20
|
+
firstSeenIso: string;
|
|
21
|
+
triagedIso?: string;
|
|
22
|
+
resolvedIso?: string;
|
|
23
|
+
status: "open" | "triaged" | "resolved";
|
|
24
|
+
}
|
|
25
|
+
interface SlaDb {
|
|
26
|
+
policies: SlaPolicy[];
|
|
27
|
+
entries: SlaEntry[];
|
|
28
|
+
}
|
|
29
|
+
export declare function trackFindings(findings: Finding[], dbPath?: string): SlaDb;
|
|
30
|
+
export declare function triageEntry(id: string, dbPath?: string): void;
|
|
31
|
+
export declare function resolveEntry(id: string, dbPath?: string): void;
|
|
32
|
+
export interface SlaViolation {
|
|
33
|
+
findingId: string;
|
|
34
|
+
ruleId: string;
|
|
35
|
+
severity: string;
|
|
36
|
+
type: "response" | "resolution";
|
|
37
|
+
elapsedHours: number;
|
|
38
|
+
allowedHours: number;
|
|
39
|
+
}
|
|
40
|
+
export declare function checkViolations(dbPath?: string): SlaViolation[];
|
|
41
|
+
export declare function getSlaStats(dbPath?: string): {
|
|
42
|
+
total: number;
|
|
43
|
+
open: number;
|
|
44
|
+
triaged: number;
|
|
45
|
+
resolved: number;
|
|
46
|
+
violations: number;
|
|
47
|
+
bySeverity: Record<string, {
|
|
48
|
+
total: number;
|
|
49
|
+
open: number;
|
|
50
|
+
violations: number;
|
|
51
|
+
}>;
|
|
52
|
+
avgResponseHours: number;
|
|
53
|
+
avgResolutionHours: number;
|
|
54
|
+
};
|
|
55
|
+
export declare function runSlaTrack(argv: string[]): Promise<void>;
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=sla-track.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sla-track.d.ts","sourceRoot":"","sources":["../../src/commands/sla-track.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CACzC;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB;AA6BD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,MAAM,SAAW,GAAG,KAAK,CAsB3E;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,IAAI,CAO/D;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,SAAW,GAAG,IAAI,CAOhE;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,GAAG,YAAY,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,MAAM,SAAW,GAAG,YAAY,EAAE,CAqCjE;AAED,wBAAgB,WAAW,CAAC,MAAM,SAAW,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CA8CA;AAID,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgI/D"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLA tracking — define response-time SLAs per severity and track
|
|
3
|
+
* violation rates across runs.
|
|
4
|
+
*
|
|
5
|
+
* Data is stored locally in .judges-sla.json — no remote storage.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
8
|
+
// ─── Default SLA Policies ───────────────────────────────────────────────────
|
|
9
|
+
const DEFAULT_POLICIES = [
|
|
10
|
+
{ severity: "critical", responseHours: 4, resolutionHours: 24 },
|
|
11
|
+
{ severity: "high", responseHours: 24, resolutionHours: 72 },
|
|
12
|
+
{ severity: "medium", responseHours: 72, resolutionHours: 168 },
|
|
13
|
+
{ severity: "low", responseHours: 168, resolutionHours: 720 },
|
|
14
|
+
{ severity: "info", responseHours: 720, resolutionHours: 2160 },
|
|
15
|
+
];
|
|
16
|
+
const SLA_FILE = ".judges-sla.json";
|
|
17
|
+
// ─── Core Functions ─────────────────────────────────────────────────────────
|
|
18
|
+
function loadDb(file) {
|
|
19
|
+
if (!existsSync(file))
|
|
20
|
+
return { policies: DEFAULT_POLICIES, entries: [] };
|
|
21
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
function saveDb(file, db) {
|
|
24
|
+
writeFileSync(file, JSON.stringify(db, null, 2));
|
|
25
|
+
}
|
|
26
|
+
function findingId(f) {
|
|
27
|
+
return `${f.ruleId}:${f.title}`;
|
|
28
|
+
}
|
|
29
|
+
export function trackFindings(findings, dbPath = SLA_FILE) {
|
|
30
|
+
const db = loadDb(dbPath);
|
|
31
|
+
const now = new Date().toISOString();
|
|
32
|
+
const seen = new Set(db.entries.map((e) => e.findingId));
|
|
33
|
+
for (const f of findings) {
|
|
34
|
+
const id = findingId(f);
|
|
35
|
+
if (!seen.has(id)) {
|
|
36
|
+
db.entries.push({
|
|
37
|
+
findingId: id,
|
|
38
|
+
ruleId: f.ruleId,
|
|
39
|
+
severity: f.severity,
|
|
40
|
+
title: f.title,
|
|
41
|
+
firstSeenIso: now,
|
|
42
|
+
status: "open",
|
|
43
|
+
});
|
|
44
|
+
seen.add(id);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
saveDb(dbPath, db);
|
|
48
|
+
return db;
|
|
49
|
+
}
|
|
50
|
+
export function triageEntry(id, dbPath = SLA_FILE) {
|
|
51
|
+
const db = loadDb(dbPath);
|
|
52
|
+
const entry = db.entries.find((e) => e.findingId === id);
|
|
53
|
+
if (!entry)
|
|
54
|
+
throw new Error(`Entry not found: ${id}`);
|
|
55
|
+
entry.triagedIso = new Date().toISOString();
|
|
56
|
+
entry.status = "triaged";
|
|
57
|
+
saveDb(dbPath, db);
|
|
58
|
+
}
|
|
59
|
+
export function resolveEntry(id, dbPath = SLA_FILE) {
|
|
60
|
+
const db = loadDb(dbPath);
|
|
61
|
+
const entry = db.entries.find((e) => e.findingId === id);
|
|
62
|
+
if (!entry)
|
|
63
|
+
throw new Error(`Entry not found: ${id}`);
|
|
64
|
+
entry.resolvedIso = new Date().toISOString();
|
|
65
|
+
entry.status = "resolved";
|
|
66
|
+
saveDb(dbPath, db);
|
|
67
|
+
}
|
|
68
|
+
export function checkViolations(dbPath = SLA_FILE) {
|
|
69
|
+
const db = loadDb(dbPath);
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
const violations = [];
|
|
72
|
+
for (const entry of db.entries) {
|
|
73
|
+
const policy = db.policies.find((p) => p.severity === entry.severity);
|
|
74
|
+
if (!policy)
|
|
75
|
+
continue;
|
|
76
|
+
const firstSeen = new Date(entry.firstSeenIso).getTime();
|
|
77
|
+
const elapsedMs = now - firstSeen;
|
|
78
|
+
const elapsedHours = Math.round((elapsedMs / 3_600_000) * 10) / 10;
|
|
79
|
+
if (entry.status === "open" && elapsedHours > policy.responseHours) {
|
|
80
|
+
violations.push({
|
|
81
|
+
findingId: entry.findingId,
|
|
82
|
+
ruleId: entry.ruleId,
|
|
83
|
+
severity: entry.severity,
|
|
84
|
+
type: "response",
|
|
85
|
+
elapsedHours,
|
|
86
|
+
allowedHours: policy.responseHours,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (entry.status !== "resolved" && elapsedHours > policy.resolutionHours) {
|
|
90
|
+
violations.push({
|
|
91
|
+
findingId: entry.findingId,
|
|
92
|
+
ruleId: entry.ruleId,
|
|
93
|
+
severity: entry.severity,
|
|
94
|
+
type: "resolution",
|
|
95
|
+
elapsedHours,
|
|
96
|
+
allowedHours: policy.resolutionHours,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return violations;
|
|
101
|
+
}
|
|
102
|
+
export function getSlaStats(dbPath = SLA_FILE) {
|
|
103
|
+
const db = loadDb(dbPath);
|
|
104
|
+
const violations = checkViolations(dbPath);
|
|
105
|
+
const stats = {
|
|
106
|
+
total: db.entries.length,
|
|
107
|
+
open: db.entries.filter((e) => e.status === "open").length,
|
|
108
|
+
triaged: db.entries.filter((e) => e.status === "triaged").length,
|
|
109
|
+
resolved: db.entries.filter((e) => e.status === "resolved").length,
|
|
110
|
+
violations: violations.length,
|
|
111
|
+
bySeverity: {},
|
|
112
|
+
avgResponseHours: 0,
|
|
113
|
+
avgResolutionHours: 0,
|
|
114
|
+
};
|
|
115
|
+
for (const entry of db.entries) {
|
|
116
|
+
if (!stats.bySeverity[entry.severity]) {
|
|
117
|
+
stats.bySeverity[entry.severity] = { total: 0, open: 0, violations: 0 };
|
|
118
|
+
}
|
|
119
|
+
stats.bySeverity[entry.severity].total++;
|
|
120
|
+
if (entry.status === "open")
|
|
121
|
+
stats.bySeverity[entry.severity].open++;
|
|
122
|
+
}
|
|
123
|
+
for (const v of violations) {
|
|
124
|
+
if (stats.bySeverity[v.severity]) {
|
|
125
|
+
stats.bySeverity[v.severity].violations++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const triaged = db.entries.filter((e) => e.triagedIso);
|
|
129
|
+
if (triaged.length > 0) {
|
|
130
|
+
const totalResponseMs = triaged.reduce((sum, e) => {
|
|
131
|
+
return sum + (new Date(e.triagedIso).getTime() - new Date(e.firstSeenIso).getTime());
|
|
132
|
+
}, 0);
|
|
133
|
+
stats.avgResponseHours = Math.round((totalResponseMs / triaged.length / 3_600_000) * 10) / 10;
|
|
134
|
+
}
|
|
135
|
+
const resolved = db.entries.filter((e) => e.resolvedIso);
|
|
136
|
+
if (resolved.length > 0) {
|
|
137
|
+
const totalResMs = resolved.reduce((sum, e) => {
|
|
138
|
+
return sum + (new Date(e.resolvedIso).getTime() - new Date(e.firstSeenIso).getTime());
|
|
139
|
+
}, 0);
|
|
140
|
+
stats.avgResolutionHours = Math.round((totalResMs / resolved.length / 3_600_000) * 10) / 10;
|
|
141
|
+
}
|
|
142
|
+
return stats;
|
|
143
|
+
}
|
|
144
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
145
|
+
export async function runSlaTrack(argv) {
|
|
146
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
147
|
+
console.log(`
|
|
148
|
+
judges sla-track — SLA tracking for security findings
|
|
149
|
+
|
|
150
|
+
Usage:
|
|
151
|
+
judges sla-track --input results.json Track findings from a results file
|
|
152
|
+
judges sla-track --check Check for SLA violations
|
|
153
|
+
judges sla-track --triage <finding-id> Mark finding as triaged
|
|
154
|
+
judges sla-track --resolve <finding-id> Mark finding as resolved
|
|
155
|
+
judges sla-track --stats Show SLA statistics
|
|
156
|
+
judges sla-track --set-policy <severity> <resp-h> <res-h>
|
|
157
|
+
|
|
158
|
+
Options:
|
|
159
|
+
--input <path> Results JSON to track
|
|
160
|
+
--check Check for SLA violations
|
|
161
|
+
--triage <id> Mark a finding as triaged
|
|
162
|
+
--resolve <id> Resolve a finding
|
|
163
|
+
--stats Show statistics
|
|
164
|
+
--set-policy Set SLA for a severity level
|
|
165
|
+
--format json JSON output
|
|
166
|
+
--help, -h Show this help
|
|
167
|
+
`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
171
|
+
// Track findings from input file
|
|
172
|
+
const inputPath = argv.find((_a, i) => argv[i - 1] === "--input");
|
|
173
|
+
if (inputPath) {
|
|
174
|
+
if (!existsSync(inputPath)) {
|
|
175
|
+
console.error(`Error: file not found: ${inputPath}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
const data = JSON.parse(readFileSync(inputPath, "utf-8"));
|
|
179
|
+
const findings = data.evaluations
|
|
180
|
+
? data.evaluations.flatMap((e) => e.findings || [])
|
|
181
|
+
: data.findings || data;
|
|
182
|
+
const db = trackFindings(findings);
|
|
183
|
+
if (format === "json") {
|
|
184
|
+
console.log(JSON.stringify(db, null, 2));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
console.log(`\n Tracked ${findings.length} findings (${db.entries.length} total in DB)\n`);
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// Triage
|
|
192
|
+
const triageTarget = argv.find((_a, i) => argv[i - 1] === "--triage");
|
|
193
|
+
if (triageTarget) {
|
|
194
|
+
triageEntry(triageTarget);
|
|
195
|
+
console.log(` Triaged: ${triageTarget}`);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
// Resolve
|
|
199
|
+
const resolveTarget = argv.find((_a, i) => argv[i - 1] === "--resolve");
|
|
200
|
+
if (resolveTarget) {
|
|
201
|
+
resolveEntry(resolveTarget);
|
|
202
|
+
console.log(` Resolved: ${resolveTarget}`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
// Set policy
|
|
206
|
+
if (argv.includes("--set-policy")) {
|
|
207
|
+
const idx = argv.indexOf("--set-policy");
|
|
208
|
+
const severity = argv[idx + 1];
|
|
209
|
+
const respH = parseFloat(argv[idx + 2]);
|
|
210
|
+
const resH = parseFloat(argv[idx + 3]);
|
|
211
|
+
if (!severity || isNaN(respH) || isNaN(resH)) {
|
|
212
|
+
console.error("Error: --set-policy <severity> <response-hours> <resolution-hours>");
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
const db = loadDb(SLA_FILE);
|
|
216
|
+
const existing = db.policies.find((p) => p.severity === severity);
|
|
217
|
+
if (existing) {
|
|
218
|
+
existing.responseHours = respH;
|
|
219
|
+
existing.resolutionHours = resH;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
db.policies.push({ severity, responseHours: respH, resolutionHours: resH });
|
|
223
|
+
}
|
|
224
|
+
saveDb(SLA_FILE, db);
|
|
225
|
+
console.log(` SLA policy set: ${severity} → response ${respH}h, resolution ${resH}h`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Check violations
|
|
229
|
+
if (argv.includes("--check")) {
|
|
230
|
+
const violations = checkViolations();
|
|
231
|
+
if (format === "json") {
|
|
232
|
+
console.log(JSON.stringify(violations, null, 2));
|
|
233
|
+
}
|
|
234
|
+
else if (violations.length === 0) {
|
|
235
|
+
console.log("\n ✅ No SLA violations\n");
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
console.log(`\n ⚠️ ${violations.length} SLA violation(s)\n`);
|
|
239
|
+
for (const v of violations) {
|
|
240
|
+
console.log(` ${v.severity.padEnd(8)} ${v.type.padEnd(10)} ${v.ruleId} — ${v.elapsedHours}h / ${v.allowedHours}h allowed`);
|
|
241
|
+
}
|
|
242
|
+
console.log("");
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
// Stats (default if --stats or no other flag)
|
|
247
|
+
const s = getSlaStats();
|
|
248
|
+
if (format === "json") {
|
|
249
|
+
console.log(JSON.stringify(s, null, 2));
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
console.log(`
|
|
253
|
+
SLA Statistics
|
|
254
|
+
──────────────────
|
|
255
|
+
Total tracked: ${s.total}
|
|
256
|
+
Open: ${s.open}
|
|
257
|
+
Triaged: ${s.triaged}
|
|
258
|
+
Resolved: ${s.resolved}
|
|
259
|
+
Violations: ${s.violations}
|
|
260
|
+
Avg response time: ${s.avgResponseHours}h
|
|
261
|
+
Avg resolution time: ${s.avgResolutionHours}h
|
|
262
|
+
`);
|
|
263
|
+
for (const [sev, data] of Object.entries(s.bySeverity)) {
|
|
264
|
+
console.log(` ${sev.padEnd(10)} ${data.total} total, ${data.open} open, ${data.violations} violations`);
|
|
265
|
+
}
|
|
266
|
+
console.log("");
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=sla-track.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sla-track.js","sourceRoot":"","sources":["../../src/commands/sla-track.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch false-positive suppression — suppress findings by glob, rule
|
|
3
|
+
* prefix, severity, or pattern with a full audit trail.
|
|
4
|
+
*
|
|
5
|
+
* Suppressions stored locally in .judges-suppressions.json.
|
|
6
|
+
*/
|
|
7
|
+
export interface SuppressionRule {
|
|
8
|
+
id: string;
|
|
9
|
+
/** Glob pattern for file paths (e.g., **\/*.test.ts) */
|
|
10
|
+
fileGlob?: string;
|
|
11
|
+
/** Rule ID prefix to suppress (e.g., AUTH) */
|
|
12
|
+
rulePrefix?: string;
|
|
13
|
+
/** Exact rule IDs to suppress */
|
|
14
|
+
ruleIds?: string[];
|
|
15
|
+
/** Minimum severity to suppress (suppress this level and below) */
|
|
16
|
+
maxSeverity?: string;
|
|
17
|
+
/** Reason for suppression */
|
|
18
|
+
reason: string;
|
|
19
|
+
/** Who created this suppression */
|
|
20
|
+
author: string;
|
|
21
|
+
/** When this suppression was created */
|
|
22
|
+
createdIso: string;
|
|
23
|
+
/** Optional expiry date */
|
|
24
|
+
expiresIso?: string;
|
|
25
|
+
/** Whether this suppression is active */
|
|
26
|
+
active: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare function addSuppression(opts: {
|
|
29
|
+
fileGlob?: string;
|
|
30
|
+
rulePrefix?: string;
|
|
31
|
+
ruleIds?: string[];
|
|
32
|
+
maxSeverity?: string;
|
|
33
|
+
reason: string;
|
|
34
|
+
author?: string;
|
|
35
|
+
expiresIn?: number;
|
|
36
|
+
}): SuppressionRule;
|
|
37
|
+
export declare function removeSuppression(id: string): boolean;
|
|
38
|
+
export declare function isFindiingSuppressed(ruleId: string, severity: string, filePath?: string): boolean;
|
|
39
|
+
export declare function runSuppress(argv: string[]): void;
|
|
40
|
+
//# sourceMappingURL=suppress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppress.d.ts","sourceRoot":"","sources":["../../src/commands/suppress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;CACjB;AAkCD,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,eAAe,CAqBlB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAOrD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAiCjG;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+GhD"}
|