@kevinrabun/judges 3.43.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +56 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/burndown.d.ts +27 -0
  6. package/dist/commands/burndown.d.ts.map +1 -0
  7. package/dist/commands/burndown.js +180 -0
  8. package/dist/commands/burndown.js.map +1 -0
  9. package/dist/commands/kb.d.ts +41 -0
  10. package/dist/commands/kb.d.ts.map +1 -0
  11. package/dist/commands/kb.js +231 -0
  12. package/dist/commands/kb.js.map +1 -0
  13. package/dist/commands/noise-advisor.d.ts +30 -0
  14. package/dist/commands/noise-advisor.d.ts.map +1 -0
  15. package/dist/commands/noise-advisor.js +171 -0
  16. package/dist/commands/noise-advisor.js.map +1 -0
  17. package/dist/commands/recommend.d.ts +21 -0
  18. package/dist/commands/recommend.d.ts.map +1 -0
  19. package/dist/commands/recommend.js +283 -0
  20. package/dist/commands/recommend.js.map +1 -0
  21. package/dist/commands/report-template.d.ts +17 -0
  22. package/dist/commands/report-template.d.ts.map +1 -0
  23. package/dist/commands/report-template.js +291 -0
  24. package/dist/commands/report-template.js.map +1 -0
  25. package/dist/commands/review-queue.d.ts +34 -0
  26. package/dist/commands/review-queue.d.ts.map +1 -0
  27. package/dist/commands/review-queue.js +226 -0
  28. package/dist/commands/review-queue.js.map +1 -0
  29. package/dist/commands/rule-owner.d.ts +31 -0
  30. package/dist/commands/rule-owner.d.ts.map +1 -0
  31. package/dist/commands/rule-owner.js +182 -0
  32. package/dist/commands/rule-owner.js.map +1 -0
  33. package/dist/commands/suppress.d.ts +40 -0
  34. package/dist/commands/suppress.d.ts.map +1 -0
  35. package/dist/commands/suppress.js +209 -0
  36. package/dist/commands/suppress.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Review queue — surface findings needing human judgment and route
3
+ * them to appropriate experts based on rule ownership.
4
+ *
5
+ * Uses local data from findings, rule-owners, and feedback.
6
+ */
7
+ import type { Finding } from "../types.js";
8
+ export interface ReviewItem {
9
+ id: string;
10
+ ruleId: string;
11
+ severity: string;
12
+ title: string;
13
+ description: string;
14
+ confidence: number;
15
+ recommendedReviewer?: string;
16
+ status: "pending" | "approved" | "dismissed" | "escalated";
17
+ verdict?: string;
18
+ reviewedBy?: string;
19
+ reviewedIso?: string;
20
+ addedIso: string;
21
+ }
22
+ export declare function addToReviewQueue(findings: Finding[], confidenceThreshold?: number): ReviewItem[];
23
+ export declare function reviewItem(id: string, verdict: "approved" | "dismissed" | "escalated", reviewer: string): void;
24
+ export declare function getQueueStats(): {
25
+ total: number;
26
+ pending: number;
27
+ approved: number;
28
+ dismissed: number;
29
+ escalated: number;
30
+ byReviewer: Record<string, number>;
31
+ avgConfidence: number;
32
+ };
33
+ export declare function runReviewQueue(argv: string[]): Promise<void>;
34
+ //# sourceMappingURL=review-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-queue.d.ts","sourceRoot":"","sources":["../../src/commands/review-queue.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,CAAC;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AA6CD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,mBAAmB,SAAM,GAAG,UAAU,EAAE,CA+B7F;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAS9G;AAED,wBAAgB,aAAa,IAAI;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAuBA;AAID,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0HlE"}
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Review queue — surface findings needing human judgment and route
3
+ * them to appropriate experts based on rule ownership.
4
+ *
5
+ * Uses local data from findings, rule-owners, and feedback.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync } from "fs";
8
+ const REVIEW_FILE = ".judges-review-queue.json";
9
+ // ─── Core ───────────────────────────────────────────────────────────────────
10
+ function loadDb(file = REVIEW_FILE) {
11
+ if (!existsSync(file))
12
+ return { items: [] };
13
+ return JSON.parse(readFileSync(file, "utf-8"));
14
+ }
15
+ function saveDb(db, file = REVIEW_FILE) {
16
+ writeFileSync(file, JSON.stringify(db, null, 2));
17
+ }
18
+ function itemId(f) {
19
+ return `${f.ruleId}:${f.title}`.slice(0, 80);
20
+ }
21
+ function resolveReviewer(ruleId) {
22
+ try {
23
+ const ownerFile = ".judges-owners.json";
24
+ if (!existsSync(ownerFile))
25
+ return undefined;
26
+ const db = JSON.parse(readFileSync(ownerFile, "utf-8"));
27
+ if (!db.owners)
28
+ return undefined;
29
+ // Exact match first
30
+ const exact = db.owners.find((o) => o.pattern === ruleId);
31
+ if (exact)
32
+ return exact.owner;
33
+ // Prefix match
34
+ let best;
35
+ for (const o of db.owners) {
36
+ if (ruleId.startsWith(o.pattern) && (!best || o.pattern.length > best.pattern.length)) {
37
+ best = o;
38
+ }
39
+ }
40
+ return best?.owner;
41
+ }
42
+ catch {
43
+ return undefined;
44
+ }
45
+ }
46
+ export function addToReviewQueue(findings, confidenceThreshold = 0.6) {
47
+ const db = loadDb();
48
+ const existing = new Set(db.items.map((i) => i.id));
49
+ const added = [];
50
+ const now = new Date().toISOString();
51
+ for (const f of findings) {
52
+ const conf = f.confidence ?? 0.5;
53
+ if (conf >= confidenceThreshold)
54
+ continue; // High-confidence: auto-approved
55
+ const id = itemId(f);
56
+ if (existing.has(id))
57
+ continue;
58
+ const item = {
59
+ id,
60
+ ruleId: f.ruleId,
61
+ severity: f.severity,
62
+ title: f.title,
63
+ description: f.description,
64
+ confidence: conf,
65
+ recommendedReviewer: resolveReviewer(f.ruleId),
66
+ status: "pending",
67
+ addedIso: now,
68
+ };
69
+ db.items.push(item);
70
+ added.push(item);
71
+ existing.add(id);
72
+ }
73
+ saveDb(db);
74
+ return added;
75
+ }
76
+ export function reviewItem(id, verdict, reviewer) {
77
+ const db = loadDb();
78
+ const item = db.items.find((i) => i.id === id);
79
+ if (!item)
80
+ throw new Error(`Review item not found: ${id}`);
81
+ item.status = verdict;
82
+ item.verdict = verdict;
83
+ item.reviewedBy = reviewer;
84
+ item.reviewedIso = new Date().toISOString();
85
+ saveDb(db);
86
+ }
87
+ export function getQueueStats() {
88
+ const db = loadDb();
89
+ const stats = {
90
+ total: db.items.length,
91
+ pending: db.items.filter((i) => i.status === "pending").length,
92
+ approved: db.items.filter((i) => i.status === "approved").length,
93
+ dismissed: db.items.filter((i) => i.status === "dismissed").length,
94
+ escalated: db.items.filter((i) => i.status === "escalated").length,
95
+ byReviewer: {},
96
+ avgConfidence: 0,
97
+ };
98
+ for (const i of db.items) {
99
+ const reviewer = i.recommendedReviewer || "unassigned";
100
+ stats.byReviewer[reviewer] = (stats.byReviewer[reviewer] || 0) + 1;
101
+ }
102
+ const pending = db.items.filter((i) => i.status === "pending");
103
+ if (pending.length > 0) {
104
+ stats.avgConfidence = Math.round((pending.reduce((s, i) => s + i.confidence, 0) / pending.length) * 100) / 100;
105
+ }
106
+ return stats;
107
+ }
108
+ // ─── CLI ────────────────────────────────────────────────────────────────────
109
+ export async function runReviewQueue(argv) {
110
+ if (argv.includes("--help") || argv.includes("-h")) {
111
+ console.log(`
112
+ judges review-queue — Human review queue for low-confidence findings
113
+
114
+ Usage:
115
+ judges review-queue --input results.json Add low-confidence findings to queue
116
+ judges review-queue --list Show pending review items
117
+ judges review-queue --approve <id> --reviewer "Alice"
118
+ judges review-queue --dismiss <id> --reviewer "Bob"
119
+ judges review-queue --escalate <id> --reviewer "Carol"
120
+ judges review-queue --stats Show queue statistics
121
+
122
+ Options:
123
+ --input <path> Results JSON with findings
124
+ --threshold <n> Confidence threshold (default: 0.6, below → queue)
125
+ --list Show pending items
126
+ --approve <id> Approve a finding as valid
127
+ --dismiss <id> Dismiss a finding as FP
128
+ --escalate <id> Escalate for deeper review
129
+ --reviewer <name> Reviewer name (required for verdicts)
130
+ --stats Queue statistics
131
+ --format json JSON output
132
+ --help, -h Show this help
133
+ `);
134
+ return;
135
+ }
136
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
137
+ // Add findings from input
138
+ const inputPath = argv.find((_a, i) => argv[i - 1] === "--input");
139
+ if (inputPath) {
140
+ if (!existsSync(inputPath)) {
141
+ console.error(`Error: file not found: ${inputPath}`);
142
+ process.exit(1);
143
+ }
144
+ const data = JSON.parse(readFileSync(inputPath, "utf-8"));
145
+ const findings = data.evaluations
146
+ ? data.evaluations.flatMap((e) => e.findings || [])
147
+ : data.findings || data;
148
+ const thresholdStr = argv.find((_a, i) => argv[i - 1] === "--threshold");
149
+ const threshold = thresholdStr ? parseFloat(thresholdStr) : 0.6;
150
+ const added = addToReviewQueue(findings, threshold);
151
+ if (format === "json") {
152
+ console.log(JSON.stringify(added, null, 2));
153
+ }
154
+ else {
155
+ console.log(`\n Added ${added.length} finding(s) to review queue (threshold: ${threshold})\n`);
156
+ for (const item of added.slice(0, 10)) {
157
+ console.log(` ${item.severity.padEnd(8)} ${item.ruleId.padEnd(12)} conf: ${item.confidence} → ${item.recommendedReviewer || "unassigned"}`);
158
+ }
159
+ if (added.length > 10)
160
+ console.log(` ... and ${added.length - 10} more`);
161
+ console.log("");
162
+ }
163
+ return;
164
+ }
165
+ // Verdicts
166
+ const reviewer = argv.find((_a, i) => argv[i - 1] === "--reviewer");
167
+ for (const action of ["approve", "dismiss", "escalate"]) {
168
+ const target = argv.find((_a, i) => argv[i - 1] === `--${action}`);
169
+ if (target) {
170
+ if (!reviewer) {
171
+ console.error("Error: --reviewer required");
172
+ process.exit(1);
173
+ }
174
+ const verdict = action === "approve" ? "approved" : action === "dismiss" ? "dismissed" : "escalated";
175
+ reviewItem(target, verdict, reviewer);
176
+ console.log(` ${verdict}: ${target} by ${reviewer}`);
177
+ return;
178
+ }
179
+ }
180
+ // List pending
181
+ if (argv.includes("--list")) {
182
+ const db = loadDb();
183
+ const pending = db.items.filter((i) => i.status === "pending");
184
+ if (format === "json") {
185
+ console.log(JSON.stringify(pending, null, 2));
186
+ }
187
+ else if (pending.length === 0) {
188
+ console.log("\n Review queue is empty.\n");
189
+ }
190
+ else {
191
+ console.log(`\n Pending Reviews (${pending.length})\n ──────────────────`);
192
+ for (const item of pending) {
193
+ console.log(` ${item.severity.padEnd(8)} ${item.ruleId.padEnd(12)} conf: ${item.confidence} → ${item.recommendedReviewer || "unassigned"}`);
194
+ console.log(` ${item.title}`);
195
+ console.log(` ID: ${item.id}`);
196
+ }
197
+ console.log("");
198
+ }
199
+ return;
200
+ }
201
+ // Stats (default)
202
+ const s = getQueueStats();
203
+ if (format === "json") {
204
+ console.log(JSON.stringify(s, null, 2));
205
+ }
206
+ else {
207
+ console.log(`
208
+ Review Queue
209
+ ────────────
210
+ Total: ${s.total}
211
+ Pending: ${s.pending}
212
+ Approved: ${s.approved}
213
+ Dismissed: ${s.dismissed}
214
+ Escalated: ${s.escalated}
215
+ Avg conf: ${s.avgConfidence}
216
+ `);
217
+ if (Object.keys(s.byReviewer).length > 0) {
218
+ console.log(" By reviewer:");
219
+ for (const [name, count] of Object.entries(s.byReviewer)) {
220
+ console.log(` ${name.padEnd(20)} ${count}`);
221
+ }
222
+ console.log("");
223
+ }
224
+ }
225
+ }
226
+ //# sourceMappingURL=review-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-queue.js","sourceRoot":"","sources":["../../src/commands/review-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
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
+ export interface RuleOwner {
8
+ /** Rule ID or prefix (e.g., "SEC-001" or "SEC") */
9
+ pattern: string;
10
+ /** Owner name or team */
11
+ owner: string;
12
+ /** Contact (email/Slack handle) */
13
+ contact?: string;
14
+ /** Expertise level */
15
+ expertise: "expert" | "familiar" | "learning";
16
+ /** When assigned */
17
+ assignedIso: string;
18
+ }
19
+ export declare function assignOwner(pattern: string, owner: string, opts?: {
20
+ contact?: string;
21
+ expertise?: RuleOwner["expertise"];
22
+ }): RuleOwner;
23
+ export declare function removeOwner(pattern: string): boolean;
24
+ export declare function findOwner(ruleId: string): RuleOwner | undefined;
25
+ export declare function getOwnerStats(): {
26
+ totalPatterns: number;
27
+ byOwner: Record<string, number>;
28
+ byExpertise: Record<string, number>;
29
+ };
30
+ export declare function runRuleOwner(argv: string[]): void;
31
+ //# sourceMappingURL=rule-owner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-owner.d.ts","sourceRoot":"","sources":["../../src/commands/rule-owner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,SAAS,EAAE,QAAQ,GAAG,UAAU,GAAG,UAAU,CAAC;IAC9C,oBAAoB;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAmBD,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;CAAE,GAC9D,SAAS,CAiBX;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAa/D;AAED,wBAAgB,aAAa,IAAI;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC,CASA;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgHjD"}
@@ -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,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"}