driftdetect-core 0.9.30 → 0.9.31
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/dist/audit/audit-engine.d.ts +43 -0
- package/dist/audit/audit-engine.d.ts.map +1 -0
- package/dist/audit/audit-engine.js +353 -0
- package/dist/audit/audit-engine.js.map +1 -0
- package/dist/audit/audit-store.d.ts +62 -0
- package/dist/audit/audit-store.d.ts.map +1 -0
- package/dist/audit/audit-store.js +351 -0
- package/dist/audit/audit-store.js.map +1 -0
- package/dist/audit/index.d.ts +13 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +15 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/types.d.ts +294 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +25 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/call-graph/index.d.ts.map +1 -1
- package/dist/call-graph/index.js +7 -2
- package/dist/call-graph/index.js.map +1 -1
- package/dist/call-graph/store/call-graph-store.d.ts +17 -4
- package/dist/call-graph/store/call-graph-store.d.ts.map +1 -1
- package/dist/call-graph/store/call-graph-store.js +150 -5
- package/dist/call-graph/store/call-graph-store.js.map +1 -1
- package/dist/call-graph/streaming-builder.d.ts.map +1 -1
- package/dist/call-graph/streaming-builder.js +7 -2
- package/dist/call-graph/streaming-builder.js.map +1 -1
- package/dist/call-graph/types.d.ts +4 -2
- package/dist/call-graph/types.d.ts.map +1 -1
- package/dist/call-graph/unified-provider.d.ts +6 -2
- package/dist/call-graph/unified-provider.d.ts.map +1 -1
- package/dist/call-graph/unified-provider.js +111 -2
- package/dist/call-graph/unified-provider.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/native/index.d.ts +708 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +369 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/native-adapters.d.ts +59 -0
- package/dist/native/native-adapters.d.ts.map +1 -0
- package/dist/native/native-adapters.js +579 -0
- package/dist/native/native-adapters.js.map +1 -0
- package/dist/scanner/default-ignores.d.ts +47 -0
- package/dist/scanner/default-ignores.d.ts.map +1 -0
- package/dist/scanner/default-ignores.js +499 -0
- package/dist/scanner/default-ignores.js.map +1 -0
- package/dist/scanner/index.d.ts +2 -0
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/index.js +4 -0
- package/dist/scanner/index.js.map +1 -1
- package/dist/scanner/native-scanner.d.ts +59 -0
- package/dist/scanner/native-scanner.d.ts.map +1 -0
- package/dist/scanner/native-scanner.js +66 -0
- package/dist/scanner/native-scanner.js.map +1 -0
- package/package.json +13 -13
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Engine
|
|
3
|
+
*
|
|
4
|
+
* Core engine for pattern auditing, deduplication detection,
|
|
5
|
+
* cross-validation, and recommendation generation.
|
|
6
|
+
*
|
|
7
|
+
* @module audit/audit-engine
|
|
8
|
+
*/
|
|
9
|
+
import type { Pattern } from '../store/types.js';
|
|
10
|
+
import type { AuditResult, AuditOptions, AuditEngineConfig, PatternAuditResult, DuplicateGroup, CrossValidationResult } from './types.js';
|
|
11
|
+
export declare class AuditEngine {
|
|
12
|
+
private readonly config;
|
|
13
|
+
constructor(config: AuditEngineConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Run a full audit on discovered patterns
|
|
16
|
+
*/
|
|
17
|
+
runAudit(patterns: Pattern[], options?: AuditOptions): Promise<AuditResult>;
|
|
18
|
+
/**
|
|
19
|
+
* Detect duplicate patterns based on location overlap
|
|
20
|
+
*/
|
|
21
|
+
detectDuplicates(patterns: Pattern[]): Promise<DuplicateGroup[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Cross-validate patterns against call graph and constraints
|
|
24
|
+
*/
|
|
25
|
+
crossValidate(patterns: Pattern[], _options: AuditOptions): Promise<CrossValidationResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Generate recommendations for each pattern
|
|
28
|
+
*/
|
|
29
|
+
generateRecommendations(patterns: Pattern[], crossValidation: CrossValidationResult, duplicates: DuplicateGroup[]): PatternAuditResult[];
|
|
30
|
+
/**
|
|
31
|
+
* Calculate overall health score
|
|
32
|
+
*/
|
|
33
|
+
calculateHealthScore(patterns: Pattern[], crossValidation: CrossValidationResult, duplicates: DuplicateGroup[]): number;
|
|
34
|
+
/**
|
|
35
|
+
* Build audit summary
|
|
36
|
+
*/
|
|
37
|
+
private buildSummary;
|
|
38
|
+
/**
|
|
39
|
+
* Generate a hash of the scan state for comparison
|
|
40
|
+
*/
|
|
41
|
+
private generateScanHash;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=audit-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-engine.d.ts","sourceRoot":"","sources":["../../src/audit/audit-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,WAAW,EAEX,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAElB,cAAc,EACd,qBAAqB,EAItB,MAAM,YAAY,CAAC;AAapB,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;gBAEzC,MAAM,EAAE,iBAAiB;IAWrC;;OAEG;IACG,QAAQ,CACZ,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC;IAgDvB;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA6DtE;;OAEG;IACG,aAAa,CACjB,QAAQ,EAAE,OAAO,EAAE,EACnB,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,qBAAqB,CAAC;IA8DjC;;OAEG;IACH,uBAAuB,CACrB,QAAQ,EAAE,OAAO,EAAE,EACnB,eAAe,EAAE,qBAAqB,EACtC,UAAU,EAAE,cAAc,EAAE,GAC3B,kBAAkB,EAAE;IAgGvB;;OAEG;IACH,oBAAoB,CAClB,QAAQ,EAAE,OAAO,EAAE,EACnB,eAAe,EAAE,qBAAqB,EACtC,UAAU,EAAE,cAAc,EAAE,GAC3B,MAAM;IAmCT;;OAEG;IACH,OAAO,CAAC,YAAY;IAqDpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAQzB"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Engine
|
|
3
|
+
*
|
|
4
|
+
* Core engine for pattern auditing, deduplication detection,
|
|
5
|
+
* cross-validation, and recommendation generation.
|
|
6
|
+
*
|
|
7
|
+
* @module audit/audit-engine
|
|
8
|
+
*/
|
|
9
|
+
import * as crypto from 'node:crypto';
|
|
10
|
+
import { HEALTH_SCORE_WEIGHTS } from './types.js';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Constants
|
|
13
|
+
// =============================================================================
|
|
14
|
+
const VERSION = '1.0.0';
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Audit Engine Class
|
|
17
|
+
// =============================================================================
|
|
18
|
+
export class AuditEngine {
|
|
19
|
+
config;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = {
|
|
22
|
+
rootDir: config.rootDir,
|
|
23
|
+
autoApproveThreshold: config.autoApproveThreshold ?? 0.90,
|
|
24
|
+
reviewThreshold: config.reviewThreshold ?? 0.70,
|
|
25
|
+
duplicateSimilarityThreshold: config.duplicateSimilarityThreshold ?? 0.85,
|
|
26
|
+
minLocationsForEstablished: config.minLocationsForEstablished ?? 3,
|
|
27
|
+
maxOutlierRatio: config.maxOutlierRatio ?? 0.5,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Run a full audit on discovered patterns
|
|
32
|
+
*/
|
|
33
|
+
async runAudit(patterns, options = {}) {
|
|
34
|
+
// Filter patterns by category if specified
|
|
35
|
+
let patternsToAudit = patterns;
|
|
36
|
+
if (options.categories && options.categories.length > 0) {
|
|
37
|
+
patternsToAudit = patterns.filter(p => options.categories.includes(p.category));
|
|
38
|
+
}
|
|
39
|
+
// Detect duplicates
|
|
40
|
+
const duplicates = await this.detectDuplicates(patternsToAudit);
|
|
41
|
+
// Cross-validate patterns
|
|
42
|
+
const crossValidation = await this.crossValidate(patternsToAudit, options);
|
|
43
|
+
// Generate recommendations for each pattern
|
|
44
|
+
const patternResults = this.generateRecommendations(patternsToAudit, crossValidation, duplicates);
|
|
45
|
+
// Calculate health score
|
|
46
|
+
const healthScore = this.calculateHealthScore(patternsToAudit, crossValidation, duplicates);
|
|
47
|
+
// Build summary
|
|
48
|
+
const summary = this.buildSummary(patternResults, duplicates, healthScore);
|
|
49
|
+
// Generate scan hash
|
|
50
|
+
const scanHash = this.generateScanHash(patternsToAudit);
|
|
51
|
+
const result = {
|
|
52
|
+
version: VERSION,
|
|
53
|
+
generatedAt: new Date().toISOString(),
|
|
54
|
+
scanHash,
|
|
55
|
+
summary,
|
|
56
|
+
patterns: patternResults,
|
|
57
|
+
duplicates,
|
|
58
|
+
crossValidation,
|
|
59
|
+
};
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Detect duplicate patterns based on location overlap
|
|
64
|
+
*/
|
|
65
|
+
async detectDuplicates(patterns) {
|
|
66
|
+
const duplicateGroups = [];
|
|
67
|
+
const processed = new Set();
|
|
68
|
+
for (let i = 0; i < patterns.length; i++) {
|
|
69
|
+
const patternA = patterns[i];
|
|
70
|
+
if (processed.has(patternA.id))
|
|
71
|
+
continue;
|
|
72
|
+
const group = [patternA.id];
|
|
73
|
+
const groupNames = [patternA.name];
|
|
74
|
+
let totalOverlap = 0;
|
|
75
|
+
let totalLocations = patternA.locations.length;
|
|
76
|
+
// Get file set for pattern A
|
|
77
|
+
const filesA = new Set(patternA.locations.map(l => `${l.file}:${l.line}`));
|
|
78
|
+
for (let j = i + 1; j < patterns.length; j++) {
|
|
79
|
+
const patternB = patterns[j];
|
|
80
|
+
if (processed.has(patternB.id))
|
|
81
|
+
continue;
|
|
82
|
+
// Skip if different categories (unlikely to be duplicates)
|
|
83
|
+
if (patternA.category !== patternB.category)
|
|
84
|
+
continue;
|
|
85
|
+
// Get file set for pattern B
|
|
86
|
+
const filesB = new Set(patternB.locations.map(l => `${l.file}:${l.line}`));
|
|
87
|
+
// Calculate overlap
|
|
88
|
+
const overlap = Array.from(filesA).filter(f => filesB.has(f)).length;
|
|
89
|
+
const unionSize = new Set([...Array.from(filesA), ...Array.from(filesB)]).size;
|
|
90
|
+
const similarity = unionSize > 0 ? overlap / unionSize : 0;
|
|
91
|
+
if (similarity >= this.config.duplicateSimilarityThreshold) {
|
|
92
|
+
group.push(patternB.id);
|
|
93
|
+
groupNames.push(patternB.name);
|
|
94
|
+
totalOverlap += overlap;
|
|
95
|
+
totalLocations += patternB.locations.length;
|
|
96
|
+
processed.add(patternB.id);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (group.length > 1) {
|
|
100
|
+
processed.add(patternA.id);
|
|
101
|
+
const avgSimilarity = totalOverlap / (totalLocations - totalOverlap || 1);
|
|
102
|
+
duplicateGroups.push({
|
|
103
|
+
id: `dup-${crypto.randomBytes(4).toString('hex')}`,
|
|
104
|
+
patterns: group,
|
|
105
|
+
patternNames: groupNames,
|
|
106
|
+
similarity: Math.min(1, avgSimilarity),
|
|
107
|
+
reason: 'High location overlap detected',
|
|
108
|
+
recommendation: avgSimilarity > 0.9 ? 'merge' : 'review',
|
|
109
|
+
overlappingLocations: totalOverlap,
|
|
110
|
+
totalLocations,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return duplicateGroups;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Cross-validate patterns against call graph and constraints
|
|
118
|
+
*/
|
|
119
|
+
async crossValidate(patterns, _options) {
|
|
120
|
+
const issues = [];
|
|
121
|
+
let patternsMatchingCallGraph = 0;
|
|
122
|
+
let patternsNotInCallGraph = 0;
|
|
123
|
+
let constraintAlignmentScore = 1.0;
|
|
124
|
+
let testCoverageAlignmentScore = 1.0;
|
|
125
|
+
// For now, we do basic validation
|
|
126
|
+
// Full call graph / constraint integration would require loading those stores
|
|
127
|
+
for (const pattern of patterns) {
|
|
128
|
+
// Check for patterns with no locations (orphans)
|
|
129
|
+
if (pattern.locations.length === 0) {
|
|
130
|
+
issues.push({
|
|
131
|
+
type: 'orphan-pattern',
|
|
132
|
+
severity: 'warning',
|
|
133
|
+
patternId: pattern.id,
|
|
134
|
+
message: `Pattern "${pattern.name}" has no locations`,
|
|
135
|
+
});
|
|
136
|
+
patternsNotInCallGraph++;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
patternsMatchingCallGraph++;
|
|
140
|
+
}
|
|
141
|
+
// Check for high outlier ratio
|
|
142
|
+
const outlierRatio = pattern.outliers.length /
|
|
143
|
+
(pattern.locations.length + pattern.outliers.length || 1);
|
|
144
|
+
if (outlierRatio > this.config.maxOutlierRatio) {
|
|
145
|
+
issues.push({
|
|
146
|
+
type: 'inconsistent-data',
|
|
147
|
+
severity: 'warning',
|
|
148
|
+
patternId: pattern.id,
|
|
149
|
+
message: `Pattern "${pattern.name}" has high outlier ratio (${(outlierRatio * 100).toFixed(0)}%)`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// Check for low confidence patterns that are approved
|
|
153
|
+
if (pattern.status === 'approved' && pattern.confidence.score < 0.5) {
|
|
154
|
+
issues.push({
|
|
155
|
+
type: 'inconsistent-data',
|
|
156
|
+
severity: 'info',
|
|
157
|
+
patternId: pattern.id,
|
|
158
|
+
message: `Approved pattern "${pattern.name}" has low confidence (${(pattern.confidence.score * 100).toFixed(0)}%)`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Calculate alignment scores based on issues
|
|
163
|
+
const totalPatterns = patterns.length || 1;
|
|
164
|
+
const issueCount = issues.filter(i => i.severity !== 'info').length;
|
|
165
|
+
constraintAlignmentScore = Math.max(0, 1 - (issueCount / totalPatterns));
|
|
166
|
+
return {
|
|
167
|
+
patternsMatchingCallGraph,
|
|
168
|
+
patternsNotInCallGraph,
|
|
169
|
+
callGraphEntriesWithoutPatterns: 0, // Would need call graph data
|
|
170
|
+
constraintAlignment: constraintAlignmentScore,
|
|
171
|
+
testCoverageAlignment: testCoverageAlignmentScore,
|
|
172
|
+
issues,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Generate recommendations for each pattern
|
|
177
|
+
*/
|
|
178
|
+
generateRecommendations(patterns, crossValidation, duplicates) {
|
|
179
|
+
// Build lookup for duplicate groups
|
|
180
|
+
const duplicateMap = new Map();
|
|
181
|
+
for (const group of duplicates) {
|
|
182
|
+
for (const patternId of group.patterns) {
|
|
183
|
+
duplicateMap.set(patternId, group.id);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Build lookup for cross-validation issues
|
|
187
|
+
const issueMap = new Map();
|
|
188
|
+
for (const issue of crossValidation.issues) {
|
|
189
|
+
if (issue.patternId) {
|
|
190
|
+
const existing = issueMap.get(issue.patternId) || [];
|
|
191
|
+
existing.push(issue);
|
|
192
|
+
issueMap.set(issue.patternId, existing);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return patterns.map(pattern => {
|
|
196
|
+
const reasons = [];
|
|
197
|
+
let recommendation;
|
|
198
|
+
const confidence = pattern.confidence.score;
|
|
199
|
+
const locationCount = pattern.locations.length;
|
|
200
|
+
const outlierCount = pattern.outliers.length;
|
|
201
|
+
const outlierRatio = outlierCount / (locationCount + outlierCount || 1);
|
|
202
|
+
const issues = issueMap.get(pattern.id) || [];
|
|
203
|
+
const duplicateGroupId = duplicateMap.get(pattern.id);
|
|
204
|
+
// Determine recommendation
|
|
205
|
+
if (confidence >= this.config.autoApproveThreshold &&
|
|
206
|
+
outlierRatio <= this.config.maxOutlierRatio &&
|
|
207
|
+
locationCount >= this.config.minLocationsForEstablished &&
|
|
208
|
+
issues.filter(i => i.severity === 'error').length === 0) {
|
|
209
|
+
recommendation = 'auto-approve';
|
|
210
|
+
reasons.push(`High confidence (${(confidence * 100).toFixed(0)}%)`);
|
|
211
|
+
reasons.push(`${locationCount} consistent locations`);
|
|
212
|
+
if (outlierCount === 0) {
|
|
213
|
+
reasons.push('No outliers detected');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else if (confidence >= this.config.reviewThreshold) {
|
|
217
|
+
recommendation = 'review';
|
|
218
|
+
reasons.push(`Moderate confidence (${(confidence * 100).toFixed(0)}%)`);
|
|
219
|
+
if (outlierRatio > 0.2) {
|
|
220
|
+
reasons.push(`Outlier ratio: ${(outlierRatio * 100).toFixed(0)}%`);
|
|
221
|
+
}
|
|
222
|
+
if (locationCount < this.config.minLocationsForEstablished) {
|
|
223
|
+
reasons.push(`Only ${locationCount} locations (need ${this.config.minLocationsForEstablished}+)`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
recommendation = 'likely-false-positive';
|
|
228
|
+
reasons.push(`Low confidence (${(confidence * 100).toFixed(0)}%)`);
|
|
229
|
+
if (outlierRatio > this.config.maxOutlierRatio) {
|
|
230
|
+
reasons.push(`High outlier ratio (${(outlierRatio * 100).toFixed(0)}%)`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Add issue-based reasons
|
|
234
|
+
for (const issue of issues) {
|
|
235
|
+
if (issue.severity === 'error' || issue.severity === 'warning') {
|
|
236
|
+
reasons.push(issue.message);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Add duplicate warning
|
|
240
|
+
if (duplicateGroupId) {
|
|
241
|
+
reasons.push('Part of potential duplicate group');
|
|
242
|
+
if (recommendation === 'auto-approve') {
|
|
243
|
+
recommendation = 'review';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Build cross-validation status
|
|
247
|
+
const crossValidationStatus = {
|
|
248
|
+
inCallGraph: locationCount > 0,
|
|
249
|
+
matchesConstraints: issues.filter(i => i.type === 'constraint-mismatch').length === 0,
|
|
250
|
+
hasTestCoverage: true, // Would need test topology data
|
|
251
|
+
issues: issues.map(i => i.message),
|
|
252
|
+
};
|
|
253
|
+
return {
|
|
254
|
+
id: pattern.id,
|
|
255
|
+
name: pattern.name,
|
|
256
|
+
category: pattern.category,
|
|
257
|
+
confidence,
|
|
258
|
+
locationCount,
|
|
259
|
+
outlierCount,
|
|
260
|
+
recommendation,
|
|
261
|
+
reasons,
|
|
262
|
+
crossValidation: crossValidationStatus,
|
|
263
|
+
...(duplicateGroupId ? { duplicateGroupId } : {}),
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Calculate overall health score
|
|
269
|
+
*/
|
|
270
|
+
calculateHealthScore(patterns, crossValidation, duplicates) {
|
|
271
|
+
if (patterns.length === 0)
|
|
272
|
+
return 100;
|
|
273
|
+
// Average confidence
|
|
274
|
+
const avgConfidence = patterns.reduce((sum, p) => sum + p.confidence.score, 0) / patterns.length;
|
|
275
|
+
// Approval ratio
|
|
276
|
+
const approvedCount = patterns.filter(p => p.status === 'approved').length;
|
|
277
|
+
const approvalRatio = approvedCount / patterns.length;
|
|
278
|
+
// Compliance rate (locations vs outliers)
|
|
279
|
+
const totalLocations = patterns.reduce((sum, p) => sum + p.locations.length, 0);
|
|
280
|
+
const totalOutliers = patterns.reduce((sum, p) => sum + p.outliers.length, 0);
|
|
281
|
+
const complianceRate = totalLocations / (totalLocations + totalOutliers || 1);
|
|
282
|
+
// Cross-validation rate
|
|
283
|
+
const crossValidationRate = crossValidation.patternsMatchingCallGraph /
|
|
284
|
+
(crossValidation.patternsMatchingCallGraph + crossValidation.patternsNotInCallGraph || 1);
|
|
285
|
+
// Duplicate-free rate
|
|
286
|
+
const patternsInDuplicates = new Set(duplicates.flatMap(d => d.patterns)).size;
|
|
287
|
+
const duplicateFreeRate = 1 - (patternsInDuplicates / patterns.length);
|
|
288
|
+
// Calculate weighted score
|
|
289
|
+
const score = (avgConfidence * HEALTH_SCORE_WEIGHTS.avgConfidence +
|
|
290
|
+
approvalRatio * HEALTH_SCORE_WEIGHTS.approvalRatio +
|
|
291
|
+
complianceRate * HEALTH_SCORE_WEIGHTS.complianceRate +
|
|
292
|
+
crossValidationRate * HEALTH_SCORE_WEIGHTS.crossValidationRate +
|
|
293
|
+
duplicateFreeRate * HEALTH_SCORE_WEIGHTS.duplicateFreeRate) * 100;
|
|
294
|
+
return Math.round(Math.max(0, Math.min(100, score)));
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Build audit summary
|
|
298
|
+
*/
|
|
299
|
+
buildSummary(patternResults, duplicates, healthScore) {
|
|
300
|
+
const byCategory = {};
|
|
301
|
+
for (const result of patternResults) {
|
|
302
|
+
if (!byCategory[result.category]) {
|
|
303
|
+
byCategory[result.category] = {
|
|
304
|
+
total: 0,
|
|
305
|
+
autoApproveEligible: 0,
|
|
306
|
+
flaggedForReview: 0,
|
|
307
|
+
likelyFalsePositives: 0,
|
|
308
|
+
avgConfidence: 0,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
const cat = byCategory[result.category];
|
|
312
|
+
cat.total++;
|
|
313
|
+
cat.avgConfidence += result.confidence;
|
|
314
|
+
switch (result.recommendation) {
|
|
315
|
+
case 'auto-approve':
|
|
316
|
+
cat.autoApproveEligible++;
|
|
317
|
+
break;
|
|
318
|
+
case 'review':
|
|
319
|
+
cat.flaggedForReview++;
|
|
320
|
+
break;
|
|
321
|
+
case 'likely-false-positive':
|
|
322
|
+
cat.likelyFalsePositives++;
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Finalize averages
|
|
327
|
+
for (const cat of Object.values(byCategory)) {
|
|
328
|
+
if (cat.total > 0) {
|
|
329
|
+
cat.avgConfidence /= cat.total;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return {
|
|
333
|
+
totalPatterns: patternResults.length,
|
|
334
|
+
autoApproveEligible: patternResults.filter(p => p.recommendation === 'auto-approve').length,
|
|
335
|
+
flaggedForReview: patternResults.filter(p => p.recommendation === 'review').length,
|
|
336
|
+
likelyFalsePositives: patternResults.filter(p => p.recommendation === 'likely-false-positive').length,
|
|
337
|
+
duplicateCandidates: duplicates.length,
|
|
338
|
+
healthScore,
|
|
339
|
+
byCategory,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Generate a hash of the scan state for comparison
|
|
344
|
+
*/
|
|
345
|
+
generateScanHash(patterns) {
|
|
346
|
+
const data = patterns
|
|
347
|
+
.map(p => `${p.id}:${p.confidence.score}:${p.locations.length}:${p.outliers.length}`)
|
|
348
|
+
.sort()
|
|
349
|
+
.join('|');
|
|
350
|
+
return crypto.createHash('sha256').update(data).digest('hex').slice(0, 16);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=audit-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-engine.js","sourceRoot":"","sources":["../../src/audit/audit-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Store
|
|
3
|
+
*
|
|
4
|
+
* Persistence layer for audit results, snapshots, and degradation tracking.
|
|
5
|
+
*
|
|
6
|
+
* Storage structure:
|
|
7
|
+
* .drift/audit/
|
|
8
|
+
* ├── latest.json # Current audit state
|
|
9
|
+
* ├── snapshots/ # Historical audits
|
|
10
|
+
* │ └── YYYY-MM-DD.json
|
|
11
|
+
* └── degradation.json # Quality trends
|
|
12
|
+
*
|
|
13
|
+
* @module audit/audit-store
|
|
14
|
+
*/
|
|
15
|
+
import type { AuditResult, DegradationResult, DegradationTracking } from './types.js';
|
|
16
|
+
export interface AuditStoreConfig {
|
|
17
|
+
rootDir: string;
|
|
18
|
+
snapshotRetention?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class AuditStore {
|
|
21
|
+
private readonly config;
|
|
22
|
+
private readonly auditDir;
|
|
23
|
+
private readonly snapshotsDir;
|
|
24
|
+
constructor(config: AuditStoreConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Initialize the audit store directories
|
|
27
|
+
*/
|
|
28
|
+
initialize(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Save an audit result
|
|
31
|
+
*/
|
|
32
|
+
saveAudit(result: AuditResult): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Load the latest audit result
|
|
35
|
+
*/
|
|
36
|
+
loadLatest(): Promise<AuditResult | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Load audit from a specific date
|
|
39
|
+
*/
|
|
40
|
+
loadSnapshot(date: string): Promise<AuditResult | null>;
|
|
41
|
+
/**
|
|
42
|
+
* List available snapshots
|
|
43
|
+
*/
|
|
44
|
+
listSnapshots(): Promise<string[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Compare two audits and generate degradation result
|
|
47
|
+
*/
|
|
48
|
+
compareAudits(current: AuditResult, previous: AuditResult): DegradationResult;
|
|
49
|
+
/**
|
|
50
|
+
* Get degradation tracking data
|
|
51
|
+
*/
|
|
52
|
+
getDegradationTracking(): Promise<DegradationTracking | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Cleanup old snapshots beyond retention period
|
|
55
|
+
*/
|
|
56
|
+
cleanupSnapshots(keepCount?: number): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Update degradation tracking with new audit
|
|
59
|
+
*/
|
|
60
|
+
private updateDegradationTracking;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=audit-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-store.d.ts","sourceRoot":"","sources":["../../src/audit/audit-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EAIpB,MAAM,YAAY,CAAC;AA8BpB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,MAAM,EAAE,gBAAgB;IASpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAW/C;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAW7D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAaxC;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,GAAG,iBAAiB;IA+G7E;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAWnE;;OAEG;IACG,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzD;;OAEG;YACW,yBAAyB;CAmHxC"}
|