@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.
Files changed (55) hide show
  1. package/README.md +278 -0
  2. package/dist/checkpoint/engine.d.ts +208 -0
  3. package/dist/checkpoint/engine.d.ts.map +1 -0
  4. package/dist/checkpoint/engine.js +369 -0
  5. package/dist/checkpoint/engine.js.map +1 -0
  6. package/dist/context/engine.d.ts +197 -0
  7. package/dist/context/engine.d.ts.map +1 -0
  8. package/dist/context/engine.js +392 -0
  9. package/dist/context/engine.js.map +1 -0
  10. package/dist/core/commitment.d.ts +154 -0
  11. package/dist/core/commitment.d.ts.map +1 -0
  12. package/dist/core/commitment.js +305 -0
  13. package/dist/core/commitment.js.map +1 -0
  14. package/dist/core/crypto.d.ts +100 -0
  15. package/dist/core/crypto.d.ts.map +1 -0
  16. package/dist/core/crypto.js +243 -0
  17. package/dist/core/crypto.js.map +1 -0
  18. package/dist/index.d.ts +121 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +234 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/mcca/engine.d.ts +260 -0
  23. package/dist/mcca/engine.d.ts.map +1 -0
  24. package/dist/mcca/engine.js +518 -0
  25. package/dist/mcca/engine.js.map +1 -0
  26. package/dist/physics/engine.d.ts +165 -0
  27. package/dist/physics/engine.d.ts.map +1 -0
  28. package/dist/physics/engine.js +371 -0
  29. package/dist/physics/engine.js.map +1 -0
  30. package/dist/tee/engine.d.ts +285 -0
  31. package/dist/tee/engine.d.ts.map +1 -0
  32. package/dist/tee/engine.js +505 -0
  33. package/dist/tee/engine.js.map +1 -0
  34. package/dist/warrant/engine.d.ts +195 -0
  35. package/dist/warrant/engine.d.ts.map +1 -0
  36. package/dist/warrant/engine.js +409 -0
  37. package/dist/warrant/engine.js.map +1 -0
  38. package/dist/zk/engine.d.ts +243 -0
  39. package/dist/zk/engine.d.ts.map +1 -0
  40. package/dist/zk/engine.js +489 -0
  41. package/dist/zk/engine.js.map +1 -0
  42. package/package.json +25 -0
  43. package/src/__tests__/phase1.test.ts +1120 -0
  44. package/src/__tests__/phase2-4.test.ts +898 -0
  45. package/src/checkpoint/engine.ts +532 -0
  46. package/src/context/engine.ts +598 -0
  47. package/src/core/commitment.ts +438 -0
  48. package/src/core/crypto.ts +304 -0
  49. package/src/index.ts +320 -0
  50. package/src/mcca/engine.ts +778 -0
  51. package/src/physics/engine.ts +563 -0
  52. package/src/tee/engine.ts +810 -0
  53. package/src/warrant/engine.ts +625 -0
  54. package/src/zk/engine.ts +730 -0
  55. package/tsconfig.json +21 -0
@@ -0,0 +1,532 @@
1
+ /**
2
+ * mdash v3.0 - Checkpoint Surety
3
+ *
4
+ * Event-driven checkpoints replace time-driven intervals.
5
+ * "State transition triggers seal, not time intervals."
6
+ *
7
+ * Target Latency:
8
+ * - Checkpoint creation: <0.5ms P50, <1ms P99
9
+ *
10
+ * Key Property:
11
+ * - Single action blast radius: if an action fails, only that action is affected
12
+ */
13
+
14
+ import {
15
+ Hash,
16
+ Seal,
17
+ Timestamp,
18
+ CheckpointId,
19
+ WarrantId,
20
+ generateCheckpointId,
21
+ generateTimestamp,
22
+ sha256Object,
23
+ hmacSeal,
24
+ hmacVerify,
25
+ deriveKey,
26
+ } from '../core/crypto';
27
+
28
+ import { CommitmentEngine } from '../core/commitment';
29
+
30
+ // ============================================================================
31
+ // CHECKPOINT TYPES
32
+ // ============================================================================
33
+
34
+ export type CheckpointTrigger =
35
+ | 'action_start'
36
+ | 'action_complete'
37
+ | 'state_change'
38
+ | 'constraint_check'
39
+ | 'error'
40
+ | 'recovery'
41
+ | 'manual';
42
+
43
+ export type CheckpointStatus = 'pending' | 'sealed' | 'verified' | 'failed';
44
+
45
+ export interface CheckpointState {
46
+ /** Current execution state */
47
+ execution_state: Record<string, unknown>;
48
+ /** Active warrant at checkpoint */
49
+ warrant_id: WarrantId | null;
50
+ /** Action being performed */
51
+ action: string;
52
+ /** Action parameters */
53
+ params: Record<string, unknown>;
54
+ /** Result (if action complete) */
55
+ result?: unknown;
56
+ /** Error (if failed) */
57
+ error?: string;
58
+ }
59
+
60
+ export interface Checkpoint {
61
+ /** Unique checkpoint identifier */
62
+ id: CheckpointId;
63
+ /** Agent this checkpoint belongs to */
64
+ agent_id: string;
65
+ /** Trigger that created this checkpoint */
66
+ trigger: CheckpointTrigger;
67
+ /** Current status */
68
+ status: CheckpointStatus;
69
+ /** State at checkpoint */
70
+ state: CheckpointState;
71
+ /** Parent checkpoint (for happens-before) */
72
+ parent_id: CheckpointId | null;
73
+ /** Physics validation score */
74
+ physics_score: number;
75
+ /** Timestamp of creation */
76
+ created_at: Timestamp;
77
+ /** Content hash */
78
+ hash: Hash;
79
+ /** HMAC seal */
80
+ seal: Seal;
81
+ /** L1 commitment reference */
82
+ commitment_id: string | null;
83
+ /** Protocol version */
84
+ version: 'v3.0';
85
+ }
86
+
87
+ export interface CheckpointChain {
88
+ /** Head of the chain */
89
+ head: Checkpoint;
90
+ /** Previous checkpoints */
91
+ predecessors: CheckpointId[];
92
+ /** Chain length */
93
+ length: number;
94
+ /** Chain hash (rolling) */
95
+ chain_hash: Hash;
96
+ }
97
+
98
+ // ============================================================================
99
+ // HAPPENS-BEFORE LATTICE
100
+ // ============================================================================
101
+
102
+ /**
103
+ * Lamport-style happens-before ordering for checkpoints
104
+ * Ensures causal consistency in distributed execution
105
+ */
106
+ export class HappensBeforeLattice {
107
+ private checkpoints: Map<CheckpointId, Checkpoint> = new Map();
108
+ private children: Map<CheckpointId, CheckpointId[]> = new Map();
109
+ private roots: CheckpointId[] = [];
110
+
111
+ /**
112
+ * Add a checkpoint to the lattice
113
+ */
114
+ add(checkpoint: Checkpoint): void {
115
+ this.checkpoints.set(checkpoint.id, checkpoint);
116
+
117
+ if (checkpoint.parent_id) {
118
+ const siblings = this.children.get(checkpoint.parent_id) || [];
119
+ siblings.push(checkpoint.id);
120
+ this.children.set(checkpoint.parent_id, siblings);
121
+ } else {
122
+ this.roots.push(checkpoint.id);
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Check if a happens-before b
128
+ */
129
+ happensBefore(a: CheckpointId, b: CheckpointId): boolean {
130
+ const cpB = this.checkpoints.get(b);
131
+ if (!cpB) return false;
132
+
133
+ // Walk up from b to see if we reach a
134
+ let current: CheckpointId | null = b;
135
+ while (current) {
136
+ if (current === a) return true;
137
+ const cp = this.checkpoints.get(current);
138
+ current = cp?.parent_id || null;
139
+ }
140
+
141
+ return false;
142
+ }
143
+
144
+ /**
145
+ * Check if two checkpoints are concurrent (neither happens-before the other)
146
+ */
147
+ areConcurrent(a: CheckpointId, b: CheckpointId): boolean {
148
+ return !this.happensBefore(a, b) && !this.happensBefore(b, a);
149
+ }
150
+
151
+ /**
152
+ * Get the causal history of a checkpoint
153
+ */
154
+ getCausalHistory(id: CheckpointId): Checkpoint[] {
155
+ const history: Checkpoint[] = [];
156
+ let current: CheckpointId | null = id;
157
+
158
+ while (current) {
159
+ const cp = this.checkpoints.get(current);
160
+ if (!cp) break;
161
+ history.push(cp);
162
+ current = cp.parent_id;
163
+ }
164
+
165
+ return history;
166
+ }
167
+
168
+ /**
169
+ * Get all checkpoints after a given one
170
+ */
171
+ getSuccessors(id: CheckpointId): Checkpoint[] {
172
+ const successors: Checkpoint[] = [];
173
+ const queue = this.children.get(id) || [];
174
+
175
+ while (queue.length > 0) {
176
+ const current = queue.shift()!;
177
+ const cp = this.checkpoints.get(current);
178
+ if (cp) {
179
+ successors.push(cp);
180
+ queue.push(...(this.children.get(current) || []));
181
+ }
182
+ }
183
+
184
+ return successors;
185
+ }
186
+
187
+ /**
188
+ * Find the latest common ancestor of two checkpoints
189
+ */
190
+ findLCA(a: CheckpointId, b: CheckpointId): CheckpointId | null {
191
+ const ancestorsA = new Set<CheckpointId>();
192
+ let current: CheckpointId | null = a;
193
+
194
+ while (current) {
195
+ ancestorsA.add(current);
196
+ const cp = this.checkpoints.get(current);
197
+ current = cp?.parent_id || null;
198
+ }
199
+
200
+ current = b;
201
+ while (current) {
202
+ if (ancestorsA.has(current)) {
203
+ return current;
204
+ }
205
+ const cp = this.checkpoints.get(current);
206
+ current = cp?.parent_id || null;
207
+ }
208
+
209
+ return null;
210
+ }
211
+
212
+ /**
213
+ * Get statistics
214
+ */
215
+ getStats(): { total: number; roots: number; maxDepth: number } {
216
+ let maxDepth = 0;
217
+
218
+ for (const id of this.checkpoints.keys()) {
219
+ const history = this.getCausalHistory(id);
220
+ maxDepth = Math.max(maxDepth, history.length);
221
+ }
222
+
223
+ return {
224
+ total: this.checkpoints.size,
225
+ roots: this.roots.length,
226
+ maxDepth,
227
+ };
228
+ }
229
+ }
230
+
231
+ // ============================================================================
232
+ // CHECKPOINT ENGINE
233
+ // ============================================================================
234
+
235
+ export class CheckpointEngine {
236
+ private key: CryptoKey | null = null;
237
+ private commitmentEngine: CommitmentEngine;
238
+ private lattice: HappensBeforeLattice;
239
+ private checkpoints: Map<CheckpointId, Checkpoint> = new Map();
240
+ private agentHeads: Map<string, CheckpointId> = new Map(); // Latest checkpoint per agent
241
+
242
+ constructor(commitmentEngine: CommitmentEngine) {
243
+ this.commitmentEngine = commitmentEngine;
244
+ this.lattice = new HappensBeforeLattice();
245
+ }
246
+
247
+ /**
248
+ * Initialize the engine with a seal key
249
+ */
250
+ async initialize(sealKey: string): Promise<void> {
251
+ this.key = await deriveKey(sealKey);
252
+ }
253
+
254
+ /**
255
+ * Create a checkpoint
256
+ * Target: <0.5ms P50, <1ms P99
257
+ */
258
+ async createCheckpoint(params: {
259
+ agent_id: string;
260
+ trigger: CheckpointTrigger;
261
+ state: CheckpointState;
262
+ physics_score?: number;
263
+ }): Promise<Checkpoint> {
264
+ if (!this.key) {
265
+ throw new Error('Engine not initialized. Call initialize() first.');
266
+ }
267
+
268
+ const startTime = performance.now();
269
+
270
+ const id = generateCheckpointId();
271
+ const now = generateTimestamp();
272
+ const parentId = this.agentHeads.get(params.agent_id) || null;
273
+
274
+ // Compute state hash
275
+ const hash = await sha256Object({
276
+ id,
277
+ agent_id: params.agent_id,
278
+ trigger: params.trigger,
279
+ state: params.state,
280
+ parent_id: parentId,
281
+ created_at: now,
282
+ });
283
+
284
+ // Create checkpoint data for sealing
285
+ const checkpointData = {
286
+ _v: 1,
287
+ id,
288
+ agent_id: params.agent_id,
289
+ trigger: params.trigger,
290
+ hash,
291
+ parent_id: parentId,
292
+ created_at: now,
293
+ };
294
+
295
+ // Seal the checkpoint
296
+ const seal = await hmacSeal(checkpointData, this.key);
297
+
298
+ const checkpoint: Checkpoint = {
299
+ id,
300
+ agent_id: params.agent_id,
301
+ trigger: params.trigger,
302
+ status: 'pending',
303
+ state: params.state,
304
+ parent_id: parentId,
305
+ physics_score: params.physics_score ?? 1.0,
306
+ created_at: now,
307
+ hash,
308
+ seal,
309
+ commitment_id: null,
310
+ version: 'v3.0',
311
+ };
312
+
313
+ // Commit to L1 (async, don't wait)
314
+ const commitmentId = `checkpoint:${id}`;
315
+ this.commitmentEngine.commit(checkpoint, commitmentId).then(() => {
316
+ checkpoint.commitment_id = commitmentId;
317
+ checkpoint.status = 'sealed';
318
+ });
319
+
320
+ // Store and index
321
+ this.checkpoints.set(id, checkpoint);
322
+ this.agentHeads.set(params.agent_id, id);
323
+ this.lattice.add(checkpoint);
324
+
325
+ const elapsed = performance.now() - startTime;
326
+ if (elapsed > 1) {
327
+ console.warn(`Checkpoint creation exceeded P99: ${elapsed.toFixed(2)}ms`);
328
+ }
329
+
330
+ return checkpoint;
331
+ }
332
+
333
+ /**
334
+ * Create checkpoint for action start
335
+ */
336
+ async onActionStart(params: {
337
+ agent_id: string;
338
+ warrant_id: WarrantId;
339
+ action: string;
340
+ params: Record<string, unknown>;
341
+ }): Promise<Checkpoint> {
342
+ return this.createCheckpoint({
343
+ agent_id: params.agent_id,
344
+ trigger: 'action_start',
345
+ state: {
346
+ execution_state: { status: 'starting' },
347
+ warrant_id: params.warrant_id,
348
+ action: params.action,
349
+ params: params.params,
350
+ },
351
+ });
352
+ }
353
+
354
+ /**
355
+ * Create checkpoint for action completion
356
+ */
357
+ async onActionComplete(params: {
358
+ agent_id: string;
359
+ warrant_id: WarrantId;
360
+ action: string;
361
+ params: Record<string, unknown>;
362
+ result: unknown;
363
+ physics_score: number;
364
+ }): Promise<Checkpoint> {
365
+ return this.createCheckpoint({
366
+ agent_id: params.agent_id,
367
+ trigger: 'action_complete',
368
+ state: {
369
+ execution_state: { status: 'complete' },
370
+ warrant_id: params.warrant_id,
371
+ action: params.action,
372
+ params: params.params,
373
+ result: params.result,
374
+ },
375
+ physics_score: params.physics_score,
376
+ });
377
+ }
378
+
379
+ /**
380
+ * Create checkpoint for error
381
+ */
382
+ async onError(params: {
383
+ agent_id: string;
384
+ warrant_id: WarrantId | null;
385
+ action: string;
386
+ error: string;
387
+ }): Promise<Checkpoint> {
388
+ return this.createCheckpoint({
389
+ agent_id: params.agent_id,
390
+ trigger: 'error',
391
+ state: {
392
+ execution_state: { status: 'error' },
393
+ warrant_id: params.warrant_id,
394
+ action: params.action,
395
+ params: {},
396
+ error: params.error,
397
+ },
398
+ physics_score: 0,
399
+ });
400
+ }
401
+
402
+ /**
403
+ * Verify a checkpoint
404
+ */
405
+ async verify(checkpoint: Checkpoint): Promise<boolean> {
406
+ if (!this.key) {
407
+ throw new Error('Engine not initialized. Call initialize() first.');
408
+ }
409
+
410
+ // Verify hash
411
+ const expectedHash = await sha256Object({
412
+ id: checkpoint.id,
413
+ agent_id: checkpoint.agent_id,
414
+ trigger: checkpoint.trigger,
415
+ state: checkpoint.state,
416
+ parent_id: checkpoint.parent_id,
417
+ created_at: checkpoint.created_at,
418
+ });
419
+
420
+ if (expectedHash !== checkpoint.hash) {
421
+ return false;
422
+ }
423
+
424
+ // Verify seal
425
+ const checkpointData = {
426
+ _v: 1,
427
+ id: checkpoint.id,
428
+ agent_id: checkpoint.agent_id,
429
+ trigger: checkpoint.trigger,
430
+ hash: checkpoint.hash,
431
+ parent_id: checkpoint.parent_id,
432
+ created_at: checkpoint.created_at,
433
+ };
434
+
435
+ return hmacVerify(checkpointData, checkpoint.seal, this.key);
436
+ }
437
+
438
+ /**
439
+ * Get checkpoint by ID
440
+ */
441
+ get(id: CheckpointId): Checkpoint | null {
442
+ return this.checkpoints.get(id) || null;
443
+ }
444
+
445
+ /**
446
+ * Get the latest checkpoint for an agent
447
+ */
448
+ getHead(agentId: string): Checkpoint | null {
449
+ const headId = this.agentHeads.get(agentId);
450
+ if (!headId) return null;
451
+ return this.checkpoints.get(headId) || null;
452
+ }
453
+
454
+ /**
455
+ * Get checkpoint chain for an agent
456
+ */
457
+ getChain(agentId: string, limit: number = 100): Checkpoint[] {
458
+ const headId = this.agentHeads.get(agentId);
459
+ if (!headId) return [];
460
+
461
+ return this.lattice.getCausalHistory(headId).slice(0, limit);
462
+ }
463
+
464
+ /**
465
+ * Check if checkpoint a happened before checkpoint b
466
+ */
467
+ happensBefore(a: CheckpointId, b: CheckpointId): boolean {
468
+ return this.lattice.happensBefore(a, b);
469
+ }
470
+
471
+ /**
472
+ * Get statistics
473
+ */
474
+ getStats(): {
475
+ total: number;
476
+ agents: number;
477
+ latticeStats: ReturnType<HappensBeforeLattice['getStats']>;
478
+ } {
479
+ return {
480
+ total: this.checkpoints.size,
481
+ agents: this.agentHeads.size,
482
+ latticeStats: this.lattice.getStats(),
483
+ };
484
+ }
485
+ }
486
+
487
+ // ============================================================================
488
+ // BLAST RADIUS ANALYZER
489
+ // ============================================================================
490
+
491
+ /**
492
+ * Analyzes the impact scope of a failed action
493
+ * "Single action blast radius" means failures are isolated
494
+ */
495
+ export class BlastRadiusAnalyzer {
496
+ private lattice: HappensBeforeLattice;
497
+
498
+ constructor(lattice: HappensBeforeLattice) {
499
+ this.lattice = lattice;
500
+ }
501
+
502
+ /**
503
+ * Analyze the blast radius of a failed checkpoint
504
+ * Returns affected checkpoints that depend on the failed one
505
+ */
506
+ analyze(failedId: CheckpointId): {
507
+ affected: Checkpoint[];
508
+ isolated: boolean;
509
+ recoveryPoint: CheckpointId | null;
510
+ } {
511
+ const successors = this.lattice.getSuccessors(failedId);
512
+ const history = this.lattice.getCausalHistory(failedId);
513
+
514
+ // Find the last good checkpoint (recovery point)
515
+ const failedCheckpoint = history[0];
516
+ const recoveryPoint = failedCheckpoint?.parent_id ?? null;
517
+
518
+ return {
519
+ affected: successors,
520
+ isolated: successors.length === 0,
521
+ recoveryPoint,
522
+ };
523
+ }
524
+
525
+ /**
526
+ * Check if an action can be safely retried
527
+ */
528
+ canRetry(checkpointId: CheckpointId): boolean {
529
+ const { isolated } = this.analyze(checkpointId);
530
+ return isolated;
531
+ }
532
+ }