@camstack/types 1.2.307 → 1.2.309

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 (34) hide show
  1. package/dist/capabilities/custom-model-registry.cap.d.ts +38 -4
  2. package/dist/capabilities/device-manager.cap.d.ts +8 -8
  3. package/dist/capabilities/hub-address.d.ts +76 -0
  4. package/dist/capabilities/index.d.ts +4 -3
  5. package/dist/capabilities/local-network.cap.d.ts +93 -0
  6. package/dist/capabilities/model-convert.cap.d.ts +19 -2
  7. package/dist/capabilities/model-distributor.cap.d.ts +38 -4
  8. package/dist/capabilities/pipeline-executor.cap.d.ts +124 -10
  9. package/dist/capabilities/pipeline-runner.cap.d.ts +13 -0
  10. package/dist/catalogs/frigate-plus-classmap.d.ts +10 -7
  11. package/dist/catalogs/index.d.ts +1 -1
  12. package/dist/catalogs/root-model-supply.d.ts +202 -0
  13. package/dist/client.js +51 -49
  14. package/dist/client.mjs +51 -49
  15. package/dist/device/location-icon.d.ts +4 -4
  16. package/dist/device/site-zone.d.ts +2 -2
  17. package/dist/ffmpeg/pinned-spawn.d.ts +1 -1
  18. package/dist/generated/addon-api.d.ts +14 -0
  19. package/dist/generated/method-access-map.d.ts +1 -1
  20. package/dist/generated/system-proxy.d.ts +1 -1
  21. package/dist/index.d.ts +3 -1
  22. package/dist/index.js +1002 -512
  23. package/dist/index.mjs +970 -500
  24. package/dist/interfaces/event-bus.d.ts +12 -6
  25. package/dist/interfaces/pipeline-executor-capability.d.ts +6 -1
  26. package/dist/node.js +1 -1
  27. package/dist/node.mjs +1 -1
  28. package/dist/pipeline/removed-model-ids.d.ts +20 -0
  29. package/dist/pipeline/root-face-crop.d.ts +31 -0
  30. package/dist/types/detection.d.ts +9 -0
  31. package/dist/types/models.d.ts +69 -8
  32. package/dist/types/pipeline-step.d.ts +6 -0
  33. package/package.json +1 -1
  34. package/dist/catalogs/classifier-fill.d.ts +0 -104
@@ -344,14 +344,20 @@ export interface DetailStepAnnounce {
344
344
  readonly inputClasses: readonly string[];
345
345
  readonly cadence: StepCadence;
346
346
  /**
347
- * The root model that already fills this step for this camera (D715): the
348
- * model declares the fill and the step's `labelLink` policy lets it be
349
- * skipped. A consumer does not dispatch the step for a track whose detection
350
- * carries the linked label (`detector-link:<stepId>`); a track without one
351
- * (a class the detector cannot name) still gets the step. Absent ⇒ the step
352
- * runs as before.
347
+ * The root model that SUPPLIES this step for this camera (D730): the root
348
+ * declares it and the step's `useRootModel` flag is on — `resolveRootSupply`
349
+ * says effective. Absent ⇒ the step runs as before.
353
350
  */
354
351
  readonly filledBy?: string;
352
+ /**
353
+ * How the root supplies it, present with `filledBy`.
354
+ * - `label`: the root's linked label IS the answer — never dispatched.
355
+ * - `crop`: the root drew the step's box; the dispatcher sends the box to
356
+ * the step's served children (`rootSupplyServes`) and never infers the
357
+ * step itself. A step none of whose children are served is not dispatched.
358
+ * A consumer that predates the field reads `filledBy` alone.
359
+ */
360
+ readonly filledAs?: 'label' | 'crop';
355
361
  }
356
362
  /**
357
363
  * Raw inference output emitted by `addon-pipeline-runner` per detection
@@ -9,7 +9,7 @@ import type { FrameResult } from '../types/detection.js';
9
9
  import type { ConfigUISchema } from './config-ui.js';
10
10
  import type { InferenceCapabilities } from './inference-capabilities.js';
11
11
  import type { IAddonResolver } from './pipeline-runner.js';
12
- import { PipelineStepInputSchema, type EngineProvisioning, type NativeCropRef, type PipelineValidationResult } from '../capabilities/pipeline-executor.cap.js';
12
+ import { PipelineStepInputSchema, type EngineProvisioning, type NativeCropRef, type PipelineValidationResult, type SuppliedRootOutput } from '../capabilities/pipeline-executor.cap.js';
13
13
  import type { z } from 'zod';
14
14
  /**
15
15
  * Step configuration for pipeline execution — no runtime/backend (comes
@@ -87,6 +87,11 @@ export interface PipelineRunInput {
87
87
  * mutually-exclusive image inputs. Absent ⇒ tile-crop children.
88
88
  */
89
89
  readonly nativeCropRef?: NativeCropRef;
90
+ /**
91
+ * Root-supplied output for the tree's ROOT step (D730) — that step is not
92
+ * inferred; see `pipelineExecutor.runPipeline.suppliedRoot`.
93
+ */
94
+ readonly suppliedRoot?: SuppliedRootOutput;
90
95
  /**
91
96
  * Offline REPLAY of stored media for `deviceId` (D56, D646). The call runs
92
97
  * the camera's structure — its detection-stage zone gate and per-device
package/dist/node.js CHANGED
@@ -1385,7 +1385,7 @@ var FfmpegProcess = class {
1385
1385
  * Node-only (`node:child_process`), so it lives under `@camstack/types/node`.
1386
1386
  */
1387
1387
  /** The detail a site refusing for want of a binary puts in its refusal. */
1388
- var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node (D540)";
1388
+ var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node";
1389
1389
  /**
1390
1390
  * {@link pinnedFfmpegSpawner}, asked at the point of use through the node's
1391
1391
  * resolver (`memoizePinnedFfmpeg`). A site that keeps the RESOLVER rather than
package/dist/node.mjs CHANGED
@@ -1362,7 +1362,7 @@ var FfmpegProcess = class {
1362
1362
  * Node-only (`node:child_process`), so it lives under `@camstack/types/node`.
1363
1363
  */
1364
1364
  /** The detail a site refusing for want of a binary puts in its refusal. */
1365
- var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node (D540)";
1365
+ var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node";
1366
1366
  /**
1367
1367
  * {@link pinnedFfmpegSpawner}, asked at the point of use through the node's
1368
1368
  * resolver (`memoizePinnedFfmpeg`). A site that keeps the RESOLVER rather than
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Model ids DELETED from a step's catalog (D703, D710, D719), per step — and
3
+ * the one question asked of them: is a stored pin to this id a pin to a model
4
+ * that no longer exists? (D725)
5
+ *
6
+ * This is NOT a resolver input. `resolveModelForFormat` still returns an
7
+ * unknown id unchanged (a custom model), and a bulk pass pinned to one still
8
+ * refuses rather than substitutes (D54). The ONE reader is the orchestrator's
9
+ * stored-pin reset (`removed-model-pin-reset.ts`), which clears such a pin from
10
+ * the store so the step follows its default again — unless a registered custom
11
+ * model carries the same id.
12
+ *
13
+ * `removed-model-ids.spec.ts` (addon-pipeline) pins that every id here is
14
+ * really absent from its step's catalog. A model deleted from a catalog is
15
+ * added here in the same change, or its stored pins stay behind as custom ids.
16
+ */
17
+ /** `stepId → ids deleted from that step's catalog`. */
18
+ export declare const REMOVED_MODEL_IDS: Readonly<Record<string, readonly string[]>>;
19
+ /** True when `modelId` was deleted from `stepId`'s catalog. */
20
+ export declare function isRemovedModelId(stepId: string, modelId: string): boolean;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The ONE face-scoped crop of a root-supplied face (D731): the rectangle a
3
+ * root model's `face` box is refined in before it can be recognised.
4
+ *
5
+ * A root face box (a Frigate+ `face`) carries no landmarks, and an unaligned
6
+ * crop must never reach the face embedder (D52: one vector index, one crop
7
+ * derivation — and the face gallery's derivation is the landmark alignment).
8
+ * So the box is only a LOCATION: a square around it is cut from the frame's
9
+ * native surface, the face detector re-finds the face in it — with landmarks —
10
+ * and the existing alignment takes it from there.
11
+ *
12
+ * This is not the detail/CLIP convention (`deriveDetailCropRect`): that one
13
+ * pads a SUBJECT for an embedder; this one frames a FACE for a detector, at a
14
+ * scale the detector was measured to find faces at.
15
+ */
16
+ import type { DetailCropRect } from './detail-crop.js';
17
+ /** Side of the square, as a multiple of the face box's longer side. */
18
+ export declare const ROOT_FACE_REFINE_SCALE = 1.6;
19
+ /**
20
+ * The input the face detector sees the square at, in pixels. A face that
21
+ * fills ~60% of a 160 px input is in the detector's measured sweet spot; the
22
+ * same square fed at 640 puts a ~400 px face in front of a detector whose
23
+ * largest anchors are far smaller.
24
+ */
25
+ export declare const ROOT_FACE_REFINE_INPUT_PX = 160;
26
+ /**
27
+ * The square (frame-space pixels) a root face box is refined in: centred on
28
+ * the box, side `ROOT_FACE_REFINE_SCALE ×` its longer side, slid inside the
29
+ * frame, and shrunk only when the frame's shorter side is smaller. Pure.
30
+ */
31
+ export declare function deriveRootFaceRefineRect(face: DetailCropRect, frameWidth: number, frameHeight: number): DetailCropRect;
@@ -369,6 +369,15 @@ export interface ObjectDetection extends DetectionBase {
369
369
  * person box (or a plate back to the vehicle box).
370
370
  */
371
371
  readonly parentId?: string;
372
+ /**
373
+ * A `detail` the ROOT model drew (D730): a Frigate+ `license_plate` / `face`
374
+ * box contained in its parent, standing in for the named crop step's
375
+ * inference. Never a track (D683) — only `first-level` entries are.
376
+ */
377
+ readonly rootSupplied?: {
378
+ readonly stepId: string;
379
+ readonly modelId: string;
380
+ };
372
381
  /**
373
382
  * Normalized (L2, ||v||=1) face/biometric embedding produced by an
374
383
  * in-pipeline embedding step (arcface, `inputClasses:['face']`). Present on
@@ -183,8 +183,19 @@ export declare const ModelLicenseSchema: z.ZodPreprocess<z.ZodObject<{
183
183
  nonCommercial: z.ZodOptional<z.ZodBoolean>;
184
184
  }, z.core.$strip>>;
185
185
  export type ModelLicense = z.infer<typeof ModelLicenseSchema>;
186
- /** One `fillsClassifierEffects` entry — see `ModelCatalogEntry.fillsClassifierEffects`. */
187
- export declare const FillsClassifierEffectSchema: z.ZodObject<{
186
+ /**
187
+ * One step a ROOT detector can supply from its own output (D730) — see
188
+ * `ModelCatalogEntry.suppliesSteps`.
189
+ *
190
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
191
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
192
+ * the root cannot produce (shown as unavailable, never a blocker).
193
+ * - `crop`: the root draws the box the step would have found (`license_plate`
194
+ * for plate-detection, `face` for face-detection). The box becomes a detail
195
+ * child of the `parentMacro` detection that contains it — never a track.
196
+ */
197
+ export declare const RootStepSupplySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
198
+ kind: z.ZodLiteral<"label">;
188
199
  stepId: z.ZodEnum<{
189
200
  "animal-classifier": "animal-classifier";
190
201
  "vehicle-classifier": "vehicle-classifier";
@@ -192,8 +203,24 @@ export declare const FillsClassifierEffectSchema: z.ZodObject<{
192
203
  }>;
193
204
  labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
194
205
  uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
195
- }, z.core.$strip>;
196
- export type FillsClassifierEffect = z.infer<typeof FillsClassifierEffectSchema>;
206
+ }, z.core.$strip>, z.ZodObject<{
207
+ kind: z.ZodLiteral<"crop">;
208
+ stepId: z.ZodEnum<{
209
+ "plate-detection": "plate-detection";
210
+ "face-detection": "face-detection";
211
+ }>;
212
+ rootLabels: z.ZodReadonly<z.ZodArray<z.ZodString>>;
213
+ parentMacro: z.ZodEnum<{
214
+ person: "person";
215
+ vehicle: "vehicle";
216
+ }>;
217
+ childClass: z.ZodEnum<{
218
+ face: "face";
219
+ plate: "plate";
220
+ }>;
221
+ rootInputPx: z.ZodOptional<z.ZodNumber>;
222
+ }, z.core.$strip>], "kind">;
223
+ export type RootStepSupply = z.infer<typeof RootStepSupplySchema>;
197
224
  export declare const ModelCatalogEntrySchema: z.ZodObject<{
198
225
  id: z.ZodString;
199
226
  name: z.ZodString;
@@ -344,7 +371,8 @@ export declare const ModelCatalogEntrySchema: z.ZodObject<{
344
371
  }>>;
345
372
  preserveOriginal: z.ZodBoolean;
346
373
  }, z.core.$strip>>;
347
- fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
374
+ suppliesSteps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
375
+ kind: z.ZodLiteral<"label">;
348
376
  stepId: z.ZodEnum<{
349
377
  "animal-classifier": "animal-classifier";
350
378
  "vehicle-classifier": "vehicle-classifier";
@@ -352,7 +380,23 @@ export declare const ModelCatalogEntrySchema: z.ZodObject<{
352
380
  }>;
353
381
  labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
354
382
  uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
355
- }, z.core.$strip>>>>;
383
+ }, z.core.$strip>, z.ZodObject<{
384
+ kind: z.ZodLiteral<"crop">;
385
+ stepId: z.ZodEnum<{
386
+ "plate-detection": "plate-detection";
387
+ "face-detection": "face-detection";
388
+ }>;
389
+ rootLabels: z.ZodReadonly<z.ZodArray<z.ZodString>>;
390
+ parentMacro: z.ZodEnum<{
391
+ person: "person";
392
+ vehicle: "vehicle";
393
+ }>;
394
+ childClass: z.ZodEnum<{
395
+ face: "face";
396
+ plate: "plate";
397
+ }>;
398
+ rootInputPx: z.ZodOptional<z.ZodNumber>;
399
+ }, z.core.$strip>], "kind">>>>;
356
400
  clip: z.ZodOptional<z.ZodObject<{
357
401
  textModelId: z.ZodString;
358
402
  embeddingDim: z.ZodNumber;
@@ -625,7 +669,8 @@ export declare const ConvertResultSchema: z.ZodObject<{
625
669
  }>>;
626
670
  preserveOriginal: z.ZodBoolean;
627
671
  }, z.core.$strip>>;
628
- fillsClassifierEffects: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodObject<{
672
+ suppliesSteps: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
673
+ kind: z.ZodLiteral<"label">;
629
674
  stepId: z.ZodEnum<{
630
675
  "animal-classifier": "animal-classifier";
631
676
  "vehicle-classifier": "vehicle-classifier";
@@ -633,7 +678,23 @@ export declare const ConvertResultSchema: z.ZodObject<{
633
678
  }>;
634
679
  labelToEffect: z.ZodRecord<z.ZodString, z.ZodString>;
635
680
  uncovered: z.ZodReadonly<z.ZodArray<z.ZodString>>;
636
- }, z.core.$strip>>>>;
681
+ }, z.core.$strip>, z.ZodObject<{
682
+ kind: z.ZodLiteral<"crop">;
683
+ stepId: z.ZodEnum<{
684
+ "plate-detection": "plate-detection";
685
+ "face-detection": "face-detection";
686
+ }>;
687
+ rootLabels: z.ZodReadonly<z.ZodArray<z.ZodString>>;
688
+ parentMacro: z.ZodEnum<{
689
+ person: "person";
690
+ vehicle: "vehicle";
691
+ }>;
692
+ childClass: z.ZodEnum<{
693
+ face: "face";
694
+ plate: "plate";
695
+ }>;
696
+ rootInputPx: z.ZodOptional<z.ZodNumber>;
697
+ }, z.core.$strip>], "kind">>>>;
637
698
  clip: z.ZodOptional<z.ZodObject<{
638
699
  textModelId: z.ZodString;
639
700
  embeddingDim: z.ZodNumber;
@@ -3,6 +3,7 @@ import type { StepModelScope } from '../pipeline/cluster-model-scope.js';
3
3
  import type { ClassMapDefinition } from './labels.js';
4
4
  import type { ModelCatalogEntry } from './models.js';
5
5
  import type { PipelineSlot } from './pipeline.js';
6
+ import type { SuppliedRootOutput } from '../capabilities/pipeline-executor.cap.js';
6
7
  /**
7
8
  * Each pipeline step implements this interface as a class.
8
9
  * `definition` holds the static metadata; `getConfigSchema()` declares
@@ -366,6 +367,11 @@ export interface PipelineRunOptions {
366
367
  readonly traceVerbosity?: TraceVerbosity;
367
368
  readonly plane?: PipelineExecutionPlane;
368
369
  readonly occasion?: PipelineRunOccasion;
370
+ /**
371
+ * Root-supplied output for a crop-kind root step (D730,
372
+ * `pipelineExecutor.runPipeline.suppliedRoot`): that step is not inferred.
373
+ */
374
+ readonly suppliedRoot?: SuppliedRootOutput;
369
375
  }
370
376
  export interface StepTrace {
371
377
  readonly stepId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.307",
3
+ "version": "1.2.309",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",
@@ -1,104 +0,0 @@
1
- /**
2
- * Detector ↔ step label link — the ONE place that says which pipeline steps a
3
- * root detector can stand in for, in whose vocabulary, and who writes tier 1.
4
- *
5
- * A Frigate+ detector already emits `deer`, `car`, `package`: the effect
6
- * `animal-classifier`, `vehicle-classifier` and `package-detection` exist to
7
- * produce. The model DECLARES that (`ModelCatalogEntry.fillsClassifierEffects`,
8
- * derived here from its labelmap), and the step's own `labelLink` policy says
9
- * whether the declaration is honoured. Pure — no I/O, no clock.
10
- */
11
- import type { FillsClassifierEffect, ModelCatalogEntry } from '../types/models.js';
12
- /** Steps a root detector may declare it fills. */
13
- export declare const FILLABLE_STEP_IDS: readonly ["animal-classifier", "vehicle-classifier", "package-detection"];
14
- export type FillableStepId = (typeof FILLABLE_STEP_IDS)[number];
15
- /** Narrow a step id to a fillable one — type guard, not a cast. */
16
- export declare function isFillableStepId(value: string): value is FillableStepId;
17
- /**
18
- * The EFFECT vocabulary of each fillable step: exactly the strings the step
19
- * itself emits, in its own spelling. A linked label is one of these and nothing
20
- * else, so a tier-1 value means the same thing whichever writer produced it.
21
- *
22
- * - `animal-classifier`: the PRIMARY model's `-labels.json` (Open Images V7,
23
- * 8 classes) — also the species allow-list the step offers.
24
- * - `vehicle-classifier`: `vehicle-type-v1-labels.json`, capitalised as the
25
- * model emits them (the classifier writes `winner.class` verbatim).
26
- * - `package-detection`: its one output class.
27
- *
28
- * `scripts/check-label-link-vocabulary.ts` fails the build if a model entry's
29
- * `labelToEffect` names anything outside this table.
30
- */
31
- export declare const FILLABLE_STEP_VOCABULARIES: Readonly<Record<FillableStepId, readonly string[]>>;
32
- /** The macro a detection must carry for the step to apply to it. */
33
- export declare const FILLABLE_STEP_MACRO: Readonly<Record<FillableStepId, string>>;
34
- /** The policy values of a step's `labelLink` setting. */
35
- export declare const LABEL_LINK_POLICIES: readonly ["run", "skip-when-filled"];
36
- export type LabelLinkPolicy = (typeof LABEL_LINK_POLICIES)[number];
37
- /** Absent setting ⇒ this. It changes nothing unless the root model declares a fill. */
38
- export declare const DEFAULT_LABEL_LINK_POLICY: LabelLinkPolicy;
39
- /** The step-settings key the policy is stored under (DeviceStepConfig.settings). */
40
- export declare const LABEL_LINK_SETTING_KEY = "labelLink";
41
- /** One fill a root model declares — the catalog schema's own type. */
42
- export type ClassifierFillDeclaration = FillsClassifierEffect;
43
- /** `ScoredLabel.stepId` prefix of a label the detector wrote for a step. */
44
- export declare const LINKED_LABEL_STEP_PREFIX = "detector-link:";
45
- /** `detector-link:<stepId>` — the attribution of a linked label. */
46
- export declare function linkedLabelStepId(stepId: FillableStepId): string;
47
- /** The step a linked label stands in for, or `undefined` for any other attribution. */
48
- export declare function linkedStepOf(attributionStepId: string | undefined): FillableStepId | undefined;
49
- /**
50
- * A labelmap is COCO when it carries at least half of the COCO-80 classes. A
51
- * COCO detector NEVER fills a step (operator decision, D715): its `dog` / `car`
52
- * is the generic class the classifier exists to refine, and its six animal
53
- * classes would otherwise read as "fills animal-classifier 6/8". Frigate+
54
- * shares about a dozen COCO names; a COCO-80 or COCO-91 labelmap carries ~80.
55
- */
56
- export declare function isCocoLabelmap(labels: readonly string[]): boolean;
57
- /**
58
- * Which steps a root detector fills, from its labelmap and classMap. A label
59
- * counts for a step only when the model's classMap sends it to that step's
60
- * macro AND it names a vocabulary entry. A step none of the labels reach is
61
- * not declared; a COCO labelmap declares nothing.
62
- */
63
- export declare function deriveClassifierFills(labels: readonly string[], classMap: {
64
- readonly mapping: Readonly<Record<string, string>>;
65
- } | undefined): readonly ClassifierFillDeclaration[];
66
- /** The fill a model declares for one step, if any. */
67
- export declare function fillFor(entry: Pick<ModelCatalogEntry, 'fillsClassifierEffects'> | undefined, stepId: FillableStepId): ClassifierFillDeclaration | undefined;
68
- /** Read the `labelLink` policy off a step's settings bag; anything else ⇒ the default. */
69
- export declare function readLabelLinkPolicy(settings: Readonly<Record<string, unknown>> | undefined): LabelLinkPolicy;
70
- /** The configured step the decision is about, as the attach tree carries it. */
71
- export interface LinkedStepState {
72
- readonly enabled: boolean;
73
- readonly settings?: Readonly<Record<string, unknown>>;
74
- }
75
- /** Who writes the step's effect for this camera. */
76
- export interface LabelLinkDecision {
77
- /**
78
- * The detector is the ONE writer of this effect: its linked label carries
79
- * the detection's score. Otherwise it is written at score 0, a fallback any
80
- * scored answer of the step outranks.
81
- */
82
- readonly authoritative: boolean;
83
- /** The step is configured to run and must NOT be dispatched. */
84
- readonly skip: boolean;
85
- readonly policy: LabelLinkPolicy;
86
- /**
87
- * Vocabulary entries the detector cannot produce that the step's
88
- * `enabledClasses` still asks for (empty allow-list = all). The skip waits
89
- * until the operator switches every one of them off.
90
- */
91
- readonly openGaps: readonly string[];
92
- }
93
- /**
94
- * Decide the writer of one filled effect for one camera.
95
- *
96
- * - The step is not running (disabled, or not in the camera's tree): the
97
- * detector is the only writer — authoritative, nothing to skip.
98
- * - The step runs, the policy is `skip-when-filled` and every coverage gap is
99
- * switched off in `enabledClasses`: the detector is authoritative and the
100
- * step is skipped.
101
- * - Otherwise the step runs and is the writer; the linked label is a score-0
102
- * fallback.
103
- */
104
- export declare function resolveLabelLink(fill: ClassifierFillDeclaration, step: LinkedStepState | undefined): LabelLinkDecision;