@camstack/types 1.2.200 → 1.2.202

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.
@@ -236,15 +236,28 @@ export type TrackAudioLabel = z.infer<typeof TrackAudioLabelSchema>;
236
236
  * - `audio` — an audio event on the camera itself that was anomalous for
237
237
  * THAT camera, loud, and heard while nothing visual was happening (D62).
238
238
  *
239
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
240
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
241
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
242
+ * detector.
243
+ *
244
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
245
+ * a persisted onboard track failed `safeParse` on read and came back with NO
246
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
247
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
248
+ * could not name.
249
+ *
239
250
  * The spatial subsystems (tracker association, occupancy count, re-id /
240
251
  * embedding, resurrection) MUST skip every synthetic source. Test for that
241
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
242
- * check silently readmits every source added after it was written.
252
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
253
+ * `!== 'sensor'` check silently readmits every source added after it was
254
+ * written.
243
255
  */
244
256
  export declare const TrackSourceSchema: z.ZodEnum<{
245
257
  sensor: "sensor";
246
258
  pipeline: "pipeline";
247
259
  audio: "audio";
260
+ onboard: "onboard";
248
261
  }>;
249
262
  export type TrackSource = z.infer<typeof TrackSourceSchema>;
250
263
  /**
@@ -431,6 +444,7 @@ declare const TrackSchema: z.ZodObject<{
431
444
  sensor: "sensor";
432
445
  pipeline: "pipeline";
433
446
  audio: "audio";
447
+ onboard: "onboard";
434
448
  }>>;
435
449
  firstSeen: z.ZodNumber;
436
450
  lastSeen: z.ZodNumber;
@@ -711,6 +725,7 @@ declare const MediaFileKindEnum: z.ZodEnum<{
711
725
  keyFrame: "keyFrame";
712
726
  keyFrameSmall: "keyFrameSmall";
713
727
  thumbnailSmall: "thumbnailSmall";
728
+ confirmationCrop: "confirmationCrop";
714
729
  sceneFrame: "sceneFrame";
715
730
  }>;
716
731
  export type MediaFileKind = z.infer<typeof MediaFileKindEnum>;
@@ -738,6 +753,7 @@ declare const MediaFileRefSchema: z.ZodObject<{
738
753
  keyFrame: "keyFrame";
739
754
  keyFrameSmall: "keyFrameSmall";
740
755
  thumbnailSmall: "thumbnailSmall";
756
+ confirmationCrop: "confirmationCrop";
741
757
  sceneFrame: "sceneFrame";
742
758
  }>;
743
759
  sizeBytes: z.ZodNumber;
@@ -812,6 +828,7 @@ declare const MediaFileSchema: z.ZodObject<{
812
828
  keyFrame: "keyFrame";
813
829
  keyFrameSmall: "keyFrameSmall";
814
830
  thumbnailSmall: "thumbnailSmall";
831
+ confirmationCrop: "confirmationCrop";
815
832
  sceneFrame: "sceneFrame";
816
833
  }>;
817
834
  sizeBytes: z.ZodNumber;
@@ -849,6 +866,7 @@ declare const MediaFileInfoSchema: z.ZodObject<{
849
866
  keyFrame: "keyFrame";
850
867
  keyFrameSmall: "keyFrameSmall";
851
868
  thumbnailSmall: "thumbnailSmall";
869
+ confirmationCrop: "confirmationCrop";
852
870
  sceneFrame: "sceneFrame";
853
871
  }>;
854
872
  url: z.ZodString;
@@ -989,6 +1007,7 @@ export declare const RetrainFrameCandidateSchema: z.ZodObject<{
989
1007
  keyFrame: "keyFrame";
990
1008
  keyFrameSmall: "keyFrameSmall";
991
1009
  thumbnailSmall: "thumbnailSmall";
1010
+ confirmationCrop: "confirmationCrop";
992
1011
  sceneFrame: "sceneFrame";
993
1012
  }>;
994
1013
  timestamp: z.ZodNumber;
@@ -1015,6 +1034,7 @@ export declare const RetrainFrameSchema: z.ZodObject<{
1015
1034
  keyFrame: "keyFrame";
1016
1035
  keyFrameSmall: "keyFrameSmall";
1017
1036
  thumbnailSmall: "thumbnailSmall";
1037
+ confirmationCrop: "confirmationCrop";
1018
1038
  sceneFrame: "sceneFrame";
1019
1039
  }>;
1020
1040
  sizeBytes: z.ZodNumber;
@@ -1048,6 +1068,7 @@ export declare const RetrainFrameSelectionSchema: z.ZodObject<{
1048
1068
  keyFrame: "keyFrame";
1049
1069
  keyFrameSmall: "keyFrameSmall";
1050
1070
  thumbnailSmall: "thumbnailSmall";
1071
+ confirmationCrop: "confirmationCrop";
1051
1072
  sceneFrame: "sceneFrame";
1052
1073
  }>;
1053
1074
  sizeBytes: z.ZodNumber;
@@ -1081,6 +1102,7 @@ export declare const RetrainFrameListSchema: z.ZodObject<{
1081
1102
  keyFrame: "keyFrame";
1082
1103
  keyFrameSmall: "keyFrameSmall";
1083
1104
  thumbnailSmall: "thumbnailSmall";
1105
+ confirmationCrop: "confirmationCrop";
1084
1106
  sceneFrame: "sceneFrame";
1085
1107
  }>;
1086
1108
  timestamp: z.ZodNumber;
@@ -1105,6 +1127,7 @@ export declare const RetrainFrameListSchema: z.ZodObject<{
1105
1127
  keyFrame: "keyFrame";
1106
1128
  keyFrameSmall: "keyFrameSmall";
1107
1129
  thumbnailSmall: "thumbnailSmall";
1130
+ confirmationCrop: "confirmationCrop";
1108
1131
  sceneFrame: "sceneFrame";
1109
1132
  }>;
1110
1133
  sizeBytes: z.ZodNumber;
@@ -1208,6 +1231,7 @@ declare const RecentTracksQueryInput: z.ZodObject<{
1208
1231
  sensor: "sensor";
1209
1232
  pipeline: "pipeline";
1210
1233
  audio: "audio";
1234
+ onboard: "onboard";
1211
1235
  }>>>;
1212
1236
  }, z.core.$strip>;
1213
1237
  export type RecentTracksQuery = z.infer<typeof RecentTracksQueryInput>;
@@ -1337,6 +1361,7 @@ declare const RecentTracksPageSchema: z.ZodObject<{
1337
1361
  sensor: "sensor";
1338
1362
  pipeline: "pipeline";
1339
1363
  audio: "audio";
1364
+ onboard: "onboard";
1340
1365
  }>>;
1341
1366
  firstSeen: z.ZodNumber;
1342
1367
  lastSeen: z.ZodNumber;
@@ -1704,6 +1729,7 @@ declare const EventMediaKindFootprintSchema: z.ZodObject<{
1704
1729
  keyFrame: "keyFrame";
1705
1730
  keyFrameSmall: "keyFrameSmall";
1706
1731
  thumbnailSmall: "thumbnailSmall";
1732
+ confirmationCrop: "confirmationCrop";
1707
1733
  sceneFrame: "sceneFrame";
1708
1734
  }>;
1709
1735
  rows: z.ZodNumber;
@@ -1751,6 +1777,7 @@ declare const EventMediaKindBreakdownSchema: z.ZodObject<{
1751
1777
  keyFrame: "keyFrame";
1752
1778
  keyFrameSmall: "keyFrameSmall";
1753
1779
  thumbnailSmall: "thumbnailSmall";
1780
+ confirmationCrop: "confirmationCrop";
1754
1781
  sceneFrame: "sceneFrame";
1755
1782
  }>;
1756
1783
  rows: z.ZodNumber;
@@ -1876,6 +1903,7 @@ export declare const pipelineAnalyticsCapability: {
1876
1903
  sensor: "sensor";
1877
1904
  pipeline: "pipeline";
1878
1905
  audio: "audio";
1906
+ onboard: "onboard";
1879
1907
  }>>;
1880
1908
  firstSeen: z.ZodNumber;
1881
1909
  lastSeen: z.ZodNumber;
@@ -1985,6 +2013,7 @@ export declare const pipelineAnalyticsCapability: {
1985
2013
  sensor: "sensor";
1986
2014
  pipeline: "pipeline";
1987
2015
  audio: "audio";
2016
+ onboard: "onboard";
1988
2017
  }>>;
1989
2018
  firstSeen: z.ZodNumber;
1990
2019
  lastSeen: z.ZodNumber;
@@ -2107,6 +2136,7 @@ export declare const pipelineAnalyticsCapability: {
2107
2136
  sensor: "sensor";
2108
2137
  pipeline: "pipeline";
2109
2138
  audio: "audio";
2139
+ onboard: "onboard";
2110
2140
  }>>>;
2111
2141
  }, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
2112
2142
  retrainStatus: z.ZodOptional<z.ZodEnum<{
@@ -2123,6 +2153,7 @@ export declare const pipelineAnalyticsCapability: {
2123
2153
  sensor: "sensor";
2124
2154
  pipeline: "pipeline";
2125
2155
  audio: "audio";
2156
+ onboard: "onboard";
2126
2157
  }>>;
2127
2158
  firstSeen: z.ZodNumber;
2128
2159
  lastSeen: z.ZodNumber;
@@ -2240,6 +2271,7 @@ export declare const pipelineAnalyticsCapability: {
2240
2271
  sensor: "sensor";
2241
2272
  pipeline: "pipeline";
2242
2273
  audio: "audio";
2274
+ onboard: "onboard";
2243
2275
  }>>>;
2244
2276
  }, z.core.$strip>, z.ZodObject<{
2245
2277
  tracks: z.ZodReadonly<z.ZodArray<z.ZodObject<{
@@ -2257,6 +2289,7 @@ export declare const pipelineAnalyticsCapability: {
2257
2289
  sensor: "sensor";
2258
2290
  pipeline: "pipeline";
2259
2291
  audio: "audio";
2292
+ onboard: "onboard";
2260
2293
  }>>;
2261
2294
  firstSeen: z.ZodNumber;
2262
2295
  lastSeen: z.ZodNumber;
@@ -3173,6 +3206,7 @@ export declare const pipelineAnalyticsCapability: {
3173
3206
  keyFrame: "keyFrame";
3174
3207
  keyFrameSmall: "keyFrameSmall";
3175
3208
  thumbnailSmall: "thumbnailSmall";
3209
+ confirmationCrop: "confirmationCrop";
3176
3210
  sceneFrame: "sceneFrame";
3177
3211
  }>;
3178
3212
  rows: z.ZodNumber;
@@ -3565,6 +3599,7 @@ export declare const pipelineAnalyticsCapability: {
3565
3599
  keyFrame: "keyFrame";
3566
3600
  keyFrameSmall: "keyFrameSmall";
3567
3601
  thumbnailSmall: "thumbnailSmall";
3602
+ confirmationCrop: "confirmationCrop";
3568
3603
  sceneFrame: "sceneFrame";
3569
3604
  }>;
3570
3605
  timestamp: z.ZodNumber;
@@ -3589,6 +3624,7 @@ export declare const pipelineAnalyticsCapability: {
3589
3624
  keyFrame: "keyFrame";
3590
3625
  keyFrameSmall: "keyFrameSmall";
3591
3626
  thumbnailSmall: "thumbnailSmall";
3627
+ confirmationCrop: "confirmationCrop";
3592
3628
  sceneFrame: "sceneFrame";
3593
3629
  }>;
3594
3630
  sizeBytes: z.ZodNumber;
@@ -3635,6 +3671,7 @@ export declare const pipelineAnalyticsCapability: {
3635
3671
  keyFrame: "keyFrame";
3636
3672
  keyFrameSmall: "keyFrameSmall";
3637
3673
  thumbnailSmall: "thumbnailSmall";
3674
+ confirmationCrop: "confirmationCrop";
3638
3675
  sceneFrame: "sceneFrame";
3639
3676
  }>;
3640
3677
  sizeBytes: z.ZodNumber;
@@ -4045,6 +4082,7 @@ export declare const pipelineAnalyticsCapability: {
4045
4082
  keyFrame: "keyFrame";
4046
4083
  keyFrameSmall: "keyFrameSmall";
4047
4084
  thumbnailSmall: "thumbnailSmall";
4085
+ confirmationCrop: "confirmationCrop";
4048
4086
  sceneFrame: "sceneFrame";
4049
4087
  }>>;
4050
4088
  deviceId: z.ZodNumber;
@@ -4063,6 +4101,7 @@ export declare const pipelineAnalyticsCapability: {
4063
4101
  keyFrame: "keyFrame";
4064
4102
  keyFrameSmall: "keyFrameSmall";
4065
4103
  thumbnailSmall: "thumbnailSmall";
4104
+ confirmationCrop: "confirmationCrop";
4066
4105
  sceneFrame: "sceneFrame";
4067
4106
  }>;
4068
4107
  sizeBytes: z.ZodNumber;
@@ -4089,6 +4128,7 @@ export declare const pipelineAnalyticsCapability: {
4089
4128
  keyFrame: "keyFrame";
4090
4129
  keyFrameSmall: "keyFrameSmall";
4091
4130
  thumbnailSmall: "thumbnailSmall";
4131
+ confirmationCrop: "confirmationCrop";
4092
4132
  sceneFrame: "sceneFrame";
4093
4133
  }>>>;
4094
4134
  deviceId: z.ZodNumber;
@@ -4107,6 +4147,7 @@ export declare const pipelineAnalyticsCapability: {
4107
4147
  keyFrame: "keyFrame";
4108
4148
  keyFrameSmall: "keyFrameSmall";
4109
4149
  thumbnailSmall: "thumbnailSmall";
4150
+ confirmationCrop: "confirmationCrop";
4110
4151
  sceneFrame: "sceneFrame";
4111
4152
  }>;
4112
4153
  sizeBytes: z.ZodNumber;
@@ -4147,6 +4188,7 @@ export declare const pipelineAnalyticsCapability: {
4147
4188
  keyFrame: "keyFrame";
4148
4189
  keyFrameSmall: "keyFrameSmall";
4149
4190
  thumbnailSmall: "thumbnailSmall";
4191
+ confirmationCrop: "confirmationCrop";
4150
4192
  sceneFrame: "sceneFrame";
4151
4193
  }>;
4152
4194
  url: z.ZodString;
@@ -4194,6 +4236,7 @@ export declare const pipelineAnalyticsCapability: {
4194
4236
  keyFrame: "keyFrame";
4195
4237
  keyFrameSmall: "keyFrameSmall";
4196
4238
  thumbnailSmall: "thumbnailSmall";
4239
+ confirmationCrop: "confirmationCrop";
4197
4240
  sceneFrame: "sceneFrame";
4198
4241
  }>;
4199
4242
  url: z.ZodString;
@@ -197,16 +197,42 @@ export declare const MotionSourcesSchema: z.ZodArray<z.ZodEnum<{
197
197
  }>>;
198
198
  export type MotionSources = z.infer<typeof MotionSourcesSchema>;
199
199
  /**
200
- * Which root detectors a camera runs. Deliberately the SAME vocabulary
201
- * post-analysis already tags every detection with (`DetectionSource`) rather
202
- * than a second spelling of the same two ideas — the value an operator picks
203
- * here is the value that comes back on the track, the overlay and the debug
204
- * row.
200
+ * Which root detector a camera runs — EXACTLY ONE.
201
+ *
202
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
203
+ * with (`DetectionSource`) rather than a second spelling of the same two
204
+ * ideas: the value an operator picks here is the value that comes back on the
205
+ * track, the overlay and the debug row.
206
+ *
207
+ * ## Why one, and why it is still an array
208
+ *
209
+ * Two roots on one camera is a capability nobody asked for and the operator has
210
+ * since ruled out. It was never free: both planes feed the SAME per-device
211
+ * stationary registry, both can promote the same parked object, and the two
212
+ * detectors disagree about the same box by construction — which is the
213
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
214
+ *
215
+ * The ARRAY shape survives because the stored settings and the attach payload
216
+ * already speak it on every camera of every fleet, and a cap input that
217
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
218
+ * in the one direction that costs an operator their cameras. So the wire stays
219
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
220
+ * element rather than refused, and `max(1)` is what every consumer can then
221
+ * rely on.
222
+ *
223
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
224
+ * a camera an operator left with no root detector — and `planDetectionSources`
225
+ * has always said so: inventing a root for them is how a default acts without
226
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
227
+ * suite caught it.
228
+ *
229
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
230
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
205
231
  */
206
- export declare const DetectionSourcesSchema: z.ZodArray<z.ZodEnum<{
232
+ export declare const DetectionSourcesSchema: z.ZodPreprocess<z.ZodArray<z.ZodEnum<{
207
233
  pipeline: "pipeline";
208
234
  onboard: "onboard";
209
- }>>;
235
+ }>>>;
210
236
  export type DetectionSources = z.infer<typeof DetectionSourcesSchema>;
211
237
  /**
212
238
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
@@ -311,10 +337,10 @@ declare const RunnerCameraConfigSchema: z.ZodObject<{
311
337
  analyzer: "analyzer";
312
338
  "device-activity": "device-activity";
313
339
  }>>>;
314
- detectionSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
340
+ detectionSources: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodEnum<{
315
341
  pipeline: "pipeline";
316
342
  onboard: "onboard";
317
- }>>>;
343
+ }>>>>;
318
344
  pipelineEnabled: z.ZodDefault<z.ZodBoolean>;
319
345
  steps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown, z.core.$ZodTypeInternals<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown>>>>>;
320
346
  audio: z.ZodOptional<z.ZodNullable<z.ZodObject<{
@@ -590,10 +616,10 @@ export declare const pipelineRunnerCapability: {
590
616
  analyzer: "analyzer";
591
617
  "device-activity": "device-activity";
592
618
  }>>>;
593
- detectionSources: z.ZodDefault<z.ZodArray<z.ZodEnum<{
619
+ detectionSources: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodEnum<{
594
620
  pipeline: "pipeline";
595
621
  onboard: "onboard";
596
- }>>>;
622
+ }>>>>;
597
623
  pipelineEnabled: z.ZodDefault<z.ZodBoolean>;
598
624
  steps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown, z.core.$ZodTypeInternals<import("./pipeline-executor.cap.js").PipelineStepInputOutput, unknown>>>>>;
599
625
  audio: z.ZodOptional<z.ZodNullable<z.ZodObject<{
package/dist/index.js CHANGED
@@ -19719,13 +19719,26 @@ var TrackAudioLabelSchema = zod.z.object({
19719
19719
  * - `audio` — an audio event on the camera itself that was anomalous for
19720
19720
  * THAT camera, loud, and heard while nothing visual was happening (D62).
19721
19721
  *
19722
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19723
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19724
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19725
+ * detector.
19726
+ *
19727
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19728
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19729
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19730
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19731
+ * could not name.
19732
+ *
19722
19733
  * The spatial subsystems (tracker association, occupancy count, re-id /
19723
19734
  * embedding, resurrection) MUST skip every synthetic source. Test for that
19724
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
19725
- * check silently readmits every source added after it was written.
19735
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19736
+ * `!== 'sensor'` check silently readmits every source added after it was
19737
+ * written.
19726
19738
  */
19727
19739
  var TrackSourceSchema = zod.z.enum([
19728
19740
  "pipeline",
19741
+ "onboard",
19729
19742
  "sensor",
19730
19743
  "audio"
19731
19744
  ]);
@@ -20348,6 +20361,7 @@ var MediaFileKindEnum = zod.z.enum([
20348
20361
  "keyFrame",
20349
20362
  "keyFrameSmall",
20350
20363
  "thumbnailSmall",
20364
+ "confirmationCrop",
20351
20365
  "sceneFrame"
20352
20366
  ]);
20353
20367
  /**
@@ -22555,13 +22569,39 @@ var MotionSourceEnum = zod.z.enum([
22555
22569
  */
22556
22570
  var MotionSourcesSchema = zod.z.array(MotionSourceEnum);
22557
22571
  /**
22558
- * Which root detectors a camera runs. Deliberately the SAME vocabulary
22559
- * post-analysis already tags every detection with (`DetectionSource`) rather
22560
- * than a second spelling of the same two ideas — the value an operator picks
22561
- * here is the value that comes back on the track, the overlay and the debug
22562
- * row.
22572
+ * Which root detector a camera runs — EXACTLY ONE.
22573
+ *
22574
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
22575
+ * with (`DetectionSource`) rather than a second spelling of the same two
22576
+ * ideas: the value an operator picks here is the value that comes back on the
22577
+ * track, the overlay and the debug row.
22578
+ *
22579
+ * ## Why one, and why it is still an array
22580
+ *
22581
+ * Two roots on one camera is a capability nobody asked for and the operator has
22582
+ * since ruled out. It was never free: both planes feed the SAME per-device
22583
+ * stationary registry, both can promote the same parked object, and the two
22584
+ * detectors disagree about the same box by construction — which is the
22585
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
22586
+ *
22587
+ * The ARRAY shape survives because the stored settings and the attach payload
22588
+ * already speak it on every camera of every fleet, and a cap input that
22589
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
22590
+ * in the one direction that costs an operator their cameras. So the wire stays
22591
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
22592
+ * element rather than refused, and `max(1)` is what every consumer can then
22593
+ * rely on.
22594
+ *
22595
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
22596
+ * a camera an operator left with no root detector — and `planDetectionSources`
22597
+ * has always said so: inventing a root for them is how a default acts without
22598
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
22599
+ * suite caught it.
22600
+ *
22601
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
22602
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
22563
22603
  */
22564
- var DetectionSourcesSchema = zod.z.array(DetectionSourceSchema);
22604
+ var DetectionSourcesSchema = zod.z.preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, zod.z.array(DetectionSourceSchema).max(1));
22565
22605
  /**
22566
22606
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
22567
22607
  * so cap-side consumers (the orchestrator forward, the runner addon's
package/dist/index.mjs CHANGED
@@ -19718,13 +19718,26 @@ var TrackAudioLabelSchema = z.object({
19718
19718
  * - `audio` — an audio event on the camera itself that was anomalous for
19719
19719
  * THAT camera, loud, and heard while nothing visual was happening (D62).
19720
19720
  *
19721
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19722
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19723
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19724
+ * detector.
19725
+ *
19726
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19727
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19728
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19729
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19730
+ * could not name.
19731
+ *
19721
19732
  * The spatial subsystems (tracker association, occupancy count, re-id /
19722
19733
  * embedding, resurrection) MUST skip every synthetic source. Test for that
19723
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
19724
- * check silently readmits every source added after it was written.
19734
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19735
+ * `!== 'sensor'` check silently readmits every source added after it was
19736
+ * written.
19725
19737
  */
19726
19738
  var TrackSourceSchema = z.enum([
19727
19739
  "pipeline",
19740
+ "onboard",
19728
19741
  "sensor",
19729
19742
  "audio"
19730
19743
  ]);
@@ -20347,6 +20360,7 @@ var MediaFileKindEnum = z.enum([
20347
20360
  "keyFrame",
20348
20361
  "keyFrameSmall",
20349
20362
  "thumbnailSmall",
20363
+ "confirmationCrop",
20350
20364
  "sceneFrame"
20351
20365
  ]);
20352
20366
  /**
@@ -22554,13 +22568,39 @@ var MotionSourceEnum = z.enum([
22554
22568
  */
22555
22569
  var MotionSourcesSchema = z.array(MotionSourceEnum);
22556
22570
  /**
22557
- * Which root detectors a camera runs. Deliberately the SAME vocabulary
22558
- * post-analysis already tags every detection with (`DetectionSource`) rather
22559
- * than a second spelling of the same two ideas — the value an operator picks
22560
- * here is the value that comes back on the track, the overlay and the debug
22561
- * row.
22571
+ * Which root detector a camera runs — EXACTLY ONE.
22572
+ *
22573
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
22574
+ * with (`DetectionSource`) rather than a second spelling of the same two
22575
+ * ideas: the value an operator picks here is the value that comes back on the
22576
+ * track, the overlay and the debug row.
22577
+ *
22578
+ * ## Why one, and why it is still an array
22579
+ *
22580
+ * Two roots on one camera is a capability nobody asked for and the operator has
22581
+ * since ruled out. It was never free: both planes feed the SAME per-device
22582
+ * stationary registry, both can promote the same parked object, and the two
22583
+ * detectors disagree about the same box by construction — which is the
22584
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
22585
+ *
22586
+ * The ARRAY shape survives because the stored settings and the attach payload
22587
+ * already speak it on every camera of every fleet, and a cap input that
22588
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
22589
+ * in the one direction that costs an operator their cameras. So the wire stays
22590
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
22591
+ * element rather than refused, and `max(1)` is what every consumer can then
22592
+ * rely on.
22593
+ *
22594
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
22595
+ * a camera an operator left with no root detector — and `planDetectionSources`
22596
+ * has always said so: inventing a root for them is how a default acts without
22597
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
22598
+ * suite caught it.
22599
+ *
22600
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
22601
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
22562
22602
  */
22563
- var DetectionSourcesSchema = z.array(DetectionSourceSchema);
22603
+ var DetectionSourcesSchema = z.preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, z.array(DetectionSourceSchema).max(1));
22564
22604
  /**
22565
22605
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
22566
22606
  * so cap-side consumers (the orchestrator forward, the runner addon's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.200",
3
+ "version": "1.2.202",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",