@cello-protocol/daemon 0.0.8 → 0.0.9

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 (64) hide show
  1. package/dist/agent-loader.d.ts +15 -18
  2. package/dist/agent-loader.d.ts.map +1 -1
  3. package/dist/agent-loader.js +24 -81
  4. package/dist/agent-loader.js.map +1 -1
  5. package/dist/bin/cello-daemon.js +5 -7
  6. package/dist/bin/cello-daemon.js.map +1 -1
  7. package/dist/daemon.d.ts.map +1 -1
  8. package/dist/daemon.js +104 -65
  9. package/dist/daemon.js.map +1 -1
  10. package/dist/db-identity-store.d.ts +97 -0
  11. package/dist/db-identity-store.d.ts.map +1 -0
  12. package/dist/db-identity-store.js +235 -0
  13. package/dist/db-identity-store.js.map +1 -0
  14. package/dist/identity-migration.d.ts +40 -0
  15. package/dist/identity-migration.d.ts.map +1 -0
  16. package/dist/identity-migration.js +455 -0
  17. package/dist/identity-migration.js.map +1 -0
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/manifest-version-store-db.d.ts +24 -0
  23. package/dist/manifest-version-store-db.d.ts.map +1 -0
  24. package/dist/manifest-version-store-db.js +57 -0
  25. package/dist/manifest-version-store-db.js.map +1 -0
  26. package/dist/manifest-version-store.d.ts +3 -1
  27. package/dist/manifest-version-store.d.ts.map +1 -1
  28. package/dist/manifest-version-store.js +3 -1
  29. package/dist/manifest-version-store.js.map +1 -1
  30. package/dist/nonce-dedup.d.ts +2 -2
  31. package/dist/nonce-dedup.d.ts.map +1 -1
  32. package/dist/nonce-dedup.js.map +1 -1
  33. package/dist/registration-manager.d.ts.map +1 -1
  34. package/dist/registration-manager.js +78 -44
  35. package/dist/registration-manager.js.map +1 -1
  36. package/dist/retry-queue.d.ts +2 -3
  37. package/dist/retry-queue.d.ts.map +1 -1
  38. package/dist/retry-queue.js +8 -16
  39. package/dist/retry-queue.js.map +1 -1
  40. package/dist/seal-upgrade.d.ts +3 -1
  41. package/dist/seal-upgrade.d.ts.map +1 -1
  42. package/dist/seal-upgrade.js +1 -2
  43. package/dist/seal-upgrade.js.map +1 -1
  44. package/dist/session-ceremony.d.ts +8 -4
  45. package/dist/session-ceremony.d.ts.map +1 -1
  46. package/dist/session-ceremony.js +3 -7
  47. package/dist/session-ceremony.js.map +1 -1
  48. package/dist/session-node-manager.d.ts +10 -10
  49. package/dist/session-node-manager.d.ts.map +1 -1
  50. package/dist/session-node-manager.js +45 -45
  51. package/dist/session-node-manager.js.map +1 -1
  52. package/dist/sqlcipher-db.d.ts +87 -0
  53. package/dist/sqlcipher-db.d.ts.map +1 -0
  54. package/dist/sqlcipher-db.js +259 -0
  55. package/dist/sqlcipher-db.js.map +1 -0
  56. package/package.json +5 -4
  57. package/dist/manifest-version-store-file.d.ts +0 -18
  58. package/dist/manifest-version-store-file.d.ts.map +0 -1
  59. package/dist/manifest-version-store-file.js +0 -40
  60. package/dist/manifest-version-store-file.js.map +0 -1
  61. package/dist/transcript-cipher.d.ts +0 -31
  62. package/dist/transcript-cipher.d.ts.map +0 -1
  63. package/dist/transcript-cipher.js +0 -74
  64. package/dist/transcript-cipher.js.map +0 -1
@@ -0,0 +1,455 @@
1
+ /**
2
+ * CELLO-M7-PERSIST-002 — Unit 4/6: one-time migration of pre-story flat-file state and a plaintext
3
+ * node:sqlite DB into the single SQLCipher-encrypted daemon DB (AC-006, DB-002).
4
+ *
5
+ * Before this story the daemon kept:
6
+ * - identity as plaintext flat files: `agents/<name>/key` (37-byte CELLO seed), `frost-share.json`,
7
+ * `ml-dsa-keypair.json`, `registration-state.json`, `agent-user-link.json`, and the legacy
8
+ * single-file `~/.cello/key` (loaded as agent "default");
9
+ * - sessions/transcript/etc. in a PLAINTEXT `sessions.db` (node:sqlite), with two columns
10
+ * (transcript.blob, retry_queue.content_blob) envelope-encrypted by a sibling
11
+ * `sessions.db.transcript-key`.
12
+ *
13
+ * This migration runs at daemon startup BEFORE the encrypted DB is opened. If it detects either a
14
+ * plaintext DB or any flat-file identity, it builds a fresh SQLCipher DB (at `<dbPath>.migrating`),
15
+ * imports every row of the old DB (decrypting the two column-ciphered blobs to plaintext) AND every
16
+ * flat-file identity item into `agents` rows, verifies, then atomically swaps it into place — backing
17
+ * up the old plaintext DB to `<dbPath>.pre-sqlcipher.bak` and deleting the flat files. It is
18
+ * idempotent: once the DB is encrypted and the flat files are gone, it is a no-op.
19
+ *
20
+ * Fail-closed (SI-002/DB-002): on ANY error it aborts cleanly — the original flat files / plaintext
21
+ * DB are left in place, the partial `.migrating` DB is discarded, and the caller surfaces
22
+ * `identity_migration_failed`. No identity is lost and no plaintext is left half-migrated.
23
+ */
24
+ import { existsSync, readFileSync, readdirSync, statSync, renameSync, unlinkSync, } from "node:fs";
25
+ import { join, dirname } from "node:path";
26
+ import { createDecipheriv } from "node:crypto";
27
+ import { DatabaseSync } from "node:sqlite";
28
+ import { InMemoryKeyProvider, decodeKeyFileSeed } from "@cello-protocol/crypto";
29
+ import { openEncryptedDatabase, isPlaintextSqliteFile, resolveDbKey, dbKeyPathFor, } from "./sqlcipher-db.js";
30
+ import { ensureIdentitySchema } from "./db-identity-store.js";
31
+ import { ensureManifestSchema } from "./manifest-version-store-db.js";
32
+ export class IdentityMigrationError extends Error {
33
+ code = "identity_migration_failed";
34
+ guidance;
35
+ constructor(message, guidance) {
36
+ super(message);
37
+ this.name = "IdentityMigrationError";
38
+ this.guidance = guidance;
39
+ }
40
+ }
41
+ const REG_FILES = {
42
+ frost: "frost-share.json",
43
+ mlDsa: "ml-dsa-keypair.json",
44
+ reg: "registration-state.json",
45
+ link: "agent-user-link.json",
46
+ };
47
+ const hexToBytes = (s) => new Uint8Array(Buffer.from(s, "hex"));
48
+ /** Decrypt a legacy column blob (iv(12)||ct||tag(16)) with the old transcript key; null on failure. */
49
+ function decryptColumnBlob(blob, key) {
50
+ if (blob.length < 12 + 16)
51
+ return null;
52
+ const buf = Buffer.from(blob);
53
+ const iv = buf.subarray(0, 12);
54
+ const tag = buf.subarray(buf.length - 16);
55
+ const ct = buf.subarray(12, buf.length - 16);
56
+ try {
57
+ const d = createDecipheriv("aes-256-gcm", key, iv);
58
+ d.setAuthTag(tag);
59
+ return Uint8Array.from(Buffer.concat([d.update(ct), d.final()]));
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ /** Read + parse a flat JSON identity file, or null if absent. */
66
+ function readJson(path) {
67
+ if (!existsSync(path))
68
+ return null;
69
+ return JSON.parse(readFileSync(path, "utf8"));
70
+ }
71
+ /** Enumerate pre-story agent directories that hold a `key` file. */
72
+ function discoverFlatAgents(celloDir) {
73
+ const out = [];
74
+ const agentsDir = join(celloDir, "agents");
75
+ if (existsSync(agentsDir) && statSync(agentsDir).isDirectory()) {
76
+ for (const entry of readdirSync(agentsDir, { withFileTypes: true })) {
77
+ if (!entry.isDirectory())
78
+ continue;
79
+ const dir = join(agentsDir, entry.name);
80
+ const keyPath = join(dir, "key");
81
+ if (existsSync(keyPath))
82
+ out.push({ name: entry.name, dir, keyPath });
83
+ }
84
+ }
85
+ // Legacy single-file ~/.cello/key → agent "default" (only when there's no agents/default already).
86
+ const legacyKey = join(celloDir, "key");
87
+ if (existsSync(legacyKey) && !out.some((a) => a.name === "default")) {
88
+ out.push({ name: "default", dir: celloDir, keyPath: legacyKey });
89
+ }
90
+ return out;
91
+ }
92
+ /** True if there is any pre-story flat-file identity to migrate. */
93
+ function hasFlatIdentity(celloDir) {
94
+ return discoverFlatAgents(celloDir).length > 0;
95
+ }
96
+ const MANIFEST_FILE = "manifest-version.json";
97
+ /**
98
+ * Carry the legacy anti-rollback floor (`manifest-version.json`) into the encrypted `manifest_state`
99
+ * table. CRITICAL (fallback-finder HIGH): without this, an upgraded operator's last-seen manifest
100
+ * version resets to null on first start, re-opening a manifest-DOWNGRADE window for one cycle. The
101
+ * upsert keeps the MAX of any existing floor, so it can never LOWER the floor. Returns true if a
102
+ * value was imported.
103
+ */
104
+ function importManifestVersion(celloDir, db, logger) {
105
+ const obj = readJson(join(celloDir, MANIFEST_FILE));
106
+ if (!obj || typeof obj["lastSeenVersion"] !== "number")
107
+ return false;
108
+ ensureManifestSchema(db);
109
+ db.prepare(`INSERT INTO manifest_state (id, last_seen_version, updated_at) VALUES (1, ?, ?)
110
+ ON CONFLICT(id) DO UPDATE SET last_seen_version = MAX(last_seen_version, excluded.last_seen_version), updated_at = excluded.updated_at`).run(obj["lastSeenVersion"], Date.now());
111
+ logger.info("persist.manifest.version.migrated", { version: obj["lastSeenVersion"] });
112
+ return true;
113
+ }
114
+ /**
115
+ * Run the one-time migration if needed. Returns { migrated:false } when there is nothing to do
116
+ * (fresh install or an already-encrypted DB with no flat files).
117
+ */
118
+ export function migrateToEncryptedIfNeeded(dbPath, logger) {
119
+ const celloDir = dirname(dbPath);
120
+ const keyPath = dbKeyPathFor(dbPath);
121
+ const migratingPath = `${dbPath}.migrating`;
122
+ // Resume a crash in the tiny window between the backup-rename and the swap-rename: a COMPLETED
123
+ // `.migrating` exists but `dbPath` is gone. Promote it (instead of the in-place branch rebuilding a
124
+ // fresh EMPTY DB and orphaning the migrated session/transcript history — code-review M1). Only if it
125
+ // decrypts with the key; otherwise discard the partial and let the originals drive a fresh attempt.
126
+ if (!existsSync(dbPath) && existsSync(migratingPath) && existsSync(keyPath)) {
127
+ try {
128
+ const k = new Uint8Array(readFileSync(keyPath));
129
+ openEncryptedDatabase(migratingPath, k, logger).close(); // probe: decrypts?
130
+ renameSync(migratingPath, dbPath);
131
+ for (const ext of ["-wal", "-shm"]) {
132
+ if (existsSync(`${migratingPath}${ext}`))
133
+ renameSync(`${migratingPath}${ext}`, `${dbPath}${ext}`);
134
+ }
135
+ logger.warn("persist.identity.migrate.resumed", {});
136
+ }
137
+ catch {
138
+ for (const p of [migratingPath, `${migratingPath}-wal`, `${migratingPath}-shm`]) {
139
+ if (existsSync(p)) {
140
+ try {
141
+ unlinkSync(p);
142
+ }
143
+ catch { /* ignore */ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+ const plaintextDb = isPlaintextSqliteFile(dbPath);
149
+ const flatIdentity = hasFlatIdentity(celloDir);
150
+ // The legacy anti-rollback floor file ALSO requires a migration pass even when there is no flat
151
+ // identity / plaintext DB (an already-encrypted DB whose manifest floor still sits in a file).
152
+ const manifestFile = existsSync(join(celloDir, MANIFEST_FILE));
153
+ if (!plaintextDb && !flatIdentity && !manifestFile) {
154
+ return { migrated: false, agentsMigrated: 0, rowsMigrated: 0 };
155
+ }
156
+ // ── In-place flat-identity import: the DB is ALREADY encrypted (or absent) and only flat-file
157
+ // identity remains to be imported. There is NO plaintext DB to re-encrypt, so we must NOT build a
158
+ // fresh DB and swap it over the existing one (that would destroy the existing encrypted data —
159
+ // sessions, transcript, hash chain). Open the existing/created encrypted DB and import in place. ──
160
+ if (!plaintextDb) {
161
+ let key;
162
+ try {
163
+ key = resolveDbKey(dbPath, keyPath); // loads the existing key, or generates one if the DB is absent
164
+ }
165
+ catch (err) {
166
+ throw new IdentityMigrationError(`could not open the encrypted DB for in-place identity import: ${err instanceof Error ? err.message : String(err)}`, "Restore the SQLCipher key file, then restart.");
167
+ }
168
+ let db = null;
169
+ let agentsMigrated = 0;
170
+ try {
171
+ db = openEncryptedDatabase(dbPath, key, logger);
172
+ ensureIdentitySchema(db);
173
+ agentsMigrated = importFlatIdentity(celloDir, db, logger);
174
+ importManifestVersion(celloDir, db, logger); // carry the anti-rollback floor (HIGH)
175
+ db.close();
176
+ db = null;
177
+ }
178
+ catch (err) {
179
+ if (db) {
180
+ try {
181
+ db.close();
182
+ }
183
+ catch { /* ignore */ }
184
+ }
185
+ if (err instanceof IdentityMigrationError)
186
+ throw err;
187
+ throw new IdentityMigrationError(`in-place identity import failed: ${err instanceof Error ? err.message : String(err)}`, "The original flat files are untouched. Resolve the error and restart to retry.");
188
+ }
189
+ deleteFlatIdentity(celloDir, logger);
190
+ logger.info("persist.identity.migrated", { agentsMigrated, rowsMigrated: 0 });
191
+ return { migrated: true, agentsMigrated, rowsMigrated: 0 };
192
+ }
193
+ // ── Re-encrypt path: a PLAINTEXT DB exists. Build a fresh encrypted DB at `<dbPath>.migrating`
194
+ // (copying every row + importing flat identity), verify, then atomically swap it into place with a
195
+ // backup of the plaintext original. ──
196
+ // Clean any stale partial from a previously-interrupted attempt.
197
+ for (const p of [migratingPath, `${migratingPath}-wal`, `${migratingPath}-shm`]) {
198
+ if (existsSync(p))
199
+ unlinkSync(p);
200
+ }
201
+ // The SQLCipher key for the NEW encrypted DB. Reuse the key file if a prior attempt already wrote
202
+ // one; otherwise generate it via resolveDbKey on the migrating path (which has no DB yet → fresh).
203
+ let dbKey;
204
+ try {
205
+ dbKey = existsSync(keyPath)
206
+ ? new Uint8Array(readFileSync(keyPath))
207
+ : resolveDbKey(migratingPath, keyPath); // generates + writes keyPath (migrating DB absent → fresh)
208
+ }
209
+ catch (err) {
210
+ throw new IdentityMigrationError(`could not establish a SQLCipher key for migration: ${err instanceof Error ? err.message : String(err)}`, "Ensure the CELLO directory is writable, then restart.");
211
+ }
212
+ let encDb = null;
213
+ let agentsMigrated = 0;
214
+ let rowsMigrated = 0;
215
+ try {
216
+ encDb = openEncryptedDatabase(migratingPath, dbKey, logger);
217
+ ensureIdentitySchema(encDb);
218
+ // (1) Copy the old plaintext DB's schema + rows, decrypting the two column-ciphered blobs.
219
+ if (plaintextDb) {
220
+ rowsMigrated = copyPlaintextDb(dbPath, encDb, celloDir, logger);
221
+ }
222
+ // (2) Import flat-file identity into `agents` rows + the anti-rollback floor into manifest_state.
223
+ agentsMigrated = importFlatIdentity(celloDir, encDb, logger);
224
+ importManifestVersion(celloDir, encDb, logger);
225
+ encDb.close();
226
+ encDb = null;
227
+ }
228
+ catch (err) {
229
+ if (encDb) {
230
+ try {
231
+ encDb.close();
232
+ }
233
+ catch { /* ignore */ }
234
+ }
235
+ for (const p of [migratingPath, `${migratingPath}-wal`, `${migratingPath}-shm`]) {
236
+ if (existsSync(p)) {
237
+ try {
238
+ unlinkSync(p);
239
+ }
240
+ catch { /* ignore */ }
241
+ }
242
+ }
243
+ if (err instanceof IdentityMigrationError)
244
+ throw err;
245
+ throw new IdentityMigrationError(`migration failed before commit: ${err instanceof Error ? err.message : String(err)}`, "The original data is untouched. Resolve the error (e.g. disk space) and restart to retry.");
246
+ }
247
+ // ── Commit: back up + swap the DB, then delete the flat files. Past this point identity is in the
248
+ // encrypted DB; deleting the now-redundant plaintext originals completes the move. ──
249
+ try {
250
+ if (plaintextDb) {
251
+ renameSync(dbPath, `${dbPath}.pre-sqlcipher.bak`);
252
+ // The old WAL/SHM + the column-cipher key are superseded — remove them.
253
+ for (const p of [`${dbPath}-wal`, `${dbPath}-shm`, `${dbPath}.transcript-key`]) {
254
+ if (existsSync(p)) {
255
+ try {
256
+ unlinkSync(p);
257
+ }
258
+ catch { /* ignore */ }
259
+ }
260
+ }
261
+ }
262
+ renameSync(migratingPath, dbPath);
263
+ for (const p of [`${migratingPath}-wal`, `${migratingPath}-shm`]) {
264
+ if (existsSync(p))
265
+ renameSync(p, p.replace(`${dbPath}.migrating`, dbPath));
266
+ }
267
+ deleteFlatIdentity(celloDir, logger);
268
+ }
269
+ catch (err) {
270
+ throw new IdentityMigrationError(`migration failed during commit/cleanup: ${err instanceof Error ? err.message : String(err)}`, "Inspect the CELLO directory: a .pre-sqlcipher.bak backup of the original DB is retained.");
271
+ }
272
+ logger.info("persist.identity.migrated", { agentsMigrated, rowsMigrated });
273
+ return { migrated: true, agentsMigrated, rowsMigrated };
274
+ }
275
+ /**
276
+ * Copy every table + row from the old plaintext DB into the encrypted DB, decrypting the two
277
+ * column-ciphered blobs to plaintext. A row whose transcript/retry blob CANNOT be decrypted (the old
278
+ * transcript-key is missing or the blob fails GCM) is SKIPPED with a loud error — it is NEVER stored
279
+ * as ciphertext-masquerading-as-plaintext (which the rest of the daemon would TextDecode into garbage;
280
+ * fallback-finder HIGH). After each table, the copied count is VERIFIED against (old count − skipped);
281
+ * a mismatch means INSERT OR IGNORE silently dropped a row → abort (the docstring's "verify" is real).
282
+ */
283
+ function copyPlaintextDb(dbPath, encDb, _celloDir, logger) {
284
+ const old = new DatabaseSync(dbPath);
285
+ try {
286
+ const transcriptKeyPath = `${dbPath}.transcript-key`;
287
+ const transcriptKey = existsSync(transcriptKeyPath) ? readFileSync(transcriptKeyPath) : null;
288
+ const tables = old
289
+ .prepare("SELECT name, sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
290
+ .all().filter((t) => t.sql);
291
+ let totalCopied = 0;
292
+ for (const t of tables) {
293
+ // Recreate the table in the encrypted DB (the old CREATE statement, made idempotent).
294
+ encDb.exec(t.sql.replace(/^CREATE TABLE/i, "CREATE TABLE IF NOT EXISTS"));
295
+ const cols = old.prepare(`PRAGMA table_info(${t.name})`).all().map((c) => c.name);
296
+ if (cols.length === 0)
297
+ continue;
298
+ const allRows = old.prepare(`SELECT * FROM ${t.name}`).all();
299
+ if (allRows.length === 0)
300
+ continue;
301
+ const placeholders = cols.map(() => "?").join(", ");
302
+ const insert = encDb.prepare(`INSERT OR IGNORE INTO ${t.name} (${cols.join(", ")}) VALUES (${placeholders})`);
303
+ let copied = 0;
304
+ let skipped = 0;
305
+ for (const r of allRows) {
306
+ let undecryptable = false;
307
+ const values = cols.map((c) => {
308
+ let v = r[c];
309
+ if (v instanceof Uint8Array && ((t.name === "transcript" && c === "blob") || (t.name === "retry_queue" && c === "content_blob"))) {
310
+ const pt = transcriptKey ? decryptColumnBlob(v, transcriptKey) : null;
311
+ if (pt !== null)
312
+ v = Buffer.from(pt);
313
+ else
314
+ undecryptable = true;
315
+ }
316
+ return v;
317
+ });
318
+ if (undecryptable) {
319
+ // Drop the row rather than store ciphertext-as-plaintext (silent corruption). The session's
320
+ // authoritative hash chain (session_tree_leaves) is unaffected; only this readable copy is lost.
321
+ logger.error("persist.identity.migrate.blob.undecryptable", { table: t.name });
322
+ skipped++;
323
+ continue;
324
+ }
325
+ insert.run(...values);
326
+ copied++;
327
+ }
328
+ // Verify: every old row was either copied or deliberately skipped — none silently dropped by IGNORE.
329
+ const newCount = Number(encDb.prepare(`SELECT COUNT(*) AS c FROM ${t.name}`).get().c);
330
+ if (newCount !== copied) {
331
+ throw new IdentityMigrationError(`row-count mismatch migrating table '${t.name}': expected ${copied}, found ${newCount}`, "A row was unexpectedly dropped during migration. The original DB is untouched; restart to retry.");
332
+ }
333
+ if (skipped > 0)
334
+ logger.warn("persist.identity.migrate.table.partial", { table: t.name, copied, skipped });
335
+ totalCopied += copied;
336
+ }
337
+ return totalCopied;
338
+ }
339
+ finally {
340
+ old.close();
341
+ }
342
+ }
343
+ /** Quarantine an agent's flat files (key + sibling secrets) to `*.corrupt`. */
344
+ function quarantineFlatAgent(a, logger) {
345
+ for (const f of [a.keyPath, ...Object.values(REG_FILES).map((n) => join(a.dir, n))]) {
346
+ if (existsSync(f)) {
347
+ try {
348
+ renameSync(f, `${f}.corrupt`);
349
+ }
350
+ catch { /* ignore */ }
351
+ }
352
+ }
353
+ logger.warn("persist.identity.migrate.agent.quarantined", { agentName: a.name });
354
+ }
355
+ /** Import each pre-story agent's flat files into one `agents` row. Returns the count imported. */
356
+ function importFlatIdentity(celloDir, encDb, logger) {
357
+ const agents = discoverFlatAgents(celloDir);
358
+ let count = 0;
359
+ for (const a of agents) {
360
+ // Skip an agent that already exists in the encrypted DB (e.g. a prior in-place run imported it but
361
+ // a cleanup unlink failed) — never overwrite live DB identity with stale flat-file values
362
+ // (fallback-finder / code-review LOW). deleteFlatIdentity will remove the redundant files.
363
+ const exists = encDb.prepare("SELECT 1 AS one FROM agents WHERE agent_name = ?").get(a.name);
364
+ if (exists)
365
+ continue;
366
+ // K_local seed from the 37-byte CELLO key file. A corrupt key SKIPS the WHOLE agent — its key AND
367
+ // its sibling plaintext secrets (frost-share/ml-dsa/link) are quarantined to `*.corrupt` so no
368
+ // plaintext secret is left on disk (code-review HIGH). One unreadable agent must not down the
369
+ // daemon (availability); its identity is unrecoverable anyway, so the daemon starts without it.
370
+ let seed;
371
+ try {
372
+ seed = decodeKeyFileSeed(new Uint8Array(readFileSync(a.keyPath)));
373
+ }
374
+ catch (err) {
375
+ logger.error("persist.identity.migrate.key.corrupt", {
376
+ agentName: a.name,
377
+ error: err?.message ?? String(err),
378
+ });
379
+ quarantineFlatAgent(a, logger);
380
+ continue;
381
+ }
382
+ const pubkeyHex = Buffer.from(deriverPubkey(seed)).toString("hex");
383
+ const reg = readJson(join(a.dir, REG_FILES.reg));
384
+ const mlDsa = readJson(join(a.dir, REG_FILES.mlDsa));
385
+ const frost = readJson(join(a.dir, REG_FILES.frost));
386
+ const link = readJson(join(a.dir, REG_FILES.link));
387
+ const state = reg ? "registered" : "created";
388
+ const now = Date.now();
389
+ encDb
390
+ .prepare(`INSERT OR IGNORE INTO agents (agent_name, k_local_seed, k_local_pubkey, state, created_at, updated_at)
391
+ VALUES (?, ?, ?, ?, ?, ?)`)
392
+ .run(a.name, Buffer.from(seed), pubkeyHex, state, now, now);
393
+ if (mlDsa) {
394
+ encDb
395
+ .prepare("UPDATE agents SET ml_dsa_pubkey = ?, ml_dsa_secret = ?, ml_dsa_algorithm = ? WHERE agent_name = ?")
396
+ .run(String(mlDsa["mlDsaPubkey"]), Buffer.from(hexToBytes(String(mlDsa["secretKeyBlob"]))), String(mlDsa["algorithm"] ?? "ML-DSA-44"), a.name);
397
+ }
398
+ if (frost) {
399
+ encDb
400
+ .prepare(`UPDATE agents SET frost_epoch_id=?, frost_primary_pubkey=?, frost_identifier=?, frost_signing_share=?,
401
+ frost_threshold=?, frost_participants=?, frost_commitments=?, frost_verifying_shares=?, frost_dkg_method=?
402
+ WHERE agent_name=?`)
403
+ .run(String(frost["epochId"]), String(frost["primaryPubkey"]), String(frost["identifier"]), Buffer.from(hexToBytes(String(frost["signingShare"]))), Number(frost["threshold"]), Number(frost["participants"]), Buffer.from(hexToBytes(String(frost["commitmentsCbor"]))), Buffer.from(hexToBytes(String(frost["verifyingSharesCbor"]))), String(frost["dkgMethod"]), a.name);
404
+ }
405
+ if (reg) {
406
+ encDb
407
+ .prepare("UPDATE agents SET reg_agent_id=?, reg_primary_pubkey=?, reg_ml_dsa_pubkey=?, reg_registered_at=?, reg_status=? WHERE agent_name=?")
408
+ .run(String(reg["agentId"]), String(reg["primaryPubkey"]), String(reg["mlDsaPubkey"]), Number(reg["registeredAt"]), String(reg["status"] ?? "active"), a.name);
409
+ }
410
+ if (link) {
411
+ encDb
412
+ .prepare("UPDATE agents SET link_agent_id=?, link_pre_auth_token=?, link_linked_at=? WHERE agent_name=?")
413
+ .run(String(link["agentId"]), String(link["preAuthToken"]), Number(link["linkedAt"]), a.name);
414
+ }
415
+ // SI-001: never log the seed/share/secret — only the agent name + count.
416
+ logger.info("persist.identity.migrated.agent", { agentName: a.name, registered: reg != null });
417
+ count++;
418
+ }
419
+ return count;
420
+ }
421
+ /** Delete every flat-file identity artifact after a successful import. */
422
+ function deleteFlatIdentity(celloDir, logger) {
423
+ for (const a of discoverFlatAgents(celloDir)) {
424
+ for (const f of [a.keyPath, ...Object.values(REG_FILES).map((n) => join(a.dir, n))]) {
425
+ if (existsSync(f)) {
426
+ try {
427
+ unlinkSync(f);
428
+ }
429
+ catch (err) {
430
+ logger.warn("persist.identity.migrate.cleanup.failed", { file: f, error: String(err) });
431
+ }
432
+ }
433
+ }
434
+ }
435
+ // The legacy anti-rollback floor file — its value now lives in manifest_state (importManifestVersion).
436
+ const manifestPath = join(celloDir, MANIFEST_FILE);
437
+ if (existsSync(manifestPath)) {
438
+ try {
439
+ unlinkSync(manifestPath);
440
+ }
441
+ catch (err) {
442
+ logger.warn("persist.identity.migrate.cleanup.failed", { file: manifestPath, error: String(err) });
443
+ }
444
+ }
445
+ }
446
+ /** Derive the Ed25519 public key for a seed (migration helper). */
447
+ function deriverPubkey(seed) {
448
+ // InMemoryKeyProvider computes the pubkey in its constructor; getPublicKey is async, but the value
449
+ // is synchronous. We re-derive via a throwaway provider's toJSON (which exposes the hex) to avoid
450
+ // an async hop in this sync migration.
451
+ const provider = new InMemoryKeyProvider(seed);
452
+ const hex = provider.toJSON().publicKey;
453
+ return new Uint8Array(Buffer.from(hex, "hex"));
454
+ }
455
+ //# sourceMappingURL=identity-migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-migration.js","sourceRoot":"","sources":["../src/identity-migration.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,6 +13,6 @@ export type { ITransportSelector, TransportResult, TransportDialer, TransportDia
13
13
  export { FileManifestProvider } from "./manifest-loader.js";
14
14
  export { RandomizedPollScheduler, ImmediatePollScheduler } from "./manifest-poll-scheduler.js";
15
15
  export { InMemoryManifestVersionStore } from "./manifest-version-store.js";
16
- export { FileManifestVersionStore } from "./manifest-version-store-file.js";
16
+ export { DbManifestVersionStore } from "./manifest-version-store-db.js";
17
17
  export { ManifestDirectoryChallengeVerifier, TestDirectoryChallengeVerifier } from "./challenge-verifier.js";
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,eAAe,EACf,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,MAAM,EACN,eAAe,EACf,UAAU,EACV,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -13,6 +13,6 @@ export { TransportSelector, LocalTransportSelectorStub, TRANSPORT_ERROR, DEFAULT
13
13
  export { FileManifestProvider } from "./manifest-loader.js";
14
14
  export { RandomizedPollScheduler, ImmediatePollScheduler } from "./manifest-poll-scheduler.js";
15
15
  export { InMemoryManifestVersionStore } from "./manifest-version-store.js";
16
- export { FileManifestVersionStore } from "./manifest-version-store-file.js";
16
+ export { DbManifestVersionStore } from "./manifest-version-store-db.js";
17
17
  export { ManifestDirectoryChallengeVerifier, TestDirectoryChallengeVerifier } from "./challenge-verifier.js";
18
18
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAA4D,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAoF,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAA0D,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,qFAAqF;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AASjC,+DAA+D;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,UAAU,EAA4D,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAAE,eAAe,EAAoF,MAAM,iBAAiB,CAAC;AACpI,OAAO,EAAE,eAAe,EAAkB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,UAAU,EAA0D,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACvH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,qFAAqF;AACrF,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AASjC,+DAA+D;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,kCAAkC,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * CELLO-M7-PERSIST-002 (AC-008): DB-backed IManifestVersionStore.
3
+ *
4
+ * The last-seen manifest version (which backs the anti-rollback monotonicity invariant across daemon
5
+ * restarts) lives in the `manifest_state` singleton row of the SQLCipher-encrypted daemon DB — not a
6
+ * plaintext `manifest-version.json` file. Same interface as the old FileManifestVersionStore, so the
7
+ * SignalingManager that consumes it is unchanged.
8
+ *
9
+ * Crypto reference: RFC 8032 context — the version number is not itself cryptographic, but its
10
+ * correct, durable persistence is load-bearing for anti-rollback security (a reset enables a manifest
11
+ * downgrade attack). Whole-DB SQLCipher now protects it at rest along with all other client state.
12
+ */
13
+ import type { IManifestVersionStore } from "@cello-protocol/transport";
14
+ import type { DaemonDatabase } from "./sqlcipher-db.js";
15
+ import type { Logger } from "./types.js";
16
+ /** Idempotent schema for the singleton manifest-version row. */
17
+ export declare function ensureManifestSchema(db: DaemonDatabase): void;
18
+ export declare class DbManifestVersionStore implements IManifestVersionStore {
19
+ #private;
20
+ constructor(db: DaemonDatabase, logger: Logger);
21
+ getLastSeenVersion(): Promise<number | null>;
22
+ persistVersion(version: number): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=manifest-version-store-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-version-store-db.d.ts","sourceRoot":"","sources":["../src/manifest-version-store-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,gEAAgE;AAChE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAQ7D;AAED,qBAAa,sBAAuB,YAAW,qBAAqB;;gBAItD,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM;IAMxC,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAO5C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBrD"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * CELLO-M7-PERSIST-002 (AC-008): DB-backed IManifestVersionStore.
3
+ *
4
+ * The last-seen manifest version (which backs the anti-rollback monotonicity invariant across daemon
5
+ * restarts) lives in the `manifest_state` singleton row of the SQLCipher-encrypted daemon DB — not a
6
+ * plaintext `manifest-version.json` file. Same interface as the old FileManifestVersionStore, so the
7
+ * SignalingManager that consumes it is unchanged.
8
+ *
9
+ * Crypto reference: RFC 8032 context — the version number is not itself cryptographic, but its
10
+ * correct, durable persistence is load-bearing for anti-rollback security (a reset enables a manifest
11
+ * downgrade attack). Whole-DB SQLCipher now protects it at rest along with all other client state.
12
+ */
13
+ /** Idempotent schema for the singleton manifest-version row. */
14
+ export function ensureManifestSchema(db) {
15
+ db.exec(`
16
+ CREATE TABLE IF NOT EXISTS manifest_state (
17
+ id INTEGER PRIMARY KEY CHECK (id = 1),
18
+ last_seen_version INTEGER,
19
+ updated_at INTEGER NOT NULL
20
+ )
21
+ `);
22
+ }
23
+ export class DbManifestVersionStore {
24
+ #db;
25
+ #logger;
26
+ constructor(db, logger) {
27
+ this.#db = db;
28
+ this.#logger = logger;
29
+ ensureManifestSchema(db);
30
+ }
31
+ async getLastSeenVersion() {
32
+ const row = this.#db
33
+ .prepare("SELECT last_seen_version FROM manifest_state WHERE id = 1")
34
+ .get();
35
+ return row && row.last_seen_version != null ? Number(row.last_seen_version) : null;
36
+ }
37
+ async persistVersion(version) {
38
+ // Upsert the singleton row. Atomic within the encrypted DB — no temp-file rename dance.
39
+ try {
40
+ this.#db
41
+ .prepare(`INSERT INTO manifest_state (id, last_seen_version, updated_at)
42
+ VALUES (1, ?, ?)
43
+ ON CONFLICT(id) DO UPDATE SET last_seen_version = excluded.last_seen_version, updated_at = excluded.updated_at`)
44
+ .run(version, Date.now());
45
+ }
46
+ catch (err) {
47
+ // AC-012: a distinct, actionable failure — never a silent no-op (a lost anti-rollback version
48
+ // would re-open a manifest-downgrade window).
49
+ this.#logger.error("persist.manifest.persist.failed", { version, error: err instanceof Error ? err.message : String(err) });
50
+ const e = new Error(`manifest_persist_failed: ${err instanceof Error ? err.message : String(err)}`);
51
+ e.code = "manifest_persist_failed";
52
+ throw e;
53
+ }
54
+ this.#logger.info("persist.manifest.version.persisted", { version });
55
+ }
56
+ }
57
+ //# sourceMappingURL=manifest-version-store-db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-version-store-db.js","sourceRoot":"","sources":["../src/manifest-version-store-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,gEAAgE;AAChE,MAAM,UAAU,oBAAoB,CAAC,EAAkB;IACrD,EAAE,CAAC,IAAI,CAAC;;;;;;GAMP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,sBAAsB;IACxB,GAAG,CAAiB;IACpB,OAAO,CAAS;IAEzB,YAAY,EAAkB,EAAE,MAAc;QAC5C,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;QACd,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,oBAAoB,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG;aACjB,OAAO,CAAC,2DAA2D,CAAC;aACpE,GAAG,EAAsD,CAAC;QAC7D,OAAO,GAAG,IAAI,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrF,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,wFAAwF;QACxF,IAAI,CAAC;YACH,IAAI,CAAC,GAAG;iBACL,OAAO,CACN;;0HAEgH,CACjH;iBACA,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,8FAA8F;YAC9F,8CAA8C;YAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC5H,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnG,CAA+B,CAAC,IAAI,GAAG,yBAAyB,CAAC;YAClE,MAAM,CAAC,CAAC;QACV,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;CACF"}
@@ -6,7 +6,9 @@
6
6
  * number than the last-seen version is rejected as a potential rollback attack.
7
7
  *
8
8
  * InMemoryManifestVersionStore: stub for tests and initial deployments.
9
- * FileManifestVersionStore: file-backed bridge for cross-process persistence (AC-005).
9
+ * DbManifestVersionStore (manifest-version-store-db.ts): the production store the version lives in
10
+ * the SQLCipher-encrypted manifest_state table (PERSIST-002 AC-008). The old file-backed store was
11
+ * removed.
10
12
  */
11
13
  import type { IManifestVersionStore } from "@cello-protocol/transport";
12
14
  export { InMemoryManifestVersionStore } from "@cello-protocol/transport";
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-version-store.d.ts","sourceRoot":"","sources":["../src/manifest-version-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAEzE,YAAY,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"manifest-version-store.d.ts","sourceRoot":"","sources":["../src/manifest-version-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAEzE,YAAY,EAAE,qBAAqB,EAAE,CAAC"}