@cleocode/core 2026.10.10 → 2026.10.11-rc.ci.680

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 (78) hide show
  1. package/dist/build-provenance.json +2 -2
  2. package/dist/cloud/nexus-cloud-conflicts.d.ts +8 -3
  3. package/dist/cloud/nexus-cloud-conflicts.d.ts.map +1 -1
  4. package/dist/cloud/nexus-cloud-conflicts.js +21 -5
  5. package/dist/cloud/nexus-cloud-conflicts.js.map +1 -1
  6. package/dist/cloud/nexus-cloud-journal-activity.d.ts +15 -1
  7. package/dist/cloud/nexus-cloud-journal-activity.d.ts.map +1 -1
  8. package/dist/cloud/nexus-cloud-journal-activity.js +8 -2
  9. package/dist/cloud/nexus-cloud-journal-activity.js.map +1 -1
  10. package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
  11. package/dist/cloud/nexus-cloud-status.js +6 -2
  12. package/dist/cloud/nexus-cloud-status.js.map +1 -1
  13. package/dist/cloud/nexus-vault.d.ts.map +1 -1
  14. package/dist/cloud/nexus-vault.js +52 -8
  15. package/dist/cloud/nexus-vault.js.map +1 -1
  16. package/dist/cloud/secret-seal.d.ts +31 -0
  17. package/dist/cloud/secret-seal.d.ts.map +1 -1
  18. package/dist/cloud/secret-seal.js +82 -4
  19. package/dist/cloud/secret-seal.js.map +1 -1
  20. package/dist/internal.d.ts +2 -0
  21. package/dist/internal.d.ts.map +1 -1
  22. package/dist/internal.js +1 -0
  23. package/dist/internal.js.map +1 -1
  24. package/dist/memory/decision-cross-link.d.ts +5 -2
  25. package/dist/memory/decision-cross-link.d.ts.map +1 -1
  26. package/dist/memory/decision-cross-link.js +5 -2
  27. package/dist/memory/decision-cross-link.js.map +1 -1
  28. package/dist/memory/decisions.d.ts.map +1 -1
  29. package/dist/memory/decisions.js +13 -5
  30. package/dist/memory/decisions.js.map +1 -1
  31. package/dist/resources/admission-ledger.d.ts +7 -0
  32. package/dist/resources/admission-ledger.d.ts.map +1 -1
  33. package/dist/resources/admission-ledger.js +53 -9
  34. package/dist/resources/admission-ledger.js.map +1 -1
  35. package/dist/store/migration-runner.d.ts +17 -0
  36. package/dist/store/migration-runner.d.ts.map +1 -1
  37. package/dist/store/migration-runner.js +53 -0
  38. package/dist/store/migration-runner.js.map +1 -1
  39. package/dist/store/migration-safety.d.ts +406 -0
  40. package/dist/store/migration-safety.d.ts.map +1 -0
  41. package/dist/store/migration-safety.js +587 -0
  42. package/dist/store/migration-safety.js.map +1 -0
  43. package/dist/store/portable-bundle.d.ts +8 -0
  44. package/dist/store/portable-bundle.d.ts.map +1 -1
  45. package/dist/store/portable-bundle.js +5 -0
  46. package/dist/store/portable-bundle.js.map +1 -1
  47. package/dist/store/sync/conflicts.d.ts +37 -0
  48. package/dist/store/sync/conflicts.d.ts.map +1 -1
  49. package/dist/store/sync/conflicts.js +88 -0
  50. package/dist/store/sync/conflicts.js.map +1 -1
  51. package/dist/store/sync/merge/engine.d.ts.map +1 -1
  52. package/dist/store/sync/merge/engine.js +18 -0
  53. package/dist/store/sync/merge/engine.js.map +1 -1
  54. package/dist/store/sync/merge/rules.d.ts +2 -1
  55. package/dist/store/sync/merge/rules.d.ts.map +1 -1
  56. package/dist/store/sync/merge/rules.js +9 -2
  57. package/dist/store/sync/merge/rules.js.map +1 -1
  58. package/dist/store/sync/merge/types.d.ts +7 -0
  59. package/dist/store/sync/merge/types.d.ts.map +1 -1
  60. package/dist/store/sync/reconcile-copy.d.ts +8 -0
  61. package/dist/store/sync/reconcile-copy.d.ts.map +1 -1
  62. package/dist/store/sync/reconcile-copy.js +1 -1
  63. package/dist/store/sync/reconcile-copy.js.map +1 -1
  64. package/dist/store/sync/sealer.d.ts +5 -1
  65. package/dist/store/sync/sealer.d.ts.map +1 -1
  66. package/dist/store/sync/sealer.js +35 -3
  67. package/dist/store/sync/sealer.js.map +1 -1
  68. package/dist/store/vault-manifest.d.ts +72 -0
  69. package/dist/store/vault-manifest.d.ts.map +1 -1
  70. package/dist/store/vault-manifest.js +134 -0
  71. package/dist/store/vault-manifest.js.map +1 -1
  72. package/dist/tasks/complete.d.ts.map +1 -1
  73. package/dist/tasks/complete.js +7 -1
  74. package/dist/tasks/complete.js.map +1 -1
  75. package/package.json +13 -13
  76. package/templates/git-hooks/commit-msg +7 -2
  77. package/templates/git-hooks/legacy-hashes.json +3 -1
  78. package/templates/git-hooks/pre-push +9 -3
@@ -0,0 +1,587 @@
1
+ /**
2
+ * The migration safety harness (T13448, saga T13339 / epic T13340).
3
+ *
4
+ * Every store move in the CleoDocs re-architecture (the T13360 migration, the
5
+ * T13361/T13362 legacy retirements) wraps its steps in this harness so a
6
+ * migration can never destroy or corrupt an existing project's store without
7
+ * a verified recovery path. Each registered step executes inside a fixed
8
+ * bracket:
9
+ *
10
+ * 1. **Pre-step backup** — a `VACUUM INTO` snapshot of the whole project
11
+ * store via {@link planMigrationSnapshot} + {@link writeMigrationSnapshot}
12
+ * (the same primitives the twin-collapse repairs use, T12535). The
13
+ * snapshot is registered as a `migration` system backup
14
+ * (`.cleo/backups/sqlite/cleo.db.<backupId>` plus its `<backupId>.meta.json`
15
+ * sidecar), so `cleo backup list` shows it and the per-type rotation
16
+ * applies. The sidecar is the step's **backup receipt**; its timestamp
17
+ * feeds the destructive-step guard. Runs OUTSIDE the transaction
18
+ * (`VACUUM INTO` requires it).
19
+ * 2. **`BEGIN IMMEDIATE`** (T13609) — single-writer exclusion for the whole
20
+ * bracket: a concurrent writer can neither interleave between the
21
+ * fingerprints, the run and the verify (masking or forging count/hash
22
+ * results) nor be silently discarded by a later restore.
23
+ * 3. **Run** — the step's `run(ctx)` executes inside the transaction.
24
+ * Table-rebuild recipes use `PRAGMA defer_foreign_keys = ON` (enforced
25
+ * at COMMIT), never `PRAGMA foreign_keys = OFF` (a no-op in a
26
+ * transaction).
27
+ * 4. **Verify** — machine-readable checks: per-table row counts before/after
28
+ * (matching, or explained by the step's declared `expectedDelta`),
29
+ * content-hash spot checks (an order-independent multiset hash over the
30
+ * table's rows, sampled to `sampleSize` rowids when the table is larger),
31
+ * and `PRAGMA foreign_key_check` (must return zero rows).
32
+ * 5. **Commit or roll back** (T13609) — only a fully verified step is
33
+ * COMMITted; a refused, failed or throwing step is ROLLBACKed, so a
34
+ * failed step is never visible in the live store. The restore path
35
+ * remains the backstop for a commit that is later found bad.
36
+ * 6. **Report** — a JSON-serializable {@link MigrationStepReport} per step
37
+ * (including the `transaction` outcome); a failed verification **halts**
38
+ * the runner and names the failed step. {@link rollbackMigrationStep}
39
+ * consumes exactly the report's backup receipt and before-fingerprints.
40
+ *
41
+ * **Destructive guard** — a step declared `destructive: true` refuses to run
42
+ * unless the harness options pass `force: true` AND the step's backup receipt
43
+ * is younger than the step start (which the harness itself guarantees by
44
+ * taking the snapshot first; a failed or skipped backup therefore refuses the
45
+ * step by construction).
46
+ *
47
+ * **Rollback** — {@link rollbackMigrationStep} restores the step's snapshot
48
+ * through {@link restoreStoreSnapshot} (the programmatic core of
49
+ * `cleo restore backup`, T13240: verified copy, live-writer refusal, the
50
+ * replaced store kept as a pinned `pre-restore-*` backup) and then re-proves
51
+ * the restored store against the pre-step fingerprints (counts and content
52
+ * hashes must match exactly).
53
+ *
54
+ * All store access here is read-only verification SQL plus the `VACUUM INTO`
55
+ * snapshot primitive; steps own their own writes and route them through the
56
+ * canonical accessors (gates 28/38).
57
+ *
58
+ * @module
59
+ * @task T13448
60
+ */
61
+ import { createHash } from 'node:crypto';
62
+ import { ExitCode } from '@cleocode/contracts/exit-codes.js';
63
+ import { CleoError } from '../errors.js';
64
+ import { getLogger } from '../logger.js';
65
+ import { readBackupSidecar } from './backup-sidecar.js';
66
+ import { resolveDualScopeDbPath } from './dual-scope-db.js';
67
+ import { openCleoDbSnapshot } from './open-cleo-db.js';
68
+ import { planMigrationSnapshot, writeMigrationSnapshot } from './pre-repair-snapshot.js';
69
+ import { restoreStoreSnapshot } from './restore-store.js';
70
+ /** Default number of rows content-hash spot-checked per oversized table. */
71
+ export const DEFAULT_VERIFICATION_SAMPLE_SIZE = 200;
72
+ /**
73
+ * Quote one SQLite identifier (table name) for interpolation.
74
+ */
75
+ function quoteIdent(name) {
76
+ return `"${name.replace(/"/g, '""')}"`;
77
+ }
78
+ /**
79
+ * Error message helper — `Error.message` when available, String otherwise.
80
+ */
81
+ function messageOf(err) {
82
+ return err instanceof Error ? err.message : String(err);
83
+ }
84
+ /**
85
+ * Deterministic, unambiguous serialization of one node:sqlite value for
86
+ * hashing: every value kind gets a tag (`N` null, `n` number, `i` bigint,
87
+ * `s` length-prefixed string, `b` hex blob), so distinct value kinds can
88
+ * never collide.
89
+ */
90
+ function encodeValue(value) {
91
+ if (value === null || value === undefined)
92
+ return 'N';
93
+ if (typeof value === 'number')
94
+ return `n:${value}`;
95
+ if (typeof value === 'bigint')
96
+ return `i:${value.toString()}`;
97
+ if (typeof value === 'string')
98
+ return `s:${value.length}:${value}`;
99
+ if (value instanceof Uint8Array)
100
+ return `b:${value.length}:${Buffer.from(value).toString('hex')}`;
101
+ return `x:${String(value)}`;
102
+ }
103
+ /**
104
+ * SHA-256 digest of one result row: sorted column names plus tagged values,
105
+ * so it is independent of the row's key order and of physical row order.
106
+ */
107
+ function rowDigest(row) {
108
+ const hash = createHash('sha256');
109
+ for (const key of Object.keys(row).sort()) {
110
+ hash.update(encodeValue(key));
111
+ hash.update('=');
112
+ hash.update(encodeValue(row[key]));
113
+ hash.update(';');
114
+ }
115
+ return hash.digest('hex');
116
+ }
117
+ /**
118
+ * Combine per-row digests into one table hash: sort the digests and hash the
119
+ * list, making the fingerprint an order-independent multiset hash (a carried
120
+ * table survives a rowid-shuffling rebuild unchanged).
121
+ */
122
+ function combineDigests(digests) {
123
+ const hash = createHash('sha256');
124
+ for (const digest of [...digests].sort()) {
125
+ hash.update(digest);
126
+ hash.update('\n');
127
+ }
128
+ return hash.digest('hex');
129
+ }
130
+ /**
131
+ * Pick `n` evenly-spaced entries from an already-sorted list (indexes
132
+ * `floor(i * len / n)`), de-duplicated. Deterministic: the same sorted input
133
+ * yields the same sample every time.
134
+ */
135
+ function evenlySpaced(sorted, n) {
136
+ if (sorted.length <= n)
137
+ return [...sorted];
138
+ const out = [];
139
+ for (let i = 0; i < n; i++) {
140
+ const item = sorted[Math.floor((i * sorted.length) / n)];
141
+ if (item !== undefined && (out.length === 0 || out[out.length - 1] !== item)) {
142
+ out.push(item);
143
+ }
144
+ }
145
+ return out;
146
+ }
147
+ /**
148
+ * Capture an order-independent content fingerprint of one table.
149
+ *
150
+ * Tables with at most `sampleSize` rows (and `WITHOUT ROWID` tables, which
151
+ * have no rowid to sample) are hashed in full; larger rowid tables are
152
+ * spot-checked on `sampleSize` evenly-spaced rowids. Reads only.
153
+ *
154
+ * @param db - Live native handle.
155
+ * @param table - Table name.
156
+ * @param sampleSize - Full-scan cutoff / sample size (default 200).
157
+ * @returns The fingerprint.
158
+ * @task T13448
159
+ */
160
+ export function fingerprintTable(db, table, sampleSize = DEFAULT_VERIFICATION_SAMPLE_SIZE) {
161
+ const quoted = quoteIdent(table);
162
+ const count = Number(db.prepare(`SELECT COUNT(*) AS n FROM ${quoted}`).get().n);
163
+ if (count === 0) {
164
+ return { table, count: 0, hash: combineDigests([]), full: true, sampledRowids: [] };
165
+ }
166
+ let rowids = null;
167
+ try {
168
+ rowids = db.prepare(`SELECT rowid AS r FROM ${quoted} ORDER BY rowid`).all().map((row) => row.r);
169
+ }
170
+ catch {
171
+ rowids = null; // WITHOUT ROWID table: no rowid to sample
172
+ }
173
+ let sample;
174
+ let full;
175
+ if (rowids === null) {
176
+ sample = null;
177
+ full = true;
178
+ }
179
+ else if (count <= sampleSize) {
180
+ sample = rowids;
181
+ full = true;
182
+ }
183
+ else {
184
+ sample = evenlySpaced(rowids, sampleSize);
185
+ full = false;
186
+ }
187
+ const digests = [];
188
+ if (sample !== null) {
189
+ const stmt = db.prepare(`SELECT * FROM ${quoted} WHERE rowid = ?`);
190
+ // Real stores carry integers beyond 2^53 (e.g. HLC timestamps); without
191
+ // big-int reads node:sqlite throws converting them to number.
192
+ stmt.setReadBigInts(true);
193
+ for (const rowid of sample) {
194
+ const row = stmt.get(rowid);
195
+ if (row !== undefined)
196
+ digests.push(rowDigest(row));
197
+ }
198
+ }
199
+ else {
200
+ const rowsStmt = db.prepare(`SELECT * FROM ${quoted}`);
201
+ rowsStmt.setReadBigInts(true);
202
+ const rows = rowsStmt.all();
203
+ for (const row of rows)
204
+ digests.push(rowDigest(row));
205
+ }
206
+ return { table, count, hash: combineDigests(digests), full, sampledRowids: sample ?? [] };
207
+ }
208
+ /**
209
+ * Run `PRAGMA foreign_key_check` and return the violation count. Zero is the
210
+ * only passing value; the pragma reports independently of the
211
+ * `foreign_keys` switch, so a migration that toggles FK enforcement mid-step
212
+ * is still checked. Read-only.
213
+ *
214
+ * @param db - Live native handle.
215
+ * @returns Number of FK violations.
216
+ * @task T13448
217
+ */
218
+ export function countForeignKeyViolations(db) {
219
+ return db.prepare('PRAGMA foreign_key_check').all().length;
220
+ }
221
+ /**
222
+ * List user tables (everything except `sqlite_*` internals) in name order.
223
+ * Read-only.
224
+ */
225
+ function listUserTables(db) {
226
+ return db
227
+ .prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
228
+ .all().map((row) => row.name);
229
+ }
230
+ /**
231
+ * Error text meaning "this table needs a loadable SQLite extension that this
232
+ * connection does not have" (e.g. `vec0` virtual tables without sqlite-vec).
233
+ * Only this read error may skip verification — such tables are
234
+ * content-addressed caches, never the source of truth; anything else stays
235
+ * fail-closed.
236
+ */
237
+ const NO_SUCH_MODULE = /no such module/i;
238
+ /**
239
+ * Capture the pre- or post-step fingerprint set for the tables in scope.
240
+ * Extension-backed unreadable tables (see {@link NO_SUCH_MODULE}) are
241
+ * returned as skipped, not fatal.
242
+ */
243
+ function captureFingerprints(db, tables, sampleSize) {
244
+ const names = tables ?? listUserTables(db);
245
+ const fingerprints = [];
246
+ const skipped = [];
247
+ for (const table of names) {
248
+ try {
249
+ fingerprints.push(fingerprintTable(db, table, sampleSize));
250
+ }
251
+ catch (err) {
252
+ if (NO_SUCH_MODULE.test(messageOf(err))) {
253
+ skipped.push({ table, reason: messageOf(err) });
254
+ continue;
255
+ }
256
+ throw err;
257
+ }
258
+ }
259
+ return { fingerprints, skipped };
260
+ }
261
+ /**
262
+ * Run migration steps inside the backup → BEGIN IMMEDIATE → migrate → verify
263
+ * → COMMIT/ROLLBACK → report bracket (T13448, T13609). Each step's writes are
264
+ * atomic and write-exclusive: a refused, failed or throwing step is rolled
265
+ * back and never becomes visible in the live store, and no concurrent writer
266
+ * can interleave between the before-fingerprints, the run and the verify.
267
+ * Never throws for verification failures, refusals, or step errors: those are
268
+ * reported and halt the run (AC1, AC4). Throws only for invalid invocation
269
+ * (no steps).
270
+ *
271
+ * @param steps - The registered steps, in execution order.
272
+ * @param opts - The store handle, project, force flag and hooks.
273
+ * @returns The machine-readable run report. On `halted`/`refused`, the last
274
+ * step report carries the backup receipt and before-fingerprints needed by
275
+ * {@link rollbackMigrationStep} (the backstop for a commit later found bad).
276
+ * @task T13448
277
+ * @task T13609 — transactional bracket; failed steps are never visible
278
+ */
279
+ export async function runMigrationSteps(steps, opts) {
280
+ if (steps.length === 0) {
281
+ // @sync-invariant none:input-shape nothing was asked of the store
282
+ throw new CleoError(ExitCode.INVALID_INPUT, 'runMigrationSteps: at least one step is required');
283
+ }
284
+ const dbPath = opts.dbPath ?? resolveDualScopeDbPath('project', opts.projectRoot);
285
+ const sampleSize = opts.sampleSize ?? DEFAULT_VERIFICATION_SAMPLE_SIZE;
286
+ const logger = getLogger('migration-safety');
287
+ const reports = [];
288
+ for (const step of steps) {
289
+ const startedAt = new Date();
290
+ const stepStartMs = startedAt.getTime();
291
+ const clockStart = Date.now();
292
+ const spec = step.verify ?? {};
293
+ const skipHash = new Set(spec.skipHash ?? []);
294
+ const stepSampleSize = spec.sampleSize ?? sampleSize;
295
+ const failures = [];
296
+ let backup = null;
297
+ let runError = null;
298
+ let status = 'completed';
299
+ const verifications = [];
300
+ let beforeTables = [];
301
+ let unreadableTables = [];
302
+ let addedTables = [];
303
+ let removedTables = [];
304
+ let fkViolations = 0;
305
+ let transaction = 'none';
306
+ // 1. Pre-step VACUUM INTO backup, registered as a migration system
307
+ // backup whose sidecar is this step's receipt (T12535 machinery).
308
+ // Runs OUTSIDE the transaction — VACUUM INTO requires it.
309
+ try {
310
+ const plan = planMigrationSnapshot(opts.db, dbPath);
311
+ const snapshotPath = writeMigrationSnapshot(opts.db, plan, `migration step: ${step.name}${step.description ? ` — ${step.description}` : ''} (T13448)`);
312
+ const receipt = readBackupSidecar(snapshotPath, 'migration');
313
+ backup = {
314
+ backupId: plan.backupId,
315
+ snapshotPath,
316
+ timestamp: receipt?.timestamp ?? new Date().toISOString(),
317
+ };
318
+ }
319
+ catch (err) {
320
+ status = 'failed';
321
+ runError = `pre-step backup failed: ${messageOf(err)}`;
322
+ }
323
+ // 2. BEGIN IMMEDIATE (T13609): single-writer exclusion for the whole
324
+ // fingerprint → run → verify bracket, so a concurrent writer can
325
+ // neither interleave (masking or forging count/hash results) nor be
326
+ // silently discarded by a later restore. Writers wait on
327
+ // busy_timeout, then fail with SQLITE_BUSY.
328
+ if (status === 'completed') {
329
+ try {
330
+ opts.db.exec('BEGIN IMMEDIATE');
331
+ transaction = 'rolled-back'; // until COMMIT proves otherwise
332
+ }
333
+ catch (err) {
334
+ status = 'failed';
335
+ runError = `BEGIN IMMEDIATE failed: ${messageOf(err)}`;
336
+ }
337
+ }
338
+ // 3. Destructive guard: refuse without force AND a receipt younger than
339
+ // the step start (AC: owner directive 2026-10-10). Inside the lock,
340
+ // before any fingerprint work.
341
+ if (status === 'completed' && step.destructive === true) {
342
+ const receiptFresh = backup !== null && Date.parse(backup.timestamp) >= stepStartMs;
343
+ if (opts.force !== true || !receiptFresh) {
344
+ status = 'refused';
345
+ failures.push('destructive step refused: requires force AND a backup receipt younger than the step start');
346
+ }
347
+ }
348
+ // 4. Before-fingerprints, inside the lock (T13609): the store they will
349
+ // be compared against cannot move underneath the bracket.
350
+ if (status === 'completed') {
351
+ try {
352
+ const captured = captureFingerprints(opts.db, spec.tables, stepSampleSize);
353
+ beforeTables = captured.fingerprints;
354
+ unreadableTables = captured.skipped;
355
+ }
356
+ catch (err) {
357
+ status = 'failed';
358
+ runError = `before-fingerprint capture failed: ${messageOf(err)}`;
359
+ }
360
+ }
361
+ // 5. Run the step, inside the transaction.
362
+ if (status === 'completed') {
363
+ const log = (message) => {
364
+ logger.info({ step: step.name }, message);
365
+ };
366
+ try {
367
+ await step.run({ db: opts.db, projectRoot: opts.projectRoot, dbPath, log });
368
+ }
369
+ catch (err) {
370
+ status = 'failed';
371
+ runError = messageOf(err);
372
+ }
373
+ }
374
+ // 6. Verify: counts (or declared deltas), content-hash spot checks, FK.
375
+ if (status === 'completed') {
376
+ try {
377
+ fkViolations = countForeignKeyViolations(opts.db);
378
+ const beforeNames = new Set(beforeTables.map((fp) => fp.table));
379
+ const afterNames = new Set(listUserTables(opts.db));
380
+ addedTables = [...afterNames].filter((name) => !beforeNames.has(name));
381
+ removedTables = [...beforeNames].filter((name) => !afterNames.has(name));
382
+ // A table skipped before the step (unreadable, e.g. a vec0 virtual
383
+ // table without its extension) must still EXIST afterwards: removal
384
+ // of a skipped table is invisible to the count/hash checks, so a
385
+ // step that drops one on this connection would go undetected.
386
+ for (const skipped of unreadableTables) {
387
+ if (!afterNames.has(skipped.table)) {
388
+ failures.push(`table ${skipped.table} was unreadable before the step (${skipped.reason}) and is missing after it`);
389
+ }
390
+ }
391
+ for (const before of beforeTables) {
392
+ const expectedDelta = spec.expectedDelta?.[before.table] ?? 0;
393
+ if (!afterNames.has(before.table)) {
394
+ failures.push(`table ${before.table} was removed by the step`);
395
+ verifications.push({
396
+ table: before.table,
397
+ before,
398
+ after: null,
399
+ expectedDelta,
400
+ countOk: false,
401
+ hashOk: null,
402
+ });
403
+ continue;
404
+ }
405
+ const after = fingerprintTable(opts.db, before.table, stepSampleSize);
406
+ const countOk = after.count === before.count + expectedDelta;
407
+ // A non-zero declared delta legitimately reshapes the table: the
408
+ // count is the contract there, the hash check applies to carried
409
+ // (zero-delta, not skip-listed) tables.
410
+ const hashChecked = expectedDelta === 0 && !skipHash.has(before.table);
411
+ const hashOk = hashChecked ? after.hash === before.hash : null;
412
+ if (!countOk) {
413
+ failures.push(`table ${before.table}: row count ${after.count} != ${before.count} + ${expectedDelta} (expected delta not explained)`);
414
+ }
415
+ if (hashOk === false) {
416
+ failures.push(`table ${before.table}: content hash changed (carried-table spot check failed)`);
417
+ }
418
+ verifications.push({
419
+ table: before.table,
420
+ before,
421
+ after,
422
+ expectedDelta,
423
+ countOk,
424
+ hashOk,
425
+ });
426
+ }
427
+ if (removedTables.length > 0) {
428
+ failures.push(`tables removed by the step: ${removedTables.join(', ')}`);
429
+ }
430
+ // Guard for the blind spot: a table skipped in the before-capture
431
+ // (extension-backed, e.g. vec0 without sqlite-vec loaded) never made
432
+ // it into beforeTables, so the loop above cannot notice the step
433
+ // dropping it. Its absence afterwards is only explainable by the
434
+ // step — fail closed.
435
+ for (const unreadable of unreadableTables) {
436
+ if (!afterNames.has(unreadable.table)) {
437
+ failures.push(`table ${unreadable.table} was removed by the step (skipped before: ${unreadable.reason})`);
438
+ }
439
+ }
440
+ if (fkViolations > 0) {
441
+ failures.push(`PRAGMA foreign_key_check returned ${fkViolations} violation(s) after the step`);
442
+ }
443
+ if (failures.length > 0)
444
+ status = 'failed';
445
+ }
446
+ catch (err) {
447
+ status = 'failed';
448
+ runError = `verification failed: ${messageOf(err)}`;
449
+ }
450
+ }
451
+ // 7. Commit only a fully verified step; roll everything else back, so a
452
+ // failed step is never visible in the live store (T13609 AC1/AC3). A
453
+ // COMMIT error (e.g. a deferred foreign-key violation surfacing at
454
+ // commit time) rolls back too.
455
+ if (transaction === 'rolled-back') {
456
+ if (status === 'completed') {
457
+ try {
458
+ opts.db.exec('COMMIT');
459
+ transaction = 'committed';
460
+ }
461
+ catch (err) {
462
+ try {
463
+ opts.db.exec('ROLLBACK');
464
+ }
465
+ catch {
466
+ // best effort — the transaction may already be closed
467
+ }
468
+ status = 'failed';
469
+ if (runError === null)
470
+ runError = `COMMIT failed: ${messageOf(err)}`;
471
+ }
472
+ }
473
+ else {
474
+ try {
475
+ opts.db.exec('ROLLBACK');
476
+ }
477
+ catch {
478
+ // best effort — the step may have closed the transaction itself
479
+ }
480
+ }
481
+ }
482
+ const report = {
483
+ step: step.name,
484
+ destructive: step.destructive === true,
485
+ status,
486
+ startedAt: startedAt.toISOString(),
487
+ durationMs: Date.now() - clockStart,
488
+ backup,
489
+ tables: verifications,
490
+ addedTables,
491
+ removedTables,
492
+ foreignKeyViolations: fkViolations,
493
+ unreadableTables,
494
+ transaction,
495
+ failures,
496
+ runError,
497
+ };
498
+ reports.push(report);
499
+ opts.onStepReport?.(report);
500
+ if (status === 'completed') {
501
+ logger.info({ step: step.name, backupId: backup?.backupId ?? null, tables: verifications.length }, 'migration step verified and committed (T13448)');
502
+ }
503
+ else {
504
+ logger.warn({ step: step.name, status, failures, runError, transaction }, 'migration step failed; transaction rolled back, store unchanged, restore path ready (T13448/T13609)');
505
+ return {
506
+ status: status === 'refused' ? 'refused' : 'halted',
507
+ steps: reports,
508
+ haltedStep: step.name,
509
+ failure: failures[0] ?? runError ?? 'step failed',
510
+ };
511
+ }
512
+ }
513
+ return { status: 'completed', steps: reports, haltedStep: null, failure: null };
514
+ }
515
+ /**
516
+ * Roll back one migration step: restore its pre-step snapshot through the
517
+ * programmatic core of `cleo restore backup` ({@link restoreStoreSnapshot} —
518
+ * verified copy, quiescence/live-writer refusal, the replaced store kept as
519
+ * a pinned `pre-restore-*` backup), then re-prove the restored store against
520
+ * the step's pre-step fingerprints. This is the tested rollback path of AC3.
521
+ *
522
+ * Note: the restore closes every in-process handle on the store (T13240
523
+ * quiescence) — discard any native handle captured before calling this and
524
+ * re-open through the chokepoint afterwards.
525
+ *
526
+ * @param params - The step, its backup receipt and its before-fingerprints.
527
+ * @returns The rollback report; `verified` is the assertion surface.
528
+ * @task T13448
529
+ */
530
+ export async function rollbackMigrationStep(params) {
531
+ const sampleSize = params.sampleSize ?? DEFAULT_VERIFICATION_SAMPLE_SIZE;
532
+ const result = await restoreStoreSnapshot({
533
+ projectRoot: params.projectRoot,
534
+ cwd: params.cwd,
535
+ snapshot: params.backup.snapshotPath,
536
+ ...(params.confirmOwnerStore !== undefined
537
+ ? { confirmOwnerStore: params.confirmOwnerStore }
538
+ : {}),
539
+ });
540
+ const failures = [];
541
+ const tables = [];
542
+ if (!result.restored) {
543
+ failures.push('restoreStoreSnapshot did not place the snapshot');
544
+ }
545
+ const restored = openCleoDbSnapshot(result.target, { readOnly: true });
546
+ try {
547
+ for (const expected of params.before) {
548
+ let actual = null;
549
+ let skipped = null;
550
+ try {
551
+ actual = fingerprintTable(restored.db, expected.table, sampleSize);
552
+ }
553
+ catch (err) {
554
+ if (NO_SUCH_MODULE.test(messageOf(err))) {
555
+ // Extension-backed cache table (e.g. vec0 without sqlite-vec on
556
+ // this read-only connection): nothing to compare, cannot fail.
557
+ skipped = messageOf(err);
558
+ }
559
+ else {
560
+ actual = null; // table absent from (or unreadable in) the restored store
561
+ }
562
+ }
563
+ const countOk = skipped !== null || (actual !== null && actual.count === expected.count);
564
+ const hashOk = skipped !== null || (actual !== null && actual.hash === expected.hash);
565
+ if (skipped === null && !countOk) {
566
+ failures.push(`rollback verify: ${expected.table} row count ${actual?.count ?? 'unreadable'} != pre-step ${expected.count}`);
567
+ }
568
+ if (skipped === null && !hashOk) {
569
+ failures.push(`rollback verify: ${expected.table} content hash differs from the pre-step snapshot`);
570
+ }
571
+ tables.push({ table: expected.table, expected, actual, countOk, hashOk, skipped });
572
+ }
573
+ }
574
+ finally {
575
+ restored.close();
576
+ }
577
+ return {
578
+ step: params.step,
579
+ restored: result.restored,
580
+ verified: failures.length === 0,
581
+ undo: result.undo,
582
+ keptBackupId: result.kept?.backupId ?? null,
583
+ tables,
584
+ failures,
585
+ };
586
+ }
587
+ //# sourceMappingURL=migration-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-safety.js","sourceRoot":"","sources":["../../src/store/migration-safety.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,7 @@
33
33
  */
34
34
  import type { PortableBundleManifest, PortableBundleScope, PortableDatabaseEntry, PortableExportResult, PortableImportResult, PortableSectionBase, PortableSkippedProject, PortableUnmigratedLegacyReport } from '@cleocode/contracts';
35
35
  import { type SectionRules } from './portable-bundle-scan.js';
36
+ import { type SealedCredentialCell } from './vault-manifest.js';
36
37
  /** Symbolic error codes raised by the portable bundle export/import. */
37
38
  export type PortableBundleErrorCode = 'E_PRIMARY_STORE_MISSING' | 'E_PRIMARY_STORE_UNREADABLE' | 'E_NO_PROJECT' | 'E_REGISTRY_UNREADABLE' | 'E_PASSPHRASE_REQUIRED' | 'E_BUNDLE_DECRYPT' | 'E_BUNDLE_FORMAT' | 'E_BUNDLE_INTEGRITY' | 'E_DATA_EXISTS' | 'E_TARGET_AMBIGUOUS' | 'E_RESTORE_MISMATCH' | 'E_REDACTION_FAILED' | 'E_PROJECT_STORE_UNAVAILABLE';
38
39
  /**
@@ -117,6 +118,13 @@ export interface ExportPortableBundleInput {
117
118
  * cloud vault leaves tracked files to git (T13019). Project scope only.
118
119
  */
119
120
  gitTrackedFiles?: ReadonlySet<string>;
121
+ /**
122
+ * Seal the primary store snapshot's credential cells before they are
123
+ * cleared; the sealed cells are written to the snapshot's
124
+ * sealed-credentials table (`vault-manifest.ts`). The cloud vault seals under the
125
+ * account key, so a joining device gets usable credentials (T13530).
126
+ */
127
+ sealCredentials?: (snapshotPath: string) => Promise<readonly SealedCredentialCell[]>;
120
128
  }
121
129
  /** A registered project row read from the global registry snapshot. */
122
130
  interface RegistryRow {
@@ -1 +1 @@
1
- {"version":3,"file":"portable-bundle.d.ts","sourceRoot":"","sources":["../../src/store/portable-bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"portable-bundle.d.ts","sourceRoot":"","sources":["../../src/store/portable-bundle.ts"],"names":[],"mappings":"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"}