@camstack/types 1.2.170 → 1.2.172
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.
- package/dist/addon.js +3 -1
- package/dist/addon.mjs +3 -1
- package/dist/capabilities/pipeline-analytics.cap.d.ts +52 -0
- package/dist/capabilities/pipeline-runner.cap.d.ts +4 -0
- package/dist/generated/addon-api.d.ts +7 -0
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +326 -1
- package/dist/index.mjs +321 -2
- package/dist/interfaces/birth-decision-ledger.d.ts +124 -0
- package/dist/interfaces/pipeline-runner-capability.d.ts +9 -0
- package/dist/interfaces/stream-broker.d.ts +20 -0
- package/dist/{sleep-IjLtwkO5.js → sleep-Bo9cUOXp.js} +1 -0
- package/dist/{sleep-uGNYCvYp.mjs → sleep-DMghvp8F.mjs} +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Birth-decision ledger — one durable row per track-birth VERDICT (D409).
|
|
3
|
+
*
|
|
4
|
+
* ── Why this exists ────────────────────────────────────────────────────────
|
|
5
|
+
* On 2026-09-08 the operator marked eleven tracks for review and five of them
|
|
6
|
+
* said "traccia partita in ritardo" — the track appears to begin long after the
|
|
7
|
+
* subject entered the scene. Two causes were proposed and NEITHER was measured:
|
|
8
|
+
*
|
|
9
|
+
* - the confirmation gate's deferral (`maxDeferralMs`, 2 s). This is now
|
|
10
|
+
* DISPROVEN as a cause of a late TIMELINE: a track's `firstSeen` and its
|
|
11
|
+
* first position are the CANDIDATE's first frame, not the confirmation's.
|
|
12
|
+
* Verified on `d035f251` (device 3829): first position == `firstSeen`, with
|
|
13
|
+
* confirmation 2 163 ms later.
|
|
14
|
+
* - the detector simply not firing until the subject is well into the scene.
|
|
15
|
+
* Unmeasured, and the reason this table exists.
|
|
16
|
+
*
|
|
17
|
+
* A second, real defect is also unquantified. The deferred-birth re-offer in
|
|
18
|
+
* `index.ts` takes the track from `result.tracked` with NO `matchedThisFrame`
|
|
19
|
+
* check, so a birth can be CONFIRMED on a frame the subject was never observed
|
|
20
|
+
* in. D379's carried birth evidence means some of those confirmations rest on a
|
|
21
|
+
* real observation of the birth instant anyway — and how often is exactly what
|
|
22
|
+
* nobody knows. {@link BirthDecisionRecord.decidedOnCoastedFrame} and
|
|
23
|
+
* {@link BirthDecisionRecord.decidedByBirthEvidence} are the two columns that
|
|
24
|
+
* answer it together.
|
|
25
|
+
*
|
|
26
|
+
* ── Why a TABLE and not a log line ─────────────────────────────────────────
|
|
27
|
+
* `logs.query` is an in-memory ring. Measured on the live hub on 2026-09-08 it
|
|
28
|
+
* held 40 000 entries covering 38 minutes — the whole ring is under an hour of
|
|
29
|
+
* fleet traffic. Every question this data is for ("how often, on camera 617,
|
|
30
|
+
* over the week the operator complained about") outlives that ring by two
|
|
31
|
+
* orders of magnitude, and a previous investigation in this repo was blocked
|
|
32
|
+
* for precisely this reason. The gate ALREADY writes a log line per decision
|
|
33
|
+
* (`confirmation gate: birth confirmed/suppressed/undecided`); adding a
|
|
34
|
+
* fourteenth field to it would answer nothing a day later.
|
|
35
|
+
*
|
|
36
|
+
* This is a MEASUREMENT table. It changes no behaviour, gates nothing, and
|
|
37
|
+
* nothing reads it on the frame path.
|
|
38
|
+
*/
|
|
39
|
+
import { z } from 'zod';
|
|
40
|
+
/**
|
|
41
|
+
* How many birth decisions the cluster keeps, across every camera.
|
|
42
|
+
*
|
|
43
|
+
* Sized off a MEASURED rate, not a guess. Fleet-wide on the live hub,
|
|
44
|
+
* 2026-09-08 20:16 local, over the 38 minutes the log ring covered: 17 `track
|
|
45
|
+
* started` + 14 `birth suppressed — track record retracted` = 31 decided
|
|
46
|
+
* births, i.e. ~49/hour, ~1 200/day. Call a busy daytime hour five times that
|
|
47
|
+
* and the fleet writes ~6 000 rows/day.
|
|
48
|
+
*
|
|
49
|
+
* 30 000 rows is therefore ~25 days at the measured rate and ~5 days at five
|
|
50
|
+
* times it — comfortably past "a few days of traffic", which is the bar the
|
|
51
|
+
* operator's week-long complaint sets. At ~200 bytes a row the ceiling is
|
|
52
|
+
* ~6 MB, against a `tracks` table measured at 4.6 MB for a single 501-row page.
|
|
53
|
+
*
|
|
54
|
+
* A COUNT and not an age, for the same reason as the debug-note archive: the
|
|
55
|
+
* denominator of a miss rate is only meaningful over whatever window the table
|
|
56
|
+
* actually holds, and a quiet fleet should keep more of it, not less. Trimmed
|
|
57
|
+
* oldest-first on append.
|
|
58
|
+
*/
|
|
59
|
+
export declare const MAX_BIRTH_DECISION_RECORDS = 30000;
|
|
60
|
+
/** Default page size for `listBirthDecisions` when the caller omits one. */
|
|
61
|
+
export declare const BIRTH_DECISION_DEFAULT_LIMIT = 500;
|
|
62
|
+
/**
|
|
63
|
+
* How stale a motion onset may be and still be offered as the birth-latency
|
|
64
|
+
* proxy. Beyond this the row records `null`, never a large number.
|
|
65
|
+
*
|
|
66
|
+
* 60 s is one order of magnitude above the latency being measured (the
|
|
67
|
+
* complaint is "seconds late") and one below the duration of a busy scene's
|
|
68
|
+
* continuous motion burst, where the onset is minutes old and says nothing
|
|
69
|
+
* about THIS subject. See {@link BirthDecisionRecord.birthLatencyMs} for the
|
|
70
|
+
* full error bars.
|
|
71
|
+
*/
|
|
72
|
+
export declare const MAX_BIRTH_LATENCY_PROXY_MS = 60000;
|
|
73
|
+
/**
|
|
74
|
+
* What the gate decided about a birth, from the CALLER's point of view.
|
|
75
|
+
*
|
|
76
|
+
* Deliberately not `ConfirmationVerdict`: `undecided` is not a birth decision
|
|
77
|
+
* at all — it is a deferral, and the row is written when the deferral ENDS.
|
|
78
|
+
* The third member is the one the gate's own type cannot express, because
|
|
79
|
+
* exhaustion is a property of how long the caller waited.
|
|
80
|
+
*/
|
|
81
|
+
export declare const BirthDecisionVerdictSchema: z.ZodEnum<{
|
|
82
|
+
confirmed: "confirmed";
|
|
83
|
+
suppressed: "suppressed";
|
|
84
|
+
"exhausted-fallback": "exhausted-fallback";
|
|
85
|
+
}>;
|
|
86
|
+
export type BirthDecisionVerdict = z.infer<typeof BirthDecisionVerdictSchema>;
|
|
87
|
+
/** One birth decision, as it is kept. */
|
|
88
|
+
export declare const BirthDecisionRecordSchema: z.ZodObject<{
|
|
89
|
+
id: z.ZodString;
|
|
90
|
+
at: z.ZodNumber;
|
|
91
|
+
deviceId: z.ZodNumber;
|
|
92
|
+
sourceTrackId: z.ZodString;
|
|
93
|
+
className: z.ZodString;
|
|
94
|
+
verdict: z.ZodEnum<{
|
|
95
|
+
confirmed: "confirmed";
|
|
96
|
+
suppressed: "suppressed";
|
|
97
|
+
"exhausted-fallback": "exhausted-fallback";
|
|
98
|
+
}>;
|
|
99
|
+
reason: z.ZodNullable<z.ZodString>;
|
|
100
|
+
attempts: z.ZodNumber;
|
|
101
|
+
deferredForMs: z.ZodNumber;
|
|
102
|
+
decidedOnCoastedFrame: z.ZodBoolean;
|
|
103
|
+
birthEvidenceAvailable: z.ZodBoolean;
|
|
104
|
+
decidedByBirthEvidence: z.ZodBoolean;
|
|
105
|
+
bestScore: z.ZodNullable<z.ZodNumber>;
|
|
106
|
+
appliedMinConfidence: z.ZodNullable<z.ZodNumber>;
|
|
107
|
+
firstSeen: z.ZodNullable<z.ZodNumber>;
|
|
108
|
+
motionOnsetAt: z.ZodNullable<z.ZodNumber>;
|
|
109
|
+
birthLatencyMs: z.ZodNullable<z.ZodNumber>;
|
|
110
|
+
birthIndexInBurst: z.ZodNullable<z.ZodNumber>;
|
|
111
|
+
}, z.core.$strip>;
|
|
112
|
+
export type BirthDecisionRecord = z.infer<typeof BirthDecisionRecordSchema>;
|
|
113
|
+
/** Query input for `listBirthDecisions` — newest first, one camera or all. */
|
|
114
|
+
export declare const BirthDecisionQueryInputSchema: z.ZodObject<{
|
|
115
|
+
deviceId: z.ZodOptional<z.ZodNumber>;
|
|
116
|
+
since: z.ZodOptional<z.ZodNumber>;
|
|
117
|
+
verdict: z.ZodOptional<z.ZodEnum<{
|
|
118
|
+
confirmed: "confirmed";
|
|
119
|
+
suppressed: "suppressed";
|
|
120
|
+
"exhausted-fallback": "exhausted-fallback";
|
|
121
|
+
}>>;
|
|
122
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
123
|
+
}, z.core.$strip>;
|
|
124
|
+
export type BirthDecisionQueryInput = z.infer<typeof BirthDecisionQueryInputSchema>;
|
|
@@ -83,6 +83,15 @@ export interface RunnerCameraConfig {
|
|
|
83
83
|
* to disable the dynamic analyzer for this camera.
|
|
84
84
|
*/
|
|
85
85
|
readonly onboardMotionDrivesAnalyzer: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Infer the session's PRE-ROLL — the retained history the restreamer replays
|
|
88
|
+
* at session open — instead of decoding it and discarding it. Mirrors
|
|
89
|
+
* `RunnerCameraConfigSchema.preRollInferenceEnabled` (default true; see the
|
|
90
|
+
* schema for why the default is the argument).
|
|
91
|
+
*/
|
|
92
|
+
readonly preRollInferenceEnabled: boolean;
|
|
93
|
+
/** Frames one pre-roll catch-up burst may send to inference. `0` disables it. */
|
|
94
|
+
readonly preRollInferenceFrames: number;
|
|
86
95
|
/** Master toggle — when false the occupancy recheck never arms (default). */
|
|
87
96
|
readonly occupancyRecheckEnabled: boolean;
|
|
88
97
|
/** Seconds between occupancy re-check bursts in watching phase. */
|
|
@@ -149,6 +149,18 @@ export interface DecodedFrame {
|
|
|
149
149
|
readonly capturedAt?: number;
|
|
150
150
|
/** Process-local lazy source. Present with an empty `data` buffer on the co-located path. */
|
|
151
151
|
readonly frameRef?: FrameRef;
|
|
152
|
+
/**
|
|
153
|
+
* True when this frame came out of a session's PRE-ROLL catch-up burst —
|
|
154
|
+
* retained history replayed at session open rather than live footage.
|
|
155
|
+
*
|
|
156
|
+
* It exists so a consumer can ROUTE the frame, not merely label it: history
|
|
157
|
+
* belongs in the runner's bounded pre-roll lane (FIFO, drained strictly
|
|
158
|
+
* behind live), never in the latest-only live detection queue, which would
|
|
159
|
+
* collapse a whole burst to its newest frame. A frame carrying this ALWAYS
|
|
160
|
+
* carries a `capturedAt` measured on the session media clock, not a fresh
|
|
161
|
+
* wall clock.
|
|
162
|
+
*/
|
|
163
|
+
readonly preRoll?: boolean;
|
|
152
164
|
}
|
|
153
165
|
export interface DecodedAudioChunk {
|
|
154
166
|
readonly data: Buffer;
|
|
@@ -446,4 +458,12 @@ export interface CameraDetectionConfig {
|
|
|
446
458
|
readonly occupancyRecheckEnabled: boolean;
|
|
447
459
|
readonly occupancyRecheckSec: number;
|
|
448
460
|
readonly occupancyRecheckFrames: number;
|
|
461
|
+
/**
|
|
462
|
+
* Whether the session's already-decoded PRE-ROLL is inferred rather than
|
|
463
|
+
* dropped as stale, and how many of its frames the catch-up burst may spend
|
|
464
|
+
* (D411). Carried here because the orchestrator resolves it per camera and
|
|
465
|
+
* the runner is the one that spends it.
|
|
466
|
+
*/
|
|
467
|
+
readonly preRollInferenceEnabled: boolean;
|
|
468
|
+
readonly preRollInferenceFrames: number;
|
|
449
469
|
}
|
|
@@ -3519,6 +3519,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3519
3519
|
deleteTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteTracks", "mutation", input),
|
|
3520
3520
|
setTrackFlags: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "setTrackFlags", "mutation", input),
|
|
3521
3521
|
listArchivedDebugNotes: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listArchivedDebugNotes", "query", input),
|
|
3522
|
+
listBirthDecisions: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listBirthDecisions", "query", input),
|
|
3522
3523
|
getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
|
|
3523
3524
|
getEventMediaFootprintByKind: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMediaFootprintByKind", "query", input),
|
|
3524
3525
|
pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
|
|
@@ -3519,6 +3519,7 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3519
3519
|
deleteTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "deleteTracks", "mutation", input),
|
|
3520
3520
|
setTrackFlags: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "setTrackFlags", "mutation", input),
|
|
3521
3521
|
listArchivedDebugNotes: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listArchivedDebugNotes", "query", input),
|
|
3522
|
+
listBirthDecisions: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listBirthDecisions", "query", input),
|
|
3522
3523
|
getEventStoreFootprint: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventStoreFootprint", "query", input),
|
|
3523
3524
|
getEventMediaFootprintByKind: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventMediaFootprintByKind", "query", input),
|
|
3524
3525
|
pruneEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEvents", "mutation", input),
|