@camstack/types 1.2.69 → 1.2.70

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.
@@ -951,6 +951,7 @@ export declare const NcRuleInputSchema: z.ZodObject<{
951
951
  }>>;
952
952
  maxImagePx: z.ZodDefault<z.ZodNumber>;
953
953
  }, z.core.$strip>>;
954
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
954
955
  }, z.core.$strip>;
955
956
  export type NcRuleInput = z.infer<typeof NcRuleInputSchema>;
956
957
  /**
@@ -1056,6 +1057,7 @@ export declare const NcRulePatchSchema: z.ZodObject<{
1056
1057
  }>>;
1057
1058
  maxImagePx: z.ZodDefault<z.ZodNumber>;
1058
1059
  }, z.core.$strip>>>;
1060
+ waitForEnhancement: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
1059
1061
  disabledTargetIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1060
1062
  enabled: z.ZodOptional<z.ZodBoolean>;
1061
1063
  conditions: z.ZodOptional<z.ZodObject<{
@@ -1426,6 +1428,7 @@ export declare const NcRuleSchema: z.ZodObject<{
1426
1428
  }>>;
1427
1429
  maxImagePx: z.ZodDefault<z.ZodNumber>;
1428
1430
  }, z.core.$strip>>;
1431
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
1429
1432
  id: z.ZodString;
1430
1433
  createdBy: z.ZodString;
1431
1434
  createdAt: z.ZodNumber;
@@ -2083,6 +2086,7 @@ export declare const notificationRulesCapability: {
2083
2086
  }>>;
2084
2087
  maxImagePx: z.ZodDefault<z.ZodNumber>;
2085
2088
  }, z.core.$strip>>;
2089
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
2086
2090
  id: z.ZodString;
2087
2091
  createdBy: z.ZodString;
2088
2092
  createdAt: z.ZodNumber;
@@ -2323,6 +2327,7 @@ export declare const notificationRulesCapability: {
2323
2327
  }>>;
2324
2328
  maxImagePx: z.ZodDefault<z.ZodNumber>;
2325
2329
  }, z.core.$strip>>;
2330
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
2326
2331
  id: z.ZodString;
2327
2332
  createdBy: z.ZodString;
2328
2333
  createdAt: z.ZodNumber;
@@ -2561,6 +2566,7 @@ export declare const notificationRulesCapability: {
2561
2566
  }>>;
2562
2567
  maxImagePx: z.ZodDefault<z.ZodNumber>;
2563
2568
  }, z.core.$strip>>;
2569
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
2564
2570
  }, z.core.$strip>;
2565
2571
  }, z.core.$strip>, z.ZodObject<{
2566
2572
  rule: z.ZodObject<{
@@ -2793,6 +2799,7 @@ export declare const notificationRulesCapability: {
2793
2799
  }>>;
2794
2800
  maxImagePx: z.ZodDefault<z.ZodNumber>;
2795
2801
  }, z.core.$strip>>;
2802
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
2796
2803
  id: z.ZodString;
2797
2804
  createdBy: z.ZodString;
2798
2805
  createdAt: z.ZodNumber;
@@ -2898,6 +2905,7 @@ export declare const notificationRulesCapability: {
2898
2905
  }>>;
2899
2906
  maxImagePx: z.ZodDefault<z.ZodNumber>;
2900
2907
  }, z.core.$strip>>>;
2908
+ waitForEnhancement: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
2901
2909
  disabledTargetIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
2902
2910
  enabled: z.ZodOptional<z.ZodBoolean>;
2903
2911
  conditions: z.ZodOptional<z.ZodObject<{
@@ -3267,6 +3275,7 @@ export declare const notificationRulesCapability: {
3267
3275
  }>>;
3268
3276
  maxImagePx: z.ZodDefault<z.ZodNumber>;
3269
3277
  }, z.core.$strip>>;
3278
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
3270
3279
  id: z.ZodString;
3271
3280
  createdBy: z.ZodString;
3272
3281
  createdAt: z.ZodNumber;
@@ -3553,6 +3562,7 @@ export declare const notificationRulesCapability: {
3553
3562
  }>>;
3554
3563
  maxImagePx: z.ZodDefault<z.ZodNumber>;
3555
3564
  }, z.core.$strip>>;
3565
+ waitForEnhancement: z.ZodOptional<z.ZodBoolean>;
3556
3566
  }, z.core.$strip>;
3557
3567
  lookbackMinutes: z.ZodDefault<z.ZodNumber>;
3558
3568
  }, z.core.$strip>, z.ZodObject<{
@@ -332,6 +332,7 @@ export declare const LabelAttributionSchema: z.ZodObject<{
332
332
  stepId: z.ZodString;
333
333
  modelId: z.ZodOptional<z.ZodString>;
334
334
  decidedAt: z.ZodNumber;
335
+ identityId: z.ZodOptional<z.ZodString>;
335
336
  }, z.core.$strip>;
336
337
  export type LabelAttribution = z.infer<typeof LabelAttributionSchema>;
337
338
  /** Per-camera slice of a training-export estimate. */
@@ -437,6 +438,7 @@ declare const TrackSchema: z.ZodObject<{
437
438
  stepId: z.ZodString;
438
439
  modelId: z.ZodOptional<z.ZodString>;
439
440
  decidedAt: z.ZodNumber;
441
+ identityId: z.ZodOptional<z.ZodString>;
440
442
  }, z.core.$strip>>;
441
443
  subLabel: z.ZodOptional<z.ZodString>;
442
444
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -444,6 +446,7 @@ declare const TrackSchema: z.ZodObject<{
444
446
  stepId: z.ZodString;
445
447
  modelId: z.ZodOptional<z.ZodString>;
446
448
  decidedAt: z.ZodNumber;
449
+ identityId: z.ZodOptional<z.ZodString>;
447
450
  }, z.core.$strip>>;
448
451
  trackId: z.ZodString;
449
452
  deviceId: z.ZodNumber;
@@ -557,6 +560,7 @@ declare const ObjectEventSchema: z.ZodObject<{
557
560
  stepId: z.ZodString;
558
561
  modelId: z.ZodOptional<z.ZodString>;
559
562
  decidedAt: z.ZodNumber;
563
+ identityId: z.ZodOptional<z.ZodString>;
560
564
  }, z.core.$strip>>;
561
565
  subLabel: z.ZodOptional<z.ZodString>;
562
566
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -564,6 +568,7 @@ declare const ObjectEventSchema: z.ZodObject<{
564
568
  stepId: z.ZodString;
565
569
  modelId: z.ZodOptional<z.ZodString>;
566
570
  decidedAt: z.ZodNumber;
571
+ identityId: z.ZodOptional<z.ZodString>;
567
572
  }, z.core.$strip>>;
568
573
  kind: z.ZodLiteral<"object">;
569
574
  source: z.ZodOptional<z.ZodEnum<{
@@ -1082,6 +1087,7 @@ declare const RecentTracksPageSchema: z.ZodObject<{
1082
1087
  stepId: z.ZodString;
1083
1088
  modelId: z.ZodOptional<z.ZodString>;
1084
1089
  decidedAt: z.ZodNumber;
1090
+ identityId: z.ZodOptional<z.ZodString>;
1085
1091
  }, z.core.$strip>>;
1086
1092
  subLabel: z.ZodOptional<z.ZodString>;
1087
1093
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1089,6 +1095,7 @@ declare const RecentTracksPageSchema: z.ZodObject<{
1089
1095
  stepId: z.ZodString;
1090
1096
  modelId: z.ZodOptional<z.ZodString>;
1091
1097
  decidedAt: z.ZodNumber;
1098
+ identityId: z.ZodOptional<z.ZodString>;
1092
1099
  }, z.core.$strip>>;
1093
1100
  trackId: z.ZodString;
1094
1101
  deviceId: z.ZodNumber;
@@ -1114,6 +1121,7 @@ declare const KeyEventSchema: z.ZodObject<{
1114
1121
  stepId: z.ZodString;
1115
1122
  modelId: z.ZodOptional<z.ZodString>;
1116
1123
  decidedAt: z.ZodNumber;
1124
+ identityId: z.ZodOptional<z.ZodString>;
1117
1125
  }, z.core.$strip>>;
1118
1126
  subLabel: z.ZodOptional<z.ZodString>;
1119
1127
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1121,6 +1129,7 @@ declare const KeyEventSchema: z.ZodObject<{
1121
1129
  stepId: z.ZodString;
1122
1130
  modelId: z.ZodOptional<z.ZodString>;
1123
1131
  decidedAt: z.ZodNumber;
1132
+ identityId: z.ZodOptional<z.ZodString>;
1124
1133
  }, z.core.$strip>>;
1125
1134
  id: z.ZodString;
1126
1135
  trackId: z.ZodString;
@@ -1183,6 +1192,7 @@ export declare const ScoredObjectEventSchema: z.ZodObject<{
1183
1192
  stepId: z.ZodString;
1184
1193
  modelId: z.ZodOptional<z.ZodString>;
1185
1194
  decidedAt: z.ZodNumber;
1195
+ identityId: z.ZodOptional<z.ZodString>;
1186
1196
  }, z.core.$strip>>;
1187
1197
  subLabel: z.ZodOptional<z.ZodString>;
1188
1198
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1190,6 +1200,7 @@ export declare const ScoredObjectEventSchema: z.ZodObject<{
1190
1200
  stepId: z.ZodString;
1191
1201
  modelId: z.ZodOptional<z.ZodString>;
1192
1202
  decidedAt: z.ZodNumber;
1203
+ identityId: z.ZodOptional<z.ZodString>;
1193
1204
  }, z.core.$strip>>;
1194
1205
  kind: z.ZodLiteral<"object">;
1195
1206
  source: z.ZodOptional<z.ZodEnum<{
@@ -1327,6 +1338,7 @@ export declare const pipelineAnalyticsCapability: {
1327
1338
  stepId: z.ZodString;
1328
1339
  modelId: z.ZodOptional<z.ZodString>;
1329
1340
  decidedAt: z.ZodNumber;
1341
+ identityId: z.ZodOptional<z.ZodString>;
1330
1342
  }, z.core.$strip>>;
1331
1343
  subLabel: z.ZodOptional<z.ZodString>;
1332
1344
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1334,6 +1346,7 @@ export declare const pipelineAnalyticsCapability: {
1334
1346
  stepId: z.ZodString;
1335
1347
  modelId: z.ZodOptional<z.ZodString>;
1336
1348
  decidedAt: z.ZodNumber;
1349
+ identityId: z.ZodOptional<z.ZodString>;
1337
1350
  }, z.core.$strip>>;
1338
1351
  trackId: z.ZodString;
1339
1352
  deviceId: z.ZodNumber;
@@ -1419,6 +1432,7 @@ export declare const pipelineAnalyticsCapability: {
1419
1432
  stepId: z.ZodString;
1420
1433
  modelId: z.ZodOptional<z.ZodString>;
1421
1434
  decidedAt: z.ZodNumber;
1435
+ identityId: z.ZodOptional<z.ZodString>;
1422
1436
  }, z.core.$strip>>;
1423
1437
  subLabel: z.ZodOptional<z.ZodString>;
1424
1438
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1426,6 +1440,7 @@ export declare const pipelineAnalyticsCapability: {
1426
1440
  stepId: z.ZodString;
1427
1441
  modelId: z.ZodOptional<z.ZodString>;
1428
1442
  decidedAt: z.ZodNumber;
1443
+ identityId: z.ZodOptional<z.ZodString>;
1429
1444
  }, z.core.$strip>>;
1430
1445
  trackId: z.ZodString;
1431
1446
  deviceId: z.ZodNumber;
@@ -1533,6 +1548,7 @@ export declare const pipelineAnalyticsCapability: {
1533
1548
  stepId: z.ZodString;
1534
1549
  modelId: z.ZodOptional<z.ZodString>;
1535
1550
  decidedAt: z.ZodNumber;
1551
+ identityId: z.ZodOptional<z.ZodString>;
1536
1552
  }, z.core.$strip>>;
1537
1553
  subLabel: z.ZodOptional<z.ZodString>;
1538
1554
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1540,6 +1556,7 @@ export declare const pipelineAnalyticsCapability: {
1540
1556
  stepId: z.ZodString;
1541
1557
  modelId: z.ZodOptional<z.ZodString>;
1542
1558
  decidedAt: z.ZodNumber;
1559
+ identityId: z.ZodOptional<z.ZodString>;
1543
1560
  }, z.core.$strip>>;
1544
1561
  trackId: z.ZodString;
1545
1562
  deviceId: z.ZodNumber;
@@ -1643,6 +1660,7 @@ export declare const pipelineAnalyticsCapability: {
1643
1660
  stepId: z.ZodString;
1644
1661
  modelId: z.ZodOptional<z.ZodString>;
1645
1662
  decidedAt: z.ZodNumber;
1663
+ identityId: z.ZodOptional<z.ZodString>;
1646
1664
  }, z.core.$strip>>;
1647
1665
  subLabel: z.ZodOptional<z.ZodString>;
1648
1666
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1650,6 +1668,7 @@ export declare const pipelineAnalyticsCapability: {
1650
1668
  stepId: z.ZodString;
1651
1669
  modelId: z.ZodOptional<z.ZodString>;
1652
1670
  decidedAt: z.ZodNumber;
1671
+ identityId: z.ZodOptional<z.ZodString>;
1653
1672
  }, z.core.$strip>>;
1654
1673
  trackId: z.ZodString;
1655
1674
  deviceId: z.ZodNumber;
@@ -1735,6 +1754,7 @@ export declare const pipelineAnalyticsCapability: {
1735
1754
  stepId: z.ZodString;
1736
1755
  modelId: z.ZodOptional<z.ZodString>;
1737
1756
  decidedAt: z.ZodNumber;
1757
+ identityId: z.ZodOptional<z.ZodString>;
1738
1758
  }, z.core.$strip>>;
1739
1759
  subLabel: z.ZodOptional<z.ZodString>;
1740
1760
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1742,6 +1762,7 @@ export declare const pipelineAnalyticsCapability: {
1742
1762
  stepId: z.ZodString;
1743
1763
  modelId: z.ZodOptional<z.ZodString>;
1744
1764
  decidedAt: z.ZodNumber;
1765
+ identityId: z.ZodOptional<z.ZodString>;
1745
1766
  }, z.core.$strip>>;
1746
1767
  kind: z.ZodLiteral<"object">;
1747
1768
  source: z.ZodOptional<z.ZodEnum<{
@@ -1939,6 +1960,7 @@ export declare const pipelineAnalyticsCapability: {
1939
1960
  stepId: z.ZodString;
1940
1961
  modelId: z.ZodOptional<z.ZodString>;
1941
1962
  decidedAt: z.ZodNumber;
1963
+ identityId: z.ZodOptional<z.ZodString>;
1942
1964
  }, z.core.$strip>>;
1943
1965
  subLabel: z.ZodOptional<z.ZodString>;
1944
1966
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -1946,6 +1968,7 @@ export declare const pipelineAnalyticsCapability: {
1946
1968
  stepId: z.ZodString;
1947
1969
  modelId: z.ZodOptional<z.ZodString>;
1948
1970
  decidedAt: z.ZodNumber;
1971
+ identityId: z.ZodOptional<z.ZodString>;
1949
1972
  }, z.core.$strip>>;
1950
1973
  id: z.ZodString;
1951
1974
  trackId: z.ZodString;
@@ -2868,6 +2891,7 @@ export declare const pipelineAnalyticsCapability: {
2868
2891
  stepId: z.ZodString;
2869
2892
  modelId: z.ZodOptional<z.ZodString>;
2870
2893
  decidedAt: z.ZodNumber;
2894
+ identityId: z.ZodOptional<z.ZodString>;
2871
2895
  }, z.core.$strip>>;
2872
2896
  subLabel: z.ZodOptional<z.ZodString>;
2873
2897
  subLabelScore: z.ZodOptional<z.ZodNumber>;
@@ -2875,6 +2899,7 @@ export declare const pipelineAnalyticsCapability: {
2875
2899
  stepId: z.ZodString;
2876
2900
  modelId: z.ZodOptional<z.ZodString>;
2877
2901
  decidedAt: z.ZodNumber;
2902
+ identityId: z.ZodOptional<z.ZodString>;
2878
2903
  }, z.core.$strip>>;
2879
2904
  kind: z.ZodLiteral<"object">;
2880
2905
  source: z.ZodOptional<z.ZodEnum<{
package/dist/index.js CHANGED
@@ -12068,7 +12068,16 @@ var NcScheduleSchema = zod.z.object({
12068
12068
  });
12069
12069
  /** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
12070
12070
  var NcPlateMatcherSchema = zod.z.object({
12071
- values: zod.z.array(zod.z.string().min(1)).min(1),
12071
+ /**
12072
+ * Plate texts (or gallery vehicle names) to match. EMPTY = **any plate the
12073
+ * pipeline could read** — the plate half of "no selection = no narrowing",
12074
+ * and the switch that says this rule is about vehicles that were IDENTIFIED
12075
+ * rather than merely seen. A subject carrying no plate still fails.
12076
+ *
12077
+ * The `.min(1)` this used to carry made that state unauthorable; nothing has
12078
+ * ever persisted an empty list, so widening it cannot change an existing rule.
12079
+ */
12080
+ values: zod.z.array(zod.z.string().min(1)),
12072
12081
  /** Max Levenshtein distance after normalization (uppercase alphanumeric). */
12073
12082
  maxDistance: zod.z.number().int().min(0).max(3).default(1)
12074
12083
  });
@@ -12330,18 +12339,47 @@ var NcConditionsSchema = zod.z.object({
12330
12339
  */
12331
12340
  labelEquals: zod.z.array(zod.z.string().min(1)).optional(),
12332
12341
  /**
12333
- * Identity matcher. P1 boundary: matched against the record's collapsed
12334
- * `label` (the identity display name propagated by the face pipeline) —
12335
- * identity-ID matching rides in P2 when identity ids reach the record.
12342
+ * KNOWN FACES the rule's identity scope, and the switch that says the rule
12343
+ * is about recognised people at all.
12344
+ *
12345
+ * Three states, and the empty one is the point:
12346
+ *
12347
+ * | value | meaning |
12348
+ * | --- | --- |
12349
+ * | absent | the rule does not care who it is; an unrecognised person matches |
12350
+ * | `[]` | **only known faces** — any identity in the gallery, nobody in particular |
12351
+ * | a list | only these identities |
12352
+ *
12353
+ * `[]` is the repo-wide "no selection = no narrowing" reading (an absent
12354
+ * `devices` list is every device), applied one level down: the operator has
12355
+ * turned the face scope ON and narrowed it to nothing, which is every known
12356
+ * face. No second field states the same thing — a switch that can disagree
12357
+ * with the list under it is worse than no switch (D62).
12358
+ *
12359
+ * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
12360
+ * renameable, and a rule authored on "Gianluca" went silently dark the moment
12361
+ * the operator fixed the spelling. The id reaches the record on
12362
+ * `LabelAttribution.identityId`; the name is what the editor shows and what
12363
+ * `{{label}}` renders.
12364
+ *
12365
+ * Rules written before this carry NAMES, and are resolved to ids lazily at
12366
+ * load (`NcRuleStore.load`) against the live gallery — a name nothing answers
12367
+ * for is left as it stands and reported, never dropped. The engine also
12368
+ * accepts a display-name hit as a compatibility leg, so a rule whose
12369
+ * migration could not resolve keeps matching exactly what it matched before.
12336
12370
  */
12337
12371
  identities: zod.z.array(zod.z.string().min(1)).optional(),
12338
- /** Fuzzy plate matcher against the record's `label` (plate text). */
12372
+ /**
12373
+ * KNOWN PLATES / VEHICLES — the plate mirror of {@link identities}, including
12374
+ * the empty-list reading: `values: []` is "any plate the OCR could read",
12375
+ * a non-empty list is those plates (fuzzily). See {@link NcPlateMatcherSchema}.
12376
+ */
12339
12377
  plates: NcPlateMatcherSchema.optional(),
12340
12378
  /**
12341
- * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics.
12342
- * Same P1 boundary: matched against the record's collapsed `label` (the
12343
- * identity display name). A record with NO label passes (nothing to
12344
- * exclude), unlike the include variant which fails on an absent label.
12379
+ * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics, and
12380
+ * the same id members and the same lazy name→id migration. A record with NO
12381
+ * identity passes (nothing to exclude), unlike the include variant which
12382
+ * fails on an unrecognised subject. An EMPTY list excludes nobody.
12345
12383
  */
12346
12384
  identitiesExclude: zod.z.array(zod.z.string().min(1)).optional(),
12347
12385
  /**
@@ -12734,7 +12772,37 @@ var NcRuleInputSchema = zod.z.object({
12734
12772
  * a rule that predates the gate must keep delivering byte-for-byte as it
12735
12773
  * did, and absent is the only way to say that without a migration.
12736
12774
  */
12737
- confirm: NcConfirmSchema.optional()
12775
+ confirm: NcConfirmSchema.optional(),
12776
+ /**
12777
+ * WAIT for face/plate recognition before saying anything.
12778
+ *
12779
+ * A notification's TEXT is frozen at enqueue and its media is re-resolved at
12780
+ * send; the identity is neither. A face is confirmed after `confirmFrames`
12781
+ * agreeing observations — p50 **11.4 s** after the track was first seen,
12782
+ * measured on this hub — and an `immediate` rule enqueues on the first object
12783
+ * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
12784
+ * immediate path, and no amount of media re-resolution fixes a sentence.
12785
+ *
12786
+ * Only two honest answers exist, and this flag picks between them. It has
12787
+ * effect ONLY on a rule that declares a recognition scope
12788
+ * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
12789
+ * other rule there is nothing to wait for and the flag is inert.
12790
+ *
12791
+ * | value | what happens |
12792
+ * | --- | --- |
12793
+ * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
12794
+ * | absent / `false` | it fires at once WITHOUT the name, and if recognition lands before the track closes a SECOND, "…is Gianluca" notification follows (one per track, per rule, per target) |
12795
+ *
12796
+ * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
12797
+ * on the addon cap path, and absent has to keep meaning exactly what every
12798
+ * rule authored before this field meant.
12799
+ *
12800
+ * The cost of `true` is stated here because the editor states it too: a rule
12801
+ * that waits also inherits track-close SEMANTICS — its `zones` condition
12802
+ * tests every zone the track visited and a `crossing` condition can no longer
12803
+ * be satisfied, because a closed track carries no crossing.
12804
+ */
12805
+ waitForEnhancement: zod.z.boolean().optional()
12738
12806
  });
12739
12807
  /**
12740
12808
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -13078,32 +13146,32 @@ var NC_CONDITION_CATALOG = [
13078
13146
  {
13079
13147
  id: "identities",
13080
13148
  group: "label",
13081
- label: "Identities",
13149
+ label: "Known faces",
13082
13150
  valueType: "stringList",
13083
13151
  operator: "in",
13084
13152
  appliesTo: ["immediate", "track-end"],
13085
13153
  phase: "P1",
13086
- description: "P1: matched against the identity display name on the record label."
13154
+ description: "Only recognised people. Selecting NOBODY means every identity in the face gallery; selecting some narrows to those. Matched on the gallery id, so renaming a person does not break the rule. On immediate delivery the name is not known yet when the notification is enqueued — see the rule’s \"wait for recognition\" switch."
13087
13155
  },
13088
13156
  {
13089
13157
  id: "plates",
13090
13158
  group: "label",
13091
- label: "License plates",
13159
+ label: "Known plates",
13092
13160
  valueType: "plateMatcher",
13093
13161
  operator: "fuzzyIn",
13094
13162
  appliesTo: ["immediate", "track-end"],
13095
13163
  phase: "P1",
13096
- description: "Levenshtein-tolerant match against the plate text."
13164
+ description: "Only vehicles whose plate was read. Selecting NO plate means any readable plate; listed plates are matched Levenshtein-tolerantly, because OCR noise makes an exact match useless."
13097
13165
  },
13098
13166
  {
13099
13167
  id: "identitiesExclude",
13100
13168
  group: "label",
13101
- label: "Excluded identities",
13169
+ label: "Excluded faces",
13102
13170
  valueType: "stringList",
13103
13171
  operator: "notIn",
13104
13172
  appliesTo: ["immediate", "track-end"],
13105
13173
  phase: "P1",
13106
- description: "Veto by identity display name (mirror of Identities; absent label passes)."
13174
+ description: "Veto by identity (mirror of Known faces, same gallery ids). A subject nobody recognised passes — there is nothing to exclude."
13107
13175
  },
13108
13176
  {
13109
13177
  id: "minLabelConfidence",
@@ -14334,7 +14402,21 @@ var LabelTierSchema = zod.z.union([zod.z.literal(1), zod.z.literal(2)]);
14334
14402
  var LabelAttributionSchema = zod.z.object({
14335
14403
  stepId: zod.z.string(),
14336
14404
  modelId: zod.z.string().optional(),
14337
- decidedAt: zod.z.number()
14405
+ decidedAt: zod.z.number(),
14406
+ /**
14407
+ * The GALLERY id behind a recognised tier-2 label — a face-gallery
14408
+ * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
14409
+ *
14410
+ * The text alone is a DISPLAY NAME, and a display name is renameable: a
14411
+ * notification rule authored on "Gianluca" stopped matching the moment the
14412
+ * operator fixed the spelling in the gallery, and nothing said so. The id is
14413
+ * the thing that does not move, so it is what a rule matches on
14414
+ * (`NcConditions.identities`) and the text is what a human is shown.
14415
+ *
14416
+ * Absent when the label names no gallery row — a plate the OCR read but no
14417
+ * vehicle claims, a sub-class, a species, any tier-1 value.
14418
+ */
14419
+ identityId: zod.z.string().optional()
14338
14420
  });
14339
14421
  /**
14340
14422
  * The TIERED label model (roadmap 4g), spread into `TrackSchema` and
package/dist/index.mjs CHANGED
@@ -12067,7 +12067,16 @@ var NcScheduleSchema = z.object({
12067
12067
  });
12068
12068
  /** Fuzzy plate matcher — OCR noise makes exact match useless (spec row 12/13). */
12069
12069
  var NcPlateMatcherSchema = z.object({
12070
- values: z.array(z.string().min(1)).min(1),
12070
+ /**
12071
+ * Plate texts (or gallery vehicle names) to match. EMPTY = **any plate the
12072
+ * pipeline could read** — the plate half of "no selection = no narrowing",
12073
+ * and the switch that says this rule is about vehicles that were IDENTIFIED
12074
+ * rather than merely seen. A subject carrying no plate still fails.
12075
+ *
12076
+ * The `.min(1)` this used to carry made that state unauthorable; nothing has
12077
+ * ever persisted an empty list, so widening it cannot change an existing rule.
12078
+ */
12079
+ values: z.array(z.string().min(1)),
12071
12080
  /** Max Levenshtein distance after normalization (uppercase alphanumeric). */
12072
12081
  maxDistance: z.number().int().min(0).max(3).default(1)
12073
12082
  });
@@ -12329,18 +12338,47 @@ var NcConditionsSchema = z.object({
12329
12338
  */
12330
12339
  labelEquals: z.array(z.string().min(1)).optional(),
12331
12340
  /**
12332
- * Identity matcher. P1 boundary: matched against the record's collapsed
12333
- * `label` (the identity display name propagated by the face pipeline) —
12334
- * identity-ID matching rides in P2 when identity ids reach the record.
12341
+ * KNOWN FACES the rule's identity scope, and the switch that says the rule
12342
+ * is about recognised people at all.
12343
+ *
12344
+ * Three states, and the empty one is the point:
12345
+ *
12346
+ * | value | meaning |
12347
+ * | --- | --- |
12348
+ * | absent | the rule does not care who it is; an unrecognised person matches |
12349
+ * | `[]` | **only known faces** — any identity in the gallery, nobody in particular |
12350
+ * | a list | only these identities |
12351
+ *
12352
+ * `[]` is the repo-wide "no selection = no narrowing" reading (an absent
12353
+ * `devices` list is every device), applied one level down: the operator has
12354
+ * turned the face scope ON and narrowed it to nothing, which is every known
12355
+ * face. No second field states the same thing — a switch that can disagree
12356
+ * with the list under it is worse than no switch (D62).
12357
+ *
12358
+ * MEMBERS ARE FACE-GALLERY `Identity.id`s (uuid), not display names. A name is
12359
+ * renameable, and a rule authored on "Gianluca" went silently dark the moment
12360
+ * the operator fixed the spelling. The id reaches the record on
12361
+ * `LabelAttribution.identityId`; the name is what the editor shows and what
12362
+ * `{{label}}` renders.
12363
+ *
12364
+ * Rules written before this carry NAMES, and are resolved to ids lazily at
12365
+ * load (`NcRuleStore.load`) against the live gallery — a name nothing answers
12366
+ * for is left as it stands and reported, never dropped. The engine also
12367
+ * accepts a display-name hit as a compatibility leg, so a rule whose
12368
+ * migration could not resolve keeps matching exactly what it matched before.
12335
12369
  */
12336
12370
  identities: z.array(z.string().min(1)).optional(),
12337
- /** Fuzzy plate matcher against the record's `label` (plate text). */
12371
+ /**
12372
+ * KNOWN PLATES / VEHICLES — the plate mirror of {@link identities}, including
12373
+ * the empty-list reading: `values: []` is "any plate the OCR could read",
12374
+ * a non-empty list is those plates (fuzzily). See {@link NcPlateMatcherSchema}.
12375
+ */
12338
12376
  plates: NcPlateMatcherSchema.optional(),
12339
12377
  /**
12340
- * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics.
12341
- * Same P1 boundary: matched against the record's collapsed `label` (the
12342
- * identity display name). A record with NO label passes (nothing to
12343
- * exclude), unlike the include variant which fails on an absent label.
12378
+ * Identity EXCLUDE — mirror of {@link identities} with `notIn` semantics, and
12379
+ * the same id members and the same lazy name→id migration. A record with NO
12380
+ * identity passes (nothing to exclude), unlike the include variant which
12381
+ * fails on an unrecognised subject. An EMPTY list excludes nobody.
12344
12382
  */
12345
12383
  identitiesExclude: z.array(z.string().min(1)).optional(),
12346
12384
  /**
@@ -12733,7 +12771,37 @@ var NcRuleInputSchema = z.object({
12733
12771
  * a rule that predates the gate must keep delivering byte-for-byte as it
12734
12772
  * did, and absent is the only way to say that without a migration.
12735
12773
  */
12736
- confirm: NcConfirmSchema.optional()
12774
+ confirm: NcConfirmSchema.optional(),
12775
+ /**
12776
+ * WAIT for face/plate recognition before saying anything.
12777
+ *
12778
+ * A notification's TEXT is frozen at enqueue and its media is re-resolved at
12779
+ * send; the identity is neither. A face is confirmed after `confirmFrames`
12780
+ * agreeing observations — p50 **11.4 s** after the track was first seen,
12781
+ * measured on this hub — and an `immediate` rule enqueues on the first object
12782
+ * event, seconds before that. So "Gianluca è arrivato" is unsayable on the
12783
+ * immediate path, and no amount of media re-resolution fixes a sentence.
12784
+ *
12785
+ * Only two honest answers exist, and this flag picks between them. It has
12786
+ * effect ONLY on a rule that declares a recognition scope
12787
+ * ({@link NcConditions.identities} or {@link NcConditions.plates}) — on any
12788
+ * other rule there is nothing to wait for and the flag is inert.
12789
+ *
12790
+ * | value | what happens |
12791
+ * | --- | --- |
12792
+ * | `true` | the rule stops firing on the object event and fires at TRACK CLOSE instead, once, with the name — later, and complete |
12793
+ * | absent / `false` | it fires at once WITHOUT the name, and if recognition lands before the track closes a SECOND, "…is Gianluca" notification follows (one per track, per rule, per target) |
12794
+ *
12795
+ * `.optional()` and deliberately NOT `.default()`: a Zod default does not run
12796
+ * on the addon cap path, and absent has to keep meaning exactly what every
12797
+ * rule authored before this field meant.
12798
+ *
12799
+ * The cost of `true` is stated here because the editor states it too: a rule
12800
+ * that waits also inherits track-close SEMANTICS — its `zones` condition
12801
+ * tests every zone the track visited and a `crossing` condition can no longer
12802
+ * be satisfied, because a closed track carries no crossing.
12803
+ */
12804
+ waitForEnhancement: z.boolean().optional()
12737
12805
  });
12738
12806
  /**
12739
12807
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -13077,32 +13145,32 @@ var NC_CONDITION_CATALOG = [
13077
13145
  {
13078
13146
  id: "identities",
13079
13147
  group: "label",
13080
- label: "Identities",
13148
+ label: "Known faces",
13081
13149
  valueType: "stringList",
13082
13150
  operator: "in",
13083
13151
  appliesTo: ["immediate", "track-end"],
13084
13152
  phase: "P1",
13085
- description: "P1: matched against the identity display name on the record label."
13153
+ description: "Only recognised people. Selecting NOBODY means every identity in the face gallery; selecting some narrows to those. Matched on the gallery id, so renaming a person does not break the rule. On immediate delivery the name is not known yet when the notification is enqueued — see the rule’s \"wait for recognition\" switch."
13086
13154
  },
13087
13155
  {
13088
13156
  id: "plates",
13089
13157
  group: "label",
13090
- label: "License plates",
13158
+ label: "Known plates",
13091
13159
  valueType: "plateMatcher",
13092
13160
  operator: "fuzzyIn",
13093
13161
  appliesTo: ["immediate", "track-end"],
13094
13162
  phase: "P1",
13095
- description: "Levenshtein-tolerant match against the plate text."
13163
+ description: "Only vehicles whose plate was read. Selecting NO plate means any readable plate; listed plates are matched Levenshtein-tolerantly, because OCR noise makes an exact match useless."
13096
13164
  },
13097
13165
  {
13098
13166
  id: "identitiesExclude",
13099
13167
  group: "label",
13100
- label: "Excluded identities",
13168
+ label: "Excluded faces",
13101
13169
  valueType: "stringList",
13102
13170
  operator: "notIn",
13103
13171
  appliesTo: ["immediate", "track-end"],
13104
13172
  phase: "P1",
13105
- description: "Veto by identity display name (mirror of Identities; absent label passes)."
13173
+ description: "Veto by identity (mirror of Known faces, same gallery ids). A subject nobody recognised passes — there is nothing to exclude."
13106
13174
  },
13107
13175
  {
13108
13176
  id: "minLabelConfidence",
@@ -14333,7 +14401,21 @@ var LabelTierSchema = z.union([z.literal(1), z.literal(2)]);
14333
14401
  var LabelAttributionSchema = z.object({
14334
14402
  stepId: z.string(),
14335
14403
  modelId: z.string().optional(),
14336
- decidedAt: z.number()
14404
+ decidedAt: z.number(),
14405
+ /**
14406
+ * The GALLERY id behind a recognised tier-2 label — a face-gallery
14407
+ * `Identity.id` or a plate-gallery `Vehicle.id` (both `randomUUID`).
14408
+ *
14409
+ * The text alone is a DISPLAY NAME, and a display name is renameable: a
14410
+ * notification rule authored on "Gianluca" stopped matching the moment the
14411
+ * operator fixed the spelling in the gallery, and nothing said so. The id is
14412
+ * the thing that does not move, so it is what a rule matches on
14413
+ * (`NcConditions.identities`) and the text is what a human is shown.
14414
+ *
14415
+ * Absent when the label names no gallery row — a plate the OCR read but no
14416
+ * vehicle claims, a sub-class, a species, any tier-1 value.
14417
+ */
14418
+ identityId: z.string().optional()
14337
14419
  });
14338
14420
  /**
14339
14421
  * The TIERED label model (roadmap 4g), spread into `TrackSchema` and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.69",
3
+ "version": "1.2.70",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",