amalgm 0.1.245 → 0.1.246

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 (157) hide show
  1. package/README.md +12 -0
  2. package/lib/cli.js +146 -8
  3. package/lib/layout.js +89 -4
  4. package/lib/shared-realtime-tunnel.js +384 -43
  5. package/lib/supervisor.js +0 -3
  6. package/package.json +2 -2
  7. package/runtime/scripts/amalgm-mcp/adapters/contract.js +197 -0
  8. package/runtime/scripts/amalgm-mcp/adapters/filesystem.js +135 -0
  9. package/runtime/scripts/amalgm-mcp/adapters/git.js +84 -0
  10. package/runtime/scripts/amalgm-mcp/adapters/index.js +43 -0
  11. package/runtime/scripts/amalgm-mcp/adapters/reference.js +31 -0
  12. package/runtime/scripts/amalgm-mcp/adapters/truth.js +19 -0
  13. package/runtime/scripts/amalgm-mcp/browser/cookie-jar.js +20 -68
  14. package/runtime/scripts/amalgm-mcp/index.js +4 -0
  15. package/runtime/scripts/amalgm-mcp/lib/layout.js +89 -4
  16. package/runtime/scripts/amalgm-mcp/observer/README.md +259 -0
  17. package/runtime/scripts/amalgm-mcp/observer/apply.js +150 -0
  18. package/runtime/scripts/amalgm-mcp/observer/continuity.js +111 -0
  19. package/runtime/scripts/amalgm-mcp/observer/edges.js +111 -0
  20. package/runtime/scripts/amalgm-mcp/observer/index.js +1146 -0
  21. package/runtime/scripts/amalgm-mcp/observer/scan.js +387 -0
  22. package/runtime/scripts/amalgm-mcp/observer/store.js +262 -0
  23. package/runtime/scripts/amalgm-mcp/observer/verify.js +200 -0
  24. package/runtime/scripts/amalgm-mcp/observer/watch.js +62 -0
  25. package/runtime/scripts/amalgm-mcp/project-context/store.js +19 -87
  26. package/runtime/scripts/amalgm-mcp/registration/classify.js +33 -0
  27. package/runtime/scripts/amalgm-mcp/registration/entity-cloud.js +456 -0
  28. package/runtime/scripts/amalgm-mcp/registration/entity-content.js +345 -0
  29. package/runtime/scripts/amalgm-mcp/registration/index.js +752 -0
  30. package/runtime/scripts/amalgm-mcp/registration/refusal.js +42 -0
  31. package/runtime/scripts/amalgm-mcp/registration/repo-followers.js +127 -0
  32. package/runtime/scripts/amalgm-mcp/registration/repo-states.js +109 -0
  33. package/runtime/scripts/amalgm-mcp/registration/service.js +310 -0
  34. package/runtime/scripts/amalgm-mcp/registration/tree.js +178 -0
  35. package/runtime/scripts/amalgm-mcp/registry/evidence.js +826 -0
  36. package/runtime/scripts/amalgm-mcp/registry/index.js +666 -0
  37. package/runtime/scripts/amalgm-mcp/registry/store.js +290 -0
  38. package/runtime/scripts/amalgm-mcp/repocard/README.md +103 -0
  39. package/runtime/scripts/amalgm-mcp/repocard/apply.js +111 -0
  40. package/runtime/scripts/amalgm-mcp/repocard/capture-worker.js +94 -0
  41. package/runtime/scripts/amalgm-mcp/repocard/capture.js +149 -0
  42. package/runtime/scripts/amalgm-mcp/repocard/follow.js +310 -0
  43. package/runtime/scripts/amalgm-mcp/repocard/git.js +48 -0
  44. package/runtime/scripts/amalgm-mcp/repocard/index.js +48 -0
  45. package/runtime/scripts/amalgm-mcp/server/local-service-router.js +2 -0
  46. package/runtime/scripts/amalgm-mcp/server/routes/entities.js +287 -0
  47. package/runtime/scripts/amalgm-mcp/server/routes/state.js +0 -13
  48. package/runtime/scripts/amalgm-mcp/state/attachments.js +11 -45
  49. package/runtime/scripts/amalgm-mcp/state/db.js +46 -215
  50. package/runtime/scripts/amalgm-mcp/state/docs.js +301 -1101
  51. package/runtime/scripts/amalgm-mcp/state/mutation-contracts.js +0 -99
  52. package/runtime/scripts/amalgm-mcp/state/mutations.js +130 -507
  53. package/runtime/scripts/amalgm-mcp/state/promotions.js +1 -21
  54. package/runtime/scripts/amalgm-mcp/state/replicas.js +13 -134
  55. package/runtime/scripts/amalgm-mcp/state/shared-rest.js +3 -46
  56. package/runtime/scripts/amalgm-mcp/tests/adapters.test.js +379 -0
  57. package/runtime/scripts/amalgm-mcp/tests/browser-cookie-cloud.test.js +0 -193
  58. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.life.test.js +449 -0
  59. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.rig.js +107 -0
  60. package/runtime/scripts/amalgm-mcp/tests/doorbell.matrix.watch.test.js +213 -0
  61. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/adapter.js +72 -0
  62. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/assert.js +497 -0
  63. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/bind.js +91 -0
  64. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/graph.js +1031 -0
  65. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/ledger.js +234 -0
  66. package/runtime/scripts/amalgm-mcp/tests/entity-oracle/referee.js +118 -0
  67. package/runtime/scripts/amalgm-mcp/tests/entity.oracle.test.js +1365 -0
  68. package/runtime/scripts/amalgm-mcp/tests/entity.registry.test.js +967 -0
  69. package/runtime/scripts/amalgm-mcp/tests/entity.rig.js +239 -0
  70. package/runtime/scripts/amalgm-mcp/tests/entity.storm.test.js +486 -0
  71. package/runtime/scripts/amalgm-mcp/tests/fake-watch.js +35 -0
  72. package/runtime/scripts/amalgm-mcp/tests/observer.links.test.js +289 -0
  73. package/runtime/scripts/amalgm-mcp/tests/observer.rig.js +103 -0
  74. package/runtime/scripts/amalgm-mcp/tests/observer.roots.test.js +505 -0
  75. package/runtime/scripts/amalgm-mcp/tests/observer.storm.test.js +389 -0
  76. package/runtime/scripts/amalgm-mcp/tests/observer.territory.test.js +845 -0
  77. package/runtime/scripts/amalgm-mcp/tests/observer.test.js +657 -0
  78. package/runtime/scripts/amalgm-mcp/tests/project-context.test.js +17 -32
  79. package/runtime/scripts/amalgm-mcp/tests/registration.service.test.js +256 -0
  80. package/runtime/scripts/amalgm-mcp/tests/registration.test.js +931 -0
  81. package/runtime/scripts/amalgm-mcp/tests/repocard.storm.test.js +284 -0
  82. package/runtime/scripts/amalgm-mcp/tests/repocard.test.js +371 -0
  83. package/runtime/scripts/amalgm-mcp/tests/repofollow.storm.test.js +435 -0
  84. package/runtime/scripts/amalgm-mcp/tests/repofollow.test.js +675 -0
  85. package/runtime/scripts/amalgm-mcp/tests/shared-tunnel-rehydration.test.js +0 -84
  86. package/runtime/scripts/amalgm-mcp/tests/state-docs.test.js +13 -376
  87. package/runtime/scripts/amalgm-mcp/tests/state-mutations.test.js +0 -309
  88. package/runtime/scripts/amalgm-mcp/tests/state-shared-replica.test.js +30 -758
  89. package/runtime/scripts/amalgm-mcp/tests/workspace-cards-store.test.js +3 -72
  90. package/runtime/scripts/amalgm-mcp/tests/workspace-cards.test.js +1 -89
  91. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint-reducer.test.js +24 -55
  92. package/runtime/scripts/amalgm-mcp/tests/workspace-checkpoint.test.js +141 -424
  93. package/runtime/scripts/amalgm-mcp/tests/workspace-object-tunnel.test.js +3 -171
  94. package/runtime/scripts/amalgm-mcp/tests/workspace-objects.test.js +7 -220
  95. package/runtime/scripts/amalgm-mcp/tests/workspace-publication-invariants.test.js +236 -179
  96. package/runtime/scripts/amalgm-mcp/tests/workspace-reducer.test.js +326 -2228
  97. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-cloud.test.js +3 -5319
  98. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-core.test.js +1 -191
  99. package/runtime/scripts/amalgm-mcp/tests/workspace-tree-store.test.js +17 -3140
  100. package/runtime/scripts/amalgm-mcp/tests/workspace-wall.test.js +740 -137
  101. package/runtime/scripts/amalgm-mcp/workspace/access-store.js +1 -5
  102. package/runtime/scripts/amalgm-mcp/workspace/card.js +11 -35
  103. package/runtime/scripts/amalgm-mcp/workspace/cards.js +14 -39
  104. package/runtime/scripts/amalgm-mcp/workspace/checkpoint.js +147 -587
  105. package/runtime/scripts/amalgm-mcp/workspace/git.js +34 -406
  106. package/runtime/scripts/amalgm-mcp/workspace/merge.js +181 -102
  107. package/runtime/scripts/amalgm-mcp/workspace/objects.js +56 -221
  108. package/runtime/scripts/amalgm-mcp/workspace/reducer.js +538 -1964
  109. package/runtime/scripts/amalgm-mcp/workspace/rest.js +28 -49
  110. package/runtime/scripts/amalgm-mcp/workspace/store.js +4 -77
  111. package/runtime/scripts/amalgm-mcp/workspace/transition.js +192 -1734
  112. package/runtime/scripts/amalgm-mcp/workspace/tree/inclusion.js +1 -7
  113. package/runtime/scripts/amalgm-mcp/workspace/tree/local-state.js +61 -73
  114. package/runtime/scripts/amalgm-mcp/workspace/tree/reducer.js +6 -51
  115. package/runtime/scripts/amalgm-mcp/workspace/tree/snapshot.js +8 -79
  116. package/runtime/scripts/amalgm-mcp/workspace/tree-cloud.js +146 -3461
  117. package/runtime/scripts/amalgm-mcp/workspace/tree-store.js +71 -899
  118. package/runtime/scripts/amalgm-mcp/workspace/wall.js +538 -370
  119. package/runtime/scripts/local-gateway.js +1 -0
  120. package/runtime/scripts/amalgm-mcp/state/doc-disk.js +0 -550
  121. package/runtime/scripts/amalgm-mcp/tests/code-project-stream.test.js +0 -399
  122. package/runtime/scripts/amalgm-mcp/tests/fixtures/code-project-stream-v2.json +0 -1
  123. package/runtime/scripts/amalgm-mcp/tests/workspace-durable.test.js +0 -24
  124. package/runtime/scripts/amalgm-mcp/tests/workspace-local-intent.test.js +0 -1999
  125. package/runtime/scripts/amalgm-mcp/tests/workspace-native-file-transaction.test.js +0 -364
  126. package/runtime/scripts/amalgm-mcp/tests/workspace-provenance.test.js +0 -185
  127. package/runtime/scripts/amalgm-mcp/tests/workspace-reducer-liveness.test.js +0 -26
  128. package/runtime/scripts/amalgm-mcp/tests/workspace-sync-stats.test.js +0 -119
  129. package/runtime/scripts/amalgm-mcp/tests/workspace-transition.test.js +0 -1446
  130. package/runtime/scripts/amalgm-mcp/workspace/content.js +0 -32
  131. package/runtime/scripts/amalgm-mcp/workspace/durable.js +0 -45
  132. package/runtime/scripts/amalgm-mcp/workspace/intent.js +0 -535
  133. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/BUILD.md +0 -31
  134. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/bin/darwin-arm64/amalgm-file-transaction +0 -0
  135. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/bin/linux-x64/amalgm-file-transaction +0 -0
  136. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/build.mjs +0 -72
  137. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/client.js +0 -165
  138. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/go.mod +0 -5
  139. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/go.sum +0 -2
  140. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/main.go +0 -2201
  141. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/manifest.json +0 -19
  142. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/move_darwin.go +0 -18
  143. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/move_linux.go +0 -18
  144. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/process_darwin.go +0 -33
  145. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/process_linux.go +0 -47
  146. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/verify.mjs +0 -43
  147. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/writers_darwin.go +0 -114
  148. package/runtime/scripts/amalgm-mcp/workspace/native-file-transaction/writers_linux.go +0 -84
  149. package/runtime/scripts/amalgm-mcp/workspace/project-stream.js +0 -771
  150. package/runtime/scripts/amalgm-mcp/workspace/provenance.js +0 -240
  151. package/runtime/scripts/amalgm-mcp/workspace/sync-stats.js +0 -240
  152. package/runtime/scripts/amalgm-mcp/workspace/tree/floor.js +0 -100
  153. package/runtime/scripts/amalgm-mcp/workspace/tree/observation-holds.js +0 -127
  154. package/runtime/scripts/amalgm-mcp/workspace/tree/path-state.js +0 -12
  155. package/runtime/scripts/amalgm-mcp/workspace/tree/root-binding.js +0 -125
  156. package/runtime/scripts/amalgm-mcp/workspace/tree/symlinks.js +0 -76
  157. package/runtime/scripts/amalgm-mcp/workspace/tree-materialization.js +0 -3766
@@ -28,8 +28,6 @@ const {
28
28
  pruneMutationJournal,
29
29
  } = require('../state/mutations');
30
30
  const { getReplicaByResourceId, registerReplica } = require('../state/replicas');
31
- const { codeProjectOrderIsDurable } = require('../state/mutation-contracts');
32
- const projectStream = require('../workspace/project-stream');
33
31
 
34
32
  const localInput = {
35
33
  channelId: 'doc:local-journal-test',
@@ -141,20 +139,6 @@ test('a lost local acknowledgement reuses the journal row and event', () => {
141
139
  listMutations({ database: db }).filter((mutation) => mutation.mutationId === localInput.mutationId).length,
142
140
  1,
143
141
  );
144
- assert.deepEqual(
145
- listMutations({
146
- database: db,
147
- localResource: localInput.localResource,
148
- }).map((mutation) => mutation.mutationId),
149
- [localInput.mutationId],
150
- );
151
- assert.deepEqual(
152
- listMutations({
153
- database: db,
154
- localResource: 'doc:unrelated-resource',
155
- }),
156
- [],
157
- );
158
142
  assert.equal(
159
143
  listEventsAfter(0).filter((event) => event.mutationId === localInput.mutationId).length,
160
144
  1,
@@ -328,169 +312,6 @@ test('the official tail reconciles a locally materialized mutation after its ack
328
312
  );
329
313
  });
330
314
 
331
- test('an early acknowledgement cannot advance past an unapplied predecessor', () => {
332
- const db = openLocalDb();
333
- const resourceId = 'shr_orderedprojectionabc';
334
- const localSecond = {
335
- ...sharedInput,
336
- channelId: `resource:${resourceId}`,
337
- sharedResourceId: resourceId,
338
- localResource: 'doc:ordered-projection-test',
339
- mutationId: 'mut_ordered_projection_02',
340
- operation: { kind: 'delta', yjs: 'ERIT' },
341
- };
342
- registerReplica({
343
- resourceId,
344
- localResource: localSecond.localResource,
345
- localPath: path.join(tempRoot, 'ordered-projection.md'),
346
- contract: localSecond.contract,
347
- schemaVersion: localSecond.schemaVersion,
348
- authorityEpoch: localSecond.authorityEpoch,
349
- appliedVersion: 0,
350
- snapshotVersion: 0,
351
- }, { database: db });
352
- commitLocalMutation(localSecond, {
353
- database: db,
354
- materialize() {},
355
- event: eventFor(localSecond),
356
- });
357
-
358
- const acknowledged = acknowledgeCloudMutation(
359
- resourceId,
360
- localSecond.mutationId,
361
- { version: 2, committedAt: '2026-07-14T18:00:20.000Z' },
362
- { database: db },
363
- );
364
- assert.equal(acknowledged.mutation.officialCloudVersion, 2);
365
- assert.equal(acknowledged.mutation.officialProjectedAt, null);
366
- assert.equal(
367
- getReplicaByResourceId(resourceId, { database: db }).appliedVersion,
368
- 0,
369
- 'an acknowledgement records order but does not claim that order was applied',
370
- );
371
-
372
- const firstEnvelope = {
373
- resourceId,
374
- authorityEpoch: 1,
375
- mutationId: 'mut_ordered_projection_01',
376
- deviceId: 'device-test-peer',
377
- baseVersion: 0,
378
- contract: localSecond.contract,
379
- schemaVersion: localSecond.schemaVersion,
380
- operationKind: 'delta',
381
- operation: { kind: 'delta', yjs: 'FBUW' },
382
- };
383
- const first = journalCloudMutation({
384
- localResource: localSecond.localResource,
385
- version: 1,
386
- committedAt: '2026-07-14T18:00:19.000Z',
387
- envelope: firstEnvelope,
388
- }, { database: db });
389
- completeMaterializedMutation(
390
- first.mutation.channelId,
391
- first.mutation.mutationId,
392
- eventFor({
393
- ...localSecond,
394
- mutationId: firstEnvelope.mutationId,
395
- operation: firstEnvelope.operation,
396
- }),
397
- { database: db },
398
- );
399
- assert.equal(
400
- getReplicaByResourceId(resourceId, { database: db }).appliedVersion,
401
- 1,
402
- 'applying N-1 still cannot skip the acknowledged but unapplied N',
403
- );
404
-
405
- const second = journalCloudMutation({
406
- localResource: localSecond.localResource,
407
- version: 2,
408
- committedAt: '2026-07-14T18:00:20.000Z',
409
- envelope: {
410
- resourceId,
411
- authorityEpoch: localSecond.authorityEpoch,
412
- mutationId: localSecond.mutationId,
413
- deviceId: localSecond.deviceId,
414
- baseVersion: localSecond.baseCloudVersion,
415
- contract: localSecond.contract,
416
- schemaVersion: localSecond.schemaVersion,
417
- operationKind: localSecond.operationKind,
418
- operation: localSecond.operation,
419
- },
420
- }, { database: db });
421
- assert.equal(second.alreadyApplied, true);
422
- assert.ok(second.mutation.officialProjectedAt);
423
- assert.equal(getReplicaByResourceId(resourceId, { database: db }).appliedVersion, 2);
424
- assert.equal(
425
- listEventsAfter(0).filter((event) => (
426
- event.resource === localSecond.localResource
427
- && event.mutationId === localSecond.mutationId
428
- )).length,
429
- 1,
430
- 'the official confirmation does not replay an already-local non-code write',
431
- );
432
- });
433
-
434
- test('a code publication is either fully outbox-ready or absent after a SQLite abort', () => {
435
- const db = openLocalDb();
436
- const resourceId = '018f0000-0000-7000-8000-000000000061';
437
- const input = {
438
- channelId: `resource:${resourceId}`,
439
- localResource: `${projectStream.LOCAL_RESOURCE_PREFIX}${resourceId}`,
440
- sharedResourceId: resourceId,
441
- mutationId: 'mut_code_atomic_commit_01',
442
- deviceId: 'device-code-atomic',
443
- authorityEpoch: 1,
444
- baseCloudVersion: 0,
445
- contract: projectStream.STREAM_CONTRACT,
446
- schemaVersion: 2,
447
- operationKind: 'code.publish',
448
- operation: {
449
- kind: 'code.publish',
450
- project: resourceId,
451
- delta: { kind: 'test-only' },
452
- },
453
- };
454
- const event = {
455
- resource: input.localResource,
456
- op: 'update',
457
- id: path.join(tempRoot, 'atomic-code.json'),
458
- source: 'test:code-atomic',
459
- };
460
- db.exec(`
461
- CREATE TRIGGER abort_code_atomic_commit
462
- BEFORE UPDATE OF mutation_state ON mutation_journal
463
- WHEN NEW.mutation_id = 'mut_code_atomic_commit_01'
464
- AND NEW.mutation_state = 'saved-local'
465
- BEGIN
466
- SELECT RAISE(ABORT, 'simulated SQLite abort');
467
- END;
468
- `);
469
-
470
- assert.throws(
471
- () => commitLocalMutation(input, { database: db, event }),
472
- /simulated SQLite abort/,
473
- );
474
- assert.equal(
475
- getMutation(input.channelId, input.mutationId, { database: db }),
476
- null,
477
- 'the journal insert rolls back with the outbox-ready update',
478
- );
479
- assert.equal(
480
- listEventsAfter(0).filter((entry) => entry.mutationId === input.mutationId).length,
481
- 0,
482
- );
483
-
484
- db.exec('DROP TRIGGER abort_code_atomic_commit');
485
- const retried = commitLocalMutation(input, { database: db, event });
486
- assert.equal(retried.mutation.state, 'saved-local');
487
- assert.ok(retried.mutation.eventSeq);
488
- assert.equal(
489
- listEventsAfter(0).filter((entry) => entry.mutationId === input.mutationId).length,
490
- 1,
491
- );
492
- });
493
-
494
315
  test('retention deletes only completed rows and preserves unresolved cloud work', () => {
495
316
  const db = openLocalDb();
496
317
  const pendingInput = {
@@ -523,133 +344,3 @@ test('retention deletes only completed rows and preserves unresolved cloud work'
523
344
  assert.equal(getMutation(pendingInput.channelId, pendingInput.mutationId, { database: db }).state, 'saved-local');
524
345
  assert.equal(getMutation(rejectedInput.channelId, rejectedInput.mutationId, { database: db }).state, 'rejected');
525
346
  });
526
-
527
- test('retention keeps a code mutation until its official fold has another durable recovery fact', () => {
528
- const db = openLocalDb();
529
- const resourceId = '018f0000-0000-7000-8000-000000000060';
530
- const file = path.join(tempRoot, 'code-prune-guard.json');
531
- const mutationId = 'mut_code_prune_guard_01';
532
- const deviceId = 'device-code-prune';
533
- const oid = 'a'.repeat(40);
534
- const chunks = [{ sha256: 'b'.repeat(64), bytes: 1 }];
535
- const bundle = {
536
- kind: 'bundle',
537
- contract: projectStream.BUNDLE_CONTRACT,
538
- resourceId,
539
- oid,
540
- ref: `refs/amalgm/exports/${oid}`,
541
- checksum: require('crypto').createHash('sha256').update(JSON.stringify(chunks)).digest('hex'),
542
- bytes: 1,
543
- chunks,
544
- };
545
- const operation = {
546
- kind: 'code.publish',
547
- project: resourceId,
548
- delta: {
549
- kind: 'card.set',
550
- card: projectStream.CARD_CONTRACT,
551
- head: { branch: 'main', oid, detached: false },
552
- objects: bundle,
553
- branches: [{ name: 'main', oid, objects: bundle }],
554
- checkpoint: {
555
- checkpoint: projectStream.CHECKPOINT_CONTRACT,
556
- baseOid: oid,
557
- branch: 'main',
558
- value: { revision: null, indexDiff: '', worktreeDiff: '' },
559
- },
560
- },
561
- };
562
- const input = {
563
- channelId: `resource:${resourceId}`,
564
- localResource: `${projectStream.LOCAL_RESOURCE_PREFIX}${resourceId}`,
565
- sharedResourceId: resourceId,
566
- mutationId,
567
- deviceId,
568
- authorityEpoch: 1,
569
- baseCloudVersion: 0,
570
- contract: projectStream.STREAM_CONTRACT,
571
- schemaVersion: 2,
572
- operationKind: 'code.publish',
573
- operation,
574
- };
575
- projectStream.writeSnapshot(file, projectStream._test.emptySnapshot(resourceId));
576
- registerReplica({
577
- resourceId,
578
- localResource: input.localResource,
579
- localPath: file,
580
- contract: input.contract,
581
- schemaVersion: input.schemaVersion,
582
- authorityEpoch: input.authorityEpoch,
583
- appliedVersion: 0,
584
- snapshotVersion: 0,
585
- }, { database: db });
586
- commitLocalMutation(input, {
587
- database: db,
588
- event: {
589
- resource: input.localResource,
590
- op: 'update',
591
- id: file,
592
- source: 'test:code-project-outbox',
593
- },
594
- });
595
- const claimed = claimCloudMutations({ database: db })
596
- .find((entry) => entry.mutation.mutationId === mutationId);
597
- acknowledgeCloudMutation(
598
- resourceId,
599
- mutationId,
600
- { version: 1, committedAt: '2026-07-14T19:00:01.000Z' },
601
- { database: db },
602
- );
603
- db.prepare('UPDATE mutation_journal SET updated_at = ? WHERE mutation_id = ?')
604
- .run('2026-07-13T00:00:00.000Z', mutationId);
605
-
606
- pruneMutationJournal({
607
- database: db,
608
- cutoffIso: '2026-07-14T00:00:00.000Z',
609
- batchSize: 100,
610
- });
611
- assert.ok(
612
- getMutation(input.channelId, mutationId, { database: db }),
613
- 'the journal remains while it is the only durable copy of the official number',
614
- );
615
- assert.equal(projectStream.readSnapshot(file, resourceId).version, 0);
616
-
617
- projectStream.applyCloudMutation({
618
- version: 1,
619
- committedAt: '2026-07-14T19:00:01.000Z',
620
- envelope: claimed.envelope,
621
- }, { database: db });
622
- const journalRow = db.prepare(
623
- 'SELECT * FROM mutation_journal WHERE mutation_id = ?',
624
- ).get(mutationId);
625
- const canonicalSnapshot = projectStream.readSnapshot(file, resourceId);
626
- assert.equal(
627
- codeProjectOrderIsDurable(journalRow, { database: db, snapshotCache: new Map() }),
628
- true,
629
- );
630
- fs.writeFileSync(file, `${JSON.stringify({
631
- schemaVersion: 2,
632
- project: resourceId,
633
- version: 1,
634
- card: null,
635
- checkpoint: null,
636
- })}\n`);
637
- assert.equal(
638
- codeProjectOrderIsDurable(journalRow, { database: db, snapshotCache: new Map() }),
639
- false,
640
- 'snapshot-shaped JSON is not a canonical verified official snapshot',
641
- );
642
- projectStream.writeSnapshot(file, canonicalSnapshot);
643
- db.prepare('UPDATE mutation_journal SET updated_at = ? WHERE mutation_id = ?')
644
- .run('2026-07-13T00:00:00.000Z', mutationId);
645
- pruneMutationJournal({
646
- database: db,
647
- cutoffIso: '2026-07-14T00:00:00.000Z',
648
- batchSize: 100,
649
- });
650
- assert.ok(
651
- getMutation(input.channelId, mutationId, { database: db }),
652
- 'an unbound snapshot alone cannot replace the local folded-intent recovery fact',
653
- );
654
- assert.equal(projectStream.readSnapshot(file, resourceId).version, 1);
655
- });