@grc-claw/continuous-trust-engine 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.
@@ -0,0 +1,145 @@
1
+ /**
2
+ * ContinuousTrustEngine - Real-time trust scoring for compliance posture
3
+ *
4
+ * Continuously evaluates compliance posture, evidence quality, agent behavior,
5
+ * and organizational trust signals to produce a dynamic trust score.
6
+ *
7
+ * This engine goes beyond static compliance checks by incorporating:
8
+ * - Real-time evidence freshness scoring
9
+ * - Agent behavioral trust signals
10
+ * - Control effectiveness metrics
11
+ * - Risk-adjusted trust calculations
12
+ * - Trust decay over time
13
+ * - Trust threshold alerts
14
+ */
15
+ export interface TrustSignal {
16
+ id: string;
17
+ type: 'evidence' | 'control' | 'agent' | 'risk' | 'behavior' | 'external';
18
+ name: string;
19
+ value: number;
20
+ weight: number;
21
+ timestamp: Date;
22
+ metadata: Record<string, unknown>;
23
+ }
24
+ export interface TrustScore {
25
+ overall: number;
26
+ breakdown: {
27
+ evidence: number;
28
+ control: number;
29
+ agent: number;
30
+ risk: number;
31
+ behavior: number;
32
+ external: number;
33
+ };
34
+ trend: 'improving' | 'stable' | 'declining';
35
+ trendDelta: number;
36
+ lastUpdated: Date;
37
+ nextUpdate: Date;
38
+ alerts: TrustAlert[];
39
+ }
40
+ export interface TrustAlert {
41
+ id: string;
42
+ severity: 'critical' | 'high' | 'medium' | 'low';
43
+ type: string;
44
+ message: string;
45
+ threshold: number;
46
+ currentValue: number;
47
+ timestamp: Date;
48
+ acknowledged: boolean;
49
+ }
50
+ export interface TrustThreshold {
51
+ metric: string;
52
+ critical: number;
53
+ high: number;
54
+ medium: number;
55
+ low: number;
56
+ }
57
+ export interface TrustHistoryEntry {
58
+ timestamp: Date;
59
+ score: TrustScore;
60
+ signals: TrustSignal[];
61
+ }
62
+ export declare class ContinuousTrustEngine {
63
+ private readonly options;
64
+ private signals;
65
+ private history;
66
+ private thresholds;
67
+ private alerts;
68
+ private updateInterval;
69
+ private listeners;
70
+ constructor(options?: {
71
+ updateIntervalMs?: number;
72
+ historyRetentionDays?: number;
73
+ maxAlerts?: number;
74
+ autoAcknowledgeAfterMs?: number;
75
+ });
76
+ /**
77
+ * Start continuous trust monitoring
78
+ */
79
+ start(): void;
80
+ /**
81
+ * Stop continuous trust monitoring
82
+ */
83
+ stop(): void;
84
+ /**
85
+ * Register a trust signal
86
+ */
87
+ registerSignal(signal: TrustSignal): void;
88
+ /**
89
+ * Update an existing trust signal
90
+ */
91
+ updateSignal(id: string, updates: Partial<TrustSignal>): void;
92
+ /**
93
+ * Remove a trust signal
94
+ */
95
+ removeSignal(id: string): void;
96
+ /**
97
+ * Get current trust score
98
+ */
99
+ getScore(): TrustScore;
100
+ /**
101
+ * Get trust history
102
+ */
103
+ getHistory(hours?: number): TrustHistoryEntry[];
104
+ /**
105
+ * Get active alerts
106
+ */
107
+ getAlerts(acknowledged?: boolean): TrustAlert[];
108
+ /**
109
+ * Acknowledge an alert
110
+ */
111
+ acknowledgeAlert(alertId: string): void;
112
+ /**
113
+ * Subscribe to trust score updates
114
+ */
115
+ subscribe(listener: (score: TrustScore) => void): () => void;
116
+ /**
117
+ * Set custom thresholds
118
+ */
119
+ setThresholds(thresholds: TrustThreshold[]): void;
120
+ /**
121
+ * Calculate trust score from all signals
122
+ */
123
+ private calculateScore;
124
+ /**
125
+ * Calculate score and notify listeners
126
+ */
127
+ private calculateAndNotify;
128
+ /**
129
+ * Evaluate thresholds and create alerts
130
+ */
131
+ private evaluateThresholds;
132
+ /**
133
+ * Get metric value from score
134
+ */
135
+ private getMetricValue;
136
+ /**
137
+ * Create a new alert
138
+ */
139
+ private createAlert;
140
+ /**
141
+ * Initialize default thresholds
142
+ */
143
+ private initializeDefaultThresholds;
144
+ }
145
+ //# 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,291 @@
1
+ "use strict";
2
+ /**
3
+ * ContinuousTrustEngine - Real-time trust scoring for compliance posture
4
+ *
5
+ * Continuously evaluates compliance posture, evidence quality, agent behavior,
6
+ * and organizational trust signals to produce a dynamic trust score.
7
+ *
8
+ * This engine goes beyond static compliance checks by incorporating:
9
+ * - Real-time evidence freshness scoring
10
+ * - Agent behavioral trust signals
11
+ * - Control effectiveness metrics
12
+ * - Risk-adjusted trust calculations
13
+ * - Trust decay over time
14
+ * - Trust threshold alerts
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ContinuousTrustEngine = void 0;
18
+ class ContinuousTrustEngine {
19
+ options;
20
+ signals = new Map();
21
+ history = [];
22
+ thresholds = [];
23
+ alerts = [];
24
+ updateInterval = null;
25
+ listeners = [];
26
+ constructor(options = {}) {
27
+ this.options = options;
28
+ this.options = {
29
+ updateIntervalMs: 60000, // 1 minute
30
+ historyRetentionDays: 90,
31
+ maxAlerts: 1000,
32
+ autoAcknowledgeAfterMs: 86400000, // 24 hours
33
+ ...options
34
+ };
35
+ this.initializeDefaultThresholds();
36
+ }
37
+ /**
38
+ * Start continuous trust monitoring
39
+ */
40
+ start() {
41
+ if (this.updateInterval) {
42
+ return; // Already running
43
+ }
44
+ this.updateInterval = setInterval(() => {
45
+ this.calculateAndNotify();
46
+ }, this.options.updateIntervalMs);
47
+ // Initial calculation
48
+ this.calculateAndNotify();
49
+ }
50
+ /**
51
+ * Stop continuous trust monitoring
52
+ */
53
+ stop() {
54
+ if (this.updateInterval) {
55
+ clearInterval(this.updateInterval);
56
+ this.updateInterval = null;
57
+ }
58
+ }
59
+ /**
60
+ * Register a trust signal
61
+ */
62
+ registerSignal(signal) {
63
+ this.signals.set(signal.id, signal);
64
+ this.evaluateThresholds();
65
+ }
66
+ /**
67
+ * Update an existing trust signal
68
+ */
69
+ updateSignal(id, updates) {
70
+ const existing = this.signals.get(id);
71
+ if (existing) {
72
+ this.signals.set(id, { ...existing, ...updates, timestamp: new Date() });
73
+ this.evaluateThresholds();
74
+ }
75
+ }
76
+ /**
77
+ * Remove a trust signal
78
+ */
79
+ removeSignal(id) {
80
+ this.signals.delete(id);
81
+ }
82
+ /**
83
+ * Get current trust score
84
+ */
85
+ getScore() {
86
+ return this.calculateScore();
87
+ }
88
+ /**
89
+ * Get trust history
90
+ */
91
+ getHistory(hours = 24) {
92
+ const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000);
93
+ return this.history.filter(entry => entry.timestamp >= cutoff);
94
+ }
95
+ /**
96
+ * Get active alerts
97
+ */
98
+ getAlerts(acknowledged = false) {
99
+ return this.alerts.filter(alert => alert.acknowledged === acknowledged);
100
+ }
101
+ /**
102
+ * Acknowledge an alert
103
+ */
104
+ acknowledgeAlert(alertId) {
105
+ const alert = this.alerts.find(a => a.id === alertId);
106
+ if (alert) {
107
+ alert.acknowledged = true;
108
+ }
109
+ }
110
+ /**
111
+ * Subscribe to trust score updates
112
+ */
113
+ subscribe(listener) {
114
+ this.listeners.push(listener);
115
+ return () => {
116
+ this.listeners = this.listeners.filter(l => l !== listener);
117
+ };
118
+ }
119
+ /**
120
+ * Set custom thresholds
121
+ */
122
+ setThresholds(thresholds) {
123
+ this.thresholds = thresholds;
124
+ }
125
+ /**
126
+ * Calculate trust score from all signals
127
+ */
128
+ calculateScore() {
129
+ const signalArray = Array.from(this.signals.values());
130
+ // Group signals by type
131
+ const byType = {
132
+ evidence: signalArray.filter(s => s.type === 'evidence'),
133
+ control: signalArray.filter(s => s.type === 'control'),
134
+ agent: signalArray.filter(s => s.type === 'agent'),
135
+ risk: signalArray.filter(s => s.type === 'risk'),
136
+ behavior: signalArray.filter(s => s.type === 'behavior'),
137
+ external: signalArray.filter(s => s.type === 'external')
138
+ };
139
+ // Calculate weighted average for each type
140
+ const calculateTypeScore = (signals) => {
141
+ if (signals.length === 0)
142
+ return 100; // Default to 100 if no signals
143
+ const totalWeight = signals.reduce((sum, s) => sum + s.weight, 0);
144
+ if (totalWeight === 0)
145
+ return 100;
146
+ return signals.reduce((sum, s) => sum + (s.value * s.weight), 0) / totalWeight;
147
+ };
148
+ const breakdown = {
149
+ evidence: calculateTypeScore(byType.evidence),
150
+ control: calculateTypeScore(byType.control),
151
+ agent: calculateTypeScore(byType.agent),
152
+ risk: calculateTypeScore(byType.risk),
153
+ behavior: calculateTypeScore(byType.behavior),
154
+ external: calculateTypeScore(byType.external)
155
+ };
156
+ // Overall score with weights
157
+ const weights = { evidence: 0.25, control: 0.25, agent: 0.15, risk: 0.15, behavior: 0.1, external: 0.1 };
158
+ const overall = (breakdown.evidence * weights.evidence +
159
+ breakdown.control * weights.control +
160
+ breakdown.agent * weights.agent +
161
+ breakdown.risk * weights.risk +
162
+ breakdown.behavior * weights.behavior +
163
+ breakdown.external * weights.external);
164
+ // Calculate trend
165
+ const previousScore = this.history.length > 0
166
+ ? this.history[this.history.length - 1].score.overall
167
+ : overall;
168
+ const trendDelta = overall - previousScore;
169
+ const trend = trendDelta > 2 ? 'improving' : trendDelta < -2 ? 'declining' : 'stable';
170
+ // Filter active alerts
171
+ const activeAlerts = this.alerts.filter(a => !a.acknowledged);
172
+ return {
173
+ overall: Math.round(overall * 100) / 100,
174
+ breakdown: {
175
+ evidence: Math.round(breakdown.evidence * 100) / 100,
176
+ control: Math.round(breakdown.control * 100) / 100,
177
+ agent: Math.round(breakdown.agent * 100) / 100,
178
+ risk: Math.round(breakdown.risk * 100) / 100,
179
+ behavior: Math.round(breakdown.behavior * 100) / 100,
180
+ external: Math.round(breakdown.external * 100) / 100
181
+ },
182
+ trend,
183
+ trendDelta: Math.round(trendDelta * 100) / 100,
184
+ lastUpdated: new Date(),
185
+ nextUpdate: new Date(Date.now() + this.options.updateIntervalMs),
186
+ alerts: activeAlerts
187
+ };
188
+ }
189
+ /**
190
+ * Calculate score and notify listeners
191
+ */
192
+ calculateAndNotify() {
193
+ const score = this.calculateScore();
194
+ // Store in history
195
+ this.history.push({
196
+ timestamp: new Date(),
197
+ score,
198
+ signals: Array.from(this.signals.values())
199
+ });
200
+ // Trim history
201
+ const cutoff = new Date(Date.now() - this.options.historyRetentionDays * 24 * 60 * 60 * 1000);
202
+ this.history = this.history.filter(entry => entry.timestamp >= cutoff);
203
+ // Notify listeners
204
+ this.listeners.forEach(listener => listener(score));
205
+ }
206
+ /**
207
+ * Evaluate thresholds and create alerts
208
+ */
209
+ evaluateThresholds() {
210
+ const score = this.calculateScore();
211
+ for (const threshold of this.thresholds) {
212
+ const value = this.getMetricValue(score, threshold.metric);
213
+ if (value === null)
214
+ continue;
215
+ let severity = null;
216
+ if (value <= threshold.critical) {
217
+ severity = 'critical';
218
+ }
219
+ else if (value <= threshold.high) {
220
+ severity = 'high';
221
+ }
222
+ else if (value <= threshold.medium) {
223
+ severity = 'medium';
224
+ }
225
+ else if (value <= threshold.low) {
226
+ severity = 'low';
227
+ }
228
+ if (severity) {
229
+ this.createAlert({
230
+ id: `threshold-${threshold.metric}-${Date.now()}`,
231
+ severity,
232
+ type: 'threshold',
233
+ message: `${threshold.metric} score (${value}) below ${severity} threshold`,
234
+ threshold: threshold[severity],
235
+ currentValue: value,
236
+ timestamp: new Date(),
237
+ acknowledged: false
238
+ });
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * Get metric value from score
244
+ */
245
+ getMetricValue(score, metric) {
246
+ switch (metric) {
247
+ case 'overall': return score.overall;
248
+ case 'evidence': return score.breakdown.evidence;
249
+ case 'control': return score.breakdown.control;
250
+ case 'agent': return score.breakdown.agent;
251
+ case 'risk': return score.breakdown.risk;
252
+ case 'behavior': return score.breakdown.behavior;
253
+ case 'external': return score.breakdown.external;
254
+ default: return null;
255
+ }
256
+ }
257
+ /**
258
+ * Create a new alert
259
+ */
260
+ createAlert(alert) {
261
+ this.alerts.push(alert);
262
+ // Trim alerts
263
+ if (this.alerts.length > this.options.maxAlerts) {
264
+ this.alerts = this.alerts.slice(-this.options.maxAlerts);
265
+ }
266
+ // Auto-acknowledge old alerts
267
+ if (this.options.autoAcknowledgeAfterMs) {
268
+ const cutoff = new Date(Date.now() - this.options.autoAcknowledgeAfterMs);
269
+ this.alerts.forEach(a => {
270
+ if (a.timestamp < cutoff && !a.acknowledged) {
271
+ a.acknowledged = true;
272
+ }
273
+ });
274
+ }
275
+ }
276
+ /**
277
+ * Initialize default thresholds
278
+ */
279
+ initializeDefaultThresholds() {
280
+ this.thresholds = [
281
+ { metric: 'overall', critical: 30, high: 50, medium: 70, low: 85 },
282
+ { metric: 'evidence', critical: 20, high: 40, medium: 60, low: 80 },
283
+ { metric: 'control', critical: 25, high: 45, medium: 65, low: 85 },
284
+ { metric: 'agent', critical: 30, high: 50, medium: 70, low: 85 },
285
+ { metric: 'risk', critical: 20, high: 40, medium: 60, low: 80 }
286
+ ];
287
+ }
288
+ }
289
+ exports.ContinuousTrustEngine = ContinuousTrustEngine;
290
+ // trigger publish
291
+ //# 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/continuous-trust-engine",
3
+ "version": "0.8.0",
4
+ "description": "Real-time trust scoring for compliance posture",
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,377 @@
1
+ /**
2
+ * ContinuousTrustEngine - Real-time trust scoring for compliance posture
3
+ *
4
+ * Continuously evaluates compliance posture, evidence quality, agent behavior,
5
+ * and organizational trust signals to produce a dynamic trust score.
6
+ *
7
+ * This engine goes beyond static compliance checks by incorporating:
8
+ * - Real-time evidence freshness scoring
9
+ * - Agent behavioral trust signals
10
+ * - Control effectiveness metrics
11
+ * - Risk-adjusted trust calculations
12
+ * - Trust decay over time
13
+ * - Trust threshold alerts
14
+ */
15
+
16
+ export interface TrustSignal {
17
+ id: string;
18
+ type: 'evidence' | 'control' | 'agent' | 'risk' | 'behavior' | 'external';
19
+ name: string;
20
+ value: number; // 0-100
21
+ weight: number; // 0-1
22
+ timestamp: Date;
23
+ metadata: Record<string, unknown>;
24
+ }
25
+
26
+ export interface TrustScore {
27
+ overall: number; // 0-100
28
+ breakdown: {
29
+ evidence: number;
30
+ control: number;
31
+ agent: number;
32
+ risk: number;
33
+ behavior: number;
34
+ external: number;
35
+ };
36
+ trend: 'improving' | 'stable' | 'declining';
37
+ trendDelta: number; // change from previous period
38
+ lastUpdated: Date;
39
+ nextUpdate: Date;
40
+ alerts: TrustAlert[];
41
+ }
42
+
43
+ export interface TrustAlert {
44
+ id: string;
45
+ severity: 'critical' | 'high' | 'medium' | 'low';
46
+ type: string;
47
+ message: string;
48
+ threshold: number;
49
+ currentValue: number;
50
+ timestamp: Date;
51
+ acknowledged: boolean;
52
+ }
53
+
54
+ export interface TrustThreshold {
55
+ metric: string;
56
+ critical: number;
57
+ high: number;
58
+ medium: number;
59
+ low: number;
60
+ }
61
+
62
+ export interface TrustHistoryEntry {
63
+ timestamp: Date;
64
+ score: TrustScore;
65
+ signals: TrustSignal[];
66
+ }
67
+
68
+ export class ContinuousTrustEngine {
69
+ private signals: Map<string, TrustSignal> = new Map();
70
+ private history: TrustHistoryEntry[] = [];
71
+ private thresholds: TrustThreshold[] = [];
72
+ private alerts: TrustAlert[] = [];
73
+ private updateInterval: NodeJS.Timeout | null = null;
74
+ private listeners: ((score: TrustScore) => void)[] = [];
75
+
76
+ constructor(
77
+ private readonly options: {
78
+ updateIntervalMs?: number;
79
+ historyRetentionDays?: number;
80
+ maxAlerts?: number;
81
+ autoAcknowledgeAfterMs?: number;
82
+ } = {}
83
+ ) {
84
+ this.options = {
85
+ updateIntervalMs: 60000, // 1 minute
86
+ historyRetentionDays: 90,
87
+ maxAlerts: 1000,
88
+ autoAcknowledgeAfterMs: 86400000, // 24 hours
89
+ ...options
90
+ };
91
+
92
+ this.initializeDefaultThresholds();
93
+ }
94
+
95
+ /**
96
+ * Start continuous trust monitoring
97
+ */
98
+ start(): void {
99
+ if (this.updateInterval) {
100
+ return; // Already running
101
+ }
102
+
103
+ this.updateInterval = setInterval(() => {
104
+ this.calculateAndNotify();
105
+ }, this.options.updateIntervalMs);
106
+
107
+ // Initial calculation
108
+ this.calculateAndNotify();
109
+ }
110
+
111
+ /**
112
+ * Stop continuous trust monitoring
113
+ */
114
+ stop(): void {
115
+ if (this.updateInterval) {
116
+ clearInterval(this.updateInterval);
117
+ this.updateInterval = null;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Register a trust signal
123
+ */
124
+ registerSignal(signal: TrustSignal): void {
125
+ this.signals.set(signal.id, signal);
126
+ this.evaluateThresholds();
127
+ }
128
+
129
+ /**
130
+ * Update an existing trust signal
131
+ */
132
+ updateSignal(id: string, updates: Partial<TrustSignal>): void {
133
+ const existing = this.signals.get(id);
134
+ if (existing) {
135
+ this.signals.set(id, { ...existing, ...updates, timestamp: new Date() });
136
+ this.evaluateThresholds();
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Remove a trust signal
142
+ */
143
+ removeSignal(id: string): void {
144
+ this.signals.delete(id);
145
+ }
146
+
147
+ /**
148
+ * Get current trust score
149
+ */
150
+ getScore(): TrustScore {
151
+ return this.calculateScore();
152
+ }
153
+
154
+ /**
155
+ * Get trust history
156
+ */
157
+ getHistory(hours: number = 24): TrustHistoryEntry[] {
158
+ const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000);
159
+ return this.history.filter(entry => entry.timestamp >= cutoff);
160
+ }
161
+
162
+ /**
163
+ * Get active alerts
164
+ */
165
+ getAlerts(acknowledged: boolean = false): TrustAlert[] {
166
+ return this.alerts.filter(alert => alert.acknowledged === acknowledged);
167
+ }
168
+
169
+ /**
170
+ * Acknowledge an alert
171
+ */
172
+ acknowledgeAlert(alertId: string): void {
173
+ const alert = this.alerts.find(a => a.id === alertId);
174
+ if (alert) {
175
+ alert.acknowledged = true;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Subscribe to trust score updates
181
+ */
182
+ subscribe(listener: (score: TrustScore) => void): () => void {
183
+ this.listeners.push(listener);
184
+ return () => {
185
+ this.listeners = this.listeners.filter(l => l !== listener);
186
+ };
187
+ }
188
+
189
+ /**
190
+ * Set custom thresholds
191
+ */
192
+ setThresholds(thresholds: TrustThreshold[]): void {
193
+ this.thresholds = thresholds;
194
+ }
195
+
196
+ /**
197
+ * Calculate trust score from all signals
198
+ */
199
+ private calculateScore(): TrustScore {
200
+ const signalArray = Array.from(this.signals.values());
201
+
202
+ // Group signals by type
203
+ const byType = {
204
+ evidence: signalArray.filter(s => s.type === 'evidence'),
205
+ control: signalArray.filter(s => s.type === 'control'),
206
+ agent: signalArray.filter(s => s.type === 'agent'),
207
+ risk: signalArray.filter(s => s.type === 'risk'),
208
+ behavior: signalArray.filter(s => s.type === 'behavior'),
209
+ external: signalArray.filter(s => s.type === 'external')
210
+ };
211
+
212
+ // Calculate weighted average for each type
213
+ const calculateTypeScore = (signals: TrustSignal[]): number => {
214
+ if (signals.length === 0) return 100; // Default to 100 if no signals
215
+ const totalWeight = signals.reduce((sum, s) => sum + s.weight, 0);
216
+ if (totalWeight === 0) return 100;
217
+ return signals.reduce((sum, s) => sum + (s.value * s.weight), 0) / totalWeight;
218
+ };
219
+
220
+ const breakdown = {
221
+ evidence: calculateTypeScore(byType.evidence),
222
+ control: calculateTypeScore(byType.control),
223
+ agent: calculateTypeScore(byType.agent),
224
+ risk: calculateTypeScore(byType.risk),
225
+ behavior: calculateTypeScore(byType.behavior),
226
+ external: calculateTypeScore(byType.external)
227
+ };
228
+
229
+ // Overall score with weights
230
+ const weights = { evidence: 0.25, control: 0.25, agent: 0.15, risk: 0.15, behavior: 0.1, external: 0.1 };
231
+ const overall = (
232
+ breakdown.evidence * weights.evidence +
233
+ breakdown.control * weights.control +
234
+ breakdown.agent * weights.agent +
235
+ breakdown.risk * weights.risk +
236
+ breakdown.behavior * weights.behavior +
237
+ breakdown.external * weights.external
238
+ );
239
+
240
+ // Calculate trend
241
+ const previousScore = this.history.length > 0
242
+ ? this.history[this.history.length - 1].score.overall
243
+ : overall;
244
+ const trendDelta = overall - previousScore;
245
+ const trend = trendDelta > 2 ? 'improving' : trendDelta < -2 ? 'declining' : 'stable';
246
+
247
+ // Filter active alerts
248
+ const activeAlerts = this.alerts.filter(a => !a.acknowledged);
249
+
250
+ return {
251
+ overall: Math.round(overall * 100) / 100,
252
+ breakdown: {
253
+ evidence: Math.round(breakdown.evidence * 100) / 100,
254
+ control: Math.round(breakdown.control * 100) / 100,
255
+ agent: Math.round(breakdown.agent * 100) / 100,
256
+ risk: Math.round(breakdown.risk * 100) / 100,
257
+ behavior: Math.round(breakdown.behavior * 100) / 100,
258
+ external: Math.round(breakdown.external * 100) / 100
259
+ },
260
+ trend,
261
+ trendDelta: Math.round(trendDelta * 100) / 100,
262
+ lastUpdated: new Date(),
263
+ nextUpdate: new Date(Date.now() + this.options.updateIntervalMs!),
264
+ alerts: activeAlerts
265
+ };
266
+ }
267
+
268
+ /**
269
+ * Calculate score and notify listeners
270
+ */
271
+ private calculateAndNotify(): void {
272
+ const score = this.calculateScore();
273
+
274
+ // Store in history
275
+ this.history.push({
276
+ timestamp: new Date(),
277
+ score,
278
+ signals: Array.from(this.signals.values())
279
+ });
280
+
281
+ // Trim history
282
+ const cutoff = new Date(Date.now() - this.options.historyRetentionDays! * 24 * 60 * 60 * 1000);
283
+ this.history = this.history.filter(entry => entry.timestamp >= cutoff);
284
+
285
+ // Notify listeners
286
+ this.listeners.forEach(listener => listener(score));
287
+ }
288
+
289
+ /**
290
+ * Evaluate thresholds and create alerts
291
+ */
292
+ private evaluateThresholds(): void {
293
+ const score = this.calculateScore();
294
+
295
+ for (const threshold of this.thresholds) {
296
+ const value = this.getMetricValue(score, threshold.metric);
297
+ if (value === null) continue;
298
+
299
+ let severity: TrustAlert['severity'] | null = null;
300
+
301
+ if (value <= threshold.critical) {
302
+ severity = 'critical';
303
+ } else if (value <= threshold.high) {
304
+ severity = 'high';
305
+ } else if (value <= threshold.medium) {
306
+ severity = 'medium';
307
+ } else if (value <= threshold.low) {
308
+ severity = 'low';
309
+ }
310
+
311
+ if (severity) {
312
+ this.createAlert({
313
+ id: `threshold-${threshold.metric}-${Date.now()}`,
314
+ severity,
315
+ type: 'threshold',
316
+ message: `${threshold.metric} score (${value}) below ${severity} threshold`,
317
+ threshold: threshold[severity],
318
+ currentValue: value,
319
+ timestamp: new Date(),
320
+ acknowledged: false
321
+ });
322
+ }
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Get metric value from score
328
+ */
329
+ private getMetricValue(score: TrustScore, metric: string): number | null {
330
+ switch (metric) {
331
+ case 'overall': return score.overall;
332
+ case 'evidence': return score.breakdown.evidence;
333
+ case 'control': return score.breakdown.control;
334
+ case 'agent': return score.breakdown.agent;
335
+ case 'risk': return score.breakdown.risk;
336
+ case 'behavior': return score.breakdown.behavior;
337
+ case 'external': return score.breakdown.external;
338
+ default: return null;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Create a new alert
344
+ */
345
+ private createAlert(alert: TrustAlert): void {
346
+ this.alerts.push(alert);
347
+
348
+ // Trim alerts
349
+ if (this.alerts.length > this.options.maxAlerts!) {
350
+ this.alerts = this.alerts.slice(-this.options.maxAlerts!);
351
+ }
352
+
353
+ // Auto-acknowledge old alerts
354
+ if (this.options.autoAcknowledgeAfterMs) {
355
+ const cutoff = new Date(Date.now() - this.options.autoAcknowledgeAfterMs);
356
+ this.alerts.forEach(a => {
357
+ if (a.timestamp < cutoff && !a.acknowledged) {
358
+ a.acknowledged = true;
359
+ }
360
+ });
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Initialize default thresholds
366
+ */
367
+ private initializeDefaultThresholds(): void {
368
+ this.thresholds = [
369
+ { metric: 'overall', critical: 30, high: 50, medium: 70, low: 85 },
370
+ { metric: 'evidence', critical: 20, high: 40, medium: 60, low: 80 },
371
+ { metric: 'control', critical: 25, high: 45, medium: 65, low: 85 },
372
+ { metric: 'agent', critical: 30, high: 50, medium: 70, low: 85 },
373
+ { metric: 'risk', critical: 20, high: 40, medium: 60, low: 80 }
374
+ ];
375
+ }
376
+ }
377
+ // trigger publish
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "composite": true
7
+ },
8
+ "include": ["src/**/*"]
9
+ }