camstack 1.2.109 → 1.2.111

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.
@@ -15741,13 +15741,28 @@ var RecordingBandSchema = external_exports.object({
15741
15741
  end: external_exports.string().regex(HHMM),
15742
15742
  mode: RecordingBandModeSchema,
15743
15743
  triggers: RecordingBandTriggersSchema.optional(),
15744
+ /**
15745
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
15746
+ *
15747
+ * It was the retroactive KEEP bound — which already-written segments survive
15748
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
15749
+ * broker could serve, or the gate would delete the seconds the ring had just
15750
+ * handed the writer. That "at least as wide as" is the tell: it was a second
15751
+ * expression of the broker's retention, in different units, in a different
15752
+ * addon, with an invariant the operator had to maintain by hand. The keep
15753
+ * bound is now derived from the one prebuffer ceiling and there is nothing
15754
+ * left to configure here.
15755
+ *
15756
+ * The key survives in the SHAPE so a config written before that record still
15757
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
15758
+ * strict, so simply deleting it would strip an operator's value in silence on
15759
+ * the next save (the failure D380 came one commit from shipping). Nothing
15760
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
15761
+ */
15744
15762
  preBufferSec: external_exports.number().min(0).optional(),
15745
15763
  postBufferSec: external_exports.number().min(0).optional()
15746
15764
  });
15747
- var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
15748
- preBufferSec: 15,
15749
- postBufferSec: 30
15750
- };
15765
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = { postBufferSec: 30 };
15751
15766
  var VISIT_MERGE_GAP_MS = DEFAULT_EVENTS_BAND_BUFFER_SEC.postBufferSec * 1e3;
15752
15767
  var RecordingRetentionSchema = external_exports.object({
15753
15768
  maxAgeDays: external_exports.number().min(0).optional(),
@@ -17869,12 +17884,30 @@ var BackupDestinationInfoSchema = external_exports.object({
17869
17884
  lastSuccessAt: external_exports.number().optional(),
17870
17885
  /** Newest-archive size from `manifests.json`, or undefined. */
17871
17886
  lastSuccessSizeBytes: external_exports.number().optional(),
17872
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
17887
+ /**
17888
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
17889
+ * destination, comma-joined. Absent when no enabled schedule targets it
17890
+ * — a destination nothing is scheduled to write to must not advertise a
17891
+ * cadence (D384). This is never the `backup_destination_policies.cron`
17892
+ * column: that per-location cron has scheduled nothing since 2026-07-28
17893
+ * and reading it made a destination with a DISABLED schedule claim a
17894
+ * nightly run.
17895
+ */
17873
17896
  cron: external_exports.string().optional(),
17874
- /** ms-epoch of next computed firing for this destination's cron, if any. */
17897
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
17875
17898
  nextRunAt: external_exports.number().optional(),
17876
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
17877
- lastRunAt: external_exports.number().optional()
17899
+ /**
17900
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
17901
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
17902
+ * newest archive that actually landed) and `lastError`.
17903
+ */
17904
+ lastAttemptAt: external_exports.number().optional(),
17905
+ /**
17906
+ * Why the last attempt failed, verbatim. Absent when the last attempt
17907
+ * landed the archive. A destination that has never been written to has
17908
+ * neither this nor `lastAttemptAt`.
17909
+ */
17910
+ lastError: external_exports.string().optional()
17878
17911
  });
17879
17912
  var BackupArchiveEntrySchema = external_exports.object({
17880
17913
  id: external_exports.string(),
@@ -17996,8 +18029,16 @@ var BackupScheduleSchema = external_exports.object({
17996
18029
  retentionCount: external_exports.number().int().min(1).max(1e3),
17997
18030
  /** Optional subset of source locations to include; omitted = all. */
17998
18031
  dataSources: external_exports.array(external_exports.string()).readonly().optional(),
17999
- /** ms-epoch of last successful run. */
18000
- lastRunAt: external_exports.number().optional(),
18032
+ /**
18033
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
18034
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
18035
+ * "succeeded" — a run refused by every destination stamps it too.
18036
+ */
18037
+ lastAttemptAt: external_exports.number().optional(),
18038
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
18039
+ lastSuccessAt: external_exports.number().optional(),
18040
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
18041
+ lastError: external_exports.string().optional(),
18001
18042
  /** ms-epoch of next computed firing (read-only, filled on list). */
18002
18043
  nextRunAt: external_exports.number().optional()
18003
18044
  });
@@ -18120,14 +18161,7 @@ var backupCapability = {
18120
18161
  locationId: external_exports.string(),
18121
18162
  enabled: external_exports.boolean(),
18122
18163
  retentionCount: external_exports.number().int().min(1).max(1e3),
18123
- label: external_exports.string().optional(),
18124
- /**
18125
- * Per-destination cron expression. Empty string clears the
18126
- * schedule (manual-only). Validated server-side via croner;
18127
- * malformed expressions reject the upsert with an actionable
18128
- * message.
18129
- */
18130
- cron: external_exports.string().optional()
18164
+ label: external_exports.string().optional()
18131
18165
  }), external_exports.void(), {
18132
18166
  kind: "mutation",
18133
18167
  auth: "admin"
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-667FSBVG.js";
4
+ } from "./chunk-A3Y6T7EJ.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-DE3AXTYV.js");
41
+ await import("./launcher-D6HMI7VW.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-DE3AXTYV.js");
86
+ await import("./launcher-D6HMI7VW.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-UWXU5NPV.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-ER4G5QZV.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-667FSBVG.js";
8
+ } from "./chunk-A3Y6T7EJ.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-HAP38XvL.js
23637
- var require_dist_HAP38XvL = __commonJS({
23638
- "../system/dist/dist-HAP38XvL.js"(exports) {
23636
+ // ../system/dist/dist-CcV3k-hD.js
23637
+ var require_dist_CcV3k_hD = __commonJS({
23638
+ "../system/dist/dist-CcV3k-hD.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -26240,13 +26240,28 @@ var require_dist_HAP38XvL = __commonJS({
26240
26240
  end: zod.z.string().regex(HHMM),
26241
26241
  mode: RecordingBandModeSchema,
26242
26242
  triggers: RecordingBandTriggersSchema.optional(),
26243
+ /**
26244
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
26245
+ *
26246
+ * It was the retroactive KEEP bound — which already-written segments survive
26247
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
26248
+ * broker could serve, or the gate would delete the seconds the ring had just
26249
+ * handed the writer. That "at least as wide as" is the tell: it was a second
26250
+ * expression of the broker's retention, in different units, in a different
26251
+ * addon, with an invariant the operator had to maintain by hand. The keep
26252
+ * bound is now derived from the one prebuffer ceiling and there is nothing
26253
+ * left to configure here.
26254
+ *
26255
+ * The key survives in the SHAPE so a config written before that record still
26256
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
26257
+ * strict, so simply deleting it would strip an operator's value in silence on
26258
+ * the next save (the failure D380 came one commit from shipping). Nothing
26259
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
26260
+ */
26243
26261
  preBufferSec: zod.z.number().min(0).optional(),
26244
26262
  postBufferSec: zod.z.number().min(0).optional()
26245
26263
  });
26246
- ({
26247
- preBufferSec: 15,
26248
- postBufferSec: 30
26249
- }).postBufferSec * 1e3;
26264
+ ({ postBufferSec: 30 }).postBufferSec * 1e3;
26250
26265
  var RecordingRetentionSchema = zod.z.object({
26251
26266
  maxAgeDays: zod.z.number().min(0).optional(),
26252
26267
  maxSizeGb: zod.z.number().min(0).optional()
@@ -28483,12 +28498,30 @@ var require_dist_HAP38XvL = __commonJS({
28483
28498
  lastSuccessAt: zod.z.number().optional(),
28484
28499
  /** Newest-archive size from `manifests.json`, or undefined. */
28485
28500
  lastSuccessSizeBytes: zod.z.number().optional(),
28486
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
28501
+ /**
28502
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
28503
+ * destination, comma-joined. Absent when no enabled schedule targets it
28504
+ * — a destination nothing is scheduled to write to must not advertise a
28505
+ * cadence (D384). This is never the `backup_destination_policies.cron`
28506
+ * column: that per-location cron has scheduled nothing since 2026-07-28
28507
+ * and reading it made a destination with a DISABLED schedule claim a
28508
+ * nightly run.
28509
+ */
28487
28510
  cron: zod.z.string().optional(),
28488
- /** ms-epoch of next computed firing for this destination's cron, if any. */
28511
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
28489
28512
  nextRunAt: zod.z.number().optional(),
28490
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
28491
- lastRunAt: zod.z.number().optional()
28513
+ /**
28514
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
28515
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
28516
+ * newest archive that actually landed) and `lastError`.
28517
+ */
28518
+ lastAttemptAt: zod.z.number().optional(),
28519
+ /**
28520
+ * Why the last attempt failed, verbatim. Absent when the last attempt
28521
+ * landed the archive. A destination that has never been written to has
28522
+ * neither this nor `lastAttemptAt`.
28523
+ */
28524
+ lastError: zod.z.string().optional()
28492
28525
  });
28493
28526
  var BackupArchiveEntrySchema = zod.z.object({
28494
28527
  id: zod.z.string(),
@@ -28610,8 +28643,16 @@ var require_dist_HAP38XvL = __commonJS({
28610
28643
  retentionCount: zod.z.number().int().min(1).max(1e3),
28611
28644
  /** Optional subset of source locations to include; omitted = all. */
28612
28645
  dataSources: zod.z.array(zod.z.string()).readonly().optional(),
28613
- /** ms-epoch of last successful run. */
28614
- lastRunAt: zod.z.number().optional(),
28646
+ /**
28647
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
28648
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
28649
+ * "succeeded" — a run refused by every destination stamps it too.
28650
+ */
28651
+ lastAttemptAt: zod.z.number().optional(),
28652
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
28653
+ lastSuccessAt: zod.z.number().optional(),
28654
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
28655
+ lastError: zod.z.string().optional(),
28615
28656
  /** ms-epoch of next computed firing (read-only, filled on list). */
28616
28657
  nextRunAt: zod.z.number().optional()
28617
28658
  });
@@ -28734,14 +28775,7 @@ var require_dist_HAP38XvL = __commonJS({
28734
28775
  locationId: zod.z.string(),
28735
28776
  enabled: zod.z.boolean(),
28736
28777
  retentionCount: zod.z.number().int().min(1).max(1e3),
28737
- label: zod.z.string().optional(),
28738
- /**
28739
- * Per-destination cron expression. Empty string clears the
28740
- * schedule (manual-only). Validated server-side via croner;
28741
- * malformed expressions reject the upsert with an actionable
28742
- * message.
28743
- */
28744
- cron: zod.z.string().optional()
28778
+ label: zod.z.string().optional()
28745
28779
  }), zod.z.void(), {
28746
28780
  kind: "mutation",
28747
28781
  auth: "admin"
@@ -60660,7 +60694,7 @@ var require_alerts_addon = __commonJS({
60660
60694
  [Symbol.toStringTag]: { value: "Module" }
60661
60695
  });
60662
60696
  require_chunk_Cek0wNdY();
60663
- var require_dist10 = require_dist_HAP38XvL();
60697
+ var require_dist10 = require_dist_CcV3k_hD();
60664
60698
  function selectExpired(alerts, cutoffMs) {
60665
60699
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60666
60700
  }
@@ -61479,7 +61513,7 @@ var require_console_logging = __commonJS({
61479
61513
  [Symbol.toStringTag]: { value: "Module" }
61480
61514
  });
61481
61515
  require_chunk_Cek0wNdY();
61482
- var require_dist10 = require_dist_HAP38XvL();
61516
+ var require_dist10 = require_dist_CcV3k_hD();
61483
61517
  var require_formatter = require_formatter_DqAKDlvN();
61484
61518
  var LEVEL_RANK = {
61485
61519
  debug: 0,
@@ -61573,7 +61607,7 @@ var require_core_blocks_addon = __commonJS({
61573
61607
  "use strict";
61574
61608
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61575
61609
  var require_chunk = require_chunk_Cek0wNdY();
61576
- var require_dist10 = require_dist_HAP38XvL();
61610
+ var require_dist10 = require_dist_CcV3k_hD();
61577
61611
  var node_crypto = __require("crypto");
61578
61612
  var node_fs_promises = __require("fs/promises");
61579
61613
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -62470,11 +62504,11 @@ var require_core_blocks = __commonJS({
62470
62504
  }
62471
62505
  });
62472
62506
 
62473
- // ../system/dist/retired-settings-keys-BYiTW-q4.js
62474
- var require_retired_settings_keys_BYiTW_q4 = __commonJS({
62475
- "../system/dist/retired-settings-keys-BYiTW-q4.js"(exports) {
62507
+ // ../system/dist/retired-settings-keys-Bd8fuwO1.js
62508
+ var require_retired_settings_keys_Bd8fuwO1 = __commonJS({
62509
+ "../system/dist/retired-settings-keys-Bd8fuwO1.js"(exports) {
62476
62510
  "use strict";
62477
- var require_dist10 = require_dist_HAP38XvL();
62511
+ var require_dist10 = require_dist_CcV3k_hD();
62478
62512
  function settingsStoreIsAuthoritativeHere(env) {
62479
62513
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62480
62514
  return raw === "" || raw === "hub";
@@ -64688,8 +64722,8 @@ var require_device_manager_addon = __commonJS({
64688
64722
  [Symbol.toStringTag]: { value: "Module" }
64689
64723
  });
64690
64724
  require_chunk_Cek0wNdY();
64691
- var require_dist10 = require_dist_HAP38XvL();
64692
- var require_retired_settings_keys = require_retired_settings_keys_BYiTW_q4();
64725
+ var require_dist10 = require_dist_CcV3k_hD();
64726
+ var require_retired_settings_keys = require_retired_settings_keys_Bd8fuwO1();
64693
64727
  var node_crypto = __require("crypto");
64694
64728
  var _camstack_types_node = require_node();
64695
64729
  var JOB_HISTORY = 20;
@@ -70314,7 +70348,7 @@ var require_hub_forwarder = __commonJS({
70314
70348
  [Symbol.toStringTag]: { value: "Module" }
70315
70349
  });
70316
70350
  require_chunk_Cek0wNdY();
70317
- var require_dist10 = require_dist_HAP38XvL();
70351
+ var require_dist10 = require_dist_CcV3k_hD();
70318
70352
  var require_formatter = require_formatter_DqAKDlvN();
70319
70353
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
70320
70354
  var HubForwarderDestination = class {
@@ -70451,7 +70485,7 @@ var require_liveness_monitor_addon = __commonJS({
70451
70485
  "use strict";
70452
70486
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
70453
70487
  require_chunk_Cek0wNdY();
70454
- var require_dist10 = require_dist_HAP38XvL();
70488
+ var require_dist10 = require_dist_CcV3k_hD();
70455
70489
  var NO_DEVICES = "liveness:no-devices";
70456
70490
  var ALL_OFFLINE = "liveness:all-devices-offline";
70457
70491
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -70647,7 +70681,7 @@ var require_local_auth_addon = __commonJS({
70647
70681
  [Symbol.toStringTag]: { value: "Module" }
70648
70682
  });
70649
70683
  var require_chunk = require_chunk_Cek0wNdY();
70650
- var require_dist10 = require_dist_HAP38XvL();
70684
+ var require_dist10 = require_dist_CcV3k_hD();
70651
70685
  var node_crypto = __require("crypto");
70652
70686
  node_crypto = require_chunk.__toESM(node_crypto);
70653
70687
  var crypto$1 = __require("crypto");
@@ -78460,7 +78494,7 @@ var require_loki_logging = __commonJS({
78460
78494
  [Symbol.toStringTag]: { value: "Module" }
78461
78495
  });
78462
78496
  require_chunk_Cek0wNdY();
78463
- var require_dist10 = require_dist_HAP38XvL();
78497
+ var require_dist10 = require_dist_CcV3k_hD();
78464
78498
  function sanitizeLabelName(raw) {
78465
78499
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
78466
78500
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79025,7 +79059,7 @@ var require_native_metrics_addon = __commonJS({
79025
79059
  [Symbol.toStringTag]: { value: "Module" }
79026
79060
  });
79027
79061
  var require_chunk = require_chunk_Cek0wNdY();
79028
- var require_dist10 = require_dist_HAP38XvL();
79062
+ var require_dist10 = require_dist_CcV3k_hD();
79029
79063
  var node_fs_promises = __require("fs/promises");
79030
79064
  var node_child_process = __require("child_process");
79031
79065
  var node_util = __require("util");
@@ -81609,7 +81643,7 @@ var require_filesystem_storage_addon = __commonJS({
81609
81643
  [Symbol.toStringTag]: { value: "Module" }
81610
81644
  });
81611
81645
  var require_chunk = require_chunk_Cek0wNdY();
81612
- var require_dist10 = require_dist_HAP38XvL();
81646
+ var require_dist10 = require_dist_CcV3k_hD();
81613
81647
  var node_crypto = __require("crypto");
81614
81648
  var node_fs_promises = __require("fs/promises");
81615
81649
  var node_path = __require("path");
@@ -82725,8 +82759,8 @@ var require_sqlite_settings_addon = __commonJS({
82725
82759
  [Symbol.toStringTag]: { value: "Module" }
82726
82760
  });
82727
82761
  var require_chunk = require_chunk_Cek0wNdY();
82728
- var require_dist10 = require_dist_HAP38XvL();
82729
- var require_retired_settings_keys = require_retired_settings_keys_BYiTW_q4();
82762
+ var require_dist10 = require_dist_CcV3k_hD();
82763
+ var require_retired_settings_keys = require_retired_settings_keys_Bd8fuwO1();
82730
82764
  var node_crypto = __require("crypto");
82731
82765
  var node_fs = __require("fs");
82732
82766
  var node_module = __require("module");
@@ -85216,7 +85250,7 @@ var require_storage_orchestrator_addon = __commonJS({
85216
85250
  [Symbol.toStringTag]: { value: "Module" }
85217
85251
  });
85218
85252
  var require_chunk = require_chunk_Cek0wNdY();
85219
- var require_dist10 = require_dist_HAP38XvL();
85253
+ var require_dist10 = require_dist_CcV3k_hD();
85220
85254
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
85221
85255
  var zod = require_zod();
85222
85256
  var node_crypto = __require("crypto");
@@ -88167,7 +88201,7 @@ var require_system_config_addon = __commonJS({
88167
88201
  [Symbol.toStringTag]: { value: "Module" }
88168
88202
  });
88169
88203
  require_chunk_Cek0wNdY();
88170
- var require_dist10 = require_dist_HAP38XvL();
88204
+ var require_dist10 = require_dist_CcV3k_hD();
88171
88205
  var SECTION_TITLES = {
88172
88206
  server: "Server",
88173
88207
  auth: "Authentication"
@@ -106228,7 +106262,7 @@ var require_winston_logging = __commonJS({
106228
106262
  [Symbol.toStringTag]: { value: "Module" }
106229
106263
  });
106230
106264
  var require_chunk = require_chunk_Cek0wNdY();
106231
- var require_dist10 = require_dist_HAP38XvL();
106265
+ var require_dist10 = require_dist_CcV3k_hD();
106232
106266
  var require_formatter = require_formatter_DqAKDlvN();
106233
106267
  var node_path = __require("path");
106234
106268
  node_path = require_chunk.__toESM(node_path);
@@ -130866,7 +130900,7 @@ var require_dist3 = __commonJS({
130866
130900
  "use strict";
130867
130901
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
130868
130902
  var require_chunk = require_chunk_Cek0wNdY();
130869
- var require_dist10 = require_dist_HAP38XvL();
130903
+ var require_dist10 = require_dist_CcV3k_hD();
130870
130904
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
130871
130905
  require_alerts();
130872
130906
  var require_formatter = require_formatter_DqAKDlvN();
@@ -213249,13 +213283,48 @@ var require_dist4 = __commonJS({
213249
213283
  end: zod.z.string().regex(HHMM),
213250
213284
  mode: RecordingBandModeSchema,
213251
213285
  triggers: RecordingBandTriggersSchema.optional(),
213286
+ /**
213287
+ * RETIRED (D381). A band no longer carries a pre-buffer of its own.
213288
+ *
213289
+ * It was the retroactive KEEP bound — which already-written segments survive
213290
+ * a trigger — and it had to be at least as wide as the widest pre-roll the
213291
+ * broker could serve, or the gate would delete the seconds the ring had just
213292
+ * handed the writer. That "at least as wide as" is the tell: it was a second
213293
+ * expression of the broker's retention, in different units, in a different
213294
+ * addon, with an invariant the operator had to maintain by hand. The keep
213295
+ * bound is now derived from the one prebuffer ceiling and there is nothing
213296
+ * left to configure here.
213297
+ *
213298
+ * The key survives in the SHAPE so a config written before that record still
213299
+ * parses and can be migrated deliberately — `RecordingBandSchema` is not
213300
+ * strict, so simply deleting it would strip an operator's value in silence on
213301
+ * the next save (the failure D380 came one commit from shipping). Nothing
213302
+ * reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
213303
+ */
213252
213304
  preBufferSec: zod.z.number().min(0).optional(),
213253
213305
  postBufferSec: zod.z.number().min(0).optional()
213254
213306
  });
213255
- var DEFAULT_EVENTS_BAND_BUFFER_SEC = {
213256
- preBufferSec: 15,
213257
- postBufferSec: 30
213258
- };
213307
+ var DEFAULT_EVENTS_BAND_BUFFER_SEC = { postBufferSec: 30 };
213308
+ function stripRetiredBandPreBufferSec(config) {
213309
+ const strippedBands = [];
213310
+ const bands = config.bands.map((band, index) => {
213311
+ if (band.preBufferSec === void 0) return band;
213312
+ strippedBands.push(index);
213313
+ const { preBufferSec: _retired, ...rest } = band;
213314
+ return rest;
213315
+ });
213316
+ if (strippedBands.length === 0) return {
213317
+ config,
213318
+ strippedBands
213319
+ };
213320
+ return {
213321
+ config: {
213322
+ ...config,
213323
+ bands
213324
+ },
213325
+ strippedBands
213326
+ };
213327
+ }
213259
213328
  var VISIT_MERGE_GAP_MS = DEFAULT_EVENTS_BAND_BUFFER_SEC.postBufferSec * 1e3;
213260
213329
  var RecordingRetentionSchema = zod.z.object({
213261
213330
  maxAgeDays: zod.z.number().min(0).optional(),
@@ -216629,12 +216698,30 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
216629
216698
  lastSuccessAt: zod.z.number().optional(),
216630
216699
  /** Newest-archive size from `manifests.json`, or undefined. */
216631
216700
  lastSuccessSizeBytes: zod.z.number().optional(),
216632
- /** Per-destination cron expression. Empty = manual-only (no schedule). */
216701
+ /**
216702
+ * Cron cadence(s) of the ENABLED schedules that fan out to this
216703
+ * destination, comma-joined. Absent when no enabled schedule targets it
216704
+ * — a destination nothing is scheduled to write to must not advertise a
216705
+ * cadence (D384). This is never the `backup_destination_policies.cron`
216706
+ * column: that per-location cron has scheduled nothing since 2026-07-28
216707
+ * and reading it made a destination with a DISABLED schedule claim a
216708
+ * nightly run.
216709
+ */
216633
216710
  cron: zod.z.string().optional(),
216634
- /** ms-epoch of next computed firing for this destination's cron, if any. */
216711
+ /** ms-epoch of the next firing across those schedules (earliest), if any. */
216635
216712
  nextRunAt: zod.z.number().optional(),
216636
- /** ms-epoch of last successful scheduled run (mirrors policy.lastRunAt). */
216637
- lastRunAt: zod.z.number().optional()
216713
+ /**
216714
+ * ms-epoch of the last time a run ATTEMPTED to write here — success or
216715
+ * failure. Never a success stamp: pair it with `lastSuccessAt` (the
216716
+ * newest archive that actually landed) and `lastError`.
216717
+ */
216718
+ lastAttemptAt: zod.z.number().optional(),
216719
+ /**
216720
+ * Why the last attempt failed, verbatim. Absent when the last attempt
216721
+ * landed the archive. A destination that has never been written to has
216722
+ * neither this nor `lastAttemptAt`.
216723
+ */
216724
+ lastError: zod.z.string().optional()
216638
216725
  });
216639
216726
  var BackupArchiveEntrySchema = zod.z.object({
216640
216727
  id: zod.z.string(),
@@ -216756,8 +216843,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
216756
216843
  retentionCount: zod.z.number().int().min(1).max(1e3),
216757
216844
  /** Optional subset of source locations to include; omitted = all. */
216758
216845
  dataSources: zod.z.array(zod.z.string()).readonly().optional(),
216759
- /** ms-epoch of last successful run. */
216760
- lastRunAt: zod.z.number().optional(),
216846
+ /**
216847
+ * ms-epoch of the last tick that FIRED this schedule. Stamped before the
216848
+ * archive runs (it is the dedupe anchor), so it says "attempted", never
216849
+ * "succeeded" — a run refused by every destination stamps it too.
216850
+ */
216851
+ lastAttemptAt: zod.z.number().optional(),
216852
+ /** ms-epoch of the last run of this schedule that landed at ≥1 destination. */
216853
+ lastSuccessAt: zod.z.number().optional(),
216854
+ /** Why the last fired run failed, verbatim. Absent when it succeeded. */
216855
+ lastError: zod.z.string().optional(),
216761
216856
  /** ms-epoch of next computed firing (read-only, filled on list). */
216762
216857
  nextRunAt: zod.z.number().optional()
216763
216858
  });
@@ -216880,14 +216975,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
216880
216975
  locationId: zod.z.string(),
216881
216976
  enabled: zod.z.boolean(),
216882
216977
  retentionCount: zod.z.number().int().min(1).max(1e3),
216883
- label: zod.z.string().optional(),
216884
- /**
216885
- * Per-destination cron expression. Empty string clears the
216886
- * schedule (manual-only). Validated server-side via croner;
216887
- * malformed expressions reject the upsert with an actionable
216888
- * message.
216889
- */
216890
- cron: zod.z.string().optional()
216978
+ label: zod.z.string().optional()
216891
216979
  }), zod.z.void(), {
216892
216980
  kind: "mutation",
216893
216981
  auth: "admin"
@@ -257536,6 +257624,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
257536
257624
  exports.streamParamsCapability = streamParamsCapability;
257537
257625
  exports.streamPixels = streamPixels;
257538
257626
  exports.streamQualityLabel = streamQualityLabel;
257627
+ exports.stripRetiredBandPreBufferSec = stripRetiredBandPreBufferSec;
257539
257628
  exports.subKindsOf = subKindsOf;
257540
257629
  exports.summarisePrivacyAudio = summarisePrivacyAudio;
257541
257630
  exports.summarizeEffectiveScope = summarizeEffectiveScope;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.109",
3
+ "version": "1.2.111",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",