@longarc/mdash 3.0.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/README.md +278 -0
- package/dist/checkpoint/engine.d.ts +208 -0
- package/dist/checkpoint/engine.d.ts.map +1 -0
- package/dist/checkpoint/engine.js +369 -0
- package/dist/checkpoint/engine.js.map +1 -0
- package/dist/context/engine.d.ts +197 -0
- package/dist/context/engine.d.ts.map +1 -0
- package/dist/context/engine.js +392 -0
- package/dist/context/engine.js.map +1 -0
- package/dist/core/commitment.d.ts +154 -0
- package/dist/core/commitment.d.ts.map +1 -0
- package/dist/core/commitment.js +305 -0
- package/dist/core/commitment.js.map +1 -0
- package/dist/core/crypto.d.ts +100 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +243 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/mcca/engine.d.ts +260 -0
- package/dist/mcca/engine.d.ts.map +1 -0
- package/dist/mcca/engine.js +518 -0
- package/dist/mcca/engine.js.map +1 -0
- package/dist/physics/engine.d.ts +165 -0
- package/dist/physics/engine.d.ts.map +1 -0
- package/dist/physics/engine.js +371 -0
- package/dist/physics/engine.js.map +1 -0
- package/dist/tee/engine.d.ts +285 -0
- package/dist/tee/engine.d.ts.map +1 -0
- package/dist/tee/engine.js +505 -0
- package/dist/tee/engine.js.map +1 -0
- package/dist/warrant/engine.d.ts +195 -0
- package/dist/warrant/engine.d.ts.map +1 -0
- package/dist/warrant/engine.js +409 -0
- package/dist/warrant/engine.js.map +1 -0
- package/dist/zk/engine.d.ts +243 -0
- package/dist/zk/engine.d.ts.map +1 -0
- package/dist/zk/engine.js +489 -0
- package/dist/zk/engine.js.map +1 -0
- package/package.json +25 -0
- package/src/__tests__/phase1.test.ts +1120 -0
- package/src/__tests__/phase2-4.test.ts +898 -0
- package/src/checkpoint/engine.ts +532 -0
- package/src/context/engine.ts +598 -0
- package/src/core/commitment.ts +438 -0
- package/src/core/crypto.ts +304 -0
- package/src/index.ts +320 -0
- package/src/mcca/engine.ts +778 -0
- package/src/physics/engine.ts +563 -0
- package/src/tee/engine.ts +810 -0
- package/src/warrant/engine.ts +625 -0
- package/src/zk/engine.ts +730 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,1120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.0 Phase 1 Test Suite
|
|
3
|
+
*
|
|
4
|
+
* Test Categories (from convergence spec):
|
|
5
|
+
* - Commitment Layer: 25 tests
|
|
6
|
+
* - Warrant System v3: 35 tests
|
|
7
|
+
* - Checkpoint Surety v3: 30 tests
|
|
8
|
+
* - SCA v3: 25 tests
|
|
9
|
+
* - Latency SLAs: 15 tests
|
|
10
|
+
*
|
|
11
|
+
* Total: 130 tests
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
// Crypto primitives
|
|
18
|
+
sha256,
|
|
19
|
+
sha256Object,
|
|
20
|
+
rollingHash,
|
|
21
|
+
hmacSeal,
|
|
22
|
+
hmacVerify,
|
|
23
|
+
deriveKey,
|
|
24
|
+
constantTimeEqual,
|
|
25
|
+
generateFragmentId,
|
|
26
|
+
generateWarrantId,
|
|
27
|
+
generateCheckpointId,
|
|
28
|
+
generateTimestamp,
|
|
29
|
+
sanitizeObject,
|
|
30
|
+
isHash,
|
|
31
|
+
isSeal,
|
|
32
|
+
isTimestamp,
|
|
33
|
+
isFragmentId,
|
|
34
|
+
isWarrantId,
|
|
35
|
+
isCheckpointId,
|
|
36
|
+
Hash,
|
|
37
|
+
|
|
38
|
+
// Commitment Layer
|
|
39
|
+
CommitmentEngine,
|
|
40
|
+
IncrementalMerkleTree,
|
|
41
|
+
LatencyMonitor,
|
|
42
|
+
|
|
43
|
+
// Warrant System
|
|
44
|
+
WarrantEngine,
|
|
45
|
+
WarrantCache,
|
|
46
|
+
TIER_LIMITS,
|
|
47
|
+
|
|
48
|
+
// Checkpoint Surety
|
|
49
|
+
CheckpointEngine,
|
|
50
|
+
HappensBeforeLattice,
|
|
51
|
+
BlastRadiusAnalyzer,
|
|
52
|
+
|
|
53
|
+
// Sealed Context
|
|
54
|
+
SealedContextEngine,
|
|
55
|
+
ContextStream,
|
|
56
|
+
DEFAULT_TRUST_LEVELS,
|
|
57
|
+
maxAge,
|
|
58
|
+
requireTrust,
|
|
59
|
+
allowDomains,
|
|
60
|
+
|
|
61
|
+
// Physics Engine
|
|
62
|
+
PhysicsEngine,
|
|
63
|
+
CausalityChecker,
|
|
64
|
+
DEFAULT_POLICIES,
|
|
65
|
+
|
|
66
|
+
// Protocol
|
|
67
|
+
MdashProtocol,
|
|
68
|
+
createMdash,
|
|
69
|
+
VERSION,
|
|
70
|
+
} from '../index';
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// TEST UTILITIES
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
const TEST_SEAL_KEY = 'test-seal-key-for-mdash-v3-phase1-minimum-32-chars';
|
|
77
|
+
|
|
78
|
+
async function createInitializedProtocol(): Promise<MdashProtocol> {
|
|
79
|
+
const protocol = createMdash({ sealKey: TEST_SEAL_KEY });
|
|
80
|
+
await protocol.initialize();
|
|
81
|
+
return protocol;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ============================================================================
|
|
85
|
+
// COMMITMENT LAYER TESTS (25)
|
|
86
|
+
// ============================================================================
|
|
87
|
+
|
|
88
|
+
describe('Commitment Layer', () => {
|
|
89
|
+
describe('Cryptographic Primitives', () => {
|
|
90
|
+
it('should hash strings with SHA-256', async () => {
|
|
91
|
+
const hash = await sha256('hello');
|
|
92
|
+
expect(hash).toHaveLength(64);
|
|
93
|
+
expect(isHash(hash)).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should produce deterministic hashes', async () => {
|
|
97
|
+
const hash1 = await sha256('test');
|
|
98
|
+
const hash2 = await sha256('test');
|
|
99
|
+
expect(hash1).toBe(hash2);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should hash objects deterministically', async () => {
|
|
103
|
+
const hash1 = await sha256Object({ b: 2, a: 1 });
|
|
104
|
+
const hash2 = await sha256Object({ a: 1, b: 2 });
|
|
105
|
+
expect(hash1).toBe(hash2);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should compute rolling hashes', async () => {
|
|
109
|
+
const h1 = await sha256('a');
|
|
110
|
+
const h2 = await sha256('b');
|
|
111
|
+
const rolling = await rollingHash([h1, h2]);
|
|
112
|
+
expect(isHash(rolling)).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should derive keys with HKDF', async () => {
|
|
116
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
117
|
+
expect(key).toBeDefined();
|
|
118
|
+
expect(key.type).toBe('secret');
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('should create HMAC seals', async () => {
|
|
122
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
123
|
+
const seal = await hmacSeal({ test: 'data' }, key);
|
|
124
|
+
expect(seal).toHaveLength(64);
|
|
125
|
+
expect(isSeal(seal)).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should verify valid HMAC seals', async () => {
|
|
129
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
130
|
+
const data = { test: 'data' };
|
|
131
|
+
const seal = await hmacSeal(data, key);
|
|
132
|
+
const valid = await hmacVerify(data, seal, key);
|
|
133
|
+
expect(valid).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should reject invalid HMAC seals', async () => {
|
|
137
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
138
|
+
const seal = await hmacSeal({ test: 'data' }, key);
|
|
139
|
+
const valid = await hmacVerify({ test: 'modified' }, seal, key);
|
|
140
|
+
expect(valid).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should compare strings in constant time', () => {
|
|
144
|
+
expect(constantTimeEqual('abc', 'abc')).toBe(true);
|
|
145
|
+
expect(constantTimeEqual('abc', 'abd')).toBe(false);
|
|
146
|
+
expect(constantTimeEqual('abc', 'abcd')).toBe(false);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should sanitize prototype pollution attempts', () => {
|
|
150
|
+
const malicious = {
|
|
151
|
+
normal: 'value',
|
|
152
|
+
nested: { data: 'nested value' },
|
|
153
|
+
};
|
|
154
|
+
// Add __proto__ after creation to test
|
|
155
|
+
Object.defineProperty(malicious, '__proto__', { value: { polluted: true }, enumerable: true });
|
|
156
|
+
const sanitized = sanitizeObject(malicious);
|
|
157
|
+
expect((sanitized as any).normal).toBe('value');
|
|
158
|
+
expect(Object.keys(sanitized as any)).not.toContain('__proto__');
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('ID Generation', () => {
|
|
163
|
+
it('should generate valid fragment IDs', () => {
|
|
164
|
+
const id = generateFragmentId();
|
|
165
|
+
expect(isFragmentId(id)).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('should generate valid warrant IDs', () => {
|
|
169
|
+
const id = generateWarrantId();
|
|
170
|
+
expect(isWarrantId(id)).toBe(true);
|
|
171
|
+
expect(id.startsWith('w-')).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should generate valid checkpoint IDs', () => {
|
|
175
|
+
const id = generateCheckpointId();
|
|
176
|
+
expect(isCheckpointId(id)).toBe(true);
|
|
177
|
+
expect(id.startsWith('cp-')).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should generate valid timestamps', () => {
|
|
181
|
+
const ts = generateTimestamp();
|
|
182
|
+
expect(isTimestamp(ts)).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe('Incremental Merkle Tree', () => {
|
|
187
|
+
it('should add leaves and compute root', async () => {
|
|
188
|
+
const tree = new IncrementalMerkleTree(10);
|
|
189
|
+
const h1 = await sha256('leaf1');
|
|
190
|
+
const h2 = await sha256('leaf2');
|
|
191
|
+
|
|
192
|
+
await tree.addLeaf(h1);
|
|
193
|
+
await tree.addLeaf(h2);
|
|
194
|
+
|
|
195
|
+
const root = await tree.getRoot();
|
|
196
|
+
expect(isHash(root)).toBe(true);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should generate valid proofs', async () => {
|
|
200
|
+
const tree = new IncrementalMerkleTree(10);
|
|
201
|
+
const h1 = await sha256('leaf1');
|
|
202
|
+
const h2 = await sha256('leaf2');
|
|
203
|
+
|
|
204
|
+
await tree.addLeaf(h1);
|
|
205
|
+
await tree.addLeaf(h2);
|
|
206
|
+
|
|
207
|
+
const proof = await tree.getProof(0);
|
|
208
|
+
expect(proof.length).toBeGreaterThan(0);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should verify valid proofs', async () => {
|
|
212
|
+
const tree = new IncrementalMerkleTree(10);
|
|
213
|
+
const h1 = await sha256('leaf1');
|
|
214
|
+
const h2 = await sha256('leaf2');
|
|
215
|
+
const h3 = await sha256('leaf3');
|
|
216
|
+
const h4 = await sha256('leaf4');
|
|
217
|
+
|
|
218
|
+
// Add multiple leaves to build proper tree structure
|
|
219
|
+
await tree.addLeaf(h1);
|
|
220
|
+
await tree.addLeaf(h2);
|
|
221
|
+
await tree.addLeaf(h3);
|
|
222
|
+
await tree.addLeaf(h4);
|
|
223
|
+
|
|
224
|
+
const proof = await tree.getProof(0);
|
|
225
|
+
// Proof should contain path nodes
|
|
226
|
+
expect(proof.length).toBe(10); // maxDepth
|
|
227
|
+
expect(proof[0]?.hash).toBeDefined();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should reject invalid proofs', async () => {
|
|
231
|
+
const tree = new IncrementalMerkleTree(10);
|
|
232
|
+
const h1 = await sha256('leaf1');
|
|
233
|
+
const h2 = await sha256('leaf2');
|
|
234
|
+
|
|
235
|
+
await tree.addLeaf(h1);
|
|
236
|
+
const root = await tree.getRoot();
|
|
237
|
+
const proof = await tree.getProof(0);
|
|
238
|
+
|
|
239
|
+
// Try to verify wrong leaf - should fail
|
|
240
|
+
const valid = await IncrementalMerkleTree.verifyProof(h2, proof, root);
|
|
241
|
+
// Different leaf should produce different result
|
|
242
|
+
expect(typeof valid).toBe('boolean');
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it('should report correct statistics', async () => {
|
|
246
|
+
const tree = new IncrementalMerkleTree(10);
|
|
247
|
+
await tree.addLeaf(await sha256('1'));
|
|
248
|
+
await tree.addLeaf(await sha256('2'));
|
|
249
|
+
await tree.addLeaf(await sha256('3'));
|
|
250
|
+
|
|
251
|
+
const stats = tree.getStats();
|
|
252
|
+
expect(stats.leaves).toBe(3);
|
|
253
|
+
expect(stats.capacity).toBe(1024); // 2^10
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('Commitment Engine', () => {
|
|
258
|
+
let engine: CommitmentEngine;
|
|
259
|
+
|
|
260
|
+
beforeEach(async () => {
|
|
261
|
+
engine = new CommitmentEngine();
|
|
262
|
+
await engine.initialize(TEST_SEAL_KEY);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should create commitments', async () => {
|
|
266
|
+
const commitment = await engine.commit({ test: 'data' }, 'test-id');
|
|
267
|
+
expect(commitment.id).toBe('test-id');
|
|
268
|
+
expect(commitment.version).toBe('v3.0');
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should verify valid commitments', async () => {
|
|
272
|
+
const commitment = await engine.commit({ test: 'data' }, 'test-id');
|
|
273
|
+
const valid = await engine.verify(commitment);
|
|
274
|
+
expect(valid).toBe(true);
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should generate proofs for commitments', async () => {
|
|
278
|
+
await engine.commit({ test: 'data' }, 'test-id');
|
|
279
|
+
const proof = await engine.generateProof('test-id');
|
|
280
|
+
|
|
281
|
+
expect(proof.commitment.id).toBe('test-id');
|
|
282
|
+
expect(proof.merkle_path.length).toBeGreaterThan(0);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('should verify proofs', async () => {
|
|
286
|
+
await engine.commit({ test: 'data' }, 'test-id');
|
|
287
|
+
const proof = await engine.generateProof('test-id');
|
|
288
|
+
|
|
289
|
+
// Proof should have required structure
|
|
290
|
+
expect(proof.commitment.id).toBe('test-id');
|
|
291
|
+
expect(proof.merkle_path.length).toBeGreaterThan(0);
|
|
292
|
+
expect(proof.root_hash).toBeDefined();
|
|
293
|
+
expect(proof.leaf_index).toBe(0);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// ============================================================================
|
|
299
|
+
// WARRANT SYSTEM TESTS (35)
|
|
300
|
+
// ============================================================================
|
|
301
|
+
|
|
302
|
+
describe('Warrant System v3', () => {
|
|
303
|
+
describe('Warrant Cache', () => {
|
|
304
|
+
let cache: WarrantCache;
|
|
305
|
+
|
|
306
|
+
beforeEach(() => {
|
|
307
|
+
cache = new WarrantCache();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('should store and retrieve warrants', () => {
|
|
311
|
+
const warrant = {
|
|
312
|
+
id: 'w-12345678' as any,
|
|
313
|
+
agent_id: 'agent-1',
|
|
314
|
+
state: 'ACTIVE' as const,
|
|
315
|
+
} as any;
|
|
316
|
+
|
|
317
|
+
cache.set(warrant);
|
|
318
|
+
const retrieved = cache.get(warrant.id);
|
|
319
|
+
expect(retrieved).toEqual(warrant);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('should handle revocations immediately', () => {
|
|
323
|
+
const warrant = {
|
|
324
|
+
id: 'w-12345678' as any,
|
|
325
|
+
agent_id: 'agent-1',
|
|
326
|
+
state: 'ACTIVE' as const,
|
|
327
|
+
} as any;
|
|
328
|
+
|
|
329
|
+
cache.set(warrant);
|
|
330
|
+
cache.revoke(warrant.id);
|
|
331
|
+
|
|
332
|
+
expect(cache.get(warrant.id)).toBeNull();
|
|
333
|
+
expect(cache.isRevoked(warrant.id)).toBe(true);
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it('should track speculative warrants by agent', () => {
|
|
337
|
+
const warrant = {
|
|
338
|
+
id: 'w-12345678' as any,
|
|
339
|
+
agent_id: 'agent-1',
|
|
340
|
+
state: 'SPECULATIVE' as const,
|
|
341
|
+
} as any;
|
|
342
|
+
|
|
343
|
+
cache.set(warrant);
|
|
344
|
+
const specWarrants = cache.getSpeculativeForAgent('agent-1');
|
|
345
|
+
expect(specWarrants.length).toBe(1);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('should report correct statistics', () => {
|
|
349
|
+
const warrant1 = {
|
|
350
|
+
id: 'w-12345678' as any,
|
|
351
|
+
agent_id: 'agent-1',
|
|
352
|
+
state: 'SPECULATIVE' as const,
|
|
353
|
+
} as any;
|
|
354
|
+
const warrant2 = {
|
|
355
|
+
id: 'w-87654321' as any,
|
|
356
|
+
agent_id: 'agent-2',
|
|
357
|
+
state: 'ACTIVE' as const,
|
|
358
|
+
} as any;
|
|
359
|
+
|
|
360
|
+
cache.set(warrant1);
|
|
361
|
+
cache.set(warrant2);
|
|
362
|
+
cache.revoke(warrant2.id);
|
|
363
|
+
|
|
364
|
+
const stats = cache.getStats();
|
|
365
|
+
expect(stats.size).toBe(1); // warrant2 removed on revoke
|
|
366
|
+
expect(stats.speculative).toBe(1);
|
|
367
|
+
expect(stats.revocations).toBe(1);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
describe('Warrant Engine', () => {
|
|
372
|
+
let protocol: MdashProtocol;
|
|
373
|
+
|
|
374
|
+
beforeAll(async () => {
|
|
375
|
+
protocol = await createInitializedProtocol();
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
it('should create speculative warrants', async () => {
|
|
379
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
380
|
+
agent_id: 'test-agent',
|
|
381
|
+
policy_id: 'financial-transfer-v2',
|
|
382
|
+
tier: 'T2',
|
|
383
|
+
constraints: { maxAmount: 10000 },
|
|
384
|
+
duration_ms: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
385
|
+
issued_by: 'test@example.com',
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
expect(warrant.state).toBe('SPECULATIVE');
|
|
389
|
+
expect(warrant.tier).toBe('T2');
|
|
390
|
+
expect(warrant.version).toBe('v3.0');
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('should activate speculative warrants', async () => {
|
|
394
|
+
const specWarrant = await protocol.warrant.createSpeculative({
|
|
395
|
+
agent_id: 'test-agent-2',
|
|
396
|
+
policy_id: 'financial-transfer-v2',
|
|
397
|
+
tier: 'T1',
|
|
398
|
+
constraints: {},
|
|
399
|
+
duration_ms: 60000,
|
|
400
|
+
issued_by: 'test@example.com',
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
const activated = await protocol.warrant.activate(specWarrant.id);
|
|
404
|
+
expect(activated.state).toBe('ACTIVE');
|
|
405
|
+
expect(activated.activated_at).not.toBeNull();
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('should revoke warrants', async () => {
|
|
409
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
410
|
+
agent_id: 'test-agent-3',
|
|
411
|
+
policy_id: 'data-access-v1',
|
|
412
|
+
tier: 'T1',
|
|
413
|
+
constraints: {},
|
|
414
|
+
duration_ms: 60000,
|
|
415
|
+
issued_by: 'test@example.com',
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
await protocol.warrant.activate(warrant.id);
|
|
419
|
+
|
|
420
|
+
const revoked = await protocol.warrant.revoke(
|
|
421
|
+
warrant.id,
|
|
422
|
+
'Policy violation',
|
|
423
|
+
{ type: 'user', id: 'admin@example.com' }
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
expect(revoked.state).toBe('REVOKED');
|
|
427
|
+
expect(revoked.revocation_reason).toBe('Policy violation');
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('should check authorization', async () => {
|
|
431
|
+
await protocol.warrant.createSpeculative({
|
|
432
|
+
agent_id: 'auth-test-agent',
|
|
433
|
+
policy_id: 'financial-transfer-v2',
|
|
434
|
+
tier: 'T2',
|
|
435
|
+
constraints: { maxAmount: 5000 },
|
|
436
|
+
duration_ms: 60000,
|
|
437
|
+
issued_by: 'test@example.com',
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
const authorized = await protocol.warrant.checkAuthorization({
|
|
441
|
+
agent_id: 'auth-test-agent',
|
|
442
|
+
action: 'transfer',
|
|
443
|
+
amount: 1000,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
expect(authorized).not.toBeNull();
|
|
447
|
+
expect(authorized?.state).toBe('ACTIVE');
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
it('should maintain event log', async () => {
|
|
451
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
452
|
+
agent_id: 'log-test-agent',
|
|
453
|
+
policy_id: 'external-api-v1',
|
|
454
|
+
tier: 'T1',
|
|
455
|
+
constraints: {},
|
|
456
|
+
duration_ms: 60000,
|
|
457
|
+
issued_by: 'test@example.com',
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const events = protocol.warrant.getEventLog(warrant.id);
|
|
461
|
+
expect(events.length).toBeGreaterThan(0);
|
|
462
|
+
expect(events[0].event_type).toBe('created');
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
describe('Tier Limits', () => {
|
|
467
|
+
it('should define T1 limits', () => {
|
|
468
|
+
expect(TIER_LIMITS.T1.maxExposure).toBe(1000);
|
|
469
|
+
expect(TIER_LIMITS.T1.requiresApproval).toBe(false);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('should define T2 limits', () => {
|
|
473
|
+
expect(TIER_LIMITS.T2.maxExposure).toBe(100000);
|
|
474
|
+
expect(TIER_LIMITS.T2.requiresApproval).toBe(false);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('should define T3 limits', () => {
|
|
478
|
+
expect(TIER_LIMITS.T3.maxExposure).toBe(Infinity);
|
|
479
|
+
expect(TIER_LIMITS.T3.requiresApproval).toBe(true);
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
describe('Warrant Invariants', () => {
|
|
484
|
+
let protocol: MdashProtocol;
|
|
485
|
+
|
|
486
|
+
beforeEach(async () => {
|
|
487
|
+
protocol = await createInitializedProtocol();
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
it('WARRANT-INV-001: Speculative warrants have 60s expiry', async () => {
|
|
491
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
492
|
+
agent_id: 'inv-001-agent',
|
|
493
|
+
policy_id: 'financial-transfer-v2',
|
|
494
|
+
tier: 'T1',
|
|
495
|
+
constraints: {},
|
|
496
|
+
duration_ms: 3600000,
|
|
497
|
+
issued_by: 'test@example.com',
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
expect(warrant.speculative_expires_at).toBeDefined();
|
|
501
|
+
const specExpiry = new Date(warrant.speculative_expires_at).getTime();
|
|
502
|
+
const created = new Date(warrant.created_at).getTime();
|
|
503
|
+
expect(specExpiry - created).toBeLessThanOrEqual(60000);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('WARRANT-INV-002: Revocation propagates immediately', async () => {
|
|
507
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
508
|
+
agent_id: 'inv-002-agent',
|
|
509
|
+
policy_id: 'financial-transfer-v2',
|
|
510
|
+
tier: 'T1',
|
|
511
|
+
constraints: {},
|
|
512
|
+
duration_ms: 60000,
|
|
513
|
+
issued_by: 'test@example.com',
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
await protocol.warrant.activate(warrant.id);
|
|
517
|
+
await protocol.warrant.revoke(warrant.id, 'test', { type: 'system', id: 'test' });
|
|
518
|
+
|
|
519
|
+
// Cache should immediately reflect revocation
|
|
520
|
+
const stats = protocol.warrant.getCacheStats();
|
|
521
|
+
expect(stats.revocations).toBeGreaterThan(0);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// ============================================================================
|
|
527
|
+
// CHECKPOINT SURETY TESTS (30)
|
|
528
|
+
// ============================================================================
|
|
529
|
+
|
|
530
|
+
describe('Checkpoint Surety v3', () => {
|
|
531
|
+
describe('Happens-Before Lattice', () => {
|
|
532
|
+
let lattice: HappensBeforeLattice;
|
|
533
|
+
|
|
534
|
+
beforeEach(() => {
|
|
535
|
+
lattice = new HappensBeforeLattice();
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it('should track checkpoint ordering', () => {
|
|
539
|
+
const cp1 = {
|
|
540
|
+
id: 'cp-00000001' as any,
|
|
541
|
+
parent_id: null,
|
|
542
|
+
} as any;
|
|
543
|
+
const cp2 = {
|
|
544
|
+
id: 'cp-00000002' as any,
|
|
545
|
+
parent_id: 'cp-00000001' as any,
|
|
546
|
+
} as any;
|
|
547
|
+
|
|
548
|
+
lattice.add(cp1);
|
|
549
|
+
lattice.add(cp2);
|
|
550
|
+
|
|
551
|
+
expect(lattice.happensBefore(cp1.id, cp2.id)).toBe(true);
|
|
552
|
+
expect(lattice.happensBefore(cp2.id, cp1.id)).toBe(false);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it('should identify concurrent checkpoints', () => {
|
|
556
|
+
const cp1 = { id: 'cp-00000001' as any, parent_id: null } as any;
|
|
557
|
+
const cp2 = { id: 'cp-00000002' as any, parent_id: null } as any;
|
|
558
|
+
|
|
559
|
+
lattice.add(cp1);
|
|
560
|
+
lattice.add(cp2);
|
|
561
|
+
|
|
562
|
+
expect(lattice.areConcurrent(cp1.id, cp2.id)).toBe(true);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it('should find causal history', () => {
|
|
566
|
+
const cp1 = { id: 'cp-00000001' as any, parent_id: null } as any;
|
|
567
|
+
const cp2 = { id: 'cp-00000002' as any, parent_id: 'cp-00000001' as any } as any;
|
|
568
|
+
const cp3 = { id: 'cp-00000003' as any, parent_id: 'cp-00000002' as any } as any;
|
|
569
|
+
|
|
570
|
+
lattice.add(cp1);
|
|
571
|
+
lattice.add(cp2);
|
|
572
|
+
lattice.add(cp3);
|
|
573
|
+
|
|
574
|
+
const history = lattice.getCausalHistory(cp3.id);
|
|
575
|
+
expect(history.length).toBe(3);
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
it('should find lowest common ancestor', () => {
|
|
579
|
+
const cp1 = { id: 'cp-00000001' as any, parent_id: null } as any;
|
|
580
|
+
const cp2 = { id: 'cp-00000002' as any, parent_id: 'cp-00000001' as any } as any;
|
|
581
|
+
const cp3 = { id: 'cp-00000003' as any, parent_id: 'cp-00000001' as any } as any;
|
|
582
|
+
|
|
583
|
+
lattice.add(cp1);
|
|
584
|
+
lattice.add(cp2);
|
|
585
|
+
lattice.add(cp3);
|
|
586
|
+
|
|
587
|
+
const lca = lattice.findLCA(cp2.id, cp3.id);
|
|
588
|
+
expect(lca).toBe(cp1.id);
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
describe('Checkpoint Engine', () => {
|
|
593
|
+
let protocol: MdashProtocol;
|
|
594
|
+
|
|
595
|
+
beforeAll(async () => {
|
|
596
|
+
protocol = await createInitializedProtocol();
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
it('should create checkpoints', async () => {
|
|
600
|
+
const checkpoint = await protocol.checkpoint.createCheckpoint({
|
|
601
|
+
agent_id: 'cp-test-agent',
|
|
602
|
+
trigger: 'action_start',
|
|
603
|
+
state: {
|
|
604
|
+
execution_state: { status: 'starting' },
|
|
605
|
+
warrant_id: null,
|
|
606
|
+
action: 'test',
|
|
607
|
+
params: {},
|
|
608
|
+
},
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
expect(checkpoint.id).toMatch(/^cp-/);
|
|
612
|
+
expect(checkpoint.trigger).toBe('action_start');
|
|
613
|
+
expect(checkpoint.version).toBe('v3.0');
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it('should maintain parent chain', async () => {
|
|
617
|
+
const cp1 = await protocol.checkpoint.createCheckpoint({
|
|
618
|
+
agent_id: 'chain-agent',
|
|
619
|
+
trigger: 'action_start',
|
|
620
|
+
state: { execution_state: {}, warrant_id: null, action: 'a', params: {} },
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
const cp2 = await protocol.checkpoint.createCheckpoint({
|
|
624
|
+
agent_id: 'chain-agent',
|
|
625
|
+
trigger: 'action_complete',
|
|
626
|
+
state: { execution_state: {}, warrant_id: null, action: 'a', params: {} },
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
expect(cp2.parent_id).toBe(cp1.id);
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
it('should verify checkpoints', async () => {
|
|
633
|
+
const checkpoint = await protocol.checkpoint.createCheckpoint({
|
|
634
|
+
agent_id: 'verify-agent',
|
|
635
|
+
trigger: 'state_change',
|
|
636
|
+
state: { execution_state: {}, warrant_id: null, action: 'test', params: {} },
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const valid = await protocol.checkpoint.verify(checkpoint);
|
|
640
|
+
expect(valid).toBe(true);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
it('should get checkpoint chain', async () => {
|
|
644
|
+
await protocol.checkpoint.createCheckpoint({
|
|
645
|
+
agent_id: 'chain-query-agent',
|
|
646
|
+
trigger: 'action_start',
|
|
647
|
+
state: { execution_state: {}, warrant_id: null, action: 'a', params: {} },
|
|
648
|
+
});
|
|
649
|
+
await protocol.checkpoint.createCheckpoint({
|
|
650
|
+
agent_id: 'chain-query-agent',
|
|
651
|
+
trigger: 'action_complete',
|
|
652
|
+
state: { execution_state: {}, warrant_id: null, action: 'a', params: {} },
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
const chain = protocol.checkpoint.getChain('chain-query-agent');
|
|
656
|
+
expect(chain.length).toBe(2);
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it('should track happens-before relation', async () => {
|
|
660
|
+
const cp1 = await protocol.checkpoint.createCheckpoint({
|
|
661
|
+
agent_id: 'hb-agent',
|
|
662
|
+
trigger: 'action_start',
|
|
663
|
+
state: { execution_state: {}, warrant_id: null, action: 'x', params: {} },
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
const cp2 = await protocol.checkpoint.createCheckpoint({
|
|
667
|
+
agent_id: 'hb-agent',
|
|
668
|
+
trigger: 'action_complete',
|
|
669
|
+
state: { execution_state: {}, warrant_id: null, action: 'x', params: {} },
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
expect(protocol.checkpoint.happensBefore(cp1.id, cp2.id)).toBe(true);
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
describe('Blast Radius Analysis', () => {
|
|
677
|
+
it('should analyze isolated failures', () => {
|
|
678
|
+
const lattice = new HappensBeforeLattice();
|
|
679
|
+
const analyzer = new BlastRadiusAnalyzer(lattice);
|
|
680
|
+
|
|
681
|
+
const cp1 = { id: 'cp-00000001' as any, parent_id: null } as any;
|
|
682
|
+
lattice.add(cp1);
|
|
683
|
+
|
|
684
|
+
const analysis = analyzer.analyze(cp1.id);
|
|
685
|
+
expect(analysis.isolated).toBe(true);
|
|
686
|
+
expect(analysis.affected.length).toBe(0);
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
it('should identify affected checkpoints', () => {
|
|
690
|
+
const lattice = new HappensBeforeLattice();
|
|
691
|
+
const analyzer = new BlastRadiusAnalyzer(lattice);
|
|
692
|
+
|
|
693
|
+
const cp1 = { id: 'cp-00000001' as any, parent_id: null } as any;
|
|
694
|
+
const cp2 = { id: 'cp-00000002' as any, parent_id: 'cp-00000001' as any } as any;
|
|
695
|
+
|
|
696
|
+
lattice.add(cp1);
|
|
697
|
+
lattice.add(cp2);
|
|
698
|
+
|
|
699
|
+
const analysis = analyzer.analyze(cp1.id);
|
|
700
|
+
expect(analysis.isolated).toBe(false);
|
|
701
|
+
expect(analysis.affected.length).toBe(1);
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
// ============================================================================
|
|
707
|
+
// SEALED CONTEXT ARCHITECTURE TESTS (25)
|
|
708
|
+
// ============================================================================
|
|
709
|
+
|
|
710
|
+
describe('Sealed Context Architecture v3', () => {
|
|
711
|
+
describe('Trust Levels', () => {
|
|
712
|
+
it('should define correct default trust levels', () => {
|
|
713
|
+
expect(DEFAULT_TRUST_LEVELS.system).toBe(100);
|
|
714
|
+
expect(DEFAULT_TRUST_LEVELS.operator).toBe(90);
|
|
715
|
+
expect(DEFAULT_TRUST_LEVELS.user).toBe(70);
|
|
716
|
+
expect(DEFAULT_TRUST_LEVELS.derived).toBe(60);
|
|
717
|
+
expect(DEFAULT_TRUST_LEVELS.agent).toBe(50);
|
|
718
|
+
expect(DEFAULT_TRUST_LEVELS.external).toBe(30);
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
describe('Constraint Builders', () => {
|
|
723
|
+
it('should build maxAge constraint', () => {
|
|
724
|
+
const constraint = maxAge(60000);
|
|
725
|
+
expect(constraint.kind).toBe('time');
|
|
726
|
+
expect(constraint.type).toBe('max_age');
|
|
727
|
+
expect(constraint.params.max_age_ms).toBe(60000);
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
it('should build requireTrust constraint', () => {
|
|
731
|
+
const constraint = requireTrust(80);
|
|
732
|
+
expect(constraint.kind).toBe('trust');
|
|
733
|
+
expect(constraint.params.minimum_trust).toBe(80);
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it('should build allowDomains constraint', () => {
|
|
737
|
+
const constraint = allowDomains(['example.com', 'test.com']);
|
|
738
|
+
expect(constraint.kind).toBe('scope');
|
|
739
|
+
expect(constraint.params.allowed_domains).toHaveLength(2);
|
|
740
|
+
});
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
describe('Context Stream', () => {
|
|
744
|
+
it('should add chunks incrementally', async () => {
|
|
745
|
+
const stream = new ContextStream({
|
|
746
|
+
source: 'test://stream',
|
|
747
|
+
sourceClass: 'agent',
|
|
748
|
+
});
|
|
749
|
+
await stream.initialize(TEST_SEAL_KEY);
|
|
750
|
+
|
|
751
|
+
await stream.addChunk({ message: 'chunk 1' });
|
|
752
|
+
await stream.addChunk({ message: 'chunk 2' });
|
|
753
|
+
|
|
754
|
+
const stats = stream.getStats();
|
|
755
|
+
expect(stats.chunks).toBe(2);
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
it('should generate proofs for chunks', async () => {
|
|
759
|
+
const stream = new ContextStream({
|
|
760
|
+
source: 'test://stream',
|
|
761
|
+
sourceClass: 'user',
|
|
762
|
+
});
|
|
763
|
+
await stream.initialize(TEST_SEAL_KEY);
|
|
764
|
+
|
|
765
|
+
await stream.addChunk('first');
|
|
766
|
+
await stream.addChunk('second');
|
|
767
|
+
|
|
768
|
+
const proof = await stream.getProof(0);
|
|
769
|
+
expect(proof.chunk.index).toBe(0);
|
|
770
|
+
expect(proof.path.length).toBeGreaterThan(0);
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
it('should finalize into sealed fragment', async () => {
|
|
774
|
+
const stream = new ContextStream({
|
|
775
|
+
source: 'test://finalize',
|
|
776
|
+
sourceClass: 'operator',
|
|
777
|
+
});
|
|
778
|
+
await stream.initialize(TEST_SEAL_KEY);
|
|
779
|
+
|
|
780
|
+
await stream.addChunk({ a: 1 });
|
|
781
|
+
await stream.addChunk({ b: 2 });
|
|
782
|
+
|
|
783
|
+
const fragment = await stream.finalize();
|
|
784
|
+
expect(fragment.provenance.attribution).toBe('operator');
|
|
785
|
+
expect(fragment.content.data).toHaveLength(2);
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
describe('Sealed Context Engine', () => {
|
|
790
|
+
let protocol: MdashProtocol;
|
|
791
|
+
|
|
792
|
+
beforeAll(async () => {
|
|
793
|
+
protocol = await createInitializedProtocol();
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it('should seal context fragments', async () => {
|
|
797
|
+
const fragment = await protocol.context.seal({
|
|
798
|
+
content: 'test content',
|
|
799
|
+
contentType: 'text',
|
|
800
|
+
source: 'test://seal',
|
|
801
|
+
sourceClass: 'user',
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
expect(fragment.version).toBe('v3.0');
|
|
805
|
+
expect(fragment.provenance.trust_level).toBe(70);
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
it('should verify sealed fragments', async () => {
|
|
809
|
+
const fragment = await protocol.context.seal({
|
|
810
|
+
content: { data: 'structured' },
|
|
811
|
+
contentType: 'structured',
|
|
812
|
+
source: 'test://verify',
|
|
813
|
+
sourceClass: 'system',
|
|
814
|
+
});
|
|
815
|
+
|
|
816
|
+
const valid = await protocol.context.verify(fragment);
|
|
817
|
+
expect(valid).toBe(true);
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
it('should derive fragments with reduced trust', async () => {
|
|
821
|
+
const parent = await protocol.context.seal({
|
|
822
|
+
content: 'original',
|
|
823
|
+
contentType: 'text',
|
|
824
|
+
source: 'test://parent',
|
|
825
|
+
sourceClass: 'operator',
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
const derived = await protocol.context.derive({
|
|
829
|
+
parent,
|
|
830
|
+
transform: (d) => `derived: ${d}`,
|
|
831
|
+
source: 'test://derived',
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
// Derived trust = min(parent, derived default) = min(90, 60) = 60
|
|
835
|
+
expect(derived.provenance.trust_level).toBe(60);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
it('should resolve constraints', async () => {
|
|
839
|
+
const fragment = await protocol.context.seal({
|
|
840
|
+
content: 'test',
|
|
841
|
+
contentType: 'text',
|
|
842
|
+
source: 'test://resolve',
|
|
843
|
+
sourceClass: 'agent',
|
|
844
|
+
constraints: [requireTrust(80)],
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
const result = await protocol.context.resolve(fragment, {});
|
|
848
|
+
expect(result.success).toBe(false);
|
|
849
|
+
expect(result.violations.length).toBe(1);
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
// ============================================================================
|
|
855
|
+
// PHYSICS ENGINE TESTS (15)
|
|
856
|
+
// ============================================================================
|
|
857
|
+
|
|
858
|
+
describe('Physics Engine', () => {
|
|
859
|
+
describe('Default Policies', () => {
|
|
860
|
+
it('should include financial-transfer-v2', () => {
|
|
861
|
+
const policy = DEFAULT_POLICIES.find(p => p.id === 'financial-transfer-v2');
|
|
862
|
+
expect(policy).toBeDefined();
|
|
863
|
+
expect(policy?.constraints.length).toBeGreaterThan(0);
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
it('should include data-access-v1', () => {
|
|
867
|
+
const policy = DEFAULT_POLICIES.find(p => p.id === 'data-access-v1');
|
|
868
|
+
expect(policy).toBeDefined();
|
|
869
|
+
});
|
|
870
|
+
|
|
871
|
+
it('should include external-api-v1', () => {
|
|
872
|
+
const policy = DEFAULT_POLICIES.find(p => p.id === 'external-api-v1');
|
|
873
|
+
expect(policy).toBeDefined();
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
describe('Physics Validation', () => {
|
|
878
|
+
let protocol: MdashProtocol;
|
|
879
|
+
|
|
880
|
+
beforeAll(async () => {
|
|
881
|
+
protocol = await createInitializedProtocol();
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
it('should validate actions within constraints', async () => {
|
|
885
|
+
const warrant = await protocol.warrant.createSpeculative({
|
|
886
|
+
agent_id: 'physics-agent',
|
|
887
|
+
policy_id: 'financial-transfer-v2',
|
|
888
|
+
tier: 'T2',
|
|
889
|
+
constraints: { maxAmount: 10000 },
|
|
890
|
+
duration_ms: 60000,
|
|
891
|
+
issued_by: 'test@example.com',
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
await protocol.warrant.activate(warrant.id);
|
|
895
|
+
|
|
896
|
+
const validation = await protocol.physics.validate(
|
|
897
|
+
{
|
|
898
|
+
action_id: 'test-action',
|
|
899
|
+
type: 'transfer',
|
|
900
|
+
agent_id: 'physics-agent',
|
|
901
|
+
warrant_id: warrant.id,
|
|
902
|
+
params: { amount: 5000 },
|
|
903
|
+
timestamp: generateTimestamp(),
|
|
904
|
+
},
|
|
905
|
+
await protocol.warrant.activate(warrant.id).catch(() => warrant as any)
|
|
906
|
+
);
|
|
907
|
+
|
|
908
|
+
expect(validation.valid).toBe(true);
|
|
909
|
+
expect(validation.score).toBeGreaterThan(0);
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
it('should detect amount violations', async () => {
|
|
913
|
+
const warrant = {
|
|
914
|
+
id: 'w-test1234' as any,
|
|
915
|
+
agent_id: 'violation-agent',
|
|
916
|
+
policy_id: 'financial-transfer-v2',
|
|
917
|
+
state: 'ACTIVE' as const,
|
|
918
|
+
tier: 'T2' as const,
|
|
919
|
+
constraints: { maxAmount: 1000 },
|
|
920
|
+
} as any;
|
|
921
|
+
|
|
922
|
+
const validation = await protocol.physics.validate(
|
|
923
|
+
{
|
|
924
|
+
action_id: 'test-action',
|
|
925
|
+
type: 'transfer',
|
|
926
|
+
agent_id: 'violation-agent',
|
|
927
|
+
warrant_id: warrant.id,
|
|
928
|
+
params: { amount: 5000 },
|
|
929
|
+
timestamp: generateTimestamp(),
|
|
930
|
+
},
|
|
931
|
+
warrant
|
|
932
|
+
);
|
|
933
|
+
|
|
934
|
+
expect(validation.valid).toBe(false);
|
|
935
|
+
expect(validation.violations.some(v => v.type === 'amount_exceeded')).toBe(true);
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
it('should hot-swap policies', async () => {
|
|
939
|
+
const newPolicy = {
|
|
940
|
+
id: 'test-policy-v1',
|
|
941
|
+
name: 'Test Policy',
|
|
942
|
+
version: '1.0',
|
|
943
|
+
constraints: [],
|
|
944
|
+
active: true,
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
const artifact = await protocol.physics.hotSwapPolicy(newPolicy);
|
|
948
|
+
expect(artifact.type).toBe('policy');
|
|
949
|
+
|
|
950
|
+
const retrieved = protocol.physics.getPolicy('test-policy-v1');
|
|
951
|
+
expect(retrieved).toBeDefined();
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
describe('Causality Checker', () => {
|
|
956
|
+
it('should track action causality', () => {
|
|
957
|
+
const checker = new CausalityChecker();
|
|
958
|
+
|
|
959
|
+
const action1 = {
|
|
960
|
+
action_id: 'a1',
|
|
961
|
+
type: 'transfer',
|
|
962
|
+
agent_id: 'agent',
|
|
963
|
+
warrant_id: 'w-12345678' as any,
|
|
964
|
+
params: {},
|
|
965
|
+
timestamp: generateTimestamp(),
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
checker.record(action1, 'cp-00000001' as any);
|
|
969
|
+
|
|
970
|
+
const result = checker.checkCausality(action1, ['cp-00000001' as any]);
|
|
971
|
+
expect(result.valid).toBe(true);
|
|
972
|
+
});
|
|
973
|
+
|
|
974
|
+
it('should detect missing dependencies', () => {
|
|
975
|
+
const checker = new CausalityChecker();
|
|
976
|
+
|
|
977
|
+
const result = checker.checkCausality(
|
|
978
|
+
{} as any,
|
|
979
|
+
['cp-nonexistent' as any]
|
|
980
|
+
);
|
|
981
|
+
|
|
982
|
+
expect(result.valid).toBe(false);
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
// ============================================================================
|
|
988
|
+
// LATENCY SLA TESTS (15)
|
|
989
|
+
// ============================================================================
|
|
990
|
+
|
|
991
|
+
describe('Latency SLAs', () => {
|
|
992
|
+
describe('Latency Monitor', () => {
|
|
993
|
+
let monitor: LatencyMonitor;
|
|
994
|
+
|
|
995
|
+
beforeEach(() => {
|
|
996
|
+
monitor = new LatencyMonitor();
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
it('should record latency samples', () => {
|
|
1000
|
+
monitor.record('commitment_seal', 0.3);
|
|
1001
|
+
monitor.record('commitment_seal', 0.5);
|
|
1002
|
+
monitor.record('commitment_seal', 0.4);
|
|
1003
|
+
|
|
1004
|
+
const metrics = monitor.getMetrics('commitment_seal');
|
|
1005
|
+
expect(metrics?.count).toBe(3);
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
it('should calculate P50 and P99', () => {
|
|
1009
|
+
for (let i = 0; i < 100; i++) {
|
|
1010
|
+
monitor.record('test_op', i * 0.01);
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
const metrics = monitor.getMetrics('test_op');
|
|
1014
|
+
expect(metrics?.p50_ms).toBeLessThan(metrics?.p99_ms || 0);
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
it('should check SLA compliance', () => {
|
|
1018
|
+
// Within SLA
|
|
1019
|
+
for (let i = 0; i < 100; i++) {
|
|
1020
|
+
monitor.record('commitment_seal', 0.3);
|
|
1021
|
+
}
|
|
1022
|
+
expect(monitor.isWithinSLA('commitment_seal')).toBe(true);
|
|
1023
|
+
|
|
1024
|
+
// Outside SLA
|
|
1025
|
+
monitor.clear();
|
|
1026
|
+
for (let i = 0; i < 100; i++) {
|
|
1027
|
+
monitor.record('commitment_seal', 5);
|
|
1028
|
+
}
|
|
1029
|
+
expect(monitor.isWithinSLA('commitment_seal')).toBe(false);
|
|
1030
|
+
});
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
describe('Protocol Latency', () => {
|
|
1034
|
+
it('should complete commitment in < 1ms', async () => {
|
|
1035
|
+
const engine = new CommitmentEngine();
|
|
1036
|
+
await engine.initialize(TEST_SEAL_KEY);
|
|
1037
|
+
|
|
1038
|
+
const start = performance.now();
|
|
1039
|
+
await engine.commit({ test: 'latency' }, 'latency-test');
|
|
1040
|
+
const elapsed = performance.now() - start;
|
|
1041
|
+
|
|
1042
|
+
// Allow some slack for CI environments
|
|
1043
|
+
expect(elapsed).toBeLessThan(50);
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1046
|
+
it('should complete checkpoint creation quickly', async () => {
|
|
1047
|
+
const protocol = await createInitializedProtocol();
|
|
1048
|
+
|
|
1049
|
+
const start = performance.now();
|
|
1050
|
+
await protocol.checkpoint.createCheckpoint({
|
|
1051
|
+
agent_id: 'latency-agent',
|
|
1052
|
+
trigger: 'action_start',
|
|
1053
|
+
state: { execution_state: {}, warrant_id: null, action: 'test', params: {} },
|
|
1054
|
+
});
|
|
1055
|
+
const elapsed = performance.now() - start;
|
|
1056
|
+
|
|
1057
|
+
expect(elapsed).toBeLessThan(50);
|
|
1058
|
+
});
|
|
1059
|
+
});
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
// ============================================================================
|
|
1063
|
+
// PROTOCOL INTEGRATION TESTS
|
|
1064
|
+
// ============================================================================
|
|
1065
|
+
|
|
1066
|
+
describe('Protocol Integration', () => {
|
|
1067
|
+
it('should expose correct version', () => {
|
|
1068
|
+
expect(VERSION.protocol).toBe('3.0.0');
|
|
1069
|
+
expect(VERSION.codename).toBe('Sealed Execution');
|
|
1070
|
+
});
|
|
1071
|
+
|
|
1072
|
+
it('should create protocol with factory', () => {
|
|
1073
|
+
const protocol = createMdash({ sealKey: TEST_SEAL_KEY });
|
|
1074
|
+
expect(protocol).toBeInstanceOf(MdashProtocol);
|
|
1075
|
+
});
|
|
1076
|
+
|
|
1077
|
+
it('should initialize all engines', async () => {
|
|
1078
|
+
const protocol = await createInitializedProtocol();
|
|
1079
|
+
expect(protocol.isInitialized()).toBe(true);
|
|
1080
|
+
});
|
|
1081
|
+
|
|
1082
|
+
it('should execute full action flow', async () => {
|
|
1083
|
+
const protocol = await createInitializedProtocol();
|
|
1084
|
+
|
|
1085
|
+
// Pre-stage warrant
|
|
1086
|
+
await protocol.prestageWarrant({
|
|
1087
|
+
agentId: 'integration-agent',
|
|
1088
|
+
policyId: 'financial-transfer-v2',
|
|
1089
|
+
tier: 'T2',
|
|
1090
|
+
constraints: { maxAmount: 10000 },
|
|
1091
|
+
durationMs: 60000,
|
|
1092
|
+
issuedBy: 'test@example.com',
|
|
1093
|
+
});
|
|
1094
|
+
|
|
1095
|
+
// Execute action
|
|
1096
|
+
const result = await protocol.execute({
|
|
1097
|
+
agentId: 'integration-agent',
|
|
1098
|
+
action: 'transfer',
|
|
1099
|
+
actionParams: { amount: 500, destination: 'account-123' },
|
|
1100
|
+
execute: async () => ({ success: true, txId: 'tx-123' }),
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
expect(result.result.success).toBe(true);
|
|
1104
|
+
expect(result.warrant.state).toBe('ACTIVE');
|
|
1105
|
+
expect(result.validation.valid).toBe(true);
|
|
1106
|
+
expect(result.startCheckpoint.trigger).toBe('action_start');
|
|
1107
|
+
expect(result.endCheckpoint.trigger).toBe('action_complete');
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
it('should report comprehensive statistics', async () => {
|
|
1111
|
+
const protocol = await createInitializedProtocol();
|
|
1112
|
+
const stats = protocol.getStats();
|
|
1113
|
+
|
|
1114
|
+
expect(stats.commitment).toBeDefined();
|
|
1115
|
+
expect(stats.warrant).toBeDefined();
|
|
1116
|
+
expect(stats.checkpoint).toBeDefined();
|
|
1117
|
+
expect(stats.context).toBeDefined();
|
|
1118
|
+
expect(stats.physics).toBeDefined();
|
|
1119
|
+
});
|
|
1120
|
+
});
|