@camstack/addon-export-hap 1.2.95 → 1.2.96

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.
@@ -24974,6 +24974,59 @@ var IdentitySampleInfoSchema = object({
24974
24974
  deviceId: number().int().optional(),
24975
24975
  base64: string().optional()
24976
24976
  });
24977
+ /**
24978
+ * One enrolled sample, judged against the gallery it lives in.
24979
+ *
24980
+ * The gallery is the one input to recognition nobody re-reads: a sample
24981
+ * enrolled from the wrong face keeps voting forever, and because the matches it
24982
+ * pulls then look confident, nobody goes back. The 2026-09-08 audit found
24983
+ * exactly one such pair on this cluster — a sample scoring 0.61 against three
24984
+ * samples of ANOTHER person, enrolled from the same camera in the same minute,
24985
+ * where every other cross-identity pair sits under 0.50.
24986
+ */
24987
+ var IdentitySampleAuditRowSchema = object({
24988
+ sampleId: string(),
24989
+ enrolledAt: number().int(),
24990
+ deviceId: number().int().optional(),
24991
+ source: _enum(["detected", "photo"]),
24992
+ /** The enrolled crop's media key, so the panel can show the evidence. */
24993
+ mediaKey: string().optional(),
24994
+ /**
24995
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
24996
+ * across feature spaces is a well-formed float with no meaning. Every number
24997
+ * below then says nothing — it must read as "cannot say", never as an
24998
+ * accusation and never as a clean bill: this list ends in a Remove button.
24999
+ */
25000
+ comparable: boolean(),
25001
+ /** Mean cosine against this person's other samples. Null when there are none
25002
+ * to compare with — never 0, which would read as "opposite". */
25003
+ selfMean: number().nullable(),
25004
+ /** The other person this sample looks most like, when it looks like one.
25005
+ * This is the half that convicts: not looking like yourself can be a hard
25006
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
25007
+ bestForeign: object({
25008
+ identityId: string(),
25009
+ name: string(),
25010
+ score: number()
25011
+ }).optional(),
25012
+ /** 0 = nothing to say. Higher = look at this one sooner. */
25013
+ suspicion: number()
25014
+ });
25015
+ var IdentitySampleAuditSchema = object({
25016
+ identityId: string(),
25017
+ name: string(),
25018
+ /** The cluster face model every comparison was made in. */
25019
+ modelId: string(),
25020
+ totalSamples: number().int(),
25021
+ comparableSamples: number().int(),
25022
+ flagged: number().int(),
25023
+ /** The bar `flagged` counts against, so the panel states the RULE and not
25024
+ * only its current result. */
25025
+ flagThreshold: number(),
25026
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
25027
+ * operator asked to see the gallery, not only its accusations. */
25028
+ rows: array(IdentitySampleAuditRowSchema).readonly()
25029
+ });
24977
25030
  var FaceInfoSchema = object({
24978
25031
  faceId: string(),
24979
25032
  deviceId: number().int(),
@@ -25125,7 +25178,7 @@ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly
25125
25178
  }), method(object({ id: string() }), _void(), {
25126
25179
  kind: "mutation",
25127
25180
  auth: "admin"
25128
- }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({
25181
+ }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({ identityId: string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }), method(object({
25129
25182
  identityId: string(),
25130
25183
  sampleId: string()
25131
25184
  }), _void(), {
@@ -32405,6 +32458,12 @@ Object.freeze({
32405
32458
  addonId: null,
32406
32459
  access: "create"
32407
32460
  },
32461
+ "faceGallery.auditIdentitySamples": {
32462
+ capName: "face-gallery",
32463
+ capScope: "system",
32464
+ addonId: null,
32465
+ access: "view"
32466
+ },
32408
32467
  "faceGallery.createIdentity": {
32409
32468
  capName: "face-gallery",
32410
32469
  capScope: "system",
@@ -24962,6 +24962,59 @@ var IdentitySampleInfoSchema = object({
24962
24962
  deviceId: number().int().optional(),
24963
24963
  base64: string().optional()
24964
24964
  });
24965
+ /**
24966
+ * One enrolled sample, judged against the gallery it lives in.
24967
+ *
24968
+ * The gallery is the one input to recognition nobody re-reads: a sample
24969
+ * enrolled from the wrong face keeps voting forever, and because the matches it
24970
+ * pulls then look confident, nobody goes back. The 2026-09-08 audit found
24971
+ * exactly one such pair on this cluster — a sample scoring 0.61 against three
24972
+ * samples of ANOTHER person, enrolled from the same camera in the same minute,
24973
+ * where every other cross-identity pair sits under 0.50.
24974
+ */
24975
+ var IdentitySampleAuditRowSchema = object({
24976
+ sampleId: string(),
24977
+ enrolledAt: number().int(),
24978
+ deviceId: number().int().optional(),
24979
+ source: _enum(["detected", "photo"]),
24980
+ /** The enrolled crop's media key, so the panel can show the evidence. */
24981
+ mediaKey: string().optional(),
24982
+ /**
24983
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
24984
+ * across feature spaces is a well-formed float with no meaning. Every number
24985
+ * below then says nothing — it must read as "cannot say", never as an
24986
+ * accusation and never as a clean bill: this list ends in a Remove button.
24987
+ */
24988
+ comparable: boolean(),
24989
+ /** Mean cosine against this person's other samples. Null when there are none
24990
+ * to compare with — never 0, which would read as "opposite". */
24991
+ selfMean: number().nullable(),
24992
+ /** The other person this sample looks most like, when it looks like one.
24993
+ * This is the half that convicts: not looking like yourself can be a hard
24994
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
24995
+ bestForeign: object({
24996
+ identityId: string(),
24997
+ name: string(),
24998
+ score: number()
24999
+ }).optional(),
25000
+ /** 0 = nothing to say. Higher = look at this one sooner. */
25001
+ suspicion: number()
25002
+ });
25003
+ var IdentitySampleAuditSchema = object({
25004
+ identityId: string(),
25005
+ name: string(),
25006
+ /** The cluster face model every comparison was made in. */
25007
+ modelId: string(),
25008
+ totalSamples: number().int(),
25009
+ comparableSamples: number().int(),
25010
+ flagged: number().int(),
25011
+ /** The bar `flagged` counts against, so the panel states the RULE and not
25012
+ * only its current result. */
25013
+ flagThreshold: number(),
25014
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
25015
+ * operator asked to see the gallery, not only its accusations. */
25016
+ rows: array(IdentitySampleAuditRowSchema).readonly()
25017
+ });
24965
25018
  var FaceInfoSchema = object({
24966
25019
  faceId: string(),
24967
25020
  deviceId: number().int(),
@@ -25113,7 +25166,7 @@ includeCrops: boolean().optional() }).optional(), array(IdentitySchema).readonly
25113
25166
  }), method(object({ id: string() }), _void(), {
25114
25167
  kind: "mutation",
25115
25168
  auth: "admin"
25116
- }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({
25169
+ }), method(object({ identityId: string() }), array(IdentitySampleInfoSchema).readonly()), method(object({ identityId: string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }), method(object({
25117
25170
  identityId: string(),
25118
25171
  sampleId: string()
25119
25172
  }), _void(), {
@@ -32393,6 +32446,12 @@ Object.freeze({
32393
32446
  addonId: null,
32394
32447
  access: "create"
32395
32448
  },
32449
+ "faceGallery.auditIdentitySamples": {
32450
+ capName: "face-gallery",
32451
+ capScope: "system",
32452
+ addonId: null,
32453
+ access: "view"
32454
+ },
32396
32455
  "faceGallery.createIdentity": {
32397
32456
  capName: "face-gallery",
32398
32457
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-export-hap",
3
- "version": "1.2.95",
3
+ "version": "1.2.96",
4
4
  "description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
5
5
  "keywords": [
6
6
  "camstack",