@camstack/addon-export-alexa 1.2.110 → 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.
@@ -19410,13 +19410,26 @@ var TrackAudioLabelSchema = object({
19410
19410
  * - `audio` — an audio event on the camera itself that was anomalous for
19411
19411
  * THAT camera, loud, and heard while nothing visual was happening (D62).
19412
19412
  *
19413
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19414
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19415
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19416
+ * detector.
19417
+ *
19418
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19419
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19420
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19421
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19422
+ * could not name.
19423
+ *
19413
19424
  * The spatial subsystems (tracker association, occupancy count, re-id /
19414
19425
  * embedding, resurrection) MUST skip every synthetic source. Test for that
19415
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
19416
- * check silently readmits every source added after it was written.
19426
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19427
+ * `!== 'sensor'` check silently readmits every source added after it was
19428
+ * written.
19417
19429
  */
19418
19430
  var TrackSourceSchema = _enum([
19419
19431
  "pipeline",
19432
+ "onboard",
19420
19433
  "sensor",
19421
19434
  "audio"
19422
19435
  ]);
@@ -21498,13 +21511,39 @@ var MotionSourceEnum = _enum([
21498
21511
  */
21499
21512
  var MotionSourcesSchema = array(MotionSourceEnum);
21500
21513
  /**
21501
- * Which root detectors a camera runs. Deliberately the SAME vocabulary
21502
- * post-analysis already tags every detection with (`DetectionSource`) rather
21503
- * than a second spelling of the same two ideas — the value an operator picks
21504
- * here is the value that comes back on the track, the overlay and the debug
21505
- * row.
21514
+ * Which root detector a camera runs — EXACTLY ONE.
21515
+ *
21516
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
21517
+ * with (`DetectionSource`) rather than a second spelling of the same two
21518
+ * ideas: the value an operator picks here is the value that comes back on the
21519
+ * track, the overlay and the debug row.
21520
+ *
21521
+ * ## Why one, and why it is still an array
21522
+ *
21523
+ * Two roots on one camera is a capability nobody asked for and the operator has
21524
+ * since ruled out. It was never free: both planes feed the SAME per-device
21525
+ * stationary registry, both can promote the same parked object, and the two
21526
+ * detectors disagree about the same box by construction — which is the
21527
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
21528
+ *
21529
+ * The ARRAY shape survives because the stored settings and the attach payload
21530
+ * already speak it on every camera of every fleet, and a cap input that
21531
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
21532
+ * in the one direction that costs an operator their cameras. So the wire stays
21533
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
21534
+ * element rather than refused, and `max(1)` is what every consumer can then
21535
+ * rely on.
21536
+ *
21537
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
21538
+ * a camera an operator left with no root detector — and `planDetectionSources`
21539
+ * has always said so: inventing a root for them is how a default acts without
21540
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
21541
+ * suite caught it.
21542
+ *
21543
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
21544
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
21506
21545
  */
21507
- var DetectionSourcesSchema = array(DetectionSourceSchema);
21546
+ var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
21508
21547
  /**
21509
21548
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
21510
21549
  * so cap-side consumers (the orchestrator forward, the runner addon's
@@ -19383,13 +19383,26 @@ var TrackAudioLabelSchema = object({
19383
19383
  * - `audio` — an audio event on the camera itself that was anomalous for
19384
19384
  * THAT camera, loud, and heard while nothing visual was happening (D62).
19385
19385
  *
19386
+ * - `onboard` — the CAMERA's own firmware, paired with a decoded frame in
19387
+ * that frame's pixel space. A real root detector and a SPATIAL one: its
19388
+ * boxes are the same kind of fact `pipeline`'s are, produced by a different
19389
+ * detector.
19390
+ *
19391
+ * `onboard` was missing here while `DetectionSourceSchema` already had it, so
19392
+ * a persisted onboard track failed `safeParse` on read and came back with NO
19393
+ * source at all — which `isSpatialTrack` then admitted by accident, through the
19394
+ * `undefined` arm rather than by anybody's decision, and which `excludeSources`
19395
+ * could not name.
19396
+ *
19386
19397
  * The spatial subsystems (tracker association, occupancy count, re-id /
19387
19398
  * embedding, resurrection) MUST skip every synthetic source. Test for that
19388
- * with `isSpatialTrack`, which allow-lists `pipeline` — a `!== 'sensor'`
19389
- * check silently readmits every source added after it was written.
19399
+ * with `isSpatialTrack`, which allow-lists the spatial sources explicitly — a
19400
+ * `!== 'sensor'` check silently readmits every source added after it was
19401
+ * written.
19390
19402
  */
19391
19403
  var TrackSourceSchema = _enum([
19392
19404
  "pipeline",
19405
+ "onboard",
19393
19406
  "sensor",
19394
19407
  "audio"
19395
19408
  ]);
@@ -21471,13 +21484,39 @@ var MotionSourceEnum = _enum([
21471
21484
  */
21472
21485
  var MotionSourcesSchema = array(MotionSourceEnum);
21473
21486
  /**
21474
- * Which root detectors a camera runs. Deliberately the SAME vocabulary
21475
- * post-analysis already tags every detection with (`DetectionSource`) rather
21476
- * than a second spelling of the same two ideas — the value an operator picks
21477
- * here is the value that comes back on the track, the overlay and the debug
21478
- * row.
21487
+ * Which root detector a camera runs — EXACTLY ONE.
21488
+ *
21489
+ * Deliberately the SAME vocabulary post-analysis already tags every detection
21490
+ * with (`DetectionSource`) rather than a second spelling of the same two
21491
+ * ideas: the value an operator picks here is the value that comes back on the
21492
+ * track, the overlay and the debug row.
21493
+ *
21494
+ * ## Why one, and why it is still an array
21495
+ *
21496
+ * Two roots on one camera is a capability nobody asked for and the operator has
21497
+ * since ruled out. It was never free: both planes feed the SAME per-device
21498
+ * stationary registry, both can promote the same parked object, and the two
21499
+ * detectors disagree about the same box by construction — which is the
21500
+ * disagreement D505 had to arbitrate. Removing the case removes the arbitration.
21501
+ *
21502
+ * The ARRAY shape survives because the stored settings and the attach payload
21503
+ * already speak it on every camera of every fleet, and a cap input that
21504
+ * suddenly refuses a stored value makes the camera un-attachable — a fail-closed
21505
+ * in the one direction that costs an operator their cameras. So the wire stays
21506
+ * tolerant and the TYPE is exact: a longer list is truncated to its first
21507
+ * element rather than refused, and `max(1)` is what every consumer can then
21508
+ * rely on.
21509
+ *
21510
+ * AT MOST one, not exactly one. The EMPTY list is a legal, deliberate pick —
21511
+ * a camera an operator left with no root detector — and `planDetectionSources`
21512
+ * has always said so: inventing a root for them is how a default acts without
21513
+ * anybody choosing it. Tightening this to `length(1)` broke that, and the
21514
+ * suite caught it.
21515
+ *
21516
+ * Measured before tightening (2026-09-15, this fleet, 6 h of attaches): 3327
21517
+ * `["pipeline"]` and 2 `["onboard"]`. Not one camera had two.
21479
21518
  */
21480
- var DetectionSourcesSchema = array(DetectionSourceSchema);
21519
+ var DetectionSourcesSchema = preprocess((value) => Array.isArray(value) && value.length > 1 ? value.slice(0, 1) : value, array(DetectionSourceSchema).max(1));
21481
21520
  /**
21482
21521
  * Input shape for `pipeline-runner.reportMotion` cap method. Exported
21483
21522
  * 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/addon-export-alexa",
3
- "version": "1.2.110",
3
+ "version": "1.2.111",
4
4
  "description": "Alexa Smart Home Skill export — hub-side OAuth provider + directive handler. The companion AWS Lambda forwards Alexa directives to this addon's /addon/export-alexa/directive endpoint.",
5
5
  "keywords": [
6
6
  "camstack",