@camstack/system 1.2.27 → 1.2.29

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 (58) hide show
  1. package/dist/addon-runner.js +3 -3
  2. package/dist/addon-runner.mjs +2 -2
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/alerts/alerts.addon.d.ts +0 -7
  8. package/dist/builtins/alerts/alerts.addon.js +47 -25
  9. package/dist/builtins/alerts/alerts.addon.mjs +47 -25
  10. package/dist/builtins/alerts/prune-policy.d.ts +44 -0
  11. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  12. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  13. package/dist/builtins/console-logging/index.js +1 -1
  14. package/dist/builtins/console-logging/index.mjs +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  16. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  17. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  18. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  19. package/dist/builtins/hub-forwarder/index.js +1 -1
  20. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  21. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  22. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  23. package/dist/builtins/local-network/local-network.addon.js +1 -1
  24. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  25. package/dist/builtins/loki-logging/index.js +1 -1
  26. package/dist/builtins/loki-logging/index.mjs +1 -1
  27. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  28. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  29. package/dist/builtins/platform-probe/index.js +1 -1
  30. package/dist/builtins/platform-probe/index.mjs +1 -1
  31. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  32. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  33. package/dist/builtins/snapshot/index.js +1 -1
  34. package/dist/builtins/snapshot/index.mjs +1 -1
  35. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  36. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  37. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +7 -1
  38. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +8 -2
  39. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +22 -4
  40. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +22 -4
  41. package/dist/builtins/storage-orchestrator/data-store-dispatch.d.ts +12 -0
  42. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +18 -7
  43. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +78 -11
  44. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +78 -11
  45. package/dist/builtins/system-config/system-config.addon.js +1 -1
  46. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  47. package/dist/builtins/winston-logging/index.js +1 -1
  48. package/dist/builtins/winston-logging/index.mjs +1 -1
  49. package/dist/{dist-BXmFvn3h.mjs → dist-B7hOpr5i.mjs} +411 -166
  50. package/dist/{dist-BxtIzexq.js → dist-CPmFYLqq.js} +416 -165
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.js +106 -2
  53. package/dist/index.mjs +102 -3
  54. package/dist/kernel/heap-watch.d.ts +36 -0
  55. package/dist/kernel/transport/uds-event-bus.d.ts +4 -1
  56. package/dist/{manifest-python-deps-KZ00cbfP.js → manifest-python-deps-BqE5j0-O.js} +25 -4
  57. package/dist/{manifest-python-deps-BNOApgK0.mjs → manifest-python-deps-Ck4-9K9m.mjs} +25 -4
  58. package/package.json +7 -3
@@ -3,7 +3,7 @@ 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-BxtIzexq.js");
6
+ const require_dist = require("../../dist-CPmFYLqq.js");
7
7
  let node_crypto = require("node:crypto");
8
8
  let better_sqlite3 = require("better-sqlite3");
9
9
  better_sqlite3 = require_chunk.__toESM(better_sqlite3);
@@ -119,6 +119,18 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
119
119
  this.db?.close();
120
120
  this.db = null;
121
121
  }
122
+ /**
123
+ * `data-store-provider` self-description — how the orchestrator names
124
+ * this engine in a log line, and (once collections declare an engine)
125
+ * how it picks between registrants.
126
+ */
127
+ async getEngineInfo() {
128
+ return {
129
+ engineId: "sqlite",
130
+ kind: "relational",
131
+ displayName: "SQLite (WAL)"
132
+ };
133
+ }
122
134
  async get({ namespace, collection, key }) {
123
135
  const scoped = this.scopedName(namespace, collection);
124
136
  const decl = this.requireDeclared(scoped);
@@ -605,8 +617,14 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
605
617
  //#endregion
606
618
  //#region src/builtins/sqlite-storage/sqlite-settings.addon.ts
607
619
  /**
608
- * SQLite Settings addon — provides persistent settings storage.
609
- * Capability: 'settings-store' (singleton)
620
+ * SQLite Settings addon — the relational ENGINE behind the data door.
621
+ *
622
+ * Capability: `data-store-provider` (collection, internal). It does not
623
+ * serve `settings-store`: that is the public door, owned by
624
+ * storage-orchestrator, which dispatches here
625
+ * ([D44](../../../../../docs/decisions/adr-0044.md)). Callers reach this
626
+ * engine only through the door — which is the point, because it is what
627
+ * makes the engine replaceable.
610
628
  */
611
629
  var SqliteSettingsAddon = class extends require_dist.BaseAddon {
612
630
  backend = null;
@@ -635,7 +653,7 @@ var SqliteSettingsAddon = class extends require_dist.BaseAddon {
635
653
  await this.backend.initialize();
636
654
  this.ctx.logger.info("Initialized successfully");
637
655
  return [{
638
- capability: require_dist.settingsStoreCapability,
656
+ capability: require_dist.dataStoreProviderCapability,
639
657
  provider: this.backend
640
658
  }];
641
659
  }
@@ -1,4 +1,4 @@
1
- import { Et as parseJsonUnknown, X as settingsStoreCapability, at as BaseAddon, c as RUNTIME_DEFAULTS, ht as asJsonObject, it as errMsg } from "../../dist-BXmFvn3h.mjs";
1
+ import { Dt as parseJsonUnknown, at as errMsg, c as RUNTIME_DEFAULTS, gt as asJsonObject, ot as BaseAddon, x as dataStoreProviderCapability } from "../../dist-B7hOpr5i.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import Database from "better-sqlite3";
4
4
  //#region src/builtins/sqlite-storage/sqlite-settings-backend.ts
@@ -113,6 +113,18 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
113
113
  this.db?.close();
114
114
  this.db = null;
115
115
  }
116
+ /**
117
+ * `data-store-provider` self-description — how the orchestrator names
118
+ * this engine in a log line, and (once collections declare an engine)
119
+ * how it picks between registrants.
120
+ */
121
+ async getEngineInfo() {
122
+ return {
123
+ engineId: "sqlite",
124
+ kind: "relational",
125
+ displayName: "SQLite (WAL)"
126
+ };
127
+ }
116
128
  async get({ namespace, collection, key }) {
117
129
  const scoped = this.scopedName(namespace, collection);
118
130
  const decl = this.requireDeclared(scoped);
@@ -599,8 +611,14 @@ var SqliteSettingsBackend = class SqliteSettingsBackend {
599
611
  //#endregion
600
612
  //#region src/builtins/sqlite-storage/sqlite-settings.addon.ts
601
613
  /**
602
- * SQLite Settings addon — provides persistent settings storage.
603
- * Capability: 'settings-store' (singleton)
614
+ * SQLite Settings addon — the relational ENGINE behind the data door.
615
+ *
616
+ * Capability: `data-store-provider` (collection, internal). It does not
617
+ * serve `settings-store`: that is the public door, owned by
618
+ * storage-orchestrator, which dispatches here
619
+ * ([D44](../../../../../docs/decisions/adr-0044.md)). Callers reach this
620
+ * engine only through the door — which is the point, because it is what
621
+ * makes the engine replaceable.
604
622
  */
605
623
  var SqliteSettingsAddon = class extends BaseAddon {
606
624
  backend = null;
@@ -629,7 +647,7 @@ var SqliteSettingsAddon = class extends BaseAddon {
629
647
  await this.backend.initialize();
630
648
  this.ctx.logger.info("Initialized successfully");
631
649
  return [{
632
- capability: settingsStoreCapability,
650
+ capability: dataStoreProviderCapability,
633
651
  provider: this.backend
634
652
  }];
635
653
  }
@@ -0,0 +1,12 @@
1
+ import { IDataStoreProvider, ISettingsStoreProvider } from '@camstack/types';
2
+ /** How the dispatcher reaches the registered engines, read per call. */
3
+ export type GetDataStoreEngines = () => readonly IDataStoreProvider[];
4
+ /**
5
+ * Build the `settings-store` provider that fronts the registered engines.
6
+ *
7
+ * `getEngines` is read on every call, never captured: engines register
8
+ * during boot and a runner respawn replaces the instance, so a snapshot
9
+ * taken at construction time would go stale exactly when an addon crashed
10
+ * and came back.
11
+ */
12
+ export declare function createDataStoreDispatch(getEngines: GetDataStoreEngines): ISettingsStoreProvider;
@@ -25,16 +25,27 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
25
25
  protected onInitialize(): Promise<ProviderRegistration[]>;
26
26
  protected onShutdown(): Promise<void>;
27
27
  /**
28
- * Resolve the live `ISettingsBackend` from the capability registry
29
- * and wrap it in a `SqliteLocationStore`. Returns `null` when the
30
- * settings-store cap isn't registered yet — the service falls back
31
- * to in-memory only. Production boot order (sqlite-settings runs
32
- * before the orchestrator) makes this the rare path.
28
+ * Resolve the live engine from the capability registry and wrap it in a
29
+ * `SqliteLocationStore`. Returns `null` when no engine has registered
30
+ * yet — the service falls back to in-memory only. Production boot order
31
+ * (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
32
+ * makes this the rare path.
33
+ *
34
+ * Reads the ENGINE, not the `settings-store` singleton: since D44 this
35
+ * addon *is* that singleton, so asking the registry for it would hand
36
+ * the orchestrator its own dispatcher and route its location table back
37
+ * through itself.
38
+ *
39
+ * The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
40
+ * still open: those six methods live on the concrete backend and on no
41
+ * cap. Promoting them to the door is a separate task; until then this
42
+ * holds the engine object directly, which only works because the engine
43
+ * is in-process on this node.
33
44
  */
34
45
  private resolveLocationStore;
35
46
  /**
36
- * Late-wire the persistence store once the `settings-store` cap registers.
37
- * Production boot order means the store is usually absent at
47
+ * Late-wire the persistence store once a `data-store-provider` engine
48
+ * registers. Production boot order means the store is usually absent at
38
49
  * `onInitialize`; this runs on every `capability:provider-registered`
39
50
  * event until it succeeds. Single-flighted + idempotent (the service
40
51
  * ignores a second attach). Without this, operator edits (e.g. a
@@ -3,7 +3,7 @@ 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-BxtIzexq.js");
6
+ const require_dist = require("../../dist-CPmFYLqq.js");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_chunk.__toESM(node_path);
9
9
  let node_fs_promises = require("node:fs/promises");
@@ -730,6 +730,53 @@ async function collectProviderInfos(providers, onError) {
730
730
  return out;
731
731
  }
732
732
  //#endregion
733
+ //#region src/builtins/storage-orchestrator/data-store-dispatch.ts
734
+ /**
735
+ * Pick the engine to serve a call.
736
+ *
737
+ * Today the rule is "the only one there is". Two cases are refused rather
738
+ * than guessed:
739
+ *
740
+ * - **none registered** — resolving to a no-op would make every read
741
+ * answer `undefined` and every write disappear, which reads exactly
742
+ * like an empty database;
743
+ * - **more than one** — there is no routing rule yet. The `engine` hint
744
+ * on `declareCollection` is what will choose, and until it exists a
745
+ * silent pick would send a collection to whichever engine happened to
746
+ * register first.
747
+ */
748
+ function resolveEngine(getEngines) {
749
+ const engines = getEngines();
750
+ if (engines.length === 0) throw new Error("settings-store: no data-store-provider engine is registered — the data door has nothing behind it");
751
+ if (engines.length > 1) throw new Error(`settings-store: ${engines.length} data-store-provider engines are registered and there is no routing rule yet — declare the engine on the collection first`);
752
+ const engine = engines[0];
753
+ if (!engine) throw new Error("settings-store: data-store-provider collection yielded an empty entry");
754
+ return engine;
755
+ }
756
+ /**
757
+ * Build the `settings-store` provider that fronts the registered engines.
758
+ *
759
+ * `getEngines` is read on every call, never captured: engines register
760
+ * during boot and a runner respawn replaces the instance, so a snapshot
761
+ * taken at construction time would go stale exactly when an addon crashed
762
+ * and came back.
763
+ */
764
+ function createDataStoreDispatch(getEngines) {
765
+ const engine = async () => resolveEngine(getEngines);
766
+ return {
767
+ get: async (input) => (await engine()).get(input),
768
+ set: async (input) => (await engine()).set(input),
769
+ query: async (input) => (await engine()).query(input),
770
+ insert: async (input) => (await engine()).insert(input),
771
+ update: async (input) => (await engine()).update(input),
772
+ delete: async (input) => (await engine()).delete(input),
773
+ count: async (input) => (await engine()).count(input),
774
+ histogram: async (input) => (await engine()).histogram(input),
775
+ isEmpty: async (input) => (await engine()).isEmpty(input),
776
+ declareCollection: async (input) => (await engine()).declareCollection(input)
777
+ };
778
+ }
779
+ //#endregion
733
780
  //#region src/builtins/storage-orchestrator/storage-pressure-manager.ts
734
781
  var DEFAULT_MAX_ROUNDS = 8;
735
782
  var DEFAULT_HYSTERESIS_PERCENT = 1;
@@ -891,6 +938,7 @@ var StoragePressureManager = class {
891
938
  * Task 7 will migrate consumers off the legacy storage shim.
892
939
  */
893
940
  var STORAGE_PROVIDER_CAP_NAME = "storage-provider";
941
+ var DATA_STORE_PROVIDER_CAP_NAME = "data-store-provider";
894
942
  var STORAGE_EVICTABLE_CAP_NAME = "storage-evictable";
895
943
  /**
896
944
  * Single-node default: existing node-local locations live on the hub.
@@ -935,6 +983,11 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
935
983
  if (!reg) return [];
936
984
  return reg.getCollection(STORAGE_PROVIDER_CAP_NAME);
937
985
  };
986
+ const getEngines = () => {
987
+ const reg = this.ctx.kernel.capabilityRegistry;
988
+ if (!reg) return [];
989
+ return reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME);
990
+ };
938
991
  const locationStore = this.resolveLocationStore();
939
992
  const service = new StorageOrchestratorService(this.ctx.logger, getProviders, locationStore, this.ctx.kernel.localNodeId ?? "hub", (nodeId) => {
940
993
  const proxy = this.ctx.kernel.resolveNodeCapability?.("storage-provider", nodeId);
@@ -1126,6 +1179,9 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
1126
1179
  return [{
1127
1180
  capability: require_dist.storageCapability,
1128
1181
  provider
1182
+ }, {
1183
+ capability: require_dist.settingsStoreCapability,
1184
+ provider: createDataStoreDispatch(getEngines)
1129
1185
  }];
1130
1186
  }
1131
1187
  async onShutdown() {
@@ -1142,18 +1198,29 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
1142
1198
  this.service = null;
1143
1199
  }
1144
1200
  /**
1145
- * Resolve the live `ISettingsBackend` from the capability registry
1146
- * and wrap it in a `SqliteLocationStore`. Returns `null` when the
1147
- * settings-store cap isn't registered yet — the service falls back
1148
- * to in-memory only. Production boot order (sqlite-settings runs
1149
- * before the orchestrator) makes this the rare path.
1201
+ * Resolve the live engine from the capability registry and wrap it in a
1202
+ * `SqliteLocationStore`. Returns `null` when no engine has registered
1203
+ * yet — the service falls back to in-memory only. Production boot order
1204
+ * (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
1205
+ * makes this the rare path.
1206
+ *
1207
+ * Reads the ENGINE, not the `settings-store` singleton: since D44 this
1208
+ * addon *is* that singleton, so asking the registry for it would hand
1209
+ * the orchestrator its own dispatcher and route its location table back
1210
+ * through itself.
1211
+ *
1212
+ * The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
1213
+ * still open: those six methods live on the concrete backend and on no
1214
+ * cap. Promoting them to the door is a separate task; until then this
1215
+ * holds the engine object directly, which only works because the engine
1216
+ * is in-process on this node.
1150
1217
  */
1151
1218
  resolveLocationStore(quiet = false) {
1152
1219
  const reg = this.ctx.kernel.capabilityRegistry;
1153
1220
  if (!reg) return null;
1154
- const backend = reg.getSingleton("settings-store");
1221
+ const backend = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
1155
1222
  if (!backend) {
1156
- if (!quiet) this.ctx.logger.warn("storage-orchestrator: no settings-store provider yet — running in-memory until it registers");
1223
+ if (!quiet) this.ctx.logger.warn("storage-orchestrator: no data-store-provider engine yet — running in-memory until one registers");
1157
1224
  return null;
1158
1225
  }
1159
1226
  if (!backend.ensureTable || !backend.tableInsert) {
@@ -1163,8 +1230,8 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
1163
1230
  return new SqliteLocationStore(backend);
1164
1231
  }
1165
1232
  /**
1166
- * Late-wire the persistence store once the `settings-store` cap registers.
1167
- * Production boot order means the store is usually absent at
1233
+ * Late-wire the persistence store once a `data-store-provider` engine
1234
+ * registers. Production boot order means the store is usually absent at
1168
1235
  * `onInitialize`; this runs on every `capability:provider-registered`
1169
1236
  * event until it succeeds. Single-flighted + idempotent (the service
1170
1237
  * ignores a second attach). Without this, operator edits (e.g. a
@@ -1178,7 +1245,7 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
1178
1245
  if (this.storeWireInFlight) return this.storeWireInFlight;
1179
1246
  const store = this.resolveLocationStore(true);
1180
1247
  if (!store) return;
1181
- this.ctx.logger.info("storage-orchestrator: settings-store now available — wiring persistence");
1248
+ this.ctx.logger.info("storage-orchestrator: data-store engine now available — wiring persistence");
1182
1249
  this.storeWireInFlight = service.attachStore(store).then(() => this.seedFromDeclarations()).catch((err) => {
1183
1250
  this.ctx.logger.error("storage-orchestrator: attachStore failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
1184
1251
  }).finally(() => {
@@ -1,4 +1,4 @@
1
- import { Q as storageCapability, Tt as parseJsonObject, at as BaseAddon, d as StorageLocationTypeSchema } from "../../dist-BXmFvn3h.mjs";
1
+ import { $ as storageCapability, Et as parseJsonObject, Z as settingsStoreCapability, d as StorageLocationTypeSchema, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
2
2
  import * as path$1 from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { buildStorageLocationRegistry } from "@camstack/system";
@@ -723,6 +723,53 @@ async function collectProviderInfos(providers, onError) {
723
723
  return out;
724
724
  }
725
725
  //#endregion
726
+ //#region src/builtins/storage-orchestrator/data-store-dispatch.ts
727
+ /**
728
+ * Pick the engine to serve a call.
729
+ *
730
+ * Today the rule is "the only one there is". Two cases are refused rather
731
+ * than guessed:
732
+ *
733
+ * - **none registered** — resolving to a no-op would make every read
734
+ * answer `undefined` and every write disappear, which reads exactly
735
+ * like an empty database;
736
+ * - **more than one** — there is no routing rule yet. The `engine` hint
737
+ * on `declareCollection` is what will choose, and until it exists a
738
+ * silent pick would send a collection to whichever engine happened to
739
+ * register first.
740
+ */
741
+ function resolveEngine(getEngines) {
742
+ const engines = getEngines();
743
+ if (engines.length === 0) throw new Error("settings-store: no data-store-provider engine is registered — the data door has nothing behind it");
744
+ if (engines.length > 1) throw new Error(`settings-store: ${engines.length} data-store-provider engines are registered and there is no routing rule yet — declare the engine on the collection first`);
745
+ const engine = engines[0];
746
+ if (!engine) throw new Error("settings-store: data-store-provider collection yielded an empty entry");
747
+ return engine;
748
+ }
749
+ /**
750
+ * Build the `settings-store` provider that fronts the registered engines.
751
+ *
752
+ * `getEngines` is read on every call, never captured: engines register
753
+ * during boot and a runner respawn replaces the instance, so a snapshot
754
+ * taken at construction time would go stale exactly when an addon crashed
755
+ * and came back.
756
+ */
757
+ function createDataStoreDispatch(getEngines) {
758
+ const engine = async () => resolveEngine(getEngines);
759
+ return {
760
+ get: async (input) => (await engine()).get(input),
761
+ set: async (input) => (await engine()).set(input),
762
+ query: async (input) => (await engine()).query(input),
763
+ insert: async (input) => (await engine()).insert(input),
764
+ update: async (input) => (await engine()).update(input),
765
+ delete: async (input) => (await engine()).delete(input),
766
+ count: async (input) => (await engine()).count(input),
767
+ histogram: async (input) => (await engine()).histogram(input),
768
+ isEmpty: async (input) => (await engine()).isEmpty(input),
769
+ declareCollection: async (input) => (await engine()).declareCollection(input)
770
+ };
771
+ }
772
+ //#endregion
726
773
  //#region src/builtins/storage-orchestrator/storage-pressure-manager.ts
727
774
  var DEFAULT_MAX_ROUNDS = 8;
728
775
  var DEFAULT_HYSTERESIS_PERCENT = 1;
@@ -884,6 +931,7 @@ var StoragePressureManager = class {
884
931
  * Task 7 will migrate consumers off the legacy storage shim.
885
932
  */
886
933
  var STORAGE_PROVIDER_CAP_NAME = "storage-provider";
934
+ var DATA_STORE_PROVIDER_CAP_NAME = "data-store-provider";
887
935
  var STORAGE_EVICTABLE_CAP_NAME = "storage-evictable";
888
936
  /**
889
937
  * Single-node default: existing node-local locations live on the hub.
@@ -928,6 +976,11 @@ var StorageOrchestratorAddon = class extends BaseAddon {
928
976
  if (!reg) return [];
929
977
  return reg.getCollection(STORAGE_PROVIDER_CAP_NAME);
930
978
  };
979
+ const getEngines = () => {
980
+ const reg = this.ctx.kernel.capabilityRegistry;
981
+ if (!reg) return [];
982
+ return reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME);
983
+ };
931
984
  const locationStore = this.resolveLocationStore();
932
985
  const service = new StorageOrchestratorService(this.ctx.logger, getProviders, locationStore, this.ctx.kernel.localNodeId ?? "hub", (nodeId) => {
933
986
  const proxy = this.ctx.kernel.resolveNodeCapability?.("storage-provider", nodeId);
@@ -1119,6 +1172,9 @@ var StorageOrchestratorAddon = class extends BaseAddon {
1119
1172
  return [{
1120
1173
  capability: storageCapability,
1121
1174
  provider
1175
+ }, {
1176
+ capability: settingsStoreCapability,
1177
+ provider: createDataStoreDispatch(getEngines)
1122
1178
  }];
1123
1179
  }
1124
1180
  async onShutdown() {
@@ -1135,18 +1191,29 @@ var StorageOrchestratorAddon = class extends BaseAddon {
1135
1191
  this.service = null;
1136
1192
  }
1137
1193
  /**
1138
- * Resolve the live `ISettingsBackend` from the capability registry
1139
- * and wrap it in a `SqliteLocationStore`. Returns `null` when the
1140
- * settings-store cap isn't registered yet — the service falls back
1141
- * to in-memory only. Production boot order (sqlite-settings runs
1142
- * before the orchestrator) makes this the rare path.
1194
+ * Resolve the live engine from the capability registry and wrap it in a
1195
+ * `SqliteLocationStore`. Returns `null` when no engine has registered
1196
+ * yet — the service falls back to in-memory only. Production boot order
1197
+ * (`data-store-provider` precedes `storage` in `INFRA_CAPABILITIES`)
1198
+ * makes this the rare path.
1199
+ *
1200
+ * Reads the ENGINE, not the `settings-store` singleton: since D44 this
1201
+ * addon *is* that singleton, so asking the registry for it would hand
1202
+ * the orchestrator its own dispatcher and route its location table back
1203
+ * through itself.
1204
+ *
1205
+ * The `ensureTable` / `tableInsert` reach-around below is the B2 bypass,
1206
+ * still open: those six methods live on the concrete backend and on no
1207
+ * cap. Promoting them to the door is a separate task; until then this
1208
+ * holds the engine object directly, which only works because the engine
1209
+ * is in-process on this node.
1143
1210
  */
1144
1211
  resolveLocationStore(quiet = false) {
1145
1212
  const reg = this.ctx.kernel.capabilityRegistry;
1146
1213
  if (!reg) return null;
1147
- const backend = reg.getSingleton("settings-store");
1214
+ const backend = reg.getCollection(DATA_STORE_PROVIDER_CAP_NAME)[0];
1148
1215
  if (!backend) {
1149
- if (!quiet) this.ctx.logger.warn("storage-orchestrator: no settings-store provider yet — running in-memory until it registers");
1216
+ if (!quiet) this.ctx.logger.warn("storage-orchestrator: no data-store-provider engine yet — running in-memory until one registers");
1150
1217
  return null;
1151
1218
  }
1152
1219
  if (!backend.ensureTable || !backend.tableInsert) {
@@ -1156,8 +1223,8 @@ var StorageOrchestratorAddon = class extends BaseAddon {
1156
1223
  return new SqliteLocationStore(backend);
1157
1224
  }
1158
1225
  /**
1159
- * Late-wire the persistence store once the `settings-store` cap registers.
1160
- * Production boot order means the store is usually absent at
1226
+ * Late-wire the persistence store once a `data-store-provider` engine
1227
+ * registers. Production boot order means the store is usually absent at
1161
1228
  * `onInitialize`; this runs on every `capability:provider-registered`
1162
1229
  * event until it succeeds. Single-flighted + idempotent (the service
1163
1230
  * ignores a second attach). Without this, operator edits (e.g. a
@@ -1171,7 +1238,7 @@ var StorageOrchestratorAddon = class extends BaseAddon {
1171
1238
  if (this.storeWireInFlight) return this.storeWireInFlight;
1172
1239
  const store = this.resolveLocationStore(true);
1173
1240
  if (!store) return;
1174
- this.ctx.logger.info("storage-orchestrator: settings-store now available — wiring persistence");
1241
+ this.ctx.logger.info("storage-orchestrator: data-store engine now available — wiring persistence");
1175
1242
  this.storeWireInFlight = service.attachStore(store).then(() => this.seedFromDeclarations()).catch((err) => {
1176
1243
  this.ctx.logger.error("storage-orchestrator: attachStore failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
1177
1244
  }).finally(() => {
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BxtIzexq.js");
6
+ const require_dist = require("../../dist-CPmFYLqq.js");
7
7
  //#region src/builtins/system-config/system-config.addon.ts
8
8
  /**
9
9
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -1,4 +1,4 @@
1
- import { St as hydrateSchema, at as BaseAddon, it as errMsg } from "../../dist-BXmFvn3h.mjs";
1
+ import { Ct as hydrateSchema, at as errMsg, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
2
2
  //#region src/builtins/system-config/system-config.addon.ts
3
3
  /**
4
4
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -3,7 +3,7 @@ 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-BxtIzexq.js");
6
+ const require_dist = require("../../dist-CPmFYLqq.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { at as BaseAddon, z as logDestinationCapability } from "../../dist-BXmFvn3h.mjs";
1
+ import { B as logDestinationCapability, ot as BaseAddon } from "../../dist-B7hOpr5i.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  import * as path$1 from "node:path";
4
4
  import path from "node:path";