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
@@ -16,8 +16,6 @@ const { cachedStatement, openLocalDb } = require('./db');
16
16
  const { insertStateEvent, publishStateEvent } = require('./events');
17
17
  const {
18
18
  diagnosticOperation,
19
- mutationNeedsOfficialMaterialization,
20
- mutationNeedsOrderedEcho,
21
19
  protectOperation,
22
20
  revealOperation,
23
21
  } = require('./mutation-contracts');
@@ -176,12 +174,10 @@ function normalizeJournalRow(row, options = {}) {
176
174
  state: row.mutation_state,
177
175
  localRevision: row.local_revision == null ? null : Number(row.local_revision),
178
176
  materializedAt: row.materialized_at || null,
179
- officialProjectedAt: row.official_projected_at || null,
180
177
  eventSeq: row.event_seq == null ? null : Number(row.event_seq),
181
178
  attemptCount: Number(row.attempt_count || 0),
182
179
  nextAttemptAt: row.next_attempt_at || null,
183
180
  lastError: row.last_error || null,
184
- failureCode: row.failure_code || null,
185
181
  cloudCommittedAt: row.cloud_committed_at || null,
186
182
  createdAt: row.created_at,
187
183
  updatedAt: row.updated_at,
@@ -228,67 +224,66 @@ function sameCloudEnvelope(existing, mutation) {
228
224
  && JSON.stringify(existingOperation) === mutation.operationJson;
229
225
  }
230
226
 
231
- function journalNormalizedMutation(database, mutation, persist = null) {
232
- const existing = getMutationRow(database, mutation.channelId, mutation.mutationId);
233
- if (existing) {
234
- if (!sameMutation(existing, mutation)) {
235
- throw invalid(
236
- `mutationId ${mutation.mutationId} was reused with different content`,
237
- 409,
238
- );
239
- }
240
- return { mutation: normalizeJournalRow(existing), duplicate: true };
241
- }
242
-
243
- if (persist) persist(database, mutation);
244
-
245
- const info = cachedStatement(database, `
246
- INSERT INTO mutation_journal (
247
- channel_id,
248
- local_resource,
249
- shared_resource_id,
250
- mutation_id,
251
- device_id,
252
- authority_epoch,
253
- base_cloud_version,
254
- contract,
255
- schema_version,
256
- operation_kind,
257
- operation_json,
258
- mutation_origin,
259
- mutation_state,
260
- local_revision
261
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'local', 'saving-local', ?)
262
- `).run(
263
- mutation.channelId,
264
- mutation.localResource,
265
- mutation.sharedResourceId,
266
- mutation.mutationId,
267
- mutation.deviceId,
268
- mutation.authorityEpoch,
269
- mutation.baseCloudVersion,
270
- mutation.contract,
271
- mutation.schemaVersion,
272
- mutation.operationKind,
273
- JSON.stringify(protectOperation(mutation.contract, mutation.operation)),
274
- mutation.localRevision,
275
- );
276
-
277
- const row = cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
278
- .get(Number(info.lastInsertRowid));
279
- trace('journal', {
280
- mutationId: mutation.mutationId,
281
- channel: mutation.channelId,
282
- shared: mutation.sharedResourceId,
283
- });
284
- return { mutation: normalizeJournalRow(row), duplicate: false };
285
- }
286
-
287
227
  function journalMutation(input, options = {}) {
288
228
  const mutation = normalizeMutationInput(input);
289
229
  const database = options.database || openLocalDb();
290
230
  const persist = typeof options.persist === 'function' ? options.persist : null;
291
- return database.transaction(() => journalNormalizedMutation(database, mutation, persist))();
231
+
232
+ return database.transaction(() => {
233
+ const existing = getMutationRow(database, mutation.channelId, mutation.mutationId);
234
+ if (existing) {
235
+ if (!sameMutation(existing, mutation)) {
236
+ throw invalid(
237
+ `mutationId ${mutation.mutationId} was reused with different content`,
238
+ 409,
239
+ );
240
+ }
241
+ return { mutation: normalizeJournalRow(existing), duplicate: true };
242
+ }
243
+
244
+ if (persist) persist(database, mutation);
245
+
246
+ const info = cachedStatement(database, `
247
+ INSERT INTO mutation_journal (
248
+ channel_id,
249
+ local_resource,
250
+ shared_resource_id,
251
+ mutation_id,
252
+ device_id,
253
+ authority_epoch,
254
+ base_cloud_version,
255
+ contract,
256
+ schema_version,
257
+ operation_kind,
258
+ operation_json,
259
+ mutation_origin,
260
+ mutation_state,
261
+ local_revision
262
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'local', 'saving-local', ?)
263
+ `).run(
264
+ mutation.channelId,
265
+ mutation.localResource,
266
+ mutation.sharedResourceId,
267
+ mutation.mutationId,
268
+ mutation.deviceId,
269
+ mutation.authorityEpoch,
270
+ mutation.baseCloudVersion,
271
+ mutation.contract,
272
+ mutation.schemaVersion,
273
+ mutation.operationKind,
274
+ JSON.stringify(protectOperation(mutation.contract, mutation.operation)),
275
+ mutation.localRevision,
276
+ );
277
+
278
+ const row = cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
279
+ .get(Number(info.lastInsertRowid));
280
+ trace('journal', {
281
+ mutationId: mutation.mutationId,
282
+ channel: mutation.channelId,
283
+ shared: mutation.sharedResourceId,
284
+ });
285
+ return { mutation: normalizeJournalRow(row), duplicate: false };
286
+ })();
292
287
  }
293
288
 
294
289
  function recordMaterializationError(database, channelId, mutationId, error) {
@@ -312,7 +307,7 @@ function advanceReplicaCursor(database, sharedResourceId) {
312
307
  WHERE shared_resource_id = ?
313
308
  AND official_cloud_version = ?
314
309
  AND mutation_state = 'synced'
315
- AND official_projected_at IS NOT NULL
310
+ AND materialized_at IS NOT NULL
316
311
  LIMIT 1
317
312
  `);
318
313
  const update = cachedStatement(database, `
@@ -337,168 +332,61 @@ function advanceReplicaCursor(database, sharedResourceId) {
337
332
  return replica ? Number(replica.applied_version) : null;
338
333
  }
339
334
 
340
- function completeMaterializedInTransaction(database, channelId, mutationId, eventInput) {
341
- const row = getMutationRow(database, channelId, mutationId);
342
- if (!row) throw invalid(`unknown mutation ${mutationId}`, 404);
343
- if (row.event_seq != null) {
344
- return { mutation: normalizeJournalRow(row), duplicate: true, event: null };
345
- }
346
- if (row.mutation_state !== 'saving-local') {
347
- throw invalid(`mutation ${mutationId} cannot materialize from ${row.mutation_state}`, 409);
348
- }
349
- if (!eventInput || eventInput.resource !== row.local_resource) {
350
- throw invalid('materialized event resource must match the journal localResource');
351
- }
352
-
353
- const event = insertStateEvent(database, {
354
- ...eventInput,
355
- mutationId: row.mutation_id,
356
- sharedResourceId: row.shared_resource_id,
357
- });
358
- const now = new Date().toISOString();
359
- const nextState = row.mutation_origin === 'cloud' ? 'synced' : 'saved-local';
360
- const officialProjectedAt = row.mutation_origin === 'cloud' ? now : null;
361
- cachedStatement(database, `
362
- UPDATE mutation_journal
363
- SET mutation_state = ?,
364
- materialized_at = ?,
365
- official_projected_at = ?,
366
- event_seq = ?,
367
- last_error = NULL,
368
- failure_code = NULL,
369
- updated_at = ?
370
- WHERE journal_id = ?
371
- `).run(nextState, now, officialProjectedAt, event.seq, now, row.journal_id);
372
-
373
- if (row.mutation_origin === 'cloud') {
374
- advanceReplicaCursor(database, row.shared_resource_id);
375
- }
376
-
377
- trace('materialized', {
378
- mutationId: row.mutation_id,
379
- origin: row.mutation_origin,
380
- state: nextState,
381
- eventSeq: event.seq,
382
- });
383
- return {
384
- mutation: normalizeJournalRow(
385
- cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
386
- .get(row.journal_id),
387
- ),
388
- duplicate: false,
389
- event,
390
- };
391
- }
392
-
393
335
  function completeMaterializedMutation(channelIdInput, mutationIdInput, eventInput, options = {}) {
394
- const channelId = cleanText(channelIdInput, 'channelId');
395
- const mutationId = cleanText(mutationIdInput, 'mutationId', 160);
396
- const database = options.database || openLocalDb();
397
- const result = database.transaction(() => {
398
- const completed = completeMaterializedInTransaction(
399
- database,
400
- channelId,
401
- mutationId,
402
- eventInput,
403
- );
404
- if (typeof options.finalize === 'function') {
405
- options.finalize(database, completed);
406
- }
407
- return completed;
408
- })();
409
- if (result.event) publishStateEvent(result.event);
410
- return result;
411
- }
412
-
413
- /**
414
- * A code-project outbox event is not the official materialization. When that
415
- * same mutation returns in the numbered cloud tail, project it once more,
416
- * then move the replica cursor. Repeating this after a crash is safe because
417
- * the contract materializer folds by official snapshot version.
418
- */
419
- function completeOfficialMaterialization(
420
- channelIdInput,
421
- mutationIdInput,
422
- eventInput,
423
- options = {},
424
- ) {
425
336
  const channelId = cleanText(channelIdInput, 'channelId');
426
337
  const mutationId = cleanText(mutationIdInput, 'mutationId', 160);
427
338
  const database = options.database || openLocalDb();
428
339
  let event = null;
340
+
429
341
  const result = database.transaction(() => {
430
- const finalize = (completed) => {
431
- if (typeof options.finalize === 'function') {
432
- options.finalize(database, completed);
433
- }
434
- return completed;
435
- };
436
342
  const row = getMutationRow(database, channelId, mutationId);
437
343
  if (!row) throw invalid(`unknown mutation ${mutationId}`, 404);
438
- if (
439
- row.mutation_origin !== 'local'
440
- || row.mutation_state !== 'synced'
441
- || row.official_cloud_version == null
442
- ) throw invalid(`mutation ${mutationId} has no official projection`, 409);
443
- const replica = cachedStatement(
444
- database,
445
- 'SELECT applied_version FROM shared_resource_replicas WHERE resource_id = ?',
446
- ).get(row.shared_resource_id);
447
- const appliedVersion = Number(replica?.applied_version);
448
- const officialVersion = Number(row.official_cloud_version);
449
- if (row.official_projected_at != null || appliedVersion >= officialVersion) {
450
- if (row.official_projected_at == null) {
451
- const now = new Date().toISOString();
452
- cachedStatement(database, `
453
- UPDATE mutation_journal
454
- SET official_projected_at = ?,
455
- updated_at = ?
456
- WHERE journal_id = ?
457
- `).run(now, now, row.journal_id);
458
- }
459
- advanceReplicaCursor(database, row.shared_resource_id);
460
- return finalize({
461
- mutation: normalizeJournalRow(
462
- cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
463
- .get(row.journal_id),
464
- ),
465
- duplicate: true,
466
- });
344
+ if (row.event_seq != null) {
345
+ return { mutation: normalizeJournalRow(row), duplicate: true };
467
346
  }
468
- if (officialVersion !== appliedVersion + 1) {
469
- const error = invalid(
470
- `shared mutation gap for ${row.shared_resource_id}: expected ${appliedVersion + 1}, received ${officialVersion}`,
471
- 409,
472
- );
473
- error.code = 'shared_mutation_gap';
474
- error.expectedVersion = appliedVersion + 1;
475
- error.receivedVersion = officialVersion;
476
- throw error;
347
+ if (row.mutation_state !== 'saving-local') {
348
+ throw invalid(`mutation ${mutationId} cannot materialize from ${row.mutation_state}`, 409);
477
349
  }
478
350
  if (!eventInput || eventInput.resource !== row.local_resource) {
479
351
  throw invalid('materialized event resource must match the journal localResource');
480
352
  }
353
+
481
354
  event = insertStateEvent(database, {
482
355
  ...eventInput,
483
356
  mutationId: row.mutation_id,
484
357
  sharedResourceId: row.shared_resource_id,
485
358
  });
486
359
  const now = new Date().toISOString();
360
+ const nextState = row.mutation_origin === 'cloud' ? 'synced' : 'saved-local';
487
361
  cachedStatement(database, `
488
362
  UPDATE mutation_journal
489
- SET official_projected_at = ?,
363
+ SET mutation_state = ?,
364
+ materialized_at = ?,
365
+ event_seq = ?,
366
+ last_error = NULL,
490
367
  updated_at = ?
491
368
  WHERE journal_id = ?
492
- `).run(now, now, row.journal_id);
493
- advanceReplicaCursor(database, row.shared_resource_id);
494
- return finalize({
369
+ `).run(nextState, now, event.seq, now, row.journal_id);
370
+
371
+ if (row.mutation_origin === 'cloud') {
372
+ advanceReplicaCursor(database, row.shared_resource_id);
373
+ }
374
+
375
+ trace('materialized', {
376
+ mutationId: row.mutation_id,
377
+ origin: row.mutation_origin,
378
+ state: nextState,
379
+ eventSeq: event.seq,
380
+ });
381
+ return {
495
382
  mutation: normalizeJournalRow(
496
383
  cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
497
384
  .get(row.journal_id),
498
385
  ),
499
386
  duplicate: false,
500
- });
387
+ };
501
388
  })();
389
+
502
390
  if (event) publishStateEvent(event);
503
391
  return { ...result, event };
504
392
  }
@@ -523,7 +411,6 @@ function journalCloudMutation(input, options = {}) {
523
411
  const version = positiveInteger(input?.version, 'version');
524
412
  const committedAt = cleanText(input?.committedAt, 'committedAt', 64);
525
413
  const database = options.database || openLocalDb();
526
- const persist = typeof options.persist === 'function' ? options.persist : null;
527
414
 
528
415
  return database.transaction(() => {
529
416
  const replica = cachedStatement(
@@ -553,60 +440,22 @@ function journalCloudMutation(input, options = {}) {
553
440
  throw invalid(`mutationId ${mutation.mutationId} was reused with different content`, 409);
554
441
  }
555
442
 
556
- if (existing.mutation_origin === 'local') {
557
- const appliedVersion = Number(replica.applied_version);
558
- if (version > appliedVersion && version !== appliedVersion + 1) {
559
- const error = invalid(
560
- `shared mutation gap for ${sharedResourceId}: expected ${appliedVersion + 1}, received ${version}`,
561
- 409,
562
- );
563
- error.code = 'shared_mutation_gap';
564
- error.expectedVersion = appliedVersion + 1;
565
- error.receivedVersion = version;
566
- throw error;
567
- }
568
- if (existing.official_cloud_version == null) {
569
- const now = new Date().toISOString();
570
- cachedStatement(database, `
571
- UPDATE mutation_journal
572
- SET mutation_state = 'synced',
573
- official_cloud_version = ?,
574
- cloud_committed_at = ?,
575
- next_attempt_at = NULL,
576
- last_error = NULL,
577
- failure_code = NULL,
578
- updated_at = ?
579
- WHERE journal_id = ?
580
- `).run(version, committedAt, now, existing.journal_id);
581
- }
582
- if (!mutationNeedsOrderedEcho(existing.contract)) {
583
- const now = new Date().toISOString();
584
- cachedStatement(database, `
585
- UPDATE mutation_journal
586
- SET official_projected_at = COALESCE(official_projected_at, ?),
587
- updated_at = ?
588
- WHERE journal_id = ?
589
- `).run(now, now, existing.journal_id);
590
- advanceReplicaCursor(database, sharedResourceId);
591
- const reconciled = cachedStatement(
592
- database,
593
- 'SELECT * FROM mutation_journal WHERE journal_id = ?',
594
- ).get(existing.journal_id);
595
- return {
596
- mutation: normalizeJournalRow(reconciled),
597
- duplicate: true,
598
- alreadyApplied: true,
599
- };
600
- }
601
- if (appliedVersion >= version && existing.official_projected_at == null) {
602
- const now = new Date().toISOString();
603
- cachedStatement(database, `
604
- UPDATE mutation_journal
605
- SET official_projected_at = ?,
606
- updated_at = ?
607
- WHERE journal_id = ?
608
- `).run(now, now, existing.journal_id);
609
- }
443
+ // The cloud tail is also the lost-ack recovery path for this runtime's
444
+ // own optimistic mutation. Reconcile the official version onto the
445
+ // existing row; never create or materialize a second local edit.
446
+ if (existing.mutation_origin === 'local' && existing.official_cloud_version == null) {
447
+ const now = new Date().toISOString();
448
+ cachedStatement(database, `
449
+ UPDATE mutation_journal
450
+ SET mutation_state = 'synced',
451
+ official_cloud_version = ?,
452
+ cloud_committed_at = ?,
453
+ next_attempt_at = NULL,
454
+ last_error = NULL,
455
+ updated_at = ?
456
+ WHERE journal_id = ?
457
+ `).run(version, committedAt, now, existing.journal_id);
458
+ advanceReplicaCursor(database, sharedResourceId);
610
459
  const reconciled = cachedStatement(
611
460
  database,
612
461
  'SELECT * FROM mutation_journal WHERE journal_id = ?',
@@ -614,15 +463,14 @@ function journalCloudMutation(input, options = {}) {
614
463
  return {
615
464
  mutation: normalizeJournalRow(reconciled),
616
465
  duplicate: true,
617
- alreadyApplied: appliedVersion >= version,
618
- officialMaterialization: appliedVersion < version,
466
+ alreadyApplied: reconciled.event_seq != null,
619
467
  };
620
468
  }
621
469
 
622
470
  return {
623
471
  mutation: normalizeJournalRow(existing),
624
472
  duplicate: true,
625
- alreadyApplied: existing.official_projected_at != null,
473
+ alreadyApplied: existing.event_seq != null,
626
474
  };
627
475
  }
628
476
 
@@ -642,7 +490,6 @@ function journalCloudMutation(input, options = {}) {
642
490
  }
643
491
 
644
492
  const now = new Date().toISOString();
645
- if (persist) persist(database, mutation);
646
493
  const info = cachedStatement(database, `
647
494
  INSERT INTO mutation_journal (
648
495
  channel_id,
@@ -694,10 +541,7 @@ function journalCloudMutation(input, options = {}) {
694
541
 
695
542
  function ingestCloudMutation(input, options = {}) {
696
543
  const database = options.database || openLocalDb();
697
- const started = journalCloudMutation(input, {
698
- database,
699
- persist: options.persist,
700
- });
544
+ const started = journalCloudMutation(input, { database });
701
545
  if (started.alreadyApplied) return { ...started, event: null };
702
546
 
703
547
  try {
@@ -714,56 +558,17 @@ function ingestCloudMutation(input, options = {}) {
714
558
  const eventInput = typeof options.event === 'function'
715
559
  ? options.event(started.mutation)
716
560
  : options.event;
717
- const completed = started.officialMaterialization
718
- ? completeOfficialMaterialization(
719
- started.mutation.channelId,
720
- started.mutation.mutationId,
721
- eventInput,
722
- { database, finalize: options.finalize },
723
- )
724
- : completeMaterializedMutation(
725
- started.mutation.channelId,
726
- started.mutation.mutationId,
727
- eventInput,
728
- { database, finalize: options.finalize },
729
- );
561
+ const completed = completeMaterializedMutation(
562
+ started.mutation.channelId,
563
+ started.mutation.mutationId,
564
+ eventInput,
565
+ { database },
566
+ );
730
567
  return { ...completed, duplicate: started.duplicate || completed.duplicate };
731
568
  }
732
569
 
733
570
  function commitLocalMutation(input, options = {}) {
734
571
  const database = options.database || openLocalDb();
735
- if (mutationNeedsOfficialMaterialization(input?.contract)) {
736
- if (typeof options.materialize === 'function') {
737
- throw invalid('code publication cannot materialize official state before cloud order', 409);
738
- }
739
- const mutation = normalizeMutationInput(input);
740
- const persist = typeof options.persist === 'function' ? options.persist : null;
741
- const result = database.transaction(() => {
742
- const started = journalNormalizedMutation(database, mutation, persist);
743
- if (started.duplicate && started.mutation.state !== 'saving-local') {
744
- return { ...started, event: null };
745
- }
746
- const eventInput = typeof options.event === 'function'
747
- ? options.event(started.mutation)
748
- : options.event;
749
- const completed = completeMaterializedInTransaction(
750
- database,
751
- started.mutation.channelId,
752
- started.mutation.mutationId,
753
- eventInput,
754
- );
755
- if (typeof options.finalize === 'function') {
756
- options.finalize(database, completed);
757
- }
758
- return {
759
- ...completed,
760
- duplicate: started.duplicate || completed.duplicate,
761
- };
762
- })();
763
- if (result.event) publishStateEvent(result.event);
764
- return result;
765
- }
766
-
767
572
  const started = journalMutation(input, { database, persist: options.persist });
768
573
  if (started.duplicate && started.mutation.state !== 'saving-local') {
769
574
  return { ...started, event: null };
@@ -790,7 +595,7 @@ function commitLocalMutation(input, options = {}) {
790
595
  started.mutation.channelId,
791
596
  started.mutation.mutationId,
792
597
  eventInput,
793
- { database, finalize: options.finalize },
598
+ { database },
794
599
  );
795
600
  return {
796
601
  ...completed,
@@ -918,10 +723,10 @@ function acknowledgeCloudMutation(sharedResourceIdInput, mutationIdInput, acknow
918
723
  cloud_committed_at = ?,
919
724
  next_attempt_at = NULL,
920
725
  last_error = NULL,
921
- failure_code = NULL,
922
726
  updated_at = ?
923
727
  WHERE journal_id = ?
924
728
  `).run(version, committedAt, now, row.journal_id);
729
+ advanceReplicaCursor(database, sharedResourceId);
925
730
  event = insertStateEvent(database, {
926
731
  resource: 'shared-mutations',
927
732
  op: 'ack',
@@ -941,17 +746,6 @@ function acknowledgeCloudMutation(sharedResourceIdInput, mutationIdInput, acknow
941
746
  };
942
747
  })();
943
748
  if (event) publishStateEvent(event);
944
- if (result.mutation?.contract === require('./mutation-contracts').CODE_PROJECT_CONTRACT) {
945
- const project = require('../workspace/wall').projectForResource(sharedResourceId);
946
- if (project) {
947
- require('../workspace/intent').markPublicationNumbered(
948
- project,
949
- mutationId,
950
- version,
951
- committedAt,
952
- );
953
- }
954
- }
955
749
  return { ...result, event };
956
750
  }
957
751
 
@@ -960,10 +754,6 @@ function failCloudMutation(sharedResourceIdInput, mutationIdInput, failure, opti
960
754
  const mutationId = cleanText(mutationIdInput, 'mutationId', 160);
961
755
  const message = cleanText(failure?.message || failure || 'cloud mutation failed', 'message', 4000);
962
756
  const retryable = failure?.retryable !== false;
963
- const failureCode = typeof failure?.code === 'string'
964
- && /^[a-z][a-z0-9_:-]{0,127}$/.test(failure.code)
965
- ? failure.code
966
- : null;
967
757
  const retryAt = retryable
968
758
  ? (failure?.retryAt || new Date(Date.now() + 1000).toISOString())
969
759
  : null;
@@ -978,17 +768,9 @@ function failCloudMutation(sharedResourceIdInput, mutationIdInput, failure, opti
978
768
  SET mutation_state = ?,
979
769
  next_attempt_at = ?,
980
770
  last_error = ?,
981
- failure_code = ?,
982
771
  updated_at = ?
983
772
  WHERE journal_id = ?
984
- `).run(
985
- retryable ? 'syncing' : 'rejected',
986
- retryAt,
987
- message,
988
- failureCode,
989
- now,
990
- row.journal_id,
991
- );
773
+ `).run(retryable ? 'syncing' : 'rejected', retryAt, message, now, row.journal_id);
992
774
  trace('cloud-fail', { mutationId, shared: sharedResourceId, retryable, message });
993
775
  return normalizeJournalRow(
994
776
  cachedStatement(database, 'SELECT * FROM mutation_journal WHERE journal_id = ?')
@@ -1017,38 +799,18 @@ function markMutationConflicted(sharedResourceIdInput, mutationIdInput, messageI
1017
799
  function listMutations(options = {}) {
1018
800
  const database = options.database || openLocalDb();
1019
801
  const limit = Math.max(1, Math.min(Number(options.limit) || 100, 1000));
1020
- const localResource = options.localResource == null
1021
- ? null
1022
- : cleanText(options.localResource, 'localResource', 8192);
1023
- let rows;
1024
- if (options.state && localResource) {
1025
- rows = cachedStatement(database, `
1026
- SELECT * FROM mutation_journal
1027
- WHERE mutation_state = ? AND local_resource = ?
1028
- ORDER BY journal_id ASC
1029
- LIMIT ?
1030
- `).all(options.state, localResource, limit);
1031
- } else if (options.state) {
1032
- rows = cachedStatement(database, `
802
+ const rows = options.state
803
+ ? cachedStatement(database, `
1033
804
  SELECT * FROM mutation_journal
1034
805
  WHERE mutation_state = ?
1035
806
  ORDER BY journal_id ASC
1036
807
  LIMIT ?
1037
- `).all(options.state, limit);
1038
- } else if (localResource) {
1039
- rows = cachedStatement(database, `
1040
- SELECT * FROM mutation_journal
1041
- WHERE local_resource = ?
1042
- ORDER BY journal_id ASC
1043
- LIMIT ?
1044
- `).all(localResource, limit);
1045
- } else {
1046
- rows = cachedStatement(database, `
808
+ `).all(options.state, limit)
809
+ : cachedStatement(database, `
1047
810
  SELECT * FROM mutation_journal
1048
811
  ORDER BY journal_id ASC
1049
812
  LIMIT ?
1050
813
  `).all(limit);
1051
- }
1052
814
  return rows.map((row) => normalizeJournalRow(row, { diagnostic: true }));
1053
815
  }
1054
816
 
@@ -1072,120 +834,6 @@ function listPendingCloudMutations(resourceIdInput, options = {}) {
1072
834
  `).all(resourceId).map((row) => normalizeJournalRow(row));
1073
835
  }
1074
836
 
1075
- /**
1076
- * Local overlay rows are every unnumbered mutation plus numbered local work
1077
- * whose official event has not yet folded into the materialized resource.
1078
- * Snapshot projection must retain the complete set, so this view is
1079
- * deliberately unpaged.
1080
- */
1081
- function listLocalOverlayMutations(resourceIdInput, options = {}) {
1082
- const resourceId = cleanText(resourceIdInput, 'resourceId', 132);
1083
- if (!isCloudResourceId(resourceId)) {
1084
- throw invalid('resourceId must be an opaque cloud resource id');
1085
- }
1086
- const database = options.database || openLocalDb();
1087
- const throughVersion = options.throughVersion == null
1088
- ? null
1089
- : nonNegativeInteger(options.throughVersion, 'throughVersion');
1090
- if (throughVersion !== null) {
1091
- return cachedStatement(database, `
1092
- SELECT * FROM mutation_journal
1093
- WHERE shared_resource_id = ?
1094
- AND mutation_origin = 'local'
1095
- AND (
1096
- mutation_state != 'synced'
1097
- OR official_cloud_version IS NULL
1098
- OR official_cloud_version > ?
1099
- )
1100
- ORDER BY journal_id ASC
1101
- `).all(resourceId, throughVersion).map((row) => normalizeJournalRow(row));
1102
- }
1103
- return cachedStatement(database, `
1104
- SELECT * FROM mutation_journal
1105
- WHERE shared_resource_id = ?
1106
- AND mutation_origin = 'local'
1107
- AND (mutation_state != 'synced' OR official_projected_at IS NULL)
1108
- ORDER BY journal_id ASC
1109
- `).all(resourceId).map((row) => normalizeJournalRow(row));
1110
- }
1111
-
1112
- function listUnappliedOfficialMutations(resourceIdInput, options = {}) {
1113
- const resourceId = cleanText(resourceIdInput, 'resourceId', 132);
1114
- if (!isCloudResourceId(resourceId)) {
1115
- throw invalid('resourceId must be an opaque cloud resource id');
1116
- }
1117
- const database = options.database || openLocalDb();
1118
- const replica = cachedStatement(
1119
- database,
1120
- 'SELECT applied_version FROM shared_resource_replicas WHERE resource_id = ?',
1121
- ).get(resourceId);
1122
- const appliedVersion = Number(replica?.applied_version ?? -1);
1123
- return cachedStatement(database, `
1124
- SELECT *
1125
- FROM mutation_journal
1126
- WHERE shared_resource_id = ?
1127
- AND mutation_origin = 'local'
1128
- AND mutation_state = 'synced'
1129
- AND official_cloud_version > ?
1130
- ORDER BY official_cloud_version ASC
1131
- `).all(resourceId, appliedVersion)
1132
- .filter((row) => mutationNeedsOfficialMaterialization(row.contract))
1133
- .map((row) => normalizeJournalRow(row));
1134
- }
1135
-
1136
- /**
1137
- * A verified code snapshot through N is the ordinary ordered fold for every
1138
- * already-numbered local publication at or before N. This repairs the same
1139
- * durable fact on an equal snapshot retry after a crash.
1140
- */
1141
- function completeOfficialSnapshotFold(resourceIdInput, throughInput, options = {}) {
1142
- const resourceId = cleanText(resourceIdInput, 'resourceId', 132);
1143
- const through = nonNegativeInteger(throughInput, 'through');
1144
- const database = options.database || openLocalDb();
1145
- const contract = cleanText(
1146
- options.contract || require('./mutation-contracts').CODE_PROJECT_CONTRACT,
1147
- 'contract',
1148
- 128,
1149
- );
1150
- const now = new Date().toISOString();
1151
- return cachedStatement(database, `
1152
- UPDATE mutation_journal
1153
- SET official_projected_at = COALESCE(official_projected_at, ?),
1154
- updated_at = ?
1155
- WHERE shared_resource_id = ?
1156
- AND contract = ?
1157
- AND mutation_origin = 'local'
1158
- AND mutation_state = 'synced'
1159
- AND official_cloud_version <= ?
1160
- `).run(
1161
- now,
1162
- now,
1163
- resourceId,
1164
- contract,
1165
- through,
1166
- ).changes;
1167
- }
1168
-
1169
- /**
1170
- * A stale proposal was never an official event. Keep it as a publication
1171
- * barrier until this replica has actually advanced past the base it used,
1172
- * then retire it so the unchanged local intent can be proposed anew.
1173
- */
1174
- function retireStaleCodeMutations(resourceIdInput, appliedVersionInput, options = {}) {
1175
- const resourceId = cleanText(resourceIdInput, 'resourceId', 132);
1176
- const appliedVersion = nonNegativeInteger(appliedVersionInput, 'appliedVersion');
1177
- const database = options.database || openLocalDb();
1178
- return cachedStatement(database, `
1179
- DELETE FROM mutation_journal
1180
- WHERE shared_resource_id = ?
1181
- AND mutation_origin = 'local'
1182
- AND contract = ?
1183
- AND mutation_state = 'rejected'
1184
- AND failure_code = 'code_project_stale_base'
1185
- AND base_cloud_version < ?
1186
- `).run(resourceId, require('./mutation-contracts').CODE_PROJECT_CONTRACT, appliedVersion).changes;
1187
- }
1188
-
1189
837
  function pruneMutationJournal(options = {}) {
1190
838
  const database = options.database || openLocalDb();
1191
839
  const hours = Number(options.retentionHours ?? process.env.AMALGM_EVENT_LOG_RETENTION_HOURS ?? 0.25);
@@ -1195,44 +843,23 @@ function pruneMutationJournal(options = {}) {
1195
843
  const cutoffIso = options.cutoffIso
1196
844
  || new Date(Date.now() - hours * 60 * 60 * 1000).toISOString();
1197
845
  const batchSize = Math.max(1, Math.floor(Number(options.batchSize) || 1000));
1198
- const readPage = cachedStatement(database, `
1199
- SELECT *
1200
- FROM mutation_journal
1201
- WHERE journal_id > ?
1202
- AND updated_at < ?
1203
- AND event_seq IS NOT NULL
1204
- AND (
1205
- (shared_resource_id IS NULL AND mutation_state = 'saved-local')
1206
- OR (
1207
- shared_resource_id IS NOT NULL
1208
- AND mutation_state = 'synced'
1209
- AND official_projected_at IS NOT NULL
846
+ const result = cachedStatement(database, `
847
+ DELETE FROM mutation_journal
848
+ WHERE journal_id IN (
849
+ SELECT journal_id
850
+ FROM mutation_journal
851
+ WHERE updated_at < ?
852
+ AND event_seq IS NOT NULL
853
+ AND (
854
+ (shared_resource_id IS NULL AND mutation_state = 'saved-local')
855
+ OR mutation_state = 'synced'
1210
856
  )
1211
- )
1212
- ORDER BY journal_id ASC
1213
- LIMIT ?
1214
- `);
1215
- const { mutationMayPrune } = require('./mutation-contracts');
1216
- const snapshotCache = new Map();
1217
- const deletable = [];
1218
- let afterJournalId = 0;
1219
- while (deletable.length < batchSize) {
1220
- const page = readPage.all(afterJournalId, cutoffIso, batchSize);
1221
- if (page.length === 0) break;
1222
- for (const row of page) {
1223
- afterJournalId = Number(row.journal_id);
1224
- if (mutationMayPrune(row, { database, snapshotCache })) {
1225
- deletable.push(row.journal_id);
1226
- if (deletable.length === batchSize) break;
1227
- }
1228
- }
1229
- }
1230
- const remove = cachedStatement(database, 'DELETE FROM mutation_journal WHERE journal_id = ?');
1231
- const deleted = database.transaction((journalIds) => (
1232
- journalIds.reduce((count, journalId) => count + remove.run(journalId).changes, 0)
1233
- ))(deletable);
857
+ ORDER BY journal_id ASC
858
+ LIMIT ?
859
+ )
860
+ `).run(cutoffIso, batchSize);
1234
861
  return {
1235
- deleted,
862
+ deleted: result.changes || 0,
1236
863
  cutoffIso,
1237
864
  retentionHours: hours,
1238
865
  batchSize,
@@ -1245,17 +872,13 @@ module.exports = {
1245
872
  claimCloudMutations,
1246
873
  commitLocalMutation,
1247
874
  completeMaterializedMutation,
1248
- completeOfficialSnapshotFold,
1249
875
  failCloudMutation,
1250
876
  getMutation,
1251
877
  ingestCloudMutation,
1252
878
  journalCloudMutation,
1253
879
  journalMutation,
1254
- listLocalOverlayMutations,
1255
- listUnappliedOfficialMutations,
1256
880
  listPendingCloudMutations,
1257
881
  listMutations,
1258
882
  markMutationConflicted,
1259
883
  pruneMutationJournal,
1260
- retireStaleCodeMutations,
1261
884
  };