@camstack/addon-post-analysis 1.2.311 → 1.2.313

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.
@@ -7677,7 +7677,7 @@ function errMsg(err) {
7677
7677
  return String(err);
7678
7678
  }
7679
7679
  //#endregion
7680
- //#region ../types/dist/composition-43aqsZQj.mjs
7680
+ //#region ../types/dist/composition-D7ULvLdD.mjs
7681
7681
  /**
7682
7682
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
7683
7683
  * canonical form sorts object keys alphabetically at every depth so two
@@ -7762,20 +7762,20 @@ function portable(target) {
7762
7762
  }
7763
7763
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7764
7764
  /**
7765
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7766
- * valutatore puro del suo FRONTE.
7765
+ * THE table "which boolean of this device type counts as HIGH", and the
7766
+ * pure evaluator of its EDGE.
7767
7767
  *
7768
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7769
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7770
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7771
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7772
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7773
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7768
+ * ONE table for everyone who asks "is this device HIGH?": the
7769
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7770
+ * sensor markers, the orchestrator's camera-sensors bridge and
7771
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7772
+ * A second copy would diverge at the first cap added, and the symptom — "the
7773
+ * sensor rings the doorbell but does not record" — is exactly D62.
7774
7774
  *
7775
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7776
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7777
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7778
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7775
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7776
+ * two must not be unified: that one answers "what is the state WORD for a
7777
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7778
+ * boolean's EDGE counts". Deliberately different vocabularies.
7779
7779
  */
7780
7780
  /**
7781
7781
  * Known binary / switch source caps → the boolean slice field whose
@@ -7867,17 +7867,17 @@ function evaluateSensorLevelEdge(input) {
7867
7867
  };
7868
7868
  }
7869
7869
  /**
7870
- * IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
7871
- * porta `prior`, `nowMs` e il proprio `startedAtMs`.
7870
+ * THE edge. Pure: no clock of its own, no memory — the caller
7871
+ * brings `prior`, `nowMs` and its own `startedAtMs`.
7872
7872
  *
7873
- * Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
7874
- * fronte solo se il timestamp UPSTREAM della transizione è posteriore a
7875
- * `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
7876
- * servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
7877
- * stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
7878
- * iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
7879
- * adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
7880
- * SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
7873
+ * The case of the FIRST slice already active is treated explicitly and counts as an
7874
+ * edge only if the UPSTREAM timestamp of the transition is later than
7875
+ * `startedAtMs` **and** within `firstSightingFreshnessMs`. Both halves
7876
+ * are needed: freshness alone would fire on a boot-time hydration of a
7877
+ * state flipped a few seconds before the restart, and "after we started"
7878
+ * alone would fire, on a long-lived process, for a source
7879
+ * adopted today whose state changed yesterday. The ambiguous case ERRS TOWARD
7880
+ * SILENCE and declares it (`baseline-seeded-stale-active`).
7881
7881
  */
7882
7882
  function evaluateSensorEdge(input) {
7883
7883
  const value = sliceActiveValue(input.capName, input.slice);
@@ -9777,22 +9777,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9777
9777
  "package"
9778
9778
  ];
9779
9779
  /**
9780
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9781
- * un operatore può selezionare.
9780
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9781
+ * an operator can select.
9782
9782
  *
9783
- * Sono le tre offerte dallo step `object-detection`
9783
+ * They are the three offered by the `object-detection` step
9784
9784
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9785
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9786
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9787
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9788
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9785
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9786
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9787
+ * `package-detection`, whose enablement is driven by zones, and offering the
9788
+ * same word twice has already made an operator turn on the COCO proxy
9789
9789
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9790
9790
  *
9791
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9792
- * dello step e una seconda volta come union `FirstLevelMacro`
9793
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9794
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9795
- * successiva.
9791
+ * ONE list. Before today the same three were hand-written in the step's offer
9792
+ * and a second time as the union `FirstLevelMacro`
9793
+ * (`types/detection.ts`); a third copy for the recording trigger
9794
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9795
+ * invisible.
9796
9796
  */
9797
9797
  var FIRST_LEVEL_MACRO_CLASSES = [
9798
9798
  "person",
@@ -9857,17 +9857,17 @@ var RecordingStorageModeSchema = _enum([
9857
9857
  "on-device-decision"
9858
9858
  ]);
9859
9859
  /**
9860
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9861
- * tre offerte dallo step `object-detection`, da UNA lista
9860
+ * The macro classes that can open a recording window — the same
9861
+ * three offered by the `object-detection` step, from ONE list
9862
9862
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9863
9863
  */
9864
9864
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9865
9865
  /**
9866
- * True quando `values` non ripete un elemento.
9866
+ * True when `values` does not repeat an element.
9867
9867
  *
9868
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9869
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9870
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9868
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9869
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9870
+ * would count its windows twice in `segmentMissedByMs`.
9871
9871
  */
9872
9872
  var noDuplicates = (values) => new Set(values).size === values.length;
9873
9873
  /** Which detectors trigger an `events`-mode band. */
@@ -9875,34 +9875,34 @@ var RecordingTriggersSchema = object({
9875
9875
  motion: boolean().optional(),
9876
9876
  audioThresholdDbfs: number().optional(),
9877
9877
  /**
9878
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9879
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9880
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9881
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9878
+ * The macro classes whose detection opens a window. ABSENT = the source
9879
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9880
+ * trigger on, no class" is the same shape "enabled and records
9881
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9882
9882
  *
9883
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9884
- * quelle che hanno attraversato `enabledMacroClasses`, i
9885
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9886
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9887
- * finestre — vedi `recorder/object-trigger.ts`.
9883
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9884
+ * those that went through `enabledMacroClasses`, the
9885
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9886
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9887
+ * windows — see `recorder/object-trigger.ts`.
9888
9888
  */
9889
9889
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9890
9890
  /**
9891
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9892
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9891
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9892
+ * is not listened to; an empty array is rejected for the same reason as
9893
9893
  * `objectClasses`.
9894
9894
  *
9895
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9896
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9897
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9898
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9899
- * device (D12) — mai un elenco globale di cap.
9895
+ * These are SOURCE device ids, not cameras: the band names them, so the
9896
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9897
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9898
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9899
+ * device (D12) — never a global list of caps.
9900
9900
  *
9901
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9902
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9903
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9904
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9905
- * registrare.
9901
+ * What "high" means depends on the device TYPE and is not decided here:
9902
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9903
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9904
+ * the level: a contact found already open at runner restart does not
9905
+ * record.
9906
9906
  */
9907
9907
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9908
9908
  });
@@ -11076,7 +11076,7 @@ var DecoderSessionConfigSchema = object({
11076
11076
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
11077
11077
  * thing: the logging settings document on the `system` cap. Two authorities
11078
11078
  * over the values is the exact defect
11079
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
11079
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
11080
11080
  * remove; re-introducing it from the cure side would be grotesque.
11081
11081
  *
11082
11082
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -14799,7 +14799,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
14799
14799
  *
14800
14800
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
14801
14801
  * was wrong — corrected 2026-08-26 after the hop map
14802
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
14802
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
14803
14803
  * There is **no Zod parse at all** between the door and the engine: the
14804
14804
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
14805
14805
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -15662,7 +15662,17 @@ var SiteZoneSchema = object({
15662
15662
  var ProviderStatusSchema = object({
15663
15663
  connected: boolean(),
15664
15664
  deviceCount: number(),
15665
- error: string().optional()
15665
+ error: string().optional(),
15666
+ /**
15667
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
15668
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
15669
+ * which every provider bundles, so only a provider BUILT from D696-amended
15670
+ * code says it. ABSENT means an older provider that may still write it (raw
15671
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
15672
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
15673
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
15674
+ */
15675
+ motionSliceWriter: literal("orchestrator").optional()
15666
15676
  });
15667
15677
  object({
15668
15678
  externalId: string(),
@@ -16869,7 +16879,7 @@ var embeddingEncoderCapability = {
16869
16879
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
16870
16880
  * ends in a log line, and a log line is the thing the operator asked to stop
16871
16881
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
16872
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16882
+ * ricontrolliamo tutti questi punti"* [can we instrument these errors in the meantime? That way next round we recheck all these points]. Reading them meant grepping Loki and
16873
16883
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16874
16884
  * media blackout were both diagnosed. The counters stay; this is where they can
16875
16885
  * be READ.
@@ -23498,14 +23508,14 @@ var TrackSchema = object({
23498
23508
  * `derive-returned-null tile=standin`,
23499
23509
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
23500
23510
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
23501
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
23511
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
23502
23512
  * tile is a face/plate stand-in, a raster crop, or an icon.
23503
23513
  *
23504
23514
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
23505
23515
  * the TILE ranked below native, so a track whose thumbnail landed natively
23506
23516
  * while its key frame missed carried no reason at all — three of the four
23507
23517
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
23508
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
23518
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
23509
23519
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
23510
23520
  * lastFrame copy source`), so its absence is now on this line whatever the
23511
23521
  * tile ended up being.
@@ -23592,7 +23602,7 @@ var MotionEventSchema = object({
23592
23602
  /**
23593
23603
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
23594
23604
  * first entry is always `0`) of every genuine off→on transition the
23595
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
23605
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
23596
23606
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
23597
23607
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
23598
23608
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -29649,7 +29659,7 @@ var ClipPlaybackSchema = object({
29649
29659
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
29650
29660
  * time the camera is awake for its own reasons — is deliberately not a member:
29651
29661
  * it was proposed, it is free on the battery, and the operator declined it on
29652
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
29662
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
29653
29663
  * D558 "Considered and not taken").
29654
29664
  */
29655
29665
  var ClipWakeSchema = _enum(["authorised"]);
@@ -29910,7 +29920,7 @@ DeviceType.Camera, method(object({
29910
29920
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
29911
29921
  * assumed the answer was a fan-out over everything a camera has. The
29912
29922
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
29913
- * solo"* — so the list is asked of one provider at a time and there is
29923
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
29914
29924
  * nothing to filter out of it.
29915
29925
  */
29916
29926
  provider: string().min(1)
@@ -34804,7 +34814,7 @@ authKey: string().optional() }), object({
34804
34814
  */
34805
34815
  /**
34806
34816
  * How long after a camera's last rising edge `pipeline-analytics` closes the
34807
- * motion EPISODE row it kept open for it (D475) — "il delay della cap", in
34817
+ * motion EPISODE row it kept open for it (D475) — "il delay della cap" [the cap's delay], in
34808
34818
  * the operator's words. One authority for the whole system: the writer of a
34809
34819
  * `Camera` device's slice (the orchestrator, D696) writes this SAME constant
34810
34820
  * in `autoClearAfterMs` while `detected: true` (never a camera's own clock —
@@ -38044,7 +38054,7 @@ var ReadGopBytesResultSchema = object({
38044
38054
  /**
38045
38055
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
38046
38056
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
38047
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
38057
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
38048
38058
  * a replay needs several seconds of native pixels, not one frame.
38049
38059
  *
38050
38060
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -55153,7 +55163,7 @@ var PreviewTextField = string().max(200);
55153
55163
  * Whether the notification's preview is a STILL or a short animation.
55154
55164
  *
55155
55165
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
55156
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
55166
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
55157
55167
  * night reads better as three seconds of motion than as one frame of it. Both
55158
55168
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
55159
55169
  * simply applies it to a dozen frames sampled across the render and assembles
@@ -7646,7 +7646,7 @@ function errMsg(err) {
7646
7646
  return String(err);
7647
7647
  }
7648
7648
  //#endregion
7649
- //#region ../types/dist/composition-43aqsZQj.mjs
7649
+ //#region ../types/dist/composition-D7ULvLdD.mjs
7650
7650
  /**
7651
7651
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
7652
7652
  * canonical form sorts object keys alphabetically at every depth so two
@@ -7731,20 +7731,20 @@ function portable(target) {
7731
7731
  }
7732
7732
  portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
7733
7733
  /**
7734
- * LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
7735
- * valutatore puro del suo FRONTE.
7734
+ * THE table "which boolean of this device type counts as HIGH", and the
7735
+ * pure evaluator of its EDGE.
7736
7736
  *
7737
- * UNA tabella per tutti quelli che chiedono "questo device è ALTO?": il
7738
- * trigger `RecordingTriggers.sensorDeviceIds` del recorder, i marker dei
7739
- * sensori della post-analysis, il bridge camera-sensors dell'orchestratore e
7740
- * le sorgenti di un campanello composto (`doorbellFeatureSources`, D671).
7741
- * Una seconda copia divergerebbe alla prima cap aggiunta, e il sintomo — "il
7742
- * sensore fa suonare il campanello ma non registra" — è esattamente D62.
7737
+ * ONE table for everyone who asks "is this device HIGH?": the
7738
+ * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
7739
+ * sensor markers, the orchestrator's camera-sensors bridge and
7740
+ * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
7741
+ * A second copy would diverge at the first cap added, and the symptom — "the
7742
+ * sensor rings the doorbell but does not record" — is exactly D62.
7743
7743
  *
7744
- * ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
7745
- * due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
7746
- * regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
7747
- * booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
7744
+ * ⚠ NOT `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), and the
7745
+ * two must not be unified: that one answers "what is the state WORD for a
7746
+ * rule" (and includes `presence`, `cover`, `alarm-panel`), this one "which
7747
+ * boolean's EDGE counts". Deliberately different vocabularies.
7748
7748
  */
7749
7749
  /**
7750
7750
  * Known binary / switch source caps → the boolean slice field whose
@@ -7836,17 +7836,17 @@ function evaluateSensorLevelEdge(input) {
7836
7836
  };
7837
7837
  }
7838
7838
  /**
7839
- * IL fronte. Puro: nessun orologio proprio, nessuna memoria — il chiamante
7840
- * porta `prior`, `nowMs` e il proprio `startedAtMs`.
7839
+ * THE edge. Pure: no clock of its own, no memory — the caller
7840
+ * brings `prior`, `nowMs` and its own `startedAtMs`.
7841
7841
  *
7842
- * Il caso della PRIMA slice già attiva è trattato esplicitamente e vale come
7843
- * fronte solo se il timestamp UPSTREAM della transizione è posteriore a
7844
- * `startedAtMs` **e** entro `firstSightingFreshnessMs`. Entrambe le metà
7845
- * servono: la sola freschezza scatterebbe su un'idratazione al boot di uno
7846
- * stato flippato pochi secondi prima del riavvio, e il solo "dopo che abbiamo
7847
- * iniziato" scatterebbe, su un processo di lunga vita, per una sorgente
7848
- * adottata oggi il cui stato è cambiato ieri. Il caso ambiguo ERRA VERSO IL
7849
- * SILENZIO e lo dichiara (`baseline-seeded-stale-active`).
7842
+ * The case of the FIRST slice already active is treated explicitly and counts as an
7843
+ * edge only if the UPSTREAM timestamp of the transition is later than
7844
+ * `startedAtMs` **and** within `firstSightingFreshnessMs`. Both halves
7845
+ * are needed: freshness alone would fire on a boot-time hydration of a
7846
+ * state flipped a few seconds before the restart, and "after we started"
7847
+ * alone would fire, on a long-lived process, for a source
7848
+ * adopted today whose state changed yesterday. The ambiguous case ERRS TOWARD
7849
+ * SILENCE and declares it (`baseline-seeded-stale-active`).
7850
7850
  */
7851
7851
  function evaluateSensorEdge(input) {
7852
7852
  const value = sliceActiveValue(input.capName, input.slice);
@@ -9746,22 +9746,22 @@ var CLASS_MAP_MACRO_TARGETS = [
9746
9746
  "package"
9747
9747
  ];
9748
9748
  /**
9749
- * Le macro classi di PRIMO LIVELLO: quelle che un object detector emette e che
9750
- * un operatore può selezionare.
9749
+ * The FIRST-LEVEL macro classes: those an object detector emits and that
9750
+ * an operator can select.
9751
9751
  *
9752
- * Sono le tre offerte dallo step `object-detection`
9752
+ * They are the three offered by the `object-detection` step
9753
9753
  * (`addon-pipeline/src/detection-pipeline/registry/step-definitions.ts`,
9754
- * `enabledMacroClasses`). `package` sta in {@link CLASS_MAP_MACRO_TARGETS} e in
9755
- * `MACRO_LABELS` — è una macro vera — ma NON qui: appartiene allo step
9756
- * `package-detection`, la cui abilitazione è guidata dalle zone, e offrire la
9757
- * stessa parola due volte ha già fatto accendere a un operatore il proxy COCO
9754
+ * `enabledMacroClasses`). `package` is in {@link CLASS_MAP_MACRO_TARGETS} and in
9755
+ * `MACRO_LABELS` — it is a true macro — but NOT here: it belongs to the step
9756
+ * `package-detection`, whose enablement is driven by zones, and offering the
9757
+ * same word twice has already made an operator turn on the COCO proxy
9758
9758
  * (suitcase/backpack/handbag) lasciando spento il detector dedicato.
9759
9759
  *
9760
- * UNA lista. Prima di oggi le stesse tre erano scritte a mano nell'offerta
9761
- * dello step e una seconda volta come union `FirstLevelMacro`
9762
- * (`types/detection.ts`); una terza copia per il trigger di registrazione
9763
- * (`RecordingTriggers.objectClasses`) avrebbe reso invisibile la divergenza
9764
- * successiva.
9760
+ * ONE list. Before today the same three were hand-written in the step's offer
9761
+ * and a second time as the union `FirstLevelMacro`
9762
+ * (`types/detection.ts`); a third copy for the recording trigger
9763
+ * (`RecordingTriggers.objectClasses`) would have made the later divergence
9764
+ * invisible.
9765
9765
  */
9766
9766
  var FIRST_LEVEL_MACRO_CLASSES = [
9767
9767
  "person",
@@ -9826,17 +9826,17 @@ var RecordingStorageModeSchema = _enum([
9826
9826
  "on-device-decision"
9827
9827
  ]);
9828
9828
  /**
9829
- * Le macro classi che possono aprire una finestra di registrazione — le stesse
9830
- * tre offerte dallo step `object-detection`, da UNA lista
9829
+ * The macro classes that can open a recording window — the same
9830
+ * three offered by the `object-detection` step, from ONE list
9831
9831
  * ({@link FIRST_LEVEL_MACRO_CLASSES}).
9832
9832
  */
9833
9833
  var RecordingObjectTriggerClassSchema = _enum(FIRST_LEVEL_MACRO_CLASSES);
9834
9834
  /**
9835
- * True quando `values` non ripete un elemento.
9835
+ * True when `values` does not repeat an element.
9836
9836
  *
9837
- * Un duplicato non è innocuo: ogni voce di `objectClasses` / `sensorDeviceIds`
9838
- * diventa una SORGENTE in `bandTriggerSources`, e la stessa sorgente due volte
9839
- * conterebbe due volte le sue finestre in `segmentMissedByMs`.
9837
+ * A duplicate is not harmless: every entry of `objectClasses` / `sensorDeviceIds`
9838
+ * becomes a SOURCE in `bandTriggerSources`, and the same source twice
9839
+ * would count its windows twice in `segmentMissedByMs`.
9840
9840
  */
9841
9841
  var noDuplicates = (values) => new Set(values).size === values.length;
9842
9842
  /** Which detectors trigger an `events`-mode band. */
@@ -9844,34 +9844,34 @@ var RecordingTriggersSchema = object({
9844
9844
  motion: boolean().optional(),
9845
9845
  audioThresholdDbfs: number().optional(),
9846
9846
  /**
9847
- * Le macro classi la cui detection apre una finestra. ASSENTE = la sorgente
9848
- * non è ascoltata; un array VUOTO è rifiutato, perché "banda events, trigger
9849
- * object acceso, nessuna classe" è la stessa forma "abilitata e non registra
9850
- * nulla, per sempre" contro cui è scritto `eventsBandCanEverDemand`.
9847
+ * The macro classes whose detection opens a window. ABSENT = the source
9848
+ * is not listened to; an EMPTY array is rejected, because "events band, object
9849
+ * trigger on, no class" is the same shape "enabled and records
9850
+ * nothing, forever" that `eventsBandCanEverDemand` is written against.
9851
9851
  *
9852
- * Il segnale letto è GIÀ FILTRATO: solo detection `source: 'pipeline'`, cioè
9853
- * quelle che hanno attraversato `enabledMacroClasses`, i
9854
- * `minConfidence<Macro>` e il full-frame guard. L'AI a bordo camera
9855
- * (`source: 'onboard'`) non attraversa nessuno di quei gate e NON apre
9856
- * finestre — vedi `recorder/object-trigger.ts`.
9852
+ * The signal read is ALREADY FILTERED: only `source: 'pipeline'` detections, i.e.
9853
+ * those that went through `enabledMacroClasses`, the
9854
+ * `minConfidence<Macro>` and the full-frame guard. The camera's onboard AI
9855
+ * (`source: 'onboard'`) goes through none of those gates and does NOT open
9856
+ * windows — see `recorder/object-trigger.ts`.
9857
9857
  */
9858
9858
  objectClasses: array(RecordingObjectTriggerClassSchema).min(1).refine(noDuplicates, { message: "objectClasses must not repeat a class" }).optional(),
9859
9859
  /**
9860
- * I device LINKED il cui FRONTE ALTO apre una finestra. Assente = la sorgente
9861
- * non è ascoltata; un array vuoto è rifiutato per la stessa ragione di
9860
+ * The LINKED devices whose RISING EDGE opens a window. Absent = the source
9861
+ * is not listened to; an empty array is rejected for the same reason as
9862
9862
  * `objectClasses`.
9863
9863
  *
9864
- * Sono id di device SORGENTE, non camere: la banda li nomina, quindi il
9865
- * percorso caldo (`DeviceStateChanged`, a ritmo di bus su tutta la flotta)
9866
- * non fa RPC. L'OFFERTA da cui l'operatore li sceglie è un'altra domanda, e
9867
- * si risolve con `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9868
- * device (D12) — mai un elenco globale di cap.
9864
+ * These are SOURCE device ids, not cameras: the band names them, so the
9865
+ * hot path (`DeviceStateChanged`, at bus rate across the whole fleet)
9866
+ * does no RPC. The OFFER from which the operator picks them is another question, and
9867
+ * is resolved with `deviceManager.getLinkedDevices` + `getBindingsBatch` per
9868
+ * device (D12) — never a global list of caps.
9869
9869
  *
9870
- * Cosa vuol dire "alto" dipende dal TIPO di device e non è deciso qui:
9871
- * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) è LA tabella,
9872
- * la stessa del campanello composto (D671). Ed è il FRONTE, non
9873
- * il livello: un contatto trovato già aperto al riavvio del runner non fa
9874
- * registrare.
9870
+ * What "high" means depends on the device TYPE and is not decided here:
9871
+ * `SOURCE_CAP_ACTIVE_FIELD` (`catalogs/sensor-active-state.ts`) is THE table,
9872
+ * the same one as the composite doorbell (D671). And it is the EDGE, not
9873
+ * the level: a contact found already open at runner restart does not
9874
+ * record.
9875
9875
  */
9876
9876
  sensorDeviceIds: array(number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
9877
9877
  });
@@ -11045,7 +11045,7 @@ var DecoderSessionConfigSchema = object({
11045
11045
  * - **VALUE** — at which level, for which scope, until when. That stays ONE
11046
11046
  * thing: the logging settings document on the `system` cap. Two authorities
11047
11047
  * over the values is the exact defect
11048
- * `docs/design/plans/2026-08-26-logging-per-componente.md` was written to
11048
+ * `docs/design/plans/2026-08-26-per-component-logging.md` was written to
11049
11049
  * remove; re-introducing it from the cure side would be grotesque.
11050
11050
  *
11051
11051
  * Nothing in this file reads a clock, an env var or a store. The registry is
@@ -14768,7 +14768,7 @@ method(_void(), EngineInfoSchema, { auth: "admin" }), method(object({
14768
14768
  *
14769
14769
  * ⚠ An earlier version of this comment blamed Zod stripping, and that
14770
14770
  * was wrong — corrected 2026-08-26 after the hop map
14771
- * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
14771
+ * (`docs/design/2026-08-26-topic-hop-map.md`) traced the path.
14772
14772
  * There is **no Zod parse at all** between the door and the engine: the
14773
14773
  * dispatcher forwards the payload verbatim and UDS carries it whole. A
14774
14774
  * field declared here reaches `SqliteSettingsBackend` either way.
@@ -15631,7 +15631,17 @@ var SiteZoneSchema = object({
15631
15631
  var ProviderStatusSchema = object({
15632
15632
  connected: boolean(),
15633
15633
  deviceCount: number(),
15634
- error: string().optional()
15634
+ error: string().optional(),
15635
+ /**
15636
+ * `'orchestrator'`: this provider writes NO camera's `motion` runtime slice
15637
+ * — the orchestrator is its only writer (D696). Set by `BaseDeviceProvider`,
15638
+ * which every provider bundles, so only a provider BUILT from D696-amended
15639
+ * code says it. ABSENT means an older provider that may still write it (raw
15640
+ * VMD writes, a boot seed), and the orchestrator's provider gate keeps that
15641
+ * provider's cameras unwritten (`camera-sensors/motion-slice-provider-gate.ts`)
15642
+ * — the provider twin of the runner's `getLocalLoad().motionSliceWriter`.
15643
+ */
15644
+ motionSliceWriter: literal("orchestrator").optional()
15635
15645
  });
15636
15646
  object({
15637
15647
  externalId: string(),
@@ -16838,7 +16848,7 @@ var embeddingEncoderCapability = {
16838
16848
  * per-device window, `KeyFrameCaptureLog`, `bumpCropMetric`. Every one of them
16839
16849
  * ends in a log line, and a log line is the thing the operator asked to stop
16840
16850
  * needing: *"possiamo armare questi errori intanto? Così al prossimo giro
16841
- * ricontrolliamo tutti questi punti"*. Reading them meant grepping Loki and
16851
+ * ricontrolliamo tutti questi punti"* [can we instrument these errors in the meantime? That way next round we recheck all these points]. Reading them meant grepping Loki and
16842
16852
  * hand-correlating timestamps, which is how a 22% thumbnail gap and a 3-hour
16843
16853
  * media blackout were both diagnosed. The counters stay; this is where they can
16844
16854
  * be READ.
@@ -23467,14 +23477,14 @@ var TrackSchema = object({
23467
23477
  * `derive-returned-null tile=standin`,
23468
23478
  * `native-tile tile=native no-key-frame-at-close`, …) written at close and
23469
23479
  * CLEARED by the late-keyFrame upgrade when a native tile lands after all.
23470
- * The operator-facing answer to "perché manca l'immagine?" on a track whose
23480
+ * The operator-facing answer to "perché manca l'immagine?" [why is the image missing?] on a track whose
23471
23481
  * tile is a face/plate stand-in, a raster crop, or an icon.
23472
23482
  *
23473
23483
  * **`no-key-frame-at-close` (D400).** The line used to be written ONLY when
23474
23484
  * the TILE ranked below native, so a track whose thumbnail landed natively
23475
23485
  * while its key frame missed carried no reason at all — three of the four
23476
23486
  * `MISSING_KEYFRAME` tracks in the 2026-09-07 operator audit were exactly
23477
- * that shape, and their "niente ultimo" had no cause anywhere on the row.
23487
+ * that shape, and their "niente ultimo" [no last frame] had no cause anywhere on the row.
23478
23488
  * The key frame is the head of a cascade (`keyFrame ⇒ keyFrameSmall ⇒ the
23479
23489
  * lastFrame copy source`), so its absence is now on this line whatever the
23480
23490
  * tile ended up being.
@@ -23561,7 +23571,7 @@ var MotionEventSchema = object({
23561
23571
  /**
23562
23572
  * Ms offsets from `timestamp` (the episode's own first rising edge, so the
23563
23573
  * first entry is always `0`) of every genuine off→on transition the
23564
- * episode saw — "ogni evento on si deve salvare" (D475). NOT one entry per
23574
+ * episode saw — "ogni evento on si deve salvare" [every ON event must be saved] (D475). NOT one entry per
23565
23575
  * push: a firmware source that keepalives at ~1 Hz for the whole burst
23566
23576
  * (Reolink, Hikvision) produces exactly one edge; a source that reports an
23567
23577
  * explicit `false` mid-episode and then resumes before the quiet window
@@ -29618,7 +29628,7 @@ var ClipPlaybackSchema = object({
29618
29628
  * **One authorised yes is one wake.** `next-natural` — take the clip the next
29619
29629
  * time the camera is awake for its own reasons — is deliberately not a member:
29620
29630
  * it was proposed, it is free on the battery, and the operator declined it on
29621
- * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."*,
29631
+ * 2026-09-20 (*"Quando un export viene richiesto si sveglia la camera."* [When an export is requested the camera wakes up],
29622
29632
  * D558 "Considered and not taken").
29623
29633
  */
29624
29634
  var ClipWakeSchema = _enum(["authorised"]);
@@ -29879,7 +29889,7 @@ DeviceType.Camera, method(object({
29879
29889
  * It replaced `sources?: string[]`, a VIEW filter over source ids that
29880
29890
  * assumed the answer was a fan-out over everything a camera has. The
29881
29891
  * operator settled otherwise on 2026-09-20 — *"l'utilizzatore è uno
29882
- * solo"* — so the list is asked of one provider at a time and there is
29892
+ * solo"* [there is only one user] — so the list is asked of one provider at a time and there is
29883
29893
  * nothing to filter out of it.
29884
29894
  */
29885
29895
  provider: string().min(1)
@@ -34773,7 +34783,7 @@ authKey: string().optional() }), object({
34773
34783
  */
34774
34784
  /**
34775
34785
  * How long after a camera's last rising edge `pipeline-analytics` closes the
34776
- * motion EPISODE row it kept open for it (D475) — "il delay della cap", in
34786
+ * motion EPISODE row it kept open for it (D475) — "il delay della cap" [the cap's delay], in
34777
34787
  * the operator's words. One authority for the whole system: the writer of a
34778
34788
  * `Camera` device's slice (the orchestrator, D696) writes this SAME constant
34779
34789
  * in `autoClearAfterMs` while `detected: true` (never a camera's own clock —
@@ -38013,7 +38023,7 @@ var ReadGopBytesResultSchema = object({
38013
38023
  /**
38014
38024
  * A time WINDOW of one finalized segment, cut by byte range — the multi-GOP
38015
38025
  * twin of {@link ReadGopBytesResultSchema}'s single instant. Built for the
38016
- * replay clip's `recording` source (`docs/design/plans/2026-08-26-replay-clip-su-pipeline.md`):
38026
+ * replay clip's `recording` source (`docs/design/plans/2026-08-26-clip-replay-on-pipeline.md`):
38017
38027
  * a replay needs several seconds of native pixels, not one frame.
38018
38028
  *
38019
38029
  * `ok.data` is standalone-demuxable, same as a GOP read. `ok.reachesRequestedEnd`
@@ -55122,7 +55132,7 @@ var PreviewTextField = string().max(200);
55122
55132
  * Whether the notification's preview is a STILL or a short animation.
55123
55133
  *
55124
55134
  * The operator's ask, verbatim: *"inviato come gif o video (come per le altre
55125
- * rule)"* — the other rules already offer an animated preview, and a ten-hour
55135
+ * rule)"* [sent as a gif or video (as for the other rules)] — the other rules already offer an animated preview, and a ten-hour
55126
55136
  * night reads better as three seconds of motion than as one frame of it. Both
55127
55137
  * modes get the SAME treatment (blurred frame, large centred title); `'gif'`
55128
55138
  * simply applies it to a dozen frames sampled across the render and assembles
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_clip_model_registry = require("../clip-model-registry-X457TLXn.js");
5
+ const require_clip_model_registry = require("../clip-model-registry-DBUJMS9d.js");
6
6
  let node_fs = require("node:fs");
7
7
  node_fs = require_clip_model_registry.__toESM(node_fs);
8
8
  let node_path = require("node:path");
@@ -1,4 +1,4 @@
1
- import { En as embeddingModelFailedError, Lr as normalizeNodeId, On as embeddingRequirementsFailedError, Rt as PoolMemoryWatchdog, Tn as embeddingEncoderCapability, Xn as parseProcStatus, a as CLIP_EMBEDDING_STEP_ID, ar as resolvePoolMemoryPolicy, c as resolveClusterModelPin, i as CLIP_TEXT_MODELS, kn as embeddingRequirementsUnavailableError, kr as BaseAddon, n as DEFAULT_CLIP_MODEL, r as CLIP_IMAGE_MODELS, t as BUILTIN_CLIP_MODELS } from "../clip-model-registry-DPqDIZrG.mjs";
1
+ import { En as embeddingModelFailedError, Lr as normalizeNodeId, On as embeddingRequirementsFailedError, Rt as PoolMemoryWatchdog, Tn as embeddingEncoderCapability, Xn as parseProcStatus, a as CLIP_EMBEDDING_STEP_ID, ar as resolvePoolMemoryPolicy, c as resolveClusterModelPin, i as CLIP_TEXT_MODELS, kn as embeddingRequirementsUnavailableError, kr as BaseAddon, n as DEFAULT_CLIP_MODEL, r as CLIP_IMAGE_MODELS, t as BUILTIN_CLIP_MODELS } from "../clip-model-registry-ltmel0yE.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs from "node:fs";
4
4
  import * as path$1 from "node:path";
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.2.285",
21
+ version: "1.2.287",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_pipeline_analytics_widgets",
@@ -33,7 +33,7 @@ var e = {
33
33
  },
34
34
  "@camstack/ui-library": {
35
35
  name: "@camstack/ui-library",
36
- version: "1.2.220",
36
+ version: "1.2.221",
37
37
  scope: ["default"],
38
38
  loaded: !1,
39
39
  from: "addon_pipeline_analytics_widgets",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.2.285",
39
+ version: "1.2.287",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -81,7 +81,7 @@ async function r() {
81
81
  }
82
82
  },
83
83
  "@camstack/ui-library": {
84
- version: "1.2.220",
84
+ version: "1.2.221",
85
85
  scope: "default",
86
86
  shareConfig: {
87
87
  singleton: !0,
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_clip_model_registry = require("../clip-model-registry-X457TLXn.js");
5
+ const require_clip_model_registry = require("../clip-model-registry-DBUJMS9d.js");
6
6
  let node_fs = require("node:fs");
7
7
  node_fs = require_clip_model_registry.__toESM(node_fs, 1);
8
8
  let node_path = require("node:path");
@@ -11664,6 +11664,18 @@ function streamHealthAccepted(category, reason) {
11664
11664
  function discardedSystemEvent(event, lookup) {
11665
11665
  const accessory = discardedAccessoryLiveness(event, lookup);
11666
11666
  if (accessory !== null) return accessory;
11667
+ if (event.category === "worker.online" || event.category === "worker.offline") {
11668
+ const workerId = stringField(event.data, "workerId");
11669
+ return {
11670
+ category: event.category,
11671
+ reason: "a runner is not a node",
11672
+ tags: {},
11673
+ meta: {
11674
+ reason: "a runner is not a node",
11675
+ ...workerId !== void 0 ? { workerId } : {}
11676
+ }
11677
+ };
11678
+ }
11667
11679
  if (event.category !== "stream.online" && event.category !== "stream.offline") return null;
11668
11680
  const data = event.data;
11669
11681
  const reason = stringField(data, "reason");
@@ -11990,12 +12002,11 @@ function incomingFromSystemEvent(event, lookup) {
11990
12002
  deviceId
11991
12003
  });
11992
12004
  }
11993
- case "agent.online":
11994
- case "agent.offline":
11995
12005
  case "worker.online":
11996
- case "worker.offline": {
11997
- const agent = event.category.startsWith("agent.");
11998
- const nodeId = stringField(data, agent ? "agentId" : "workerId");
12006
+ case "worker.offline": return null;
12007
+ case "agent.online":
12008
+ case "agent.offline": {
12009
+ const nodeId = stringField(data, "agentId");
11999
12010
  if (nodeId === void 0) return null;
12000
12011
  const kind = event.category.endsWith(".online") ? "node-online" : "node-offline";
12001
12012
  return systemSubject({
@@ -12003,7 +12014,7 @@ function incomingFromSystemEvent(event, lookup) {
12003
12014
  kind,
12004
12015
  subject: `node:${nodeId}`,
12005
12016
  titleKey: `system.${kind}.title`,
12006
- bodyKey: agent ? `system.${kind}.body.agent` : `system.${kind}.body.worker`,
12017
+ bodyKey: `system.${kind}.body.agent`,
12007
12018
  textParams: { nodeId },
12008
12019
  nodeId
12009
12020
  });
@@ -13620,10 +13631,8 @@ var en_default = {
13620
13631
  "system.stream-offline.body.profiled": "{{profile}} stream for camera {{deviceName}} is offline",
13621
13632
  "system.node-online.title": "Node online",
13622
13633
  "system.node-online.body.agent": "Agent {{nodeId}} is online",
13623
- "system.node-online.body.worker": "Worker {{nodeId}} is online",
13624
13634
  "system.node-offline.title": "Node offline",
13625
13635
  "system.node-offline.body.agent": "Agent {{nodeId}} is offline",
13626
- "system.node-offline.body.worker": "Worker {{nodeId}} is offline",
13627
13636
  "system.node-inference-unavailable.title": "Node has no usable inference device",
13628
13637
  "system.node-inference-unavailable.body": "Node {{nodeId}} can no longer run inference — every enabled device is unavailable ({{devices}}). It will not receive cameras until one returns.",
13629
13638
  "system.addon-crash-loop.title": "Addon stopped after repeated crashes",
@@ -13950,10 +13959,8 @@ var it_default = {
13950
13959
  "system.stream-offline.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è offline",
13951
13960
  "system.node-online.title": "Nodo online",
13952
13961
  "system.node-online.body.agent": "L'agent {{nodeId}} è online",
13953
- "system.node-online.body.worker": "Il worker {{nodeId}} è online",
13954
13962
  "system.node-offline.title": "Nodo offline",
13955
13963
  "system.node-offline.body.agent": "L'agent {{nodeId}} è offline",
13956
- "system.node-offline.body.worker": "Il worker {{nodeId}} è offline",
13957
13964
  "system.node-inference-unavailable.title": "Nodo senza dispositivi di inferenza utilizzabili",
13958
13965
  "system.node-inference-unavailable.body": "Il nodo {{nodeId}} non può più eseguire inferenza — tutti i dispositivi abilitati non sono disponibili ({{devices}}). Non riceverà camere finché uno non torna disponibile.",
13959
13966
  "system.addon-crash-loop.title": "Addon fermato dopo ripetuti crash",
@@ -28482,7 +28489,7 @@ function buildSummaryOutboxInputs(input) {
28482
28489
  *
28483
28490
  * A digest is retrospective. The operator's own framing, verbatim: *"ideale
28484
28491
  * sarebbe considerare solo tracce che vengono alla fine promosse a tracce, dato
28485
- * che il summary non è atteso di essere realtime"* — the window is closed
28492
+ * che il summary non è atteso di essere realtime"* [ideally we would consider only tracks that are eventually promoted to tracks, given that the summary is not expected to be realtime] — the window is closed
28486
28493
  * before this function is called, so the selection may wait for the pipeline's
28487
28494
  * verdict instead of guessing at it.
28488
28495
  *
@@ -38791,13 +38798,13 @@ var DEFAULT_MEDIA_LOCATION = "eventMedia";
38791
38798
  *
38792
38799
  * And why it is not the addon's data dir either: from 2026-08-31 to 2026-09-04
38793
38800
  * the gallery was pinned to `<dataDir>/gallery` (873b73e2c). The operator's
38794
- * rule of 2026-09-04 — *"le cartelle addons non devono trasportare nulla"* —
38801
+ * rule of 2026-09-04 — *"le cartelle addons non devono trasportare nulla"* [the addons folders must not carry anything] —
38795
38802
  * reversed that: media in an addon dir is swept into every system backup,
38796
38803
  * sits on the constrained appdata disk, and is invisible to every
38797
38804
  * storage-location surface (occupancy, relocation, the locations UI).
38798
38805
  *
38799
38806
  * Since 2026-09-04 the gallery is the THIRD TENANT of the shared `artifacts`
38800
- * class ("no nessuna eccezione. Rimane li in artifacts."): its bytes live at
38807
+ * class ("no nessuna eccezione. Rimane li in artifacts." [no, no exception. It stays there in artifacts.]): its bytes live at
38801
38808
  * `<artifactsRoot>/gallery/…` ({@link GALLERY_TENANT_SUBPATH}). This ref is
38802
38809
  * therefore no longer a declared storage class — it is the rows' PERMANENT
38803
38810
  * `locationId` value, which the media-storage wiring maps to the tenant
@@ -40690,7 +40697,7 @@ async function publishPreview(ports, input) {
40690
40697
  * The timelapse PREVIEW frame: one still out of the finished video, titled.
40691
40698
  *
40692
40699
  * The operator's ask, verbatim: the timelapse notification must carry a
40693
- * preview image *"come per le altre rule"* — every detection rule's card shows
40700
+ * preview image *"come per le altre rule"* [as for the other rules] — every detection rule's card shows
40694
40701
  * a picture, and a timelapse's showed nothing but text. A notification with no
40695
40702
  * image is a notification you have to open to understand.
40696
40703
  *
@@ -41439,8 +41446,8 @@ function centralSquareContainmentFraction(bbox, frame, layout = wideCentralSquar
41439
41446
  * padding) wherever the subject still lands ≥ {@link CENTRAL_SQUARE_CONTAINMENT_MIN}
41440
41447
  * inside the delivered central square. Only when it does NOT — the
41441
41448
  * subject-on-the-side case, where the square view would show no subject at all
41442
- * — fall back to the contained layout: the subject DEVE essere nel media
41443
- * consegnato (operator, 2026-08-21), and a padding band in the lateral third
41449
+ * — fall back to the contained layout: the subject MUST be in the delivered
41450
+ * media (operator, 2026-08-21), and a padding band in the lateral third
41444
41451
  * is the price of the only crop that still shows it.
41445
41452
  */
41446
41453
  function deliveredWideCentralSquareLayout(bbox, frame) {
@@ -45357,7 +45364,7 @@ async function pruneV1DetectedSamples(deps, options) {
45357
45364
  *
45358
45365
  * The operator's decision of 2026-09-26: "cancelliamo e ripartiamo, tieni 3
45359
45366
  * esemplari migliori per soggetto … discard tutto il resto anche quelle
45360
- * pending". The gallery after D643 is two alignments mixed, 518 detected
45367
+ * pending" [let us delete and restart, keep the 3 best exemplars per subject … discard everything else, including the pending ones]. The gallery after D643 is two alignments mixed, 518 detected
45361
45368
  * samples of which none can be re-derived; starting again from a small, clean
45362
45369
  * core is cheaper than pruning it into shape.
45363
45370
  *
@@ -51555,7 +51562,7 @@ function clipPenaltyScale(alongClip, acrossClip) {
51555
51562
  * bottom, and it is meaningless for an upright person: a 4K frame is 3840 px
51556
51563
  * wide, a person clipped at the head is ~400 px wide, so `spanX = 0.104` and a
51557
51564
  * decapitated person lost **5.2 %** of its score — the operator's "questi tagli
51558
- * hanno uno score troppo alto, non si vedono il dorso e testa", with the number
51565
+ * hanno uno score troppo alto, non si vedono il dorso e testa" [these crops have too high a score, the back and head are not visible], with the number
51559
51566
  * attached. The frame's width is not a fact about the subject. The remnant's
51560
51567
  * own aspect is: the same person now loses 47.9 %, and the wide-subject case the
51561
51568
  * old shape existed for is penalised MORE than before (a 900×400 vehicle flush
@@ -52210,7 +52217,7 @@ function intersection(a, b) {
52210
52217
  * keyFrame→thumbnail derive — framed a motorcycle with its rider's head cut
52211
52218
  * off. Operator, device 617, tracks `7f50622b` and `9cbc4791`, three minutes
52212
52219
  * apart: "motocicli e veicoli a due ruote devono includere il conducente nel
52213
- * keyframe" (D407).
52220
+ * keyframe" [motorcycles and two-wheeled vehicles must include the rider in the keyframe] (D407).
52214
52221
  *
52215
52222
  * This is the ONE place the folded subject's rectangle is formed, and it is
52216
52223
  * formed BEFORE the tracker — so no crop path derives a second rectangle
@@ -52809,7 +52816,7 @@ function ruleApplies(resolved, det, className, maskInfo, _zones, frameWidth, fra
52809
52816
  *
52810
52817
  * Arithmetic, not optimism. The alphabet is 32 characters, so an id is 50 bits
52811
52818
  * and the space is 32^10 ≈ 1.13e15. The live table held 17 870 track rows under
52812
- * a 7-day window (measured, `piano-riduzione-database`), so call the population
52819
+ * a 7-day window (measured, `database-reduction-plan`), so call the population
52813
52820
  * 20 000 ids that must not collide with each other. Birthday:
52814
52821
  *
52815
52822
  * p ≈ n² / 2N = 4e8 / 2.25e15 ≈ 1.8e-7 per retention window
@@ -1,4 +1,4 @@
1
- import { $ as NC_ALARM_SYSTEM_EVENT_KINDS, $n as readDeviceStateFrom, $r as union, $t as SetTrackPurityInputSchema, A as EMBEDDING_REQUIREMENTS_FAILED, An as encodeVectorBase64, Ar as CamProfileSchema, At as NcSnoozeSuppressedSchema, B as ListTrackRelationsInputSchema, Bn as isMediaOwnerType, Br as _enum, Bt as RECORDING_SOURCE_CAMSTACK_ADDON, C as DEFAULT_EVENT_COLOR, Cn as describeSystemEventDeliveryProblem, Cr as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, Ct as NcRulePatchSchema, D as DeclaredDevices, Dn as embeddingRefusalOf, Dr as DeviceType, Dt as NcScheduleSchema, E as DETECTION_PIPELINE_CAP_NAME, Er as isSourceCap, Et as NcRuleUpdateInputSchema, F as EXPORT_DENSE_MAX_RANGES, Fn as gifFromMp4Args, Fr as isDeviceScopedCap, Ft as NcTemplateVarDescriptorSchema, G as MAX_BIRTH_LATENCY_PROXY_MS, Gn as kebabToCamel, Gr as looseObject, Gt as SCENE_DEFAULT_ANCHOR_THRESHOLD, H as LockStateSchema, Hn as isSystemDelivery, Hr as boolean, Ht as RetrainStatusSchema, I as FIRST_LEVEL_MACRO_CLASSES, In as isAudioClassName, Ir as nodePin, It as OPS_LOG_DEFAULT_LIMIT, J as MOTION_CLOSE_AFTER_MS, Jn as notificationRulesCapability, Jr as partialRecord, Jt as SCENE_DEFAULT_QUIET_SECONDS, K as MAX_TRACK_PURITIES, Kn as mayWriteToLocation, Kr as number, Kt as SCENE_DEFAULT_CHECK_INTERVAL_SEC, L as FULL_IMAGE_BBOX, Ln as isDetectionMacroClass, Lt as OpsLogEntrySchema, M as EVENT_DENSITY_BATCH_MAX, Mn as faceGalleryCapability, Mr as customAction, Mt as NcTaxonomySchema, N as EVENT_KIND_BY_CAP, Nn as failureContributionCapability, Nr as defineCustomActions, Nt as NcTemplatePreviewInputSchema, O as DetectionSourceSchema, Or as errMsg, Ot as NcSnoozeInputSchema, P as EVENT_OWNER_TYPES, Pn as gifDeriveSpeed, Pr as hydrateSchema, Pt as NcTemplatePreviewSchema, Q as NC_ALARM_DELAY_MAX_SEC, Qn as plateGalleryCapability, Qr as tuple, Qt as SceneMonitorSchema, R as FailureCounters, Rn as isEventOwnerType, Rr as sleep$1, S as CoverStateSchema, Sn as deriveRecordingMode, Sr as zoneAnalyticsCapability, St as NcRuleInputSchema, T as DETECTION_MACRO_CLASSES, Tr as evaluateSensorEdge, Tt as NcRuleTargetSchema, U as MAX_ARCHIVED_DEBUG_NOTES, Un as isSystemEventSummaryRule, Ur as discriminatedUnion, Ut as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, V as ListTrackRelationsResultSchema, Vn as isScheduleActive, Vr as array, Vt as RebuildObjectEmbeddingsRefusalSchema, W as MAX_BIRTH_DECISION_RECORDS, Wn as isVectorIndexDimConflict, Wr as literal, Wt as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, X as MotionTriggeredBySchema, Xr as strictObject, Xt as SCENE_DIVERGED, Y as MediaFileKindEnum, Yn as occupancyScope, Yr as record, Yt as SCENE_DEFAULT_UNCOVERED_POLICY, Z as NC_ALARM_DELAY_FIELDS, Zn as pipelineAnalyticsCapability, Zr as string, Zt as SCENE_RESET_RECAPTURES, _ as BaseDevice, _n as audioMetricsCapability, _r as systemEventSummaryScheduleOf, _t as NcAlarmSensorsInputSchema, a as CLIP_EMBEDDING_STEP_ID, an as TimelapseRulePatchSchema, at as NC_CLIP_RETENTION_MAX_SEC, b as ClearTrackRelationInputSchema, bn as consumableLowPercentOf, br as templateVarsFor, bt as NcConditionDescriptorSchema, c as resolveClusterModelPin, cn as TrackRelationKindSchema, cr as ruleKindOf, ct as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, d as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, dn as TrackSourceSchema, dr as servedTemplateVars, dt as NC_SNOOZE_MAX_MINUTES, ei as unknown, en as SetTrackPurityResultSchema, er as readMotionTriggeredBy, et as NC_ALARM_TRIGGERED_MAX_SEC, f as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, fn as addonWidgetsSourceCapability, fr as storageOccupancyCapability, ft as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, g as BIRTH_DECISION_DEFAULT_LIMIT, gn as assertTimelapseCadences, gr as systemEventFilterApplies, gt as NcAlarmConfigSchema, h as ArchivedDebugNoteSchema, hn as applyNonBlockingEdit, hr as systemEventFamilyProblems, ht as NC_TEMPLATE_VARS, in as TimelapseRuleInputSchema, ir as resolveModeDelays, it as NC_CLIP_PRE_ROLL_DEFAULT_SEC, j as EMBEDDING_REQUIREMENTS_UNAVAILABLE, jn as evictionPolicyOfLocation, jr as createEvent, jt as NcSystemEventKindSchema, k as EMBEDDING_MODEL_FAILED, kr as BaseAddon, kt as NcSnoozeSchema, l as APPEARANCE_BIN_COUNT, ln as TrackRelationSchema, lr as sceneMonitorCapability, lt as NC_DEFAULT_SNOOZE_MINUTES, m as AlarmArmModeSchema, mn as applyModeDelaysEdits, mr as systemEventDeliveryProblems, mt as NC_TAXONOMY, nn as TIMELAPSE_DENSE_FLOOR_SEC, nr as resolveClipSearchMinScore, nt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, o as FACE_EMBEDDING_STEP_ID, on as TimelapseRuleSchema, or as ruleBelongsToAlarm$1, ot as NC_CONDITION_CATALOG, p as AUDIO_MACRO_LABELS, pn as alarmPanelCapability, pr as subKindsOf, pt as NC_TANK_SYSTEM_EVENT_KINDS, q as MAX_TRACK_RELATIONS, qn as memoizePinnedFfmpeg, qr as object, qt as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, rn as TRACK_RELATIONS_DEFAULT_LIMIT, rr as resolveLocationMode, rt as NC_CLIP_POST_ROLL_DEFAULT_SEC, s as readClusterModelPinStrict, sn as TrackPuritySchema, sr as ruleDeviceCompatCapQueries, st as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, t as BUILTIN_CLIP_MODELS, ti as EventCategory, tn as SetTrackRelationInputSchema, tr as readTimelapseGeneratedAt, tt as NC_AUDIO_CONFIRM_HITS_DEFAULT, u as APPEARANCE_BLOCKS, un as TrackSideSchema, ur as sensorRaisedOf, ut as NC_SENSOR_TRANSITION_KINDS, v as BirthDecisionRecordSchema, vn as audioModeOf, vr as systemEventSummarySplitOf, vt as NcAlarmSensorsSchema, w as DEFAULT_TIMELAPSE_PREVIEW_TEXT, wn as describeSystemEventFamilyProblem, wr as canonicalHash, wt as NcRuleSchema, x as ClearTrackRelationResultSchema, xn as cosineSimilarity$1, xr as vectorDimFromBase64, xt as NcConditionsSchema, y as COCO_TO_MACRO, yn as buildEventKindDescriptor, yr as templateCarriesSummary, yt as NcAlarmSettingsPatchSchema, z as LabelAttributionSchema, zn as isKnownTemplateVar, zr as ZodObject, zt as RECORDING_EXPORT_MAX_READ_BYTES } from "../clip-model-registry-DPqDIZrG.mjs";
1
+ import { $ as NC_ALARM_SYSTEM_EVENT_KINDS, $n as readDeviceStateFrom, $r as union, $t as SetTrackPurityInputSchema, A as EMBEDDING_REQUIREMENTS_FAILED, An as encodeVectorBase64, Ar as CamProfileSchema, At as NcSnoozeSuppressedSchema, B as ListTrackRelationsInputSchema, Bn as isMediaOwnerType, Br as _enum, Bt as RECORDING_SOURCE_CAMSTACK_ADDON, C as DEFAULT_EVENT_COLOR, Cn as describeSystemEventDeliveryProblem, Cr as DEFAULT_FIRST_SIGHTING_FRESHNESS_MS, Ct as NcRulePatchSchema, D as DeclaredDevices, Dn as embeddingRefusalOf, Dr as DeviceType, Dt as NcScheduleSchema, E as DETECTION_PIPELINE_CAP_NAME, Er as isSourceCap, Et as NcRuleUpdateInputSchema, F as EXPORT_DENSE_MAX_RANGES, Fn as gifFromMp4Args, Fr as isDeviceScopedCap, Ft as NcTemplateVarDescriptorSchema, G as MAX_BIRTH_LATENCY_PROXY_MS, Gn as kebabToCamel, Gr as looseObject, Gt as SCENE_DEFAULT_ANCHOR_THRESHOLD, H as LockStateSchema, Hn as isSystemDelivery, Hr as boolean, Ht as RetrainStatusSchema, I as FIRST_LEVEL_MACRO_CLASSES, In as isAudioClassName, Ir as nodePin, It as OPS_LOG_DEFAULT_LIMIT, J as MOTION_CLOSE_AFTER_MS, Jn as notificationRulesCapability, Jr as partialRecord, Jt as SCENE_DEFAULT_QUIET_SECONDS, K as MAX_TRACK_PURITIES, Kn as mayWriteToLocation, Kr as number, Kt as SCENE_DEFAULT_CHECK_INTERVAL_SEC, L as FULL_IMAGE_BBOX, Ln as isDetectionMacroClass, Lt as OpsLogEntrySchema, M as EVENT_DENSITY_BATCH_MAX, Mn as faceGalleryCapability, Mr as customAction, Mt as NcTaxonomySchema, N as EVENT_KIND_BY_CAP, Nn as failureContributionCapability, Nr as defineCustomActions, Nt as NcTemplatePreviewInputSchema, O as DetectionSourceSchema, Or as errMsg, Ot as NcSnoozeInputSchema, P as EVENT_OWNER_TYPES, Pn as gifDeriveSpeed, Pr as hydrateSchema, Pt as NcTemplatePreviewSchema, Q as NC_ALARM_DELAY_MAX_SEC, Qn as plateGalleryCapability, Qr as tuple, Qt as SceneMonitorSchema, R as FailureCounters, Rn as isEventOwnerType, Rr as sleep$1, S as CoverStateSchema, Sn as deriveRecordingMode, Sr as zoneAnalyticsCapability, St as NcRuleInputSchema, T as DETECTION_MACRO_CLASSES, Tr as evaluateSensorEdge, Tt as NcRuleTargetSchema, U as MAX_ARCHIVED_DEBUG_NOTES, Un as isSystemEventSummaryRule, Ur as discriminatedUnion, Ut as SCENE_CONFIRM_DEFAULT_MAX_IMAGE_PX, V as ListTrackRelationsResultSchema, Vn as isScheduleActive, Vr as array, Vt as RebuildObjectEmbeddingsRefusalSchema, W as MAX_BIRTH_DECISION_RECORDS, Wn as isVectorIndexDimConflict, Wr as literal, Wt as SCENE_CONFIRM_DEFAULT_TIMEOUT_MS, X as MotionTriggeredBySchema, Xr as strictObject, Xt as SCENE_DIVERGED, Y as MediaFileKindEnum, Yn as occupancyScope, Yr as record, Yt as SCENE_DEFAULT_UNCOVERED_POLICY, Z as NC_ALARM_DELAY_FIELDS, Zn as pipelineAnalyticsCapability, Zr as string, Zt as SCENE_RESET_RECAPTURES, _ as BaseDevice, _n as audioMetricsCapability, _r as systemEventSummaryScheduleOf, _t as NcAlarmSensorsInputSchema, a as CLIP_EMBEDDING_STEP_ID, an as TimelapseRulePatchSchema, at as NC_CLIP_RETENTION_MAX_SEC, b as ClearTrackRelationInputSchema, bn as consumableLowPercentOf, br as templateVarsFor, bt as NcConditionDescriptorSchema, c as resolveClusterModelPin, cn as TrackRelationKindSchema, cr as ruleKindOf, ct as NC_CONSUMABLE_SYSTEM_EVENT_KINDS, d as APPEARANCE_RESOLVES_AMBIGUITY_DEFAULT, dn as TrackSourceSchema, dr as servedTemplateVars, dt as NC_SNOOZE_MAX_MINUTES, ei as unknown, en as SetTrackPurityResultSchema, er as readMotionTriggeredBy, et as NC_ALARM_TRIGGERED_MAX_SEC, f as ARCHIVED_DEBUG_NOTES_DEFAULT_LIMIT, fn as addonWidgetsSourceCapability, fr as storageOccupancyCapability, ft as NC_SYSTEM_EVENT_KIND_GROUP_SPECS, g as BIRTH_DECISION_DEFAULT_LIMIT, gn as assertTimelapseCadences, gr as systemEventFilterApplies, gt as NcAlarmConfigSchema, h as ArchivedDebugNoteSchema, hn as applyNonBlockingEdit, hr as systemEventFamilyProblems, ht as NC_TEMPLATE_VARS, in as TimelapseRuleInputSchema, ir as resolveModeDelays, it as NC_CLIP_PRE_ROLL_DEFAULT_SEC, j as EMBEDDING_REQUIREMENTS_UNAVAILABLE, jn as evictionPolicyOfLocation, jr as createEvent, jt as NcSystemEventKindSchema, k as EMBEDDING_MODEL_FAILED, kr as BaseAddon, kt as NcSnoozeSchema, l as APPEARANCE_BIN_COUNT, ln as TrackRelationSchema, lr as sceneMonitorCapability, lt as NC_DEFAULT_SNOOZE_MINUTES, m as AlarmArmModeSchema, mn as applyModeDelaysEdits, mr as systemEventDeliveryProblems, mt as NC_TAXONOMY, nn as TIMELAPSE_DENSE_FLOOR_SEC, nr as resolveClipSearchMinScore, nt as NC_AUDIO_CONFIRM_WINDOW_SEC_DEFAULT, o as FACE_EMBEDDING_STEP_ID, on as TimelapseRuleSchema, or as ruleBelongsToAlarm$1, ot as NC_CONDITION_CATALOG, p as AUDIO_MACRO_LABELS, pn as alarmPanelCapability, pr as subKindsOf, pt as NC_TANK_SYSTEM_EVENT_KINDS, q as MAX_TRACK_RELATIONS, qn as memoizePinnedFfmpeg, qr as object, qt as SCENE_DEFAULT_OBSERVATION_SPACING_SEC, rn as TRACK_RELATIONS_DEFAULT_LIMIT, rr as resolveLocationMode, rt as NC_CLIP_POST_ROLL_DEFAULT_SEC, s as readClusterModelPinStrict, sn as TrackPuritySchema, sr as ruleDeviceCompatCapQueries, st as NC_CONSUMABLE_LOW_PERCENT_DEFAULT, t as BUILTIN_CLIP_MODELS, ti as EventCategory, tn as SetTrackRelationInputSchema, tr as readTimelapseGeneratedAt, tt as NC_AUDIO_CONFIRM_HITS_DEFAULT, u as APPEARANCE_BLOCKS, un as TrackSideSchema, ur as sensorRaisedOf, ut as NC_SENSOR_TRANSITION_KINDS, v as BirthDecisionRecordSchema, vn as audioModeOf, vr as systemEventSummarySplitOf, vt as NcAlarmSensorsSchema, w as DEFAULT_TIMELAPSE_PREVIEW_TEXT, wn as describeSystemEventFamilyProblem, wr as canonicalHash, wt as NcRuleSchema, x as ClearTrackRelationResultSchema, xn as cosineSimilarity$1, xr as vectorDimFromBase64, xt as NcConditionsSchema, y as COCO_TO_MACRO, yn as buildEventKindDescriptor, yr as templateCarriesSummary, yt as NcAlarmSettingsPatchSchema, z as LabelAttributionSchema, zn as isKnownTemplateVar, zr as ZodObject, zt as RECORDING_EXPORT_MAX_READ_BYTES } from "../clip-model-registry-ltmel0yE.mjs";
2
2
  import { t as __exportAll } from "../embedding-encoder/index.mjs";
3
3
  import * as fs$1 from "node:fs";
4
4
  import { createWriteStream, promises } from "node:fs";
@@ -11656,6 +11656,18 @@ function streamHealthAccepted(category, reason) {
11656
11656
  function discardedSystemEvent(event, lookup) {
11657
11657
  const accessory = discardedAccessoryLiveness(event, lookup);
11658
11658
  if (accessory !== null) return accessory;
11659
+ if (event.category === "worker.online" || event.category === "worker.offline") {
11660
+ const workerId = stringField(event.data, "workerId");
11661
+ return {
11662
+ category: event.category,
11663
+ reason: "a runner is not a node",
11664
+ tags: {},
11665
+ meta: {
11666
+ reason: "a runner is not a node",
11667
+ ...workerId !== void 0 ? { workerId } : {}
11668
+ }
11669
+ };
11670
+ }
11659
11671
  if (event.category !== "stream.online" && event.category !== "stream.offline") return null;
11660
11672
  const data = event.data;
11661
11673
  const reason = stringField(data, "reason");
@@ -11982,12 +11994,11 @@ function incomingFromSystemEvent(event, lookup) {
11982
11994
  deviceId
11983
11995
  });
11984
11996
  }
11985
- case "agent.online":
11986
- case "agent.offline":
11987
11997
  case "worker.online":
11988
- case "worker.offline": {
11989
- const agent = event.category.startsWith("agent.");
11990
- const nodeId = stringField(data, agent ? "agentId" : "workerId");
11998
+ case "worker.offline": return null;
11999
+ case "agent.online":
12000
+ case "agent.offline": {
12001
+ const nodeId = stringField(data, "agentId");
11991
12002
  if (nodeId === void 0) return null;
11992
12003
  const kind = event.category.endsWith(".online") ? "node-online" : "node-offline";
11993
12004
  return systemSubject({
@@ -11995,7 +12006,7 @@ function incomingFromSystemEvent(event, lookup) {
11995
12006
  kind,
11996
12007
  subject: `node:${nodeId}`,
11997
12008
  titleKey: `system.${kind}.title`,
11998
- bodyKey: agent ? `system.${kind}.body.agent` : `system.${kind}.body.worker`,
12009
+ bodyKey: `system.${kind}.body.agent`,
11999
12010
  textParams: { nodeId },
12000
12011
  nodeId
12001
12012
  });
@@ -13612,10 +13623,8 @@ var en_default = {
13612
13623
  "system.stream-offline.body.profiled": "{{profile}} stream for camera {{deviceName}} is offline",
13613
13624
  "system.node-online.title": "Node online",
13614
13625
  "system.node-online.body.agent": "Agent {{nodeId}} is online",
13615
- "system.node-online.body.worker": "Worker {{nodeId}} is online",
13616
13626
  "system.node-offline.title": "Node offline",
13617
13627
  "system.node-offline.body.agent": "Agent {{nodeId}} is offline",
13618
- "system.node-offline.body.worker": "Worker {{nodeId}} is offline",
13619
13628
  "system.node-inference-unavailable.title": "Node has no usable inference device",
13620
13629
  "system.node-inference-unavailable.body": "Node {{nodeId}} can no longer run inference — every enabled device is unavailable ({{devices}}). It will not receive cameras until one returns.",
13621
13630
  "system.addon-crash-loop.title": "Addon stopped after repeated crashes",
@@ -13942,10 +13951,8 @@ var it_default = {
13942
13951
  "system.stream-offline.body.profiled": "Lo stream {{profile}} della camera {{deviceName}} è offline",
13943
13952
  "system.node-online.title": "Nodo online",
13944
13953
  "system.node-online.body.agent": "L'agent {{nodeId}} è online",
13945
- "system.node-online.body.worker": "Il worker {{nodeId}} è online",
13946
13954
  "system.node-offline.title": "Nodo offline",
13947
13955
  "system.node-offline.body.agent": "L'agent {{nodeId}} è offline",
13948
- "system.node-offline.body.worker": "Il worker {{nodeId}} è offline",
13949
13956
  "system.node-inference-unavailable.title": "Nodo senza dispositivi di inferenza utilizzabili",
13950
13957
  "system.node-inference-unavailable.body": "Il nodo {{nodeId}} non può più eseguire inferenza — tutti i dispositivi abilitati non sono disponibili ({{devices}}). Non riceverà camere finché uno non torna disponibile.",
13951
13958
  "system.addon-crash-loop.title": "Addon fermato dopo ripetuti crash",
@@ -28459,7 +28466,7 @@ function buildSummaryOutboxInputs(input) {
28459
28466
  *
28460
28467
  * A digest is retrospective. The operator's own framing, verbatim: *"ideale
28461
28468
  * sarebbe considerare solo tracce che vengono alla fine promosse a tracce, dato
28462
- * che il summary non è atteso di essere realtime"* — the window is closed
28469
+ * che il summary non è atteso di essere realtime"* [ideally we would consider only tracks that are eventually promoted to tracks, given that the summary is not expected to be realtime] — the window is closed
28463
28470
  * before this function is called, so the selection may wait for the pipeline's
28464
28471
  * verdict instead of guessing at it.
28465
28472
  *
@@ -38768,13 +38775,13 @@ var DEFAULT_MEDIA_LOCATION = "eventMedia";
38768
38775
  *
38769
38776
  * And why it is not the addon's data dir either: from 2026-08-31 to 2026-09-04
38770
38777
  * the gallery was pinned to `<dataDir>/gallery` (873b73e2c). The operator's
38771
- * rule of 2026-09-04 — *"le cartelle addons non devono trasportare nulla"* —
38778
+ * rule of 2026-09-04 — *"le cartelle addons non devono trasportare nulla"* [the addons folders must not carry anything] —
38772
38779
  * reversed that: media in an addon dir is swept into every system backup,
38773
38780
  * sits on the constrained appdata disk, and is invisible to every
38774
38781
  * storage-location surface (occupancy, relocation, the locations UI).
38775
38782
  *
38776
38783
  * Since 2026-09-04 the gallery is the THIRD TENANT of the shared `artifacts`
38777
- * class ("no nessuna eccezione. Rimane li in artifacts."): its bytes live at
38784
+ * class ("no nessuna eccezione. Rimane li in artifacts." [no, no exception. It stays there in artifacts.]): its bytes live at
38778
38785
  * `<artifactsRoot>/gallery/…` ({@link GALLERY_TENANT_SUBPATH}). This ref is
38779
38786
  * therefore no longer a declared storage class — it is the rows' PERMANENT
38780
38787
  * `locationId` value, which the media-storage wiring maps to the tenant
@@ -40667,7 +40674,7 @@ async function publishPreview(ports, input) {
40667
40674
  * The timelapse PREVIEW frame: one still out of the finished video, titled.
40668
40675
  *
40669
40676
  * The operator's ask, verbatim: the timelapse notification must carry a
40670
- * preview image *"come per le altre rule"* — every detection rule's card shows
40677
+ * preview image *"come per le altre rule"* [as for the other rules] — every detection rule's card shows
40671
40678
  * a picture, and a timelapse's showed nothing but text. A notification with no
40672
40679
  * image is a notification you have to open to understand.
40673
40680
  *
@@ -41416,8 +41423,8 @@ function centralSquareContainmentFraction(bbox, frame, layout = wideCentralSquar
41416
41423
  * padding) wherever the subject still lands ≥ {@link CENTRAL_SQUARE_CONTAINMENT_MIN}
41417
41424
  * inside the delivered central square. Only when it does NOT — the
41418
41425
  * subject-on-the-side case, where the square view would show no subject at all
41419
- * — fall back to the contained layout: the subject DEVE essere nel media
41420
- * consegnato (operator, 2026-08-21), and a padding band in the lateral third
41426
+ * — fall back to the contained layout: the subject MUST be in the delivered
41427
+ * media (operator, 2026-08-21), and a padding band in the lateral third
41421
41428
  * is the price of the only crop that still shows it.
41422
41429
  */
41423
41430
  function deliveredWideCentralSquareLayout(bbox, frame) {
@@ -45315,7 +45322,7 @@ async function pruneV1DetectedSamples(deps, options) {
45315
45322
  *
45316
45323
  * The operator's decision of 2026-09-26: "cancelliamo e ripartiamo, tieni 3
45317
45324
  * esemplari migliori per soggetto … discard tutto il resto anche quelle
45318
- * pending". The gallery after D643 is two alignments mixed, 518 detected
45325
+ * pending" [let us delete and restart, keep the 3 best exemplars per subject … discard everything else, including the pending ones]. The gallery after D643 is two alignments mixed, 518 detected
45319
45326
  * samples of which none can be re-derived; starting again from a small, clean
45320
45327
  * core is cheaper than pruning it into shape.
45321
45328
  *
@@ -51511,7 +51518,7 @@ function clipPenaltyScale(alongClip, acrossClip) {
51511
51518
  * bottom, and it is meaningless for an upright person: a 4K frame is 3840 px
51512
51519
  * wide, a person clipped at the head is ~400 px wide, so `spanX = 0.104` and a
51513
51520
  * decapitated person lost **5.2 %** of its score — the operator's "questi tagli
51514
- * hanno uno score troppo alto, non si vedono il dorso e testa", with the number
51521
+ * hanno uno score troppo alto, non si vedono il dorso e testa" [these crops have too high a score, the back and head are not visible], with the number
51515
51522
  * attached. The frame's width is not a fact about the subject. The remnant's
51516
51523
  * own aspect is: the same person now loses 47.9 %, and the wide-subject case the
51517
51524
  * old shape existed for is penalised MORE than before (a 900×400 vehicle flush
@@ -52166,7 +52173,7 @@ function intersection(a, b) {
52166
52173
  * keyFrame→thumbnail derive — framed a motorcycle with its rider's head cut
52167
52174
  * off. Operator, device 617, tracks `7f50622b` and `9cbc4791`, three minutes
52168
52175
  * apart: "motocicli e veicoli a due ruote devono includere il conducente nel
52169
- * keyframe" (D407).
52176
+ * keyframe" [motorcycles and two-wheeled vehicles must include the rider in the keyframe] (D407).
52170
52177
  *
52171
52178
  * This is the ONE place the folded subject's rectangle is formed, and it is
52172
52179
  * formed BEFORE the tracker — so no crop path derives a second rectangle
@@ -52765,7 +52772,7 @@ function ruleApplies(resolved, det, className, maskInfo, _zones, frameWidth, fra
52765
52772
  *
52766
52773
  * Arithmetic, not optimism. The alphabet is 32 characters, so an id is 50 bits
52767
52774
  * and the space is 32^10 ≈ 1.13e15. The live table held 17 870 track rows under
52768
- * a 7-day window (measured, `piano-riduzione-database`), so call the population
52775
+ * a 7-day window (measured, `database-reduction-plan`), so call the population
52769
52776
  * 20 000 ids that must not collide with each other. Birthday:
52770
52777
  *
52771
52778
  * p ≈ n² / 2N = 4e8 / 2.25e15 ≈ 1.8e-7 per retention window
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-D0JVXXRd.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-Bjj5m6Qi.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-post-analysis",
3
- "version": "1.2.311",
3
+ "version": "1.2.313",
4
4
  "description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
5
5
  "keywords": [
6
6
  "camstack",