@trillboards/edge-sdk 0.2.76 → 0.2.79

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.
Files changed (40) hide show
  1. package/deploy/detector/tests/test_server.py +14 -0
  2. package/dist/CloudSensingManager.d.ts +39 -0
  3. package/dist/CloudSensingManager.d.ts.map +1 -1
  4. package/dist/CloudSensingManager.js +88 -0
  5. package/dist/CloudSensingManager.js.map +1 -1
  6. package/dist/DetectorShadowProbe.d.ts +381 -0
  7. package/dist/DetectorShadowProbe.d.ts.map +1 -0
  8. package/dist/DetectorShadowProbe.js +463 -0
  9. package/dist/DetectorShadowProbe.js.map +1 -0
  10. package/dist/DurableVlmCandidateSpool.d.ts.map +1 -1
  11. package/dist/DurableVlmCandidateSpool.js +2 -0
  12. package/dist/DurableVlmCandidateSpool.js.map +1 -1
  13. package/dist/EdgeAgent.js +1 -1
  14. package/dist/SensingProfileClient.d.ts +25 -22
  15. package/dist/SensingProfileClient.d.ts.map +1 -1
  16. package/dist/SensingProfileClient.js.map +1 -1
  17. package/dist/VlmCandidateBuffer.d.ts +13 -0
  18. package/dist/VlmCandidateBuffer.d.ts.map +1 -1
  19. package/dist/VlmCandidateBuffer.js +4 -0
  20. package/dist/VlmCandidateBuffer.js.map +1 -1
  21. package/dist/config.d.ts +37 -0
  22. package/dist/config.d.ts.map +1 -1
  23. package/dist/config.js.map +1 -1
  24. package/dist/diagnose.d.ts +1 -1
  25. package/dist/diagnose.js +1 -1
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +19 -4
  29. package/dist/index.js.map +1 -1
  30. package/dist/localInferenceSchema.d.ts +11 -2
  31. package/dist/localInferenceSchema.d.ts.map +1 -1
  32. package/dist/localInferenceSchema.js.map +1 -1
  33. package/dist/localSensing.d.ts +11 -0
  34. package/dist/localSensing.d.ts.map +1 -1
  35. package/dist/localSensing.js +4 -0
  36. package/dist/localSensing.js.map +1 -1
  37. package/dist/sensingRunMode.d.ts.map +1 -1
  38. package/dist/sensingRunMode.js +24 -0
  39. package/dist/sensingRunMode.js.map +1 -1
  40. package/package.json +2 -2
@@ -0,0 +1,381 @@
1
+ /**
2
+ * DetectorShadowProbe — the on-device object detector running in SHADOW MODE.
3
+ *
4
+ * It records the decision the cascade gate WOULD have made and changes nothing.
5
+ * Nothing downstream of it may branch on its answer: not the cadence, not
6
+ * admission, not whether the VLM runs.
7
+ *
8
+ * ── WHY SHADOW FIRST, AND WHY THAT IS NOT A FORMALITY ──────────────────────
9
+ *
10
+ * The detector is a cascade GATE. When it says "nobody here" the VLM call is
11
+ * skipped, and no alert can fire from a frame nobody looked at. The numbers
12
+ * that justify it — ~84.7% of VLM calls removed for ~2.1% of events — were
13
+ * measured on 134 hand-labelled frames drawn from ALERT EPISODES, so the eval
14
+ * set is 64% positive while production is ~84.7% empty
15
+ * (docs/runbooks/cctv-detector-tier.md §1). Those are the right numbers for
16
+ * choosing BETWEEN detectors and the wrong population for sizing a suppressor.
17
+ *
18
+ * So the gate is measured against real fleet traffic before it is allowed to
19
+ * suppress anything. At ~63 ms on top of a ~5,645 ms analyze that measurement
20
+ * costs about 1% — and this class is what keeps it to about 1% when the service
21
+ * is missing, wedged, or answering slowly.
22
+ *
23
+ * ── THREE STATES, NEVER TWO ────────────────────────────────────────────────
24
+ *
25
+ * person_present at least one accepted person-class detection
26
+ * empty the service ANSWERED and found nobody — this is a RESULT
27
+ * unavailable transport failed, non-2xx, bad envelope, or nothing installed
28
+ *
29
+ * `unavailable` must never collapse into `empty`. That collapse is the entire
30
+ * failure mode this feature can have: once the gate is armed, a broken detector
31
+ * read as a quiet venue suppresses every VLM call — and therefore every alert —
32
+ * while `postCount`, `sensingState:'active'` and the portal's "AI active" tile
33
+ * all stay green (docs/runbooks/cctv-connector-runtime-edge-cases.md). The
34
+ * distinction is already load-bearing one layer down: `LocalDetectorClient`
35
+ * throws `DetectorUnavailableError` for a service failure and returns an empty
36
+ * `detections` array for an empty frame, and refuses to default a missing
37
+ * `detections` key to `[]`. This class is the consumer that has to honour it.
38
+ *
39
+ * ── WHY THE SERVICE BEING ABSENT MUST COST NOTHING ─────────────────────────
40
+ *
41
+ * The service exists as of edge-sdk 0.2.76 and ships in all three installers,
42
+ * but "the service shipped" and "this box is running it" are different events.
43
+ * A connector below 0.2.76 has no detector at all, and a FRESH 0.2.76 install
44
+ * answers `/health` with **503 by design** until the OTA'd ONNX lands — so for
45
+ * as long as the fleet takes to upgrade, "nothing usable on 9380" is the common
46
+ * case and shadow mode has to be free in it, or it is a fleet-wide latency
47
+ * regression bought with no measurement at all.
48
+ *
49
+ * Two bounds do that, and neither is a retry policy:
50
+ *
51
+ * 1. A HARD DEADLINE. The client is constructed with a short `timeoutMs`
52
+ * (default 1000 ms) rather than its own 5 s default, so a wedged service
53
+ * can never hold a capture tick for five seconds. ECONNREFUSED — the
54
+ * overwhelmingly common case — settles in microseconds and never reaches
55
+ * it.
56
+ * 2. A BACKOFF ON FAILURE, exponential to a ceiling. After a failure the
57
+ * probe stops calling `detect()` entirely and reports `unavailable` at
58
+ * zero cost until the window closes, at which point ONE cheap `/health`
59
+ * GET decides whether to resume. So a box with no detector pays one
60
+ * connection refusal per backoff window, not one per frame.
61
+ *
62
+ * A skipped frame still REPORTS `unavailable`. Reporting nothing would make a
63
+ * fleet with no detector look like a small sample rather than what it is, and
64
+ * the unavailable RATE is one of the three numbers the soak exists to produce.
65
+ *
66
+ * ── WHY IT NEVER THROWS ────────────────────────────────────────────────────
67
+ *
68
+ * It sits inside `CloudSensingManager.lookThenAdmit`, on the path to the only
69
+ * thing that produces alerts. A shadow measurement that can fail a real capture
70
+ * tick is strictly worse than no measurement. Every exit returns a verdict.
71
+ *
72
+ * @reuse-audit
73
+ * considered: LocalDetectorClient (this package)
74
+ * - reused wholesale, unchanged, as the transport and the parser. Its
75
+ * DetectorUnavailableError-vs-empty-array distinction IS this class's
76
+ * three-state vocabulary; re-deriving it here would be a second opinion
77
+ * about the same bytes.
78
+ * considered: LiteRtVlmProvider's accelerator probe
79
+ * - rejected: it caches a CAPABILITY answered once at startup. This caches a
80
+ * LIVENESS verdict that must be able to return to healthy while the
81
+ * process runs — a detector installed by an MDM push at 3 a.m. has to be
82
+ * picked up without a restart, which is the same reason enterpriseTrust
83
+ * drops its cache on a classified failure.
84
+ */
85
+ import { type DetectResult } from './LocalDetectorClient';
86
+ /** The decision the armed gate WOULD have made about one frame. */
87
+ export type DetectorShadowVerdict = 'person_present' | 'empty' | 'unavailable';
88
+ /**
89
+ * What travels to the server with the frame, and nothing more.
90
+ *
91
+ * Exactly four fields because exactly four columns read them
92
+ * (`vision_call_log.detector_shadow_verdict / _min_confidence / _inference_ms /
93
+ * _wall_ms`).
94
+ * Everything else the probe knows — why a call was unavailable, how many people
95
+ * were found, which artifact answered — stays in `getStats()` for the local
96
+ * health surface. A field on the wire with no column at the other end is the
97
+ * telemetry-producer-substrate defect wearing its other face.
98
+ */
99
+ export interface DetectorShadowWire {
100
+ verdict: DetectorShadowVerdict;
101
+ /**
102
+ * The confidence threshold this verdict was produced at.
103
+ *
104
+ * Carried per frame, not restated server-side: a fleet mid-upgrade across two
105
+ * connector versions can be running two thresholds at once, and pooling those
106
+ * into one rate averages two different gates with nothing saying so. The soak
107
+ * groups on it and refuses to pool. See DETECTOR_GATE_CONFIDENCE.
108
+ */
109
+ minConfidence: number;
110
+ /**
111
+ * Wall-clock ms the SERVICE reports it spent on inference, or null when it
112
+ * did not answer. Distinct from `wallMs` on purpose: the difference between
113
+ * them is loopback + base64 + JSON, which is the part a gate would still pay
114
+ * after it stopped paying for the VLM.
115
+ */
116
+ inferenceMs: number | null;
117
+ /**
118
+ * Wall-clock ms SHADOW MODE cost this capture tick, measured by the caller
119
+ * that paid it. This is the number that says whether the ~1% overhead claim
120
+ * survived contact with real hardware, and it is 0 for a frame skipped under
121
+ * backoff.
122
+ */
123
+ wallMs: number;
124
+ }
125
+ /** The full local reading, including the parts that do not go on the wire. */
126
+ export interface DetectorShadowObservation extends DetectorShadowWire {
127
+ /** Accepted person-class detections. Null when the service did not answer. */
128
+ personCount: number | null;
129
+ /** Highest accepted confidence, for calibrating a threshold later. */
130
+ topConfidence: number | null;
131
+ /** The artifact that answered, as it names itself. */
132
+ model: string | null;
133
+ /** Why `unavailable`. Null on every other verdict. */
134
+ unavailableReason: string | null;
135
+ }
136
+ export interface DetectorShadowStats {
137
+ enabled: boolean;
138
+ /** Frames the probe was asked about, whatever the outcome. */
139
+ observed: number;
140
+ /**
141
+ * Frames declined by the per-feed cadence bound WITHOUT any detector call.
142
+ *
143
+ * Non-zero means this box is starved: `analyze: true` is arriving faster than
144
+ * the analyze cadence the detector is scored at. See `minIntervalMs`.
145
+ */
146
+ rateLimited: number;
147
+ personPresent: number;
148
+ empty: number;
149
+ unavailable: number;
150
+ /** Unavailable frames the backoff answered without touching the network. */
151
+ skippedUnderBackoff: number;
152
+ /** ms this probe has cost capture ticks, summed. */
153
+ totalWallMs: number;
154
+ /** Whether the probe is currently in its failure backoff. */
155
+ backingOff: boolean;
156
+ /** Most recent reason a frame came back `unavailable`. */
157
+ lastUnavailableReason: string | null;
158
+ /** The artifact that most recently answered. */
159
+ lastModel: string | null;
160
+ }
161
+ /**
162
+ * Labels that count as a person.
163
+ *
164
+ * The same set the offline scoring harness accepts
165
+ * (`trillboard-api/scripts/vision/detector-arm-eval.mjs#PERSON_LABELS`), so a
166
+ * shadow verdict and an eval score mean the same thing by the same rule. Held
167
+ * as LABELS and never as a class index: an eval run once defaulted an absent
168
+ * class to index 0 and scored buses as people for a whole run, and the table
169
+ * looked entirely plausible (cctv-detector-tier.md §5).
170
+ *
171
+ * The SHIPPED artifact emits COCO names, so `person` is the only member it can
172
+ * currently produce (`deploy/detector/trillboards_detector/labels.py`). The
173
+ * other three are kept because they are what the SCORING harness accepts and
174
+ * because none of them is a COCO name — so a future artifact with a different
175
+ * vocabulary is graded the same way, and today's cannot be mis-classified by
176
+ * their presence.
177
+ */
178
+ export declare const PERSON_LABELS: ReadonlySet<string>;
179
+ /**
180
+ * Ceiling on how long shadow mode may hold a capture tick.
181
+ *
182
+ * NOT the client's own 5 s default. `lookThenAdmit` runs this between the
183
+ * motion verdict and the admission gate, so every ms here is a ms the frame is
184
+ * older when it reaches the model. The detector's measured cost is ~63 ms, so
185
+ * 1000 ms is ~16x headroom for the slowest plausible answer and still ~0.02% of
186
+ * a 5,645 ms analyze in the worst case — and it is paid at most once per
187
+ * backoff window, because a breach opens the backoff.
188
+ */
189
+ export declare const DEFAULT_SHADOW_TIMEOUT_MS = 1000;
190
+ /** First backoff step after a failure. */
191
+ export declare const DEFAULT_BACKOFF_INITIAL_MS = 30000;
192
+ /**
193
+ * Backoff ceiling.
194
+ *
195
+ * Five minutes rather than "give up": the detector service arrives by MDM push
196
+ * or by an installer run while the connector is already running, so a probe
197
+ * that latched off permanently would need a restart to notice its own product
198
+ * shipping. Same reasoning as the enterprise trust-store cache.
199
+ */
200
+ export declare const DEFAULT_BACKOFF_MAX_MS = 300000;
201
+ /**
202
+ * Minimum wall time between shadow observations OF ONE FEED. 15 s.
203
+ *
204
+ * ── WHY THIS BOUND EXISTS AND WHY IT IS NOT A TUNING KNOB ──────────────────
205
+ *
206
+ * `cctv-detector-tier.md` §2 is unambiguous: **the detector gates the ANALYZE,
207
+ * not the LOOK.** At the 500 ms look cadence, 6 cameras never clears at p95 on
208
+ * any thread configuration measured; at the analyze cadence nothing binds.
209
+ *
210
+ * The call site — one observation per `analyze: true` verdict — is the right
211
+ * PLACE and, on a starved box, the wrong RATE. `MotionGate.evaluate` resolves
212
+ * `heartbeatDue` before it consults the motion verdict, and `markAnalyzed()`
213
+ * only fires when an inference actually LANDS. So on a connector whose single
214
+ * inference slot is saturated, every feed is permanently heartbeat-due and
215
+ * every look returns `analyze: true`. That is the LOOK cadence: measured on the
216
+ * shipped constants, **64 verdicts/second at 32 feeds** — ~4 CPU-seconds per
217
+ * wall second of detector at ~63 ms each, on the exact box the runbook already
218
+ * describes as starved. Worse, almost all of those frames are dropped at
219
+ * admission and never POST, so the calls buy no measurement at all.
220
+ *
221
+ * 15 s is `MIN_ANALYZE_INTERVAL_MS / 2`. Half, not equal, so it cannot bind on
222
+ * a HEALTHY feed: `MotionGate`'s own `minAnalyzeIntervalMs` floor already keeps
223
+ * `analyze: true` at least 30 s apart there, so every analyzed frame is
224
+ * observed and coverage is 100% — which is the fleet the measurement is for.
225
+ * On a starved feed it caps the cost at 1 call per feed per 15 s (2.13/s at 32
226
+ * feeds, ~13% of one core) and the frames it declines simply carry no verdict:
227
+ * the column's NULL already means "not reported", and the soak counts only
228
+ * non-null rows, so the ratio it reports is unchanged.
229
+ *
230
+ * The sampling is by TIME and never by content, so it cannot move the
231
+ * disagreement or savings rates. What it does cost is COVERAGE on a starved
232
+ * box, and that is the deliberate trade: a bounded loss of sample there against
233
+ * an unbounded CPU regression §2 already measured as not clearing.
234
+ */
235
+ export declare const DEFAULT_MIN_OBSERVE_INTERVAL_MS = 15000;
236
+ /**
237
+ * The confidence threshold the QUOTED GATE RESULT was produced at. 0.2918.
238
+ *
239
+ * NOT `LocalDetectorClient`'s 0.25 default, and the difference is the whole
240
+ * point of measuring. The committed evaluation
241
+ * (`trillboard-api/scripts/ai/eval-baselines/detector-arm-results-2026-08-23.json`,
242
+ * arm `rfdetr-medium`) carries TWO numbers that are easy to conflate:
243
+ *
244
+ * pooled_at_0.25 precision 98.8 / recall 98.8 — a DETECTOR score
245
+ * cascade_gate 2.1% events lost / 84.7% saved — a GATE score, and its
246
+ * own `at` field says "the TRAIN-selected threshold, applied
247
+ * to the TEST half" = held_out.threshold_chosen_on_train
248
+ * = 0.2918
249
+ *
250
+ * §1 of the runbook is explicit that those are different questions and that the
251
+ * ranking inverts between them. A shadow run at 0.25 would therefore measure a
252
+ * DIFFERENT gate and hand back rates presented as comparable to 2.1%/84.7%,
253
+ * which is the exact "quoted under other conditions" error the shadow phase
254
+ * exists to stop.
255
+ *
256
+ * The value travels ON THE WIRE per frame (`minConfidence` below) rather than
257
+ * being restated server-side, because a fleet is routinely mid-upgrade across
258
+ * two connector versions and a soak that pooled two thresholds would average
259
+ * two different gates into one number with nothing saying so — the
260
+ * `agent_version` trap in docs/runbooks/ctv-agent-version-map.md, one column
261
+ * over.
262
+ */
263
+ export declare const DETECTOR_GATE_CONFIDENCE = 0.2918;
264
+ /**
265
+ * Ceiling on the WHOLE observation, enforced by this class rather than by the
266
+ * transport. 1500 ms.
267
+ *
268
+ * `LocalDetectorClient`'s `timeoutMs` is an INACTIVITY timeout — its own header
269
+ * says so, and names the case it cannot cover: a server dribbling bytes slowly
270
+ * under a large Content-Length keeps the socket busy, the inactivity timer
271
+ * never fires, and the call is genuinely unbounded. That is tolerable for a
272
+ * client nothing calls on the hot path and NOT tolerable here, because this
273
+ * runs on the path to every admitted analysis — the only path that produces
274
+ * alerts.
275
+ *
276
+ * So the elapsed-time bound lives here, above the transport, where "how long
277
+ * may a shadow measurement hold a capture tick" is actually decided. Slightly
278
+ * above the client's own 1000 ms so the transport still wins the ordinary
279
+ * timeout and reports it as one.
280
+ */
281
+ export declare const DEFAULT_OBSERVE_DEADLINE_MS = 1500;
282
+ export interface DetectorShadowProbeOptions {
283
+ /** Off entirely. Nothing is called and every observe() returns null. */
284
+ enabled?: boolean;
285
+ /** Detector service base URL. Defaults to the client's loopback default. */
286
+ baseUrl?: string;
287
+ /** Hard per-frame deadline. Default DEFAULT_SHADOW_TIMEOUT_MS. */
288
+ timeoutMs?: number;
289
+ /**
290
+ * Confidence floor applied AT THE SERVICE. Default DETECTOR_GATE_CONFIDENCE
291
+ * (0.2918) — the threshold the quoted gate result was produced at, NOT the
292
+ * client's 0.25 default. See that constant for why the difference matters.
293
+ */
294
+ minConfidence?: number;
295
+ /**
296
+ * Ceiling on the whole observation. Default DEFAULT_OBSERVE_DEADLINE_MS —
297
+ * the transport's timeout is an INACTIVITY timeout and cannot bound a
298
+ * dribbling response. 0 disables it, which is only correct on a bench rig.
299
+ */
300
+ deadlineMs?: number;
301
+ backoffInitialMs?: number;
302
+ backoffMaxMs?: number;
303
+ /**
304
+ * Minimum wall time between observations OF ONE FEED. Default 15 s — see
305
+ * DEFAULT_MIN_OBSERVE_INTERVAL_MS for why this is a safety bound rather than
306
+ * a tuning knob. 0 disables it, which is only correct on a bench rig.
307
+ */
308
+ minIntervalMs?: number;
309
+ /** Clock injection for tests. Default Date.now. */
310
+ now?: () => number;
311
+ }
312
+ /** The slice of LocalDetectorClient this probe uses — injectable for tests. */
313
+ export interface DetectorLike {
314
+ detect(jpeg: Buffer): Promise<DetectResult>;
315
+ isHealthy(): Promise<boolean>;
316
+ }
317
+ export declare class DetectorShadowProbe {
318
+ private readonly client;
319
+ private readonly enabled;
320
+ private readonly backoffInitialMs;
321
+ private readonly backoffMaxMs;
322
+ private readonly minIntervalMs;
323
+ private readonly minConfidence;
324
+ private readonly deadlineMs;
325
+ private readonly now;
326
+ /** Last observation per feed, for the cadence bound. */
327
+ private readonly lastObservedAtMs;
328
+ /** null ⇒ not backing off. Otherwise the clock reading backoff expires at. */
329
+ private backoffUntilMs;
330
+ private backoffStepMs;
331
+ private observed;
332
+ private rateLimited;
333
+ private personPresent;
334
+ private empty;
335
+ private unavailable;
336
+ private skippedUnderBackoff;
337
+ private totalWallMs;
338
+ private lastUnavailableReason;
339
+ private lastModel;
340
+ constructor(options?: DetectorShadowProbeOptions, client?: DetectorLike);
341
+ isEnabled(): boolean;
342
+ /**
343
+ * Record the decision the armed gate WOULD have made about this frame.
344
+ *
345
+ * NEVER THROWS, never returns a promise that rejects, and never returns
346
+ * `empty` for a service that did not answer.
347
+ *
348
+ * Returns null for the two cases that are NOT a verdict — the probe is
349
+ * disabled, or this feed is inside its cadence bound — so a caller can tell
350
+ * "no reading" from "the detector is down". Those must not share a value:
351
+ * `unavailable` is a claim about the detector, and null means nobody asked.
352
+ * The caller sends nothing for a null, and the column's NULL already means
353
+ * "not reported".
354
+ *
355
+ * @param jpeg the exact bytes the VLM is about to analyze
356
+ * @param feedKey which feed this frame came from; the cadence bound is
357
+ * PER FEED, because a busy camera must not spend a quiet camera's budget
358
+ */
359
+ observe(jpeg: Buffer, feedKey?: string): Promise<DetectorShadowObservation | null>;
360
+ /** The wire slice — exactly the fields a column reads. */
361
+ static toWire(observation: DetectorShadowObservation): DetectorShadowWire;
362
+ getStats(): DetectorShadowStats;
363
+ private recordUnavailable;
364
+ /**
365
+ * Bound a detector call by ELAPSED time, which the transport cannot do.
366
+ *
367
+ * `LocalDetectorClient`'s timeout is an inactivity timer, and its own header
368
+ * names the hole: a server dribbling bytes under a large Content-Length keeps
369
+ * the socket busy forever. On the path to every admitted analysis, that is an
370
+ * unbounded stall on the only path that produces alerts.
371
+ *
372
+ * The loser's rejection is swallowed rather than left to become an unhandled
373
+ * rejection — the underlying request still settles on its own timeout and its
374
+ * result is simply discarded, which is the correct outcome for a measurement
375
+ * whose window has passed.
376
+ */
377
+ private withDeadline;
378
+ private openBackoff;
379
+ private closeBackoff;
380
+ }
381
+ //# sourceMappingURL=DetectorShadowProbe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DetectorShadowProbe.d.ts","sourceRoot":"","sources":["../src/DetectorShadowProbe.ts"],"names":[],"mappings":"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"}