@grc-claw/ai-governance 0.8.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/dist/index.d.ts +204 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +270 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -0
- package/src/index.ts +457 -0
- package/tsconfig.json +9 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGovernance - EU AI Act compliance and AI risk management
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive AI governance capabilities including:
|
|
5
|
+
* - AI system registration and inventory
|
|
6
|
+
* - Risk classification per EU AI Act
|
|
7
|
+
* - Model risk scoring
|
|
8
|
+
* - Bias detection and monitoring
|
|
9
|
+
* - Transparency and explainability tracking
|
|
10
|
+
* - Regulatory compliance mapping
|
|
11
|
+
*/
|
|
12
|
+
export interface AISystem {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
owner: string;
|
|
17
|
+
department: string;
|
|
18
|
+
useCase: string;
|
|
19
|
+
riskClass: 'unacceptable' | 'high' | 'limited' | 'minimal';
|
|
20
|
+
status: 'registered' | 'assessed' | 'approved' | 'deployed' | 'retired';
|
|
21
|
+
registrationDate: Date;
|
|
22
|
+
lastAssessment?: Date;
|
|
23
|
+
nextAssessment?: Date;
|
|
24
|
+
models: AIModel[];
|
|
25
|
+
documentation: AIDocumentation;
|
|
26
|
+
}
|
|
27
|
+
export interface AIModel {
|
|
28
|
+
id: string;
|
|
29
|
+
name: string;
|
|
30
|
+
type: 'llm' | 'ml' | 'dl' | 'rule_based' | 'hybrid';
|
|
31
|
+
version: string;
|
|
32
|
+
provider: string;
|
|
33
|
+
trainingData?: TrainingData;
|
|
34
|
+
performanceMetrics: ModelMetrics;
|
|
35
|
+
biasMetrics?: BiasMetrics;
|
|
36
|
+
explainabilityScore?: number;
|
|
37
|
+
lastUpdated: Date;
|
|
38
|
+
}
|
|
39
|
+
export interface TrainingData {
|
|
40
|
+
source: string;
|
|
41
|
+
size: string;
|
|
42
|
+
dateRange: {
|
|
43
|
+
start: Date;
|
|
44
|
+
end: Date;
|
|
45
|
+
};
|
|
46
|
+
demographics: Record<string, number>;
|
|
47
|
+
consentObtained: boolean;
|
|
48
|
+
dataProcessingAgreement: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface ModelMetrics {
|
|
51
|
+
accuracy: number;
|
|
52
|
+
precision: number;
|
|
53
|
+
recall: number;
|
|
54
|
+
f1Score: number;
|
|
55
|
+
latencyMs: number;
|
|
56
|
+
throughput: number;
|
|
57
|
+
lastEvaluated: Date;
|
|
58
|
+
}
|
|
59
|
+
export interface BiasMetrics {
|
|
60
|
+
demographicParity: number;
|
|
61
|
+
equalizedOdds: number;
|
|
62
|
+
calibration: number;
|
|
63
|
+
individualFairness: number;
|
|
64
|
+
lastEvaluated: Date;
|
|
65
|
+
protectedAttributes: string[];
|
|
66
|
+
}
|
|
67
|
+
export interface AIDocumentation {
|
|
68
|
+
purposeStatement: string;
|
|
69
|
+
intendedUse: string;
|
|
70
|
+
limitations: string[];
|
|
71
|
+
risksAndMitigations: RiskItem[];
|
|
72
|
+
monitoringPlan: string;
|
|
73
|
+
humanOversight: string;
|
|
74
|
+
dataGovernance: string;
|
|
75
|
+
technicalDocumentation: string;
|
|
76
|
+
}
|
|
77
|
+
export interface RiskItem {
|
|
78
|
+
id: string;
|
|
79
|
+
description: string;
|
|
80
|
+
likelihood: 'high' | 'medium' | 'low';
|
|
81
|
+
impact: 'high' | 'medium' | 'low';
|
|
82
|
+
mitigation: string;
|
|
83
|
+
status: 'open' | 'mitigated' | 'accepted';
|
|
84
|
+
}
|
|
85
|
+
export interface ComplianceAssessment {
|
|
86
|
+
id: string;
|
|
87
|
+
systemId: string;
|
|
88
|
+
assessmentDate: Date;
|
|
89
|
+
assessor: string;
|
|
90
|
+
overallScore: number;
|
|
91
|
+
requirements: RequirementAssessment[];
|
|
92
|
+
findings: AssessmentFinding[];
|
|
93
|
+
recommendations: string[];
|
|
94
|
+
nextAssessmentDate: Date;
|
|
95
|
+
}
|
|
96
|
+
export interface RequirementAssessment {
|
|
97
|
+
requirementId: string;
|
|
98
|
+
description: string;
|
|
99
|
+
status: 'compliant' | 'partially_compliant' | 'non_compliant' | 'not_applicable';
|
|
100
|
+
evidence: string[];
|
|
101
|
+
notes?: string;
|
|
102
|
+
}
|
|
103
|
+
export interface AssessmentFinding {
|
|
104
|
+
id: string;
|
|
105
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
106
|
+
category: string;
|
|
107
|
+
description: string;
|
|
108
|
+
recommendation: string;
|
|
109
|
+
status: 'open' | 'in_remediation' | 'closed';
|
|
110
|
+
}
|
|
111
|
+
export interface AIUsageLog {
|
|
112
|
+
id: string;
|
|
113
|
+
systemId: string;
|
|
114
|
+
modelId: string;
|
|
115
|
+
timestamp: Date;
|
|
116
|
+
input: string;
|
|
117
|
+
output: string;
|
|
118
|
+
decision?: string;
|
|
119
|
+
humanReview: boolean;
|
|
120
|
+
outcome: 'approved' | 'rejected' | 'flagged' | 'pending';
|
|
121
|
+
}
|
|
122
|
+
export declare class AIGovernance {
|
|
123
|
+
private readonly options;
|
|
124
|
+
private systems;
|
|
125
|
+
private assessments;
|
|
126
|
+
private usageLogs;
|
|
127
|
+
constructor(options?: {
|
|
128
|
+
maxSystems?: number;
|
|
129
|
+
assessmentFrequencyDays?: number;
|
|
130
|
+
autoClassify?: boolean;
|
|
131
|
+
});
|
|
132
|
+
/**
|
|
133
|
+
* Register an AI system
|
|
134
|
+
*/
|
|
135
|
+
registerSystem(system: AISystem): void;
|
|
136
|
+
/**
|
|
137
|
+
* Update an AI system
|
|
138
|
+
*/
|
|
139
|
+
updateSystem(id: string, updates: Partial<AISystem>): void;
|
|
140
|
+
/**
|
|
141
|
+
* Get an AI system
|
|
142
|
+
*/
|
|
143
|
+
getSystem(id: string): AISystem | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* Get all AI systems
|
|
146
|
+
*/
|
|
147
|
+
getSystems(filters?: {
|
|
148
|
+
riskClass?: string;
|
|
149
|
+
status?: string;
|
|
150
|
+
department?: string;
|
|
151
|
+
}): AISystem[];
|
|
152
|
+
/**
|
|
153
|
+
* Assess compliance for a system
|
|
154
|
+
*/
|
|
155
|
+
assessCompliance(systemId: string, assessor: string, requirements: RequirementAssessment[]): ComplianceAssessment;
|
|
156
|
+
/**
|
|
157
|
+
* Get assessments for a system
|
|
158
|
+
*/
|
|
159
|
+
getAssessments(systemId: string): ComplianceAssessment[];
|
|
160
|
+
/**
|
|
161
|
+
* Log AI usage
|
|
162
|
+
*/
|
|
163
|
+
logUsage(log: AIUsageLog): void;
|
|
164
|
+
/**
|
|
165
|
+
* Get usage logs for a system
|
|
166
|
+
*/
|
|
167
|
+
getUsageLogs(systemId: string, filters?: {
|
|
168
|
+
fromDate?: Date;
|
|
169
|
+
toDate?: Date;
|
|
170
|
+
outcome?: string;
|
|
171
|
+
}): AIUsageLog[];
|
|
172
|
+
/**
|
|
173
|
+
* Get AI governance dashboard data
|
|
174
|
+
*/
|
|
175
|
+
getDashboardData(): {
|
|
176
|
+
totalSystems: number;
|
|
177
|
+
byRiskClass: Record<string, number>;
|
|
178
|
+
byStatus: Record<string, number>;
|
|
179
|
+
complianceStats: {
|
|
180
|
+
assessed: number;
|
|
181
|
+
compliant: number;
|
|
182
|
+
needsRemediation: number;
|
|
183
|
+
};
|
|
184
|
+
recentAssessments: ComplianceAssessment[];
|
|
185
|
+
upcomingAssessments: {
|
|
186
|
+
systemId: string;
|
|
187
|
+
systemName: string;
|
|
188
|
+
date: Date;
|
|
189
|
+
}[];
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Classify risk level for an AI system
|
|
193
|
+
*/
|
|
194
|
+
private classifyRisk;
|
|
195
|
+
/**
|
|
196
|
+
* Generate findings from requirements
|
|
197
|
+
*/
|
|
198
|
+
private generateFindings;
|
|
199
|
+
/**
|
|
200
|
+
* Generate recommendations
|
|
201
|
+
*/
|
|
202
|
+
private generateRecommendations;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AIGovernance - EU AI Act compliance and AI risk management
|
|
4
|
+
*
|
|
5
|
+
* Provides comprehensive AI governance capabilities including:
|
|
6
|
+
* - AI system registration and inventory
|
|
7
|
+
* - Risk classification per EU AI Act
|
|
8
|
+
* - Model risk scoring
|
|
9
|
+
* - Bias detection and monitoring
|
|
10
|
+
* - Transparency and explainability tracking
|
|
11
|
+
* - Regulatory compliance mapping
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.AIGovernance = void 0;
|
|
15
|
+
class AIGovernance {
|
|
16
|
+
options;
|
|
17
|
+
systems = new Map();
|
|
18
|
+
assessments = new Map();
|
|
19
|
+
usageLogs = new Map();
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.options = options;
|
|
22
|
+
this.options = {
|
|
23
|
+
maxSystems: 1000,
|
|
24
|
+
assessmentFrequencyDays: 90,
|
|
25
|
+
autoClassify: true,
|
|
26
|
+
...options
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Register an AI system
|
|
31
|
+
*/
|
|
32
|
+
registerSystem(system) {
|
|
33
|
+
if (this.systems.size >= this.options.maxSystems) {
|
|
34
|
+
throw new Error('Maximum system limit reached');
|
|
35
|
+
}
|
|
36
|
+
// Auto-classify if enabled
|
|
37
|
+
if (this.options.autoClassify && !system.riskClass) {
|
|
38
|
+
system.riskClass = this.classifyRisk(system);
|
|
39
|
+
}
|
|
40
|
+
system.status = 'registered';
|
|
41
|
+
system.registrationDate = new Date();
|
|
42
|
+
this.systems.set(system.id, system);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Update an AI system
|
|
46
|
+
*/
|
|
47
|
+
updateSystem(id, updates) {
|
|
48
|
+
const system = this.systems.get(id);
|
|
49
|
+
if (system) {
|
|
50
|
+
this.systems.set(id, { ...system, ...updates });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get an AI system
|
|
55
|
+
*/
|
|
56
|
+
getSystem(id) {
|
|
57
|
+
return this.systems.get(id);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get all AI systems
|
|
61
|
+
*/
|
|
62
|
+
getSystems(filters) {
|
|
63
|
+
let systems = Array.from(this.systems.values());
|
|
64
|
+
if (filters) {
|
|
65
|
+
if (filters.riskClass) {
|
|
66
|
+
systems = systems.filter(s => s.riskClass === filters.riskClass);
|
|
67
|
+
}
|
|
68
|
+
if (filters.status) {
|
|
69
|
+
systems = systems.filter(s => s.status === filters.status);
|
|
70
|
+
}
|
|
71
|
+
if (filters.department) {
|
|
72
|
+
systems = systems.filter(s => s.department === filters.department);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return systems;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Assess compliance for a system
|
|
79
|
+
*/
|
|
80
|
+
assessCompliance(systemId, assessor, requirements) {
|
|
81
|
+
const system = this.systems.get(systemId);
|
|
82
|
+
if (!system) {
|
|
83
|
+
throw new Error(`System ${systemId} not found`);
|
|
84
|
+
}
|
|
85
|
+
const compliantCount = requirements.filter(r => r.status === 'compliant').length;
|
|
86
|
+
const partialCount = requirements.filter(r => r.status === 'partially_compliant').length;
|
|
87
|
+
const overallScore = ((compliantCount + partialCount * 0.5) / requirements.length) * 100;
|
|
88
|
+
const assessment = {
|
|
89
|
+
id: `assessment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
90
|
+
systemId,
|
|
91
|
+
assessmentDate: new Date(),
|
|
92
|
+
assessor,
|
|
93
|
+
overallScore,
|
|
94
|
+
requirements,
|
|
95
|
+
findings: this.generateFindings(requirements),
|
|
96
|
+
recommendations: this.generateRecommendations(requirements),
|
|
97
|
+
nextAssessmentDate: new Date(Date.now() + this.options.assessmentFrequencyDays * 24 * 60 * 60 * 1000)
|
|
98
|
+
};
|
|
99
|
+
// Store assessment
|
|
100
|
+
const assessments = this.assessments.get(systemId) || [];
|
|
101
|
+
assessments.push(assessment);
|
|
102
|
+
this.assessments.set(systemId, assessments);
|
|
103
|
+
// Update system
|
|
104
|
+
system.lastAssessment = new Date();
|
|
105
|
+
system.nextAssessment = assessment.nextAssessmentDate;
|
|
106
|
+
system.status = overallScore >= 80 ? 'approved' : 'assessed';
|
|
107
|
+
return assessment;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get assessments for a system
|
|
111
|
+
*/
|
|
112
|
+
getAssessments(systemId) {
|
|
113
|
+
return this.assessments.get(systemId) || [];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Log AI usage
|
|
117
|
+
*/
|
|
118
|
+
logUsage(log) {
|
|
119
|
+
const logs = this.usageLogs.get(log.systemId) || [];
|
|
120
|
+
logs.push(log);
|
|
121
|
+
this.usageLogs.set(log.systemId, logs);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get usage logs for a system
|
|
125
|
+
*/
|
|
126
|
+
getUsageLogs(systemId, filters) {
|
|
127
|
+
let logs = this.usageLogs.get(systemId) || [];
|
|
128
|
+
if (filters) {
|
|
129
|
+
if (filters.fromDate) {
|
|
130
|
+
logs = logs.filter(l => l.timestamp >= filters.fromDate);
|
|
131
|
+
}
|
|
132
|
+
if (filters.toDate) {
|
|
133
|
+
logs = logs.filter(l => l.timestamp <= filters.toDate);
|
|
134
|
+
}
|
|
135
|
+
if (filters.outcome) {
|
|
136
|
+
logs = logs.filter(l => l.outcome === filters.outcome);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return logs;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get AI governance dashboard data
|
|
143
|
+
*/
|
|
144
|
+
getDashboardData() {
|
|
145
|
+
const systems = Array.from(this.systems.values());
|
|
146
|
+
// Count by risk class
|
|
147
|
+
const byRiskClass = {};
|
|
148
|
+
systems.forEach(s => {
|
|
149
|
+
byRiskClass[s.riskClass] = (byRiskClass[s.riskClass] || 0) + 1;
|
|
150
|
+
});
|
|
151
|
+
// Count by status
|
|
152
|
+
const byStatus = {};
|
|
153
|
+
systems.forEach(s => {
|
|
154
|
+
byStatus[s.status] = (byStatus[s.status] || 0) + 1;
|
|
155
|
+
});
|
|
156
|
+
// Compliance stats
|
|
157
|
+
const assessedSystems = systems.filter(s => s.lastAssessment);
|
|
158
|
+
const compliantSystems = assessedSystems.filter(s => {
|
|
159
|
+
const assessments = this.assessments.get(s.id) || [];
|
|
160
|
+
const latest = assessments[assessments.length - 1];
|
|
161
|
+
return latest && latest.overallScore >= 80;
|
|
162
|
+
});
|
|
163
|
+
// Recent assessments
|
|
164
|
+
const allAssessments = Array.from(this.assessments.values()).flat();
|
|
165
|
+
const recentAssessments = allAssessments
|
|
166
|
+
.sort((a, b) => b.assessmentDate.getTime() - a.assessmentDate.getTime())
|
|
167
|
+
.slice(0, 10);
|
|
168
|
+
// Upcoming assessments
|
|
169
|
+
const upcomingAssessments = systems
|
|
170
|
+
.filter(s => s.nextAssessment)
|
|
171
|
+
.map(s => ({
|
|
172
|
+
systemId: s.id,
|
|
173
|
+
systemName: s.name,
|
|
174
|
+
date: s.nextAssessment
|
|
175
|
+
}))
|
|
176
|
+
.sort((a, b) => a.date.getTime() - b.date.getTime())
|
|
177
|
+
.slice(0, 10);
|
|
178
|
+
return {
|
|
179
|
+
totalSystems: systems.length,
|
|
180
|
+
byRiskClass,
|
|
181
|
+
byStatus,
|
|
182
|
+
complianceStats: {
|
|
183
|
+
assessed: assessedSystems.length,
|
|
184
|
+
compliant: compliantSystems.length,
|
|
185
|
+
needsRemediation: assessedSystems.length - compliantSystems.length
|
|
186
|
+
},
|
|
187
|
+
recentAssessments,
|
|
188
|
+
upcomingAssessments
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Classify risk level for an AI system
|
|
193
|
+
*/
|
|
194
|
+
classifyRisk(system) {
|
|
195
|
+
// EU AI Act risk classification logic
|
|
196
|
+
const highRiskUseCases = [
|
|
197
|
+
'credit_scoring',
|
|
198
|
+
'hiring',
|
|
199
|
+
'law_enforcement',
|
|
200
|
+
'migration',
|
|
201
|
+
'justice',
|
|
202
|
+
'democracy',
|
|
203
|
+
'safety',
|
|
204
|
+
'critical_infrastructure'
|
|
205
|
+
];
|
|
206
|
+
const limitedRiskUseCases = [
|
|
207
|
+
'chatbot',
|
|
208
|
+
'emotion_recognition',
|
|
209
|
+
'biometric',
|
|
210
|
+
'deepfake'
|
|
211
|
+
];
|
|
212
|
+
const useCaseLower = system.useCase.toLowerCase();
|
|
213
|
+
if (highRiskUseCases.some(uc => useCaseLower.includes(uc))) {
|
|
214
|
+
return 'high';
|
|
215
|
+
}
|
|
216
|
+
if (limitedRiskUseCases.some(uc => useCaseLower.includes(uc))) {
|
|
217
|
+
return 'limited';
|
|
218
|
+
}
|
|
219
|
+
return 'minimal';
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Generate findings from requirements
|
|
223
|
+
*/
|
|
224
|
+
generateFindings(requirements) {
|
|
225
|
+
const findings = [];
|
|
226
|
+
requirements.forEach(req => {
|
|
227
|
+
if (req.status === 'non_compliant') {
|
|
228
|
+
findings.push({
|
|
229
|
+
id: `finding-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
230
|
+
severity: 'high',
|
|
231
|
+
category: 'compliance',
|
|
232
|
+
description: `Non-compliant with requirement: ${req.description}`,
|
|
233
|
+
recommendation: `Address gap for requirement ${req.requirementId}`,
|
|
234
|
+
status: 'open'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else if (req.status === 'partially_compliant') {
|
|
238
|
+
findings.push({
|
|
239
|
+
id: `finding-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
240
|
+
severity: 'medium',
|
|
241
|
+
category: 'compliance',
|
|
242
|
+
description: `Partially compliant with requirement: ${req.description}`,
|
|
243
|
+
recommendation: `Complete implementation for requirement ${req.requirementId}`,
|
|
244
|
+
status: 'open'
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
return findings;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Generate recommendations
|
|
252
|
+
*/
|
|
253
|
+
generateRecommendations(requirements) {
|
|
254
|
+
const recommendations = [];
|
|
255
|
+
const nonCompliant = requirements.filter(r => r.status === 'non_compliant');
|
|
256
|
+
const partial = requirements.filter(r => r.status === 'partially_compliant');
|
|
257
|
+
if (nonCompliant.length > 0) {
|
|
258
|
+
recommendations.push(`Address ${nonCompliant.length} non-compliant requirements immediately`);
|
|
259
|
+
}
|
|
260
|
+
if (partial.length > 0) {
|
|
261
|
+
recommendations.push(`Complete implementation for ${partial.length} partially compliant requirements`);
|
|
262
|
+
}
|
|
263
|
+
if (requirements.length > 0) {
|
|
264
|
+
recommendations.push('Schedule follow-up assessment within 90 days');
|
|
265
|
+
}
|
|
266
|
+
return recommendations;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.AIGovernance = AIGovernance;
|
|
270
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@grc-claw/ai-governance",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "EU AI Act compliance and AI risk management",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "node --test dist/**/*.test.js"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"typescript": "^5.7.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AIGovernance - EU AI Act compliance and AI risk management
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive AI governance capabilities including:
|
|
5
|
+
* - AI system registration and inventory
|
|
6
|
+
* - Risk classification per EU AI Act
|
|
7
|
+
* - Model risk scoring
|
|
8
|
+
* - Bias detection and monitoring
|
|
9
|
+
* - Transparency and explainability tracking
|
|
10
|
+
* - Regulatory compliance mapping
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface AISystem {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
owner: string;
|
|
18
|
+
department: string;
|
|
19
|
+
useCase: string;
|
|
20
|
+
riskClass: 'unacceptable' | 'high' | 'limited' | 'minimal';
|
|
21
|
+
status: 'registered' | 'assessed' | 'approved' | 'deployed' | 'retired';
|
|
22
|
+
registrationDate: Date;
|
|
23
|
+
lastAssessment?: Date;
|
|
24
|
+
nextAssessment?: Date;
|
|
25
|
+
models: AIModel[];
|
|
26
|
+
documentation: AIDocumentation;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface AIModel {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
type: 'llm' | 'ml' | 'dl' | 'rule_based' | 'hybrid';
|
|
33
|
+
version: string;
|
|
34
|
+
provider: string;
|
|
35
|
+
trainingData?: TrainingData;
|
|
36
|
+
performanceMetrics: ModelMetrics;
|
|
37
|
+
biasMetrics?: BiasMetrics;
|
|
38
|
+
explainabilityScore?: number; // 0-100
|
|
39
|
+
lastUpdated: Date;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface TrainingData {
|
|
43
|
+
source: string;
|
|
44
|
+
size: string;
|
|
45
|
+
dateRange: { start: Date; end: Date };
|
|
46
|
+
demographics: Record<string, number>;
|
|
47
|
+
consentObtained: boolean;
|
|
48
|
+
dataProcessingAgreement: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface ModelMetrics {
|
|
52
|
+
accuracy: number;
|
|
53
|
+
precision: number;
|
|
54
|
+
recall: number;
|
|
55
|
+
f1Score: number;
|
|
56
|
+
latencyMs: number;
|
|
57
|
+
throughput: number;
|
|
58
|
+
lastEvaluated: Date;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface BiasMetrics {
|
|
62
|
+
demographicParity: number;
|
|
63
|
+
equalizedOdds: number;
|
|
64
|
+
calibration: number;
|
|
65
|
+
individualFairness: number;
|
|
66
|
+
lastEvaluated: Date;
|
|
67
|
+
protectedAttributes: string[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface AIDocumentation {
|
|
71
|
+
purposeStatement: string;
|
|
72
|
+
intendedUse: string;
|
|
73
|
+
limitations: string[];
|
|
74
|
+
risksAndMitigations: RiskItem[];
|
|
75
|
+
monitoringPlan: string;
|
|
76
|
+
humanOversight: string;
|
|
77
|
+
dataGovernance: string;
|
|
78
|
+
technicalDocumentation: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface RiskItem {
|
|
82
|
+
id: string;
|
|
83
|
+
description: string;
|
|
84
|
+
likelihood: 'high' | 'medium' | 'low';
|
|
85
|
+
impact: 'high' | 'medium' | 'low';
|
|
86
|
+
mitigation: string;
|
|
87
|
+
status: 'open' | 'mitigated' | 'accepted';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface ComplianceAssessment {
|
|
91
|
+
id: string;
|
|
92
|
+
systemId: string;
|
|
93
|
+
assessmentDate: Date;
|
|
94
|
+
assessor: string;
|
|
95
|
+
overallScore: number; // 0-100
|
|
96
|
+
requirements: RequirementAssessment[];
|
|
97
|
+
findings: AssessmentFinding[];
|
|
98
|
+
recommendations: string[];
|
|
99
|
+
nextAssessmentDate: Date;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface RequirementAssessment {
|
|
103
|
+
requirementId: string;
|
|
104
|
+
description: string;
|
|
105
|
+
status: 'compliant' | 'partially_compliant' | 'non_compliant' | 'not_applicable';
|
|
106
|
+
evidence: string[];
|
|
107
|
+
notes?: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface AssessmentFinding {
|
|
111
|
+
id: string;
|
|
112
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
113
|
+
category: string;
|
|
114
|
+
description: string;
|
|
115
|
+
recommendation: string;
|
|
116
|
+
status: 'open' | 'in_remediation' | 'closed';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface AIUsageLog {
|
|
120
|
+
id: string;
|
|
121
|
+
systemId: string;
|
|
122
|
+
modelId: string;
|
|
123
|
+
timestamp: Date;
|
|
124
|
+
input: string;
|
|
125
|
+
output: string;
|
|
126
|
+
decision?: string;
|
|
127
|
+
humanReview: boolean;
|
|
128
|
+
outcome: 'approved' | 'rejected' | 'flagged' | 'pending';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export class AIGovernance {
|
|
132
|
+
private systems: Map<string, AISystem> = new Map();
|
|
133
|
+
private assessments: Map<string, ComplianceAssessment[]> = new Map();
|
|
134
|
+
private usageLogs: Map<string, AIUsageLog[]> = new Map();
|
|
135
|
+
|
|
136
|
+
constructor(
|
|
137
|
+
private readonly options: {
|
|
138
|
+
maxSystems?: number;
|
|
139
|
+
assessmentFrequencyDays?: number;
|
|
140
|
+
autoClassify?: boolean;
|
|
141
|
+
} = {}
|
|
142
|
+
) {
|
|
143
|
+
this.options = {
|
|
144
|
+
maxSystems: 1000,
|
|
145
|
+
assessmentFrequencyDays: 90,
|
|
146
|
+
autoClassify: true,
|
|
147
|
+
...options
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Register an AI system
|
|
153
|
+
*/
|
|
154
|
+
registerSystem(system: AISystem): void {
|
|
155
|
+
if (this.systems.size >= this.options.maxSystems!) {
|
|
156
|
+
throw new Error('Maximum system limit reached');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Auto-classify if enabled
|
|
160
|
+
if (this.options.autoClassify && !system.riskClass) {
|
|
161
|
+
system.riskClass = this.classifyRisk(system);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
system.status = 'registered';
|
|
165
|
+
system.registrationDate = new Date();
|
|
166
|
+
this.systems.set(system.id, system);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Update an AI system
|
|
171
|
+
*/
|
|
172
|
+
updateSystem(id: string, updates: Partial<AISystem>): void {
|
|
173
|
+
const system = this.systems.get(id);
|
|
174
|
+
if (system) {
|
|
175
|
+
this.systems.set(id, { ...system, ...updates });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get an AI system
|
|
181
|
+
*/
|
|
182
|
+
getSystem(id: string): AISystem | undefined {
|
|
183
|
+
return this.systems.get(id);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get all AI systems
|
|
188
|
+
*/
|
|
189
|
+
getSystems(filters?: {
|
|
190
|
+
riskClass?: string;
|
|
191
|
+
status?: string;
|
|
192
|
+
department?: string;
|
|
193
|
+
}): AISystem[] {
|
|
194
|
+
let systems = Array.from(this.systems.values());
|
|
195
|
+
|
|
196
|
+
if (filters) {
|
|
197
|
+
if (filters.riskClass) {
|
|
198
|
+
systems = systems.filter(s => s.riskClass === filters.riskClass);
|
|
199
|
+
}
|
|
200
|
+
if (filters.status) {
|
|
201
|
+
systems = systems.filter(s => s.status === filters.status);
|
|
202
|
+
}
|
|
203
|
+
if (filters.department) {
|
|
204
|
+
systems = systems.filter(s => s.department === filters.department);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return systems;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Assess compliance for a system
|
|
213
|
+
*/
|
|
214
|
+
assessCompliance(
|
|
215
|
+
systemId: string,
|
|
216
|
+
assessor: string,
|
|
217
|
+
requirements: RequirementAssessment[]
|
|
218
|
+
): ComplianceAssessment {
|
|
219
|
+
const system = this.systems.get(systemId);
|
|
220
|
+
if (!system) {
|
|
221
|
+
throw new Error(`System ${systemId} not found`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const compliantCount = requirements.filter(r => r.status === 'compliant').length;
|
|
225
|
+
const partialCount = requirements.filter(r => r.status === 'partially_compliant').length;
|
|
226
|
+
const overallScore = ((compliantCount + partialCount * 0.5) / requirements.length) * 100;
|
|
227
|
+
|
|
228
|
+
const assessment: ComplianceAssessment = {
|
|
229
|
+
id: `assessment-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
230
|
+
systemId,
|
|
231
|
+
assessmentDate: new Date(),
|
|
232
|
+
assessor,
|
|
233
|
+
overallScore,
|
|
234
|
+
requirements,
|
|
235
|
+
findings: this.generateFindings(requirements),
|
|
236
|
+
recommendations: this.generateRecommendations(requirements),
|
|
237
|
+
nextAssessmentDate: new Date(
|
|
238
|
+
Date.now() + this.options.assessmentFrequencyDays! * 24 * 60 * 60 * 1000
|
|
239
|
+
)
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// Store assessment
|
|
243
|
+
const assessments = this.assessments.get(systemId) || [];
|
|
244
|
+
assessments.push(assessment);
|
|
245
|
+
this.assessments.set(systemId, assessments);
|
|
246
|
+
|
|
247
|
+
// Update system
|
|
248
|
+
system.lastAssessment = new Date();
|
|
249
|
+
system.nextAssessment = assessment.nextAssessmentDate;
|
|
250
|
+
system.status = overallScore >= 80 ? 'approved' : 'assessed';
|
|
251
|
+
|
|
252
|
+
return assessment;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Get assessments for a system
|
|
257
|
+
*/
|
|
258
|
+
getAssessments(systemId: string): ComplianceAssessment[] {
|
|
259
|
+
return this.assessments.get(systemId) || [];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Log AI usage
|
|
264
|
+
*/
|
|
265
|
+
logUsage(log: AIUsageLog): void {
|
|
266
|
+
const logs = this.usageLogs.get(log.systemId) || [];
|
|
267
|
+
logs.push(log);
|
|
268
|
+
this.usageLogs.set(log.systemId, logs);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Get usage logs for a system
|
|
273
|
+
*/
|
|
274
|
+
getUsageLogs(
|
|
275
|
+
systemId: string,
|
|
276
|
+
filters?: {
|
|
277
|
+
fromDate?: Date;
|
|
278
|
+
toDate?: Date;
|
|
279
|
+
outcome?: string;
|
|
280
|
+
}
|
|
281
|
+
): AIUsageLog[] {
|
|
282
|
+
let logs = this.usageLogs.get(systemId) || [];
|
|
283
|
+
|
|
284
|
+
if (filters) {
|
|
285
|
+
if (filters.fromDate) {
|
|
286
|
+
logs = logs.filter(l => l.timestamp >= filters.fromDate!);
|
|
287
|
+
}
|
|
288
|
+
if (filters.toDate) {
|
|
289
|
+
logs = logs.filter(l => l.timestamp <= filters.toDate!);
|
|
290
|
+
}
|
|
291
|
+
if (filters.outcome) {
|
|
292
|
+
logs = logs.filter(l => l.outcome === filters.outcome);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return logs;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Get AI governance dashboard data
|
|
301
|
+
*/
|
|
302
|
+
getDashboardData(): {
|
|
303
|
+
totalSystems: number;
|
|
304
|
+
byRiskClass: Record<string, number>;
|
|
305
|
+
byStatus: Record<string, number>;
|
|
306
|
+
complianceStats: {
|
|
307
|
+
assessed: number;
|
|
308
|
+
compliant: number;
|
|
309
|
+
needsRemediation: number;
|
|
310
|
+
};
|
|
311
|
+
recentAssessments: ComplianceAssessment[];
|
|
312
|
+
upcomingAssessments: { systemId: string; systemName: string; date: Date }[];
|
|
313
|
+
} {
|
|
314
|
+
const systems = Array.from(this.systems.values());
|
|
315
|
+
|
|
316
|
+
// Count by risk class
|
|
317
|
+
const byRiskClass: Record<string, number> = {};
|
|
318
|
+
systems.forEach(s => {
|
|
319
|
+
byRiskClass[s.riskClass] = (byRiskClass[s.riskClass] || 0) + 1;
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Count by status
|
|
323
|
+
const byStatus: Record<string, number> = {};
|
|
324
|
+
systems.forEach(s => {
|
|
325
|
+
byStatus[s.status] = (byStatus[s.status] || 0) + 1;
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Compliance stats
|
|
329
|
+
const assessedSystems = systems.filter(s => s.lastAssessment);
|
|
330
|
+
const compliantSystems = assessedSystems.filter(s => {
|
|
331
|
+
const assessments = this.assessments.get(s.id) || [];
|
|
332
|
+
const latest = assessments[assessments.length - 1];
|
|
333
|
+
return latest && latest.overallScore >= 80;
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// Recent assessments
|
|
337
|
+
const allAssessments = Array.from(this.assessments.values()).flat();
|
|
338
|
+
const recentAssessments = allAssessments
|
|
339
|
+
.sort((a, b) => b.assessmentDate.getTime() - a.assessmentDate.getTime())
|
|
340
|
+
.slice(0, 10);
|
|
341
|
+
|
|
342
|
+
// Upcoming assessments
|
|
343
|
+
const upcomingAssessments = systems
|
|
344
|
+
.filter(s => s.nextAssessment)
|
|
345
|
+
.map(s => ({
|
|
346
|
+
systemId: s.id,
|
|
347
|
+
systemName: s.name,
|
|
348
|
+
date: s.nextAssessment!
|
|
349
|
+
}))
|
|
350
|
+
.sort((a, b) => a.date.getTime() - b.date.getTime())
|
|
351
|
+
.slice(0, 10);
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
totalSystems: systems.length,
|
|
355
|
+
byRiskClass,
|
|
356
|
+
byStatus,
|
|
357
|
+
complianceStats: {
|
|
358
|
+
assessed: assessedSystems.length,
|
|
359
|
+
compliant: compliantSystems.length,
|
|
360
|
+
needsRemediation: assessedSystems.length - compliantSystems.length
|
|
361
|
+
},
|
|
362
|
+
recentAssessments,
|
|
363
|
+
upcomingAssessments
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Classify risk level for an AI system
|
|
369
|
+
*/
|
|
370
|
+
private classifyRisk(system: AISystem): AISystem['riskClass'] {
|
|
371
|
+
// EU AI Act risk classification logic
|
|
372
|
+
const highRiskUseCases = [
|
|
373
|
+
'credit_scoring',
|
|
374
|
+
'hiring',
|
|
375
|
+
'law_enforcement',
|
|
376
|
+
'migration',
|
|
377
|
+
'justice',
|
|
378
|
+
'democracy',
|
|
379
|
+
'safety',
|
|
380
|
+
'critical_infrastructure'
|
|
381
|
+
];
|
|
382
|
+
|
|
383
|
+
const limitedRiskUseCases = [
|
|
384
|
+
'chatbot',
|
|
385
|
+
'emotion_recognition',
|
|
386
|
+
'biometric',
|
|
387
|
+
'deepfake'
|
|
388
|
+
];
|
|
389
|
+
|
|
390
|
+
const useCaseLower = system.useCase.toLowerCase();
|
|
391
|
+
|
|
392
|
+
if (highRiskUseCases.some(uc => useCaseLower.includes(uc))) {
|
|
393
|
+
return 'high';
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (limitedRiskUseCases.some(uc => useCaseLower.includes(uc))) {
|
|
397
|
+
return 'limited';
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
return 'minimal';
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Generate findings from requirements
|
|
405
|
+
*/
|
|
406
|
+
private generateFindings(requirements: RequirementAssessment[]): AssessmentFinding[] {
|
|
407
|
+
const findings: AssessmentFinding[] = [];
|
|
408
|
+
|
|
409
|
+
requirements.forEach(req => {
|
|
410
|
+
if (req.status === 'non_compliant') {
|
|
411
|
+
findings.push({
|
|
412
|
+
id: `finding-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
413
|
+
severity: 'high',
|
|
414
|
+
category: 'compliance',
|
|
415
|
+
description: `Non-compliant with requirement: ${req.description}`,
|
|
416
|
+
recommendation: `Address gap for requirement ${req.requirementId}`,
|
|
417
|
+
status: 'open'
|
|
418
|
+
});
|
|
419
|
+
} else if (req.status === 'partially_compliant') {
|
|
420
|
+
findings.push({
|
|
421
|
+
id: `finding-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
422
|
+
severity: 'medium',
|
|
423
|
+
category: 'compliance',
|
|
424
|
+
description: `Partially compliant with requirement: ${req.description}`,
|
|
425
|
+
recommendation: `Complete implementation for requirement ${req.requirementId}`,
|
|
426
|
+
status: 'open'
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
return findings;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Generate recommendations
|
|
436
|
+
*/
|
|
437
|
+
private generateRecommendations(requirements: RequirementAssessment[]): string[] {
|
|
438
|
+
const recommendations: string[] = [];
|
|
439
|
+
|
|
440
|
+
const nonCompliant = requirements.filter(r => r.status === 'non_compliant');
|
|
441
|
+
const partial = requirements.filter(r => r.status === 'partially_compliant');
|
|
442
|
+
|
|
443
|
+
if (nonCompliant.length > 0) {
|
|
444
|
+
recommendations.push(`Address ${nonCompliant.length} non-compliant requirements immediately`);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (partial.length > 0) {
|
|
448
|
+
recommendations.push(`Complete implementation for ${partial.length} partially compliant requirements`);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (requirements.length > 0) {
|
|
452
|
+
recommendations.push('Schedule follow-up assessment within 90 days');
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return recommendations;
|
|
456
|
+
}
|
|
457
|
+
}
|