@camstack/system 1.2.389 → 1.2.391

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 (503) hide show
  1. package/dist/addon/addon-api-factory.d.ts +30 -30
  2. package/dist/addon-routes/addon-route-registry.d.ts +31 -31
  3. package/dist/addon-runner.js +1 -1
  4. package/dist/addon-runner.mjs +1 -1
  5. package/dist/addon-utils.d.ts +22 -22
  6. package/dist/auth/admin-token-manager.d.ts +37 -67
  7. package/dist/auth/api-key-manager.d.ts +8 -8
  8. package/dist/auth/auth-audit-log.d.ts +29 -49
  9. package/dist/auth/auth-manager.d.ts +127 -126
  10. package/dist/auth/cidr.d.ts +8 -8
  11. package/dist/auth/external-identity-manager.d.ts +46 -34
  12. package/dist/auth/jwt-signing-key.d.ts +14 -14
  13. package/dist/auth/login-session-manager.d.ts +95 -135
  14. package/dist/auth/parse-record.d.ts +13 -13
  15. package/dist/auth/scope-matcher.d.ts +7 -7
  16. package/dist/auth/scoped-token-manager.d.ts +62 -62
  17. package/dist/auth/token-expiry.d.ts +49 -26
  18. package/dist/auth/totp-manager.d.ts +48 -48
  19. package/dist/auth/user-management-internal.d.ts +67 -52
  20. package/dist/auth/user-manager.d.ts +58 -58
  21. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +54 -54
  22. package/dist/builtins/addon-pages-aggregator/dedupe-pages.d.ts +22 -4
  23. package/dist/builtins/addon-pages-aggregator/index.d.ts +1 -1
  24. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +54 -54
  25. package/dist/builtins/addon-widgets-aggregator/index.d.ts +1 -1
  26. package/dist/builtins/alerts/alerts.addon.d.ts +88 -87
  27. package/dist/builtins/alerts/device-label.d.ts +6 -6
  28. package/dist/builtins/alerts/index.d.ts +1 -1
  29. package/dist/builtins/alerts/prune-policy.d.ts +36 -36
  30. package/dist/builtins/autotrack/autotrack-cameras.d.ts +102 -79
  31. package/dist/builtins/autotrack/autotrack-config.d.ts +81 -81
  32. package/dist/builtins/autotrack/autotrack-decision.d.ts +69 -82
  33. package/dist/builtins/autotrack/autotrack-loop.d.ts +81 -61
  34. package/dist/builtins/autotrack/autotrack.addon.d.ts +103 -66
  35. package/dist/builtins/autotrack/frame-error.d.ts +38 -38
  36. package/dist/builtins/autotrack/frame-measurements.d.ts +79 -79
  37. package/dist/builtins/autotrack/index.d.ts +2 -2
  38. package/dist/builtins/autotrack/ptz-mirror.d.ts +46 -17
  39. package/dist/builtins/autotrack/target-selection.d.ts +33 -47
  40. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +270 -269
  41. package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +17 -17
  42. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +99 -82
  43. package/dist/builtins/backup-orchestrator/download-helpers.d.ts +9 -9
  44. package/dist/builtins/backup-orchestrator/encryption-key-store.d.ts +40 -29
  45. package/dist/builtins/backup-orchestrator/index.d.ts +2 -2
  46. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +88 -69
  47. package/dist/builtins/backup-orchestrator/restore-archive.d.ts +14 -14
  48. package/dist/builtins/backup-orchestrator/run-queue.d.ts +86 -86
  49. package/dist/builtins/backup-orchestrator/schedule-store.d.ts +53 -37
  50. package/dist/builtins/backup-orchestrator/staging-paths.d.ts +23 -23
  51. package/dist/builtins/backup-orchestrator/write-targets.d.ts +53 -53
  52. package/dist/builtins/calendars/calendar-color.d.ts +5 -1
  53. package/dist/builtins/calendars/calendar-prefs-store.d.ts +18 -12
  54. package/dist/builtins/calendars/calendars.addon.d.ts +16 -11
  55. package/dist/builtins/calendars/index.d.ts +1 -1
  56. package/dist/builtins/camera-grid/acquire-retry.d.ts +26 -26
  57. package/dist/builtins/camera-grid/addon.d.ts +200 -174
  58. package/dist/builtins/camera-grid/flv-join.d.ts +32 -58
  59. package/dist/builtins/camera-grid/grid-activity-mirror.d.ts +37 -37
  60. package/dist/builtins/camera-grid/grid-activity.d.ts +83 -42
  61. package/dist/builtins/camera-grid/grid-camera-declarations.d.ts +46 -46
  62. package/dist/builtins/camera-grid/grid-camera-device.d.ts +60 -34
  63. package/dist/builtins/camera-grid/grid-canvas-derivation.d.ts +50 -15
  64. package/dist/builtins/camera-grid/grid-canvas-seed.d.ts +96 -46
  65. package/dist/builtins/camera-grid/grid-canvas.d.ts +74 -74
  66. package/dist/builtins/camera-grid/grid-child.d.ts +29 -16
  67. package/dist/builtins/camera-grid/grid-compositor-child.d.ts +2 -2
  68. package/dist/builtins/camera-grid/grid-compositor-invocation.d.ts +39 -11
  69. package/dist/builtins/camera-grid/grid-compositor.d.ts +50 -50
  70. package/dist/builtins/camera-grid/grid-detection-mapping.d.ts +52 -22
  71. package/dist/builtins/camera-grid/grid-device-settings.d.ts +31 -7
  72. package/dist/builtins/camera-grid/grid-filter-graph.d.ts +41 -41
  73. package/dist/builtins/camera-grid/grid-frame-sample.d.ts +45 -19
  74. package/dist/builtins/camera-grid/grid-instances.d.ts +20 -50
  75. package/dist/builtins/camera-grid/grid-last-frame-store.d.ts +51 -51
  76. package/dist/builtins/camera-grid/grid-layout-native-provider.d.ts +30 -4
  77. package/dist/builtins/camera-grid/grid-plan.d.ts +30 -20
  78. package/dist/builtins/camera-grid/grid-profiles.d.ts +85 -45
  79. package/dist/builtins/camera-grid/grid-row-normalization.d.ts +6 -6
  80. package/dist/builtins/camera-grid/grid-sentry-sources.d.ts +57 -57
  81. package/dist/builtins/camera-grid/grid-snapshot.d.ts +41 -41
  82. package/dist/builtins/camera-grid/grid-stream-descriptor.d.ts +49 -21
  83. package/dist/builtins/camera-grid/grid-stream-invocation.d.ts +37 -22
  84. package/dist/builtins/camera-grid/grid-stream-relay.d.ts +26 -26
  85. package/dist/builtins/camera-grid/grid-stream-session.d.ts +123 -93
  86. package/dist/builtins/camera-grid/grid-tile-feed.d.ts +47 -47
  87. package/dist/builtins/camera-grid/grid-tile-plan.d.ts +55 -20
  88. package/dist/builtins/camera-grid/grid-wire-format.d.ts +22 -6
  89. package/dist/builtins/camera-grid/index.d.ts +44 -44
  90. package/dist/builtins/camera-grid/silence-analysis.d.ts +31 -14
  91. package/dist/builtins/composer/claim-gate.d.ts +54 -27
  92. package/dist/builtins/composer/composed-device-set.d.ts +40 -26
  93. package/dist/builtins/composer/composed-device.d.ts +39 -17
  94. package/dist/builtins/composer/composer-apply-waits.d.ts +20 -13
  95. package/dist/builtins/composer/composer-grafts.d.ts +57 -38
  96. package/dist/builtins/composer/composer-live-set.d.ts +15 -15
  97. package/dist/builtins/composer/composer-plan.d.ts +76 -60
  98. package/dist/builtins/composer/composer-runtime-factory.d.ts +21 -14
  99. package/dist/builtins/composer/composer-seeds.d.ts +20 -14
  100. package/dist/builtins/composer/composer-verdict.d.ts +28 -14
  101. package/dist/builtins/composer/composer.addon.d.ts +23 -9
  102. package/dist/builtins/composer/composer.d.ts +145 -100
  103. package/dist/builtins/composer/composition-declarations.d.ts +50 -39
  104. package/dist/builtins/composer/composition-evaluation.d.ts +38 -22
  105. package/dist/builtins/composer/composition-runtime.d.ts +178 -125
  106. package/dist/builtins/composer/composition-target.d.ts +38 -34
  107. package/dist/builtins/composer/confirmed-seed.d.ts +35 -23
  108. package/dist/builtins/composer/deadline-timer.d.ts +13 -13
  109. package/dist/builtins/composer/existing-target.d.ts +90 -73
  110. package/dist/builtins/composer/field-record.d.ts +26 -19
  111. package/dist/builtins/composer/graft-host.d.ts +56 -32
  112. package/dist/builtins/composer/held-claims.d.ts +26 -9
  113. package/dist/builtins/composer/index.d.ts +1 -1
  114. package/dist/builtins/composer/own-field-reads.d.ts +26 -15
  115. package/dist/builtins/composer/owned-fields-target.d.ts +75 -44
  116. package/dist/builtins/composer/slice-assembler.d.ts +19 -3
  117. package/dist/builtins/composer/source-readings.d.ts +67 -61
  118. package/dist/builtins/composer/source-tracker.d.ts +133 -69
  119. package/dist/builtins/console-logging/console-destination.d.ts +15 -8
  120. package/dist/builtins/console-logging/console-logging.addon.d.ts +20 -19
  121. package/dist/builtins/console-logging/index.d.ts +3 -3
  122. package/dist/builtins/core-blocks/block-package.d.ts +37 -37
  123. package/dist/builtins/core-blocks/block-settings-store.d.ts +34 -21
  124. package/dist/builtins/core-blocks/block-supervisor.d.ts +138 -117
  125. package/dist/builtins/core-blocks/block-type-defs.d.ts +21 -21
  126. package/dist/builtins/core-blocks/blocks-integration.d.ts +76 -49
  127. package/dist/builtins/core-blocks/compile-block.d.ts +37 -37
  128. package/dist/builtins/core-blocks/composition-api.d.ts +38 -24
  129. package/dist/builtins/core-blocks/composition-peers.d.ts +26 -4
  130. package/dist/builtins/core-blocks/composition-sources.d.ts +25 -10
  131. package/dist/builtins/core-blocks/core-block-store.d.ts +109 -109
  132. package/dist/builtins/core-blocks/core-blocks.addon.d.ts +72 -72
  133. package/dist/builtins/core-blocks/extract-settings-schema.d.ts +4 -4
  134. package/dist/builtins/core-blocks/index.d.ts +8 -8
  135. package/dist/builtins/device-manager/adoption-job-engine.d.ts +141 -98
  136. package/dist/builtins/device-manager/claimed-status-overlay.d.ts +42 -9
  137. package/dist/builtins/device-manager/contribution-cache.d.ts +56 -56
  138. package/dist/builtins/device-manager/day-night-config-schema.d.ts +26 -12
  139. package/dist/builtins/device-manager/device-aggregation-merge.d.ts +17 -17
  140. package/dist/builtins/device-manager/device-aggregation.d.ts +277 -254
  141. package/dist/builtins/device-manager/device-bindings-store.d.ts +232 -220
  142. package/dist/builtins/device-manager/device-config-contribution.d.ts +29 -29
  143. package/dist/builtins/device-manager/device-config-secrets.d.ts +32 -13
  144. package/dist/builtins/device-manager/device-event-propagator.d.ts +22 -22
  145. package/dist/builtins/device-manager/device-extension-linked-slot.d.ts +17 -17
  146. package/dist/builtins/device-manager/device-form-secrets.d.ts +14 -14
  147. package/dist/builtins/device-manager/device-linked-devices.d.ts +159 -98
  148. package/dist/builtins/device-manager/device-manager.addon.d.ts +223 -197
  149. package/dist/builtins/device-manager/device-meta-actions.d.ts +306 -305
  150. package/dist/builtins/device-manager/device-meta-store.d.ts +100 -90
  151. package/dist/builtins/device-manager/device-meta-types.d.ts +250 -241
  152. package/dist/builtins/device-manager/device-online-fallback.d.ts +30 -30
  153. package/dist/builtins/device-manager/device-projection.d.ts +53 -67
  154. package/dist/builtins/device-manager/device-provider-context.d.ts +109 -94
  155. package/dist/builtins/device-manager/device-queries.d.ts +63 -63
  156. package/dist/builtins/device-manager/device-row-store.d.ts +417 -365
  157. package/dist/builtins/device-manager/device-source-activation.d.ts +91 -49
  158. package/dist/builtins/device-manager/device-state-claim-views.d.ts +76 -61
  159. package/dist/builtins/device-manager/device-state-claims.d.ts +53 -30
  160. package/dist/builtins/device-manager/device-state-mirror.d.ts +256 -264
  161. package/dist/builtins/device-manager/device-sync-resolvers.d.ts +25 -25
  162. package/dist/builtins/device-manager/field-claims-index.d.ts +85 -58
  163. package/dist/builtins/device-manager/field-ownership.d.ts +54 -36
  164. package/dist/builtins/device-manager/fleet-read-census.d.ts +99 -61
  165. package/dist/builtins/device-manager/image-settings-config-schema.d.ts +18 -8
  166. package/dist/builtins/device-manager/index.d.ts +2 -2
  167. package/dist/builtins/device-manager/linked-devices-manual-backfill.d.ts +20 -9
  168. package/dist/builtins/device-manager/location-alignment.d.ts +46 -46
  169. package/dist/builtins/device-manager/migrate-device.d.ts +178 -101
  170. package/dist/builtins/device-manager/migrate-guard.d.ts +66 -34
  171. package/dist/builtins/device-manager/migrate-hardware-state.d.ts +59 -59
  172. package/dist/builtins/device-manager/migrate-reload.d.ts +42 -4
  173. package/dist/builtins/device-manager/migration-refused.d.ts +20 -20
  174. package/dist/builtins/device-manager/mirror-row-writer.d.ts +205 -179
  175. package/dist/builtins/device-manager/recording-onboard-config-schema.d.ts +56 -32
  176. package/dist/builtins/device-manager/removal-fence.d.ts +48 -48
  177. package/dist/builtins/device-manager/runtime-state-persist-gate.d.ts +54 -26
  178. package/dist/builtins/device-manager/secret-config-paths.d.ts +17 -17
  179. package/dist/builtins/device-manager/stale-wrapper-activations.d.ts +52 -25
  180. package/dist/builtins/device-manager/write-lock.d.ts +13 -13
  181. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +41 -41
  182. package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +13 -12
  183. package/dist/builtins/hub-forwarder/index.d.ts +3 -3
  184. package/dist/builtins/keychain/index.d.ts +1 -1
  185. package/dist/builtins/keychain/key-sources.d.ts +19 -19
  186. package/dist/builtins/keychain/keychain-crypto.d.ts +4 -4
  187. package/dist/builtins/keychain/keychain-reset-trigger.d.ts +13 -13
  188. package/dist/builtins/keychain/keychain-service.d.ts +128 -128
  189. package/dist/builtins/keychain/keychain-store.d.ts +96 -87
  190. package/dist/builtins/keychain/keychain-usage.d.ts +13 -2
  191. package/dist/builtins/keychain/keychain.addon.d.ts +31 -6
  192. package/dist/builtins/keychain/platform-key-source.d.ts +15 -15
  193. package/dist/builtins/keychain/system-held-secrets.d.ts +17 -4
  194. package/dist/builtins/liveness-monitor/index.d.ts +2 -2
  195. package/dist/builtins/liveness-monitor/liveness-checks.d.ts +73 -52
  196. package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +57 -36
  197. package/dist/builtins/local-auth/admin-account-boot.d.ts +14 -14
  198. package/dist/builtins/local-auth/auth-config-reader.d.ts +34 -17
  199. package/dist/builtins/local-auth/auth-schema.d.ts +92 -69
  200. package/dist/builtins/local-auth/index.d.ts +1 -1
  201. package/dist/builtins/local-auth/jwt-signing-key-keeper.d.ts +22 -22
  202. package/dist/builtins/local-auth/local-auth.addon.d.ts +41 -40
  203. package/dist/builtins/local-auth/oauth-grants.d.ts +57 -57
  204. package/dist/builtins/local-auth/oauth-session-manager.d.ts +62 -62
  205. package/dist/builtins/local-network/address-book.d.ts +61 -36
  206. package/dist/builtins/local-network/index.d.ts +2 -2
  207. package/dist/builtins/local-network/ipv6-lan.d.ts +12 -17
  208. package/dist/builtins/local-network/local-hostname.d.ts +10 -10
  209. package/dist/builtins/local-network/local-network.addon.d.ts +259 -258
  210. package/dist/builtins/loki-logging/index.d.ts +4 -4
  211. package/dist/builtins/loki-logging/loki-destination.d.ts +113 -87
  212. package/dist/builtins/loki-logging/loki-logging.addon.d.ts +61 -42
  213. package/dist/builtins/loki-logging/loki-payload.d.ts +82 -39
  214. package/dist/builtins/loki-logging/retire-enabled-flag.d.ts +37 -12
  215. package/dist/builtins/native-metrics/cgroup-memory.d.ts +206 -159
  216. package/dist/builtins/native-metrics/cgroup-pids.d.ts +138 -91
  217. package/dist/builtins/native-metrics/container-memory-series.d.ts +212 -178
  218. package/dist/builtins/native-metrics/gpu-probe.d.ts +9 -9
  219. package/dist/builtins/native-metrics/index.d.ts +2 -2
  220. package/dist/builtins/native-metrics/load-series-config.d.ts +29 -57
  221. package/dist/builtins/native-metrics/load-series-reader.d.ts +52 -26
  222. package/dist/builtins/native-metrics/load-series-store.d.ts +237 -176
  223. package/dist/builtins/native-metrics/native-metrics-provider.d.ts +43 -43
  224. package/dist/builtins/native-metrics/native-metrics.addon.d.ts +230 -230
  225. package/dist/builtins/native-metrics/node-load-ring.d.ts +196 -196
  226. package/dist/builtins/native-metrics/proc-process-table.d.ts +12 -12
  227. package/dist/builtins/native-metrics/process-classification.d.ts +95 -36
  228. package/dist/builtins/native-metrics/thread-cpu-sampler.d.ts +95 -95
  229. package/dist/builtins/platform-probe/coral-accelerators.d.ts +17 -17
  230. package/dist/builtins/platform-probe/index.d.ts +38 -30
  231. package/dist/builtins/platform-probe/inference-config-resolver.d.ts +27 -27
  232. package/dist/builtins/platform-probe/intel-accelerators.d.ts +8 -8
  233. package/dist/builtins/platform-probe/intel-npu.d.ts +30 -30
  234. package/dist/builtins/platform-probe/platform-scorer.d.ts +35 -35
  235. package/dist/builtins/platform-probe/runtime-packages.d.ts +3 -3
  236. package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +87 -87
  237. package/dist/builtins/remote-access-orchestrator/index.d.ts +1 -1
  238. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +66 -35
  239. package/dist/builtins/shared/device-state-changed.d.ts +9 -9
  240. package/dist/builtins/shared/settle-sources.d.ts +16 -16
  241. package/dist/builtins/snapshot/index.d.ts +2 -2
  242. package/dist/builtins/snapshot/snapshot-cache.d.ts +92 -92
  243. package/dist/builtins/snapshot/snapshot-coalescing.d.ts +108 -108
  244. package/dist/builtins/snapshot/snapshot-courtesy.d.ts +48 -48
  245. package/dist/builtins/snapshot/snapshot-durable-store.d.ts +32 -32
  246. package/dist/builtins/snapshot/snapshot-fatigue.d.ts +34 -34
  247. package/dist/builtins/snapshot/snapshot-grab-pick.d.ts +14 -14
  248. package/dist/builtins/snapshot/snapshot-link-url.d.ts +49 -49
  249. package/dist/builtins/snapshot/snapshot-media-handler.d.ts +97 -97
  250. package/dist/builtins/snapshot/snapshot-resize.d.ts +64 -103
  251. package/dist/builtins/snapshot/snapshot.addon.d.ts +569 -568
  252. package/dist/builtins/sqlite-storage/analyze-stats.d.ts +73 -29
  253. package/dist/builtins/sqlite-storage/config-store.d.ts +6 -6
  254. package/dist/builtins/sqlite-storage/device-store.d.ts +16 -16
  255. package/dist/builtins/sqlite-storage/filesystem-browse-provider.d.ts +23 -23
  256. package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +79 -79
  257. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +27 -26
  258. package/dist/builtins/sqlite-storage/filter-compiler.d.ts +107 -107
  259. package/dist/builtins/sqlite-storage/index.d.ts +12 -12
  260. package/dist/builtins/sqlite-storage/integration-registry.d.ts +37 -37
  261. package/dist/builtins/sqlite-storage/path-guard.d.ts +5 -5
  262. package/dist/builtins/sqlite-storage/prefix-range.d.ts +44 -44
  263. package/dist/builtins/sqlite-storage/query-bounds.d.ts +100 -106
  264. package/dist/builtins/sqlite-storage/query-profiler.d.ts +217 -217
  265. package/dist/builtins/sqlite-storage/retired-collections.d.ts +124 -55
  266. package/dist/builtins/sqlite-storage/retired-settings-keys.d.ts +239 -189
  267. package/dist/builtins/sqlite-storage/shm-lock-canary.d.ts +41 -41
  268. package/dist/builtins/sqlite-storage/sqlite-pragmas.d.ts +162 -162
  269. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +458 -458
  270. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +59 -58
  271. package/dist/builtins/sqlite-storage/sqlite-snapshot-protocol.d.ts +37 -32
  272. package/dist/builtins/sqlite-storage/sqlite-snapshot-worker.d.ts +19 -19
  273. package/dist/builtins/sqlite-storage/sqlite-snapshotter.d.ts +76 -76
  274. package/dist/builtins/sqlite-storage/statement-shape.d.ts +54 -54
  275. package/dist/builtins/sqlite-storage/table-sizes.d.ts +71 -71
  276. package/dist/builtins/sqlite-storage/vector-index-shared.d.ts +63 -54
  277. package/dist/builtins/sqlite-storage/vector-index-vec.d.ts +133 -96
  278. package/dist/builtins/sqlite-storage/wal-checkpoint-policy.d.ts +161 -161
  279. package/dist/builtins/sqlite-storage/wal-checkpointer.d.ts +60 -60
  280. package/dist/builtins/sqlite-storage/wal-maintenance.d.ts +94 -94
  281. package/dist/builtins/storage-orchestrator/access-guards.d.ts +37 -26
  282. package/dist/builtins/storage-orchestrator/data-store-dispatch.d.ts +33 -18
  283. package/dist/builtins/storage-orchestrator/drain-ratchet.d.ts +85 -85
  284. package/dist/builtins/storage-orchestrator/drain-state-store.d.ts +20 -10
  285. package/dist/builtins/storage-orchestrator/hub-settings-forward.d.ts +113 -53
  286. package/dist/builtins/storage-orchestrator/index.d.ts +7 -7
  287. package/dist/builtins/storage-orchestrator/location-occupancy-slice.d.ts +64 -40
  288. package/dist/builtins/storage-orchestrator/location-occupancy.d.ts +14 -14
  289. package/dist/builtins/storage-orchestrator/location-protection.d.ts +13 -13
  290. package/dist/builtins/storage-orchestrator/location-repoint-move.d.ts +44 -44
  291. package/dist/builtins/storage-orchestrator/location-root-collision.d.ts +61 -25
  292. package/dist/builtins/storage-orchestrator/location-secrets.d.ts +99 -58
  293. package/dist/builtins/storage-orchestrator/location-store.d.ts +56 -47
  294. package/dist/builtins/storage-orchestrator/location-volume-capacity.d.ts +37 -37
  295. package/dist/builtins/storage-orchestrator/provider-discovery.d.ts +20 -6
  296. package/dist/builtins/storage-orchestrator/storage-cleanup-coordinator.d.ts +51 -51
  297. package/dist/builtins/storage-orchestrator/storage-migration-coordinator.d.ts +224 -224
  298. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +292 -292
  299. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +431 -450
  300. package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +104 -104
  301. package/dist/builtins/system-backup/backup-encryption.d.ts +60 -23
  302. package/dist/builtins/system-backup/system-backup.service.d.ts +240 -240
  303. package/dist/builtins/system-config/cluster-secret-keeper.d.ts +54 -34
  304. package/dist/builtins/system-config/index.d.ts +2 -2
  305. package/dist/builtins/system-config/mesh-actions.d.ts +2 -30
  306. package/dist/builtins/system-config/system-config.addon.d.ts +57 -93
  307. package/dist/builtins/system-config/system-config.addon.js +46 -33
  308. package/dist/builtins/system-config/system-config.addon.mjs +46 -33
  309. package/dist/builtins/winston-logging/index.d.ts +3 -3
  310. package/dist/builtins/winston-logging/winston-destination.d.ts +15 -15
  311. package/dist/builtins/winston-logging/winston-logging.addon.d.ts +14 -13
  312. package/dist/{child-cap-dispatch-nURMuVTX.js → child-cap-dispatch-Bnr8brru.js} +18 -0
  313. package/dist/{child-cap-dispatch-B1gyE35b.mjs → child-cap-dispatch-mHO_6r0G.mjs} +1 -1
  314. package/dist/download/hosted-model-revisions.d.ts +8 -8
  315. package/dist/download/model-download-service.d.ts +32 -32
  316. package/dist/download/model-downloader.d.ts +88 -88
  317. package/dist/events/event-bus.d.ts +6 -6
  318. package/dist/events/system-event-bus.d.ts +11 -11
  319. package/dist/feature/feature-manager.d.ts +6 -6
  320. package/dist/http/asset-compression.d.ts +35 -73
  321. package/dist/http/authenticated-file-server.d.ts +32 -32
  322. package/dist/http/data-plane-registry.d.ts +49 -39
  323. package/dist/http/file-data-plane.d.ts +14 -14
  324. package/dist/http/lan-http-bind.d.ts +24 -13
  325. package/dist/http/reverse-proxy.d.ts +36 -24
  326. package/dist/index.d.ts +137 -137
  327. package/dist/index.js +4 -3
  328. package/dist/index.mjs +2 -4
  329. package/dist/kernel/addon-class-resolver.d.ts +1 -1
  330. package/dist/kernel/addon-engine-manager.d.ts +20 -20
  331. package/dist/kernel/addon-health-monitor.d.ts +151 -151
  332. package/dist/kernel/addon-installer.d.ts +609 -609
  333. package/dist/kernel/addon-loader.d.ts +133 -133
  334. package/dist/kernel/addon-manifest.d.ts +118 -118
  335. package/dist/kernel/addon-residue.d.ts +28 -32
  336. package/dist/kernel/array-buffer-census.d.ts +84 -88
  337. package/dist/kernel/bootstrap-config.d.ts +3 -3
  338. package/dist/kernel/cap-router-builder.d.ts +145 -101
  339. package/dist/kernel/capability-handle.d.ts +41 -41
  340. package/dist/kernel/capability-registry.d.ts +588 -576
  341. package/dist/kernel/config-manager.d.ts +199 -199
  342. package/dist/kernel/config-schema.d.ts +132 -128
  343. package/dist/kernel/custom-action-registry.d.ts +25 -25
  344. package/dist/kernel/deps/addon-deps-manager.d.ts +17 -17
  345. package/dist/kernel/deps/closure-dedupe.d.ts +76 -76
  346. package/dist/kernel/deps/ensure-addon-natives.d.ts +34 -34
  347. package/dist/kernel/deps/ensure-native-prebuilds.d.ts +25 -25
  348. package/dist/kernel/deps/manifest-native-deps.d.ts +38 -38
  349. package/dist/kernel/deps/manifest-python-deps.d.ts +18 -18
  350. package/dist/kernel/deps/manifest-system-deps.d.ts +13 -13
  351. package/dist/kernel/deps/npm-command.d.ts +45 -45
  352. package/dist/kernel/deps/system-package-allowlist.d.ts +9 -9
  353. package/dist/kernel/deps/system-package-broker.d.ts +20 -20
  354. package/dist/kernel/deps/system-package-client.d.ts +3 -3
  355. package/dist/kernel/device-registry.d.ts +27 -27
  356. package/dist/kernel/event-loop-stall-monitor.d.ts +33 -33
  357. package/dist/kernel/event-plane-report.d.ts +174 -174
  358. package/dist/kernel/fs-utils.d.ts +70 -70
  359. package/dist/kernel/gc-census.d.ts +119 -119
  360. package/dist/kernel/heap-spaces.d.ts +87 -87
  361. package/dist/kernel/heap-watch.d.ts +706 -706
  362. package/dist/kernel/host-externals.d.ts +8 -8
  363. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +27 -27
  364. package/dist/kernel/index.d.ts +115 -113
  365. package/dist/kernel/inference/inference-resolver.d.ts +13 -13
  366. package/dist/kernel/infra-capabilities.d.ts +7 -7
  367. package/dist/kernel/isolated-builtin-phase.d.ts +42 -42
  368. package/dist/kernel/lifecycle/job-journal.d.ts +17 -17
  369. package/dist/kernel/lifecycle/lifecycle-job-engine.d.ts +99 -99
  370. package/dist/kernel/lifecycle/staging-area.d.ts +22 -22
  371. package/dist/kernel/moleculer/addon-context-factory.d.ts +90 -89
  372. package/dist/kernel/moleculer/addon-data-plane-facility.d.ts +12 -12
  373. package/dist/kernel/moleculer/addon-deploy-source.d.ts +11 -11
  374. package/dist/kernel/moleculer/addon-peer-bytes-facility.d.ts +18 -18
  375. package/dist/kernel/moleculer/addon-service-factory.d.ts +41 -41
  376. package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +60 -33
  377. package/dist/kernel/moleculer/agent-ui-unlock.d.ts +30 -30
  378. package/dist/kernel/moleculer/broker-factory.d.ts +61 -61
  379. package/dist/kernel/moleculer/cap-usage-registry.d.ts +108 -153
  380. package/dist/kernel/moleculer/capabilities-access.d.ts +19 -19
  381. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +43 -43
  382. package/dist/kernel/moleculer/child-cap-descriptors.d.ts +26 -26
  383. package/dist/kernel/moleculer/child-cap-dispatch.d.ts +52 -52
  384. package/dist/kernel/moleculer/children-batch-loader.d.ts +86 -34
  385. package/dist/kernel/moleculer/cluster-secret.d.ts +19 -19
  386. package/dist/kernel/moleculer/core-cap-service.d.ts +53 -53
  387. package/dist/kernel/moleculer/crash-supervisor.d.ts +39 -39
  388. package/dist/kernel/moleculer/device-cap-proxy.d.ts +51 -51
  389. package/dist/kernel/moleculer/device-event-ring.d.ts +117 -75
  390. package/dist/kernel/moleculer/event-bus-core.d.ts +171 -159
  391. package/dist/kernel/moleculer/event-bus.d.ts +73 -73
  392. package/dist/kernel/moleculer/hub-log-forwarder.d.ts +30 -30
  393. package/dist/kernel/moleculer/hub-service.d.ts +42 -42
  394. package/dist/kernel/moleculer/init-watchdog.d.ts +49 -49
  395. package/dist/kernel/moleculer/mesh-access-middleware.d.ts +36 -21
  396. package/dist/kernel/moleculer/mesh-auth-mode.d.ts +33 -39
  397. package/dist/kernel/moleculer/mesh-authenticator.d.ts +58 -58
  398. package/dist/kernel/moleculer/mesh-auto-enforce.d.ts +38 -18
  399. package/dist/kernel/moleculer/mesh-join-client.d.ts +67 -45
  400. package/dist/kernel/moleculer/mesh-join-proof.d.ts +8 -8
  401. package/dist/kernel/moleculer/mesh-mtls/constants.d.ts +1 -1
  402. package/dist/kernel/moleculer/mesh-mtls/index.d.ts +10 -10
  403. package/dist/kernel/moleculer/mesh-mtls/mesh-ca-keeper.d.ts +43 -38
  404. package/dist/kernel/moleculer/mesh-mtls/mesh-ca.d.ts +29 -20
  405. package/dist/kernel/moleculer/mesh-mtls/mesh-clear-port.d.ts +32 -32
  406. package/dist/kernel/moleculer/mesh-mtls/mesh-crl.d.ts +11 -11
  407. package/dist/kernel/moleculer/mesh-mtls/mesh-enroll.d.ts +19 -16
  408. package/dist/kernel/moleculer/mesh-mtls/mesh-join-token.d.ts +40 -40
  409. package/dist/kernel/moleculer/mesh-mtls/mesh-tls-enabler.d.ts +5 -1
  410. package/dist/kernel/moleculer/mesh-mtls/tls-tcp-transporter.d.ts +131 -130
  411. package/dist/kernel/moleculer/mesh-queue-report.d.ts +39 -39
  412. package/dist/kernel/moleculer/node-registry.d.ts +120 -120
  413. package/dist/kernel/moleculer/process-context.d.ts +2 -2
  414. package/dist/kernel/moleculer/process-service.d.ts +168 -168
  415. package/dist/kernel/moleculer/provider-registry.d.ts +9 -9
  416. package/dist/kernel/moleculer/readiness-context.d.ts +58 -58
  417. package/dist/kernel/moleculer/readiness-service.d.ts +31 -16
  418. package/dist/kernel/moleculer/register-framework-resolver.d.ts +6 -6
  419. package/dist/kernel/moleculer/register-node-client.d.ts +34 -27
  420. package/dist/kernel/moleculer/remote-logger.d.ts +29 -29
  421. package/dist/kernel/moleculer/resilient-cap-call.d.ts +21 -21
  422. package/dist/kernel/moleculer/runner-native-allocator.d.ts +95 -95
  423. package/dist/kernel/moleculer/runner-process-group.d.ts +57 -57
  424. package/dist/kernel/moleculer/runtime-state-load.d.ts +21 -11
  425. package/dist/kernel/moleculer/settings-read-guard.d.ts +39 -39
  426. package/dist/kernel/moleculer/stream-probe-service.d.ts +25 -6
  427. package/dist/kernel/moleculer/trpc-links.d.ts +203 -203
  428. package/dist/kernel/moleculer/typed-array-serde.d.ts +9 -20
  429. package/dist/kernel/moleculer/worker-device-restore.d.ts +8 -8
  430. package/dist/kernel/outbound-queue-watch.d.ts +74 -74
  431. package/dist/kernel/process-cpu-census.d.ts +55 -55
  432. package/dist/kernel/provider-kind-drift.d.ts +17 -8
  433. package/dist/kernel/restart-coordinator.d.ts +71 -71
  434. package/dist/kernel/settings-door-view.d.ts +36 -25
  435. package/dist/kernel/settings-read-error.d.ts +29 -31
  436. package/dist/kernel/settings-view-types.d.ts +100 -95
  437. package/dist/kernel/socket-plane-report.d.ts +214 -153
  438. package/dist/kernel/status-overlay.d.ts +31 -11
  439. package/dist/kernel/storage-location-registry.d.ts +50 -50
  440. package/dist/kernel/store-settings-view.d.ts +13 -13
  441. package/dist/kernel/system-settings-mirror.d.ts +40 -28
  442. package/dist/kernel/system-settings-policy.d.ts +15 -34
  443. package/dist/kernel/transport/cap-action-census.d.ts +183 -183
  444. package/dist/kernel/transport/cap-action-name.d.ts +84 -84
  445. package/dist/kernel/transport/cap-child-index.d.ts +41 -41
  446. package/dist/kernel/transport/cap-route-resolver.d.ts +237 -212
  447. package/dist/kernel/transport/cap-route.d.ts +139 -139
  448. package/dist/kernel/transport/cap-routing-hints.d.ts +37 -37
  449. package/dist/kernel/transport/child-cap-protocol.d.ts +245 -245
  450. package/dist/kernel/transport/claimed-get-status.d.ts +30 -6
  451. package/dist/kernel/transport/create-local-transport.d.ts +5 -5
  452. package/dist/kernel/transport/frame-codec.d.ts +109 -109
  453. package/dist/kernel/transport/hub-cap-forward.d.ts +81 -59
  454. package/dist/kernel/transport/index.d.ts +36 -36
  455. package/dist/kernel/transport/local-child-client.d.ts +184 -184
  456. package/dist/kernel/transport/local-child-registry.d.ts +592 -592
  457. package/dist/kernel/transport/local-endpoint-path.d.ts +4 -4
  458. package/dist/kernel/transport/local-transport.d.ts +92 -92
  459. package/dist/kernel/transport/parent-unowned-call.d.ts +266 -237
  460. package/dist/kernel/transport/peer-answered-error.d.ts +14 -14
  461. package/dist/kernel/transport/socket-channel.d.ts +110 -110
  462. package/dist/kernel/transport/socket-traffic.d.ts +96 -96
  463. package/dist/kernel/transport/uds-event-bridge.d.ts +77 -50
  464. package/dist/kernel/transport/uds-event-bus.d.ts +75 -26
  465. package/dist/kernel/transport/uds-local-transport.d.ts +14 -14
  466. package/dist/kernel/transport/uds-log-ingest.d.ts +38 -23
  467. package/dist/kernel/transport/uds-logger.d.ts +33 -33
  468. package/dist/kernel/utils/ring-buffer.d.ts +12 -12
  469. package/dist/kernel/workspace-detect.d.ts +7 -7
  470. package/dist/lifecycle/lifecycle-state-machine.d.ts +24 -24
  471. package/dist/logging/formatter.d.ts +52 -25
  472. package/dist/logging/log-manager.d.ts +133 -133
  473. package/dist/logging/log-redactor.d.ts +22 -1
  474. package/dist/logging/log-ring-buffer.d.ts +57 -57
  475. package/dist/logging/logging-gate.d.ts +69 -25
  476. package/dist/logging/logging-gate.singleton.d.ts +12 -1
  477. package/dist/logging/partitioned-log-buffer.d.ts +161 -161
  478. package/dist/logging/scoped-logger.d.ts +14 -14
  479. package/dist/network/network-quality.d.ts +8 -8
  480. package/dist/notification/notification-service.d.ts +37 -37
  481. package/dist/notification/toast-service.d.ts +18 -18
  482. package/dist/pipeline/engine-manager-resolver.d.ts +12 -12
  483. package/dist/pipeline/pipeline-runner.d.ts +6 -6
  484. package/dist/pipeline/pipeline-validator.d.ts +8 -8
  485. package/dist/process/proc-stat.d.ts +51 -51
  486. package/dist/process/resource-monitor.d.ts +19 -19
  487. package/dist/python/python-env-manager.d.ts +10 -10
  488. package/dist/repl/interfaces.d.ts +21 -21
  489. package/dist/repl/repl-engine.d.ts +6 -6
  490. package/dist/storage/fs-storage-backend.d.ts +35 -35
  491. package/dist/storage/storage-location-manager.d.ts +21 -21
  492. package/dist/storage/storage-manager.d.ts +68 -68
  493. package/dist/tls/boot-tls.d.ts +24 -24
  494. package/dist/tls/cert-evaluation.d.ts +25 -25
  495. package/dist/tls/cert-identity.d.ts +39 -39
  496. package/dist/tls/cert-issue.d.ts +37 -17
  497. package/dist/tls/cert-manager.d.ts +86 -84
  498. package/dist/tls/https-listener.d.ts +16 -16
  499. package/dist/tls/index.d.ts +8 -8
  500. package/dist/tls/tls-actions.d.ts +18 -18
  501. package/dist/tls/tls-status.d.ts +15 -15
  502. package/dist/tls/uploaded-cert.d.ts +9 -9
  503. package/package.json +9 -3
@@ -1,396 +1,448 @@
1
- import { ChildLayout, CollectionColumn, CollectionIndex, DeviceDisplayOverride, IScopedLogger, MutationFilter, QueryFilter, SettingsRecord, SettingsStoreClient } from '@camstack/types';
2
- import { RetiredRowStore } from '../sqlite-storage/retired-settings-keys.js';
3
- import { PersistedDeviceMeta } from './device-meta-types.js';
4
- import { FleetReadCensus } from './fleet-read-census.js';
5
1
  /**
6
- * @durable class=ledger owner=device-manager
7
- * write="one row per device, written by `allocateDeviceId` (identity placeholder),
8
- * `registerDevice` (full reconcile) and every meta setter (single-column patch);
9
- * `setMetadata` patches the `metadata` column of the same row"
10
- * retention="none — a row goes only when the operator removes the device
11
- * (`removeDevice`), or when an integration is deleted and cascades. Bounded by the
12
- * fleet an operator configures (974 rows on the reference hub)."
13
- *
14
- * ### Why `ledger` and not `config`
15
- *
16
- * This shipped as `class=registry`, a sixth class that does not exist —
17
- * `DURABLE_CLASSES` is `ledger | mirror | ephemeral | config | audit`, so
18
- * `check-durable-state-declared.ts` has failed since. `config` is the tempting
19
- * answer, because a device's `name` and `location` ARE operator intent. It is
20
- * the wrong one, and wrong in the dangerous direction: `config`'s rule is
21
- * *"already durable everywhere"*, and that is exactly the premise that made the
22
- * dead `devices` table look harmless right up to D183.
23
- *
24
- * Nothing else holds a device's NUMERIC id. `allocateDeviceId` mints it here
25
- * and every other store in the system keys on it — `addon-device-settings`,
26
- * `device-runtime-state`, every `pipeline-analytics:*` row, every recorder path.
27
- * That is `ledger`'s definition verbatim ("a fact only this component ever
28
- * held"), and `ledger`'s rule — *must not be pruned against a fallible read* —
29
- * is precisely the rule this collection needs (D49): a `getBindings` or an
30
- * integration listing that answers empty because it FAILED must never be
31
- * allowed to retire a device row.
32
- */
2
+ * `device-manager:devices` — ONE ROW PER DEVICE.
3
+ *
4
+ * ## What this replaces
5
+ *
6
+ * The device-manager used to keep its whole fleet in three JSON blobs on the
7
+ * addon-settings row set (`deviceMeta`, `deviceMetadata`, `deviceIndex`).
8
+ * Measured on the live hub 2026-08-19: 467 KB + 87 KB + 70 KB = 625 KB of the
9
+ * table's 627 KB, and EVERY read of any of them read and `JSON.parse`d all
10
+ * three, synchronously, on hub-main's event loop — `ctx.settings.readAddonStore`
11
+ * lands in `SqliteSettingsBackend.getAllAddon`, which is prefix-scoped to the
12
+ * addon but not to the key. A V8 profile of that boot had hub-main's JS thread
13
+ * 99.9% busy for 76 s with 64% of it inside `getAllAddon`, ~89% of that entered
14
+ * through the meta store, and every runner's first store read queued behind it.
15
+ *
16
+ * Writing was worse than reading. `ConfigManager.createSettingsView`'s
17
+ * `writeAddonStore` is `setAllAddon(addonId, { ...existing, ...patch })`, and
18
+ * `setAllAddon` DELETEs and re-INSERTs every row of the addon — so renaming one
19
+ * camera rewrote 625 KB.
20
+ *
21
+ * A row per device makes the per-device question a primary-key lookup and the
22
+ * per-device write a single-row upsert touching only the columns named.
23
+ *
24
+ * ## Why `deviceIndex` has no column and no collection
25
+ *
26
+ * `deviceIndex` was `Record<addonId, stableId[]>` — pure derivation: `addonId`
27
+ * and `stableId` are fields of every row, so "this addon's devices" is
28
+ * `where: { addonId }`. It carried exactly one bit that is NOT derivable:
29
+ * membership meant "`registerDevice` has run at least once", which is how
30
+ * `registerDevice` tells a FIRST registration (emit `DeviceRegistered`) from a
31
+ * meta refresh. `allocateDeviceId` writes a row without registering, so row
32
+ * existence alone cannot answer it. That bit is the {@link registered} column,
33
+ * and nothing else of `deviceIndex` survives.
34
+ *
35
+ * ## Why metadata is a column and not a second collection
36
+ *
37
+ * `deviceMetadata` lived in its own blob for ONE reason: a blob write is
38
+ * whole-value, so a lifecycle writer (`registerDevice` / `setName` / …) that
39
+ * had to preserve a `metadata` field would eventually clobber a concurrent
40
+ * `setMetadata`. Single-writer-per-blob was the fix. Column writes have no such
41
+ * problem — `set` names its columns and leaves the rest of the row untouched —
42
+ * so the split has no reason to exist and metadata rides on the device's own
43
+ * row.
44
+ *
45
+ * ## Adding a column later
46
+ *
47
+ * `declareCollection` is additive ONLY when SQLite can `ALTER TABLE … ADD
48
+ * COLUMN` it. A new `NOT NULL` column without a `defaultValue` cannot be added
49
+ * to a populated table, so the backend counts it as non-additive and REBUILDS
50
+ * the collection — dropping every row. Any column added here after ship must
51
+ * either be nullable or carry a `defaultValue`.
52
+ */
53
+ import type { ChildLayout, CollectionColumn, CollectionIndex, DeviceDisplayOverride, IScopedLogger, MutationFilter, QueryFilter, SettingsRecord, SettingsStoreClient } from "@camstack/types";
54
+ import type { RetiredRowStore } from "../sqlite-storage/retired-settings-keys.js";
55
+ import type { PersistedDeviceMeta } from "./device-meta-types.js";
56
+ import { FleetReadCensus } from "./fleet-read-census.js";
57
+ /**
58
+ * @durable class=ledger owner=device-manager
59
+ * write="one row per device, written by `allocateDeviceId` (identity placeholder),
60
+ * `registerDevice` (full reconcile) and every meta setter (single-column patch);
61
+ * `setMetadata` patches the `metadata` column of the same row"
62
+ * retention="none — a row goes only when the operator removes the device
63
+ * (`removeDevice`), or when an integration is deleted and cascades. Bounded by the
64
+ * fleet an operator configures (974 rows on the reference hub)."
65
+ *
66
+ * ### Why `ledger` and not `config`
67
+ *
68
+ * This shipped as `class=registry`, a sixth class that does not exist —
69
+ * `DURABLE_CLASSES` is `ledger | mirror | ephemeral | config | audit`, so
70
+ * `check-durable-state-declared.ts` has failed since. `config` is the tempting
71
+ * answer, because a device's `name` and `location` ARE operator intent. It is
72
+ * the wrong one, and wrong in the dangerous direction: `config`'s rule is
73
+ * *"already durable everywhere"*, and that is exactly the premise that made the
74
+ * dead `devices` table look harmless right up to D183.
75
+ *
76
+ * Nothing else holds a device's NUMERIC id. `allocateDeviceId` mints it here
77
+ * and every other store in the system keys on it — `addon-device-settings`,
78
+ * `device-runtime-state`, every `pipeline-analytics:*` row, every recorder path.
79
+ * That is `ledger`'s definition verbatim ("a fact only this component ever
80
+ * held"), and `ledger`'s rule — *must not be pruned against a fallible read* —
81
+ * is precisely the rule this collection needs (D49): a `getBindings` or an
82
+ * integration listing that answers empty because it FAILED must never be
83
+ * allowed to retire a device row.
84
+ */
33
85
  export declare const DEVICE_ROWS_COLLECTION = "device-manager:devices";
34
86
  /**
35
- * Fleet reads pass this explicitly.
36
- *
37
- * `settings-store.query` applies a DEFAULT row cap of 2 000 when the caller
38
- * names no `limit` (`query-bounds.ts`), and truncation there is silent to the
39
- * caller — it warns in the engine's log and returns a short list that looks
40
- * complete. The reference hub is already at 974 devices; half the default cap
41
- * is not a margin worth betting the fleet listing on. 20 000 is the engine's
42
- * hard ceiling, so this asks for everything the engine will ever serve in one
43
- * call and any future need to page is a loud failure rather than a quiet one.
44
- */
45
- export declare const DEVICE_ROWS_FLEET_LIMIT = 20000;
87
+ * Fleet reads pass this explicitly.
88
+ *
89
+ * `settings-store.query` applies a DEFAULT row cap of 2 000 when the caller
90
+ * names no `limit` (`query-bounds.ts`), and truncation there is silent to the
91
+ * caller — it warns in the engine's log and returns a short list that looks
92
+ * complete. The reference hub is already at 974 devices; half the default cap
93
+ * is not a margin worth betting the fleet listing on. 20 000 is the engine's
94
+ * hard ceiling, so this asks for everything the engine will ever serve in one
95
+ * call and any future need to page is a loud failure rather than a quiet one.
96
+ */
97
+ export declare const DEVICE_ROWS_FLEET_LIMIT = 2e4;
46
98
  export declare const DEVICE_ROWS_COLUMNS: readonly CollectionColumn[];
47
99
  /**
48
- * The columns a SLIM fleet read selects: every declared column except the
49
- * primary key (always returned) and `metadata`.
50
- *
51
- * ## Why this is a DENYLIST and must stay one
52
- *
53
- * `decodeDeviceRow` returns `null` when `deviceId`, `addonId`, `stableId`,
54
- * `type` or `name` is missing, and `list()` then SKIPS the row with a warn. A
55
- * hand-written allowlist that forgot one of the five would not make the fleet
56
- * slower — it would make devices vanish from every listing, quietly, and the
57
- * only trace would be a log line nobody is reading at the time. Deriving the
58
- * list by subtraction means a column added tomorrow is carried by default and
59
- * the only way to lose one is to name it here.
60
- *
61
- * `metadata` is the one slim provably discards: `device-queries.ts#listAll`
62
- * sets `metadata: null` on every slim row. It is also the largest JSON column
63
- * on the row, which is why this is worth doing at all.
64
- *
65
- * ## What is NOT here, and will not be
66
- *
67
- * There is no `where: { type: 'camera' }` companion to this. `isCameraDevice`
68
- * is a method-presence check (`getStreamSources`), not the persisted `type`, so
69
- * a doorbell with a camera answers YES while its row says `doorbell`. Filtering
70
- * the rows by type would strip exactly those devices of their row — and
71
- * `toDeviceInfo` reads `name` / `location` / `disabled` from the ROW precisely
72
- * because the live device's copies are stale by construction. The fleet would
73
- * keep working and start reporting pre-rename names on doorbells. The
74
- * `isCamera` filter stays in JS.
75
- */
100
+ * The columns a SLIM fleet read selects: every declared column except the
101
+ * primary key (always returned) and `metadata`.
102
+ *
103
+ * ## Why this is a DENYLIST and must stay one
104
+ *
105
+ * `decodeDeviceRow` returns `null` when `deviceId`, `addonId`, `stableId`,
106
+ * `type` or `name` is missing, and `list()` then SKIPS the row with a warn. A
107
+ * hand-written allowlist that forgot one of the five would not make the fleet
108
+ * slower — it would make devices vanish from every listing, quietly, and the
109
+ * only trace would be a log line nobody is reading at the time. Deriving the
110
+ * list by subtraction means a column added tomorrow is carried by default and
111
+ * the only way to lose one is to name it here.
112
+ *
113
+ * `metadata` is the one slim provably discards: `device-queries.ts#listAll`
114
+ * sets `metadata: null` on every slim row. It is also the largest JSON column
115
+ * on the row, which is why this is worth doing at all.
116
+ *
117
+ * ## What is NOT here, and will not be
118
+ *
119
+ * There is no `where: { type: 'camera' }` companion to this. `isCameraDevice`
120
+ * is a method-presence check (`getStreamSources`), not the persisted `type`, so
121
+ * a doorbell with a camera answers YES while its row says `doorbell`. Filtering
122
+ * the rows by type would strip exactly those devices of their row — and
123
+ * `toDeviceInfo` reads `name` / `location` / `disabled` from the ROW precisely
124
+ * because the live device's copies are stale by construction. The fleet would
125
+ * keep working and start reporting pre-rename names on doorbells. The
126
+ * `isCamera` filter stays in JS.
127
+ */
76
128
  export declare const DEVICE_ROWS_SLIM_COLUMNS: readonly string[];
77
129
  export declare const DEVICE_ROWS_INDEXES: readonly CollectionIndex[];
78
130
  /**
79
- * The settings-store door this store needs, as a plain object surface.
80
- *
81
- * The production door is the tRPC client on `ctx.api.settingsStore`
82
- * (`client.get.query(…)` / `client.set.mutate(…)`); {@link deviceRowBackendOf}
83
- * adapts it. Declaring the port separately is what lets a test hand over an
84
- * in-memory table without reconstructing a tRPC router, and it names exactly
85
- * the seven methods this store is allowed to reach for.
86
- */
131
+ * The settings-store door this store needs, as a plain object surface.
132
+ *
133
+ * The production door is the tRPC client on `ctx.api.settingsStore`
134
+ * (`client.get.query(…)` / `client.set.mutate(…)`); {@link deviceRowBackendOf}
135
+ * adapts it. Declaring the port separately is what lets a test hand over an
136
+ * in-memory table without reconstructing a tRPC router, and it names exactly
137
+ * the seven methods this store is allowed to reach for.
138
+ */
87
139
  export interface DeviceRowBackend {
88
- declareCollection(input: {
89
- collection: string;
90
- columns: readonly CollectionColumn[];
91
- indexes?: readonly CollectionIndex[];
92
- }): Promise<void>;
93
- get(input: {
94
- collection: string;
95
- key: string;
96
- }): Promise<unknown>;
97
- set(input: {
98
- collection: string;
99
- key: string;
100
- value: Record<string, unknown>;
101
- }): Promise<void>;
102
- query(input: {
103
- collection: string;
104
- filter?: QueryFilter;
105
- }): Promise<readonly SettingsRecord<Record<string, unknown>>[]>;
106
- updateWhere(input: {
107
- collection: string;
108
- filter: MutationFilter;
109
- data: Record<string, unknown>;
110
- }): Promise<{
111
- updated: number;
112
- }>;
113
- delete(input: {
114
- collection: string;
115
- key: string;
116
- }): Promise<void>;
117
- count(input: {
118
- collection: string;
119
- filter?: QueryFilter;
120
- }): Promise<number>;
140
+ declareCollection(input: {
141
+ collection: string;
142
+ columns: readonly CollectionColumn[];
143
+ indexes?: readonly CollectionIndex[];
144
+ }): Promise<void>;
145
+ get(input: {
146
+ collection: string;
147
+ key: string;
148
+ }): Promise<unknown>;
149
+ set(input: {
150
+ collection: string;
151
+ key: string;
152
+ value: Record<string, unknown>;
153
+ }): Promise<void>;
154
+ query(input: {
155
+ collection: string;
156
+ filter?: QueryFilter;
157
+ }): Promise<readonly SettingsRecord<Record<string, unknown>>[]>;
158
+ updateWhere(input: {
159
+ collection: string;
160
+ filter: MutationFilter;
161
+ data: Record<string, unknown>;
162
+ }): Promise<{
163
+ updated: number;
164
+ }>;
165
+ delete(input: {
166
+ collection: string;
167
+ key: string;
168
+ }): Promise<void>;
169
+ count(input: {
170
+ collection: string;
171
+ filter?: QueryFilter;
172
+ }): Promise<number>;
121
173
  }
122
174
  /** Adapt `ctx.api.settingsStore` (tRPC namespace) to {@link DeviceRowBackend}. */
123
175
  export declare function deviceRowBackendOf(client: SettingsStoreClient): DeviceRowBackend;
124
176
  /**
125
- * The fields a single-column patch may set.
126
- *
127
- * Every key is OPTIONAL and only the keys PRESENT reach the `SET` list, so an
128
- * omitted key leaves that column exactly as it was. `null` is a real value and
129
- * CLEARS the column; it is how `setDisplay(null)` removes an override.
130
- *
131
- * A patch is an UPDATE, never an insert — see {@link DeviceRowStore.patch}.
132
- */
177
+ * The fields a single-column patch may set.
178
+ *
179
+ * Every key is OPTIONAL and only the keys PRESENT reach the `SET` list, so an
180
+ * omitted key leaves that column exactly as it was. `null` is a real value and
181
+ * CLEARS the column; it is how `setDisplay(null)` removes an override.
182
+ *
183
+ * A patch is an UPDATE, never an insert — see {@link DeviceRowStore.patch}.
184
+ */
133
185
  export interface DeviceRowPatch {
134
- readonly type?: string;
135
- readonly name?: string;
136
- readonly userNamed?: boolean;
137
- readonly location?: string | null;
138
- readonly disabled?: boolean;
139
- readonly parentDeviceId?: number | null;
140
- readonly registered?: boolean;
141
- readonly features?: readonly string[];
142
- readonly exportFingerprint?: string;
143
- readonly integrationId?: string | null;
144
- readonly linkDeviceId?: number | null;
145
- readonly primaryChildEntityId?: string | null;
146
- readonly childLayout?: ChildLayout | null;
147
- readonly role?: string | null;
148
- readonly display?: DeviceDisplayOverride | null;
149
- readonly metadata?: Record<string, unknown> | null;
186
+ readonly type?: string;
187
+ readonly name?: string;
188
+ readonly userNamed?: boolean;
189
+ readonly location?: string | null;
190
+ readonly disabled?: boolean;
191
+ readonly parentDeviceId?: number | null;
192
+ readonly registered?: boolean;
193
+ readonly features?: readonly string[];
194
+ readonly exportFingerprint?: string;
195
+ readonly integrationId?: string | null;
196
+ readonly linkDeviceId?: number | null;
197
+ readonly primaryChildEntityId?: string | null;
198
+ readonly childLayout?: ChildLayout | null;
199
+ readonly role?: string | null;
200
+ readonly display?: DeviceDisplayOverride | null;
201
+ readonly metadata?: Record<string, unknown> | null;
150
202
  }
151
203
  /**
152
- * Every column `registerDevice` writes.
153
- *
154
- * It is spelled out rather than reusing {@link DeviceRowPatch} because this
155
- * statement doubles as the INSERT for a device whose row does not exist yet
156
- * (`allocateDeviceId` is not on every path into `registerDevice`), and SQLite
157
- * checks `NOT NULL` on the insert attempt BEFORE the upsert clause gets to
158
- * intercept the primary-key conflict. Every `NOT NULL` column is therefore
159
- * required here, and the type is what keeps it that way.
160
- *
161
- * Columns NOT listed — `integrationId`, `linkDeviceId`, `primaryChildEntityId`,
162
- * `childLayout`, `role`, `display`, `metadata` — are not in the statement at
163
- * all, so re-registering preserves them. The blob shape had to re-state each
164
- * one to avoid clobbering it, and every field added since has been one more
165
- * spread somebody had to remember.
166
- */
204
+ * Every column `registerDevice` writes.
205
+ *
206
+ * It is spelled out rather than reusing {@link DeviceRowPatch} because this
207
+ * statement doubles as the INSERT for a device whose row does not exist yet
208
+ * (`allocateDeviceId` is not on every path into `registerDevice`), and SQLite
209
+ * checks `NOT NULL` on the insert attempt BEFORE the upsert clause gets to
210
+ * intercept the primary-key conflict. Every `NOT NULL` column is therefore
211
+ * required here, and the type is what keeps it that way.
212
+ *
213
+ * Columns NOT listed — `integrationId`, `linkDeviceId`, `primaryChildEntityId`,
214
+ * `childLayout`, `role`, `display`, `metadata` — are not in the statement at
215
+ * all, so re-registering preserves them. The blob shape had to re-state each
216
+ * one to avoid clobbering it, and every field added since has been one more
217
+ * spread somebody had to remember.
218
+ */
167
219
  export interface DeviceRegistrationRow {
168
- readonly deviceId: number;
169
- readonly addonId: string;
170
- readonly stableId: string;
171
- readonly type: string;
172
- readonly name: string;
173
- readonly userNamed: boolean;
174
- readonly location: string | null;
175
- readonly disabled: boolean;
176
- readonly parentDeviceId: number | null;
177
- readonly registered: boolean;
178
- readonly features: readonly string[];
179
- readonly exportFingerprint: string;
220
+ readonly deviceId: number;
221
+ readonly addonId: string;
222
+ readonly stableId: string;
223
+ readonly type: string;
224
+ readonly name: string;
225
+ readonly userNamed: boolean;
226
+ readonly location: string | null;
227
+ readonly disabled: boolean;
228
+ readonly parentDeviceId: number | null;
229
+ readonly registered: boolean;
230
+ readonly features: readonly string[];
231
+ readonly exportFingerprint: string;
180
232
  }
181
233
  /** A device row as this store hands it back: the meta record plus its metadata blob. */
182
234
  export interface DeviceRow {
183
- readonly meta: PersistedDeviceMeta;
184
- /** `null` when the device has no hardware-identity metadata. */
185
- readonly metadata: Record<string, unknown> | null;
186
- /** Has `registerDevice` ever run for this device? (former `deviceIndex` membership) */
187
- readonly registered: boolean;
235
+ readonly meta: PersistedDeviceMeta;
236
+ /** `null` when the device has no hardware-identity metadata. */
237
+ readonly metadata: Record<string, unknown> | null;
238
+ /** Has `registerDevice` ever run for this device? (former `deviceIndex` membership) */
239
+ readonly registered: boolean;
188
240
  }
189
241
  /**
190
- * Decode one stored row.
191
- *
192
- * Returns `null` for a row missing an identity field the rest of the system
193
- * treats as an invariant (`deviceId` / `addonId` / `stableId` / `type` /
194
- * `name`). A row like that cannot be projected into a `DeviceInfo` and taking
195
- * the whole fleet read down for it would be worse — the caller logs the skip.
196
- */
242
+ * Decode one stored row.
243
+ *
244
+ * Returns `null` for a row missing an identity field the rest of the system
245
+ * treats as an invariant (`deviceId` / `addonId` / `stableId` / `type` /
246
+ * `name`). A row like that cannot be projected into a `DeviceInfo` and taking
247
+ * the whole fleet read down for it would be worse — the caller logs the skip.
248
+ */
197
249
  export declare function decodeDeviceRow(data: Record<string, unknown>): DeviceRow | null;
198
250
  /** Full-row value for an upsert: identity + every field of the meta record. */
199
251
  export declare function encodeDeviceRow(meta: PersistedDeviceMeta, extra?: {
200
- readonly registered?: boolean;
201
- readonly metadata?: Record<string, unknown> | null;
252
+ readonly registered?: boolean;
253
+ readonly metadata?: Record<string, unknown> | null;
202
254
  }): Record<string, unknown>;
203
255
  /** Column map for a partial write — only the keys the caller actually named. */
204
256
  export declare function encodeDeviceRowPatch(patch: DeviceRowPatch): Record<string, unknown>;
205
257
  /**
206
- * Row access for the device fleet. Every method is a single statement against
207
- * `device-manager:devices` — there is no in-memory copy of the fleet here and
208
- * no cache: a per-device question is a primary-key lookup, a fleet question is
209
- * one indexed scan.
210
- */
258
+ * Row access for the device fleet. Every method is a single statement against
259
+ * `device-manager:devices` — there is no in-memory copy of the fleet here and
260
+ * no cache: a per-device question is a primary-key lookup, a fleet question is
261
+ * one indexed scan.
262
+ */
211
263
  export declare class DeviceRowStore {
212
- private readonly backend;
213
- private readonly logger;
214
- private declared;
215
- /** Call-site attribution for fleet reads. Armed only by
216
- * `CAMSTACK_FLEET_READ_CENSUS_MS`; see `fleet-read-census.ts`. */
217
- private readonly census;
218
- /**
219
- * Is the fleet-read census armed right now? Exposed so a caller ABOVE this
220
- * store (`device-queries.ts`) can skip extracting a caller identity off its
221
- * input entirely when nobody is measuring — "the boolean field read first"
222
- * pattern this repo already uses elsewhere to keep a diagnostic seam at
223
- * zero cost while disarmed.
224
- */
225
- get censusArmed(): boolean;
226
- constructor(backend: DeviceRowBackend, logger: IScopedLogger, census?: FleetReadCensus);
227
- /**
228
- * Lazy, idempotent `declareCollection`, memoised on the PROMISE so N
229
- * concurrent first-callers issue one declaration rather than N. A rejection
230
- * is not latched — the slot is cleared so the next caller retries instead of
231
- * inheriting a dead collection forever.
232
- */
233
- declare(): Promise<void>;
234
- /** One device, by numeric id. `null` when the fleet does not know it. */
235
- get(deviceId: number): Promise<DeviceRow | null>;
236
- /**
237
- * Every device, ordered by numeric id.
238
- *
239
- * `callerAddonId`, when known, is the addon that ORIGINATED this call —
240
- * captured off the cap-channel envelope (`CapCallInput.callerAddonId`, set
241
- * by `LocalChildRegistry` from the registered `childId`), never guessed.
242
- * Passed straight to the census; a stack walk can never name it (see
243
- * `fleet-read-census.ts#siteOf`).
244
- */
245
- listAll(callerAddonId?: string): Promise<readonly DeviceRow[]>;
246
- /**
247
- * The fleet, read as narrowly as the question allows.
248
- *
249
- * `listAll` is a full-table `SELECT … ORDER BY "deviceId"` — ~1 017 rows a
250
- * call on the live hub, 14–54 calls a minute — and its callers then filtered
251
- * the result in JS. The two filters that CAN be pushed down are here:
252
- *
253
- * - `deviceIds` becomes a `whereIn`. The viewer's linked-devices panel asks
254
- * about ~8 named ids; it was answered by reading the whole ledger. An
255
- * EMPTY set reads nothing at all rather than degrading to "everything" —
256
- * a request for no devices is a request, not an omission.
257
- * - `slim` becomes a column projection, {@link DEVICE_ROWS_SLIM_COLUMNS}.
258
- *
259
- * `isCamera` is deliberately NOT one of them — see that constant's note and
260
- * `device-row-store-filtered.spec.ts`.
261
- *
262
- * `callerAddonId` — see {@link listAll}'s doc; same meaning here.
263
- */
264
- listFleet(opts: {
265
- readonly deviceIds?: readonly number[];
266
- readonly slim?: boolean;
267
- }, callerAddonId?: string): Promise<readonly DeviceRow[]>;
268
- /**
269
- * Many devices, by numeric id, in ONE query.
270
- *
271
- * `get(id)` called once per id in a loop is the primary-key lookup this
272
- * store exists to make cheap, repeated until it isn't — measured on the
273
- * live hub 2026-08-25: `get device-manager:devices` at 1 656 calls/min
274
- * steady-state and 17 687 during boot, exactly one row per call. This
275
- * collapses that into the same `whereIn` {@link listFleet} already does for
276
- * a fleet read, keyed by id.
277
- *
278
- * A requested id the fleet does not know is simply ABSENT from the map —
279
- * never a fabricated row, matching {@link get}'s `null`. An empty `ids`
280
- * reads nothing at all, same as `listFleet({ deviceIds: [] })`.
281
- */
282
- getMany(ids: readonly number[]): Promise<ReadonlyMap<number, DeviceRow>>;
283
- /**
284
- * The device an addon knows as `stableId`, or `null`.
285
- *
286
- * `(addonId, stableId)` is the addon-facing identity — unique by
287
- * construction, since `allocateDeviceId` is the only thing that mints a row
288
- * and it returns the existing id for a pair it already knows. A second row
289
- * for the pair would be a corruption, so this takes the LOWEST id and says
290
- * so rather than picking arbitrarily.
291
- */
292
- findByStableId(addonId: string, stableId: string): Promise<DeviceRow | null>;
293
- /** Every device owned by one addon, ordered by numeric id. */
294
- listByAddon(addonId: string): Promise<readonly DeviceRow[]>;
295
- /** Every device an integration owns, ordered by numeric id. */
296
- listByIntegration(integrationId: string): Promise<readonly DeviceRow[]>;
297
- /** Direct children of one device, ordered by numeric id. */
298
- listByParent(parentDeviceId: number): Promise<readonly DeviceRow[]>;
299
- /**
300
- * Direct children of MANY devices, in ONE query.
301
- *
302
- * `listByParent` called once per parent is the same shape `get` was before
303
- * {@link getMany}: an indexed lookup this store makes cheap, repeated until
304
- * it isn't. Measured on the live hub 2026-08-27, 120-second boot window:
305
- * `DeviceRowStore.list < DeviceRowStore.listByParent < getChildren` at
306
- * **1 024 calls** — one per device — for 919 rows in total. The BFS in
307
- * `device-meta-actions.ts#collectDescendants` walked a container tree the
308
- * same way, one query per node.
309
- *
310
- * `whereIn` on the indexed `parentDeviceId` column collapses a level of that
311
- * walk into a single statement. Contract, verbatim from {@link getMany}: an
312
- * EMPTY `parentDeviceIds` reads nothing at all rather than degrading to
313
- * "everything", and a parent with no children — or one the fleet does not
314
- * know — is simply ABSENT from the map, never an invented empty row.
315
- */
316
- listByParentMany(parentDeviceIds: readonly number[]): Promise<ReadonlyMap<number, readonly DeviceRow[]>>;
317
- /** How many devices the fleet holds. Used to tell "empty store" from "gone device". */
318
- count(): Promise<number>;
319
- private list;
320
- /** Insert or replace the whole identity row. */
321
- upsert(meta: PersistedDeviceMeta, extra?: {
322
- readonly registered?: boolean;
323
- readonly metadata?: Record<string, unknown> | null;
324
- }): Promise<void>;
325
- /**
326
- * Write the named columns of an EXISTING row and nothing else.
327
- *
328
- * An UPDATE, deliberately not an upsert: a partial upsert would try to INSERT
329
- * a row carrying only the patched columns, and SQLite rejects that on the
330
- * `NOT NULL` identity columns before the primary-key conflict can turn it
331
- * into an update. Every caller resolves the row under the write lock and
332
- * throws when it is gone, so matching zero rows means a device was removed
333
- * between the resolve and the write — the patch is lost, and a lost write
334
- * that says nothing reads as a write that happened.
335
- */
336
- patch(deviceId: number, patch: DeviceRowPatch): Promise<void>;
337
- /**
338
- * Insert-or-update the registration columns. See {@link DeviceRegistrationRow}
339
- * for why this is a separate, fully-specified statement rather than a patch.
340
- */
341
- upsertRegistration(row: DeviceRegistrationRow): Promise<void>;
342
- /** Drop the device's row. Idempotent. */
343
- /**
344
- * Exchange the ids of two devices, carrying their children with them.
345
- *
346
- * ## Why this exists as a primitive
347
- *
348
- * Replacing a camera means the new hardware has to become the device the rest
349
- * of the system already knows. Everything general about a camera is keyed on
350
- * the NUMERIC id and on nothing else — the recording path on disk is
351
- * `<deviceId>/profile/…`, the hour ledger, the media store and zone ownership
352
- * carry `deviceId` and not one `stableId` between them, and all four
353
- * ecosystem exports (Home Assistant, Alexa, HomeKit, Google) key on it too.
354
- * Moving that work is the expensive, lossy operation. Moving the NUMBER is
355
- * two rows.
356
- *
357
- * ## Children are re-pointed, not renumbered
358
- *
359
- * A child keeps its own id and follows its parent: every row whose
360
- * `parentDeviceId` was `a` now names `b`, and the reverse. Renumbering the
361
- * children as well would move THEIR general work for no reason — the
362
- * accessory's own recordings and rules are keyed on the child id, which is
363
- * not the id being inherited.
364
- *
365
- * ## There are no transactions here, so the ORDER is the safety
366
- *
367
- * The backing store is a collection API (`set` / `delete` / `updateWhere`);
368
- * there is no rollback to lean on. So the sequence is chosen to make every
369
- * crash point LOUD rather than plausible: `a` first moves to a freshly
370
- * allocated id, which the monotonic counter guarantees was never used and
371
- * will never be reused. A crash before the end therefore leaves a device
372
- * missing from its number and a stray at an unfamiliar one — visible in the
373
- * device list at a glance. What it can never leave is two rows on one number,
374
- * or a row that looks correct while its children point elsewhere.
375
- *
376
- * The caller holds {@link DeviceMetaStore.withMetaWriteLock}. This method does
377
- * not take it: taking it here would deadlock the migration that has to disable
378
- * functions on both devices in the same critical section.
379
- */
380
- swapIds(a: number, b: number, tempId: number): Promise<void>;
381
- /** The read-only half of {@link swapIds}: every refusal, every read, no write. */
382
- private planSwap;
383
- /** Rewrite a row under a new id and drop the old key. Not exported: the only
384
- * legitimate reason to move a row is {@link swapIds}. */
385
- private moveRow;
386
- remove(deviceId: number): Promise<void>;
387
- /**
388
- * The retirement door for the three blobs this collection replaced.
389
- *
390
- * The purge is gated on THIS collection being non-empty, and the count has to
391
- * be taken after `declare()` — which is why the owning addon runs it and the
392
- * settings engine cannot: at the engine's own boot no addon has declared
393
- * anything, so every successor would read as unreadable, forever.
394
- */
395
- retiredRowStore(): RetiredRowStore;
264
+ private readonly backend;
265
+ private readonly logger;
266
+ private declared;
267
+ /** Call-site attribution for fleet reads. Armed only by
268
+ * `CAMSTACK_FLEET_READ_CENSUS_MS`; see `fleet-read-census.ts`. */
269
+ private readonly census;
270
+ /**
271
+ * Is the fleet-read census armed right now? Exposed so a caller ABOVE this
272
+ * store (`device-queries.ts`) can skip extracting a caller identity off its
273
+ * input entirely when nobody is measuring — "the boolean field read first"
274
+ * pattern this repo already uses elsewhere to keep a diagnostic seam at
275
+ * zero cost while disarmed.
276
+ */
277
+ get censusArmed(): boolean;
278
+ constructor(backend: DeviceRowBackend, logger: IScopedLogger, census?: FleetReadCensus);
279
+ /**
280
+ * Lazy, idempotent `declareCollection`, memoised on the PROMISE so N
281
+ * concurrent first-callers issue one declaration rather than N. A rejection
282
+ * is not latched — the slot is cleared so the next caller retries instead of
283
+ * inheriting a dead collection forever.
284
+ */
285
+ declare(): Promise<void>;
286
+ /** One device, by numeric id. `null` when the fleet does not know it. */
287
+ get(deviceId: number): Promise<DeviceRow | null>;
288
+ /**
289
+ * Every device, ordered by numeric id.
290
+ *
291
+ * `callerAddonId`, when known, is the addon that ORIGINATED this call —
292
+ * captured off the cap-channel envelope (`CapCallInput.callerAddonId`, set
293
+ * by `LocalChildRegistry` from the registered `childId`), never guessed.
294
+ * Passed straight to the census; a stack walk can never name it (see
295
+ * `fleet-read-census.ts#siteOf`).
296
+ */
297
+ listAll(callerAddonId?: string): Promise<readonly DeviceRow[]>;
298
+ /**
299
+ * The fleet, read as narrowly as the question allows.
300
+ *
301
+ * `listAll` is a full-table `SELECT … ORDER BY "deviceId"` — ~1 017 rows a
302
+ * call on the live hub, 14–54 calls a minute — and its callers then filtered
303
+ * the result in JS. The two filters that CAN be pushed down are here:
304
+ *
305
+ * - `deviceIds` becomes a `whereIn`. The viewer's linked-devices panel asks
306
+ * about ~8 named ids; it was answered by reading the whole ledger. An
307
+ * EMPTY set reads nothing at all rather than degrading to "everything" —
308
+ * a request for no devices is a request, not an omission.
309
+ * - `slim` becomes a column projection, {@link DEVICE_ROWS_SLIM_COLUMNS}.
310
+ *
311
+ * `isCamera` is deliberately NOT one of them — see that constant's note and
312
+ * `device-row-store-filtered.spec.ts`.
313
+ *
314
+ * `callerAddonId` — see {@link listAll}'s doc; same meaning here.
315
+ */
316
+ listFleet(opts: {
317
+ readonly deviceIds?: readonly number[];
318
+ readonly slim?: boolean;
319
+ }, callerAddonId?: string): Promise<readonly DeviceRow[]>;
320
+ /**
321
+ * Many devices, by numeric id, in ONE query.
322
+ *
323
+ * `get(id)` called once per id in a loop is the primary-key lookup this
324
+ * store exists to make cheap, repeated until it isn't — measured on the
325
+ * live hub 2026-08-25: `get device-manager:devices` at 1 656 calls/min
326
+ * steady-state and 17 687 during boot, exactly one row per call. This
327
+ * collapses that into the same `whereIn` {@link listFleet} already does for
328
+ * a fleet read, keyed by id.
329
+ *
330
+ * A requested id the fleet does not know is simply ABSENT from the map —
331
+ * never a fabricated row, matching {@link get}'s `null`. An empty `ids`
332
+ * reads nothing at all, same as `listFleet({ deviceIds: [] })`.
333
+ */
334
+ getMany(ids: readonly number[]): Promise<ReadonlyMap<number, DeviceRow>>;
335
+ /**
336
+ * The device an addon knows as `stableId`, or `null`.
337
+ *
338
+ * `(addonId, stableId)` is the addon-facing identity — unique by
339
+ * construction, since `allocateDeviceId` is the only thing that mints a row
340
+ * and it returns the existing id for a pair it already knows. A second row
341
+ * for the pair would be a corruption, so this takes the LOWEST id and says
342
+ * so rather than picking arbitrarily.
343
+ */
344
+ findByStableId(addonId: string, stableId: string): Promise<DeviceRow | null>;
345
+ /** Every device owned by one addon, ordered by numeric id. */
346
+ listByAddon(addonId: string): Promise<readonly DeviceRow[]>;
347
+ /** Every device an integration owns, ordered by numeric id. */
348
+ listByIntegration(integrationId: string): Promise<readonly DeviceRow[]>;
349
+ /** Direct children of one device, ordered by numeric id. */
350
+ listByParent(parentDeviceId: number): Promise<readonly DeviceRow[]>;
351
+ /**
352
+ * Direct children of MANY devices, in ONE query.
353
+ *
354
+ * `listByParent` called once per parent is the same shape `get` was before
355
+ * {@link getMany}: an indexed lookup this store makes cheap, repeated until
356
+ * it isn't. Measured on the live hub 2026-08-27, 120-second boot window:
357
+ * `DeviceRowStore.list < DeviceRowStore.listByParent < getChildren` at
358
+ * **1 024 calls** — one per device — for 919 rows in total. The BFS in
359
+ * `device-meta-actions.ts#collectDescendants` walked a container tree the
360
+ * same way, one query per node.
361
+ *
362
+ * `whereIn` on the indexed `parentDeviceId` column collapses a level of that
363
+ * walk into a single statement. Contract, verbatim from {@link getMany}: an
364
+ * EMPTY `parentDeviceIds` reads nothing at all rather than degrading to
365
+ * "everything", and a parent with no children — or one the fleet does not
366
+ * know — is simply ABSENT from the map, never an invented empty row.
367
+ */
368
+ listByParentMany(parentDeviceIds: readonly number[]): Promise<ReadonlyMap<number, readonly DeviceRow[]>>;
369
+ /** How many devices the fleet holds. Used to tell "empty store" from "gone device". */
370
+ count(): Promise<number>;
371
+ private list;
372
+ /** Insert or replace the whole identity row. */
373
+ upsert(meta: PersistedDeviceMeta, extra?: {
374
+ readonly registered?: boolean;
375
+ readonly metadata?: Record<string, unknown> | null;
376
+ }): Promise<void>;
377
+ /**
378
+ * Write the named columns of an EXISTING row and nothing else.
379
+ *
380
+ * An UPDATE, deliberately not an upsert: a partial upsert would try to INSERT
381
+ * a row carrying only the patched columns, and SQLite rejects that on the
382
+ * `NOT NULL` identity columns before the primary-key conflict can turn it
383
+ * into an update. Every caller resolves the row under the write lock and
384
+ * throws when it is gone, so matching zero rows means a device was removed
385
+ * between the resolve and the write — the patch is lost, and a lost write
386
+ * that says nothing reads as a write that happened.
387
+ */
388
+ patch(deviceId: number, patch: DeviceRowPatch): Promise<void>;
389
+ /**
390
+ * Insert-or-update the registration columns. See {@link DeviceRegistrationRow}
391
+ * for why this is a separate, fully-specified statement rather than a patch.
392
+ */
393
+ upsertRegistration(row: DeviceRegistrationRow): Promise<void>;
394
+ /** Drop the device's row. Idempotent. */
395
+ /**
396
+ * Exchange the ids of two devices, carrying their children with them.
397
+ *
398
+ * ## Why this exists as a primitive
399
+ *
400
+ * Replacing a camera means the new hardware has to become the device the rest
401
+ * of the system already knows. Everything general about a camera is keyed on
402
+ * the NUMERIC id and on nothing else — the recording path on disk is
403
+ * `<deviceId>/profile/…`, the hour ledger, the media store and zone ownership
404
+ * carry `deviceId` and not one `stableId` between them, and all four
405
+ * ecosystem exports (Home Assistant, Alexa, HomeKit, Google) key on it too.
406
+ * Moving that work is the expensive, lossy operation. Moving the NUMBER is
407
+ * two rows.
408
+ *
409
+ * ## Children are re-pointed, not renumbered
410
+ *
411
+ * A child keeps its own id and follows its parent: every row whose
412
+ * `parentDeviceId` was `a` now names `b`, and the reverse. Renumbering the
413
+ * children as well would move THEIR general work for no reason — the
414
+ * accessory's own recordings and rules are keyed on the child id, which is
415
+ * not the id being inherited.
416
+ *
417
+ * ## There are no transactions here, so the ORDER is the safety
418
+ *
419
+ * The backing store is a collection API (`set` / `delete` / `updateWhere`);
420
+ * there is no rollback to lean on. So the sequence is chosen to make every
421
+ * crash point LOUD rather than plausible: `a` first moves to a freshly
422
+ * allocated id, which the monotonic counter guarantees was never used and
423
+ * will never be reused. A crash before the end therefore leaves a device
424
+ * missing from its number and a stray at an unfamiliar one — visible in the
425
+ * device list at a glance. What it can never leave is two rows on one number,
426
+ * or a row that looks correct while its children point elsewhere.
427
+ *
428
+ * The caller holds {@link DeviceMetaStore.withMetaWriteLock}. This method does
429
+ * not take it: taking it here would deadlock the migration that has to disable
430
+ * functions on both devices in the same critical section.
431
+ */
432
+ swapIds(a: number, b: number, tempId: number): Promise<void>;
433
+ /** The read-only half of {@link swapIds}: every refusal, every read, no write. */
434
+ private planSwap;
435
+ /** Rewrite a row under a new id and drop the old key. Not exported: the only
436
+ * legitimate reason to move a row is {@link swapIds}. */
437
+ private moveRow;
438
+ remove(deviceId: number): Promise<void>;
439
+ /**
440
+ * The retirement door for the three blobs this collection replaced.
441
+ *
442
+ * The purge is gated on THIS collection being non-empty, and the count has to
443
+ * be taken after `declare()` — which is why the owning addon runs it and the
444
+ * settings engine cannot: at the engine's own boot no addon has declared
445
+ * anything, so every successor would read as unreadable, forever.
446
+ */
447
+ retiredRowStore(): RetiredRowStore;
396
448
  }