@longarc/mdash 3.1.2 → 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.
Files changed (172) hide show
  1. package/README.md +86 -23
  2. package/SECURITY.md +254 -0
  3. package/dist/accountability/engine.d.ts +27 -0
  4. package/dist/accountability/engine.d.ts.map +1 -0
  5. package/dist/accountability/engine.js +148 -0
  6. package/dist/accountability/engine.js.map +1 -0
  7. package/dist/accountability/types.d.ts +46 -0
  8. package/dist/accountability/types.d.ts.map +1 -0
  9. package/dist/accountability/types.js +8 -0
  10. package/dist/accountability/types.js.map +1 -0
  11. package/dist/checkpoint/engine.d.ts.map +1 -1
  12. package/dist/checkpoint/engine.js +4 -0
  13. package/dist/checkpoint/engine.js.map +1 -1
  14. package/dist/context/compose.d.ts +62 -0
  15. package/dist/context/compose.d.ts.map +1 -0
  16. package/dist/context/compose.js +286 -0
  17. package/dist/context/compose.js.map +1 -0
  18. package/dist/context/crypto/hash.d.ts +100 -0
  19. package/dist/context/crypto/hash.d.ts.map +1 -0
  20. package/dist/context/crypto/hash.js +248 -0
  21. package/dist/context/crypto/hash.js.map +1 -0
  22. package/dist/context/crypto/hmac.d.ts +80 -0
  23. package/dist/context/crypto/hmac.d.ts.map +1 -0
  24. package/dist/context/crypto/hmac.js +192 -0
  25. package/dist/context/crypto/hmac.js.map +1 -0
  26. package/dist/context/crypto/index.d.ts +7 -0
  27. package/dist/context/crypto/index.d.ts.map +1 -0
  28. package/dist/context/crypto/index.js +7 -0
  29. package/dist/context/crypto/index.js.map +1 -0
  30. package/dist/context/engine-v3.0-backup.d.ts +197 -0
  31. package/dist/context/engine-v3.0-backup.d.ts.map +1 -0
  32. package/dist/context/engine-v3.0-backup.js +392 -0
  33. package/dist/context/engine-v3.0-backup.js.map +1 -0
  34. package/dist/context/fragment.d.ts +99 -0
  35. package/dist/context/fragment.d.ts.map +1 -0
  36. package/dist/context/fragment.js +316 -0
  37. package/dist/context/fragment.js.map +1 -0
  38. package/dist/context/index.d.ts +99 -0
  39. package/dist/context/index.d.ts.map +1 -0
  40. package/dist/context/index.js +180 -0
  41. package/dist/context/index.js.map +1 -0
  42. package/dist/context/provenance.d.ts +80 -0
  43. package/dist/context/provenance.d.ts.map +1 -0
  44. package/dist/context/provenance.js +294 -0
  45. package/dist/context/provenance.js.map +1 -0
  46. package/dist/context/resolve.d.ts +106 -0
  47. package/dist/context/resolve.d.ts.map +1 -0
  48. package/dist/context/resolve.js +440 -0
  49. package/dist/context/resolve.js.map +1 -0
  50. package/dist/context/store.d.ts +156 -0
  51. package/dist/context/store.d.ts.map +1 -0
  52. package/dist/context/store.js +396 -0
  53. package/dist/context/store.js.map +1 -0
  54. package/dist/context/types.d.ts +463 -0
  55. package/dist/context/types.d.ts.map +1 -0
  56. package/dist/context/types.js +94 -0
  57. package/dist/context/types.js.map +1 -0
  58. package/dist/context/utils/atomic.d.ts +76 -0
  59. package/dist/context/utils/atomic.d.ts.map +1 -0
  60. package/dist/context/utils/atomic.js +159 -0
  61. package/dist/context/utils/atomic.js.map +1 -0
  62. package/dist/context/utils/credit.d.ts +65 -0
  63. package/dist/context/utils/credit.d.ts.map +1 -0
  64. package/dist/context/utils/credit.js +164 -0
  65. package/dist/context/utils/credit.js.map +1 -0
  66. package/dist/context/utils/index.d.ts +13 -0
  67. package/dist/context/utils/index.d.ts.map +1 -0
  68. package/dist/context/utils/index.js +13 -0
  69. package/dist/context/utils/index.js.map +1 -0
  70. package/dist/context/utils/utility.d.ts +63 -0
  71. package/dist/context/utils/utility.d.ts.map +1 -0
  72. package/dist/context/utils/utility.js +141 -0
  73. package/dist/context/utils/utility.js.map +1 -0
  74. package/dist/core/commitment.d.ts +25 -2
  75. package/dist/core/commitment.d.ts.map +1 -1
  76. package/dist/core/commitment.js +44 -6
  77. package/dist/core/commitment.js.map +1 -1
  78. package/dist/core/crypto.d.ts +2 -0
  79. package/dist/core/crypto.d.ts.map +1 -1
  80. package/dist/core/crypto.js +12 -0
  81. package/dist/core/crypto.js.map +1 -1
  82. package/dist/index.d.ts +11 -6
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +35 -10
  85. package/dist/index.js.map +1 -1
  86. package/dist/mcca/engine.d.ts.map +1 -1
  87. package/dist/mcca/engine.js +5 -4
  88. package/dist/mcca/engine.js.map +1 -1
  89. package/dist/physics/engine.d.ts +1 -0
  90. package/dist/physics/engine.d.ts.map +1 -1
  91. package/dist/physics/engine.js +36 -2
  92. package/dist/physics/engine.js.map +1 -1
  93. package/dist/provenance/api-handler.d.ts +45 -0
  94. package/dist/provenance/api-handler.d.ts.map +1 -0
  95. package/dist/provenance/api-handler.js +223 -0
  96. package/dist/provenance/api-handler.js.map +1 -0
  97. package/dist/provenance/api-types.d.ts +108 -0
  98. package/dist/provenance/api-types.d.ts.map +1 -0
  99. package/dist/provenance/api-types.js +9 -0
  100. package/dist/provenance/api-types.js.map +1 -0
  101. package/dist/provenance/index.d.ts +6 -0
  102. package/dist/provenance/index.d.ts.map +1 -0
  103. package/dist/provenance/index.js +3 -0
  104. package/dist/provenance/index.js.map +1 -0
  105. package/dist/provenance/provenance-engine.d.ts +63 -0
  106. package/dist/provenance/provenance-engine.d.ts.map +1 -0
  107. package/dist/provenance/provenance-engine.js +311 -0
  108. package/dist/provenance/provenance-engine.js.map +1 -0
  109. package/dist/provenance/types.d.ts +193 -0
  110. package/dist/provenance/types.d.ts.map +1 -0
  111. package/dist/provenance/types.js +9 -0
  112. package/dist/provenance/types.js.map +1 -0
  113. package/dist/tee/engine.d.ts.map +1 -1
  114. package/dist/tee/engine.js +14 -0
  115. package/dist/tee/engine.js.map +1 -1
  116. package/dist/warrant/engine.d.ts +24 -1
  117. package/dist/warrant/engine.d.ts.map +1 -1
  118. package/dist/warrant/engine.js +76 -1
  119. package/dist/warrant/engine.js.map +1 -1
  120. package/dist/zk/engine.d.ts.map +1 -1
  121. package/dist/zk/engine.js +7 -4
  122. package/dist/zk/engine.js.map +1 -1
  123. package/docs/SECURITY-PATCHES.md +170 -0
  124. package/package.json +17 -5
  125. package/src/__tests__/accountability.test.ts +308 -0
  126. package/src/__tests__/l1-verification-modes.test.ts +424 -0
  127. package/src/__tests__/phase1.benchmark.test.ts +94 -0
  128. package/src/__tests__/phase1.test.ts +0 -77
  129. package/src/__tests__/phase2-4.benchmark.test.ts +60 -0
  130. package/src/__tests__/phase2-4.test.ts +1 -52
  131. package/src/__tests__/provenance/api-handler.test.ts +356 -0
  132. package/src/__tests__/provenance/provenance-engine.test.ts +628 -0
  133. package/src/__tests__/sa-2026-008.test.ts +45 -0
  134. package/src/__tests__/sa-2026-009.test.ts +86 -0
  135. package/src/__tests__/sa-2026-010.test.ts +72 -0
  136. package/src/__tests__/sa-2026-012.test.ts +65 -0
  137. package/src/__tests__/sa-2026-nfc.test.ts +40 -0
  138. package/src/__tests__/security.test.ts +786 -0
  139. package/src/accountability/engine.ts +230 -0
  140. package/src/accountability/types.ts +58 -0
  141. package/src/checkpoint/engine.ts +4 -0
  142. package/src/context/__tests__/caret-v0.2.0.test.ts +860 -0
  143. package/src/context/__tests__/integration.test.ts +356 -0
  144. package/src/context/compose.ts +388 -0
  145. package/src/context/crypto/hash.ts +277 -0
  146. package/src/context/crypto/hmac.ts +253 -0
  147. package/src/context/crypto/index.ts +29 -0
  148. package/src/context/engine-v3.0-backup.ts +598 -0
  149. package/src/context/fragment.ts +454 -0
  150. package/src/context/index.ts +427 -0
  151. package/src/context/provenance.ts +380 -0
  152. package/src/context/resolve.ts +581 -0
  153. package/src/context/store.ts +503 -0
  154. package/src/context/types.ts +679 -0
  155. package/src/context/utils/atomic.ts +207 -0
  156. package/src/context/utils/credit.ts +224 -0
  157. package/src/context/utils/index.ts +13 -0
  158. package/src/context/utils/utility.ts +200 -0
  159. package/src/core/commitment.ts +129 -67
  160. package/src/core/crypto.ts +13 -0
  161. package/src/index.ts +62 -10
  162. package/src/mcca/engine.ts +5 -4
  163. package/src/physics/engine.ts +40 -3
  164. package/src/provenance/api-handler.ts +248 -0
  165. package/src/provenance/api-types.ts +112 -0
  166. package/src/provenance/index.ts +19 -0
  167. package/src/provenance/provenance-engine.ts +387 -0
  168. package/src/provenance/types.ts +211 -0
  169. package/src/tee/engine.ts +16 -0
  170. package/src/warrant/engine.ts +89 -1
  171. package/src/zk/engine.ts +8 -4
  172. 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
+ });