@longarc/mdash 3.1.1 → 3.1.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.
- package/README.md +86 -23
- package/SECURITY.md +254 -0
- package/dist/accountability/engine.d.ts +27 -0
- package/dist/accountability/engine.d.ts.map +1 -0
- package/dist/accountability/engine.js +148 -0
- package/dist/accountability/engine.js.map +1 -0
- package/dist/accountability/types.d.ts +46 -0
- package/dist/accountability/types.d.ts.map +1 -0
- package/dist/accountability/types.js +8 -0
- package/dist/accountability/types.js.map +1 -0
- package/dist/checkpoint/engine.d.ts +2 -2
- package/dist/checkpoint/engine.d.ts.map +1 -1
- package/dist/checkpoint/engine.js +5 -1
- package/dist/checkpoint/engine.js.map +1 -1
- package/dist/context/compose.d.ts +62 -0
- package/dist/context/compose.d.ts.map +1 -0
- package/dist/context/compose.js +286 -0
- package/dist/context/compose.js.map +1 -0
- package/dist/context/crypto/hash.d.ts +100 -0
- package/dist/context/crypto/hash.d.ts.map +1 -0
- package/dist/context/crypto/hash.js +248 -0
- package/dist/context/crypto/hash.js.map +1 -0
- package/dist/context/crypto/hmac.d.ts +80 -0
- package/dist/context/crypto/hmac.d.ts.map +1 -0
- package/dist/context/crypto/hmac.js +192 -0
- package/dist/context/crypto/hmac.js.map +1 -0
- package/dist/context/crypto/index.d.ts +7 -0
- package/dist/context/crypto/index.d.ts.map +1 -0
- package/dist/context/crypto/index.js +7 -0
- package/dist/context/crypto/index.js.map +1 -0
- package/dist/context/engine-v3.0-backup.d.ts +197 -0
- package/dist/context/engine-v3.0-backup.d.ts.map +1 -0
- package/dist/context/engine-v3.0-backup.js +392 -0
- package/dist/context/engine-v3.0-backup.js.map +1 -0
- package/dist/context/engine.d.ts +2 -2
- package/dist/context/engine.d.ts.map +1 -1
- package/dist/context/engine.js +2 -2
- package/dist/context/engine.js.map +1 -1
- package/dist/context/fragment.d.ts +99 -0
- package/dist/context/fragment.d.ts.map +1 -0
- package/dist/context/fragment.js +316 -0
- package/dist/context/fragment.js.map +1 -0
- package/dist/context/index.d.ts +99 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +180 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/provenance.d.ts +80 -0
- package/dist/context/provenance.d.ts.map +1 -0
- package/dist/context/provenance.js +294 -0
- package/dist/context/provenance.js.map +1 -0
- package/dist/context/resolve.d.ts +106 -0
- package/dist/context/resolve.d.ts.map +1 -0
- package/dist/context/resolve.js +440 -0
- package/dist/context/resolve.js.map +1 -0
- package/dist/context/store.d.ts +156 -0
- package/dist/context/store.d.ts.map +1 -0
- package/dist/context/store.js +396 -0
- package/dist/context/store.js.map +1 -0
- package/dist/context/types.d.ts +463 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +94 -0
- package/dist/context/types.js.map +1 -0
- package/dist/context/utils/atomic.d.ts +76 -0
- package/dist/context/utils/atomic.d.ts.map +1 -0
- package/dist/context/utils/atomic.js +159 -0
- package/dist/context/utils/atomic.js.map +1 -0
- package/dist/context/utils/credit.d.ts +65 -0
- package/dist/context/utils/credit.d.ts.map +1 -0
- package/dist/context/utils/credit.js +164 -0
- package/dist/context/utils/credit.js.map +1 -0
- package/dist/context/utils/index.d.ts +13 -0
- package/dist/context/utils/index.d.ts.map +1 -0
- package/dist/context/utils/index.js +13 -0
- package/dist/context/utils/index.js.map +1 -0
- package/dist/context/utils/utility.d.ts +63 -0
- package/dist/context/utils/utility.d.ts.map +1 -0
- package/dist/context/utils/utility.js +141 -0
- package/dist/context/utils/utility.js.map +1 -0
- package/dist/core/commitment.d.ts +26 -3
- package/dist/core/commitment.d.ts.map +1 -1
- package/dist/core/commitment.js +45 -7
- package/dist/core/commitment.js.map +1 -1
- package/dist/core/crypto.d.ts +2 -0
- package/dist/core/crypto.d.ts.map +1 -1
- package/dist/core/crypto.js +12 -0
- package/dist/core/crypto.js.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -10
- package/dist/index.js.map +1 -1
- package/dist/mcca/engine.d.ts.map +1 -1
- package/dist/mcca/engine.js +5 -4
- package/dist/mcca/engine.js.map +1 -1
- package/dist/physics/engine.d.ts +3 -2
- package/dist/physics/engine.d.ts.map +1 -1
- package/dist/physics/engine.js +37 -3
- package/dist/physics/engine.js.map +1 -1
- package/dist/provenance/api-handler.d.ts +45 -0
- package/dist/provenance/api-handler.d.ts.map +1 -0
- package/dist/provenance/api-handler.js +223 -0
- package/dist/provenance/api-handler.js.map +1 -0
- package/dist/provenance/api-types.d.ts +108 -0
- package/dist/provenance/api-types.d.ts.map +1 -0
- package/dist/provenance/api-types.js +9 -0
- package/dist/provenance/api-types.js.map +1 -0
- package/dist/provenance/index.d.ts +6 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +3 -0
- package/dist/provenance/index.js.map +1 -0
- package/dist/provenance/provenance-engine.d.ts +63 -0
- package/dist/provenance/provenance-engine.d.ts.map +1 -0
- package/dist/provenance/provenance-engine.js +311 -0
- package/dist/provenance/provenance-engine.js.map +1 -0
- package/dist/provenance/types.d.ts +193 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +9 -0
- package/dist/provenance/types.js.map +1 -0
- package/dist/tee/engine.d.ts.map +1 -1
- package/dist/tee/engine.js +14 -0
- package/dist/tee/engine.js.map +1 -1
- package/dist/warrant/engine.d.ts +24 -1
- package/dist/warrant/engine.d.ts.map +1 -1
- package/dist/warrant/engine.js +76 -1
- package/dist/warrant/engine.js.map +1 -1
- package/dist/zk/engine.d.ts.map +1 -1
- package/dist/zk/engine.js +7 -4
- package/dist/zk/engine.js.map +1 -1
- package/docs/SECURITY-PATCHES.md +170 -0
- package/package.json +17 -5
- package/src/__tests__/accountability.test.ts +308 -0
- package/src/__tests__/l1-verification-modes.test.ts +424 -0
- package/src/__tests__/phase1.benchmark.test.ts +94 -0
- package/src/__tests__/phase1.test.ts +0 -77
- package/src/__tests__/phase2-4.benchmark.test.ts +60 -0
- package/src/__tests__/phase2-4.test.ts +1 -52
- package/src/__tests__/provenance/api-handler.test.ts +356 -0
- package/src/__tests__/provenance/provenance-engine.test.ts +628 -0
- package/src/__tests__/sa-2026-008.test.ts +45 -0
- package/src/__tests__/sa-2026-009.test.ts +86 -0
- package/src/__tests__/sa-2026-010.test.ts +72 -0
- package/src/__tests__/sa-2026-012.test.ts +65 -0
- package/src/__tests__/sa-2026-nfc.test.ts +40 -0
- package/src/__tests__/security.test.ts +786 -0
- package/src/accountability/engine.ts +230 -0
- package/src/accountability/types.ts +58 -0
- package/src/checkpoint/engine.ts +6 -2
- package/src/context/__tests__/caret-v0.2.0.test.ts +860 -0
- package/src/context/__tests__/integration.test.ts +356 -0
- package/src/context/compose.ts +388 -0
- package/src/context/crypto/hash.ts +277 -0
- package/src/context/crypto/hmac.ts +253 -0
- package/src/context/crypto/index.ts +29 -0
- package/src/context/engine-v3.0-backup.ts +598 -0
- package/src/context/engine.ts +2 -2
- package/src/context/fragment.ts +454 -0
- package/src/context/index.ts +427 -0
- package/src/context/provenance.ts +380 -0
- package/src/context/resolve.ts +581 -0
- package/src/context/store.ts +503 -0
- package/src/context/types.ts +679 -0
- package/src/context/utils/atomic.ts +207 -0
- package/src/context/utils/credit.ts +224 -0
- package/src/context/utils/index.ts +13 -0
- package/src/context/utils/utility.ts +200 -0
- package/src/core/commitment.ts +130 -68
- package/src/core/crypto.ts +13 -0
- package/src/index.ts +62 -10
- package/src/mcca/engine.ts +5 -4
- package/src/physics/engine.ts +42 -5
- package/src/provenance/api-handler.ts +248 -0
- package/src/provenance/api-types.ts +112 -0
- package/src/provenance/index.ts +19 -0
- package/src/provenance/provenance-engine.ts +387 -0
- package/src/provenance/types.ts +211 -0
- package/src/tee/engine.ts +16 -0
- package/src/warrant/engine.ts +89 -1
- package/src/zk/engine.ts +8 -4
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L1 Verification Modes Test Suite
|
|
3
|
+
*
|
|
4
|
+
* Tests the v3.1 verification mode extension to the Commitment Layer.
|
|
5
|
+
* Covers: claim/verified/witnessed modes, seal versioning, backwards
|
|
6
|
+
* compatibility, and cross-layer contract preservation.
|
|
7
|
+
*
|
|
8
|
+
* These tests are ADDITIVE -- no existing test files are modified.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
sha256,
|
|
15
|
+
sha256Object,
|
|
16
|
+
hmacSeal,
|
|
17
|
+
hmacVerify,
|
|
18
|
+
deriveKey,
|
|
19
|
+
isHash,
|
|
20
|
+
isSeal,
|
|
21
|
+
Hash,
|
|
22
|
+
CommitmentEngine,
|
|
23
|
+
Commitment,
|
|
24
|
+
VerificationMode,
|
|
25
|
+
} from '../index';
|
|
26
|
+
|
|
27
|
+
const TEST_SEAL_KEY = 'test-seal-key-for-mdash-v3-phase1-minimum-32-chars';
|
|
28
|
+
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// BACKWARDS COMPATIBILITY (Critical -- existing behavior preserved exactly)
|
|
31
|
+
// ============================================================================
|
|
32
|
+
|
|
33
|
+
describe('L1 Verification Modes', () => {
|
|
34
|
+
let engine: CommitmentEngine;
|
|
35
|
+
|
|
36
|
+
beforeEach(async () => {
|
|
37
|
+
engine = new CommitmentEngine();
|
|
38
|
+
await engine.initialize(TEST_SEAL_KEY);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('Backwards Compatibility', () => {
|
|
42
|
+
it('default commit() produces v3.0 commitment (no options)', async () => {
|
|
43
|
+
const commitment = await engine.commit({ test: 'data' }, 'compat-1');
|
|
44
|
+
expect(commitment.version).toBe('v3.0');
|
|
45
|
+
expect(commitment.verification_mode).toBeUndefined();
|
|
46
|
+
expect(commitment.verification_proof).toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('explicit claim mode produces v3.0 commitment', async () => {
|
|
50
|
+
const commitment = await engine.commit({ test: 'data' }, 'compat-2', {
|
|
51
|
+
mode: 'claim',
|
|
52
|
+
});
|
|
53
|
+
expect(commitment.version).toBe('v3.0');
|
|
54
|
+
expect(commitment.verification_mode).toBeUndefined();
|
|
55
|
+
expect(commitment.verification_proof).toBeUndefined();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('default commit seal matches _v:1 format exactly', async () => {
|
|
59
|
+
// Manually compute what the old code would have produced
|
|
60
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
61
|
+
const content = { test: 'backwards-compat' };
|
|
62
|
+
const commitment = await engine.commit(content, 'compat-3');
|
|
63
|
+
|
|
64
|
+
// Reconstruct _v:1 seal data
|
|
65
|
+
const v1Data = {
|
|
66
|
+
_v: 1,
|
|
67
|
+
id: 'compat-3',
|
|
68
|
+
content_hash: commitment.content_hash,
|
|
69
|
+
committed_at: commitment.committed_at,
|
|
70
|
+
};
|
|
71
|
+
const expectedSeal = await hmacSeal(v1Data, key);
|
|
72
|
+
expect(commitment.seal).toBe(expectedSeal);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('default commit verifies with the engine', async () => {
|
|
76
|
+
const commitment = await engine.commit({ test: 'data' }, 'compat-4');
|
|
77
|
+
const valid = await engine.verify(commitment);
|
|
78
|
+
expect(valid).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('default commit proof generation still works', async () => {
|
|
82
|
+
await engine.commit({ test: 'data' }, 'compat-5');
|
|
83
|
+
const proof = await engine.generateProof('compat-5');
|
|
84
|
+
expect(proof.commitment.id).toBe('compat-5');
|
|
85
|
+
expect(proof.merkle_path.length).toBeGreaterThan(0);
|
|
86
|
+
expect(proof.root_hash).toBeDefined();
|
|
87
|
+
expect(proof.leaf_index).toBe(0);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('default commit seal verification still works within proof', async () => {
|
|
91
|
+
await engine.commit({ test: 'data' }, 'compat-6');
|
|
92
|
+
const proof = await engine.generateProof('compat-6');
|
|
93
|
+
// Seal verification (the part our changes touch) works
|
|
94
|
+
const sealValid = await engine.verify(proof.commitment);
|
|
95
|
+
expect(sealValid).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// VERIFIED MODE
|
|
101
|
+
// ============================================================================
|
|
102
|
+
|
|
103
|
+
describe('Verified Mode (L1:verified)', () => {
|
|
104
|
+
it('creates v3.1 commitment with verification_mode', async () => {
|
|
105
|
+
const verificationProof = await sha256('lsh-digest-placeholder');
|
|
106
|
+
const commitment = await engine.commit({ test: 'verified' }, 'ver-1', {
|
|
107
|
+
mode: 'verified',
|
|
108
|
+
verificationProof,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
expect(commitment.version).toBe('v3.1');
|
|
112
|
+
expect(commitment.verification_mode).toBe('verified');
|
|
113
|
+
expect(commitment.verification_proof).toBe(verificationProof);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('verified commitment seal includes verification fields', async () => {
|
|
117
|
+
const key = await deriveKey(TEST_SEAL_KEY);
|
|
118
|
+
const verificationProof = await sha256('lsh-digest');
|
|
119
|
+
const commitment = await engine.commit({ test: 'verified' }, 'ver-2', {
|
|
120
|
+
mode: 'verified',
|
|
121
|
+
verificationProof,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// Reconstruct _v:2 seal data
|
|
125
|
+
const v2Data = {
|
|
126
|
+
_v: 2,
|
|
127
|
+
id: 'ver-2',
|
|
128
|
+
content_hash: commitment.content_hash,
|
|
129
|
+
committed_at: commitment.committed_at,
|
|
130
|
+
verification_mode: 'verified',
|
|
131
|
+
verification_proof: verificationProof,
|
|
132
|
+
};
|
|
133
|
+
const expectedSeal = await hmacSeal(v2Data, key);
|
|
134
|
+
expect(commitment.seal).toBe(expectedSeal);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('verified commitment verifies correctly', async () => {
|
|
138
|
+
const verificationProof = await sha256('lsh-digest');
|
|
139
|
+
const commitment = await engine.commit({ test: 'verified' }, 'ver-3', {
|
|
140
|
+
mode: 'verified',
|
|
141
|
+
verificationProof,
|
|
142
|
+
});
|
|
143
|
+
const valid = await engine.verify(commitment);
|
|
144
|
+
expect(valid).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('verified commitment with tampered proof fails verification', async () => {
|
|
148
|
+
const verificationProof = await sha256('lsh-digest');
|
|
149
|
+
const commitment = await engine.commit({ test: 'verified' }, 'ver-4', {
|
|
150
|
+
mode: 'verified',
|
|
151
|
+
verificationProof,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Tamper with the proof
|
|
155
|
+
const tampered: Commitment = {
|
|
156
|
+
...commitment,
|
|
157
|
+
verification_proof: await sha256('tampered'),
|
|
158
|
+
};
|
|
159
|
+
const valid = await engine.verify(tampered);
|
|
160
|
+
expect(valid).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('verified commitment with tampered mode fails verification', async () => {
|
|
164
|
+
const verificationProof = await sha256('lsh-digest');
|
|
165
|
+
const commitment = await engine.commit({ test: 'verified' }, 'ver-5', {
|
|
166
|
+
mode: 'verified',
|
|
167
|
+
verificationProof,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Tamper: change mode to witnessed
|
|
171
|
+
const tampered: Commitment = {
|
|
172
|
+
...commitment,
|
|
173
|
+
verification_mode: 'witnessed' as VerificationMode,
|
|
174
|
+
};
|
|
175
|
+
const valid = await engine.verify(tampered);
|
|
176
|
+
expect(valid).toBe(false);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('verified mode without proof throws', async () => {
|
|
180
|
+
await expect(
|
|
181
|
+
engine.commit({ test: 'data' }, 'ver-6', { mode: 'verified' })
|
|
182
|
+
).rejects.toThrow('Enhanced verification mode requires a verification_proof');
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('invalid mode string rejected at runtime', async () => {
|
|
186
|
+
await expect(
|
|
187
|
+
engine.commit({ test: 'data' }, 'ver-7', {
|
|
188
|
+
mode: 'admin-override' as VerificationMode,
|
|
189
|
+
})
|
|
190
|
+
).rejects.toThrow('Invalid verification mode');
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// ============================================================================
|
|
195
|
+
// WITNESSED MODE
|
|
196
|
+
// ============================================================================
|
|
197
|
+
|
|
198
|
+
describe('Witnessed Mode (L1:witnessed)', () => {
|
|
199
|
+
it('creates v3.1 commitment with witnessed mode', async () => {
|
|
200
|
+
const witnessSeal = await sha256('warden-cosign-abc');
|
|
201
|
+
const commitment = await engine.commit({ test: 'witnessed' }, 'wit-1', {
|
|
202
|
+
mode: 'witnessed',
|
|
203
|
+
verificationProof: witnessSeal,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(commitment.version).toBe('v3.1');
|
|
207
|
+
expect(commitment.verification_mode).toBe('witnessed');
|
|
208
|
+
expect(commitment.verification_proof).toBe(witnessSeal);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('witnessed commitment verifies correctly', async () => {
|
|
212
|
+
const witnessSeal = await sha256('warden-cosign');
|
|
213
|
+
const commitment = await engine.commit({ test: 'witnessed' }, 'wit-2', {
|
|
214
|
+
mode: 'witnessed',
|
|
215
|
+
verificationProof: witnessSeal,
|
|
216
|
+
});
|
|
217
|
+
const valid = await engine.verify(commitment);
|
|
218
|
+
expect(valid).toBe(true);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('witnessed mode without proof throws', async () => {
|
|
222
|
+
await expect(
|
|
223
|
+
engine.commit({ test: 'data' }, 'wit-3', { mode: 'witnessed' })
|
|
224
|
+
).rejects.toThrow('Enhanced verification mode requires a verification_proof');
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// ============================================================================
|
|
229
|
+
// CROSS-VERSION INTEGRITY
|
|
230
|
+
// ============================================================================
|
|
231
|
+
|
|
232
|
+
describe('Cross-Version Integrity', () => {
|
|
233
|
+
it('v3.0 and v3.1 commitments coexist in same engine', async () => {
|
|
234
|
+
const v30 = await engine.commit({ a: 1 }, 'cross-v30');
|
|
235
|
+
const proof = await sha256('proof');
|
|
236
|
+
const v31 = await engine.commit({ b: 2 }, 'cross-v31', {
|
|
237
|
+
mode: 'verified',
|
|
238
|
+
verificationProof: proof,
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
expect(v30.version).toBe('v3.0');
|
|
242
|
+
expect(v31.version).toBe('v3.1');
|
|
243
|
+
|
|
244
|
+
// Both verify independently
|
|
245
|
+
expect(await engine.verify(v30)).toBe(true);
|
|
246
|
+
expect(await engine.verify(v31)).toBe(true);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('v3.0 and v3.1 commitments share Merkle tree', async () => {
|
|
250
|
+
await engine.commit({ a: 1 }, 'tree-v30');
|
|
251
|
+
const proof = await sha256('proof');
|
|
252
|
+
await engine.commit({ b: 2 }, 'tree-v31', {
|
|
253
|
+
mode: 'verified',
|
|
254
|
+
verificationProof: proof,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const stats = engine.getStats();
|
|
258
|
+
expect(stats.commitments).toBe(2);
|
|
259
|
+
expect(stats.treeStats.leaves).toBe(2);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('v3.0 commitment proof still valid after v3.1 commitments added', async () => {
|
|
263
|
+
await engine.commit({ first: true }, 'order-1');
|
|
264
|
+
const proofHash = await sha256('proof');
|
|
265
|
+
await engine.commit({ second: true }, 'order-2', {
|
|
266
|
+
mode: 'verified',
|
|
267
|
+
verificationProof: proofHash,
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// v3.0 commitment still verifiable after v3.1 additions
|
|
271
|
+
const proof = await engine.generateProof('order-1');
|
|
272
|
+
expect(proof.commitment.version).toBe('v3.0');
|
|
273
|
+
// Seal verification works across versions
|
|
274
|
+
const sealValid = await engine.verify(proof.commitment);
|
|
275
|
+
expect(sealValid).toBe(true);
|
|
276
|
+
// Proof structure intact
|
|
277
|
+
expect(proof.merkle_path.length).toBeGreaterThan(0);
|
|
278
|
+
expect(proof.root_hash).toBeDefined();
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('v3.1 commitment generates valid proof structure', async () => {
|
|
282
|
+
const proofHash = await sha256('proof');
|
|
283
|
+
await engine.commit({ data: true }, 'merkle-v31', {
|
|
284
|
+
mode: 'witnessed',
|
|
285
|
+
verificationProof: proofHash,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
const proof = await engine.generateProof('merkle-v31');
|
|
289
|
+
expect(proof.commitment.version).toBe('v3.1');
|
|
290
|
+
expect(proof.commitment.verification_mode).toBe('witnessed');
|
|
291
|
+
// Seal verification works for v3.1
|
|
292
|
+
const sealValid = await engine.verify(proof.commitment);
|
|
293
|
+
expect(sealValid).toBe(true);
|
|
294
|
+
// Proof structure intact
|
|
295
|
+
expect(proof.merkle_path.length).toBeGreaterThan(0);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// ============================================================================
|
|
300
|
+
// SEAL ISOLATION (v1 and v2 seals cannot cross-verify)
|
|
301
|
+
// ============================================================================
|
|
302
|
+
|
|
303
|
+
describe('Seal Version Isolation', () => {
|
|
304
|
+
it('v3.0 seal does not verify as v3.1 commitment', async () => {
|
|
305
|
+
const commitment = await engine.commit({ test: 'data' }, 'iso-1');
|
|
306
|
+
|
|
307
|
+
// Force-upgrade to v3.1 shape without re-sealing
|
|
308
|
+
const fakeV31: Commitment = {
|
|
309
|
+
...commitment,
|
|
310
|
+
version: 'v3.1',
|
|
311
|
+
verification_mode: 'verified',
|
|
312
|
+
verification_proof: await sha256('fake-proof'),
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// Should fail: the seal was computed with _v:1, not _v:2
|
|
316
|
+
const valid = await engine.verify(fakeV31);
|
|
317
|
+
expect(valid).toBe(false);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('different verification proofs produce different seals', async () => {
|
|
321
|
+
const proof1 = await sha256('proof-a');
|
|
322
|
+
const proof2 = await sha256('proof-b');
|
|
323
|
+
|
|
324
|
+
const c1 = await engine.commit({ same: 'content' }, 'diff-seal-1', {
|
|
325
|
+
mode: 'verified',
|
|
326
|
+
verificationProof: proof1,
|
|
327
|
+
});
|
|
328
|
+
const c2 = await engine.commit({ same: 'content' }, 'diff-seal-2', {
|
|
329
|
+
mode: 'verified',
|
|
330
|
+
verificationProof: proof2,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Same content, different proofs -> different seals
|
|
334
|
+
expect(c1.seal).not.toBe(c2.seal);
|
|
335
|
+
// But same content hash
|
|
336
|
+
expect(c1.content_hash).toBe(c2.content_hash);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('same proof with different modes produces different seals', async () => {
|
|
340
|
+
const proof = await sha256('same-proof');
|
|
341
|
+
|
|
342
|
+
const verified = await engine.commit({ x: 1 }, 'mode-seal-1', {
|
|
343
|
+
mode: 'verified',
|
|
344
|
+
verificationProof: proof,
|
|
345
|
+
});
|
|
346
|
+
const witnessed = await engine.commit({ x: 1 }, 'mode-seal-2', {
|
|
347
|
+
mode: 'witnessed',
|
|
348
|
+
verificationProof: proof,
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
expect(verified.seal).not.toBe(witnessed.seal);
|
|
352
|
+
});
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ============================================================================
|
|
356
|
+
// CROSS-LAYER CONTRACT (L2/L3 interfaces unchanged)
|
|
357
|
+
// ============================================================================
|
|
358
|
+
|
|
359
|
+
describe('Cross-Layer Contract Preservation', () => {
|
|
360
|
+
it('v3.1 commitment has operationId (L2 bridge contract)', async () => {
|
|
361
|
+
const proof = await sha256('proof');
|
|
362
|
+
const commitment = await engine.commit({ test: 'bridge' }, 'bridge-1', {
|
|
363
|
+
mode: 'verified',
|
|
364
|
+
verificationProof: proof,
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// L2 AttestationBridge checks: attestation.commitment_id === commitment.operationId
|
|
368
|
+
expect(commitment.operationId).toBe('bridge-1');
|
|
369
|
+
expect(commitment.id).toBe(commitment.operationId);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('v3.1 commitment has content_hash (Merkle tree contract)', async () => {
|
|
373
|
+
const proof = await sha256('proof');
|
|
374
|
+
const commitment = await engine.commit({ test: 'merkle' }, 'merkle-1', {
|
|
375
|
+
mode: 'verified',
|
|
376
|
+
verificationProof: proof,
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
expect(isHash(commitment.content_hash)).toBe(true);
|
|
380
|
+
expect(commitment.content_hash).toHaveLength(64);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('v3.1 commitment has id (L3 reference contract)', async () => {
|
|
384
|
+
const proof = await sha256('proof');
|
|
385
|
+
const commitment = await engine.commit({ test: 'ref' }, 'ref-1', {
|
|
386
|
+
mode: 'witnessed',
|
|
387
|
+
verificationProof: proof,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// L3 ZK engine references commitments by ID
|
|
391
|
+
expect(commitment.id).toBe('ref-1');
|
|
392
|
+
expect(engine.getCommitment('ref-1')).toBeDefined();
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// ============================================================================
|
|
397
|
+
// REWARD SIGNAL COMPATIBILITY (Future training bridge)
|
|
398
|
+
// ============================================================================
|
|
399
|
+
|
|
400
|
+
describe('Reward Signal Compatibility', () => {
|
|
401
|
+
it('composite score as float in [0,1] is attestable', async () => {
|
|
402
|
+
// Simulate what Kiwi CompositeRubric will produce:
|
|
403
|
+
// A composite_score that becomes both a grade AND a reward signal
|
|
404
|
+
const evalResult = {
|
|
405
|
+
composite_score: 0.847,
|
|
406
|
+
rubric_scores: { constraint_adherence: 0.9, factual_grounding: 0.8 },
|
|
407
|
+
agent_profile_id: 'agent-001',
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const proof = await sha256('eval-verification');
|
|
411
|
+
const commitment = await engine.commit(evalResult, 'eval-1', {
|
|
412
|
+
mode: 'verified',
|
|
413
|
+
verificationProof: proof,
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
expect(await engine.verify(commitment)).toBe(true);
|
|
417
|
+
|
|
418
|
+
// The committed content_hash cryptographically binds the composite_score
|
|
419
|
+
// This same score can later serve as a GRPO reward signal
|
|
420
|
+
const expectedHash = await sha256Object(evalResult);
|
|
421
|
+
expect(commitment.content_hash).toBe(expectedHash);
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.0 Phase 1 Benchmark Tests
|
|
3
|
+
*
|
|
4
|
+
* Environment-sensitive latency SLA tests.
|
|
5
|
+
* Excluded from Lane A (merge gate). Run in Lane B with continue-on-error.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
CommitmentEngine,
|
|
12
|
+
LatencyMonitor,
|
|
13
|
+
MdashProtocol,
|
|
14
|
+
createMdash,
|
|
15
|
+
} from '../index';
|
|
16
|
+
|
|
17
|
+
const TEST_SEAL_KEY = 'test-seal-key-for-mdash-v3-phase1-minimum-32-chars';
|
|
18
|
+
|
|
19
|
+
async function createInitializedProtocol(): Promise<MdashProtocol> {
|
|
20
|
+
const protocol = createMdash({ sealKey: TEST_SEAL_KEY });
|
|
21
|
+
await protocol.initialize();
|
|
22
|
+
return protocol;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
describe('[benchmark] Latency SLAs', () => {
|
|
26
|
+
describe('Latency Monitor', () => {
|
|
27
|
+
let monitor: LatencyMonitor;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
monitor = new LatencyMonitor();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should record latency samples', () => {
|
|
34
|
+
monitor.record('commitment_seal', 0.3);
|
|
35
|
+
monitor.record('commitment_seal', 0.5);
|
|
36
|
+
monitor.record('commitment_seal', 0.4);
|
|
37
|
+
|
|
38
|
+
const metrics = monitor.getMetrics('commitment_seal');
|
|
39
|
+
expect(metrics?.count).toBe(3);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should calculate P50 and P99', () => {
|
|
43
|
+
for (let i = 0; i < 100; i++) {
|
|
44
|
+
monitor.record('test_op', i * 0.01);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const metrics = monitor.getMetrics('test_op');
|
|
48
|
+
expect(metrics?.p50_ms).toBeLessThan(metrics?.p99_ms || 0);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should check SLA compliance', () => {
|
|
52
|
+
// Within SLA
|
|
53
|
+
for (let i = 0; i < 100; i++) {
|
|
54
|
+
monitor.record('commitment_seal', 0.3);
|
|
55
|
+
}
|
|
56
|
+
expect(monitor.isWithinSLA('commitment_seal')).toBe(true);
|
|
57
|
+
|
|
58
|
+
// Outside SLA
|
|
59
|
+
monitor.clear();
|
|
60
|
+
for (let i = 0; i < 100; i++) {
|
|
61
|
+
monitor.record('commitment_seal', 5);
|
|
62
|
+
}
|
|
63
|
+
expect(monitor.isWithinSLA('commitment_seal')).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('Protocol Latency', () => {
|
|
68
|
+
it('should complete commitment in < 1ms', async () => {
|
|
69
|
+
const engine = new CommitmentEngine();
|
|
70
|
+
await engine.initialize(TEST_SEAL_KEY);
|
|
71
|
+
|
|
72
|
+
const start = performance.now();
|
|
73
|
+
await engine.commit({ test: 'latency' }, 'latency-test');
|
|
74
|
+
const elapsed = performance.now() - start;
|
|
75
|
+
|
|
76
|
+
// Allow some slack for CI environments
|
|
77
|
+
expect(elapsed).toBeLessThan(50);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should complete checkpoint creation quickly', async () => {
|
|
81
|
+
const protocol = await createInitializedProtocol();
|
|
82
|
+
|
|
83
|
+
const start = performance.now();
|
|
84
|
+
await protocol.checkpoint.createCheckpoint({
|
|
85
|
+
agent_id: 'latency-agent',
|
|
86
|
+
trigger: 'action_start',
|
|
87
|
+
state: { execution_state: {}, warrant_id: null, action: 'test', params: {} },
|
|
88
|
+
});
|
|
89
|
+
const elapsed = performance.now() - start;
|
|
90
|
+
|
|
91
|
+
expect(elapsed).toBeLessThan(50);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -38,8 +38,6 @@ import {
|
|
|
38
38
|
// Commitment Layer
|
|
39
39
|
CommitmentEngine,
|
|
40
40
|
IncrementalMerkleTree,
|
|
41
|
-
LatencyMonitor,
|
|
42
|
-
|
|
43
41
|
// Warrant System
|
|
44
42
|
WarrantEngine,
|
|
45
43
|
WarrantCache,
|
|
@@ -984,81 +982,6 @@ describe('Physics Engine', () => {
|
|
|
984
982
|
});
|
|
985
983
|
});
|
|
986
984
|
|
|
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
985
|
// ============================================================================
|
|
1063
986
|
// PROTOCOL INTEGRATION TESTS
|
|
1064
987
|
// ============================================================================
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.0 Phase 2-4 Benchmark Tests
|
|
3
|
+
*
|
|
4
|
+
* Environment-sensitive P99 latency SLA tests for L1/L2.
|
|
5
|
+
* Excluded from Lane A (merge gate). Run in Lane B with continue-on-error.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
9
|
+
import { CommitmentEngine } from '../core/commitment.js';
|
|
10
|
+
import { TEEAttestationEngine } from '../tee/engine.js';
|
|
11
|
+
|
|
12
|
+
const TEST_SEAL_KEY = 'test-seal-key-phase-2-4-v3.0.0-x';
|
|
13
|
+
|
|
14
|
+
describe('[benchmark] Latency SLA Compliance', () => {
|
|
15
|
+
let commitmentEngine: CommitmentEngine;
|
|
16
|
+
let teeEngine: TEEAttestationEngine;
|
|
17
|
+
|
|
18
|
+
beforeAll(async () => {
|
|
19
|
+
commitmentEngine = new CommitmentEngine();
|
|
20
|
+
await commitmentEngine.initialize(TEST_SEAL_KEY);
|
|
21
|
+
|
|
22
|
+
teeEngine = new TEEAttestationEngine(commitmentEngine);
|
|
23
|
+
await teeEngine.initialize(TEST_SEAL_KEY);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('L1 commitment should complete in <1ms (P99)', async () => {
|
|
27
|
+
const latencies: number[] = [];
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < 100; i++) {
|
|
30
|
+
const start = performance.now();
|
|
31
|
+
await commitmentEngine.commit({ iteration: i }, `latency-l1-${i}`);
|
|
32
|
+
latencies.push(performance.now() - start);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Sort and get P99
|
|
36
|
+
latencies.sort((a, b) => a - b);
|
|
37
|
+
const p99 = latencies[98];
|
|
38
|
+
|
|
39
|
+
// Note: In Node.js environment, actual latency may vary
|
|
40
|
+
// Target is <1ms, we allow 5ms for test stability
|
|
41
|
+
expect(p99).toBeLessThan(5);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('L2 attestation should complete in <10ms (P99)', async () => {
|
|
45
|
+
const latencies: number[] = [];
|
|
46
|
+
|
|
47
|
+
for (let i = 0; i < 50; i++) {
|
|
48
|
+
const start = performance.now();
|
|
49
|
+
await teeEngine.attest({ iteration: i }, `latency-l2-${i}`);
|
|
50
|
+
latencies.push(performance.now() - start);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Sort and get P99
|
|
54
|
+
latencies.sort((a, b) => a - b);
|
|
55
|
+
const p99 = latencies[Math.floor(latencies.length * 0.99)];
|
|
56
|
+
|
|
57
|
+
// Target is <10ms, we allow 50ms for test stability
|
|
58
|
+
expect(p99).toBeLessThan(50);
|
|
59
|
+
});
|
|
60
|
+
});
|