camstack 1.2.124 → 1.2.125

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.
@@ -33372,6 +33372,49 @@ var IdentitySampleInfoSchema = external_exports.object({
33372
33372
  deviceId: external_exports.number().int().optional(),
33373
33373
  base64: external_exports.string().optional()
33374
33374
  });
33375
+ var IdentitySampleAuditRowSchema = external_exports.object({
33376
+ sampleId: external_exports.string(),
33377
+ enrolledAt: external_exports.number().int(),
33378
+ deviceId: external_exports.number().int().optional(),
33379
+ source: external_exports.enum(["detected", "photo"]),
33380
+ /** The enrolled crop's media key, so the panel can show the evidence. */
33381
+ mediaKey: external_exports.string().optional(),
33382
+ /**
33383
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
33384
+ * across feature spaces is a well-formed float with no meaning. Every number
33385
+ * below then says nothing — it must read as "cannot say", never as an
33386
+ * accusation and never as a clean bill: this list ends in a Remove button.
33387
+ */
33388
+ comparable: external_exports.boolean(),
33389
+ /** Mean cosine against this person's other samples. Null when there are none
33390
+ * to compare with — never 0, which would read as "opposite". */
33391
+ selfMean: external_exports.number().nullable(),
33392
+ /** The other person this sample looks most like, when it looks like one.
33393
+ * This is the half that convicts: not looking like yourself can be a hard
33394
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
33395
+ bestForeign: external_exports.object({
33396
+ identityId: external_exports.string(),
33397
+ name: external_exports.string(),
33398
+ score: external_exports.number()
33399
+ }).optional(),
33400
+ /** 0 = nothing to say. Higher = look at this one sooner. */
33401
+ suspicion: external_exports.number()
33402
+ });
33403
+ var IdentitySampleAuditSchema = external_exports.object({
33404
+ identityId: external_exports.string(),
33405
+ name: external_exports.string(),
33406
+ /** The cluster face model every comparison was made in. */
33407
+ modelId: external_exports.string(),
33408
+ totalSamples: external_exports.number().int(),
33409
+ comparableSamples: external_exports.number().int(),
33410
+ flagged: external_exports.number().int(),
33411
+ /** The bar `flagged` counts against, so the panel states the RULE and not
33412
+ * only its current result. */
33413
+ flagThreshold: external_exports.number(),
33414
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
33415
+ * operator asked to see the gallery, not only its accusations. */
33416
+ rows: external_exports.array(IdentitySampleAuditRowSchema).readonly()
33417
+ });
33375
33418
  var FaceInfoSchema = external_exports.object({
33376
33419
  faceId: external_exports.string(),
33377
33420
  deviceId: external_exports.number().int(),
@@ -33499,6 +33542,19 @@ var faceGalleryCapability = {
33499
33542
  auth: "admin"
33500
33543
  }),
33501
33544
  listIdentitySamples: method(external_exports.object({ identityId: external_exports.string() }), external_exports.array(IdentitySampleInfoSchema).readonly()),
33545
+ /**
33546
+ * Re-analyse ONE person's enrolled samples against the whole gallery.
33547
+ *
33548
+ * A pure read — no write, no inference, just dot products over vectors the
33549
+ * hub already holds (327 of them on this cluster). `admin` for the same
33550
+ * reason `listIdentitySamples` is: the answer names every enrolled person
33551
+ * and how well one person's samples match them, which is the gallery's
33552
+ * shape and not a viewer-level fact.
33553
+ *
33554
+ * Removal deliberately stays `removeSample`: an analysis that could also
33555
+ * delete would be one confirmation away from emptying a gallery.
33556
+ */
33557
+ auditIdentitySamples: method(external_exports.object({ identityId: external_exports.string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }),
33502
33558
  removeSample: method(external_exports.object({
33503
33559
  identityId: external_exports.string(),
33504
33560
  sampleId: external_exports.string()
@@ -41908,6 +41964,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
41908
41964
  addonId: null,
41909
41965
  access: "create"
41910
41966
  },
41967
+ "faceGallery.auditIdentitySamples": {
41968
+ capName: "face-gallery",
41969
+ capScope: "system",
41970
+ addonId: null,
41971
+ access: "view"
41972
+ },
41911
41973
  "faceGallery.createIdentity": {
41912
41974
  capName: "face-gallery",
41913
41975
  capScope: "system",
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDiscover
4
- } from "./chunk-2S3TRFS3.js";
4
+ } from "./chunk-JYGD4EQO.js";
5
5
  import "./chunk-LMMQX4CK.js";
6
6
 
7
7
  // src/cli.ts
@@ -38,7 +38,7 @@ async function runServe(args) {
38
38
  ...typeof values.data === "string" ? { data: values.data } : {}
39
39
  };
40
40
  Object.assign(process.env, buildServeEnv(opts));
41
- await import("./launcher-VFR24CPY.js");
41
+ await import("./launcher-KIFZDGA7.js");
42
42
  }
43
43
 
44
44
  // src/commands/agent.ts
@@ -83,7 +83,7 @@ async function runAgent(args) {
83
83
  ...typeof values.port === "string" ? { port: values.port } : {}
84
84
  };
85
85
  Object.assign(process.env, buildAgentEnv(opts));
86
- await import("./launcher-VFR24CPY.js");
86
+ await import("./launcher-KIFZDGA7.js");
87
87
  }
88
88
 
89
89
  // src/commands/setup.ts
@@ -1130,7 +1130,7 @@ function isUnknown(_value) {
1130
1130
  return true;
1131
1131
  }
1132
1132
  async function resolveServerInteractive(presetNamespace) {
1133
- const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-4ZPVKRSY.js");
1133
+ const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-45BLIQAV.js");
1134
1134
  if (presetNamespace) {
1135
1135
  const spinner4 = clack.spinner();
1136
1136
  spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
@@ -5,7 +5,7 @@ import {
5
5
  filterHubNodes,
6
6
  resolveHubFromDiscovered,
7
7
  runDiscover
8
- } from "./chunk-2S3TRFS3.js";
8
+ } from "./chunk-JYGD4EQO.js";
9
9
  import "./chunk-LMMQX4CK.js";
10
10
  export {
11
11
  DEFAULT_HUB_HTTPS_PORT,
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
23633
23633
  }
23634
23634
  });
23635
23635
 
23636
- // ../system/dist/dist-CEUwB91M.js
23637
- var require_dist_CEUwB91M = __commonJS({
23638
- "../system/dist/dist-CEUwB91M.js"(exports) {
23636
+ // ../system/dist/dist-CNxDnJwz.js
23637
+ var require_dist_CNxDnJwz = __commonJS({
23638
+ "../system/dist/dist-CNxDnJwz.js"(exports) {
23639
23639
  "use strict";
23640
23640
  var zod = require_zod();
23641
23641
  var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
@@ -43989,6 +43989,49 @@ var require_dist_CEUwB91M = __commonJS({
43989
43989
  deviceId: zod.z.number().int().optional(),
43990
43990
  base64: zod.z.string().optional()
43991
43991
  });
43992
+ var IdentitySampleAuditRowSchema = zod.z.object({
43993
+ sampleId: zod.z.string(),
43994
+ enrolledAt: zod.z.number().int(),
43995
+ deviceId: zod.z.number().int().optional(),
43996
+ source: zod.z.enum(["detected", "photo"]),
43997
+ /** The enrolled crop's media key, so the panel can show the evidence. */
43998
+ mediaKey: zod.z.string().optional(),
43999
+ /**
44000
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
44001
+ * across feature spaces is a well-formed float with no meaning. Every number
44002
+ * below then says nothing — it must read as "cannot say", never as an
44003
+ * accusation and never as a clean bill: this list ends in a Remove button.
44004
+ */
44005
+ comparable: zod.z.boolean(),
44006
+ /** Mean cosine against this person's other samples. Null when there are none
44007
+ * to compare with — never 0, which would read as "opposite". */
44008
+ selfMean: zod.z.number().nullable(),
44009
+ /** The other person this sample looks most like, when it looks like one.
44010
+ * This is the half that convicts: not looking like yourself can be a hard
44011
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
44012
+ bestForeign: zod.z.object({
44013
+ identityId: zod.z.string(),
44014
+ name: zod.z.string(),
44015
+ score: zod.z.number()
44016
+ }).optional(),
44017
+ /** 0 = nothing to say. Higher = look at this one sooner. */
44018
+ suspicion: zod.z.number()
44019
+ });
44020
+ var IdentitySampleAuditSchema = zod.z.object({
44021
+ identityId: zod.z.string(),
44022
+ name: zod.z.string(),
44023
+ /** The cluster face model every comparison was made in. */
44024
+ modelId: zod.z.string(),
44025
+ totalSamples: zod.z.number().int(),
44026
+ comparableSamples: zod.z.number().int(),
44027
+ flagged: zod.z.number().int(),
44028
+ /** The bar `flagged` counts against, so the panel states the RULE and not
44029
+ * only its current result. */
44030
+ flagThreshold: zod.z.number(),
44031
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
44032
+ * operator asked to see the gallery, not only its accusations. */
44033
+ rows: zod.z.array(IdentitySampleAuditRowSchema).readonly()
44034
+ });
43992
44035
  var FaceInfoSchema = zod.z.object({
43993
44036
  faceId: zod.z.string(),
43994
44037
  deviceId: zod.z.number().int(),
@@ -44116,6 +44159,19 @@ var require_dist_CEUwB91M = __commonJS({
44116
44159
  auth: "admin"
44117
44160
  }),
44118
44161
  listIdentitySamples: method(zod.z.object({ identityId: zod.z.string() }), zod.z.array(IdentitySampleInfoSchema).readonly()),
44162
+ /**
44163
+ * Re-analyse ONE person's enrolled samples against the whole gallery.
44164
+ *
44165
+ * A pure read — no write, no inference, just dot products over vectors the
44166
+ * hub already holds (327 of them on this cluster). `admin` for the same
44167
+ * reason `listIdentitySamples` is: the answer names every enrolled person
44168
+ * and how well one person's samples match them, which is the gallery's
44169
+ * shape and not a viewer-level fact.
44170
+ *
44171
+ * Removal deliberately stays `removeSample`: an analysis that could also
44172
+ * delete would be one confirmation away from emptying a gallery.
44173
+ */
44174
+ auditIdentitySamples: method(zod.z.object({ identityId: zod.z.string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }),
44119
44175
  removeSample: method(zod.z.object({
44120
44176
  identityId: zod.z.string(),
44121
44177
  sampleId: zod.z.string()
@@ -53352,6 +53408,12 @@ var require_dist_CEUwB91M = __commonJS({
53352
53408
  addonId: null,
53353
53409
  access: "create"
53354
53410
  },
53411
+ "faceGallery.auditIdentitySamples": {
53412
+ capName: "face-gallery",
53413
+ capScope: "system",
53414
+ addonId: null,
53415
+ access: "view"
53416
+ },
53355
53417
  "faceGallery.createIdentity": {
53356
53418
  capName: "face-gallery",
53357
53419
  capScope: "system",
@@ -60981,7 +61043,7 @@ var require_alerts_addon = __commonJS({
60981
61043
  [Symbol.toStringTag]: { value: "Module" }
60982
61044
  });
60983
61045
  require_chunk_Cek0wNdY();
60984
- var require_dist10 = require_dist_CEUwB91M();
61046
+ var require_dist10 = require_dist_CNxDnJwz();
60985
61047
  function selectExpired(alerts, cutoffMs) {
60986
61048
  return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
60987
61049
  }
@@ -61800,7 +61862,7 @@ var require_console_logging = __commonJS({
61800
61862
  [Symbol.toStringTag]: { value: "Module" }
61801
61863
  });
61802
61864
  require_chunk_Cek0wNdY();
61803
- var require_dist10 = require_dist_CEUwB91M();
61865
+ var require_dist10 = require_dist_CNxDnJwz();
61804
61866
  var require_formatter = require_formatter_DqAKDlvN();
61805
61867
  var LEVEL_RANK = {
61806
61868
  debug: 0,
@@ -61894,7 +61956,7 @@ var require_core_blocks_addon = __commonJS({
61894
61956
  "use strict";
61895
61957
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
61896
61958
  var require_chunk = require_chunk_Cek0wNdY();
61897
- var require_dist10 = require_dist_CEUwB91M();
61959
+ var require_dist10 = require_dist_CNxDnJwz();
61898
61960
  var node_crypto = __require("crypto");
61899
61961
  var node_fs_promises = __require("fs/promises");
61900
61962
  node_fs_promises = require_chunk.__toESM(node_fs_promises);
@@ -62791,11 +62853,11 @@ var require_core_blocks = __commonJS({
62791
62853
  }
62792
62854
  });
62793
62855
 
62794
- // ../system/dist/retired-settings-keys-DtPZcaQ_.js
62795
- var require_retired_settings_keys_DtPZcaQ = __commonJS({
62796
- "../system/dist/retired-settings-keys-DtPZcaQ_.js"(exports) {
62856
+ // ../system/dist/retired-settings-keys-D9wnrXOC.js
62857
+ var require_retired_settings_keys_D9wnrXOC = __commonJS({
62858
+ "../system/dist/retired-settings-keys-D9wnrXOC.js"(exports) {
62797
62859
  "use strict";
62798
- var require_dist10 = require_dist_CEUwB91M();
62860
+ var require_dist10 = require_dist_CNxDnJwz();
62799
62861
  function settingsStoreIsAuthoritativeHere(env) {
62800
62862
  const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
62801
62863
  return raw === "" || raw === "hub";
@@ -65030,8 +65092,8 @@ var require_device_manager_addon = __commonJS({
65030
65092
  [Symbol.toStringTag]: { value: "Module" }
65031
65093
  });
65032
65094
  require_chunk_Cek0wNdY();
65033
- var require_dist10 = require_dist_CEUwB91M();
65034
- var require_retired_settings_keys = require_retired_settings_keys_DtPZcaQ();
65095
+ var require_dist10 = require_dist_CNxDnJwz();
65096
+ var require_retired_settings_keys = require_retired_settings_keys_D9wnrXOC();
65035
65097
  var node_crypto = __require("crypto");
65036
65098
  var _camstack_types_node = require_node();
65037
65099
  var JOB_HISTORY = 20;
@@ -70656,7 +70718,7 @@ var require_hub_forwarder = __commonJS({
70656
70718
  [Symbol.toStringTag]: { value: "Module" }
70657
70719
  });
70658
70720
  require_chunk_Cek0wNdY();
70659
- var require_dist10 = require_dist_CEUwB91M();
70721
+ var require_dist10 = require_dist_CNxDnJwz();
70660
70722
  var require_formatter = require_formatter_DqAKDlvN();
70661
70723
  var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
70662
70724
  var HubForwarderDestination = class {
@@ -70793,7 +70855,7 @@ var require_liveness_monitor_addon = __commonJS({
70793
70855
  "use strict";
70794
70856
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
70795
70857
  require_chunk_Cek0wNdY();
70796
- var require_dist10 = require_dist_CEUwB91M();
70858
+ var require_dist10 = require_dist_CNxDnJwz();
70797
70859
  var NO_DEVICES = "liveness:no-devices";
70798
70860
  var ALL_OFFLINE = "liveness:all-devices-offline";
70799
70861
  var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
@@ -70989,7 +71051,7 @@ var require_local_auth_addon = __commonJS({
70989
71051
  [Symbol.toStringTag]: { value: "Module" }
70990
71052
  });
70991
71053
  var require_chunk = require_chunk_Cek0wNdY();
70992
- var require_dist10 = require_dist_CEUwB91M();
71054
+ var require_dist10 = require_dist_CNxDnJwz();
70993
71055
  var node_crypto = __require("crypto");
70994
71056
  node_crypto = require_chunk.__toESM(node_crypto);
70995
71057
  var crypto$1 = __require("crypto");
@@ -78802,7 +78864,7 @@ var require_loki_logging = __commonJS({
78802
78864
  [Symbol.toStringTag]: { value: "Module" }
78803
78865
  });
78804
78866
  require_chunk_Cek0wNdY();
78805
- var require_dist10 = require_dist_CEUwB91M();
78867
+ var require_dist10 = require_dist_CNxDnJwz();
78806
78868
  function sanitizeLabelName(raw) {
78807
78869
  const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
78808
78870
  return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
@@ -79367,7 +79429,7 @@ var require_native_metrics_addon = __commonJS({
79367
79429
  [Symbol.toStringTag]: { value: "Module" }
79368
79430
  });
79369
79431
  var require_chunk = require_chunk_Cek0wNdY();
79370
- var require_dist10 = require_dist_CEUwB91M();
79432
+ var require_dist10 = require_dist_CNxDnJwz();
79371
79433
  var node_fs_promises = __require("fs/promises");
79372
79434
  var node_child_process = __require("child_process");
79373
79435
  var node_util = __require("util");
@@ -81951,7 +82013,7 @@ var require_filesystem_storage_addon = __commonJS({
81951
82013
  [Symbol.toStringTag]: { value: "Module" }
81952
82014
  });
81953
82015
  var require_chunk = require_chunk_Cek0wNdY();
81954
- var require_dist10 = require_dist_CEUwB91M();
82016
+ var require_dist10 = require_dist_CNxDnJwz();
81955
82017
  var node_crypto = __require("crypto");
81956
82018
  var node_fs_promises = __require("fs/promises");
81957
82019
  var node_path = __require("path");
@@ -83067,8 +83129,8 @@ var require_sqlite_settings_addon = __commonJS({
83067
83129
  [Symbol.toStringTag]: { value: "Module" }
83068
83130
  });
83069
83131
  var require_chunk = require_chunk_Cek0wNdY();
83070
- var require_dist10 = require_dist_CEUwB91M();
83071
- var require_retired_settings_keys = require_retired_settings_keys_DtPZcaQ();
83132
+ var require_dist10 = require_dist_CNxDnJwz();
83133
+ var require_retired_settings_keys = require_retired_settings_keys_D9wnrXOC();
83072
83134
  var node_crypto = __require("crypto");
83073
83135
  var node_fs = __require("fs");
83074
83136
  var node_module = __require("module");
@@ -85572,7 +85634,7 @@ var require_storage_orchestrator_addon = __commonJS({
85572
85634
  [Symbol.toStringTag]: { value: "Module" }
85573
85635
  });
85574
85636
  var require_chunk = require_chunk_Cek0wNdY();
85575
- var require_dist10 = require_dist_CEUwB91M();
85637
+ var require_dist10 = require_dist_CNxDnJwz();
85576
85638
  var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
85577
85639
  var zod = require_zod();
85578
85640
  var node_crypto = __require("crypto");
@@ -89128,7 +89190,7 @@ var require_system_config_addon = __commonJS({
89128
89190
  [Symbol.toStringTag]: { value: "Module" }
89129
89191
  });
89130
89192
  require_chunk_Cek0wNdY();
89131
- var require_dist10 = require_dist_CEUwB91M();
89193
+ var require_dist10 = require_dist_CNxDnJwz();
89132
89194
  var SECTION_TITLES = {
89133
89195
  server: "Server",
89134
89196
  auth: "Authentication"
@@ -107189,7 +107251,7 @@ var require_winston_logging = __commonJS({
107189
107251
  [Symbol.toStringTag]: { value: "Module" }
107190
107252
  });
107191
107253
  var require_chunk = require_chunk_Cek0wNdY();
107192
- var require_dist10 = require_dist_CEUwB91M();
107254
+ var require_dist10 = require_dist_CNxDnJwz();
107193
107255
  var require_formatter = require_formatter_DqAKDlvN();
107194
107256
  var node_path = __require("path");
107195
107257
  node_path = require_chunk.__toESM(node_path);
@@ -131799,7 +131861,7 @@ var require_dist3 = __commonJS({
131799
131861
  "use strict";
131800
131862
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
131801
131863
  var require_chunk = require_chunk_Cek0wNdY();
131802
- var require_dist10 = require_dist_CEUwB91M();
131864
+ var require_dist10 = require_dist_CNxDnJwz();
131803
131865
  var require_builtins_alerts_alerts_addon = require_alerts_addon();
131804
131866
  require_alerts();
131805
131867
  var require_formatter = require_formatter_DqAKDlvN();
@@ -234187,6 +234249,49 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
234187
234249
  deviceId: zod.z.number().int().optional(),
234188
234250
  base64: zod.z.string().optional()
234189
234251
  });
234252
+ var IdentitySampleAuditRowSchema = zod.z.object({
234253
+ sampleId: zod.z.string(),
234254
+ enrolledAt: zod.z.number().int(),
234255
+ deviceId: zod.z.number().int().optional(),
234256
+ source: zod.z.enum(["detected", "photo"]),
234257
+ /** The enrolled crop's media key, so the panel can show the evidence. */
234258
+ mediaKey: zod.z.string().optional(),
234259
+ /**
234260
+ * False = the sample is stamped with a DIFFERENT face model, and a cosine
234261
+ * across feature spaces is a well-formed float with no meaning. Every number
234262
+ * below then says nothing — it must read as "cannot say", never as an
234263
+ * accusation and never as a clean bill: this list ends in a Remove button.
234264
+ */
234265
+ comparable: zod.z.boolean(),
234266
+ /** Mean cosine against this person's other samples. Null when there are none
234267
+ * to compare with — never 0, which would read as "opposite". */
234268
+ selfMean: zod.z.number().nullable(),
234269
+ /** The other person this sample looks most like, when it looks like one.
234270
+ * This is the half that convicts: not looking like yourself can be a hard
234271
+ * angle; looking like someone the gallery can NAME is a mis-enrolment. */
234272
+ bestForeign: zod.z.object({
234273
+ identityId: zod.z.string(),
234274
+ name: zod.z.string(),
234275
+ score: zod.z.number()
234276
+ }).optional(),
234277
+ /** 0 = nothing to say. Higher = look at this one sooner. */
234278
+ suspicion: zod.z.number()
234279
+ });
234280
+ var IdentitySampleAuditSchema = zod.z.object({
234281
+ identityId: zod.z.string(),
234282
+ name: zod.z.string(),
234283
+ /** The cluster face model every comparison was made in. */
234284
+ modelId: zod.z.string(),
234285
+ totalSamples: zod.z.number().int(),
234286
+ comparableSamples: zod.z.number().int(),
234287
+ flagged: zod.z.number().int(),
234288
+ /** The bar `flagged` counts against, so the panel states the RULE and not
234289
+ * only its current result. */
234290
+ flagThreshold: zod.z.number(),
234291
+ /** Worst first. A row with nothing to say still appears, at the bottom: the
234292
+ * operator asked to see the gallery, not only its accusations. */
234293
+ rows: zod.z.array(IdentitySampleAuditRowSchema).readonly()
234294
+ });
234190
234295
  var FaceInfoSchema = zod.z.object({
234191
234296
  faceId: zod.z.string(),
234192
234297
  deviceId: zod.z.number().int(),
@@ -234314,6 +234419,19 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
234314
234419
  auth: "admin"
234315
234420
  }),
234316
234421
  listIdentitySamples: require_sleep.method(zod.z.object({ identityId: zod.z.string() }), zod.z.array(IdentitySampleInfoSchema).readonly()),
234422
+ /**
234423
+ * Re-analyse ONE person's enrolled samples against the whole gallery.
234424
+ *
234425
+ * A pure read — no write, no inference, just dot products over vectors the
234426
+ * hub already holds (327 of them on this cluster). `admin` for the same
234427
+ * reason `listIdentitySamples` is: the answer names every enrolled person
234428
+ * and how well one person's samples match them, which is the gallery's
234429
+ * shape and not a viewer-level fact.
234430
+ *
234431
+ * Removal deliberately stays `removeSample`: an analysis that could also
234432
+ * delete would be one confirmation away from emptying a gallery.
234433
+ */
234434
+ auditIdentitySamples: require_sleep.method(zod.z.object({ identityId: zod.z.string().min(1) }), IdentitySampleAuditSchema, { auth: "admin" }),
234317
234435
  removeSample: require_sleep.method(zod.z.object({
234318
234436
  identityId: zod.z.string(),
234319
234437
  sampleId: zod.z.string()
@@ -247063,6 +247181,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
247063
247181
  addonId: null,
247064
247182
  access: "create"
247065
247183
  },
247184
+ "faceGallery.auditIdentitySamples": {
247185
+ capName: "face-gallery",
247186
+ capScope: "system",
247187
+ addonId: null,
247188
+ access: "view"
247189
+ },
247066
247190
  "faceGallery.createIdentity": {
247067
247191
  capName: "face-gallery",
247068
247192
  capScope: "system",
@@ -254237,6 +254361,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
254237
254361
  renameIdentity: (input) => dispatch("faceGallery", "renameIdentity", "mutation", input),
254238
254362
  deleteIdentity: (input) => dispatch("faceGallery", "deleteIdentity", "mutation", input),
254239
254363
  listIdentitySamples: (input) => dispatch("faceGallery", "listIdentitySamples", "query", input),
254364
+ auditIdentitySamples: (input) => dispatch("faceGallery", "auditIdentitySamples", "query", input),
254240
254365
  removeSample: (input) => dispatch("faceGallery", "removeSample", "mutation", input),
254241
254366
  getFaceMedia: (input) => dispatch("faceGallery", "getFaceMedia", "query", input),
254242
254367
  assignFace: (input) => dispatch("faceGallery", "assignFace", "mutation", input),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstack",
3
- "version": "1.2.124",
3
+ "version": "1.2.125",
4
4
  "description": "CLI tool for managing and running CamStack server",
5
5
  "keywords": [
6
6
  "camstack",