@camstack/system 1.2.274 → 1.2.276

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 (74) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/autotrack/index.js +1 -1
  8. package/dist/builtins/autotrack/index.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  11. package/dist/builtins/camera-grid/grid-last-frame-store.d.ts +39 -0
  12. package/dist/builtins/camera-grid/index.js +67 -12
  13. package/dist/builtins/camera-grid/index.mjs +67 -12
  14. package/dist/builtins/console-logging/index.js +1 -1
  15. package/dist/builtins/console-logging/index.mjs +1 -1
  16. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  17. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  18. package/dist/builtins/device-manager/device-aggregation.d.ts +0 -6
  19. package/dist/builtins/device-manager/device-bindings-store.d.ts +12 -2
  20. package/dist/builtins/device-manager/device-manager.addon.d.ts +4 -0
  21. package/dist/builtins/device-manager/device-manager.addon.js +177 -58
  22. package/dist/builtins/device-manager/device-manager.addon.mjs +174 -59
  23. package/dist/builtins/device-manager/device-meta-types.d.ts +36 -3
  24. package/dist/builtins/device-manager/device-source-activation.d.ts +70 -0
  25. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  26. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  27. package/dist/builtins/hub-forwarder/index.js +1 -1
  28. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  29. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  30. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  31. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  32. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  33. package/dist/builtins/local-network/local-network.addon.js +2 -2
  34. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  35. package/dist/builtins/loki-logging/index.js +1 -1
  36. package/dist/builtins/loki-logging/index.mjs +1 -1
  37. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  38. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  39. package/dist/builtins/platform-probe/index.js +1 -1
  40. package/dist/builtins/platform-probe/index.mjs +1 -1
  41. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  42. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  43. package/dist/builtins/snapshot/index.js +26 -6
  44. package/dist/builtins/snapshot/index.mjs +26 -6
  45. package/dist/builtins/snapshot/snapshot-durable-store.d.ts +4 -0
  46. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  47. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  48. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  49. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  51. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  52. package/dist/builtins/system-config/system-config.addon.js +1 -1
  53. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  54. package/dist/builtins/winston-logging/index.js +1 -1
  55. package/dist/builtins/winston-logging/index.mjs +1 -1
  56. package/dist/{dist-DchKwh_m.mjs → dist-AHdiIdJH.mjs} +412 -19
  57. package/dist/{dist-C_4Xt0Ya.js → dist-D_OlSf31.js} +417 -18
  58. package/dist/index.d.ts +7 -0
  59. package/dist/index.js +104 -38
  60. package/dist/index.mjs +102 -40
  61. package/dist/kernel/capability-registry.d.ts +59 -9
  62. package/dist/kernel/index.d.ts +1 -0
  63. package/dist/{retired-settings-keys-DPSHUHMu.mjs → retired-settings-keys-Cp3oG_aH.mjs} +1 -1
  64. package/dist/{retired-settings-keys-6wZNp7lr.js → retired-settings-keys-LwFyTKun.js} +1 -1
  65. package/dist/tls/cert-identity.d.ts +22 -0
  66. package/dist/tls/cert-issue.d.ts +31 -0
  67. package/dist/tls/cert-manager.d.ts +8 -2
  68. package/dist/tls/index.d.ts +2 -2
  69. package/dist/tls-D_wUeOTD.js +12122 -0
  70. package/dist/tls-IM-v7JV4.mjs +11984 -0
  71. package/package.json +2 -1
  72. package/dist/tls/cert-openssl.d.ts +0 -23
  73. package/dist/tls-2xbgg78V.mjs +0 -752
  74. package/dist/tls-BFs4PzoW.js +0 -890
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-C_4Xt0Ya.js");
3
+ const require_dist = require("./dist-D_OlSf31.js");
4
4
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
5
5
  require("./builtins/alerts/index.js");
6
6
  const require_formatter = require("./formatter-DqAKDlvN.js");
@@ -26,7 +26,7 @@ const require_builtins_system_config_system_config_addon = require("./builtins/s
26
26
  require("./builtins/system-config/index.js");
27
27
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
28
28
  const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-CAsHdMwP.js");
29
- const require_tls$1 = require("./tls-BFs4PzoW.js");
29
+ const require_tls$1 = require("./tls-D_wUeOTD.js");
30
30
  const require_manifest_system_deps = require("./manifest-system-deps-CfVyUKLU.js");
31
31
  const require_resource_monitor = require("./resource-monitor-LVE1BoLs.js");
32
32
  const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
@@ -5892,8 +5892,23 @@ var CapabilityRegistry = class CapabilityRegistry {
5892
5892
  singletonNodeOverrides = /* @__PURE__ */ new Map();
5893
5893
  /** Optional reader for persisted per-node overrides: (cap, nodeId) → addonId. */
5894
5894
  nodeConfigReader = null;
5895
- /** Per-device collection filters: deviceId → (capability → addonIds[]) */
5896
- deviceCollectionFilters = /* @__PURE__ */ new Map();
5895
+ /**
5896
+ * Per-device SOURCE deactivations: deviceId → (capability → disabled addon ids).
5897
+ *
5898
+ * The in-memory PROJECTION of the persisted wrapper activation
5899
+ * (`deviceBindings[deviceId][capName].disabledSourceAddonIds`, written by
5900
+ * `setWrapperActive`), and never an authority of its own —
5901
+ * [D556](../../../../docs/decisions/adr-0556-a-per-device-source-switch-is-the-wrapper-activation-and-the-registry-holds-only-its-projection.md).
5902
+ * Nothing but `device-source-activation.ts` writes it: the operator's verb
5903
+ * is `deviceManager.setWrapperActive`, and a second writable surface here is
5904
+ * exactly the two-authorities defect D62 exists for.
5905
+ *
5906
+ * A DENY list, not an allow list, and that is the deliberate answer to what
5907
+ * "unset" means: a source nobody has ruled out is a source. An untouched
5908
+ * camera keeps every provider it has today, and a provider that registers
5909
+ * after the operator's last toggle needs no second write to be seen.
5910
+ */
5911
+ deviceDisabledSources = /* @__PURE__ */ new Map();
5897
5912
  /** autoActivate flags per (capability, addonId) — from addon manifests */
5898
5913
  autoActivateFlags = /* @__PURE__ */ new Map();
5899
5914
  /**
@@ -6789,54 +6804,73 @@ var CapabilityRegistry = class CapabilityRegistry {
6789
6804
  for (const [addonId, provider] of state.providers) if (this.isActiveForSystem(capability, addonId)) return asProvider(provider);
6790
6805
  return null;
6791
6806
  }
6792
- /** Set a per-device collection filter. */
6793
- setDeviceCollectionFilter(deviceId, capability, addonIds) {
6794
- if (!this.capabilities.get(capability)) {
6795
- this.logger.warn("Cannot set device collection filter for undeclared capability", { meta: { capability } });
6807
+ /**
6808
+ * Mirror ONE device's persisted source deactivations for `capability` into
6809
+ * the projection (D556). The authority is the device-manager's
6810
+ * `deviceBindings` store; this is the read side of that write and the only
6811
+ * way the set changes.
6812
+ *
6813
+ * No check that `capability` is declared, and none that the addons are
6814
+ * registered: a persisted operator decision is a fact about the fleet, not a
6815
+ * reference to a live object, and replaying it at boot must not depend on
6816
+ * which addon happened to register first. An empty list drops the entry
6817
+ * (unset = every source).
6818
+ */
6819
+ setDeviceDisabledSources(deviceId, capability, addonIds) {
6820
+ let deviceMap = this.deviceDisabledSources.get(deviceId);
6821
+ if (addonIds.length === 0) {
6822
+ if (!deviceMap) return;
6823
+ deviceMap.delete(capability);
6824
+ if (deviceMap.size === 0) this.deviceDisabledSources.delete(deviceId);
6825
+ this.logger.debug("Device source deactivations cleared", {
6826
+ tags: { deviceId: Number(deviceId) },
6827
+ meta: { capability }
6828
+ });
6796
6829
  return;
6797
6830
  }
6798
- let deviceMap = this.deviceCollectionFilters.get(deviceId);
6799
6831
  if (!deviceMap) {
6800
6832
  deviceMap = /* @__PURE__ */ new Map();
6801
- this.deviceCollectionFilters.set(deviceId, deviceMap);
6833
+ this.deviceDisabledSources.set(deviceId, deviceMap);
6802
6834
  }
6803
- deviceMap.set(capability, [...addonIds]);
6804
- this.logger.info("Device collection filter set", {
6835
+ deviceMap.set(capability, new Set(addonIds));
6836
+ this.logger.debug("Device source deactivations mirrored", {
6805
6837
  tags: { deviceId: Number(deviceId) },
6806
6838
  meta: {
6807
6839
  capability,
6808
- addonIds
6840
+ disabledAddonIds: [...addonIds]
6809
6841
  }
6810
6842
  });
6811
6843
  }
6812
- /** Clear a per-device collection filter. */
6813
- clearDeviceCollectionFilter(deviceId, capability) {
6814
- const deviceMap = this.deviceCollectionFilters.get(deviceId);
6815
- if (!deviceMap) return;
6816
- deviceMap.delete(capability);
6817
- if (deviceMap.size === 0) this.deviceCollectionFilters.delete(deviceId);
6818
- this.logger.info("Device collection filter cleared", {
6819
- tags: { deviceId: Number(deviceId) },
6820
- meta: { capability }
6821
- });
6844
+ /**
6845
+ * The addon ids the operator switched OFF as sources of this device for
6846
+ * `capability`. Empty means every source — never "none".
6847
+ */
6848
+ getDeviceDisabledSources(deviceId, capability) {
6849
+ const disabled = this.deviceDisabledSources.get(deviceId)?.get(capability);
6850
+ return disabled === void 0 ? [] : [...disabled];
6851
+ }
6852
+ /** Is `addonId` switched off as a source of this device for `capability`? */
6853
+ isDeviceSourceDisabled(deviceId, capability, addonId) {
6854
+ return this.deviceDisabledSources.get(deviceId)?.get(capability)?.has(addonId) === true;
6822
6855
  }
6823
6856
  /**
6824
6857
  * Resolve collection providers for a specific device.
6825
- * Filters by activation (the manifest's autoActivate) and optional collection filter.
6826
- */
6827
- resolveCollectionForDevice(capability, deviceId) {
6858
+ * Filters by activation (the manifest's autoActivate) and by the per-device
6859
+ * source deactivations the operator persisted (D556).
6860
+ *
6861
+ * `includeSwitchedOff` keeps the providers the operator switched off for this
6862
+ * device. It exists for ONE caller — the source LISTING path — because a
6863
+ * switched-off source must still produce a row to be switched back on from
6864
+ * (D554 decision 4, D556 as amended), and only its own provider can name it.
6865
+ * Every other path takes the default and sees the SERVING set: the sources
6866
+ * that may actually contribute.
6867
+ */
6868
+ resolveCollectionForDevice(capability, deviceId, options) {
6828
6869
  const state = this.capabilities.get(capability);
6829
6870
  if (!state || state.definition.mode !== "collection") return [];
6830
- let entries = [...state.providers.entries()].filter(([addonId]) => !state.disabledProviders.has(addonId)).filter(([addonId]) => this.isActiveForSystem(capability, addonId));
6831
- const deviceMap = this.deviceCollectionFilters.get(deviceId);
6832
- if (deviceMap) {
6833
- const filterAddonIds = deviceMap.get(capability);
6834
- if (filterAddonIds) {
6835
- const filterSet = new Set(filterAddonIds);
6836
- entries = entries.filter(([addonId]) => filterSet.has(addonId));
6837
- }
6838
- }
6839
- return entries.map(([, provider]) => asProvider(provider));
6871
+ const disabledForDevice = this.deviceDisabledSources.get(deviceId)?.get(capability);
6872
+ const keepSwitchedOff = options?.includeSwitchedOff === true;
6873
+ return [...state.providers.entries()].filter(([addonId]) => !state.disabledProviders.has(addonId)).filter(([addonId]) => this.isActiveForSystem(capability, addonId)).filter(([addonId]) => keepSwitchedOff || disabledForDevice?.has(addonId) !== true).map(([, provider]) => asProvider(provider));
6840
6874
  }
6841
6875
  /** Check if all dependencies for a capability are satisfied. */
6842
6876
  areDependenciesMet(capabilityName) {
@@ -7000,6 +7034,35 @@ var CapabilityRegistry = class CapabilityRegistry {
7000
7034
  function systemMountKindFor(def) {
7001
7035
  return def.mode === "collection" ? "collection" : "singleton";
7002
7036
  }
7037
+ /**
7038
+ * The mount kind ONE method resolves through — the cap's mount, except where
7039
+ * the method cannot be dispatched per device.
7040
+ *
7041
+ * Two ways a method leaves a per-device mount for the cap's SYSTEM provider:
7042
+ *
7043
+ * - `systemOnly: true` — declared via the `systemMethod()` factory. The
7044
+ * author said so; it wins everywhere, including on a `device-native` cap
7045
+ * (`snapshot.getSnapshotOverview`).
7046
+ * - a `device-scoped` cap's method whose input declares no top-level REQUIRED
7047
+ * numeric `deviceId`. The per-device dispatcher demands one on every call
7048
+ * (`requireDeviceScoped`), so such a method would answer BAD_REQUEST
7049
+ * "input must carry numeric deviceId" for every caller — unreachable. It
7050
+ * names no device, so there is no per-device provider to resolve: the cap's
7051
+ * hub-resident system/wrapper provider is the only honest destination, and
7052
+ * it is where that method already resolved before the mount was fixed.
7053
+ *
7054
+ * NOT applied to `device-native`, deliberately: there the native IS the device
7055
+ * and a deviceId-less method is a definition error the author must resolve
7056
+ * with `systemMethod()` — which is what `snapshot` does. This rule exists for
7057
+ * the mount kind that was DERIVED under caps that never opted in, where a
7058
+ * silent 400 would be a regression introduced by the derivation itself.
7059
+ */
7060
+ function methodMountKindFor(def, mountKind, method) {
7061
+ if (method.schema.systemOnly === true) return systemMountKindFor(def);
7062
+ if (mountKind !== "device-scoped") return mountKind;
7063
+ if (require_dist.objectInputDeclaresRequiredDeviceId(method.schema.input)) return mountKind;
7064
+ return systemMountKindFor(def);
7065
+ }
7003
7066
  function methodsFor(def) {
7004
7067
  const effective = require_dist.expandCapMethods(def);
7005
7068
  return Object.entries(effective).map(([name, schema]) => {
@@ -7126,12 +7189,11 @@ function requireLocal(capName, getLocal, services) {
7126
7189
  function buildOneCapRouter(def, primitives, services) {
7127
7190
  const capName = def.name;
7128
7191
  const mount = require_dist.resolveCapMount(def);
7129
- const systemMountKind = systemMountKindFor(def);
7130
7192
  const nodeIdData = def.nodeIdMode === "data";
7131
7193
  const procedures = {};
7132
7194
  for (const method of methodsFor(def)) {
7133
7195
  if (method.callerRequired && (method.kind === "subscription" || !method.isObject)) throw new Error(`Cap "${capName}" method "${method.name}": caller: 'required' is only supported on query/mutation methods with an object input schema`);
7134
- const effectiveMountKind = method.schema.systemOnly === true ? systemMountKind : mount.kind;
7196
+ const effectiveMountKind = methodMountKindFor(def, mount.kind, method);
7135
7197
  const isCollection = effectiveMountKind === "collection";
7136
7198
  const getLocal = (ctx, addonId) => services.getLocalProvider(capName, effectiveMountKind, ctx, addonId);
7137
7199
  const base = primitives.procedures[require_dist.procedureAuthKey(method.auth)];
@@ -96177,12 +96239,14 @@ exports.isClusterSecretMismatchError = isClusterSecretMismatchError;
96177
96239
  exports.isCollectionArrayMethod = require_dist.isCollectionArrayMethod;
96178
96240
  exports.isInfraCapability = isInfraCapability;
96179
96241
  exports.isModelDownloaded = require_event_loop_stall_monitor.isModelDownloaded;
96242
+ exports.isSourceDenied = require_builtins_device_manager_device_manager_addon.isSourceDenied;
96180
96243
  exports.isSourceNewer = isSourceNewer;
96181
96244
  exports.isolatedBuiltinPhase = isolatedBuiltinPhase;
96182
96245
  exports.loadTlsCert = require_tls$1.loadTlsCert;
96183
96246
  exports.localEndpointPath = require_manifest_system_deps.localEndpointPath;
96184
96247
  exports.localProviderLink = require_manifest_system_deps.localProviderLink;
96185
96248
  exports.mountNativeCapService = require_manifest_system_deps.mountNativeCapService;
96249
+ exports.nextDisabledSources = require_builtins_device_manager_device_manager_addon.nextDisabledSources;
96186
96250
  exports.nextRssBudgetState = require_manifest_system_deps.nextRssBudgetState;
96187
96251
  exports.parseCapAction = require_manifest_system_deps.parseCapAction;
96188
96252
  exports.parseRangeHeader = require_event_loop_stall_monitor.parseRangeHeader;
@@ -96208,6 +96272,7 @@ exports.reissueTlsLeaf = require_tls$1.reissueTlsLeaf;
96208
96272
  exports.resolveFilePath = require_event_loop_stall_monitor.resolveFilePath;
96209
96273
  exports.resolveHwAccel = require_manifest_system_deps.resolveHwAccel;
96210
96274
  exports.resolveNpmInvocation = require_manifest_system_deps.resolveNpmInvocation;
96275
+ exports.restoreDeviceSourceActivations = require_builtins_device_manager_device_manager_addon.restoreDeviceSourceActivations;
96211
96276
  exports.runHubAddonBoot = runHubAddonBoot;
96212
96277
  exports.runNpm = require_manifest_system_deps.runNpm;
96213
96278
  exports.sampleSocketDirection = require_manifest_system_deps.sampleSocketDirection;
@@ -96220,6 +96285,7 @@ exports.selectReportedSpaces = require_manifest_system_deps.selectReportedSpaces
96220
96285
  exports.serializeTypedArrays = require_manifest_system_deps.serializeTypedArrays;
96221
96286
  exports.setHubConnected = require_manifest_system_deps.setHubConnected;
96222
96287
  exports.setNodeEventInterest = require_manifest_system_deps.setNodeEventInterest;
96288
+ exports.setWrapperActive = require_builtins_device_manager_device_manager_addon.setWrapperActive;
96223
96289
  exports.shouldReclaim = require_manifest_system_deps.shouldReclaim;
96224
96290
  exports.socketDirectionBytes = require_manifest_system_deps.socketDirectionBytes;
96225
96291
  exports.socketDirectionMessages = require_manifest_system_deps.socketDirectionMessages;
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { An as readinessKey, Cn as expandCapMethods, F as addonSettingsCapability, Ft as procedureAuthKey, Mn as scopeKey, Mt as objectInputDeclaresAddonId, On as parseJsonObject, Pn as EventCategory$1, S as RUNTIME_DEFAULTS, Tt as looseSchema, Ut as scopesAllowAddon, Vt as resolveMethodAuth, Wt as scopesAllowDeviceCap, _n as asJsonObject$1, _t as isVoidInput, an as errMsg$1, bn as createEvent, bt as lifecycleJobSchema, cn as DATAPLANE_SECRET_HEADER$1, dt as isArrayOutputSchema, ft as isCollectionArrayMethod, g as LOG_LEVEL_RANK, hn as ReadinessTimeoutError, jn as resolveCapMount, kn as parseJsonUnknown, ln as DEVICE_SETTINGS_CONTRIBUTION_METHODS, mn as ReadinessRegistry, mt as isObjectInput, st as extractNestedAddonId, t as ALL_CAPABILITY_DEFINITIONS, un as DEVICE_STATUS_METHOD, vn as asNumber, vt as kebabToCamel, wt as logLevelAtMost, xn as emitDownForOwnedCaps, y as METHOD_ACCESS_MAP, yn as asString$1 } from "./dist-DchKwh_m.mjs";
2
+ import { An as parseJsonUnknown, F as addonSettingsCapability, Fn as EventCategory$1, Gt as scopesAllowDeviceCap, Ht as resolveMethodAuth, It as procedureAuthKey, Mn as resolveCapMount, Mt as objectInputDeclaresAddonId, Nn as scopeKey, Nt as objectInputDeclaresRequiredDeviceId, S as RUNTIME_DEFAULTS, Sn as emitDownForOwnedCaps, Tt as looseSchema, Wt as scopesAllowAddon, _t as isVoidInput, bn as asString$1, bt as lifecycleJobSchema, dn as DEVICE_STATUS_METHOD, dt as isArrayOutputSchema, ft as isCollectionArrayMethod, g as LOG_LEVEL_RANK, gn as ReadinessTimeoutError, hn as ReadinessRegistry, jn as readinessKey, kn as parseJsonObject, ln as DATAPLANE_SECRET_HEADER$1, mt as isObjectInput, on as errMsg$1, st as extractNestedAddonId, t as ALL_CAPABILITY_DEFINITIONS, un as DEVICE_SETTINGS_CONTRIBUTION_METHODS, vn as asJsonObject$1, vt as kebabToCamel, wn as expandCapMethods, wt as logLevelAtMost, xn as createEvent, y as METHOD_ACCESS_MAP, yn as asNumber } from "./dist-AHdiIdJH.mjs";
3
3
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
4
4
  import "./builtins/alerts/index.mjs";
5
5
  import { t as formatLogLine } from "./formatter-B7qW8bPJ.mjs";
6
6
  import { ConsoleDestination, ConsoleLoggingAddon } from "./builtins/console-logging/index.mjs";
7
7
  import { CoreBlocksAddon } from "./builtins/core-blocks/core-blocks.addon.mjs";
8
8
  import "./builtins/core-blocks/index.mjs";
9
- import { DeviceManagerAddon } from "./builtins/device-manager/device-manager.addon.mjs";
9
+ import { DeviceManagerAddon, i as setWrapperActive, n as nextDisabledSources, r as restoreDeviceSourceActivations, t as isSourceDenied } from "./builtins/device-manager/device-manager.addon.mjs";
10
10
  import "./builtins/device-manager/index.mjs";
11
11
  import { HubForwarderAddon, HubForwarderDestination } from "./builtins/hub-forwarder/index.mjs";
12
12
  import { LivenessMonitorAddon } from "./builtins/liveness-monitor/liveness-monitor.addon.mjs";
@@ -25,7 +25,7 @@ import { SystemConfigAddon } from "./builtins/system-config/system-config.addon.
25
25
  import "./builtins/system-config/index.mjs";
26
26
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
27
27
  import { _ as fetchJson, a as createFileDataPlaneHandler, c as parseRangeHeader, d as ModelDownloadService, f as collectModelFiles, g as ensureModel, h as downloadModel, i as startEventLoopStallMonitor, l as parseTokenizedUrl, m as downloadFile, n as STALL_TICK_MS, o as contentTypeFor, p as deleteModelFromDisk, r as attributeStall, s as createAuthenticatedFileServer, t as STALL_REPORT_MS, u as resolveFilePath, v as getModelFilePath, y as isModelDownloaded } from "./event-loop-stall-monitor-GPrVvx14.mjs";
28
- import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-2xbgg78V.mjs";
28
+ import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-IM-v7JV4.mjs";
29
29
  import { $ as buildNativeCapProxy, $t as ARRAY_BUFFER_CENSUS_SUSTAIN_MS, A as createUdsLogger, An as createSocketDirectionCounters, At as HEAP_WATCH_WARN_RATIO, B as UDS_NO_ROUTE_PREFIX, Bn as createCapActionCensus, Bt as createDeferredHeapWatchSink, C as deviceCapResolverLink, Cn as SOCKET_QUEUE_TOP_N, Ct as resolveNpmInvocation, D as createUdsEventBridge, Dn as formatSocketPlane, Dt as HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, E as createParentUnownedCallHandler, En as diffSocketPlane, Et as HEAP_RECLAIM_MIN_INTERVAL_MS, F as callWithServiceDiscovery, Fn as CAP_ACTION_OVERFLOW_LABEL, Ft as RSS_BUDGET_RELEASE_RATIO, G as getCapUsageRegistry, Gn as diffEventPlane, Gt as nextRssBudgetState, H as CapUsageRegistry, Hn as EVENT_PLANE_TOP_N, Ht as createV8Reclaimer, I as CapRouteError, In as CAP_ACTION_UNLABELLED, It as RUNNER_HEAP_WATCH_INTERVAL_MS, J as UdsLocalTransportServer, Jt as shouldReclaim, K as createLocalTransport, Kn as formatEventPlane, Kt as parseRssBudgetMb, L as classifyCapRoute, Ln as EMPTY_CAP_ACTION_READING, Lt as RUNNER_RSS_BUDGET_ENV, M as AGENT_CAP_FWD_ACTION, Mn as sampleSocketDirection, Mt as HUB_MAIN_RSS_BUDGET_MB, N as AGENT_CAP_FWD_SERVICE, Nn as socketDirectionBytes, Nt as HUB_RSS_BUDGET_ENV, O as createUdsEventBus, On as readSocketQueues, Ot as HEAP_RECLAIM_TRIGGER_MB, P as CapRouteResolver, Pn as socketDirectionMessages, Pt as RSS_BUDGET_REANNOUNCE_MIN_MS, Q as encodeFrame, Qt as ARRAY_BUFFER_CENSUS_COOLDOWN_MS, R as LocalChildClient, Rn as MAX_CAP_ACTIONS_PER_PEER, Rt as ZERO_LOOP_DELAY, S as buildLinkChain, Sn as SOCKET_PLANE_TOP_N, St as buildNpmChildEnv, T as localProviderLink, Tn as createSocketPlaneReader, Tt as createAddonDataPlaneFacility, U as PARENT_ROUTED_PROVIDER_ADDON_ID, Un as createEventPlaneMeter, Ut as describeRss, V as readMoleculerFanoutMode, Vn as diffCapActionCensus, Vt as createLoopDelayMeter, W as __resetCapUsageRegistryForTests, Wn as createEventPlaneReader, Wt as hubMainRssBudget, X as localEndpointPath, Xt as startRunnerHeapWatch, Y as SocketChannel, Yt as startHeapWatch, Z as FrameDecoder, Zt as strandedMb, _ as AddonDepsManager, _n as formatOutboundQueueVerdict, _t as CapabilityHandle, a as createUdsAddonContext, an as isArrayBufferCensusReport, b as brokerCallForCap, bn as formatMeshQueue, bt as installManifestNativeDeps, c as getOrInitReadinessRegistryForClient, cn as emitHeapDiagnosticReport, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as clusterEventTopic, dn as readHeapSpaces, dt as capBareAction, en as ARRAY_BUFFER_CENSUS_THRESHOLD_MB, et as buildUdsNativeCapProxy, f as getBrokerEventBus, fn as selectReportedSpaces, ft as capServiceName, g as subscribePassthrough, gn as createOutboundQueueGate, gt as DeviceRegistry, h as setNodeEventInterest, hn as OUTBOUND_QUEUE_THRESHOLD_BYTES, ht as serializeTypedArrays, i as createAddonContext, in as formatArrayBufferCensus, it as mountNativeCapService, j as createUdsLoggerWithControl, jn as recordSocketFrame, jt as HUB_MAIN_HEAP_WATCH_LABEL, k as udsChildLogToWorkerEntry, kn as EMPTY_SOCKET_DIRECTION, kt as HEAP_WATCH_INTERVAL_MS, l as setHubConnected, ln as formatHeapSpaces, lt as capActionName, m as registerEventBusService, mn as OUTBOUND_QUEUE_SUSTAIN_MS, mt as deserializeTypedArrays, n as installManifestPythonDeps, nn as createArrayBufferCensusGate, o as getWorkerDeviceRegistry, on as DECISIVE_HEAP_SPACES, ot as createAddonService, p as getMoleculerEventStats, pn as OUTBOUND_QUEUE_COOLDOWN_MS, pt as parseCapAction, q as UdsLocalTransportClient, qt as reclaimIntervalMs, r as adaptBrokerToCluster, rn as createInspectorArrayBufferCensus, s as getOrInitReadinessRegistry, sn as HEAP_SPACE_REPORT_MIN_MB, st as validateProviderRegistrations, t as installManifestSystemDeps, tn as ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, tt as createBrokerDeviceManagerApi, u as EVENT_TOPIC_PREFIX, un as heapSpaceField, ut as capActionSuffix, v as createKernelHwAccel, vn as MESH_QUEUE_TOP_N, vt as CapabilityUnavailableError, w as ipcParentLink, wn as createSocketPlaneMeter, wt as runNpm, x as brokerTransportLink, xn as EMPTY_SOCKET_PLANE_BASELINE, xt as resolveAddonClass, y as resolveHwAccel, yn as createMeshQueueReader, yt as copyBundledNativeModules, z as LocalChildRegistry, zn as capActionLabel, zt as buildHeapSample } from "./manifest-system-deps-BXf-Ouqx.mjs";
30
30
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Vp0bPV3U.mjs";
31
31
  import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
@@ -5885,8 +5885,23 @@ var CapabilityRegistry = class CapabilityRegistry {
5885
5885
  singletonNodeOverrides = /* @__PURE__ */ new Map();
5886
5886
  /** Optional reader for persisted per-node overrides: (cap, nodeId) → addonId. */
5887
5887
  nodeConfigReader = null;
5888
- /** Per-device collection filters: deviceId → (capability → addonIds[]) */
5889
- deviceCollectionFilters = /* @__PURE__ */ new Map();
5888
+ /**
5889
+ * Per-device SOURCE deactivations: deviceId → (capability → disabled addon ids).
5890
+ *
5891
+ * The in-memory PROJECTION of the persisted wrapper activation
5892
+ * (`deviceBindings[deviceId][capName].disabledSourceAddonIds`, written by
5893
+ * `setWrapperActive`), and never an authority of its own —
5894
+ * [D556](../../../../docs/decisions/adr-0556-a-per-device-source-switch-is-the-wrapper-activation-and-the-registry-holds-only-its-projection.md).
5895
+ * Nothing but `device-source-activation.ts` writes it: the operator's verb
5896
+ * is `deviceManager.setWrapperActive`, and a second writable surface here is
5897
+ * exactly the two-authorities defect D62 exists for.
5898
+ *
5899
+ * A DENY list, not an allow list, and that is the deliberate answer to what
5900
+ * "unset" means: a source nobody has ruled out is a source. An untouched
5901
+ * camera keeps every provider it has today, and a provider that registers
5902
+ * after the operator's last toggle needs no second write to be seen.
5903
+ */
5904
+ deviceDisabledSources = /* @__PURE__ */ new Map();
5890
5905
  /** autoActivate flags per (capability, addonId) — from addon manifests */
5891
5906
  autoActivateFlags = /* @__PURE__ */ new Map();
5892
5907
  /**
@@ -6782,54 +6797,73 @@ var CapabilityRegistry = class CapabilityRegistry {
6782
6797
  for (const [addonId, provider] of state.providers) if (this.isActiveForSystem(capability, addonId)) return asProvider(provider);
6783
6798
  return null;
6784
6799
  }
6785
- /** Set a per-device collection filter. */
6786
- setDeviceCollectionFilter(deviceId, capability, addonIds) {
6787
- if (!this.capabilities.get(capability)) {
6788
- this.logger.warn("Cannot set device collection filter for undeclared capability", { meta: { capability } });
6800
+ /**
6801
+ * Mirror ONE device's persisted source deactivations for `capability` into
6802
+ * the projection (D556). The authority is the device-manager's
6803
+ * `deviceBindings` store; this is the read side of that write and the only
6804
+ * way the set changes.
6805
+ *
6806
+ * No check that `capability` is declared, and none that the addons are
6807
+ * registered: a persisted operator decision is a fact about the fleet, not a
6808
+ * reference to a live object, and replaying it at boot must not depend on
6809
+ * which addon happened to register first. An empty list drops the entry
6810
+ * (unset = every source).
6811
+ */
6812
+ setDeviceDisabledSources(deviceId, capability, addonIds) {
6813
+ let deviceMap = this.deviceDisabledSources.get(deviceId);
6814
+ if (addonIds.length === 0) {
6815
+ if (!deviceMap) return;
6816
+ deviceMap.delete(capability);
6817
+ if (deviceMap.size === 0) this.deviceDisabledSources.delete(deviceId);
6818
+ this.logger.debug("Device source deactivations cleared", {
6819
+ tags: { deviceId: Number(deviceId) },
6820
+ meta: { capability }
6821
+ });
6789
6822
  return;
6790
6823
  }
6791
- let deviceMap = this.deviceCollectionFilters.get(deviceId);
6792
6824
  if (!deviceMap) {
6793
6825
  deviceMap = /* @__PURE__ */ new Map();
6794
- this.deviceCollectionFilters.set(deviceId, deviceMap);
6826
+ this.deviceDisabledSources.set(deviceId, deviceMap);
6795
6827
  }
6796
- deviceMap.set(capability, [...addonIds]);
6797
- this.logger.info("Device collection filter set", {
6828
+ deviceMap.set(capability, new Set(addonIds));
6829
+ this.logger.debug("Device source deactivations mirrored", {
6798
6830
  tags: { deviceId: Number(deviceId) },
6799
6831
  meta: {
6800
6832
  capability,
6801
- addonIds
6833
+ disabledAddonIds: [...addonIds]
6802
6834
  }
6803
6835
  });
6804
6836
  }
6805
- /** Clear a per-device collection filter. */
6806
- clearDeviceCollectionFilter(deviceId, capability) {
6807
- const deviceMap = this.deviceCollectionFilters.get(deviceId);
6808
- if (!deviceMap) return;
6809
- deviceMap.delete(capability);
6810
- if (deviceMap.size === 0) this.deviceCollectionFilters.delete(deviceId);
6811
- this.logger.info("Device collection filter cleared", {
6812
- tags: { deviceId: Number(deviceId) },
6813
- meta: { capability }
6814
- });
6837
+ /**
6838
+ * The addon ids the operator switched OFF as sources of this device for
6839
+ * `capability`. Empty means every source — never "none".
6840
+ */
6841
+ getDeviceDisabledSources(deviceId, capability) {
6842
+ const disabled = this.deviceDisabledSources.get(deviceId)?.get(capability);
6843
+ return disabled === void 0 ? [] : [...disabled];
6844
+ }
6845
+ /** Is `addonId` switched off as a source of this device for `capability`? */
6846
+ isDeviceSourceDisabled(deviceId, capability, addonId) {
6847
+ return this.deviceDisabledSources.get(deviceId)?.get(capability)?.has(addonId) === true;
6815
6848
  }
6816
6849
  /**
6817
6850
  * Resolve collection providers for a specific device.
6818
- * Filters by activation (the manifest's autoActivate) and optional collection filter.
6819
- */
6820
- resolveCollectionForDevice(capability, deviceId) {
6851
+ * Filters by activation (the manifest's autoActivate) and by the per-device
6852
+ * source deactivations the operator persisted (D556).
6853
+ *
6854
+ * `includeSwitchedOff` keeps the providers the operator switched off for this
6855
+ * device. It exists for ONE caller — the source LISTING path — because a
6856
+ * switched-off source must still produce a row to be switched back on from
6857
+ * (D554 decision 4, D556 as amended), and only its own provider can name it.
6858
+ * Every other path takes the default and sees the SERVING set: the sources
6859
+ * that may actually contribute.
6860
+ */
6861
+ resolveCollectionForDevice(capability, deviceId, options) {
6821
6862
  const state = this.capabilities.get(capability);
6822
6863
  if (!state || state.definition.mode !== "collection") return [];
6823
- let entries = [...state.providers.entries()].filter(([addonId]) => !state.disabledProviders.has(addonId)).filter(([addonId]) => this.isActiveForSystem(capability, addonId));
6824
- const deviceMap = this.deviceCollectionFilters.get(deviceId);
6825
- if (deviceMap) {
6826
- const filterAddonIds = deviceMap.get(capability);
6827
- if (filterAddonIds) {
6828
- const filterSet = new Set(filterAddonIds);
6829
- entries = entries.filter(([addonId]) => filterSet.has(addonId));
6830
- }
6831
- }
6832
- return entries.map(([, provider]) => asProvider(provider));
6864
+ const disabledForDevice = this.deviceDisabledSources.get(deviceId)?.get(capability);
6865
+ const keepSwitchedOff = options?.includeSwitchedOff === true;
6866
+ return [...state.providers.entries()].filter(([addonId]) => !state.disabledProviders.has(addonId)).filter(([addonId]) => this.isActiveForSystem(capability, addonId)).filter(([addonId]) => keepSwitchedOff || disabledForDevice?.has(addonId) !== true).map(([, provider]) => asProvider(provider));
6833
6867
  }
6834
6868
  /** Check if all dependencies for a capability are satisfied. */
6835
6869
  areDependenciesMet(capabilityName) {
@@ -6993,6 +7027,35 @@ var CapabilityRegistry = class CapabilityRegistry {
6993
7027
  function systemMountKindFor(def) {
6994
7028
  return def.mode === "collection" ? "collection" : "singleton";
6995
7029
  }
7030
+ /**
7031
+ * The mount kind ONE method resolves through — the cap's mount, except where
7032
+ * the method cannot be dispatched per device.
7033
+ *
7034
+ * Two ways a method leaves a per-device mount for the cap's SYSTEM provider:
7035
+ *
7036
+ * - `systemOnly: true` — declared via the `systemMethod()` factory. The
7037
+ * author said so; it wins everywhere, including on a `device-native` cap
7038
+ * (`snapshot.getSnapshotOverview`).
7039
+ * - a `device-scoped` cap's method whose input declares no top-level REQUIRED
7040
+ * numeric `deviceId`. The per-device dispatcher demands one on every call
7041
+ * (`requireDeviceScoped`), so such a method would answer BAD_REQUEST
7042
+ * "input must carry numeric deviceId" for every caller — unreachable. It
7043
+ * names no device, so there is no per-device provider to resolve: the cap's
7044
+ * hub-resident system/wrapper provider is the only honest destination, and
7045
+ * it is where that method already resolved before the mount was fixed.
7046
+ *
7047
+ * NOT applied to `device-native`, deliberately: there the native IS the device
7048
+ * and a deviceId-less method is a definition error the author must resolve
7049
+ * with `systemMethod()` — which is what `snapshot` does. This rule exists for
7050
+ * the mount kind that was DERIVED under caps that never opted in, where a
7051
+ * silent 400 would be a regression introduced by the derivation itself.
7052
+ */
7053
+ function methodMountKindFor(def, mountKind, method) {
7054
+ if (method.schema.systemOnly === true) return systemMountKindFor(def);
7055
+ if (mountKind !== "device-scoped") return mountKind;
7056
+ if (objectInputDeclaresRequiredDeviceId(method.schema.input)) return mountKind;
7057
+ return systemMountKindFor(def);
7058
+ }
6996
7059
  function methodsFor(def) {
6997
7060
  const effective = expandCapMethods(def);
6998
7061
  return Object.entries(effective).map(([name, schema]) => {
@@ -7119,12 +7182,11 @@ function requireLocal(capName, getLocal, services) {
7119
7182
  function buildOneCapRouter(def, primitives, services) {
7120
7183
  const capName = def.name;
7121
7184
  const mount = resolveCapMount(def);
7122
- const systemMountKind = systemMountKindFor(def);
7123
7185
  const nodeIdData = def.nodeIdMode === "data";
7124
7186
  const procedures = {};
7125
7187
  for (const method of methodsFor(def)) {
7126
7188
  if (method.callerRequired && (method.kind === "subscription" || !method.isObject)) throw new Error(`Cap "${capName}" method "${method.name}": caller: 'required' is only supported on query/mutation methods with an object input schema`);
7127
- const effectiveMountKind = method.schema.systemOnly === true ? systemMountKind : mount.kind;
7189
+ const effectiveMountKind = methodMountKindFor(def, mount.kind, method);
7128
7190
  const isCollection = effectiveMountKind === "collection";
7129
7191
  const getLocal = (ctx, addonId) => services.getLocalProvider(capName, effectiveMountKind, ctx, addonId);
7130
7192
  const base = primitives.procedures[procedureAuthKey(method.auth)];
@@ -95817,4 +95879,4 @@ var LifecycleJobEngine = class {
95817
95879
  }
95818
95880
  };
95819
95881
  //#endregion
95820
- export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
95882
+ export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createLocalTransport, createLoopDelayMeter, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceDenied, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, nextDisabledSources, nextRssBudgetState, parseCapAction, parseRangeHeader, parseRssBudgetMb, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readHeapSpaces, readLanHttpState, readMoleculerFanoutMode, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, restoreDeviceSourceActivations, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, setHubConnected, setNodeEventInterest, setWrapperActive, shouldReclaim, socketDirectionBytes, socketDirectionMessages, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -30,6 +30,17 @@ export type CollectionConfigReader = (capability: string) => readonly string[] |
30
30
  * cannot present it. See docs/decisions/adr-0188-an-unregister-carries-proof-of-ownership.md.
31
31
  */
32
32
  export type ProviderOwnerToken = string;
33
+ /**
34
+ * How much of a device's COLLECTION a caller is asking for.
35
+ *
36
+ * The default — and every caller that intends to USE the providers — is the
37
+ * serving set: the sources that may contribute. The source LISTING path asks
38
+ * for the whole set instead, because a source the operator switched off must
39
+ * still produce a row to be switched back on from (D556 as amended).
40
+ */
41
+ export interface DeviceCollectionResolution {
42
+ readonly includeSwitchedOff: boolean;
43
+ }
33
44
  export declare class CapabilityRegistry {
34
45
  private readonly capabilities;
35
46
  private readonly logger;
@@ -59,8 +70,23 @@ export declare class CapabilityRegistry {
59
70
  private readonly singletonNodeOverrides;
60
71
  /** Optional reader for persisted per-node overrides: (cap, nodeId) → addonId. */
61
72
  private nodeConfigReader;
62
- /** Per-device collection filters: deviceId → (capability → addonIds[]) */
63
- private readonly deviceCollectionFilters;
73
+ /**
74
+ * Per-device SOURCE deactivations: deviceId → (capability → disabled addon ids).
75
+ *
76
+ * The in-memory PROJECTION of the persisted wrapper activation
77
+ * (`deviceBindings[deviceId][capName].disabledSourceAddonIds`, written by
78
+ * `setWrapperActive`), and never an authority of its own —
79
+ * [D556](../../../../docs/decisions/adr-0556-a-per-device-source-switch-is-the-wrapper-activation-and-the-registry-holds-only-its-projection.md).
80
+ * Nothing but `device-source-activation.ts` writes it: the operator's verb
81
+ * is `deviceManager.setWrapperActive`, and a second writable surface here is
82
+ * exactly the two-authorities defect D62 exists for.
83
+ *
84
+ * A DENY list, not an allow list, and that is the deliberate answer to what
85
+ * "unset" means: a source nobody has ruled out is a source. An untouched
86
+ * camera keeps every provider it has today, and a provider that registers
87
+ * after the operator's last toggle needs no second write to be seen.
88
+ */
89
+ private readonly deviceDisabledSources;
64
90
  /** autoActivate flags per (capability, addonId) — from addon manifests */
65
91
  private readonly autoActivateFlags;
66
92
  /**
@@ -465,15 +491,39 @@ export declare class CapabilityRegistry {
465
491
  * singleton override — the in-memory provider pin, not a persisted flag.
466
492
  */
467
493
  resolveForDevice<T = unknown>(capability: string, deviceId: string): T | null;
468
- /** Set a per-device collection filter. */
469
- setDeviceCollectionFilter(deviceId: string, capability: string, addonIds: string[]): void;
470
- /** Clear a per-device collection filter. */
471
- clearDeviceCollectionFilter(deviceId: string, capability: string): void;
472
494
  /**
473
- * Resolve collection providers for a specific device.
474
- * Filters by activation (the manifest's autoActivate) and optional collection filter.
495
+ * Mirror ONE device's persisted source deactivations for `capability` into
496
+ * the projection (D556). The authority is the device-manager's
497
+ * `deviceBindings` store; this is the read side of that write and the only
498
+ * way the set changes.
499
+ *
500
+ * No check that `capability` is declared, and none that the addons are
501
+ * registered: a persisted operator decision is a fact about the fleet, not a
502
+ * reference to a live object, and replaying it at boot must not depend on
503
+ * which addon happened to register first. An empty list drops the entry
504
+ * (unset = every source).
505
+ */
506
+ setDeviceDisabledSources(deviceId: string, capability: string, addonIds: readonly string[]): void;
507
+ /**
508
+ * The addon ids the operator switched OFF as sources of this device for
509
+ * `capability`. Empty means every source — never "none".
475
510
  */
476
- resolveCollectionForDevice<T = unknown>(capability: string, deviceId: string): readonly T[];
511
+ getDeviceDisabledSources(deviceId: string, capability: string): readonly string[];
512
+ /** Is `addonId` switched off as a source of this device for `capability`? */
513
+ isDeviceSourceDisabled(deviceId: string, capability: string, addonId: string): boolean;
514
+ /**
515
+ * Resolve collection providers for a specific device.
516
+ * Filters by activation (the manifest's autoActivate) and by the per-device
517
+ * source deactivations the operator persisted (D556).
518
+ *
519
+ * `includeSwitchedOff` keeps the providers the operator switched off for this
520
+ * device. It exists for ONE caller — the source LISTING path — because a
521
+ * switched-off source must still produce a row to be switched back on from
522
+ * (D554 decision 4, D556 as amended), and only its own provider can name it.
523
+ * Every other path takes the default and sees the SERVING set: the sources
524
+ * that may actually contribute.
525
+ */
526
+ resolveCollectionForDevice<T = unknown>(capability: string, deviceId: string, options?: DeviceCollectionResolution): readonly T[];
477
527
  /** Check if all dependencies for a capability are satisfied. */
478
528
  areDependenciesMet(capabilityName: string): boolean;
479
529
  /** Get topologically sorted boot order based on dependsOn. */
@@ -13,6 +13,7 @@ export { RESTART_MARKER_FILE, clearPendingRestart, getRestartMarkerPath, readPen
13
13
  export type { PendingRestartMarker, RestartKind, ScheduleSelfRestartOptions, } from './restart-coordinator.js';
14
14
  export { CapabilityHandle, CapabilityUnavailableError } from './capability-handle.js';
15
15
  export { CapabilityRegistry } from './capability-registry.js';
16
+ export type { DeviceCollectionResolution } from './capability-registry.js';
16
17
  export { buildCapRouters, builderMountedCapNames } from './cap-router-builder.js';
17
18
  export type { CapRouterPrimitives, CapRouterServices, CapProviderGetter, RemoteProxyFactory, ProcedureBuilder, ProcedureResolverArgs, } from './cap-router-builder.js';
18
19
  export { describeProviderKindDrift } from './provider-kind-drift.js';
@@ -1,4 +1,4 @@
1
- import { _n as asJsonObject } from "./dist-DchKwh_m.mjs";
1
+ import { vn as asJsonObject } from "./dist-AHdiIdJH.mjs";
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-C_4Xt0Ya.js");
1
+ const require_dist = require("./dist-D_OlSf31.js");
2
2
  //#region src/builtins/sqlite-storage/retired-settings-keys.ts
3
3
  /**
4
4
  * Is THIS node the one whose settings store is the cluster's authority?
@@ -1,3 +1,23 @@
1
+ /** One address on one interface — the slice of `os.NetworkInterfaceInfo` this uses. */
2
+ export interface HostInterfaceAddress {
3
+ readonly address: string;
4
+ readonly internal: boolean;
5
+ }
6
+ /**
7
+ * What the certificate needs to know about the machine it identifies.
8
+ *
9
+ * Injected rather than read, for the same reason `evaluateExistingCert`
10
+ * takes `now` instead of calling `Date.now()`: a rule whose inputs are
11
+ * ambient cannot be stated in a test, and a spec that reads the real
12
+ * `os.hostname()` is a statement about the machine running it. The CI
13
+ * runner and this laptop disagreed about both halves (D551).
14
+ */
15
+ export interface HostFacts {
16
+ readonly hostname: string;
17
+ readonly networkInterfaces: Readonly<Record<string, readonly HostInterfaceAddress[] | undefined>>;
18
+ }
19
+ /** The real machine. The only place in `tls/` that touches `os`. */
20
+ export declare function systemHostFacts(): HostFacts;
1
21
  /**
2
22
  * Names/addresses that go INTO the certificate, and the subset whose
3
23
  * absence forces a reissue.
@@ -17,6 +37,8 @@ export interface CertIdentity {
17
37
  export interface CertIdentityOptions {
18
38
  readonly commonName: string;
19
39
  readonly extraSans: readonly string[];
40
+ /** The machine being certified. Defaults to {@link systemHostFacts}. */
41
+ readonly hostFacts?: HostFacts;
20
42
  }
21
43
  export declare function isIpv4(value: string): boolean;
22
44
  export declare function isIpv6(value: string): boolean;