@camstack/types 1.2.200 → 1.2.201

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;
@@ -1208,6 +1222,7 @@ declare const RecentTracksQueryInput: z.ZodObject<{
1208
1222
  sensor: "sensor";
1209
1223
  pipeline: "pipeline";
1210
1224
  audio: "audio";
1225
+ onboard: "onboard";
1211
1226
  }>>>;
1212
1227
  }, z.core.$strip>;
1213
1228
  export type RecentTracksQuery = z.infer<typeof RecentTracksQueryInput>;
@@ -1337,6 +1352,7 @@ declare const RecentTracksPageSchema: z.ZodObject<{
1337
1352
  sensor: "sensor";
1338
1353
  pipeline: "pipeline";
1339
1354
  audio: "audio";
1355
+ onboard: "onboard";
1340
1356
  }>>;
1341
1357
  firstSeen: z.ZodNumber;
1342
1358
  lastSeen: z.ZodNumber;
@@ -1876,6 +1892,7 @@ export declare const pipelineAnalyticsCapability: {
1876
1892
  sensor: "sensor";
1877
1893
  pipeline: "pipeline";
1878
1894
  audio: "audio";
1895
+ onboard: "onboard";
1879
1896
  }>>;
1880
1897
  firstSeen: z.ZodNumber;
1881
1898
  lastSeen: z.ZodNumber;
@@ -1985,6 +2002,7 @@ export declare const pipelineAnalyticsCapability: {
1985
2002
  sensor: "sensor";
1986
2003
  pipeline: "pipeline";
1987
2004
  audio: "audio";
2005
+ onboard: "onboard";
1988
2006
  }>>;
1989
2007
  firstSeen: z.ZodNumber;
1990
2008
  lastSeen: z.ZodNumber;
@@ -2107,6 +2125,7 @@ export declare const pipelineAnalyticsCapability: {
2107
2125
  sensor: "sensor";
2108
2126
  pipeline: "pipeline";
2109
2127
  audio: "audio";
2128
+ onboard: "onboard";
2110
2129
  }>>>;
2111
2130
  }, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
2112
2131
  retrainStatus: z.ZodOptional<z.ZodEnum<{
@@ -2123,6 +2142,7 @@ export declare const pipelineAnalyticsCapability: {
2123
2142
  sensor: "sensor";
2124
2143
  pipeline: "pipeline";
2125
2144
  audio: "audio";
2145
+ onboard: "onboard";
2126
2146
  }>>;
2127
2147
  firstSeen: z.ZodNumber;
2128
2148
  lastSeen: z.ZodNumber;
@@ -2240,6 +2260,7 @@ export declare const pipelineAnalyticsCapability: {
2240
2260
  sensor: "sensor";
2241
2261
  pipeline: "pipeline";
2242
2262
  audio: "audio";
2263
+ onboard: "onboard";
2243
2264
  }>>>;
2244
2265
  }, z.core.$strip>, z.ZodObject<{
2245
2266
  tracks: z.ZodReadonly<z.ZodArray<z.ZodObject<{
@@ -2257,6 +2278,7 @@ export declare const pipelineAnalyticsCapability: {
2257
2278
  sensor: "sensor";
2258
2279
  pipeline: "pipeline";
2259
2280
  audio: "audio";
2281
+ onboard: "onboard";
2260
2282
  }>>;
2261
2283
  firstSeen: z.ZodNumber;
2262
2284
  lastSeen: z.ZodNumber;
@@ -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
  ]);
@@ -22555,13 +22568,39 @@ var MotionSourceEnum = zod.z.enum([
22555
22568
  */
22556
22569
  var MotionSourcesSchema = zod.z.array(MotionSourceEnum);
22557
22570
  /**
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.
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.
22563
22602
  */
22564
- var DetectionSourcesSchema = zod.z.array(DetectionSourceSchema);
22603
+ var DetectionSourcesSchema = zod.z.preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, zod.z.array(DetectionSourceSchema).max(1));
22565
22604
  /**
22566
22605
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
22567
22606
  * 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
  ]);
@@ -22554,13 +22567,39 @@ var MotionSourceEnum = z.enum([
22554
22567
  */
22555
22568
  var MotionSourcesSchema = z.array(MotionSourceEnum);
22556
22569
  /**
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.
22570
+ * Which root detector a camera runs — EXACTLY ONE.
22571
+ *
22572
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
22573
+ * with (`DetectionSource`) rather than a second spelling of the same two
22574
+ * ideas: the value an operator picks here is the value that comes back on the
22575
+ * track, the overlay and the debug row.
22576
+ *
22577
+ * ## Why one, and why it is still an array
22578
+ *
22579
+ * Two roots on one camera is a capability nobody asked for and the operator has
22580
+ * since ruled out. It was never free: both planes feed the SAME per-device
22581
+ * stationary registry, both can promote the same parked object, and the two
22582
+ * detectors disagree about the same box by construction — which is the
22583
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
22584
+ *
22585
+ * The ARRAY shape survives because the stored settings and the attach payload
22586
+ * already speak it on every camera of every fleet, and a cap input that
22587
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
22588
+ * in the one direction that costs an operator their cameras. So the wire stays
22589
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
22590
+ * element rather than refused, and `max(1)` is what every consumer can then
22591
+ * rely on.
22592
+ *
22593
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
22594
+ * a camera an operator left with no root detector — and `planDetectionSources`
22595
+ * has always said so: inventing a root for them is how a default acts without
22596
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
22597
+ * suite caught it.
22598
+ *
22599
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
22600
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
22562
22601
  */
22563
- var DetectionSourcesSchema = z.array(DetectionSourceSchema);
22602
+ var DetectionSourcesSchema = z.preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, z.array(DetectionSourceSchema).max(1));
22564
22603
  /**
22565
22604
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
22566
22605
  * 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.201",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",