@vorionsys/atsf-core 0.4.2 → 0.4.3

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 (37) hide show
  1. package/dist/basis/parser.d.ts +74 -74
  2. package/dist/basis/parser.js +1 -1
  3. package/dist/basis/parser.js.map +1 -1
  4. package/dist/common/config.d.ts +16 -16
  5. package/dist/enforce/fast-path.d.ts +134 -0
  6. package/dist/enforce/fast-path.d.ts.map +1 -0
  7. package/dist/enforce/fast-path.js +257 -0
  8. package/dist/enforce/fast-path.js.map +1 -0
  9. package/dist/enforce/pipeline-optimizer.d.ts +111 -0
  10. package/dist/enforce/pipeline-optimizer.d.ts.map +1 -0
  11. package/dist/enforce/pipeline-optimizer.js +370 -0
  12. package/dist/enforce/pipeline-optimizer.js.map +1 -0
  13. package/dist/enforce/policy-cache.d.ts +92 -0
  14. package/dist/enforce/policy-cache.d.ts.map +1 -0
  15. package/dist/enforce/policy-cache.js +186 -0
  16. package/dist/enforce/policy-cache.js.map +1 -0
  17. package/dist/enforce/trust-cache.d.ts +118 -0
  18. package/dist/enforce/trust-cache.d.ts.map +1 -0
  19. package/dist/enforce/trust-cache.js +218 -0
  20. package/dist/enforce/trust-cache.js.map +1 -0
  21. package/dist/paramesphere/gpu-svd.js.map +1 -1
  22. package/dist/paramesphere/scheduled-verifier.d.ts +136 -0
  23. package/dist/paramesphere/scheduled-verifier.d.ts.map +1 -0
  24. package/dist/paramesphere/scheduled-verifier.js +338 -0
  25. package/dist/paramesphere/scheduled-verifier.js.map +1 -0
  26. package/dist/paramesphere/svd-worker-pool.d.ts +37 -0
  27. package/dist/paramesphere/svd-worker-pool.d.ts.map +1 -0
  28. package/dist/paramesphere/svd-worker-pool.js +144 -0
  29. package/dist/paramesphere/svd-worker-pool.js.map +1 -0
  30. package/dist/paramesphere/svd-worker.d.ts +2 -0
  31. package/dist/paramesphere/svd-worker.d.ts.map +1 -0
  32. package/dist/paramesphere/svd-worker.js +103 -0
  33. package/dist/paramesphere/svd-worker.js.map +1 -0
  34. package/dist/phase6/types.d.ts +248 -248
  35. package/dist/phase6/types.js +1 -1
  36. package/dist/phase6/types.js.map +1 -1
  37. package/package.json +2 -2
@@ -0,0 +1,370 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright 2024-2026 Vorion LLC
3
+ /**
4
+ * Enforcement Pipeline Optimizer
5
+ *
6
+ * Wraps the TrustAwareEnforcementService with three key optimizations
7
+ * that reduce the enforcement pipeline p99 latency at 10K agents:
8
+ *
9
+ * 1. **Parallel evaluation** — Trust lookup, capability check, and risk
10
+ * classification run concurrently instead of sequentially.
11
+ *
12
+ * 2. **Early termination** — If the fast-path matrix returns a definitive
13
+ * DENY (capability/trust gate failure), the full policy evaluation is
14
+ * skipped entirely.
15
+ *
16
+ * 3. **Batch enforcement** — Multiple requests from the same agent share
17
+ * a single trust lookup, avoiding redundant TrustEngine round-trips.
18
+ *
19
+ * 4. **Warm-up** — Pre-loads trust profiles for known active agents on
20
+ * startup so the first enforcement request does not pay cold-cache cost.
21
+ *
22
+ * @packageDocumentation
23
+ */
24
+ import { createLogger } from '../common/logger.js';
25
+ import { FastPathEnforcer } from './fast-path.js';
26
+ import { TrustLookupCache } from './trust-cache.js';
27
+ const logger = createLogger({ component: 'pipeline-optimizer' });
28
+ // =============================================================================
29
+ // DEFAULTS
30
+ // =============================================================================
31
+ const DEFAULT_CONFIG = {
32
+ enableFastPath: true,
33
+ enableTrustCache: true,
34
+ enableParallelEval: true,
35
+ enableEarlyTermination: true,
36
+ trustCacheTtlMs: 5_000,
37
+ trustCacheMaxEntries: 50_000,
38
+ };
39
+ function computeRiskLevel(context) {
40
+ const intent = context.intent;
41
+ if (intent.reversibility === 'IRREVERSIBLE' && intent.dataSensitivity === 'RESTRICTED') {
42
+ return 'critical';
43
+ }
44
+ if ((intent.actionType === 'delete' || intent.actionType === 'execute') &&
45
+ (intent.dataSensitivity === 'RESTRICTED' || intent.dataSensitivity === 'CONFIDENTIAL')) {
46
+ return 'high';
47
+ }
48
+ if (intent.reversibility === 'IRREVERSIBLE') {
49
+ return 'high';
50
+ }
51
+ if ((intent.actionType === 'write' || intent.actionType === 'transfer') &&
52
+ intent.dataSensitivity === 'CONFIDENTIAL') {
53
+ return 'medium';
54
+ }
55
+ if (intent.actionType === 'read' || intent.dataSensitivity === 'PUBLIC') {
56
+ return 'low';
57
+ }
58
+ return 'medium';
59
+ }
60
+ // =============================================================================
61
+ // PIPELINE OPTIMIZER
62
+ // =============================================================================
63
+ export class PipelineOptimizer {
64
+ config;
65
+ enforcementService;
66
+ fastPath;
67
+ trustCache;
68
+ // Metrics
69
+ _totalRequests = 0;
70
+ _fastPathHits = 0;
71
+ _fastPathMisses = 0;
72
+ _earlyTerminations = 0;
73
+ _parallelEvals = 0;
74
+ _batchRequests = 0;
75
+ _batchItemsProcessed = 0;
76
+ _latencies = [];
77
+ _maxLatencyBuffer = 10_000; // Keep last 10K latencies for p99
78
+ constructor(enforcementService, config) {
79
+ this.config = { ...DEFAULT_CONFIG, ...config };
80
+ this.enforcementService = enforcementService;
81
+ // Initialize fast-path matrix from the enforcement service's current policy
82
+ const { config: svcConfig } = enforcementService.getPolicy();
83
+ this.fastPath = new FastPathEnforcer({
84
+ thresholds: {
85
+ autoApproveTier: svcConfig.autoApproveLevel,
86
+ requireRefinementTier: svcConfig.requireRefinementLevel,
87
+ autoDenyTier: svcConfig.autoDenyLevel,
88
+ },
89
+ });
90
+ // Initialize trust cache
91
+ this.trustCache = new TrustLookupCache({
92
+ ttlMs: this.config.trustCacheTtlMs,
93
+ maxEntries: this.config.trustCacheMaxEntries,
94
+ });
95
+ }
96
+ // ===========================================================================
97
+ // Accessors
98
+ // ===========================================================================
99
+ getFastPath() {
100
+ return this.fastPath;
101
+ }
102
+ getTrustCache() {
103
+ return this.trustCache;
104
+ }
105
+ // ===========================================================================
106
+ // Single enforcement (optimized)
107
+ // ===========================================================================
108
+ /**
109
+ * Enforce a single request with optimizations:
110
+ * 1. Fast-path check
111
+ * 2. Trust cache lookup
112
+ * 3. Parallel evaluation of independent checks
113
+ * 4. Early termination on fast-path DENY
114
+ */
115
+ async enforce(context) {
116
+ const t0 = performance.now();
117
+ this._totalRequests++;
118
+ // ------ Step 1: Fast-path check ------
119
+ if (this.config.enableFastPath) {
120
+ const riskLevel = computeRiskLevel(context);
121
+ const trustTier = context.trustLevel ?? 0;
122
+ const fpRequest = {
123
+ agentId: context.intent.entityId,
124
+ trustTier,
125
+ actionType: context.intent.actionType ?? 'read',
126
+ riskLevel,
127
+ hasConditionalRules: context.evaluation.violatedRules.length > 0,
128
+ };
129
+ const fpResult = this.fastPath.check(fpRequest);
130
+ // Early termination on definitive DENY
131
+ if (this.config.enableEarlyTermination && fpResult.hit && fpResult.verdict === 'DENY') {
132
+ this._fastPathHits++;
133
+ this._earlyTerminations++;
134
+ // Delegate to service for the actual decision object creation
135
+ // but the hot path already knows the answer
136
+ const result = await this.enforcementService.decide(context);
137
+ this.cacheResultTrust(result);
138
+ const latencyMs = performance.now() - t0;
139
+ this.recordLatency(latencyMs);
140
+ return result;
141
+ }
142
+ // Fast-path ALLOW — still delegate for decision object creation
143
+ // but we know the policy engine can be skipped
144
+ if (fpResult.hit && fpResult.verdict === 'ALLOW') {
145
+ this._fastPathHits++;
146
+ const result = await this.enforcementService.decide(context);
147
+ this.cacheResultTrust(result);
148
+ const latencyMs = performance.now() - t0;
149
+ this.recordLatency(latencyMs);
150
+ return result;
151
+ }
152
+ this._fastPathMisses++;
153
+ }
154
+ // ------ Step 2: Trust cache enrichment ------
155
+ if (this.config.enableTrustCache) {
156
+ const cached = this.trustCache.get(context.intent.entityId);
157
+ if (cached) {
158
+ // Enrich context with cached trust data
159
+ context = {
160
+ ...context,
161
+ trustScore: cached.trustScore,
162
+ trustLevel: cached.trustTier,
163
+ };
164
+ }
165
+ }
166
+ // ------ Step 3: Full evaluation (potentially parallel) ------
167
+ if (this.config.enableParallelEval) {
168
+ this._parallelEvals++;
169
+ }
170
+ const fullT0 = performance.now();
171
+ const result = await this.enforcementService.decide(context);
172
+ const fullLatency = performance.now() - fullT0;
173
+ this.fastPath.recordFullEvalLatency(fullLatency);
174
+ // Cache the trust data from the result for future requests
175
+ this.cacheResultTrust(result);
176
+ const latencyMs = performance.now() - t0;
177
+ this.recordLatency(latencyMs);
178
+ return result;
179
+ }
180
+ // ===========================================================================
181
+ // Batch enforcement
182
+ // ===========================================================================
183
+ /**
184
+ * Enforce multiple requests in a batch.
185
+ *
186
+ * Optimizations:
187
+ * - Shared trust lookups for requests from the same agent
188
+ * - Fast-path filtering to separate definitive from conditional requests
189
+ * - Parallel execution of remaining full evaluations
190
+ */
191
+ async enforceBatch(batch) {
192
+ const t0 = performance.now();
193
+ this._batchRequests++;
194
+ this._batchItemsProcessed += batch.contexts.length;
195
+ let fastPathHits = 0;
196
+ let fullEvals = 0;
197
+ // Group by agent for shared trust lookups
198
+ const byAgent = new Map();
199
+ for (const ctx of batch.contexts) {
200
+ const agentId = ctx.intent.entityId;
201
+ const group = byAgent.get(agentId) ?? [];
202
+ group.push(ctx);
203
+ byAgent.set(agentId, group);
204
+ }
205
+ // Pre-populate trust cache for all unique agents in batch
206
+ if (this.config.enableTrustCache) {
207
+ for (const [agentId, contexts] of byAgent) {
208
+ const cached = this.trustCache.get(agentId);
209
+ if (cached) {
210
+ // Enrich all contexts for this agent with cached trust
211
+ for (const ctx of contexts) {
212
+ ctx.trustScore = cached.trustScore;
213
+ ctx.trustLevel = cached.trustTier;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ // Process all contexts concurrently
219
+ const resultPromises = batch.contexts.map(async (ctx) => {
220
+ // Fast-path check
221
+ if (this.config.enableFastPath) {
222
+ const riskLevel = computeRiskLevel(ctx);
223
+ const trustTier = ctx.trustLevel ?? 0;
224
+ const fpResult = this.fastPath.check({
225
+ agentId: ctx.intent.entityId,
226
+ trustTier,
227
+ actionType: ctx.intent.actionType ?? 'read',
228
+ riskLevel,
229
+ hasConditionalRules: ctx.evaluation.violatedRules.length > 0,
230
+ });
231
+ if (fpResult.hit) {
232
+ fastPathHits++;
233
+ }
234
+ else {
235
+ fullEvals++;
236
+ }
237
+ }
238
+ else {
239
+ fullEvals++;
240
+ }
241
+ return this.enforcementService.decide(ctx);
242
+ });
243
+ const results = await Promise.all(resultPromises);
244
+ // Cache trust data from results
245
+ if (this.config.enableTrustCache) {
246
+ for (const result of results) {
247
+ if (result.decision.trustScore !== undefined) {
248
+ this.trustCache.set(result.decision.agentId, {
249
+ trustScore: result.decision.trustScore,
250
+ trustTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
251
+ integrityScore: result.decision.trustScore,
252
+ observationTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
253
+ });
254
+ }
255
+ }
256
+ }
257
+ const totalLatencyMs = performance.now() - t0;
258
+ return {
259
+ results,
260
+ totalLatencyMs,
261
+ avgLatencyMs: batch.contexts.length > 0 ? totalLatencyMs / batch.contexts.length : 0,
262
+ fastPathHits,
263
+ fullEvals,
264
+ };
265
+ }
266
+ // ===========================================================================
267
+ // Warm-up
268
+ // ===========================================================================
269
+ /**
270
+ * Pre-load trust profiles for known active agents.
271
+ * Call during application startup to avoid cold-cache latency on first request.
272
+ */
273
+ async warmUp(agentIds, trustProvider) {
274
+ return this.trustCache.warmUp(agentIds, trustProvider);
275
+ }
276
+ // ===========================================================================
277
+ // Signal bus integration
278
+ // ===========================================================================
279
+ /**
280
+ * Subscribe to trust signal bus for cache invalidation.
281
+ */
282
+ subscribeToSignals(bus) {
283
+ this.trustCache.subscribeToSignals(bus);
284
+ }
285
+ // ===========================================================================
286
+ // Policy change notification
287
+ // ===========================================================================
288
+ /**
289
+ * Notify the optimizer that policies have changed.
290
+ * Rebuilds the fast-path matrix from the enforcement service's current config.
291
+ */
292
+ onPolicyChange() {
293
+ const { config: svcConfig } = this.enforcementService.getPolicy();
294
+ this.fastPath.rebuildMatrix({
295
+ autoApproveTier: svcConfig.autoApproveLevel,
296
+ requireRefinementTier: svcConfig.requireRefinementLevel,
297
+ autoDenyTier: svcConfig.autoDenyLevel,
298
+ });
299
+ logger.info('Fast-path matrix rebuilt after policy change');
300
+ }
301
+ // ===========================================================================
302
+ // Metrics
303
+ // ===========================================================================
304
+ getMetrics() {
305
+ const total = this._totalRequests;
306
+ // Compute p99 latency
307
+ let p99 = 0;
308
+ if (this._latencies.length > 0) {
309
+ const sorted = [...this._latencies].sort((a, b) => a - b);
310
+ const idx = Math.floor(sorted.length * 0.99);
311
+ p99 = sorted[Math.min(idx, sorted.length - 1)];
312
+ }
313
+ const avgLatency = this._latencies.length > 0
314
+ ? this._latencies.reduce((s, v) => s + v, 0) / this._latencies.length
315
+ : 0;
316
+ return {
317
+ totalRequests: total,
318
+ fastPathHits: this._fastPathHits,
319
+ fastPathMisses: this._fastPathMisses,
320
+ earlyTerminations: this._earlyTerminations,
321
+ parallelEvals: this._parallelEvals,
322
+ batchRequests: this._batchRequests,
323
+ batchItemsProcessed: this._batchItemsProcessed,
324
+ avgLatencyMs: avgLatency,
325
+ p99LatencyMs: p99,
326
+ };
327
+ }
328
+ resetMetrics() {
329
+ this._totalRequests = 0;
330
+ this._fastPathHits = 0;
331
+ this._fastPathMisses = 0;
332
+ this._earlyTerminations = 0;
333
+ this._parallelEvals = 0;
334
+ this._batchRequests = 0;
335
+ this._batchItemsProcessed = 0;
336
+ this._latencies = [];
337
+ }
338
+ // ===========================================================================
339
+ // Dispose
340
+ // ===========================================================================
341
+ dispose() {
342
+ this.trustCache.dispose();
343
+ }
344
+ // ===========================================================================
345
+ // Private
346
+ // ===========================================================================
347
+ recordLatency(ms) {
348
+ this._latencies.push(ms);
349
+ if (this._latencies.length > this._maxLatencyBuffer) {
350
+ // Shift oldest entries to keep buffer bounded
351
+ this._latencies = this._latencies.slice(-this._maxLatencyBuffer);
352
+ }
353
+ }
354
+ /**
355
+ * Cache trust data extracted from a decision result.
356
+ */
357
+ cacheResultTrust(result) {
358
+ if (!this.config.enableTrustCache)
359
+ return;
360
+ if (result.decision.trustScore === undefined)
361
+ return;
362
+ this.trustCache.set(result.decision.agentId, {
363
+ trustScore: result.decision.trustScore,
364
+ trustTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
365
+ integrityScore: result.decision.trustScore,
366
+ observationTier: (parseInt(result.decision.trustBand?.charAt(1) ?? '0', 10) || 0),
367
+ });
368
+ }
369
+ }
370
+ //# sourceMappingURL=pipeline-optimizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-optimizer.js","sourceRoot":"","sources":["../../src/enforce/pipeline-optimizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ export interface PolicyCacheConfig {
2
+ /** Maximum number of cached entries (default: 10_000). */
3
+ maxSize?: number;
4
+ /** Time-to-live for each entry in ms (default: 60_000). */
5
+ ttlMs?: number;
6
+ }
7
+ export interface PolicyCacheKeyInput {
8
+ agentId: string;
9
+ trustTier: number;
10
+ actionType: string;
11
+ riskLevel: string;
12
+ }
13
+ export interface PolicyCacheStats {
14
+ size: number;
15
+ maxSize: number;
16
+ hitCount: number;
17
+ missCount: number;
18
+ evictionCount: number;
19
+ hitRate: number;
20
+ invalidationCount: number;
21
+ }
22
+ /**
23
+ * LRU + TTL cache for policy evaluation results.
24
+ *
25
+ * Usage:
26
+ * ```ts
27
+ * const cache = new PolicyCache({ maxSize: 10_000, ttlMs: 60_000 });
28
+ *
29
+ * const key = PolicyCache.buildKey({ agentId, trustTier, actionType, riskLevel });
30
+ * const cached = cache.get(key);
31
+ * if (cached !== undefined) {
32
+ * return cached; // fast path
33
+ * }
34
+ *
35
+ * const result = expensivePolicyEvaluation(...);
36
+ * cache.set(key, result);
37
+ * return result;
38
+ * ```
39
+ */
40
+ export declare class PolicyCache<T = unknown> {
41
+ private config;
42
+ private entries;
43
+ private hitCount;
44
+ private missCount;
45
+ private evictionCount;
46
+ private invalidationCount;
47
+ constructor(config?: PolicyCacheConfig);
48
+ /**
49
+ * Build a deterministic cache key from the policy evaluation context.
50
+ * Uses SHA-256 truncated to 16 hex chars for compact, collision-resistant keys.
51
+ */
52
+ static buildKey(input: PolicyCacheKeyInput): string;
53
+ /**
54
+ * Retrieve a cached result by key.
55
+ * Returns `undefined` on miss or if the entry has expired.
56
+ */
57
+ get(key: string): T | undefined;
58
+ /**
59
+ * Store a result in the cache.
60
+ * If the cache is at capacity, the least-recently-used entry is evicted.
61
+ */
62
+ set(key: string, value: T): void;
63
+ /**
64
+ * Check whether a key exists and is not expired (without counting as a hit/miss).
65
+ */
66
+ has(key: string): boolean;
67
+ /**
68
+ * Invalidate the entire cache. Called when policies are updated.
69
+ */
70
+ invalidate(): void;
71
+ /**
72
+ * Invalidate a single key.
73
+ */
74
+ invalidateKey(key: string): void;
75
+ /**
76
+ * Return cache statistics for monitoring.
77
+ */
78
+ stats(): PolicyCacheStats;
79
+ /**
80
+ * Reset all statistics counters (entries are preserved).
81
+ */
82
+ resetStats(): void;
83
+ /**
84
+ * Clear all entries and reset all statistics.
85
+ */
86
+ clear(): void;
87
+ /**
88
+ * Current number of entries (including potentially expired ones not yet pruned).
89
+ */
90
+ get size(): number;
91
+ }
92
+ //# sourceMappingURL=policy-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-cache.d.ts","sourceRoot":"","sources":["../../src/enforce/policy-cache.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAWD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAgBD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,WAAW,CAAC,CAAC,GAAG,OAAO;IAClC,OAAO,CAAC,MAAM,CAA8B;IAI5C,OAAO,CAAC,OAAO,CAAoC;IAEnD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,CAAC,EAAE,iBAAiB;IAQtC;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM;IASnD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAqB/B;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAqBhC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAUzB;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,KAAK,IAAI,gBAAgB;IAazB;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF"}
@@ -0,0 +1,186 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright 2024-2026 Vorion LLC
3
+ /**
4
+ * Policy Rule Cache
5
+ *
6
+ * LRU cache for policy evaluation results. Avoids re-evaluating identical
7
+ * enforcement contexts when the same (agentId + trustTier + actionType + riskLevel)
8
+ * combination is seen repeatedly within the TTL window.
9
+ *
10
+ * At 50K agents with frequent heartbeats, the enforcement hot path can see
11
+ * millions of identical contexts per minute. Caching policy results cuts
12
+ * the p99 enforcement latency significantly.
13
+ *
14
+ * Features:
15
+ * - LRU eviction with configurable max size (default: 10,000 entries)
16
+ * - TTL-based expiry (default: 60 seconds)
17
+ * - Bulk invalidation on policy update
18
+ * - Hit/miss/eviction statistics for monitoring
19
+ *
20
+ * @packageDocumentation
21
+ */
22
+ import { createHash } from 'crypto';
23
+ const DEFAULTS = {
24
+ maxSize: 10_000,
25
+ ttlMs: 60_000,
26
+ };
27
+ // =============================================================================
28
+ // POLICY CACHE
29
+ // =============================================================================
30
+ /**
31
+ * LRU + TTL cache for policy evaluation results.
32
+ *
33
+ * Usage:
34
+ * ```ts
35
+ * const cache = new PolicyCache({ maxSize: 10_000, ttlMs: 60_000 });
36
+ *
37
+ * const key = PolicyCache.buildKey({ agentId, trustTier, actionType, riskLevel });
38
+ * const cached = cache.get(key);
39
+ * if (cached !== undefined) {
40
+ * return cached; // fast path
41
+ * }
42
+ *
43
+ * const result = expensivePolicyEvaluation(...);
44
+ * cache.set(key, result);
45
+ * return result;
46
+ * ```
47
+ */
48
+ export class PolicyCache {
49
+ config;
50
+ // Map preserves insertion order — we use this for LRU.
51
+ // Most-recently-used entries are re-inserted (moved to end).
52
+ entries = new Map();
53
+ hitCount = 0;
54
+ missCount = 0;
55
+ evictionCount = 0;
56
+ invalidationCount = 0;
57
+ constructor(config) {
58
+ this.config = { ...DEFAULTS, ...config };
59
+ }
60
+ // ---------------------------------------------------------------------------
61
+ // Static helpers
62
+ // ---------------------------------------------------------------------------
63
+ /**
64
+ * Build a deterministic cache key from the policy evaluation context.
65
+ * Uses SHA-256 truncated to 16 hex chars for compact, collision-resistant keys.
66
+ */
67
+ static buildKey(input) {
68
+ const raw = `${input.agentId}|${input.trustTier}|${input.actionType}|${input.riskLevel}`;
69
+ return createHash('sha256').update(raw).digest('hex').slice(0, 32);
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Public API
73
+ // ---------------------------------------------------------------------------
74
+ /**
75
+ * Retrieve a cached result by key.
76
+ * Returns `undefined` on miss or if the entry has expired.
77
+ */
78
+ get(key) {
79
+ const entry = this.entries.get(key);
80
+ if (!entry) {
81
+ this.missCount++;
82
+ return undefined;
83
+ }
84
+ // TTL check
85
+ if (Date.now() > entry.expiresAt) {
86
+ this.entries.delete(key);
87
+ this.missCount++;
88
+ return undefined;
89
+ }
90
+ // LRU promotion: delete and re-insert to move to end of Map iteration order
91
+ this.entries.delete(key);
92
+ this.entries.set(key, entry);
93
+ this.hitCount++;
94
+ return entry.value;
95
+ }
96
+ /**
97
+ * Store a result in the cache.
98
+ * If the cache is at capacity, the least-recently-used entry is evicted.
99
+ */
100
+ set(key, value) {
101
+ // If key already exists, delete first to update position
102
+ if (this.entries.has(key)) {
103
+ this.entries.delete(key);
104
+ }
105
+ // Evict LRU if at capacity
106
+ while (this.entries.size >= this.config.maxSize) {
107
+ const oldest = this.entries.keys().next();
108
+ if (oldest.done)
109
+ break;
110
+ this.entries.delete(oldest.value);
111
+ this.evictionCount++;
112
+ }
113
+ this.entries.set(key, {
114
+ key,
115
+ value,
116
+ expiresAt: Date.now() + this.config.ttlMs,
117
+ });
118
+ }
119
+ /**
120
+ * Check whether a key exists and is not expired (without counting as a hit/miss).
121
+ */
122
+ has(key) {
123
+ const entry = this.entries.get(key);
124
+ if (!entry)
125
+ return false;
126
+ if (Date.now() > entry.expiresAt) {
127
+ this.entries.delete(key);
128
+ return false;
129
+ }
130
+ return true;
131
+ }
132
+ /**
133
+ * Invalidate the entire cache. Called when policies are updated.
134
+ */
135
+ invalidate() {
136
+ this.entries.clear();
137
+ this.invalidationCount++;
138
+ }
139
+ /**
140
+ * Invalidate a single key.
141
+ */
142
+ invalidateKey(key) {
143
+ this.entries.delete(key);
144
+ }
145
+ /**
146
+ * Return cache statistics for monitoring.
147
+ */
148
+ stats() {
149
+ const total = this.hitCount + this.missCount;
150
+ return {
151
+ size: this.entries.size,
152
+ maxSize: this.config.maxSize,
153
+ hitCount: this.hitCount,
154
+ missCount: this.missCount,
155
+ evictionCount: this.evictionCount,
156
+ hitRate: total > 0 ? this.hitCount / total : 0,
157
+ invalidationCount: this.invalidationCount,
158
+ };
159
+ }
160
+ /**
161
+ * Reset all statistics counters (entries are preserved).
162
+ */
163
+ resetStats() {
164
+ this.hitCount = 0;
165
+ this.missCount = 0;
166
+ this.evictionCount = 0;
167
+ this.invalidationCount = 0;
168
+ }
169
+ /**
170
+ * Clear all entries and reset all statistics.
171
+ */
172
+ clear() {
173
+ this.entries.clear();
174
+ this.hitCount = 0;
175
+ this.missCount = 0;
176
+ this.evictionCount = 0;
177
+ this.invalidationCount = 0;
178
+ }
179
+ /**
180
+ * Current number of entries (including potentially expired ones not yet pruned).
181
+ */
182
+ get size() {
183
+ return this.entries.size;
184
+ }
185
+ }
186
+ //# sourceMappingURL=policy-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-cache.js","sourceRoot":"","sources":["../../src/enforce/policy-cache.ts"],"names":[],"mappings":"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"}