@camstack/system 1.2.458 → 1.2.460

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 (109) hide show
  1. package/dist/addon-runner.js +26 -11
  2. package/dist/addon-runner.mjs +26 -11
  3. package/dist/addon-utils.mjs +1 -1
  4. package/dist/{agent-https-DOELEug8.js → agent-https-Dnr_nIVx.js} +3 -723
  5. package/dist/{agent-https-CQA3W-3e.mjs → agent-https-Iw3RSQup.mjs} +4 -616
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
  10. package/dist/builtins/alerts/alerts.addon.js +5 -7
  11. package/dist/builtins/alerts/alerts.addon.mjs +5 -7
  12. package/dist/builtins/alerts/record-kinds.d.ts +1 -1
  13. package/dist/builtins/autotrack/index.js +1 -1
  14. package/dist/builtins/autotrack/index.mjs +1 -1
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +242 -4
  16. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +243 -5
  17. package/dist/builtins/calendars/calendars.addon.js +2 -10
  18. package/dist/builtins/calendars/calendars.addon.mjs +2 -3
  19. package/dist/builtins/calendars/record-kinds.d.ts +1 -1
  20. package/dist/builtins/camera-grid/index.js +1 -1
  21. package/dist/builtins/camera-grid/index.mjs +1 -1
  22. package/dist/builtins/composer/composer.addon.js +2 -2
  23. package/dist/builtins/composer/composer.addon.mjs +2 -2
  24. package/dist/builtins/console-logging/index.js +1 -1
  25. package/dist/builtins/console-logging/index.mjs +1 -1
  26. package/dist/builtins/core-blocks/core-blocks.addon.js +4 -6
  27. package/dist/builtins/core-blocks/core-blocks.addon.mjs +4 -6
  28. package/dist/builtins/device-history/device-history.addon.js +1 -1
  29. package/dist/builtins/device-history/device-history.addon.mjs +1 -1
  30. package/dist/builtins/device-manager/device-manager.addon.js +2 -4
  31. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -4
  32. package/dist/builtins/hub-forwarder/index.js +1 -1
  33. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  34. package/dist/builtins/keychain/index.js +41 -43
  35. package/dist/builtins/keychain/index.mjs +41 -43
  36. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  37. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  38. package/dist/builtins/local-auth/local-auth.addon.js +24 -40
  39. package/dist/builtins/local-auth/local-auth.addon.mjs +27 -43
  40. package/dist/builtins/local-network/local-network.addon.js +2 -2
  41. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  42. package/dist/builtins/loki-logging/index.js +1 -1
  43. package/dist/builtins/loki-logging/index.mjs +1 -1
  44. package/dist/builtins/native-metrics/native-metrics.addon.js +39 -4
  45. package/dist/builtins/native-metrics/native-metrics.addon.mjs +48 -13
  46. package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +16 -2
  47. package/dist/builtins/platform-probe/coral-accelerators.d.ts +10 -1
  48. package/dist/builtins/platform-probe/index.js +7 -4
  49. package/dist/builtins/platform-probe/index.mjs +13 -10
  50. package/dist/builtins/platform-probe/platform-scorer.d.ts +4 -1
  51. package/dist/builtins/record-entries/index.js +1 -1
  52. package/dist/builtins/record-entries/index.mjs +1 -1
  53. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  54. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  55. package/dist/builtins/snapshot/index.js +1 -1
  56. package/dist/builtins/snapshot/index.mjs +1 -1
  57. package/dist/builtins/sqlite-storage/file-host-protocol.d.ts +0 -15
  58. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  59. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +20 -20
  60. package/dist/builtins/sqlite-storage/index.js +1 -1
  61. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  62. package/dist/builtins/sqlite-storage/owned-sqlite-file.d.ts +0 -44
  63. package/dist/builtins/sqlite-storage/records/records-catalog.d.ts +0 -2
  64. package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +0 -21
  65. package/dist/builtins/sqlite-storage/records/records-engine.d.ts +3 -20
  66. package/dist/builtins/sqlite-storage/records/records-plan.d.ts +9 -4
  67. package/dist/builtins/sqlite-storage/records/records-provider.d.ts +4 -18
  68. package/dist/builtins/sqlite-storage/records/records-sql.d.ts +1 -1
  69. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +0 -17
  70. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +21 -196
  71. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +21 -196
  72. package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +6 -14
  73. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +2 -2
  74. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +7 -9
  75. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +7 -9
  76. package/dist/builtins/system-config/system-config.addon.js +667 -40
  77. package/dist/builtins/system-config/system-config.addon.mjs +737 -127
  78. package/dist/builtins/winston-logging/index.js +1 -1
  79. package/dist/builtins/winston-logging/index.mjs +1 -1
  80. package/dist/{composition-sources-BVguN7VV.mjs → composition-sources-DNRZWR1j.mjs} +1 -1
  81. package/dist/{composition-sources-DURQNDJ4.js → composition-sources-b0e_2I-D.js} +1 -1
  82. package/dist/{constants-Njka8Cv6.js → constants-6OeJiZgi.js} +1 -1
  83. package/dist/{constants-FGjnsE2x.mjs → constants-BnkOdj9Q.mjs} +1 -1
  84. package/dist/{coral-accelerators-DcnZvctM.mjs → coral-accelerators-Qhn5TOYZ.mjs} +18 -15
  85. package/dist/{coral-accelerators-Bi_c3Rft.js → coral-accelerators-oUXmmbc2.js} +13 -10
  86. package/dist/{custom-action-registry-stpC3Zy-.mjs → custom-action-registry-DStvrQKI.mjs} +37 -37
  87. package/dist/{device-ca-lEaAQ9Xi.mjs → device-ca-Bnkw8GyU.mjs} +1 -1
  88. package/dist/{device-ca-BrVK_5s3.js → device-ca-CPTDs--d.js} +1 -1
  89. package/dist/{dist-BZQjLPiz.js → dist-Bn-RNanh.js} +29 -130
  90. package/dist/{dist-B_GRPhnY.mjs → dist-Wy8cTxg6.mjs} +30 -113
  91. package/dist/file-host-worker.js +1 -1
  92. package/dist/file-host-worker.mjs +1 -1
  93. package/dist/{hub-mdns-ciao-Bg2HfTwP.mjs → hub-mdns-ciao-CJu0nhla.mjs} +2 -2
  94. package/dist/{hub-mdns-ciao-nce3TXs_.js → hub-mdns-ciao-CTBTlia4.js} +2 -2
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.js +56 -31
  97. package/dist/index.mjs +257 -233
  98. package/dist/kernel/deps/addon-deps-manager.d.ts +9 -0
  99. package/dist/{restore-archive-C7kLDI_0.mjs → restore-archive-CM23Pq9B.mjs} +177 -424
  100. package/dist/{restore-archive-FyfZ8YMC.js → restore-archive-DM1OBYq4.js} +89 -342
  101. package/dist/{wal-maintenance-Duejh7Lx.mjs → wal-maintenance-Bj_MmDkr.mjs} +0 -0
  102. package/dist/{wal-maintenance-DfSIOj24.js → wal-maintenance-CaJjuLHq.js} +0 -0
  103. package/package.json +1 -1
  104. package/dist/builtins/records/legacy-table-row-count.d.ts +0 -5
  105. package/dist/builtins/records/phase6-declare-gate.d.ts +0 -28
  106. package/dist/builtins/sqlite-storage/records/count-settings-array-legacy.d.ts +0 -5
  107. package/dist/builtins/sqlite-storage/records/count-settings-brokers-legacy.d.ts +0 -6
  108. package/dist/phase6-declare-gate-Dag1_WR2.js +0 -98
  109. package/dist/phase6-declare-gate-Lb-mrVvz.mjs +0 -93
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BZQjLPiz.js");
6
+ const require_dist = require("../../dist-Bn-RNanh.js");
7
7
  const require_retired_settings_keys = require("../../retired-settings-keys-D_VwZiDt.js");
8
- const require_wal_maintenance = require("../../wal-maintenance-DfSIOj24.js");
8
+ const require_wal_maintenance = require("../../wal-maintenance-CaJjuLHq.js");
9
9
  const require_sqlite_snapshot_protocol = require("../../sqlite-snapshot-protocol-B9OndqZv.js");
10
10
  const require_wal_checkpoint_policy = require("../../wal-checkpoint-policy-d2z2qPqx.js");
11
11
  let node_fs_promises = require("node:fs/promises");
@@ -937,9 +937,6 @@ var InlineOwnedFile = class extends OwnedFileBase {
937
937
  listPhysicalTables(ownerPrefix) {
938
938
  return Promise.resolve(require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "listPhysicalTables", { ownerPrefix }));
939
939
  }
940
- readLegacyCollection(input) {
941
- return Promise.resolve(require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "readLegacyCollection", input));
942
- }
943
940
  async dropRetiredTable(name) {
944
941
  return require_wal_maintenance.callControl(require_wal_maintenance.controlTargetOf(this.backend, 0), "dropRetiredTable", { name });
945
942
  }
@@ -997,9 +994,6 @@ var WorkerOwnedFile = class extends OwnedFileBase {
997
994
  listPhysicalTables(ownerPrefix) {
998
995
  return this.client.control("listPhysicalTables", { ownerPrefix });
999
996
  }
1000
- readLegacyCollection(input) {
1001
- return this.client.control("readLegacyCollection", input);
1002
- }
1003
997
  dropRetiredTable(name) {
1004
998
  return this.client.control("dropRetiredTable", { name });
1005
999
  }
@@ -1244,54 +1238,6 @@ var PlacementRouter = class {
1244
1238
  }
1245
1239
  };
1246
1240
  //#endregion
1247
- //#region src/builtins/sqlite-storage/records/count-settings-array-legacy.ts
1248
- function isRecord$1(value) {
1249
- return typeof value === "object" && value !== null && !Array.isArray(value);
1250
- }
1251
- function unwrapValue$1(raw) {
1252
- if (isRecord$1(raw) && "value" in raw) return raw["value"];
1253
- return raw;
1254
- }
1255
- function legacyRowId(item) {
1256
- const id = item["id"];
1257
- if (typeof id === "string" && id.length > 0) return id;
1258
- const username = item["username"];
1259
- if (typeof username === "string" && username.length > 0) return username;
1260
- return null;
1261
- }
1262
- async function countSettingsArrayLegacy(router, addonId, settingsKey) {
1263
- const list = unwrapValue$1(await router.get({
1264
- collection: "addon-settings",
1265
- key: `${addonId}.${settingsKey}`
1266
- }));
1267
- if (!Array.isArray(list)) return 0;
1268
- let n = 0;
1269
- for (const item of list) {
1270
- if (!isRecord$1(item)) continue;
1271
- if (legacyRowId(item) !== null) n += 1;
1272
- }
1273
- return n;
1274
- }
1275
- //#endregion
1276
- //#region src/builtins/sqlite-storage/records/count-settings-brokers-legacy.ts
1277
- function isRecord(value) {
1278
- return typeof value === "object" && value !== null && !Array.isArray(value);
1279
- }
1280
- function unwrapValue(raw) {
1281
- if (isRecord(raw) && "value" in raw) return raw["value"];
1282
- return raw;
1283
- }
1284
- async function countSettingsBrokersLegacy(router, addonId) {
1285
- const list = unwrapValue(await router.get({
1286
- collection: "addon-settings",
1287
- key: `${addonId}.brokers`
1288
- }));
1289
- if (!Array.isArray(list)) return 0;
1290
- let n = 0;
1291
- for (const item of list) if (isRecord(item) && typeof item["id"] === "string") n += 1;
1292
- return n;
1293
- }
1294
- //#endregion
1295
1241
  //#region src/builtins/sqlite-storage/records/records-provider.ts
1296
1242
  /**
1297
1243
  * The `records` capability of the engine (D881): resolves WHO is calling and
@@ -1304,9 +1250,9 @@ async function countSettingsBrokersLegacy(router, addonId) {
1304
1250
  * rebuilt from each open file's own `_record_kinds` at boot and updated on
1305
1251
  * declaration. A kind declared for another file than the one it lives in is
1306
1252
  * refused (the engine never moves data, D853).
1307
- * - **The boot guard**: after a declaration, a kind with `adoptsFrom` that is
1308
- * EMPTY while its legacy table still holds rows is reported `adoptionPending`;
1309
- * `ctx.records.declare` turns that into a refusal to start.
1253
+ * - **No adoption** (D900): the records migration is closed. A declaration
1254
+ * reads no legacy table, and a retired `adoptsFrom` an older addon still
1255
+ * sends is dropped before the catalog stores the declaration.
1310
1256
  */
1311
1257
  /** The caller the transport stamped, or a refusal. */
1312
1258
  function recordsCallerOf(input) {
@@ -1317,6 +1263,16 @@ function recordsCallerOf(input) {
1317
1263
  function keyOf(owner, kind) {
1318
1264
  return `${owner}\u0000${kind}`;
1319
1265
  }
1266
+ /**
1267
+ * A declaration as the catalog stores it: the retired `adoptsFrom` (D900) left
1268
+ * out, so the row an older addon's redeclaration writes no longer carries it.
1269
+ */
1270
+ function withoutRetiredKeys(declaration) {
1271
+ return {
1272
+ ...declaration,
1273
+ adoptsFrom: void 0
1274
+ };
1275
+ }
1320
1276
  var RecordsProvider = class {
1321
1277
  router;
1322
1278
  logger;
@@ -1350,7 +1306,7 @@ var RecordsProvider = class {
1350
1306
  const owner = recordsCallerOf(input);
1351
1307
  const byDatabase = /* @__PURE__ */ new Map();
1352
1308
  const parsed = /* @__PURE__ */ new Map();
1353
- for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, require_dist.RecordKindDeclarationSchema.parse(raw));
1309
+ for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, withoutRetiredKeys(require_dist.RecordKindDeclarationSchema.parse(raw)));
1354
1310
  await this.assertFamiliesInOneFile(owner, parsed);
1355
1311
  for (const [kind, declaration] of parsed) {
1356
1312
  const known = this.placement.get(keyOf(owner, kind));
@@ -1372,22 +1328,7 @@ var RecordsProvider = class {
1372
1328
  merged[kind] = result;
1373
1329
  }
1374
1330
  }
1375
- return { kinds: await this.withAdoption(owner, input.kinds, merged) };
1376
- }
1377
- /**
1378
- * Rows of a legacy table in EVERY open records-capable file. A legacy table lives
1379
- * in one file, but which one is the layout's business: the phase-3 NC ledgers moved
1380
- * to `events.db` with the P5 split, and a guard that asked `camstack.db` alone
1381
- * answered "no legacy rows" for 522 outbox rows (2026-10-20 audit).
1382
- */
1383
- async legacyRowsAnywhere(table) {
1384
- let total = 0;
1385
- for (const file of this.router.openFiles()) {
1386
- if (file.databaseId === "history") continue;
1387
- const rows = await file.records("legacyRowCount", { table });
1388
- if (rows !== null) total += rows;
1389
- }
1390
- return total;
1331
+ return { kinds: merged };
1391
1332
  }
1392
1333
  /**
1393
1334
  * `transactFamily` (plan risk 8): kinds that must agree through one `transact` sit
@@ -1418,52 +1359,6 @@ var RecordsProvider = class {
1418
1359
  throw new require_dist.DeclarationRefusedError(`transactFamily "${family}" of "${owner}" is split across files (${[...members.entries()].map(([k, db]) => `${k}@${db}`).join(", ")}); a family lives in ONE file`);
1419
1360
  }
1420
1361
  }
1421
- /** The boot guard: empty kind + a legacy table that still has rows = adoption pending. */
1422
- async withAdoption(owner, declared, results) {
1423
- const out = { ...results };
1424
- for (const [kind, raw] of Object.entries(declared)) {
1425
- const legacy = raw.adoptsFrom;
1426
- const result = results[kind];
1427
- if (legacy === void 0 || result === void 0) continue;
1428
- if ((await (await this.fileOf(owner, kind)).records("adoptionState", {
1429
- owner,
1430
- kind
1431
- })).adoptedAt !== null) continue;
1432
- const settingsBrokersAddon = require_dist.parseSettingsBrokersAdoptsFrom(legacy);
1433
- if (settingsBrokersAddon !== null) {
1434
- const legacyRows = await countSettingsBrokersLegacy(this.router, settingsBrokersAddon);
1435
- if (legacyRows > 0) out[kind] = {
1436
- ...result,
1437
- adoptionPending: {
1438
- legacyTable: legacy,
1439
- legacyRows
1440
- }
1441
- };
1442
- continue;
1443
- }
1444
- const settingsArray = require_dist.parseSettingsArrayAdoptsFrom(legacy);
1445
- if (settingsArray !== null) {
1446
- const legacyRows = await countSettingsArrayLegacy(this.router, settingsArray.addonId, settingsArray.settingsKey);
1447
- if (legacyRows > 0) out[kind] = {
1448
- ...result,
1449
- adoptionPending: {
1450
- legacyTable: legacy,
1451
- legacyRows
1452
- }
1453
- };
1454
- continue;
1455
- }
1456
- const legacyRows = await this.legacyRowsAnywhere(legacy);
1457
- if (legacyRows > 0) out[kind] = {
1458
- ...result,
1459
- adoptionPending: {
1460
- legacyTable: legacy,
1461
- legacyRows
1462
- }
1463
- };
1464
- }
1465
- return out;
1466
- }
1467
1362
  async get(input) {
1468
1363
  const owner = recordsCallerOf(input);
1469
1364
  return (await this.fileOf(owner, input.kind)).records("get", {
@@ -1597,50 +1492,6 @@ var RecordsProvider = class {
1597
1492
  } });
1598
1493
  return (await this.fileOf(input.owner, input.kind)).records("query", input);
1599
1494
  }
1600
- /** True when a declared kind lists `collection` as `adoptsFrom` and adoption finished. */
1601
- async isAdoptedLegacyTable(collection) {
1602
- const { kinds } = await this.listKinds({ counts: false });
1603
- for (const k of kinds) {
1604
- if (k.state === "dropped") continue;
1605
- if (k.declaration.adoptsFrom !== collection) continue;
1606
- const { adoptedAt } = await (await this.fileOf(k.owner, k.kind)).records("adoptionState", {
1607
- owner: k.owner,
1608
- kind: k.kind
1609
- });
1610
- if (adoptedAt !== null) return true;
1611
- }
1612
- return false;
1613
- }
1614
- async adoptRecords(input) {
1615
- const file = await this.fileOf(input.owner, input.kind);
1616
- if (input.records.length > 0) {
1617
- const { adoptedAt } = await file.records("adoptionState", {
1618
- owner: input.owner,
1619
- kind: input.kind
1620
- });
1621
- if (adoptedAt !== null) {
1622
- if ((await file.records("count", {
1623
- owner: input.owner,
1624
- kind: input.kind
1625
- })).count === 0) await file.records("revokeAdopted", {
1626
- owner: input.owner,
1627
- kind: input.kind
1628
- });
1629
- }
1630
- }
1631
- const result = await file.records("putMany", input);
1632
- if (input.complete === true) await file.records("markAdopted", {
1633
- owner: input.owner,
1634
- kind: input.kind
1635
- });
1636
- this.logger.warn("records: ADOPTED rows as their declared owner", { meta: {
1637
- owner: input.owner,
1638
- kind: input.kind,
1639
- count: result.count,
1640
- complete: input.complete === true
1641
- } });
1642
- return { adopted: result.count };
1643
- }
1644
1495
  /** Housekeeping: delete rows past `expires_at` in every file that hosts kinds. */
1645
1496
  async sweepExpired() {
1646
1497
  let deleted = 0;
@@ -1655,8 +1506,9 @@ var RecordsProvider = class {
1655
1506
  //#region src/builtins/sqlite-storage/storage-admin-provider.ts
1656
1507
  /**
1657
1508
  * The `storage-admin` provider of the SQLite engine (D870): the operator's
1658
- * maintenance reach into the settings database - list its tables, drop one that
1659
- * nothing owns any more. Every call is logged with its table and counts.
1509
+ * maintenance reach into the settings database - list its tables and record
1510
+ * kinds, read a kind for diagnosis, drop a table that nothing owns any more.
1511
+ * Every call is logged with its table and counts.
1660
1512
  *
1661
1513
  * `dropCollection` is a one-shot of the D870 migration: remove it, and the
1662
1514
  * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
@@ -1680,32 +1532,6 @@ var StorageAdminProvider = class {
1680
1532
  readRecords(input) {
1681
1533
  return this.records.readRecords(input);
1682
1534
  }
1683
- adoptRecords(input) {
1684
- return this.records.adoptRecords(input);
1685
- }
1686
- isAdoptedLegacyTable(input) {
1687
- return this.records.isAdoptedLegacyTable(input.collection).then((adopted) => ({ adopted }));
1688
- }
1689
- async readLegacyCollection(input) {
1690
- if (this.backend.hasTable(input.collection)) {
1691
- const page = this.backend.readLegacyCollection(input);
1692
- return {
1693
- rows: [...page.rows],
1694
- nextCursor: page.nextCursor
1695
- };
1696
- }
1697
- for (const file of await this.peerFiles()) if (await file.hasTable(input.collection)) {
1698
- const page = await file.readLegacyCollection(input);
1699
- return {
1700
- rows: [...page.rows],
1701
- nextCursor: page.nextCursor
1702
- };
1703
- }
1704
- return {
1705
- rows: [],
1706
- nextCursor: null
1707
- };
1708
- }
1709
1535
  /** May this table be dropped AT ALL? Throws with the reason when not. */
1710
1536
  async assertDroppable(collection) {
1711
1537
  const colon = collection.indexOf(":");
@@ -1717,7 +1543,7 @@ var StorageAdminProvider = class {
1717
1543
  throw new Error(`drop refused: the installed addons could not be read (${err instanceof Error ? err.message : String(err)})`);
1718
1544
  });
1719
1545
  const owner = collection.slice(0, colon);
1720
- if (installed.has(owner) && !await this.records.isAdoptedLegacyTable(collection)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1546
+ if (installed.has(owner)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1721
1547
  }
1722
1548
  async listTables(input) {
1723
1549
  const tables = [...this.backend.listTables(input.ownerPrefix)];
@@ -1732,7 +1558,6 @@ var StorageAdminProvider = class {
1732
1558
  async dropCollection(input) {
1733
1559
  try {
1734
1560
  await this.assertDroppable(input.collection);
1735
- if (await this.records.isAdoptedLegacyTable(input.collection)) this.backend.forgetDeclaredThisBoot(input.collection);
1736
1561
  const rows = this.backend.dropTable(input.collection, input.expectRows);
1737
1562
  this.logger.warn("storage-admin: DROPPED a table", { meta: {
1738
1563
  collection: input.collection,
@@ -1,6 +1,6 @@
1
- import { C as DATABASE_SNAPSHOT_TIMEOUT_MS, Jt as databaseSnapshotCapability, Ot as bareAddonId, Rr as vectorStoreCapability, S as DATABASE_SNAPSHOT_SUFFIX, Tr as storageAdminCapability, ar as recordsCapability, ci as DeclarationRefusedError, ji as UnknownRecordKindError, la as normalizeSecretOwner, ma as parseSettingsBrokersAdoptsFrom, ni as BaseAddon, ot as STORAGE_ADMIN_MOVED_COLLECTIONS, pa as parseSettingsArrayAdoptsFrom, pi as NoCallerError, qt as dataStoreProviderCapability, st as STORAGE_ADMIN_SCOPED_BASES, ti as errMsg, vi as RECORD_SWEEP_INTERVAL_MS, w as DATA_STORE_DATABASES, wi as RecordKindDeclarationSchema, x as DATABASE_SNAPSHOT_PARTIAL_SUFFIX, xi as RUNTIME_DEFAULTS } from "../../dist-B_GRPhnY.mjs";
1
+ import { C as DATABASE_SNAPSHOT_TIMEOUT_MS, Jt as databaseSnapshotCapability, Ot as bareAddonId, Rr as vectorStoreCapability, S as DATABASE_SNAPSHOT_SUFFIX, Tr as storageAdminCapability, ar as recordsCapability, ca as normalizeSecretOwner, ci as DeclarationRefusedError, ji as UnknownRecordKindError, ni as BaseAddon, ot as STORAGE_ADMIN_MOVED_COLLECTIONS, pi as NoCallerError, qt as dataStoreProviderCapability, st as STORAGE_ADMIN_SCOPED_BASES, ti as errMsg, vi as RECORD_SWEEP_INTERVAL_MS, w as DATA_STORE_DATABASES, wi as RecordKindDeclarationSchema, x as DATABASE_SNAPSHOT_PARTIAL_SUFFIX, xi as RUNTIME_DEFAULTS } from "../../dist-Wy8cTxg6.mjs";
2
2
  import { i as retiredKeyStoreOf, n as purgeRetiredSettingsKeys } from "../../retired-settings-keys-Bhwe4ymb.mjs";
3
- import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, S as trustResult, T as callData, _ as collectTransferables, a as WalMaintenance, c as vectorProviderOfOwnedFile, d as CrossDatabaseTransactError, f as DatabaseBusyError, l as SqliteSettingsBackend, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callControl } from "../../wal-maintenance-Duejh7Lx.mjs";
3
+ import { C as RecordsEngine, D as callVector, E as callRecords, O as controlTargetOf, S as trustResult, T as callData, _ as collectTransferables, a as WalMaintenance, c as vectorProviderOfOwnedFile, d as CrossDatabaseTransactError, f as DatabaseBusyError, l as SqliteSettingsBackend, m as rehydrateError, o as createVectorIndex, p as DuplicatePlacementError, s as vectorProviderOf, u as CollectionPlacementError, v as isFileHostMessage, w as callControl } from "../../wal-maintenance-Bj_MmDkr.mjs";
4
4
  import { r as isSnapshotWorkerMessage } from "../../sqlite-snapshot-protocol-2QaTouWV.mjs";
5
5
  import { a as isWorkerMessage, t as WAL_CHECKPOINT_LARGE_PASS_FRAMES } from "../../wal-checkpoint-policy-BahrTtyD.mjs";
6
6
  import { createRequire } from "node:module";
@@ -931,9 +931,6 @@ var InlineOwnedFile = class extends OwnedFileBase {
931
931
  listPhysicalTables(ownerPrefix) {
932
932
  return Promise.resolve(callControl(controlTargetOf(this.backend, 0), "listPhysicalTables", { ownerPrefix }));
933
933
  }
934
- readLegacyCollection(input) {
935
- return Promise.resolve(callControl(controlTargetOf(this.backend, 0), "readLegacyCollection", input));
936
- }
937
934
  async dropRetiredTable(name) {
938
935
  return callControl(controlTargetOf(this.backend, 0), "dropRetiredTable", { name });
939
936
  }
@@ -991,9 +988,6 @@ var WorkerOwnedFile = class extends OwnedFileBase {
991
988
  listPhysicalTables(ownerPrefix) {
992
989
  return this.client.control("listPhysicalTables", { ownerPrefix });
993
990
  }
994
- readLegacyCollection(input) {
995
- return this.client.control("readLegacyCollection", input);
996
- }
997
991
  dropRetiredTable(name) {
998
992
  return this.client.control("dropRetiredTable", { name });
999
993
  }
@@ -1238,54 +1232,6 @@ var PlacementRouter = class {
1238
1232
  }
1239
1233
  };
1240
1234
  //#endregion
1241
- //#region src/builtins/sqlite-storage/records/count-settings-array-legacy.ts
1242
- function isRecord$1(value) {
1243
- return typeof value === "object" && value !== null && !Array.isArray(value);
1244
- }
1245
- function unwrapValue$1(raw) {
1246
- if (isRecord$1(raw) && "value" in raw) return raw["value"];
1247
- return raw;
1248
- }
1249
- function legacyRowId(item) {
1250
- const id = item["id"];
1251
- if (typeof id === "string" && id.length > 0) return id;
1252
- const username = item["username"];
1253
- if (typeof username === "string" && username.length > 0) return username;
1254
- return null;
1255
- }
1256
- async function countSettingsArrayLegacy(router, addonId, settingsKey) {
1257
- const list = unwrapValue$1(await router.get({
1258
- collection: "addon-settings",
1259
- key: `${addonId}.${settingsKey}`
1260
- }));
1261
- if (!Array.isArray(list)) return 0;
1262
- let n = 0;
1263
- for (const item of list) {
1264
- if (!isRecord$1(item)) continue;
1265
- if (legacyRowId(item) !== null) n += 1;
1266
- }
1267
- return n;
1268
- }
1269
- //#endregion
1270
- //#region src/builtins/sqlite-storage/records/count-settings-brokers-legacy.ts
1271
- function isRecord(value) {
1272
- return typeof value === "object" && value !== null && !Array.isArray(value);
1273
- }
1274
- function unwrapValue(raw) {
1275
- if (isRecord(raw) && "value" in raw) return raw["value"];
1276
- return raw;
1277
- }
1278
- async function countSettingsBrokersLegacy(router, addonId) {
1279
- const list = unwrapValue(await router.get({
1280
- collection: "addon-settings",
1281
- key: `${addonId}.brokers`
1282
- }));
1283
- if (!Array.isArray(list)) return 0;
1284
- let n = 0;
1285
- for (const item of list) if (isRecord(item) && typeof item["id"] === "string") n += 1;
1286
- return n;
1287
- }
1288
- //#endregion
1289
1235
  //#region src/builtins/sqlite-storage/records/records-provider.ts
1290
1236
  /**
1291
1237
  * The `records` capability of the engine (D881): resolves WHO is calling and
@@ -1298,9 +1244,9 @@ async function countSettingsBrokersLegacy(router, addonId) {
1298
1244
  * rebuilt from each open file's own `_record_kinds` at boot and updated on
1299
1245
  * declaration. A kind declared for another file than the one it lives in is
1300
1246
  * refused (the engine never moves data, D853).
1301
- * - **The boot guard**: after a declaration, a kind with `adoptsFrom` that is
1302
- * EMPTY while its legacy table still holds rows is reported `adoptionPending`;
1303
- * `ctx.records.declare` turns that into a refusal to start.
1247
+ * - **No adoption** (D900): the records migration is closed. A declaration
1248
+ * reads no legacy table, and a retired `adoptsFrom` an older addon still
1249
+ * sends is dropped before the catalog stores the declaration.
1304
1250
  */
1305
1251
  /** The caller the transport stamped, or a refusal. */
1306
1252
  function recordsCallerOf(input) {
@@ -1311,6 +1257,16 @@ function recordsCallerOf(input) {
1311
1257
  function keyOf(owner, kind) {
1312
1258
  return `${owner}\u0000${kind}`;
1313
1259
  }
1260
+ /**
1261
+ * A declaration as the catalog stores it: the retired `adoptsFrom` (D900) left
1262
+ * out, so the row an older addon's redeclaration writes no longer carries it.
1263
+ */
1264
+ function withoutRetiredKeys(declaration) {
1265
+ return {
1266
+ ...declaration,
1267
+ adoptsFrom: void 0
1268
+ };
1269
+ }
1314
1270
  var RecordsProvider = class {
1315
1271
  router;
1316
1272
  logger;
@@ -1344,7 +1300,7 @@ var RecordsProvider = class {
1344
1300
  const owner = recordsCallerOf(input);
1345
1301
  const byDatabase = /* @__PURE__ */ new Map();
1346
1302
  const parsed = /* @__PURE__ */ new Map();
1347
- for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, RecordKindDeclarationSchema.parse(raw));
1303
+ for (const [kind, raw] of Object.entries(input.kinds)) parsed.set(kind, withoutRetiredKeys(RecordKindDeclarationSchema.parse(raw)));
1348
1304
  await this.assertFamiliesInOneFile(owner, parsed);
1349
1305
  for (const [kind, declaration] of parsed) {
1350
1306
  const known = this.placement.get(keyOf(owner, kind));
@@ -1366,22 +1322,7 @@ var RecordsProvider = class {
1366
1322
  merged[kind] = result;
1367
1323
  }
1368
1324
  }
1369
- return { kinds: await this.withAdoption(owner, input.kinds, merged) };
1370
- }
1371
- /**
1372
- * Rows of a legacy table in EVERY open records-capable file. A legacy table lives
1373
- * in one file, but which one is the layout's business: the phase-3 NC ledgers moved
1374
- * to `events.db` with the P5 split, and a guard that asked `camstack.db` alone
1375
- * answered "no legacy rows" for 522 outbox rows (2026-10-20 audit).
1376
- */
1377
- async legacyRowsAnywhere(table) {
1378
- let total = 0;
1379
- for (const file of this.router.openFiles()) {
1380
- if (file.databaseId === "history") continue;
1381
- const rows = await file.records("legacyRowCount", { table });
1382
- if (rows !== null) total += rows;
1383
- }
1384
- return total;
1325
+ return { kinds: merged };
1385
1326
  }
1386
1327
  /**
1387
1328
  * `transactFamily` (plan risk 8): kinds that must agree through one `transact` sit
@@ -1412,52 +1353,6 @@ var RecordsProvider = class {
1412
1353
  throw new DeclarationRefusedError(`transactFamily "${family}" of "${owner}" is split across files (${[...members.entries()].map(([k, db]) => `${k}@${db}`).join(", ")}); a family lives in ONE file`);
1413
1354
  }
1414
1355
  }
1415
- /** The boot guard: empty kind + a legacy table that still has rows = adoption pending. */
1416
- async withAdoption(owner, declared, results) {
1417
- const out = { ...results };
1418
- for (const [kind, raw] of Object.entries(declared)) {
1419
- const legacy = raw.adoptsFrom;
1420
- const result = results[kind];
1421
- if (legacy === void 0 || result === void 0) continue;
1422
- if ((await (await this.fileOf(owner, kind)).records("adoptionState", {
1423
- owner,
1424
- kind
1425
- })).adoptedAt !== null) continue;
1426
- const settingsBrokersAddon = parseSettingsBrokersAdoptsFrom(legacy);
1427
- if (settingsBrokersAddon !== null) {
1428
- const legacyRows = await countSettingsBrokersLegacy(this.router, settingsBrokersAddon);
1429
- if (legacyRows > 0) out[kind] = {
1430
- ...result,
1431
- adoptionPending: {
1432
- legacyTable: legacy,
1433
- legacyRows
1434
- }
1435
- };
1436
- continue;
1437
- }
1438
- const settingsArray = parseSettingsArrayAdoptsFrom(legacy);
1439
- if (settingsArray !== null) {
1440
- const legacyRows = await countSettingsArrayLegacy(this.router, settingsArray.addonId, settingsArray.settingsKey);
1441
- if (legacyRows > 0) out[kind] = {
1442
- ...result,
1443
- adoptionPending: {
1444
- legacyTable: legacy,
1445
- legacyRows
1446
- }
1447
- };
1448
- continue;
1449
- }
1450
- const legacyRows = await this.legacyRowsAnywhere(legacy);
1451
- if (legacyRows > 0) out[kind] = {
1452
- ...result,
1453
- adoptionPending: {
1454
- legacyTable: legacy,
1455
- legacyRows
1456
- }
1457
- };
1458
- }
1459
- return out;
1460
- }
1461
1356
  async get(input) {
1462
1357
  const owner = recordsCallerOf(input);
1463
1358
  return (await this.fileOf(owner, input.kind)).records("get", {
@@ -1591,50 +1486,6 @@ var RecordsProvider = class {
1591
1486
  } });
1592
1487
  return (await this.fileOf(input.owner, input.kind)).records("query", input);
1593
1488
  }
1594
- /** True when a declared kind lists `collection` as `adoptsFrom` and adoption finished. */
1595
- async isAdoptedLegacyTable(collection) {
1596
- const { kinds } = await this.listKinds({ counts: false });
1597
- for (const k of kinds) {
1598
- if (k.state === "dropped") continue;
1599
- if (k.declaration.adoptsFrom !== collection) continue;
1600
- const { adoptedAt } = await (await this.fileOf(k.owner, k.kind)).records("adoptionState", {
1601
- owner: k.owner,
1602
- kind: k.kind
1603
- });
1604
- if (adoptedAt !== null) return true;
1605
- }
1606
- return false;
1607
- }
1608
- async adoptRecords(input) {
1609
- const file = await this.fileOf(input.owner, input.kind);
1610
- if (input.records.length > 0) {
1611
- const { adoptedAt } = await file.records("adoptionState", {
1612
- owner: input.owner,
1613
- kind: input.kind
1614
- });
1615
- if (adoptedAt !== null) {
1616
- if ((await file.records("count", {
1617
- owner: input.owner,
1618
- kind: input.kind
1619
- })).count === 0) await file.records("revokeAdopted", {
1620
- owner: input.owner,
1621
- kind: input.kind
1622
- });
1623
- }
1624
- }
1625
- const result = await file.records("putMany", input);
1626
- if (input.complete === true) await file.records("markAdopted", {
1627
- owner: input.owner,
1628
- kind: input.kind
1629
- });
1630
- this.logger.warn("records: ADOPTED rows as their declared owner", { meta: {
1631
- owner: input.owner,
1632
- kind: input.kind,
1633
- count: result.count,
1634
- complete: input.complete === true
1635
- } });
1636
- return { adopted: result.count };
1637
- }
1638
1489
  /** Housekeeping: delete rows past `expires_at` in every file that hosts kinds. */
1639
1490
  async sweepExpired() {
1640
1491
  let deleted = 0;
@@ -1649,8 +1500,9 @@ var RecordsProvider = class {
1649
1500
  //#region src/builtins/sqlite-storage/storage-admin-provider.ts
1650
1501
  /**
1651
1502
  * The `storage-admin` provider of the SQLite engine (D870): the operator's
1652
- * maintenance reach into the settings database - list its tables, drop one that
1653
- * nothing owns any more. Every call is logged with its table and counts.
1503
+ * maintenance reach into the settings database - list its tables and record
1504
+ * kinds, read a kind for diagnosis, drop a table that nothing owns any more.
1505
+ * Every call is logged with its table and counts.
1654
1506
  *
1655
1507
  * `dropCollection` is a one-shot of the D870 migration: remove it, and the
1656
1508
  * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
@@ -1674,32 +1526,6 @@ var StorageAdminProvider = class {
1674
1526
  readRecords(input) {
1675
1527
  return this.records.readRecords(input);
1676
1528
  }
1677
- adoptRecords(input) {
1678
- return this.records.adoptRecords(input);
1679
- }
1680
- isAdoptedLegacyTable(input) {
1681
- return this.records.isAdoptedLegacyTable(input.collection).then((adopted) => ({ adopted }));
1682
- }
1683
- async readLegacyCollection(input) {
1684
- if (this.backend.hasTable(input.collection)) {
1685
- const page = this.backend.readLegacyCollection(input);
1686
- return {
1687
- rows: [...page.rows],
1688
- nextCursor: page.nextCursor
1689
- };
1690
- }
1691
- for (const file of await this.peerFiles()) if (await file.hasTable(input.collection)) {
1692
- const page = await file.readLegacyCollection(input);
1693
- return {
1694
- rows: [...page.rows],
1695
- nextCursor: page.nextCursor
1696
- };
1697
- }
1698
- return {
1699
- rows: [],
1700
- nextCursor: null
1701
- };
1702
- }
1703
1529
  /** May this table be dropped AT ALL? Throws with the reason when not. */
1704
1530
  async assertDroppable(collection) {
1705
1531
  const colon = collection.indexOf(":");
@@ -1711,7 +1537,7 @@ var StorageAdminProvider = class {
1711
1537
  throw new Error(`drop refused: the installed addons could not be read (${err instanceof Error ? err.message : String(err)})`);
1712
1538
  });
1713
1539
  const owner = collection.slice(0, colon);
1714
- if (installed.has(owner) && !await this.records.isAdoptedLegacyTable(collection)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1540
+ if (installed.has(owner)) throw new Error(`drop refused: "${collection}" belongs to the installed addon "${owner}"`);
1715
1541
  }
1716
1542
  async listTables(input) {
1717
1543
  const tables = [...this.backend.listTables(input.ownerPrefix)];
@@ -1726,7 +1552,6 @@ var StorageAdminProvider = class {
1726
1552
  async dropCollection(input) {
1727
1553
  try {
1728
1554
  await this.assertDroppable(input.collection);
1729
- if (await this.records.isAdoptedLegacyTable(input.collection)) this.backend.forgetDeclaredThisBoot(input.collection);
1730
1555
  const rows = this.backend.dropTable(input.collection, input.expectRows);
1731
1556
  this.logger.warn("storage-admin: DROPPED a table", { meta: {
1732
1557
  collection: input.collection,
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The `storage-admin` provider of the SQLite engine (D870): the operator's
3
- * maintenance reach into the settings database - list its tables, drop one that
4
- * nothing owns any more. Every call is logged with its table and counts.
3
+ * maintenance reach into the settings database - list its tables and record
4
+ * kinds, read a kind for diagnosis, drop a table that nothing owns any more.
5
+ * Every call is logged with its table and counts.
5
6
  *
6
7
  * `dropCollection` is a one-shot of the D870 migration: remove it, and the
7
8
  * capability's method, once the last hub ran `migrate-device-store.ts --drop`.
@@ -15,22 +16,13 @@ export declare class StorageAdminProvider implements IStorageAdminProvider {
15
16
  private readonly logger;
16
17
  /** The addon ids installed on this hub; a throw means "cannot tell" and refuses the drop. */
17
18
  private readonly installedOwners;
18
- /** The records provider the System -> Data and migration methods delegate to (D881). */
19
+ /** The records provider the System -> Data methods delegate to (D881). */
19
20
  private readonly records;
20
- /** Non-settings files (`events.db`, `history.db`) for legacy table listing and reads. */
21
+ /** Non-settings files (`events.db`, `history.db`) whose tables `listTables` lists too. */
21
22
  private readonly peerFiles;
22
- constructor(backend: SqliteSettingsBackend, logger: IScopedLogger, installedOwners: () => Promise<ReadonlySet<string>>, records: Pick<RecordsProvider, "listKinds" | "readRecords" | "adoptRecords" | "isAdoptedLegacyTable">, peerFiles?: () => Promise<readonly OwnedSqliteFile[]>);
23
+ constructor(backend: SqliteSettingsBackend, logger: IScopedLogger, installedOwners: () => Promise<ReadonlySet<string>>, records: Pick<RecordsProvider, "listKinds" | "readRecords">, peerFiles?: () => Promise<readonly OwnedSqliteFile[]>);
23
24
  listKinds(input: Parameters<IStorageAdminProvider["listKinds"]>[0]): ReturnType<IStorageAdminProvider["listKinds"]>;
24
25
  readRecords(input: Parameters<IStorageAdminProvider["readRecords"]>[0]): ReturnType<IStorageAdminProvider["readRecords"]>;
25
- adoptRecords(input: Parameters<IStorageAdminProvider["adoptRecords"]>[0]): ReturnType<IStorageAdminProvider["adoptRecords"]>;
26
- isAdoptedLegacyTable(input: {
27
- collection: string;
28
- }): ReturnType<IStorageAdminProvider["isAdoptedLegacyTable"]>;
29
- readLegacyCollection(input: {
30
- collection: string;
31
- cursor?: string | undefined;
32
- limit?: number | undefined;
33
- }): ReturnType<IStorageAdminProvider["readLegacyCollection"]>;
34
26
  /** May this table be dropped AT ALL? Throws with the reason when not. */
35
27
  private assertDroppable;
36
28
  listTables(input: {
@@ -104,8 +104,8 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
104
104
  * restart — the service never hydrates from / persists to SQLite.
105
105
  */
106
106
  private storeWireInFlight;
107
- /** True while the locations kind is empty and its legacy table still holds rows. */
108
- private adoptionIsPending;
107
+ /** True while the locations kind cannot be declared: its empty answer is not authoritative. */
108
+ private locationsKindNotReady;
109
109
  private ensureStoreWired;
110
110
  private storageProviders;
111
111
  /** Single-flighted pressure sweep — never overlaps a slow eviction round. */