@camstack/system 1.2.414 → 1.2.416

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 (92) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/addon-runner.mjs +1 -1
  3. package/dist/addon-utils.js +1 -1
  4. package/dist/addon-utils.mjs +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +1 -1
  10. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  15. package/dist/builtins/calendars/calendars.addon.js +1 -1
  16. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  17. package/dist/builtins/camera-grid/index.js +1 -1
  18. package/dist/builtins/camera-grid/index.mjs +1 -1
  19. package/dist/builtins/composer/composer.addon.js +2 -2
  20. package/dist/builtins/composer/composer.addon.mjs +2 -2
  21. package/dist/builtins/console-logging/index.js +1 -1
  22. package/dist/builtins/console-logging/index.mjs +1 -1
  23. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  24. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  25. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  26. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  27. package/dist/builtins/hub-forwarder/index.js +1 -1
  28. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  29. package/dist/builtins/keychain/index.js +3 -3
  30. package/dist/builtins/keychain/index.mjs +3 -3
  31. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  32. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  33. package/dist/builtins/local-auth/local-auth.addon.js +9 -8
  34. package/dist/builtins/local-auth/local-auth.addon.mjs +4 -3
  35. package/dist/builtins/local-network/hub-mdns-ciao.d.ts +7 -0
  36. package/dist/builtins/local-network/hub-mdns.d.ts +58 -0
  37. package/dist/builtins/local-network/local-network.addon.d.ts +11 -0
  38. package/dist/builtins/local-network/local-network.addon.js +194 -3
  39. package/dist/builtins/local-network/local-network.addon.mjs +195 -3
  40. package/dist/builtins/loki-logging/index.js +1 -1
  41. package/dist/builtins/loki-logging/index.mjs +1 -1
  42. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  43. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  44. package/dist/builtins/platform-probe/index.js +1 -1
  45. package/dist/builtins/platform-probe/index.mjs +1 -1
  46. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  47. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  48. package/dist/builtins/snapshot/index.js +1 -1
  49. package/dist/builtins/snapshot/index.mjs +1 -1
  50. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  51. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  52. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  53. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  54. package/dist/builtins/storage-orchestrator/storage-location-band-monitor.d.ts +43 -0
  55. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +6 -0
  56. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +112 -1
  57. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +112 -1
  58. package/dist/builtins/system-config/system-config.addon.js +80 -785
  59. package/dist/builtins/system-config/system-config.addon.mjs +52 -757
  60. package/dist/builtins/winston-logging/index.js +1 -1
  61. package/dist/builtins/winston-logging/index.mjs +1 -1
  62. package/dist/{child-cap-dispatch-fnYkJDjG.js → child-cap-dispatch-B87B0FrC.js} +1 -1
  63. package/dist/{child-cap-dispatch-CpYnlLNt.mjs → child-cap-dispatch-CmfT-OR2.mjs} +1 -1
  64. package/dist/{composition-sources-BX6Caql_.js → composition-sources-DBcOVpGn.js} +1 -1
  65. package/dist/{composition-sources-QndhKNb5.mjs → composition-sources-DEZqZLPT.mjs} +1 -1
  66. package/dist/{constants-vMEWqCqG.mjs → constants-BSBtmzm3.mjs} +1 -1
  67. package/dist/{constants-CMXQ1QIC.js → constants-C4jZO_qO.js} +1 -1
  68. package/dist/{dist-ItJ3qAAA.mjs → dist-DwE9yHdk.mjs} +67 -3
  69. package/dist/{dist-BcnmH70Z.js → dist-DxiDI8hZ.js} +78 -2
  70. package/dist/{event-loop-stall-monitor-DoFaUgFf.js → event-loop-stall-monitor-E2hFvhDg.js} +1 -1
  71. package/dist/{event-loop-stall-monitor-CogzcENb.mjs → event-loop-stall-monitor-LBZskC1S.mjs} +1 -1
  72. package/dist/index.js +7 -7
  73. package/dist/index.mjs +7 -7
  74. package/dist/{jwt-signing-key-CST1LdM6.js → jwt-signing-key-CsC-FxSm.js} +1 -1
  75. package/dist/{jwt-signing-key-CpMSrZuI.mjs → jwt-signing-key-DLbjTIuA.mjs} +1 -1
  76. package/dist/lib-B_R6sPC3.mjs +7106 -0
  77. package/dist/lib-DOJ5yyWA.js +7110 -0
  78. package/dist/{ms-DlIWNkkk.mjs → ms-CgH2OFlD.mjs} +2 -42
  79. package/dist/{ms-t68_FaqE.js → ms-LB3giGoU.js} +1 -48
  80. package/dist/{restore-archive-pSlTKRgU.js → restore-archive-BtKjaVua.js} +1 -1
  81. package/dist/{restore-archive-8F_M_wW0.mjs → restore-archive-CImzbuRo.mjs} +1 -1
  82. package/dist/{retired-settings-keys-D3E47aR_.js → retired-settings-keys-Cl1tnkmq.js} +1 -1
  83. package/dist/{retired-settings-keys-CbkMnFXg.mjs → retired-settings-keys-D1WsCdUY.mjs} +1 -1
  84. package/dist/safe-buffer-B1OjL1I9.mjs +42 -0
  85. package/dist/safe-buffer-D3aoa-7X.js +46 -0
  86. package/dist/src-CnAqG6EF.js +714 -0
  87. package/dist/src-hG4grMU4.mjs +709 -0
  88. package/dist/{tls-BWpwU-d5.js → tls-C0TRPfqc.js} +1 -1
  89. package/dist/{tls-C2NT-Orr.mjs → tls-D-2dPY-5.mjs} +1 -1
  90. package/dist/{x509.es-Xf3K_brW.mjs → x509.es-CAjSsrkk.mjs} +643 -2
  91. package/dist/{x509.es-BhTzcFhZ.js → x509.es-Dzl0BbmG.js} +653 -0
  92. package/package.json +2 -1
@@ -4,6 +4,7 @@ interface StorageOrchestratorConfig extends Record<string, unknown> {}
4
4
  export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestratorConfig> {
5
5
  private service;
6
6
  private pressureManager;
7
+ private readonly locationBandMonitor;
7
8
  /**
8
9
  * How much of each location CamStack itself holds (D388).
9
10
  *
@@ -100,6 +101,11 @@ export declare class StorageOrchestratorAddon extends BaseAddon<StorageOrchestra
100
101
  /** Single-flighted pressure sweep — never overlaps a slow eviction round. */
101
102
  private runPressureSweep;
102
103
  /**
104
+ * Sample free space for every managed location and emit NC band edges.
105
+ * A failed capacity read stays `null` (critical) — never folded to 0 (D393).
106
+ */
107
+ private emitLocationBandEvents;
108
+ /**
103
109
  * locationId → resolved `minFreePercent`. The policy is intrinsic to the
104
110
  * location's provider (`shouldSaveDiskSpace` gates the guard, `minFreePercent`
105
111
  * is the default), overridable per-location via `config.minFreePercent`.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-BcnmH70Z.js");
6
+ const require_dist = require("../../dist-DxiDI8hZ.js");
7
7
  const require_hub_cap_forward = require("../../hub-cap-forward-W8oEm4ME.js");
8
8
  let zod = require("zod");
9
9
  let node_crypto = require("node:crypto");
@@ -3342,6 +3342,64 @@ var StoragePressureManager = class {
3342
3342
  }
3343
3343
  };
3344
3344
  //#endregion
3345
+ //#region src/builtins/storage-orchestrator/storage-location-band-monitor.ts
3346
+ var DEFAULT_STORAGE_LOCATION_BAND_CONFIG = {
3347
+ lowPercent: 15,
3348
+ criticalPercent: 5
3349
+ };
3350
+ function bandOf(freePercent, config) {
3351
+ if (freePercent === null) return {
3352
+ band: "critical",
3353
+ reason: "capacity-unreadable"
3354
+ };
3355
+ if (freePercent <= config.criticalPercent) return {
3356
+ band: "critical",
3357
+ reason: "free-below-critical"
3358
+ };
3359
+ if (freePercent <= config.lowPercent) return {
3360
+ band: "low",
3361
+ reason: "free-below-warn"
3362
+ };
3363
+ return {
3364
+ band: "ok",
3365
+ reason: "free-ok"
3366
+ };
3367
+ }
3368
+ var StorageLocationBandMonitor = class {
3369
+ config;
3370
+ band = /* @__PURE__ */ new Map();
3371
+ constructor(config = DEFAULT_STORAGE_LOCATION_BAND_CONFIG) {
3372
+ this.config = config;
3373
+ }
3374
+ /**
3375
+ * Observe one sweep of managed locations. Locations missing from `samples`
3376
+ * drop their episode without emitting `ok` (disabled / removed).
3377
+ */
3378
+ observe(samples) {
3379
+ const seen = /* @__PURE__ */ new Set();
3380
+ const out = [];
3381
+ for (const sample of samples) {
3382
+ seen.add(sample.locationId);
3383
+ const { band, reason } = bandOf(sample.freePercent, this.config);
3384
+ const previous = this.band.get(sample.locationId) ?? null;
3385
+ if (previous === band) continue;
3386
+ this.band.set(sample.locationId, band);
3387
+ if (previous === null && band === "ok") continue;
3388
+ out.push({
3389
+ locationId: sample.locationId,
3390
+ ...sample.nodeId !== void 0 ? { nodeId: sample.nodeId } : {},
3391
+ ...sample.locationName !== void 0 ? { locationName: sample.locationName } : {},
3392
+ band,
3393
+ freePercent: sample.freePercent,
3394
+ reason,
3395
+ previous
3396
+ });
3397
+ }
3398
+ for (const id of [...this.band.keys()]) if (!seen.has(id)) this.band.delete(id);
3399
+ return out;
3400
+ }
3401
+ };
3402
+ //#endregion
3345
3403
  //#region src/builtins/storage-orchestrator/storage-orchestrator.addon.ts
3346
3404
  /**
3347
3405
  * `storage-orchestrator` builtin — singleton owner of the consumer-
@@ -3386,6 +3444,7 @@ var CAP_PROVIDER_REGISTERED_CATEGORY = "capability:provider-registered";
3386
3444
  var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
3387
3445
  service = null;
3388
3446
  pressureManager = null;
3447
+ locationBandMonitor = new StorageLocationBandMonitor();
3389
3448
  /**
3390
3449
  * How much of each location CamStack itself holds (D388).
3391
3450
  *
@@ -3888,6 +3947,7 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
3888
3947
  this.pressureSweepInFlight = true;
3889
3948
  try {
3890
3949
  await this.pressureManager.sweep();
3950
+ await this.emitLocationBandEvents();
3891
3951
  } catch (err) {
3892
3952
  this.ctxIfReady?.logger.warn("storage pressure sweep failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
3893
3953
  } finally {
@@ -3895,6 +3955,57 @@ var StorageOrchestratorAddon = class extends require_dist.BaseAddon {
3895
3955
  }
3896
3956
  }
3897
3957
  /**
3958
+ * Sample free space for every managed location and emit NC band edges.
3959
+ * A failed capacity read stays `null` (critical) — never folded to 0 (D393).
3960
+ */
3961
+ async emitLocationBandEvents() {
3962
+ const svc = this.service;
3963
+ const ctx = this.ctxIfReady;
3964
+ if (!svc || !ctx) return;
3965
+ const thresholds = await this.resolveLocationThresholds();
3966
+ const byId = new Map(svc.listLocations().map((loc) => [loc.id, loc]));
3967
+ const samples = await Promise.all([...thresholds.keys()].map(async (locationId) => {
3968
+ const loc = byId.get(locationId);
3969
+ if (loc === void 0 || !require_dist.mayReadLocation(loc)) return {
3970
+ locationId,
3971
+ freePercent: null
3972
+ };
3973
+ const capacity = await this.volumeCapacityOf(locationId).catch(() => null);
3974
+ const freePercent = capacity === null ? null : freePercentOf(capacity);
3975
+ return {
3976
+ locationId,
3977
+ nodeId: loc.nodeId,
3978
+ locationName: loc.displayName,
3979
+ freePercent
3980
+ };
3981
+ }));
3982
+ for (const edge of this.locationBandMonitor.observe(samples)) {
3983
+ const category = edge.band === "low" ? require_dist.EventCategory.StorageLocationLow : edge.band === "critical" ? require_dist.EventCategory.StorageLocationCritical : require_dist.EventCategory.StorageLocationOk;
3984
+ ctx.logger.info("storage: location band changed", { meta: {
3985
+ locationId: edge.locationId,
3986
+ band: edge.band,
3987
+ freePercent: edge.freePercent,
3988
+ reason: edge.reason
3989
+ } });
3990
+ ctx.eventBus.emit({
3991
+ id: (0, node_crypto.randomUUID)(),
3992
+ timestamp: /* @__PURE__ */ new Date(),
3993
+ source: {
3994
+ type: "addon",
3995
+ id: this.ctx.id
3996
+ },
3997
+ category,
3998
+ data: {
3999
+ locationId: edge.locationId,
4000
+ ...edge.nodeId !== void 0 ? { nodeId: edge.nodeId } : {},
4001
+ ...edge.locationName !== void 0 ? { locationName: edge.locationName } : {},
4002
+ freePercent: edge.freePercent,
4003
+ reason: edge.reason
4004
+ }
4005
+ });
4006
+ }
4007
+ }
4008
+ /**
3898
4009
  * locationId → resolved `minFreePercent`. The policy is intrinsic to the
3899
4010
  * location's provider (`shouldSaveDiskSpace` gates the guard, `minFreePercent`
3900
4011
  * is the default), overridable per-location via `config.minFreePercent`.
@@ -1,4 +1,4 @@
1
- import { B as StorageCleanupJobSchema, Fn as storageCapability, Ft as gbToBytes, H as StorageLocationTypeSchema, In as storageMigrationCapability, Jn as withLocationMode, Jr as resolveSecretMarkers, Jt as legacyModeOf, Mn as settingsStoreCapability, O as LegacyStorageLocationDefaultSchema, Ot as evictionPolicyOfLocation, Rr as isSecretMarker, Tn as resolveLocationMode, U as StorageMigrationJobSchema, Ur as parseJsonObject, V as StorageLocationModeSchema, Vt as isLocationEnabled, Zr as secretTreeFromPaths, dr as BaseAddon, hr as REDACTED_SECRET, ni as transformSecretWrite, nn as mayReadLocation, on as modeMayWrite, ri as EventCategory, rn as mayWriteToLocation, wr as collectSecretConfigKeys } from "../../dist-ItJ3qAAA.mjs";
1
+ import { $r as secretTreeFromPaths, A as LegacyStorageLocationDefaultSchema, At as evictionPolicyOfLocation, Br as isSecretMarker, Dn as resolveLocationMode, Er as collectSecretConfigKeys, G as StorageMigrationJobSchema, Gr as parseJsonObject, H as StorageCleanupJobSchema, Ln as storageCapability, Lt as gbToBytes, Pn as settingsStoreCapability, Rn as storageMigrationCapability, U as StorageLocationModeSchema, Ut as isLocationEnabled, W as StorageLocationTypeSchema, Xn as withLocationMode, Xr as resolveSecretMarkers, Xt as legacyModeOf, _r as REDACTED_SECRET, ai as EventCategory, an as mayWriteToLocation, cn as modeMayWrite, ii as transformSecretWrite, in as mayReadLocation, pr as BaseAddon } from "../../dist-DwE9yHdk.mjs";
2
2
  import { t as HUB_CAP_FWD_ACTION } from "../../hub-cap-forward-CDiN1p98.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
@@ -3337,6 +3337,64 @@ var StoragePressureManager = class {
3337
3337
  }
3338
3338
  };
3339
3339
  //#endregion
3340
+ //#region src/builtins/storage-orchestrator/storage-location-band-monitor.ts
3341
+ var DEFAULT_STORAGE_LOCATION_BAND_CONFIG = {
3342
+ lowPercent: 15,
3343
+ criticalPercent: 5
3344
+ };
3345
+ function bandOf(freePercent, config) {
3346
+ if (freePercent === null) return {
3347
+ band: "critical",
3348
+ reason: "capacity-unreadable"
3349
+ };
3350
+ if (freePercent <= config.criticalPercent) return {
3351
+ band: "critical",
3352
+ reason: "free-below-critical"
3353
+ };
3354
+ if (freePercent <= config.lowPercent) return {
3355
+ band: "low",
3356
+ reason: "free-below-warn"
3357
+ };
3358
+ return {
3359
+ band: "ok",
3360
+ reason: "free-ok"
3361
+ };
3362
+ }
3363
+ var StorageLocationBandMonitor = class {
3364
+ config;
3365
+ band = /* @__PURE__ */ new Map();
3366
+ constructor(config = DEFAULT_STORAGE_LOCATION_BAND_CONFIG) {
3367
+ this.config = config;
3368
+ }
3369
+ /**
3370
+ * Observe one sweep of managed locations. Locations missing from `samples`
3371
+ * drop their episode without emitting `ok` (disabled / removed).
3372
+ */
3373
+ observe(samples) {
3374
+ const seen = /* @__PURE__ */ new Set();
3375
+ const out = [];
3376
+ for (const sample of samples) {
3377
+ seen.add(sample.locationId);
3378
+ const { band, reason } = bandOf(sample.freePercent, this.config);
3379
+ const previous = this.band.get(sample.locationId) ?? null;
3380
+ if (previous === band) continue;
3381
+ this.band.set(sample.locationId, band);
3382
+ if (previous === null && band === "ok") continue;
3383
+ out.push({
3384
+ locationId: sample.locationId,
3385
+ ...sample.nodeId !== void 0 ? { nodeId: sample.nodeId } : {},
3386
+ ...sample.locationName !== void 0 ? { locationName: sample.locationName } : {},
3387
+ band,
3388
+ freePercent: sample.freePercent,
3389
+ reason,
3390
+ previous
3391
+ });
3392
+ }
3393
+ for (const id of [...this.band.keys()]) if (!seen.has(id)) this.band.delete(id);
3394
+ return out;
3395
+ }
3396
+ };
3397
+ //#endregion
3340
3398
  //#region src/builtins/storage-orchestrator/storage-orchestrator.addon.ts
3341
3399
  /**
3342
3400
  * `storage-orchestrator` builtin — singleton owner of the consumer-
@@ -3381,6 +3439,7 @@ var CAP_PROVIDER_REGISTERED_CATEGORY = "capability:provider-registered";
3381
3439
  var StorageOrchestratorAddon = class extends BaseAddon {
3382
3440
  service = null;
3383
3441
  pressureManager = null;
3442
+ locationBandMonitor = new StorageLocationBandMonitor();
3384
3443
  /**
3385
3444
  * How much of each location CamStack itself holds (D388).
3386
3445
  *
@@ -3883,6 +3942,7 @@ var StorageOrchestratorAddon = class extends BaseAddon {
3883
3942
  this.pressureSweepInFlight = true;
3884
3943
  try {
3885
3944
  await this.pressureManager.sweep();
3945
+ await this.emitLocationBandEvents();
3886
3946
  } catch (err) {
3887
3947
  this.ctxIfReady?.logger.warn("storage pressure sweep failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
3888
3948
  } finally {
@@ -3890,6 +3950,57 @@ var StorageOrchestratorAddon = class extends BaseAddon {
3890
3950
  }
3891
3951
  }
3892
3952
  /**
3953
+ * Sample free space for every managed location and emit NC band edges.
3954
+ * A failed capacity read stays `null` (critical) — never folded to 0 (D393).
3955
+ */
3956
+ async emitLocationBandEvents() {
3957
+ const svc = this.service;
3958
+ const ctx = this.ctxIfReady;
3959
+ if (!svc || !ctx) return;
3960
+ const thresholds = await this.resolveLocationThresholds();
3961
+ const byId = new Map(svc.listLocations().map((loc) => [loc.id, loc]));
3962
+ const samples = await Promise.all([...thresholds.keys()].map(async (locationId) => {
3963
+ const loc = byId.get(locationId);
3964
+ if (loc === void 0 || !mayReadLocation(loc)) return {
3965
+ locationId,
3966
+ freePercent: null
3967
+ };
3968
+ const capacity = await this.volumeCapacityOf(locationId).catch(() => null);
3969
+ const freePercent = capacity === null ? null : freePercentOf(capacity);
3970
+ return {
3971
+ locationId,
3972
+ nodeId: loc.nodeId,
3973
+ locationName: loc.displayName,
3974
+ freePercent
3975
+ };
3976
+ }));
3977
+ for (const edge of this.locationBandMonitor.observe(samples)) {
3978
+ const category = edge.band === "low" ? EventCategory.StorageLocationLow : edge.band === "critical" ? EventCategory.StorageLocationCritical : EventCategory.StorageLocationOk;
3979
+ ctx.logger.info("storage: location band changed", { meta: {
3980
+ locationId: edge.locationId,
3981
+ band: edge.band,
3982
+ freePercent: edge.freePercent,
3983
+ reason: edge.reason
3984
+ } });
3985
+ ctx.eventBus.emit({
3986
+ id: randomUUID(),
3987
+ timestamp: /* @__PURE__ */ new Date(),
3988
+ source: {
3989
+ type: "addon",
3990
+ id: this.ctx.id
3991
+ },
3992
+ category,
3993
+ data: {
3994
+ locationId: edge.locationId,
3995
+ ...edge.nodeId !== void 0 ? { nodeId: edge.nodeId } : {},
3996
+ ...edge.locationName !== void 0 ? { locationName: edge.locationName } : {},
3997
+ freePercent: edge.freePercent,
3998
+ reason: edge.reason
3999
+ }
4000
+ });
4001
+ }
4002
+ }
4003
+ /**
3893
4004
  * locationId → resolved `minFreePercent`. The policy is intrinsic to the
3894
4005
  * location's provider (`shouldSaveDiskSpace` gates the guard, `minFreePercent`
3895
4006
  * is the default), overridable per-location via `config.minFreePercent`.