@vorionsys/atsf-core 0.1.0 → 0.2.1
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/README.md +12 -12
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +463 -35
- package/dist/api/server.js.map +1 -1
- package/dist/arbitration/index.d.ts.map +1 -1
- package/dist/arbitration/index.js +8 -6
- package/dist/arbitration/index.js.map +1 -1
- package/dist/audit/key-manager.d.ts +118 -0
- package/dist/audit/key-manager.d.ts.map +1 -0
- package/dist/audit/key-manager.js +565 -0
- package/dist/audit/key-manager.js.map +1 -0
- package/dist/basis/evaluator.d.ts +31 -0
- package/dist/basis/evaluator.d.ts.map +1 -1
- package/dist/basis/evaluator.js +205 -10
- package/dist/basis/evaluator.js.map +1 -1
- package/dist/basis/parser.d.ts +210 -210
- package/dist/basis/parser.js.map +1 -1
- package/dist/carbon-aware/carbon-metrics.d.ts +151 -0
- package/dist/carbon-aware/carbon-metrics.d.ts.map +1 -0
- package/dist/carbon-aware/carbon-metrics.js +370 -0
- package/dist/carbon-aware/carbon-metrics.js.map +1 -0
- package/dist/carbon-aware/carbon-router.d.ts +101 -0
- package/dist/carbon-aware/carbon-router.d.ts.map +1 -0
- package/dist/carbon-aware/carbon-router.js +400 -0
- package/dist/carbon-aware/carbon-router.js.map +1 -0
- package/dist/chain/index.d.ts +147 -0
- package/dist/chain/index.d.ts.map +1 -0
- package/dist/chain/index.js +219 -0
- package/dist/chain/index.js.map +1 -0
- package/dist/cognigate/index.d.ts +33 -4
- package/dist/cognigate/index.d.ts.map +1 -1
- package/dist/cognigate/index.js +199 -24
- package/dist/cognigate/index.js.map +1 -1
- package/dist/common/adapters.d.ts +172 -0
- package/dist/common/adapters.d.ts.map +1 -0
- package/dist/common/adapters.js +329 -0
- package/dist/common/adapters.js.map +1 -0
- package/dist/common/config.d.ts +168 -163
- package/dist/common/config.d.ts.map +1 -1
- package/dist/common/config.js +2 -0
- package/dist/common/config.js.map +1 -1
- package/dist/common/index.d.ts +1 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +1 -0
- package/dist/common/index.js.map +1 -1
- package/dist/common/types.d.ts +67 -16
- package/dist/common/types.d.ts.map +1 -1
- package/dist/common/types.js +4 -0
- package/dist/common/types.js.map +1 -1
- package/dist/enforce/index.d.ts +226 -16
- package/dist/enforce/index.d.ts.map +1 -1
- package/dist/enforce/index.js +196 -49
- package/dist/enforce/index.js.map +1 -1
- package/dist/governance/fluid-workflow.d.ts +217 -0
- package/dist/governance/fluid-workflow.d.ts.map +1 -0
- package/dist/governance/fluid-workflow.js +491 -0
- package/dist/governance/fluid-workflow.js.map +1 -0
- package/dist/governance/index.d.ts +1 -0
- package/dist/governance/index.d.ts.map +1 -1
- package/dist/governance/index.js +1 -0
- package/dist/governance/index.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/intent/index.d.ts +127 -10
- package/dist/intent/index.d.ts.map +1 -1
- package/dist/intent/index.js +121 -16
- package/dist/intent/index.js.map +1 -1
- package/dist/langchain/executor.d.ts +19 -5
- package/dist/langchain/executor.d.ts.map +1 -1
- package/dist/langchain/executor.js +287 -36
- package/dist/langchain/executor.js.map +1 -1
- package/dist/langchain/index.d.ts +2 -1
- package/dist/langchain/index.d.ts.map +1 -1
- package/dist/langchain/index.js +3 -1
- package/dist/langchain/index.js.map +1 -1
- package/dist/langchain/tools.d.ts.map +1 -1
- package/dist/langchain/tools.js +2 -1
- package/dist/langchain/tools.js.map +1 -1
- package/dist/langchain/types.d.ts +41 -0
- package/dist/langchain/types.d.ts.map +1 -1
- package/dist/layers/index.d.ts +1 -1
- package/dist/layers/index.d.ts.map +1 -1
- package/dist/persistence/file.d.ts +35 -3
- package/dist/persistence/file.d.ts.map +1 -1
- package/dist/persistence/file.js +138 -11
- package/dist/persistence/file.js.map +1 -1
- package/dist/persistence/index.d.ts +11 -1
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +25 -1
- package/dist/persistence/index.js.map +1 -1
- package/dist/persistence/sqlite.d.ts +135 -0
- package/dist/persistence/sqlite.d.ts.map +1 -0
- package/dist/persistence/sqlite.js +372 -0
- package/dist/persistence/sqlite.js.map +1 -0
- package/dist/persistence/supabase.d.ts +93 -0
- package/dist/persistence/supabase.d.ts.map +1 -0
- package/dist/persistence/supabase.js +219 -0
- package/dist/persistence/supabase.js.map +1 -0
- package/dist/persistence/types.d.ts +5 -1
- package/dist/persistence/types.d.ts.map +1 -1
- package/dist/phase6/ceiling.d.ts +177 -0
- package/dist/phase6/ceiling.d.ts.map +1 -0
- package/dist/phase6/ceiling.js +463 -0
- package/dist/phase6/ceiling.js.map +1 -0
- package/dist/phase6/context.d.ts +207 -0
- package/dist/phase6/context.d.ts.map +1 -0
- package/dist/phase6/context.js +603 -0
- package/dist/phase6/context.js.map +1 -0
- package/dist/phase6/index.d.ts +79 -0
- package/dist/phase6/index.d.ts.map +1 -0
- package/dist/phase6/index.js +152 -0
- package/dist/phase6/index.js.map +1 -0
- package/dist/phase6/presets.d.ts +148 -0
- package/dist/phase6/presets.d.ts.map +1 -0
- package/dist/phase6/presets.js +467 -0
- package/dist/phase6/presets.js.map +1 -0
- package/dist/phase6/provenance.d.ts +148 -0
- package/dist/phase6/provenance.d.ts.map +1 -0
- package/dist/phase6/provenance.js +545 -0
- package/dist/phase6/provenance.js.map +1 -0
- package/dist/phase6/role-gates/index.d.ts +7 -0
- package/dist/phase6/role-gates/index.d.ts.map +1 -0
- package/dist/phase6/role-gates/index.js +7 -0
- package/dist/phase6/role-gates/index.js.map +1 -0
- package/dist/phase6/role-gates/kernel.d.ts +84 -0
- package/dist/phase6/role-gates/kernel.d.ts.map +1 -0
- package/dist/phase6/role-gates/kernel.js +258 -0
- package/dist/phase6/role-gates/kernel.js.map +1 -0
- package/dist/phase6/role-gates/policy.d.ts +110 -0
- package/dist/phase6/role-gates/policy.d.ts.map +1 -0
- package/dist/phase6/role-gates/policy.js +157 -0
- package/dist/phase6/role-gates/policy.js.map +1 -0
- package/dist/phase6/role-gates.d.ts +164 -0
- package/dist/phase6/role-gates.d.ts.map +1 -0
- package/dist/phase6/role-gates.js +536 -0
- package/dist/phase6/role-gates.js.map +1 -0
- package/dist/phase6/types.d.ts +1827 -0
- package/dist/phase6/types.d.ts.map +1 -0
- package/dist/phase6/types.js +450 -0
- package/dist/phase6/types.js.map +1 -0
- package/dist/phase6/weight-presets/canonical.d.ts +93 -0
- package/dist/phase6/weight-presets/canonical.d.ts.map +1 -0
- package/dist/phase6/weight-presets/canonical.js +122 -0
- package/dist/phase6/weight-presets/canonical.js.map +1 -0
- package/dist/phase6/weight-presets/deltas.d.ts +144 -0
- package/dist/phase6/weight-presets/deltas.d.ts.map +1 -0
- package/dist/phase6/weight-presets/deltas.js +184 -0
- package/dist/phase6/weight-presets/deltas.js.map +1 -0
- package/dist/phase6/weight-presets/index.d.ts +8 -0
- package/dist/phase6/weight-presets/index.d.ts.map +1 -0
- package/dist/phase6/weight-presets/index.js +8 -0
- package/dist/phase6/weight-presets/index.js.map +1 -0
- package/dist/phase6/weight-presets/merger.d.ts +79 -0
- package/dist/phase6/weight-presets/merger.d.ts.map +1 -0
- package/dist/phase6/weight-presets/merger.js +161 -0
- package/dist/phase6/weight-presets/merger.js.map +1 -0
- package/dist/proof/index.d.ts +50 -1
- package/dist/proof/index.d.ts.map +1 -1
- package/dist/proof/index.js +122 -3
- package/dist/proof/index.js.map +1 -1
- package/dist/proof/merkle.d.ts +195 -0
- package/dist/proof/merkle.d.ts.map +1 -0
- package/dist/proof/merkle.js +412 -0
- package/dist/proof/merkle.js.map +1 -0
- package/dist/proof/zk-proofs.d.ts +218 -0
- package/dist/proof/zk-proofs.d.ts.map +1 -0
- package/dist/proof/zk-proofs.js +531 -0
- package/dist/proof/zk-proofs.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts +98 -0
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/audit.js +160 -0
- package/dist/trust-engine/ceiling-enforcement/audit.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/index.d.ts +6 -0
- package/dist/trust-engine/ceiling-enforcement/index.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/index.js +6 -0
- package/dist/trust-engine/ceiling-enforcement/index.js.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts +112 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts.map +1 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.js +158 -0
- package/dist/trust-engine/ceiling-enforcement/kernel.js.map +1 -0
- package/dist/trust-engine/context-policy/enforcement.d.ts +62 -0
- package/dist/trust-engine/context-policy/enforcement.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/enforcement.js +104 -0
- package/dist/trust-engine/context-policy/enforcement.js.map +1 -0
- package/dist/trust-engine/context-policy/factory.d.ts +75 -0
- package/dist/trust-engine/context-policy/factory.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/factory.js +130 -0
- package/dist/trust-engine/context-policy/factory.js.map +1 -0
- package/dist/trust-engine/context-policy/index.d.ts +6 -0
- package/dist/trust-engine/context-policy/index.d.ts.map +1 -0
- package/dist/trust-engine/context-policy/index.js +6 -0
- package/dist/trust-engine/context-policy/index.js.map +1 -0
- package/dist/trust-engine/creation-modifiers/index.d.ts +5 -0
- package/dist/trust-engine/creation-modifiers/index.d.ts.map +1 -0
- package/dist/trust-engine/creation-modifiers/index.js +5 -0
- package/dist/trust-engine/creation-modifiers/index.js.map +1 -0
- package/dist/trust-engine/creation-modifiers/types.d.ts +112 -0
- package/dist/trust-engine/creation-modifiers/types.d.ts.map +1 -0
- package/dist/trust-engine/creation-modifiers/types.js +166 -0
- package/dist/trust-engine/creation-modifiers/types.js.map +1 -0
- package/dist/trust-engine/decay-profiles.d.ts +159 -0
- package/dist/trust-engine/decay-profiles.d.ts.map +1 -0
- package/dist/trust-engine/decay-profiles.js +210 -0
- package/dist/trust-engine/decay-profiles.js.map +1 -0
- package/dist/trust-engine/index.d.ts +144 -5
- package/dist/trust-engine/index.d.ts.map +1 -1
- package/dist/trust-engine/index.js +320 -15
- package/dist/trust-engine/index.js.map +1 -1
- package/dist/trust-engine/phase6-types.d.ts +123 -0
- package/dist/trust-engine/phase6-types.d.ts.map +1 -0
- package/dist/trust-engine/phase6-types.js +88 -0
- package/dist/trust-engine/phase6-types.js.map +1 -0
- package/package.json +26 -10
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @vorionsys/atsf-core
|
|
2
2
|
|
|
3
3
|
Agentic Trust Scoring Framework - Core runtime for AI agent governance, trust scoring, and policy enforcement.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @
|
|
8
|
+
npm install @vorionsys/atsf-core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
createIntentService,
|
|
19
19
|
EnforcementService,
|
|
20
20
|
createEnforcementService,
|
|
21
|
-
} from '@
|
|
21
|
+
} from '@vorionsys/atsf-core';
|
|
22
22
|
|
|
23
23
|
// Create a trust engine
|
|
24
24
|
const trustEngine = createTrustEngine();
|
|
@@ -50,7 +50,7 @@ console.log(record?.score, record?.level);
|
|
|
50
50
|
0-1000 trust scoring with 6 tiers, time-based decay, and accelerated decay on failure.
|
|
51
51
|
|
|
52
52
|
```typescript
|
|
53
|
-
import { TrustEngine, createTrustEngine } from '@
|
|
53
|
+
import { TrustEngine, createTrustEngine } from '@vorionsys/atsf-core';
|
|
54
54
|
|
|
55
55
|
// Basic usage
|
|
56
56
|
const engine = createTrustEngine();
|
|
@@ -71,7 +71,7 @@ const configuredEngine = createTrustEngine({
|
|
|
71
71
|
Constraint evaluation for governance policies.
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
|
-
import { createEvaluator, parseNamespace } from '@
|
|
74
|
+
import { createEvaluator, parseNamespace } from '@vorionsys/atsf-core';
|
|
75
75
|
|
|
76
76
|
const evaluator = createEvaluator();
|
|
77
77
|
evaluator.registerNamespace(parseNamespace(ruleDefinition));
|
|
@@ -83,7 +83,7 @@ const result = await evaluator.evaluate(context);
|
|
|
83
83
|
Submit and track agent intents through the governance pipeline.
|
|
84
84
|
|
|
85
85
|
```typescript
|
|
86
|
-
import { createIntentService } from '@
|
|
86
|
+
import { createIntentService } from '@vorionsys/atsf-core';
|
|
87
87
|
|
|
88
88
|
const intentService = createIntentService();
|
|
89
89
|
const intent = await intentService.submit({
|
|
@@ -98,7 +98,7 @@ const intent = await intentService.submit({
|
|
|
98
98
|
Policy decision point for allow/deny/escalate decisions.
|
|
99
99
|
|
|
100
100
|
```typescript
|
|
101
|
-
import { createEnforcementService } from '@
|
|
101
|
+
import { createEnforcementService } from '@vorionsys/atsf-core';
|
|
102
102
|
|
|
103
103
|
const enforcer = createEnforcementService({
|
|
104
104
|
defaultAction: 'deny',
|
|
@@ -112,7 +112,7 @@ const decision = await enforcer.decide(context);
|
|
|
112
112
|
Immutable audit chain with SHA-256 hashing.
|
|
113
113
|
|
|
114
114
|
```typescript
|
|
115
|
-
import { createProofService } from '@
|
|
115
|
+
import { createProofService } from '@vorionsys/atsf-core';
|
|
116
116
|
|
|
117
117
|
const proofService = createProofService();
|
|
118
118
|
const proof = await proofService.create({ intent, decision, inputs, outputs });
|
|
@@ -124,7 +124,7 @@ const verification = await proofService.verify(proof.id);
|
|
|
124
124
|
Constrained execution with resource limits.
|
|
125
125
|
|
|
126
126
|
```typescript
|
|
127
|
-
import { createGateway } from '@
|
|
127
|
+
import { createGateway } from '@vorionsys/atsf-core';
|
|
128
128
|
|
|
129
129
|
const gateway = createGateway({
|
|
130
130
|
maxMemoryMb: 256,
|
|
@@ -150,7 +150,7 @@ const result = await gateway.execute(context);
|
|
|
150
150
|
The Trust Engine extends `EventEmitter` and emits the following events:
|
|
151
151
|
|
|
152
152
|
```typescript
|
|
153
|
-
import { TrustEngine } from '@
|
|
153
|
+
import { TrustEngine } from '@vorionsys/atsf-core';
|
|
154
154
|
|
|
155
155
|
const engine = new TrustEngine();
|
|
156
156
|
|
|
@@ -225,7 +225,7 @@ import {
|
|
|
225
225
|
createTrustEngine,
|
|
226
226
|
createFileProvider,
|
|
227
227
|
createMemoryProvider,
|
|
228
|
-
} from '@
|
|
228
|
+
} from '@vorionsys/atsf-core';
|
|
229
229
|
|
|
230
230
|
// File-based persistence
|
|
231
231
|
const fileProvider = createFileProvider({
|
|
@@ -263,7 +263,7 @@ import {
|
|
|
263
263
|
createTrustEngine,
|
|
264
264
|
createTrustAwareExecutor,
|
|
265
265
|
createTrustTools,
|
|
266
|
-
} from '@
|
|
266
|
+
} from '@vorionsys/atsf-core';
|
|
267
267
|
|
|
268
268
|
// Create trust-aware executor
|
|
269
269
|
const engine = createTrustEngine();
|
package/dist/api/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAgB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/api/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAgB,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AA4KjF;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CA2iB7D;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBjD"}
|
package/dist/api/server.js
CHANGED
|
@@ -9,16 +9,100 @@ import Fastify from 'fastify';
|
|
|
9
9
|
import cors from '@fastify/cors';
|
|
10
10
|
import helmet from '@fastify/helmet';
|
|
11
11
|
import rateLimit from '@fastify/rate-limit';
|
|
12
|
-
import { createLogger
|
|
12
|
+
import { createLogger } from '../common/logger.js';
|
|
13
13
|
import { getConfig } from '../common/config.js';
|
|
14
|
+
import { createIntentService } from '../intent/index.js';
|
|
15
|
+
import { createProofService } from '../proof/index.js';
|
|
16
|
+
import { createTrustEngine } from '../trust-engine/index.js';
|
|
17
|
+
import { createEvaluator } from '../basis/evaluator.js';
|
|
14
18
|
const apiLogger = createLogger({ component: 'api' });
|
|
19
|
+
// ============================================================
|
|
20
|
+
// Health Check Implementation
|
|
21
|
+
// ============================================================
|
|
22
|
+
/**
|
|
23
|
+
* Get system metrics for health reporting
|
|
24
|
+
*/
|
|
25
|
+
function getSystemMetrics(startTime) {
|
|
26
|
+
const memUsage = process.memoryUsage();
|
|
27
|
+
const heapUsed = memUsage.heapUsed;
|
|
28
|
+
const heapTotal = memUsage.heapTotal;
|
|
29
|
+
return {
|
|
30
|
+
memoryUsageMB: Math.round(heapUsed / 1024 / 1024),
|
|
31
|
+
memoryUsagePercent: Math.round((heapUsed / heapTotal) * 100),
|
|
32
|
+
heapTotalMB: Math.round(heapTotal / 1024 / 1024),
|
|
33
|
+
uptimeSeconds: Math.round((Date.now() - startTime.getTime()) / 1000),
|
|
34
|
+
nodeVersion: process.version,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check system health (memory, etc.)
|
|
39
|
+
*/
|
|
40
|
+
function checkSystemHealth(startTime) {
|
|
41
|
+
const metrics = getSystemMetrics(startTime);
|
|
42
|
+
// Warning threshold: 80% memory usage
|
|
43
|
+
// Error threshold: 95% memory usage
|
|
44
|
+
let status = 'ok';
|
|
45
|
+
let message = 'System healthy';
|
|
46
|
+
if (metrics.memoryUsagePercent > 95) {
|
|
47
|
+
status = 'error';
|
|
48
|
+
message = 'Critical memory pressure';
|
|
49
|
+
}
|
|
50
|
+
else if (metrics.memoryUsagePercent > 80) {
|
|
51
|
+
status = 'degraded';
|
|
52
|
+
message = 'High memory usage';
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
status,
|
|
56
|
+
message,
|
|
57
|
+
details: {
|
|
58
|
+
memoryUsageMB: metrics.memoryUsageMB,
|
|
59
|
+
memoryUsagePercent: metrics.memoryUsagePercent,
|
|
60
|
+
uptimeSeconds: metrics.uptimeSeconds,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check a service by attempting a simple operation
|
|
66
|
+
*/
|
|
67
|
+
async function checkService(name, checkFn) {
|
|
68
|
+
const start = Date.now();
|
|
69
|
+
try {
|
|
70
|
+
await checkFn();
|
|
71
|
+
return {
|
|
72
|
+
status: 'ok',
|
|
73
|
+
latencyMs: Date.now() - start,
|
|
74
|
+
message: `${name} operational`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
status: 'error',
|
|
80
|
+
latencyMs: Date.now() - start,
|
|
81
|
+
message: `${name} error: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
15
85
|
/**
|
|
16
86
|
* Create and configure the API server
|
|
17
87
|
*/
|
|
18
88
|
export async function createServer() {
|
|
19
89
|
const config = getConfig();
|
|
90
|
+
const startTime = new Date();
|
|
91
|
+
// Initialize services
|
|
92
|
+
const intentService = createIntentService();
|
|
93
|
+
const proofService = createProofService();
|
|
94
|
+
const trustEngine = createTrustEngine();
|
|
95
|
+
const evaluator = createEvaluator();
|
|
96
|
+
// Use pino logger config for Fastify 5
|
|
97
|
+
const isTest = process.env['NODE_ENV'] === 'test' || process.env['VITEST'];
|
|
20
98
|
const server = Fastify({
|
|
21
|
-
logger:
|
|
99
|
+
logger: isTest ? false : {
|
|
100
|
+
level: config.env === 'production' ? 'info' : 'debug',
|
|
101
|
+
transport: config.env !== 'production' ? {
|
|
102
|
+
target: 'pino-pretty',
|
|
103
|
+
options: { colorize: true },
|
|
104
|
+
} : undefined,
|
|
105
|
+
},
|
|
22
106
|
requestIdHeader: 'x-request-id',
|
|
23
107
|
requestIdLogLabel: 'requestId',
|
|
24
108
|
});
|
|
@@ -34,51 +118,395 @@ export async function createServer() {
|
|
|
34
118
|
max: config.api.rateLimit,
|
|
35
119
|
timeWindow: '1 minute',
|
|
36
120
|
});
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
121
|
+
// API Key authentication for protected routes
|
|
122
|
+
const API_KEY = process.env['VORION_API_KEY'] || config.api.apiKey;
|
|
123
|
+
const requiresAuth = (url) => {
|
|
124
|
+
// Public endpoints that don't require auth
|
|
125
|
+
const publicPaths = ['/health', '/ready', '/live', '/api/v1/health'];
|
|
126
|
+
return !publicPaths.some(path => url === path || url.startsWith(path + '?'));
|
|
127
|
+
};
|
|
128
|
+
server.addHook('onRequest', async (request, reply) => {
|
|
129
|
+
// Skip auth in test mode or for public endpoints
|
|
130
|
+
if (isTest || !requiresAuth(request.url)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Skip auth if no API key is configured (development mode)
|
|
134
|
+
if (!API_KEY) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const authHeader = request.headers['authorization'];
|
|
138
|
+
if (!authHeader) {
|
|
139
|
+
return reply.status(401).send({
|
|
140
|
+
error: { code: 'UNAUTHORIZED', message: 'Missing Authorization header' },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const [scheme, token] = authHeader.split(' ');
|
|
144
|
+
if (scheme?.toLowerCase() !== 'bearer' || token !== API_KEY) {
|
|
145
|
+
return reply.status(401).send({
|
|
146
|
+
error: { code: 'UNAUTHORIZED', message: 'Invalid API key' },
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
// Health check endpoint - performs actual checks on all services
|
|
151
|
+
server.get('/health', async () => {
|
|
152
|
+
const checks = {};
|
|
153
|
+
// Check trust engine
|
|
154
|
+
checks.trustEngine = await checkService('Trust engine', async () => {
|
|
155
|
+
await trustEngine.getScore('__health_check__');
|
|
156
|
+
});
|
|
157
|
+
// Check proof service
|
|
158
|
+
checks.proofService = await checkService('Proof service', async () => {
|
|
159
|
+
await proofService.get('__health_check_proof__');
|
|
160
|
+
});
|
|
161
|
+
// Check intent service
|
|
162
|
+
checks.intentService = await checkService('Intent service', async () => {
|
|
163
|
+
await intentService.get('__health_check_intent__', '__system__');
|
|
164
|
+
});
|
|
165
|
+
// Check system health
|
|
166
|
+
checks.system = checkSystemHealth(startTime);
|
|
167
|
+
// Determine overall status
|
|
168
|
+
const statuses = Object.values(checks).map((c) => c.status);
|
|
169
|
+
let status;
|
|
170
|
+
if (statuses.every((s) => s === 'ok')) {
|
|
171
|
+
status = 'healthy';
|
|
172
|
+
}
|
|
173
|
+
else if (statuses.some((s) => s === 'error')) {
|
|
174
|
+
status = 'unhealthy';
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
status = 'degraded';
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
status,
|
|
181
|
+
timestamp: new Date().toISOString(),
|
|
182
|
+
version: process.env['npm_package_version'],
|
|
183
|
+
environment: config.env,
|
|
184
|
+
checks,
|
|
185
|
+
metrics: getSystemMetrics(startTime),
|
|
186
|
+
};
|
|
187
|
+
});
|
|
188
|
+
// Ready check endpoint - verifies all critical services are ready
|
|
189
|
+
server.get('/ready', async (_request, reply) => {
|
|
190
|
+
const checks = {};
|
|
191
|
+
// Check trust engine (critical)
|
|
192
|
+
checks.trustEngine = await checkService('Trust engine', async () => {
|
|
193
|
+
await trustEngine.getScore('__health_check__');
|
|
194
|
+
});
|
|
195
|
+
// Check proof service (critical)
|
|
196
|
+
checks.proofService = await checkService('Proof service', async () => {
|
|
197
|
+
await proofService.get('__health_check_proof__');
|
|
198
|
+
});
|
|
199
|
+
// Check intent service (critical)
|
|
200
|
+
checks.intentService = await checkService('Intent service', async () => {
|
|
201
|
+
await intentService.get('__health_check_intent__', '__system__');
|
|
202
|
+
});
|
|
203
|
+
const allPassed = Object.values(checks).every((c) => c.status === 'ok' || c.status === 'degraded');
|
|
204
|
+
// Return 503 if not ready (for Kubernetes probes)
|
|
205
|
+
if (!allPassed) {
|
|
206
|
+
reply.status(503);
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
status: allPassed ? 'ready' : 'not_ready',
|
|
210
|
+
timestamp: new Date().toISOString(),
|
|
211
|
+
checks,
|
|
212
|
+
allPassed,
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
// Liveness probe endpoint - simple alive check (no deep checks)
|
|
216
|
+
server.get('/live', async () => ({
|
|
217
|
+
status: 'alive',
|
|
42
218
|
timestamp: new Date().toISOString(),
|
|
43
219
|
}));
|
|
44
|
-
// Ready check endpoint
|
|
45
|
-
server.get('/ready', async () => ({
|
|
46
|
-
status: 'ready',
|
|
47
|
-
checks: {
|
|
48
|
-
database: 'ok', // TODO: Implement actual checks
|
|
49
|
-
redis: 'ok',
|
|
50
|
-
proof: 'ok',
|
|
51
|
-
},
|
|
52
|
-
}));
|
|
53
220
|
// API routes
|
|
54
221
|
server.register(async (api) => {
|
|
55
|
-
//
|
|
56
|
-
api.
|
|
57
|
-
|
|
58
|
-
|
|
222
|
+
// SDK: Health check endpoint
|
|
223
|
+
api.get('/health', async () => ({
|
|
224
|
+
status: 'healthy',
|
|
225
|
+
version: process.env['npm_package_version'] ?? '0.1.0',
|
|
226
|
+
}));
|
|
227
|
+
// Intent routes - unified handler for both legacy and SDK formats
|
|
228
|
+
api.post('/intents', async (request, reply) => {
|
|
229
|
+
const body = request.body;
|
|
230
|
+
// Detect format: SDK format has 'agentId' and 'action', legacy has 'entityId' and 'goal'
|
|
231
|
+
if ('agentId' in body && 'action' in body) {
|
|
232
|
+
// SDK format
|
|
233
|
+
const startTime = Date.now();
|
|
234
|
+
const { agentId, capabilities = [], action } = body;
|
|
235
|
+
if (!agentId || !action?.type || !action?.resource) {
|
|
236
|
+
return reply.status(400).send({
|
|
237
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing required fields: agentId, action.type, action.resource' },
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// Get or create agent trust record
|
|
241
|
+
let trustRecord = await trustEngine.getScore(agentId);
|
|
242
|
+
if (!trustRecord) {
|
|
243
|
+
await trustEngine.initializeEntity(agentId, 3); // Default to T3
|
|
244
|
+
trustRecord = await trustEngine.getScore(agentId);
|
|
245
|
+
}
|
|
246
|
+
// Check capability
|
|
247
|
+
const hasCapability = capabilities.some(cap => cap === '*' ||
|
|
248
|
+
cap === action.type ||
|
|
249
|
+
cap === `${action.type}:*` ||
|
|
250
|
+
cap === `${action.type}:${action.resource.split('/')[0]}`);
|
|
251
|
+
// Determine decision
|
|
252
|
+
const trustLevel = trustRecord?.level ?? 3;
|
|
253
|
+
const trustScore = trustRecord?.score ?? 500;
|
|
254
|
+
const allowed = hasCapability && trustScore >= 200;
|
|
255
|
+
// Decision tier based on trust level
|
|
256
|
+
let tier;
|
|
257
|
+
if (!allowed) {
|
|
258
|
+
tier = 'RED';
|
|
259
|
+
}
|
|
260
|
+
else if (trustLevel >= 5) {
|
|
261
|
+
tier = 'GREEN';
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
tier = 'YELLOW';
|
|
265
|
+
}
|
|
266
|
+
// Create proof record
|
|
267
|
+
const proofId = `proof-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
268
|
+
const intentId = `intent-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
269
|
+
// Determine constraints based on tier
|
|
270
|
+
const constraints = [];
|
|
271
|
+
if (trustLevel <= 1) {
|
|
272
|
+
constraints.push('rate_limit:10/min', 'audit:full', 'sandbox:true');
|
|
273
|
+
}
|
|
274
|
+
else if (trustLevel <= 3) {
|
|
275
|
+
constraints.push('rate_limit:100/min', 'audit:standard');
|
|
276
|
+
}
|
|
277
|
+
else if (trustLevel <= 5) {
|
|
278
|
+
constraints.push('rate_limit:1000/min', 'audit:light');
|
|
279
|
+
}
|
|
280
|
+
const reason = allowed
|
|
281
|
+
? 'Action permitted based on capabilities and trust level'
|
|
282
|
+
: hasCapability
|
|
283
|
+
? `Trust score ${trustScore} below minimum threshold (200)`
|
|
284
|
+
: `Missing capability for ${action.type}:${action.resource.split('/')[0]}`;
|
|
285
|
+
apiLogger.info({ intentId, agentId, action: action.type, allowed, tier }, 'Intent processed');
|
|
286
|
+
return {
|
|
287
|
+
intentId,
|
|
288
|
+
allowed,
|
|
289
|
+
tier,
|
|
290
|
+
reason,
|
|
291
|
+
proofId,
|
|
292
|
+
constraints: allowed ? constraints : undefined,
|
|
293
|
+
processingTimeMs: Date.now() - startTime,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
// Legacy format
|
|
298
|
+
const { entityId, goal, context, metadata } = body;
|
|
299
|
+
if (!entityId || !goal) {
|
|
300
|
+
return reply.status(400).send({
|
|
301
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing required fields: entityId, goal' },
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const intent = await intentService.submit({
|
|
305
|
+
entityId,
|
|
306
|
+
goal,
|
|
307
|
+
context: context ?? {},
|
|
308
|
+
metadata,
|
|
309
|
+
}, { tenantId: '__system__' });
|
|
310
|
+
apiLogger.info({ intentId: intent.id, entityId }, 'Intent submitted');
|
|
311
|
+
return reply.status(201).send({ intent });
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
api.get('/intents/:id', async (request, reply) => {
|
|
315
|
+
const intent = await intentService.get(request.params.id, '__system__');
|
|
316
|
+
if (!intent) {
|
|
317
|
+
return reply.status(404).send({
|
|
318
|
+
error: { code: 'NOT_FOUND', message: 'Intent not found' },
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return { intent };
|
|
59
322
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
323
|
+
// SDK: Check intent (pre-flight, no side effects)
|
|
324
|
+
api.post('/intents/check', async (request, reply) => {
|
|
325
|
+
const { agentId, capabilities = [], action } = request.body;
|
|
326
|
+
if (!agentId || !action?.type || !action?.resource) {
|
|
327
|
+
return reply.status(400).send({
|
|
328
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing required fields' },
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
// Get agent trust record
|
|
332
|
+
const trustRecord = await trustEngine.getScore(agentId);
|
|
333
|
+
const trustScore = trustRecord?.score ?? 0;
|
|
334
|
+
const trustLevel = trustRecord?.level ?? 0;
|
|
335
|
+
// Check capability
|
|
336
|
+
const hasCapability = capabilities.some(cap => cap === '*' ||
|
|
337
|
+
cap === action.type ||
|
|
338
|
+
cap === `${action.type}:*` ||
|
|
339
|
+
cap === `${action.type}:${action.resource.split('/')[0]}`);
|
|
340
|
+
const wouldAllow = hasCapability && trustScore >= 200;
|
|
341
|
+
let tier;
|
|
342
|
+
if (!wouldAllow) {
|
|
343
|
+
tier = 'RED';
|
|
344
|
+
}
|
|
345
|
+
else if (trustLevel >= 5) {
|
|
346
|
+
tier = 'GREEN';
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
tier = 'YELLOW';
|
|
350
|
+
}
|
|
351
|
+
const reason = wouldAllow
|
|
352
|
+
? 'Action would be permitted'
|
|
353
|
+
: hasCapability
|
|
354
|
+
? `Trust score ${trustScore} below minimum threshold`
|
|
355
|
+
: `Missing capability for ${action.type}`;
|
|
356
|
+
return { wouldAllow, tier, reason };
|
|
63
357
|
});
|
|
64
358
|
// Proof routes
|
|
65
|
-
api.get('/proofs/:id', async (
|
|
66
|
-
|
|
67
|
-
|
|
359
|
+
api.get('/proofs/:id', async (request, reply) => {
|
|
360
|
+
const proof = await proofService.get(request.params.id);
|
|
361
|
+
if (!proof) {
|
|
362
|
+
return reply.status(404).send({
|
|
363
|
+
error: { code: 'NOT_FOUND', message: 'Proof not found' },
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
return { proof };
|
|
68
367
|
});
|
|
69
|
-
api.post('/proofs/:id/verify', async (
|
|
70
|
-
|
|
71
|
-
|
|
368
|
+
api.post('/proofs/:id/verify', async (request, reply) => {
|
|
369
|
+
const result = await proofService.verify(request.params.id);
|
|
370
|
+
if (result.chainPosition === -1) {
|
|
371
|
+
return reply.status(404).send({
|
|
372
|
+
error: { code: 'NOT_FOUND', message: 'Proof not found' },
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
return { verification: result };
|
|
72
376
|
});
|
|
73
377
|
// Trust routes
|
|
74
|
-
api.get('/trust/:entityId', async (
|
|
75
|
-
|
|
76
|
-
|
|
378
|
+
api.get('/trust/:entityId', async (request) => {
|
|
379
|
+
const record = await trustEngine.getScore(request.params.entityId);
|
|
380
|
+
if (!record) {
|
|
381
|
+
// Return null values for non-existent agents (SDK compatible)
|
|
382
|
+
return {
|
|
383
|
+
agentId: request.params.entityId,
|
|
384
|
+
score: null,
|
|
385
|
+
tier: null,
|
|
386
|
+
tierName: null,
|
|
387
|
+
message: 'Agent not found',
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
return {
|
|
391
|
+
agentId: record.entityId,
|
|
392
|
+
score: record.score,
|
|
393
|
+
tier: record.level,
|
|
394
|
+
tierName: trustEngine.getLevelName(record.level),
|
|
395
|
+
observationCeiling: 7, // Max tier ceiling
|
|
396
|
+
};
|
|
397
|
+
});
|
|
398
|
+
// SDK: Admit agent endpoint
|
|
399
|
+
api.post('/trust/admit', async (request, reply) => {
|
|
400
|
+
const { agentId, name, capabilities, observationTier } = request.body;
|
|
401
|
+
if (!agentId || !name) {
|
|
402
|
+
return reply.status(400).send({
|
|
403
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing required fields: agentId, name' },
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
// Initialize agent in trust engine at T3 (Monitored)
|
|
407
|
+
const initialLevel = 3;
|
|
408
|
+
await trustEngine.initializeEntity(agentId, initialLevel);
|
|
409
|
+
const record = await trustEngine.getScore(agentId);
|
|
410
|
+
const expiresAt = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString(); // 1 year
|
|
411
|
+
apiLogger.info({ agentId, name, initialLevel }, 'Agent admitted');
|
|
412
|
+
return reply.status(201).send({
|
|
413
|
+
admitted: true,
|
|
414
|
+
initialTier: record?.level ?? initialLevel,
|
|
415
|
+
initialScore: record?.score ?? 500,
|
|
416
|
+
observationCeiling: observationTier === 'WHITE_BOX' ? 7 : observationTier === 'GRAY_BOX' ? 5 : 3,
|
|
417
|
+
capabilities: capabilities ?? [],
|
|
418
|
+
expiresAt,
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
// SDK: Record trust signal
|
|
422
|
+
api.post('/trust/:agentId/signal', async (request, reply) => {
|
|
423
|
+
const { agentId } = request.params;
|
|
424
|
+
const { type, source, weight = 0.1, context } = request.body;
|
|
425
|
+
const recordBefore = await trustEngine.getScore(agentId);
|
|
426
|
+
if (!recordBefore) {
|
|
427
|
+
return reply.status(404).send({
|
|
428
|
+
error: { code: 'NOT_FOUND', message: 'Agent not found' },
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
const scoreBefore = recordBefore.score;
|
|
432
|
+
// Map signal type to trust value
|
|
433
|
+
const valueMap = {
|
|
434
|
+
success: 0.8 + (weight * 0.2),
|
|
435
|
+
failure: 0.2 - (weight * 0.1),
|
|
436
|
+
violation: 0.0,
|
|
437
|
+
neutral: 0.5,
|
|
438
|
+
};
|
|
439
|
+
// Record the signal
|
|
440
|
+
await trustEngine.recordSignal({
|
|
441
|
+
id: `signal-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
442
|
+
entityId: agentId,
|
|
443
|
+
type: `behavioral.${type}`,
|
|
444
|
+
value: valueMap[type] ?? 0.5,
|
|
445
|
+
source,
|
|
446
|
+
timestamp: new Date().toISOString(),
|
|
447
|
+
metadata: context ?? {},
|
|
448
|
+
});
|
|
449
|
+
const recordAfter = await trustEngine.getScore(agentId);
|
|
450
|
+
const scoreAfter = recordAfter?.score ?? scoreBefore;
|
|
451
|
+
return {
|
|
452
|
+
accepted: true,
|
|
453
|
+
scoreBefore,
|
|
454
|
+
scoreAfter,
|
|
455
|
+
change: scoreAfter - scoreBefore,
|
|
456
|
+
newTier: recordAfter?.level ?? null,
|
|
457
|
+
newTierName: recordAfter ? trustEngine.getLevelName(recordAfter.level) : null,
|
|
458
|
+
};
|
|
77
459
|
});
|
|
78
460
|
// Constraint routes
|
|
79
|
-
api.post('/constraints/validate', async (
|
|
80
|
-
|
|
81
|
-
|
|
461
|
+
api.post('/constraints/validate', async (request, reply) => {
|
|
462
|
+
const { entityId, intentType, context } = request.body;
|
|
463
|
+
if (!entityId || !intentType) {
|
|
464
|
+
return reply.status(400).send({
|
|
465
|
+
error: { code: 'INVALID_REQUEST', message: 'Missing required fields' },
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
// Get entity trust record
|
|
469
|
+
const trustRecord = await trustEngine.getScore(entityId);
|
|
470
|
+
if (!trustRecord) {
|
|
471
|
+
return reply.status(404).send({
|
|
472
|
+
error: { code: 'NOT_FOUND', message: 'Entity not found' },
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
// Create evaluation context
|
|
476
|
+
const evalContext = {
|
|
477
|
+
intent: {
|
|
478
|
+
id: 'validation-check',
|
|
479
|
+
type: intentType,
|
|
480
|
+
goal: 'constraint-validation',
|
|
481
|
+
context: context ?? {},
|
|
482
|
+
},
|
|
483
|
+
entity: {
|
|
484
|
+
id: entityId,
|
|
485
|
+
type: 'agent',
|
|
486
|
+
trustScore: trustRecord.score,
|
|
487
|
+
trustLevel: trustRecord.level,
|
|
488
|
+
attributes: {},
|
|
489
|
+
},
|
|
490
|
+
environment: {
|
|
491
|
+
timestamp: new Date().toISOString(),
|
|
492
|
+
timezone: 'UTC',
|
|
493
|
+
requestId: request.id,
|
|
494
|
+
},
|
|
495
|
+
custom: {},
|
|
496
|
+
};
|
|
497
|
+
// Evaluate constraints
|
|
498
|
+
const result = await evaluator.evaluate(evalContext);
|
|
499
|
+
return {
|
|
500
|
+
validation: {
|
|
501
|
+
passed: result.passed,
|
|
502
|
+
action: result.finalAction,
|
|
503
|
+
rulesEvaluated: result.rulesEvaluated.length,
|
|
504
|
+
violations: result.violatedRules.map((r) => ({
|
|
505
|
+
ruleId: r.ruleId,
|
|
506
|
+
reason: r.reason,
|
|
507
|
+
})),
|
|
508
|
+
},
|
|
509
|
+
};
|
|
82
510
|
});
|
|
83
511
|
}, { prefix: config.api.basePath });
|
|
84
512
|
// Error handler
|