@mmnto/cli 1.5.10 → 1.5.11

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 (65) hide show
  1. package/dist/adapters/github-cli-pr.d.ts +7 -0
  2. package/dist/adapters/github-cli-pr.d.ts.map +1 -1
  3. package/dist/adapters/github-cli-pr.js +31 -1
  4. package/dist/adapters/github-cli-pr.js.map +1 -1
  5. package/dist/adapters/pr-adapter.d.ts +7 -0
  6. package/dist/adapters/pr-adapter.d.ts.map +1 -1
  7. package/dist/commands/extract.d.ts +1 -0
  8. package/dist/commands/extract.d.ts.map +1 -1
  9. package/dist/commands/extract.js +1 -1
  10. package/dist/commands/extract.js.map +1 -1
  11. package/dist/commands/ledger-analyzer.d.ts.map +1 -1
  12. package/dist/commands/ledger-analyzer.js +2 -0
  13. package/dist/commands/ledger-analyzer.js.map +1 -1
  14. package/dist/commands/review-learn.d.ts.map +1 -1
  15. package/dist/commands/review-learn.js +38 -1
  16. package/dist/commands/review-learn.js.map +1 -1
  17. package/dist/commands/shield.d.ts +1 -0
  18. package/dist/commands/shield.d.ts.map +1 -1
  19. package/dist/commands/shield.js +59 -5
  20. package/dist/commands/shield.js.map +1 -1
  21. package/dist/commands/triage-pr.d.ts +4 -1
  22. package/dist/commands/triage-pr.d.ts.map +1 -1
  23. package/dist/commands/triage-pr.js +163 -3
  24. package/dist/commands/triage-pr.js.map +1 -1
  25. package/dist/exemptions/__tests__/exemption-engine.test.d.ts +2 -0
  26. package/dist/exemptions/__tests__/exemption-engine.test.d.ts.map +1 -0
  27. package/dist/exemptions/__tests__/exemption-engine.test.js +317 -0
  28. package/dist/exemptions/__tests__/exemption-engine.test.js.map +1 -0
  29. package/dist/exemptions/exemption-engine.d.ts +27 -0
  30. package/dist/exemptions/exemption-engine.d.ts.map +1 -0
  31. package/dist/exemptions/exemption-engine.js +193 -0
  32. package/dist/exemptions/exemption-engine.js.map +1 -0
  33. package/dist/exemptions/exemption-schema.d.ts +127 -0
  34. package/dist/exemptions/exemption-schema.d.ts.map +1 -0
  35. package/dist/exemptions/exemption-schema.js +32 -0
  36. package/dist/exemptions/exemption-schema.js.map +1 -0
  37. package/dist/exemptions/exemption-store.d.ts +22 -0
  38. package/dist/exemptions/exemption-store.d.ts.map +1 -0
  39. package/dist/exemptions/exemption-store.js +80 -0
  40. package/dist/exemptions/exemption-store.js.map +1 -0
  41. package/dist/index.js +4 -2
  42. package/dist/index.js.map +1 -1
  43. package/dist/parsers/bot-review-parser.d.ts +8 -0
  44. package/dist/parsers/bot-review-parser.d.ts.map +1 -1
  45. package/dist/parsers/bot-review-parser.js +48 -11
  46. package/dist/parsers/bot-review-parser.js.map +1 -1
  47. package/dist/parsers/bot-review-parser.test.js +108 -1
  48. package/dist/parsers/bot-review-parser.test.js.map +1 -1
  49. package/dist/services/__tests__/deferred-issuer.test.d.ts +2 -0
  50. package/dist/services/__tests__/deferred-issuer.test.d.ts.map +1 -0
  51. package/dist/services/__tests__/deferred-issuer.test.js +114 -0
  52. package/dist/services/__tests__/deferred-issuer.test.js.map +1 -0
  53. package/dist/services/deferred-issuer.d.ts +17 -0
  54. package/dist/services/deferred-issuer.d.ts.map +1 -0
  55. package/dist/services/deferred-issuer.js +64 -0
  56. package/dist/services/deferred-issuer.js.map +1 -0
  57. package/dist/utils/__tests__/milestone-inference.test.d.ts +2 -0
  58. package/dist/utils/__tests__/milestone-inference.test.d.ts.map +1 -0
  59. package/dist/utils/__tests__/milestone-inference.test.js +35 -0
  60. package/dist/utils/__tests__/milestone-inference.test.js.map +1 -0
  61. package/dist/utils/milestone-inference.d.ts +6 -0
  62. package/dist/utils/milestone-inference.d.ts.map +1 -0
  63. package/dist/utils/milestone-inference.js +15 -0
  64. package/dist/utils/milestone-inference.js.map +1 -0
  65. package/package.json +2 -2
@@ -0,0 +1,317 @@
1
+ import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { addManualSuppression, computePatternId, filterExemptedFindings, promoteToShared, recordFalsePositive, } from '../exemption-engine.js';
6
+ import { EMPTY_LOCAL, EMPTY_SHARED, PROMOTION_THRESHOLD } from '../exemption-schema.js';
7
+ import { readLocalExemptions, readSharedExemptions, writeLocalExemptions, writeSharedExemptions, } from '../exemption-store.js';
8
+ // ─── Helpers ───────────────────────────────────────────
9
+ const makeFinding = (message, severity = 'CRITICAL') => ({
10
+ severity,
11
+ confidence: 0.9,
12
+ message,
13
+ });
14
+ // ─── computePatternId ──────────────────────────────────
15
+ describe('computePatternId', () => {
16
+ it('produces stable hash for same message', () => {
17
+ const a = computePatternId('missing error handler in async route');
18
+ const b = computePatternId('missing error handler in async route');
19
+ expect(a).toBe(b);
20
+ });
21
+ it('produces same hash regardless of word order (keywords are sorted)', () => {
22
+ const a = computePatternId('handler missing async');
23
+ const b = computePatternId('async missing handler');
24
+ expect(a).toBe(b);
25
+ });
26
+ it('survives minor rephrasing (stopwords stripped, punctuation removed)', () => {
27
+ const a = computePatternId('the handler is missing in async route');
28
+ const b = computePatternId('handler missing, async route!');
29
+ expect(a).toBe(b);
30
+ });
31
+ it('different messages produce different hashes', () => {
32
+ const a = computePatternId('missing error handler in async route');
33
+ const b = computePatternId('unused variable declared in module');
34
+ expect(a).not.toBe(b);
35
+ });
36
+ it('prefixed with shield:', () => {
37
+ const id = computePatternId('something went wrong');
38
+ expect(id).toMatch(/^shield:[a-f0-9]{64}$/);
39
+ });
40
+ });
41
+ // ─── recordFalsePositive ───────────────────────────────
42
+ describe('recordFalsePositive', () => {
43
+ const pid = computePatternId('missing error handler');
44
+ const msg = 'missing error handler in route';
45
+ it('increments count on first call', () => {
46
+ const { updatedLocal } = recordFalsePositive({ ...EMPTY_LOCAL }, pid, 'shield', msg);
47
+ expect(updatedLocal.patterns[pid]?.count).toBe(1);
48
+ });
49
+ it('increments count on subsequent calls', () => {
50
+ let local = { ...EMPTY_LOCAL };
51
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
52
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
53
+ expect(local.patterns[pid]?.count).toBe(2);
54
+ });
55
+ it('promoted=false for counts 1 and 2', () => {
56
+ let local = { ...EMPTY_LOCAL };
57
+ let promoted;
58
+ ({ updatedLocal: local, promoted } = recordFalsePositive(local, pid, 'shield', msg));
59
+ expect(promoted).toBe(false);
60
+ ({ updatedLocal: local, promoted } = recordFalsePositive(local, pid, 'shield', msg));
61
+ expect(promoted).toBe(false);
62
+ });
63
+ it('promoted=true exactly on count 3 (PROMOTION_THRESHOLD)', () => {
64
+ expect(PROMOTION_THRESHOLD).toBe(3);
65
+ let local = { ...EMPTY_LOCAL };
66
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
67
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
68
+ const { promoted } = recordFalsePositive(local, pid, 'shield', msg);
69
+ expect(promoted).toBe(true);
70
+ });
71
+ it('promoted=false for count 4+ (only triggers once)', () => {
72
+ let local = { ...EMPTY_LOCAL };
73
+ for (let i = 0; i < 3; i++) {
74
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
75
+ }
76
+ const { updatedLocal, promoted } = recordFalsePositive(local, pid, 'shield', msg);
77
+ expect(updatedLocal.patterns[pid]?.count).toBe(4);
78
+ expect(promoted).toBe(false);
79
+ });
80
+ it('tracks unique sources (no duplicates)', () => {
81
+ let local = { ...EMPTY_LOCAL };
82
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
83
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
84
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'bot', msg));
85
+ const sources = local.patterns[pid]?.sources;
86
+ expect(sources).toEqual(['shield', 'bot']);
87
+ });
88
+ it('caps sampleMessages at 3', () => {
89
+ let local = { ...EMPTY_LOCAL };
90
+ for (let i = 0; i < 5; i++) {
91
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', `msg-${i}`));
92
+ }
93
+ expect(local.patterns[pid]?.sampleMessages).toHaveLength(3);
94
+ expect(local.patterns[pid]?.sampleMessages).toEqual(['msg-0', 'msg-1', 'msg-2']);
95
+ });
96
+ });
97
+ // ─── promoteToShared ───────────────────────────────────
98
+ describe('promoteToShared', () => {
99
+ const pid = computePatternId('missing error handler');
100
+ const makeLocalPattern = () => ({
101
+ count: 3,
102
+ sources: ['shield'],
103
+ lastSeenAt: new Date().toISOString(),
104
+ sampleMessages: ['missing error handler in route'],
105
+ });
106
+ it('adds entry to empty shared exemptions', () => {
107
+ const shared = promoteToShared({ ...EMPTY_SHARED }, pid, makeLocalPattern());
108
+ expect(shared.exemptions).toHaveLength(1);
109
+ expect(shared.exemptions[0]?.patternId).toBe(pid);
110
+ });
111
+ it('skips duplicate patternId (idempotent)', () => {
112
+ let shared = promoteToShared({ ...EMPTY_SHARED }, pid, makeLocalPattern());
113
+ shared = promoteToShared(shared, pid, makeLocalPattern());
114
+ expect(shared.exemptions).toHaveLength(1);
115
+ });
116
+ it('auto-generates label from keywords', () => {
117
+ const shared = promoteToShared({ ...EMPTY_SHARED }, pid, makeLocalPattern());
118
+ const label = shared.exemptions[0]?.label ?? '';
119
+ // label should contain keywords from the sample message
120
+ expect(label.length).toBeGreaterThan(0);
121
+ // keywords are extracted from 'missing error handler in route'
122
+ // "in" is a stopword, so expect something like "error handler missing route"
123
+ expect(label).toContain('handler');
124
+ expect(label).toContain('missing');
125
+ expect(label).toContain('route');
126
+ });
127
+ it("sets promotedBy to 'auto'", () => {
128
+ const shared = promoteToShared({ ...EMPTY_SHARED }, pid, makeLocalPattern());
129
+ expect(shared.exemptions[0]?.promotedBy).toBe('auto');
130
+ });
131
+ });
132
+ // ─── filterExemptedFindings ────────────────────────────
133
+ describe('filterExemptedFindings', () => {
134
+ it('passes through non-matching findings unchanged', () => {
135
+ const findings = [makeFinding('something unique and rare')];
136
+ const shared = { ...EMPTY_SHARED };
137
+ const { filtered, exempted } = filterExemptedFindings(findings, shared);
138
+ expect(filtered).toHaveLength(1);
139
+ expect(exempted).toHaveLength(0);
140
+ expect(filtered[0]?.severity).toBe('CRITICAL');
141
+ });
142
+ it('downgrades matching findings to INFO severity', () => {
143
+ const msg = 'missing error handler in route';
144
+ const pid = computePatternId(msg);
145
+ const shared = {
146
+ version: 1,
147
+ exemptions: [
148
+ {
149
+ patternId: pid,
150
+ label: 'error handler missing route',
151
+ reason: 'Auto-promoted',
152
+ promotedAt: new Date().toISOString(),
153
+ promotedBy: 'auto',
154
+ sampleMessages: [msg],
155
+ },
156
+ ],
157
+ };
158
+ const findings = [makeFinding(msg)];
159
+ const { filtered, exempted } = filterExemptedFindings(findings, shared);
160
+ expect(filtered).toHaveLength(0);
161
+ expect(exempted).toHaveLength(1);
162
+ expect(exempted[0]?.severity).toBe('INFO');
163
+ });
164
+ it('returns exempted findings separately', () => {
165
+ const exemptMsg = 'missing error handler in route';
166
+ const pid = computePatternId(exemptMsg);
167
+ const shared = {
168
+ version: 1,
169
+ exemptions: [
170
+ {
171
+ patternId: pid,
172
+ label: 'test',
173
+ reason: 'test',
174
+ promotedAt: new Date().toISOString(),
175
+ promotedBy: 'auto',
176
+ sampleMessages: [],
177
+ },
178
+ ],
179
+ };
180
+ const findings = [makeFinding(exemptMsg), makeFinding('totally different finding')];
181
+ const { filtered, exempted } = filterExemptedFindings(findings, shared);
182
+ expect(filtered).toHaveLength(1);
183
+ expect(filtered[0]?.message).toBe('totally different finding');
184
+ expect(exempted).toHaveLength(1);
185
+ expect(exempted[0]?.message).toBe(exemptMsg);
186
+ });
187
+ it('handles empty exemptions (no filtering)', () => {
188
+ const findings = [makeFinding('finding one'), makeFinding('finding two')];
189
+ const { filtered, exempted } = filterExemptedFindings(findings, {
190
+ ...EMPTY_SHARED,
191
+ });
192
+ expect(filtered).toHaveLength(2);
193
+ expect(exempted).toHaveLength(0);
194
+ });
195
+ it('matches auto-generated pattern IDs', () => {
196
+ // Simulate the full flow: record 3 FPs, promote, then filter
197
+ const msg = 'unused import detected in module';
198
+ const pid = computePatternId(msg);
199
+ let local = { ...EMPTY_LOCAL };
200
+ for (let i = 0; i < 3; i++) {
201
+ ({ updatedLocal: local } = recordFalsePositive(local, pid, 'shield', msg));
202
+ }
203
+ const shared = promoteToShared({ ...EMPTY_SHARED }, pid, local.patterns[pid]);
204
+ const findings = [makeFinding(msg)];
205
+ const { filtered, exempted } = filterExemptedFindings(findings, shared);
206
+ expect(filtered).toHaveLength(0);
207
+ expect(exempted).toHaveLength(1);
208
+ });
209
+ it('matches manual suppression labels (substring match in message)', () => {
210
+ const shared = addManualSuppression({ ...EMPTY_SHARED }, 'unused import', 'team convention');
211
+ const findings = [makeFinding('There is an unused import detected in the module')];
212
+ const { filtered, exempted } = filterExemptedFindings(findings, shared);
213
+ expect(filtered).toHaveLength(0);
214
+ expect(exempted).toHaveLength(1);
215
+ expect(exempted[0]?.severity).toBe('INFO');
216
+ });
217
+ });
218
+ // ─── addManualSuppression ──────────────────────────────
219
+ describe('addManualSuppression', () => {
220
+ it("adds entry with 'manual:' prefix patternId", () => {
221
+ const shared = addManualSuppression({ ...EMPTY_SHARED }, 'test-label', 'some reason');
222
+ expect(shared.exemptions).toHaveLength(1);
223
+ expect(shared.exemptions[0]?.patternId).toBe('manual:test-label');
224
+ });
225
+ it('skips duplicate labels (idempotent)', () => {
226
+ let shared = addManualSuppression({ ...EMPTY_SHARED }, 'dup-label', 'reason 1');
227
+ shared = addManualSuppression(shared, 'dup-label', 'reason 2');
228
+ expect(shared.exemptions).toHaveLength(1);
229
+ });
230
+ it("sets promotedBy to 'manual'", () => {
231
+ const shared = addManualSuppression({ ...EMPTY_SHARED }, 'my-label', 'reason');
232
+ expect(shared.exemptions[0]?.promotedBy).toBe('manual');
233
+ });
234
+ });
235
+ // ─── exemption-store ───────────────────────────────────
236
+ describe('exemption-store', () => {
237
+ let tmpDir;
238
+ beforeEach(() => {
239
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'totem-exemption-'));
240
+ });
241
+ afterEach(() => {
242
+ fs.rmSync(tmpDir, { recursive: true, force: true });
243
+ });
244
+ // ── readLocalExemptions / writeLocalExemptions ──
245
+ describe('readLocalExemptions / writeLocalExemptions', () => {
246
+ it('round-trips valid data', () => {
247
+ const data = {
248
+ patterns: {
249
+ 'shield:abc123': {
250
+ count: 2,
251
+ sources: ['shield'],
252
+ lastSeenAt: new Date().toISOString(),
253
+ sampleMessages: ['msg one'],
254
+ },
255
+ },
256
+ };
257
+ writeLocalExemptions(tmpDir, data);
258
+ const loaded = readLocalExemptions(tmpDir);
259
+ expect(loaded).toEqual(data);
260
+ });
261
+ it('returns EMPTY_LOCAL for missing file', () => {
262
+ const result = readLocalExemptions(tmpDir);
263
+ expect(result).toEqual(EMPTY_LOCAL);
264
+ });
265
+ it('returns EMPTY_LOCAL for corrupt JSON (calls onWarn)', () => {
266
+ const filePath = path.join(tmpDir, 'exemption-local.json');
267
+ fs.writeFileSync(filePath, '{ not valid json!!!', 'utf-8');
268
+ const warns = [];
269
+ const result = readLocalExemptions(tmpDir, (msg) => warns.push(msg));
270
+ expect(result).toEqual(EMPTY_LOCAL);
271
+ expect(warns.length).toBeGreaterThan(0);
272
+ });
273
+ it('returns EMPTY_LOCAL for invalid schema', () => {
274
+ const filePath = path.join(tmpDir, 'exemption-local.json');
275
+ fs.writeFileSync(filePath, JSON.stringify({ patterns: { foo: { count: 'not-a-number' } } }), 'utf-8');
276
+ const warns = [];
277
+ const result = readLocalExemptions(tmpDir, (msg) => warns.push(msg));
278
+ expect(result).toEqual(EMPTY_LOCAL);
279
+ expect(warns).toHaveLength(1);
280
+ expect(warns[0]).toContain('Corrupt');
281
+ });
282
+ });
283
+ // ── readSharedExemptions / writeSharedExemptions ──
284
+ describe('readSharedExemptions / writeSharedExemptions', () => {
285
+ it('round-trips valid data', () => {
286
+ const data = {
287
+ version: 1,
288
+ exemptions: [
289
+ {
290
+ patternId: 'shield:abc',
291
+ label: 'test label',
292
+ reason: 'test reason',
293
+ promotedAt: new Date().toISOString(),
294
+ promotedBy: 'auto',
295
+ sampleMessages: ['msg one'],
296
+ },
297
+ ],
298
+ };
299
+ writeSharedExemptions(tmpDir, data);
300
+ const loaded = readSharedExemptions(tmpDir);
301
+ expect(loaded).toEqual(data);
302
+ });
303
+ it('returns EMPTY_SHARED for missing file', () => {
304
+ const result = readSharedExemptions(tmpDir);
305
+ expect(result).toEqual(EMPTY_SHARED);
306
+ });
307
+ it('returns EMPTY_SHARED for corrupt JSON (calls onWarn)', () => {
308
+ const filePath = path.join(tmpDir, 'exemptions.json');
309
+ fs.writeFileSync(filePath, '<<<not json>>>', 'utf-8');
310
+ const warns = [];
311
+ const result = readSharedExemptions(tmpDir, (msg) => warns.push(msg));
312
+ expect(result).toEqual(EMPTY_SHARED);
313
+ expect(warns.length).toBeGreaterThan(0);
314
+ });
315
+ });
316
+ });
317
+ //# sourceMappingURL=exemption-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exemption-engine.test.js","sourceRoot":"","sources":["../../../src/exemptions/__tests__/exemption-engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ShieldFinding } from '../commands/shield-templates.js';
2
+ import type { ExemptionLocal, ExemptionPattern, ExemptionShared } from './exemption-schema.js';
3
+ export declare function computePatternId(message: string): string;
4
+ export declare function recordFalsePositive(local: ExemptionLocal, patternId: string, source: 'shield' | 'bot', message: string): {
5
+ updatedLocal: ExemptionLocal;
6
+ promoted: boolean;
7
+ };
8
+ export declare function promoteToShared(shared: ExemptionShared, patternId: string, localPattern: ExemptionPattern): ExemptionShared;
9
+ export declare function filterExemptedFindings(findings: ShieldFinding[], shared: ExemptionShared): {
10
+ filtered: ShieldFinding[];
11
+ exempted: ShieldFinding[];
12
+ };
13
+ export declare function isExempted(patternId: string, exemptions: ExemptionShared): boolean;
14
+ export declare function addManualSuppression(shared: ExemptionShared, label: string, reason: string): ExemptionShared;
15
+ export interface TrackResult {
16
+ local: ExemptionLocal;
17
+ shared: ExemptionShared;
18
+ promoted: string[];
19
+ }
20
+ /**
21
+ * Track false positives for a batch of findings. Returns updated local/shared
22
+ * state and a list of promoted pattern messages (for logging).
23
+ */
24
+ export declare function trackFalsePositives(findings: Array<{
25
+ message: string;
26
+ }>, source: 'shield' | 'bot', local: ExemptionLocal, shared: ExemptionShared): TrackResult;
27
+ //# sourceMappingURL=exemption-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exemption-engine.d.ts","sourceRoot":"","sources":["../../src/exemptions/exemption-engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,eAAe,EAEhB,MAAM,uBAAuB,CAAC;AAkE/B,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,QAAQ,GAAG,KAAK,EACxB,OAAO,EAAE,MAAM,GACd;IAAE,YAAY,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CA6BrD;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,gBAAgB,GAC7B,eAAe,CAuBjB;AAYD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,EAAE,eAAe,GACtB;IAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAsB1D;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,GAAG,OAAO,CAElF;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EACvB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,eAAe,CAsBjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EACpC,MAAM,EAAE,QAAQ,GAAG,KAAK,EACxB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,eAAe,GACtB,WAAW,CA4Bb"}
@@ -0,0 +1,193 @@
1
+ import * as crypto from 'node:crypto';
2
+ import { PROMOTION_THRESHOLD } from './exemption-schema.js';
3
+ // ─── Stopwords ──────────────────────────────────────────
4
+ const STOPWORDS = new Set([
5
+ 'a',
6
+ 'an',
7
+ 'the',
8
+ 'is',
9
+ 'are',
10
+ 'was',
11
+ 'were',
12
+ 'be',
13
+ 'been',
14
+ 'being',
15
+ 'have',
16
+ 'has',
17
+ 'had',
18
+ 'do',
19
+ 'does',
20
+ 'did',
21
+ 'will',
22
+ 'would',
23
+ 'shall',
24
+ 'should',
25
+ 'may',
26
+ 'might',
27
+ 'must',
28
+ 'can',
29
+ 'could',
30
+ 'to',
31
+ 'of',
32
+ 'in',
33
+ 'for',
34
+ 'on',
35
+ 'with',
36
+ 'at',
37
+ 'by',
38
+ 'from',
39
+ 'as',
40
+ 'or',
41
+ 'and',
42
+ 'but',
43
+ 'not',
44
+ 'this',
45
+ 'that',
46
+ 'it',
47
+ 'its',
48
+ 'no',
49
+ 'if',
50
+ 'so',
51
+ 'up',
52
+ 'out',
53
+ 'about',
54
+ ]);
55
+ function extractKeywords(message) {
56
+ return message
57
+ .toLowerCase()
58
+ .replace(/[^a-z0-9\s]/g, ' ')
59
+ .split(/\s+/)
60
+ .filter((w) => w.length >= 3 && !STOPWORDS.has(w))
61
+ .sort();
62
+ }
63
+ export function computePatternId(message) {
64
+ const keywords = extractKeywords(message);
65
+ const source = keywords.length > 0 ? keywords.join(':') : message.toLowerCase().trim();
66
+ const hash = crypto.createHash('sha256').update(source).digest('hex');
67
+ return `shield:${hash}`;
68
+ }
69
+ export function recordFalsePositive(local, patternId, source, message) {
70
+ const existing = local.patterns[patternId] ?? {
71
+ count: 0,
72
+ sources: [],
73
+ lastSeenAt: new Date().toISOString(),
74
+ sampleMessages: [],
75
+ };
76
+ const count = existing.count + 1;
77
+ const sources = existing.sources.includes(source)
78
+ ? existing.sources
79
+ : [...existing.sources, source];
80
+ const sampleMessages = existing.sampleMessages.length < 3
81
+ ? [...existing.sampleMessages, message]
82
+ : existing.sampleMessages;
83
+ const updated = {
84
+ count,
85
+ sources,
86
+ lastSeenAt: new Date().toISOString(),
87
+ sampleMessages,
88
+ };
89
+ const updatedLocal = {
90
+ patterns: { ...local.patterns, [patternId]: updated },
91
+ };
92
+ return { updatedLocal, promoted: count === PROMOTION_THRESHOLD };
93
+ }
94
+ export function promoteToShared(shared, patternId, localPattern) {
95
+ if (shared.exemptions.some((e) => e.patternId === patternId)) {
96
+ return shared;
97
+ }
98
+ const keywords = localPattern.sampleMessages[0]
99
+ ? extractKeywords(localPattern.sampleMessages[0]).slice(0, 5).join(' ')
100
+ : '';
101
+ const label = keywords || patternId;
102
+ const entry = {
103
+ patternId,
104
+ label,
105
+ reason: `Auto-promoted after ${localPattern.count} false positives`,
106
+ promotedAt: new Date().toISOString(),
107
+ promotedBy: 'auto',
108
+ sampleMessages: localPattern.sampleMessages,
109
+ };
110
+ return {
111
+ ...shared,
112
+ exemptions: [...shared.exemptions, entry],
113
+ };
114
+ }
115
+ function escapeRegExp(s) {
116
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
117
+ }
118
+ function buildManualLabelMatchers(shared) {
119
+ return shared.exemptions
120
+ .filter((e) => e.patternId.startsWith('manual:'))
121
+ .map((e) => new RegExp('\\b' + escapeRegExp(e.label.toLowerCase()) + '\\b', 'i'));
122
+ }
123
+ export function filterExemptedFindings(findings, shared) {
124
+ const autoExemptedIds = new Set(shared.exemptions.filter((e) => !e.patternId.startsWith('manual:')).map((e) => e.patternId));
125
+ const manualLabelPatterns = buildManualLabelMatchers(shared);
126
+ const filtered = [];
127
+ const exempted = [];
128
+ for (const finding of findings) {
129
+ const pid = computePatternId(finding.message);
130
+ const matchesAuto = autoExemptedIds.has(pid);
131
+ const matchesManual = manualLabelPatterns.some((re) => re.test(finding.message));
132
+ if (matchesAuto || matchesManual) {
133
+ exempted.push({ ...finding, severity: 'INFO' });
134
+ }
135
+ else {
136
+ filtered.push(finding);
137
+ }
138
+ }
139
+ return { filtered, exempted };
140
+ }
141
+ export function isExempted(patternId, exemptions) {
142
+ return exemptions.exemptions.some((e) => e.patternId === patternId);
143
+ }
144
+ export function addManualSuppression(shared, label, reason) {
145
+ const trimmed = label.trim();
146
+ if (!trimmed)
147
+ return shared;
148
+ const patternId = `manual:${trimmed}`;
149
+ if (shared.exemptions.some((e) => e.patternId === patternId)) {
150
+ return shared;
151
+ }
152
+ const entry = {
153
+ patternId,
154
+ label: trimmed,
155
+ reason,
156
+ promotedAt: new Date().toISOString(),
157
+ promotedBy: 'manual',
158
+ sampleMessages: [],
159
+ };
160
+ return {
161
+ ...shared,
162
+ exemptions: [...shared.exemptions, entry],
163
+ };
164
+ }
165
+ /**
166
+ * Track false positives for a batch of findings. Returns updated local/shared
167
+ * state and a list of promoted pattern messages (for logging).
168
+ */
169
+ export function trackFalsePositives(findings, source, local, shared) {
170
+ let currentLocal = local;
171
+ let currentShared = shared;
172
+ const promoted = [];
173
+ const seenPatternIds = new Set();
174
+ const manualPatterns = buildManualLabelMatchers(shared);
175
+ for (const finding of findings) {
176
+ const pid = computePatternId(finding.message);
177
+ if (seenPatternIds.has(pid))
178
+ continue;
179
+ seenPatternIds.add(pid);
180
+ if (isExempted(pid, currentShared))
181
+ continue;
182
+ if (manualPatterns.some((re) => re.test(finding.message)))
183
+ continue;
184
+ const { updatedLocal, promoted: didPromote } = recordFalsePositive(currentLocal, pid, source, finding.message);
185
+ currentLocal = updatedLocal;
186
+ if (didPromote) {
187
+ currentShared = promoteToShared(currentShared, pid, updatedLocal.patterns[pid]);
188
+ promoted.push(finding.message.slice(0, 80));
189
+ }
190
+ }
191
+ return { local: currentLocal, shared: currentShared, promoted };
192
+ }
193
+ //# sourceMappingURL=exemption-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exemption-engine.js","sourceRoot":"","sources":["../../src/exemptions/exemption-engine.ts"],"names":[],"mappings":"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"}