@camstack/types 1.2.123 → 1.2.126

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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_event_category = require("./event-category-BaEgqJNv.js");
3
- const require_sleep = require("./sleep-DUxF5DdC.js");
3
+ const require_sleep = require("./sleep-CWWLTM6W.js");
4
4
  const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
5
5
  const require_enums = require("./enums.js");
6
6
  const require_err_msg = require("./err-msg-COpsHMw2.js");
@@ -1193,6 +1193,69 @@ function composeSwitchedOff(input) {
1193
1193
  };
1194
1194
  }
1195
1195
  //#endregion
1196
+ //#region src/interfaces/config-ui-secrets.ts
1197
+ /**
1198
+ * The value a redacted secret is replaced with on every read surface.
1199
+ *
1200
+ * It is also the WRITE-BACK token: an `upsertLocation` that sends this value
1201
+ * back for a key means "keep what is stored", which is what lets an operator
1202
+ * rename a location without retyping its password. A literal an operator could
1203
+ * plausibly choose as a real password would turn that convenience into a way
1204
+ * to lock yourself out, hence the sentinel shape.
1205
+ */
1206
+ var REDACTED_SECRET = "__camstack_redacted__";
1207
+ /** Is this field's stored value a credential? */
1208
+ function isSecretConfigField(field) {
1209
+ if (field.type === "password") return true;
1210
+ return "secret" in field && field.secret === true;
1211
+ }
1212
+ /**
1213
+ * Every config key in `schema` whose value is a secret, including keys nested
1214
+ * inside `group` / `sub-tabs` containers.
1215
+ */
1216
+ function collectSecretConfigKeys(schema) {
1217
+ const keys = /* @__PURE__ */ new Set();
1218
+ for (const section of sectionsOf(schema)) for (const field of fieldsOf(section)) walkField(field, keys);
1219
+ return keys;
1220
+ }
1221
+ /**
1222
+ * True when the value is a readable schema declaring at least one field of any
1223
+ * kind. Lets a caller tell "this provider has no secrets" from "this provider's
1224
+ * schema could not be read", which are the same empty set otherwise.
1225
+ */
1226
+ function schemaDeclaresAnyField(schema) {
1227
+ for (const section of sectionsOf(schema)) if (fieldsOf(section).length > 0) return true;
1228
+ return false;
1229
+ }
1230
+ function isRecord$2(value) {
1231
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1232
+ }
1233
+ function sectionsOf(schema) {
1234
+ if (!isRecord$2(schema)) return [];
1235
+ const sections = schema["sections"];
1236
+ return Array.isArray(sections) ? sections : [];
1237
+ }
1238
+ function fieldsOf(node) {
1239
+ if (!isRecord$2(node)) return [];
1240
+ const fields = node["fields"];
1241
+ return Array.isArray(fields) ? fields : [];
1242
+ }
1243
+ function walkField(field, out) {
1244
+ if (!isRecord$2(field)) return;
1245
+ const type = field["type"];
1246
+ const key = field["key"];
1247
+ if ((type === "password" || field["secret"] === true) && typeof key === "string" && key.length > 0) out.add(key);
1248
+ if (type === "group") {
1249
+ for (const child of fieldsOf(field)) walkField(child, out);
1250
+ return;
1251
+ }
1252
+ if (type === "sub-tabs") {
1253
+ const tabs = field["tabs"];
1254
+ if (!Array.isArray(tabs)) return;
1255
+ for (const tab of tabs) for (const child of fieldsOf(tab)) walkField(child, out);
1256
+ }
1257
+ }
1258
+ //#endregion
1196
1259
  //#region src/interfaces/device-capabilities/camera.ts
1197
1260
  /** Friendly display labels for stream quality IDs. */
1198
1261
  var STREAM_QUALITY_LABELS = {
@@ -2225,18 +2288,61 @@ var RelocateFootageInputSchema = zod.z.object({
2225
2288
  * `RecordingConfig.enabled` or camera wrapper bindings. */
2226
2289
  var StorageMigrationLeaseInputSchema = zod.z.object({ leaseId: zod.z.string().min(1) });
2227
2290
  var StorageMigrationFootageMoveInputSchema = RelocateFootageInputSchema.extend({ leaseId: zod.z.string().min(1) });
2291
+ /**
2292
+ * What a `relocateMedia` pass DOES. One engine, three passes — never a second
2293
+ * mover (the engine already walks both collections with a timestamp cursor and
2294
+ * already has a stamp-without-copy path).
2295
+ *
2296
+ * - `move` — the default and the historical behaviour: event-media and
2297
+ * retrain blobs move to `toLocationId` and their rows are
2298
+ * stamped. The enrolled gallery is skipped (D197).
2299
+ * - `seal` — ROWS ONLY, no bytes. Every row whose `locationId` is NULL is
2300
+ * stamped with `toLocationId`. `toLocationId` here is the id the
2301
+ * bytes ALREADY sit on — today's `eventMedia` default — because
2302
+ * a NULL row means "wherever `eventMedia` points *now*", and the
2303
+ * instant a repoint moves that pointer the row reads from the
2304
+ * new disk while its bytes are on the old one.
2305
+ * - `gallery` — the inverse selection of `move`: ONLY the retention-exempt
2306
+ * (enrolled-gallery) rows, which `move` deliberately skips.
2307
+ * `galleryMedia` is `cardinality: 'single'`, so this pass can
2308
+ * never run beside a live second location: it is stop-the-world
2309
+ * by construction, which is acceptable only because the gallery
2310
+ * is a few KB per enrolled sample.
2311
+ */
2312
+ var MediaRelocateModeSchema = zod.z.enum([
2313
+ "move",
2314
+ "seal",
2315
+ "gallery"
2316
+ ]);
2228
2317
  var RelocateMediaInputSchema = zod.z.object({
2229
2318
  toLocationId: zod.z.string(),
2230
- throttleMbps: zod.z.number().min(1).max(1e3).optional()
2319
+ throttleMbps: zod.z.number().min(1).max(1e3).optional(),
2320
+ /** Omitted = `move`, the pre-existing behaviour. */
2321
+ mode: MediaRelocateModeSchema.optional()
2322
+ });
2323
+ /** How many rows still carry NO `locationId` — the population a repoint would
2324
+ * silently re-aim at a disk that does not hold their bytes. Zero is the only
2325
+ * value that permits a non-blocking `eventMedia` cutover. */
2326
+ var UnstampedEventMediaCountSchema = zod.z.object({
2327
+ media: zod.z.number().int().nonnegative(),
2328
+ retrainFrames: zod.z.number().int().nonnegative(),
2329
+ total: zod.z.number().int().nonnegative()
2231
2330
  });
2232
2331
  var StorageMigrationMediaMoveInputSchema = RelocateMediaInputSchema.extend({ leaseId: zod.z.string().min(1) });
2233
- /** The independently selectable logical storage classes. `recordings`
2234
- * encompasses the high and mid segment profiles; `recordingsLow` is low
2235
- * segments; `eventMedia` is post-analysis blobs. */
2332
+ /** The independently selectable logical storage classes — every class
2333
+ * `storage.listLocationDeclarations` reports, so an operator never meets a
2334
+ * Zod enum error where they should meet an explanation.
2335
+ *
2336
+ * `recordings` encompasses the high and mid segment profiles; `recordingsLow`
2337
+ * is low segments; `eventMedia` is post-analysis blobs; `galleryMedia` is the
2338
+ * enrolled gallery; `backups` is the system backup archive. The last two have
2339
+ * their own rules — see {@link StorageMigrationFindingCodeSchema}. */
2236
2340
  var StorageMigrationClassSchema = zod.z.enum([
2237
2341
  "recordings",
2238
2342
  "recordingsLow",
2239
- "eventMedia"
2343
+ "eventMedia",
2344
+ "backups",
2345
+ "galleryMedia"
2240
2346
  ]);
2241
2347
  /** A destination is always an existing, fully-qualified location id. The
2242
2348
  * migration API intentionally never changes a source location's `basePath`:
@@ -2244,20 +2350,56 @@ var StorageMigrationClassSchema = zod.z.enum([
2244
2350
  var StorageMigrationDestinationsSchema = zod.z.object({
2245
2351
  recordings: zod.z.string().min(1).optional(),
2246
2352
  recordingsLow: zod.z.string().min(1).optional(),
2247
- eventMedia: zod.z.string().min(1).optional()
2353
+ eventMedia: zod.z.string().min(1).optional(),
2354
+ backups: zod.z.string().min(1).optional(),
2355
+ galleryMedia: zod.z.string().min(1).optional()
2248
2356
  }).refine((value) => Object.keys(value).length > 0, { message: "select at least one storage class" });
2357
+ /**
2358
+ * How a migration sequences the cutover against the byte move.
2359
+ *
2360
+ * - `blocking` — the historical order: pause, move every byte, repoint,
2361
+ * resume. Recording is stopped for the whole move. Right
2362
+ * for a small or a cold class, and the only legal mode for
2363
+ * a `cardinality: 'single'` class.
2364
+ * - `nonBlocking` — repoint FIRST, drain behind: seal, pause, repoint,
2365
+ * refresh, resume, then move the past with everything
2366
+ * running. The pause is three bounded instants (a detach +
2367
+ * attach round, a write-gate drain, a lease) instead of one
2368
+ * bounded by bytes. 1.09 TB at 7–14 MB/s is thirty hours of
2369
+ * stopped recording under `blocking`; the same move is
2370
+ * seconds of stopped recording under `nonBlocking`.
2371
+ *
2372
+ * The mode is on the JOB, not only on the input, because `status` is where an
2373
+ * operator finds out which one is running.
2374
+ */
2375
+ var StorageMigrationModeSchema = zod.z.enum(["blocking", "nonBlocking"]);
2249
2376
  /** Shared input for planning and starting an orchestrated storage migration. */
2250
2377
  var StorageMigrationInputSchema = zod.z.object({
2251
2378
  destinations: StorageMigrationDestinationsSchema,
2252
- throttleMbps: zod.z.number().min(1).max(1e3).optional()
2379
+ throttleMbps: zod.z.number().min(1).max(1e3).optional(),
2380
+ /** Omitted = `blocking`, which stays the default. */
2381
+ mode: StorageMigrationModeSchema.optional()
2253
2382
  });
2254
- /** The durable coordinator state machine. The only phase that changes default
2255
- * locations is `repointing`, after every selected mover has completed and been
2256
- * verified. */
2383
+ /**
2384
+ * The durable coordinator state machine.
2385
+ *
2386
+ * `blocking`:
2387
+ * planning → pausing → moving → verifying → repointing → refreshing → resuming → done
2388
+ *
2389
+ * `nonBlocking`:
2390
+ * planning → sealing → pausing → repointing → refreshing → resuming → draining → verifying → done
2391
+ *
2392
+ * Same phases, different order plus two new ones — not a second mover.
2393
+ * `sealing` closes the `eventMedia` NULL-row hole BEFORE anything is paused;
2394
+ * `draining` runs the same movers UNLEASED, after every writer is back up.
2395
+ * `repointing` is still the only phase that changes a default location.
2396
+ */
2257
2397
  var StorageMigrationPhaseSchema = zod.z.enum([
2258
2398
  "planning",
2399
+ "sealing",
2259
2400
  "pausing",
2260
2401
  "moving",
2402
+ "draining",
2261
2403
  "verifying",
2262
2404
  "repointing",
2263
2405
  "refreshing",
@@ -2271,17 +2413,56 @@ var StorageMigrationParticipantSchema = zod.z.enum([
2271
2413
  "recorder",
2272
2414
  "analytics"
2273
2415
  ]);
2416
+ /**
2417
+ * The mover's own numbers, folded onto the coordinator's durable move record.
2418
+ *
2419
+ * The long half of a non-blocking migration is `draining`, and it is measured
2420
+ * in hours: 136 885 files at ~4 MB/s is about five of them. Before this shape
2421
+ * existed the only place those numbers appeared was a Loki line, so an operator
2422
+ * watching the Admin UI saw `phase: draining` and nothing else for a whole
2423
+ * afternoon.
2424
+ *
2425
+ * It is POLLED, never pushed. Events are telemetry and may be dropped
2426
+ * (D8/D11), and a dropped progress event is indistinguishable from a stalled
2427
+ * mover — which is the exact failure this is meant to end. The coordinator's
2428
+ * `waitForMoves` already fetches the whole {@link RelocateJob} on every tick to
2429
+ * read `state`; folding the counters costs no extra read and makes the durable
2430
+ * record say afterwards how far a move actually got.
2431
+ *
2432
+ * `filesTotal` is `null` for "no honest denominator" and is never zero-filled:
2433
+ * a windowed footage job (`sinceMs`) and a node with no ledger both genuinely
2434
+ * cannot say M, and a 0 there would render as "100 % done".
2435
+ */
2436
+ var StorageMigrationMoveProgressSchema = zod.z.object({
2437
+ filesMoved: zod.z.number().int().nonnegative(),
2438
+ /** The archive census — the **M** of "N of M" (D295). `null` = unknowable. */
2439
+ filesTotal: zod.z.number().int().nonnegative().nullable(),
2440
+ bytesMoved: zod.z.number().int().nonnegative(),
2441
+ /** The MOVER's start, not the migration's: a drain restarted after an addon
2442
+ * crash gets a new mover, and a rate computed from the migration's start
2443
+ * would silently average in the time nothing was running. */
2444
+ startedAt: zod.z.number(),
2445
+ /** When the coordinator last read these numbers. Paired with `startedAt` it
2446
+ * is the only honest rate: both clocks are the hub's, so a UI never has to
2447
+ * subtract its own. */
2448
+ observedAt: zod.z.number()
2449
+ });
2274
2450
  var StorageMigrationMoveSchema = zod.z.object({
2275
2451
  storageClass: StorageMigrationClassSchema,
2276
2452
  fromLocationId: zod.z.string(),
2277
2453
  toLocationId: zod.z.string(),
2278
2454
  moverJobId: zod.z.string().nullable(),
2279
2455
  state: RelocateJobStateSchema.nullable(),
2280
- error: zod.z.string().nullable()
2456
+ error: zod.z.string().nullable(),
2457
+ /** Last observed mover counters; `null` until the mover has been polled once. */
2458
+ progress: StorageMigrationMoveProgressSchema.nullable()
2281
2459
  });
2282
2460
  var StorageMigrationJobSchema = zod.z.object({
2283
2461
  jobId: zod.z.string(),
2284
2462
  phase: StorageMigrationPhaseSchema,
2463
+ /** Which order this job is running. `status` is the only place an operator
2464
+ * can tell a seconds-long cutover from a thirty-hour one. */
2465
+ mode: StorageMigrationModeSchema,
2285
2466
  destinations: StorageMigrationDestinationsSchema,
2286
2467
  throttleMbps: zod.z.number(),
2287
2468
  moves: zod.z.array(StorageMigrationMoveSchema),
@@ -2294,13 +2475,154 @@ var StorageMigrationJobSchema = zod.z.object({
2294
2475
  finishedAt: zod.z.number().nullable(),
2295
2476
  error: zod.z.string().nullable()
2296
2477
  });
2478
+ /**
2479
+ * What the planner NOTICED but did not refuse.
2480
+ *
2481
+ * A refusal throws — the operator cannot miss it. A finding is the other half:
2482
+ * something true about this plan that changes what the operator should expect,
2483
+ * surfaced where they read it rather than in a document they will not open.
2484
+ *
2485
+ * - `sharesDeviceWithSource` — the destination realpath's to the same place as
2486
+ * the source. The move will be a row re-stamp, not a byte move, and it buys
2487
+ * no redundancy. NOTE: this is PATH identity, not `st_dev` — two distinct
2488
+ * directories on one filesystem are NOT detected. See
2489
+ * `deviceIdentityUnknown`.
2490
+ * - `deviceIdentityUnknown` — a location carries a `nodeId` other than this
2491
+ * one (or has no `basePath`), so its realpath cannot be taken here and the
2492
+ * same-device question was not answered at all. Stated rather than assumed
2493
+ * clear: a check that silently never fires is worse than no check.
2494
+ * - `unstampedEventMediaRows` — how many `eventMedia`/retrain rows still carry
2495
+ * no `locationId`. Non-zero refuses a `nonBlocking` cutover.
2496
+ * - `blockingOnly` — this class is `cardinality: 'single'`, so it can never
2497
+ * span two locations and can only ever be moved stop-the-world.
2498
+ * - `noMover` — the class is selectable and planned, but no addon owns a mover
2499
+ * for it. The migration cannot move its bytes.
2500
+ */
2501
+ var StorageMigrationFindingCodeSchema = zod.z.enum([
2502
+ "sharesDeviceWithSource",
2503
+ "deviceIdentityUnknown",
2504
+ "unstampedEventMediaRows",
2505
+ "blockingOnly",
2506
+ "noMover"
2507
+ ]);
2508
+ var StorageMigrationFindingSchema = zod.z.object({
2509
+ code: StorageMigrationFindingCodeSchema,
2510
+ storageClass: StorageMigrationClassSchema,
2511
+ /** Human-readable, already carrying the ids and counts. */
2512
+ message: zod.z.string()
2513
+ });
2297
2514
  var StorageMigrationPlanSchema = zod.z.object({
2298
2515
  destinations: StorageMigrationDestinationsSchema,
2516
+ /** The mode this plan was built for. A plan is only valid for its mode: the
2517
+ * `eventMedia` seal gate and the single-cardinality refusal both depend on
2518
+ * it. */
2519
+ mode: StorageMigrationModeSchema,
2299
2520
  moves: zod.z.array(zod.z.object({
2300
2521
  storageClass: StorageMigrationClassSchema,
2301
2522
  fromLocationId: zod.z.string(),
2302
2523
  toLocationId: zod.z.string()
2303
- }))
2524
+ })),
2525
+ findings: zod.z.array(StorageMigrationFindingSchema)
2526
+ });
2527
+ /**
2528
+ * Which single-flight engine owns a class of work.
2529
+ *
2530
+ * Shared rather than re-declared per consumer: the coordinator lanes its moves
2531
+ * by it, and `storageMigration.movers` labels a mover with it so an operator
2532
+ * can see *which* engine is busy when a drain refuses to start beside another.
2533
+ */
2534
+ var StorageMigrationLaneSchema = zod.z.enum(["footage", "media"]);
2535
+ /**
2536
+ * A mover as it exists RIGHT NOW, whether or not a migration job owns it.
2537
+ *
2538
+ * The coordinator's job record is the state of record for a migration, and its
2539
+ * moves carry {@link StorageMigrationMoveProgress}. But the movers are usable
2540
+ * standalone — `recording.relocateFootage` and `pipelineAnalytics.relocateMedia`
2541
+ * are both operator-callable, and on 2026-08-29 a five-hour drain was armed that
2542
+ * way because no supported UI path existed. A mover armed like that has no job
2543
+ * to fold progress into, so it has to be readable on its own or it is invisible.
2544
+ *
2545
+ * `migrationJobId` is what tells the two apart: `null` means nothing here
2546
+ * orchestrated it.
2547
+ */
2548
+ var StorageMigrationMoverSchema = zod.z.object({
2549
+ lane: StorageMigrationLaneSchema,
2550
+ job: RelocateJobSchema,
2551
+ /** The coordinator job that armed this mover, or `null` for a mover armed
2552
+ * directly against the owning addon. */
2553
+ migrationJobId: zod.z.string().nullable(),
2554
+ /** When the hub read these counters. Stamped here so a rate is `bytesMoved`
2555
+ * over (`observedAt` − `job.startedAt`) with BOTH ends on the hub's clock —
2556
+ * a browser subtracting its own `Date.now()` from a server `startedAt` is a
2557
+ * rate made of two different clocks. */
2558
+ observedAt: zod.z.number()
2559
+ });
2560
+ /**
2561
+ * What a SOURCE still holds for one storage class — the number that makes a
2562
+ * "drain remaining" action honest rather than hopeful.
2563
+ *
2564
+ * It comes from the archive (`SegmentHourLedger.census` for footage, the media
2565
+ * engine's own selection count for media), never from the resident index: a
2566
+ * drain sized off `RecordingIndex` is what reported `done` over 80.3 GB it had
2567
+ * never been told about (D295).
2568
+ *
2569
+ * `items`/`bytes` are `null` for "the archive could not be asked", which is
2570
+ * deliberately NOT zero: a drain is still offered for an unknown residue,
2571
+ * because refusing on an unanswerable read would hide exactly the case an
2572
+ * operator needs to act on.
2573
+ */
2574
+ var StorageMigrationResidueSchema = zod.z.object({
2575
+ storageClass: StorageMigrationClassSchema,
2576
+ /** The location still holding the data. `'*'` for the media lane, whose rows
2577
+ * move from wherever they are rather than from one named source. */
2578
+ fromLocationId: zod.z.string(),
2579
+ /** Where a drain would move it — the class's CURRENT default. */
2580
+ toLocationId: zod.z.string(),
2581
+ /** Segments (footage lane) or rows (media lane) still on the source. */
2582
+ items: zod.z.number().int().nonnegative().nullable(),
2583
+ /** Bytes on the source; `null` when the lane counts rows rather than bytes. */
2584
+ bytes: zod.z.number().int().nonnegative().nullable()
2585
+ });
2586
+ /**
2587
+ * Run the DRAIN half and nothing else.
2588
+ *
2589
+ * A migration that reached `done` has already repointed, so `start` correctly
2590
+ * refuses its destination ("already the default") — there is nothing left to
2591
+ * repoint. But the drain can fail, be cancelled, be interrupted by a restart,
2592
+ * or finish against a work list that was a tenth of the archive (D295), and
2593
+ * before this there was no supported way to run only that half: the only way
2594
+ * through was calling `recording.relocateFootage` by hand over admin tRPC.
2595
+ *
2596
+ * `drain` NEVER calls `setDefaultLocations`. That is what keeps `start`'s
2597
+ * refusal meaningful: the two verbs are disjoint, so nothing here can silently
2598
+ * re-repoint a class that is already migrated.
2599
+ */
2600
+ var StorageMigrationDrainInputSchema = zod.z.object({
2601
+ /** The classes to drain. Each must appear in `storageMigration.residue`, so
2602
+ * a class whose source is already empty is refused rather than started. */
2603
+ classes: zod.z.array(StorageMigrationClassSchema).min(1),
2604
+ throttleMbps: zod.z.number().min(1).max(1e3).optional()
2605
+ });
2606
+ /** What a footage source still holds, asked of the durable hour ledger. */
2607
+ var RelocateResidueInputSchema = zod.z.object({
2608
+ fromLocationId: zod.z.string().min(1),
2609
+ /** Narrow to one logical class; omit for every profile on the location. */
2610
+ footageClass: RelocateFootageClassSchema.optional()
2611
+ });
2612
+ /** `null` = the archive could not answer (no ledger on this node, or the
2613
+ * aggregate failed). Never conflated with an empty source. */
2614
+ var RelocateResidueSchema = zod.z.object({
2615
+ segments: zod.z.number().int().nonnegative(),
2616
+ bytes: zod.z.number().int().nonnegative()
2617
+ }).nullable();
2618
+ /** How many rows a media pass would still act on against a given target — the
2619
+ * media lane's denominator AND its residue, from ONE derivation so the two can
2620
+ * never disagree. `null` = the count could not be taken. */
2621
+ var RelocatableMediaCountSchema = zod.z.object({ rows: zod.z.number().int().nonnegative() }).nullable();
2622
+ var RelocatableMediaCountInputSchema = zod.z.object({
2623
+ toLocationId: zod.z.string().min(1),
2624
+ /** Omitted = `move`. */
2625
+ mode: MediaRelocateModeSchema.optional()
2304
2626
  });
2305
2627
  //#endregion
2306
2628
  //#region src/interfaces/server-analysis.ts
@@ -2419,6 +2741,38 @@ var StorageLocationRefSchema = zod.z.union([StorageLocationTypeSchema, zod.z.str
2419
2741
  * two addons declaring the same `id` must agree on `cardinality` (validated
2420
2742
  * at kernel aggregation time, not here).
2421
2743
  */
2744
+ /**
2745
+ * `StorageAccess` — how the service that DECLARED a storage-location kind
2746
+ * actually reaches the bytes. It is the constraint that decides which
2747
+ * `storage-provider`s may back a location of that kind.
2748
+ *
2749
+ * - `'local-path'` — the service asks `storage.resolve` for a path string and
2750
+ * then does its own `node:fs` I/O on it (the recorder's segment writer, the
2751
+ * post-analysis media roots). Only a provider that serves a genuine local
2752
+ * filesystem (`getProviderInfo().nodeLocal === true`) can satisfy that: a
2753
+ * remote provider's `resolve` returns a path on the REMOTE host, and
2754
+ * `fs.readdir` of it on this node either fails or — far worse — succeeds
2755
+ * against a same-named local directory that is something else entirely.
2756
+ *
2757
+ * - `'cap-mediated'` — every byte travels through the `storage` cap
2758
+ * (`read`/`write`, or `beginUpload`/`writeChunk`/`finalizeUpload`). The
2759
+ * service never sees a path, so any provider can back it. `backups` is the
2760
+ * one kind that qualifies today.
2761
+ *
2762
+ * Before this existed, `recordings` was unreachable by SFTP/S3/WebDAV only as
2763
+ * an EMERGENT property of how the recorder happened to be written. Nothing
2764
+ * refused the configuration; the first write simply went somewhere wrong, and
2765
+ * a recording write that goes wrong surfaces as a silent black window rather
2766
+ * than an error (the read path does not `stat`). This turns that accident into
2767
+ * a declared, enforced, testable refusal.
2768
+ */
2769
+ var StorageAccessSchema = zod.z.enum(["local-path", "cap-mediated"]);
2770
+ /**
2771
+ * What an ABSENT `access` means. Fail-closed: a declaration that says nothing
2772
+ * is treated as if it does raw filesystem I/O, so a remote provider is
2773
+ * refused for it. The permissive value must be written down.
2774
+ */
2775
+ var STORAGE_ACCESS_FALLBACK = "local-path";
2422
2776
  var StorageLocationDeclarationSchema = zod.z.object({
2423
2777
  /**
2424
2778
  * Global location identifier, e.g. `recordings` or `recordingsLow`.
@@ -2438,6 +2792,19 @@ var StorageLocationDeclarationSchema = zod.z.object({
2438
2792
  */
2439
2793
  cardinality: zod.z.enum(["single", "multi"]),
2440
2794
  /**
2795
+ * HOW the declaring service reaches the bytes — and therefore WHICH
2796
+ * providers may back a location of this kind. See {@link StorageAccessSchema}
2797
+ * and {@link STORAGE_ACCESS_FALLBACK}.
2798
+ *
2799
+ * Absent means `'local-path'`. That default is FAIL-CLOSED on purpose: it
2800
+ * can only over-restrict (refuse a remote provider for a kind that might
2801
+ * have coped) and never under-restrict. Declaring `'cap-mediated'` is the
2802
+ * permissive direction and is therefore never inferred — a repo guard
2803
+ * (`scripts/check-storage-access-declarations.ts`) refuses to let it be
2804
+ * reached by omission.
2805
+ */
2806
+ access: StorageAccessSchema.optional(),
2807
+ /**
2441
2808
  * When set, the default instance for this location inherits its resolved
2442
2809
  * root from the named location's default instance. Useful for derivative
2443
2810
  * slots (e.g. `recordingsLow` → `recordings`) so operators only need to
@@ -17548,8 +17915,10 @@ var TrackSchema = zod.z.object({
17548
17915
  lastSeen: zod.z.number(),
17549
17916
  /** Frame-rate position history (subject to maxPositionHistory cap). */
17550
17917
  positions: zod.z.array(TrackPositionSchema).readonly(),
17551
- /** Periodic snapshots at snapshotIntervalMs cadence (subject to
17552
- * saveThumbnails policy). */
17918
+ /** Periodic snapshots at snapshotIntervalMs cadence DEBUG media, produced
17919
+ * only while `MediaSettings.debugMediaEnabled` is on for the camera (D299;
17920
+ * the retired `saveThumbnails` used to gate this and the rolling
17921
+ * `lastFrame` together). Empty is the healthy default, not a capture gap. */
17553
17922
  snapshots: zod.z.array(TrackSnapshotSchema).readonly(),
17554
17923
  /** Deduplicated zones the track has entered at least once. Zone IDS. */
17555
17924
  zonesVisited: zod.z.array(zod.z.string()).readonly(),
@@ -18630,6 +18999,32 @@ var pipelineAnalyticsCapability = {
18630
18999
  kind: "mutation",
18631
19000
  auth: "admin"
18632
19001
  }),
19002
+ /**
19003
+ * How many media / retrain rows still carry NO `locationId`.
19004
+ *
19005
+ * A NULL row means "wherever `eventMedia` points NOW", so the instant a
19006
+ * repoint moves that pointer every such row reads from the new disk while
19007
+ * its bytes are on the old one — the archive goes dark until a drain
19008
+ * happens to stamp it. This count is what the migration planner's
19009
+ * non-blocking gate reads; `relocateMedia({ mode: 'seal' })` is what drives
19010
+ * it to zero.
19011
+ */
19012
+ countUnstampedEventMedia: require_sleep.method(zod.z.object({}), UnstampedEventMediaCountSchema, { auth: "admin" }),
19013
+ /**
19014
+ * How many rows a pass would STILL act on against `toLocationId`.
19015
+ *
19016
+ * One derivation, two consumers: it is the media lane's denominator (the
19017
+ * **M** the footage lane gets from the ledger census — D295) and it is the
19018
+ * residue behind "drain remaining". Deriving them separately is how "N of M"
19019
+ * ends up comparing two different populations.
19020
+ *
19021
+ * `null` means the count could not be taken; it is never zero-filled,
19022
+ * because a zero here reads as "nothing left to move".
19023
+ */
19024
+ countRelocatableMedia: require_sleep.method(RelocatableMediaCountInputSchema, RelocatableMediaCountSchema, {
19025
+ kind: "query",
19026
+ auth: "admin"
19027
+ }),
18633
19028
  /** Every relocate job this addon knows about, newest first (in RAM: the
18634
19029
  * move is resumable, so a lost list costs nothing but the display). */
18635
19030
  listRelocateMediaJobs: require_sleep.method(zod.z.object({}), zod.z.array(RelocateJobSchema).readonly(), {
@@ -21702,7 +22097,24 @@ var storageCapability = {
21702
22097
  kind: "mutation",
21703
22098
  auth: "admin"
21704
22099
  }),
21705
- deleteLocation: require_sleep.method(zod.z.object({ id: zod.z.string() }), zod.z.void(), {
22100
+ /**
22101
+ * Remove a location record. REFUSES a location that still holds data —
22102
+ * deleting a drained location whose durable rows still name it is how this
22103
+ * hub acquired 2 131 ghost `recordings:high` segments, and playback does
22104
+ * not stat, so the operator sees a silent black window rather than an
22105
+ * error.
22106
+ *
22107
+ * `force` exists because the occupancy check is BEST-EFFORT and refuses on
22108
+ * "unknown" as well as on "occupied" (a read that fails must not authorise
22109
+ * a destruction — D49). A location on a removed disk, on another node, or
22110
+ * behind a remote provider answers "unknown" forever, and a refusal an
22111
+ * operator cannot override is its own failure mode. `force: true` is
22112
+ * logged, loudly, with what the check saw.
22113
+ */
22114
+ deleteLocation: require_sleep.method(zod.z.object({
22115
+ id: zod.z.string(),
22116
+ force: zod.z.boolean().optional()
22117
+ }), zod.z.void(), {
21706
22118
  kind: "mutation",
21707
22119
  auth: "admin"
21708
22120
  }),
@@ -21795,6 +22207,35 @@ var storageMigrationCapability = {
21795
22207
  cancel: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
21796
22208
  kind: "mutation",
21797
22209
  auth: "admin"
22210
+ }),
22211
+ /**
22212
+ * Every mover running RIGHT NOW, in both lanes, with its counters.
22213
+ *
22214
+ * `status` covers a migration's own moves — the coordinator folds their
22215
+ * progress onto the durable job record it is already polling. This covers
22216
+ * the other case, and it is not hypothetical: a drain armed straight against
22217
+ * `recording.relocateFootage` (the only path that existed before
22218
+ * {@link drain}) has no job to fold into and would otherwise be invisible.
22219
+ */
22220
+ movers: require_sleep.method(zod.z.object({}), zod.z.array(StorageMigrationMoverSchema).readonly(), { auth: "admin" }),
22221
+ /**
22222
+ * What each class's SOURCE still holds, from the archive — never from the
22223
+ * resident index (D295). Only classes with something left (or something
22224
+ * unknown) are listed, so an empty list means there is nothing to drain and
22225
+ * the UI has no honest button to offer.
22226
+ */
22227
+ residue: require_sleep.method(zod.z.object({}), zod.z.array(StorageMigrationResidueSchema).readonly(), { auth: "admin" }),
22228
+ /**
22229
+ * Run the drain half alone, on a class whose default has ALREADY moved.
22230
+ *
22231
+ * It never repoints anything, which is what lets `start` keep refusing a
22232
+ * destination that is already the default: the two verbs cannot be confused
22233
+ * for one another, and no operator can re-repoint a migrated class through
22234
+ * this door.
22235
+ */
22236
+ drain: require_sleep.method(StorageMigrationDrainInputSchema, zod.z.object({ jobId: zod.z.string() }), {
22237
+ kind: "mutation",
22238
+ auth: "admin"
21798
22239
  })
21799
22240
  }
21800
22241
  };
@@ -22367,12 +22808,38 @@ response: zod.z.record(zod.z.string(), zod.z.unknown()) }), zod.z.object({
22367
22808
  *
22368
22809
  * ## Why this is a capability and not a helper
22369
22810
  *
22370
- * Six stores in `addon-post-analysis` already hold vectors object CLIP, face,
22371
- * plate, vehicle, identity, and the event store's derivativesand every one of
22372
- * them keeps its vectors in a `JSON` settings-store column and ranks them by
22373
- * brute-force cosine in JS. Measured on the live hub that costs ~11.7 KB per row
22374
- * (512 floats as TEXT, `JSON.parse`d on every search) and made semantic search
22375
- * load 5,000 rows before ranking anything.
22811
+ * This capability was introduced with the claim that SIX stores in
22812
+ * `addon-post-analysis` held vectors in a `JSON` settings-store columnobject
22813
+ * CLIP, face, plate, vehicle, identity, and the event store's derivatives. That
22814
+ * claim was never true, and leaving it here made five stores look like pending
22815
+ * work when three of them have no vector at all. Counted column by column on
22816
+ * 2026-08-30, exactly THREE ever held one:
22817
+ *
22818
+ * - `object-clip` — 512-dim CLIP image embedding, migrated 2026-08-06.
22819
+ * - `faces.embedding` — 512-dim ArcFace face embedding, migrated 2026-08-30.
22820
+ * - `identity-samples.embedding` — the same ArcFace vector for an ENROLLED
22821
+ * face, migrated 2026-08-30 into its OWN index (see below).
22822
+ *
22823
+ * `plates` and `vehicle-samples` store a plate STRING and a score; `vehicles`
22824
+ * and `identities` store a name; the event store stores no derivative vector.
22825
+ * They are not migration candidates and never were.
22826
+ *
22827
+ * Measured on the live hub the JSON encoding cost ~11.7 KB per row (512 floats
22828
+ * as TEXT, `JSON.parse`d on every search) and made semantic search load 5,000
22829
+ * rows before ranking anything.
22830
+ *
22831
+ * ## One index per COMPARISON, never per encoder
22832
+ *
22833
+ * `faces` and `identity-samples` hold the same 512 ArcFace dims from the same
22834
+ * model, and they still get two indexes. An index is a set of things that are
22835
+ * ranked against each other and that live and die together, and these two are
22836
+ * neither: a `faces` row is TRACK-OWNED and cascades away with its track under
22837
+ * a per-camera capacity cap, an `identity-samples` row is retention-EXEMPT
22838
+ * forever and is the gallery every recognition ranks against. One index would
22839
+ * mean every gallery load and every reconcile carried a filter whose failure
22840
+ * mode is either ranking a candidate against itself or reclaiming an enrolled
22841
+ * person's only sample. The dimension they share is not a reason to share an
22842
+ * index; the question they answer is, and it differs.
22376
22843
  *
22377
22844
  * The fix is not a faster loop, it is a different backend — and the backend
22378
22845
  * should be replaceable without touching six callers. So: a singleton
@@ -22477,7 +22944,20 @@ var VectorQueryResultSchema = zod.z.object({
22477
22944
  */
22478
22945
  scanned: zod.z.number(),
22479
22946
  /** True when the backend could not consider every row that passed the filter. */
22480
- truncated: zod.z.boolean()
22947
+ truncated: zod.z.boolean(),
22948
+ /**
22949
+ * The `topK` the backend actually ran with.
22950
+ *
22951
+ * Every backend has a ceiling — sqlite-vec's is 4,096 — and a caller asking
22952
+ * past it used to learn nothing but a boolean, from a WARN in the provider's
22953
+ * own log rather than in its answer. That is how an audit asking for 20,000
22954
+ * consumed 4,096 and reported `examined: 4096` as if it had walked the index,
22955
+ * for weeks. `truncated` says THAT the answer was short; this says BY HOW
22956
+ * MUCH, in the return value, where the caller cannot fail to see it.
22957
+ *
22958
+ * Equals the requested `topK` whenever nothing was lowered.
22959
+ */
22960
+ effectiveTopK: zod.z.number().int().positive()
22481
22961
  });
22482
22962
  var VectorDeleteInputSchema = zod.z.object({
22483
22963
  index: zod.z.string(),
@@ -22506,6 +22986,68 @@ var VectorGetResultSchema = zod.z.object({ items: zod.z.array(zod.z.object({
22506
22986
  id: zod.z.string(),
22507
22987
  metadata: VectorMetadataSchema
22508
22988
  })) });
22989
+ /**
22990
+ * Ids to read back WITH their vectors.
22991
+ *
22992
+ * The sibling of {@link VectorGetResultSchema}, and deliberately a separate
22993
+ * method rather than a flag on it: `getByIds` promises no vectors and its one
22994
+ * caller depends on that promise. This one promises the opposite.
22995
+ *
22996
+ * It exists because a store cannot put its vectors here otherwise. An ArcFace
22997
+ * gallery is ranked IN PROCESS, per detection, against every enrolled sample —
22998
+ * a per-face cross-process KNN would be a network round trip inside the
22999
+ * recognition loop. So the gallery is loaded once and held in RAM, and loading
23000
+ * it requires the index to hand the floats back. Without this method the only
23001
+ * way to keep a readable vector is a JSON column, which is the thing this
23002
+ * capability exists to delete.
23003
+ *
23004
+ * BOUNDED BY THE CALLER: ids are named, never "everything". Enumerating an
23005
+ * index is {@link VectorScanInputSchema}'s job, and it returns no vectors.
23006
+ */
23007
+ var VectorFetchInputSchema = zod.z.object({
23008
+ index: zod.z.string(),
23009
+ ids: zod.z.array(zod.z.string())
23010
+ });
23011
+ var VectorFetchResultSchema = zod.z.object({ items: zod.z.array(zod.z.object({
23012
+ id: zod.z.string(),
23013
+ /** base64 Float32LE — the same wire form `upsert` accepts. */
23014
+ vector: zod.z.string(),
23015
+ metadata: VectorMetadataSchema
23016
+ })) });
23017
+ /**
23018
+ * ENUMERATE an index: one page of rows in a stable order, no ranking.
23019
+ *
23020
+ * A reconcile does not want the nearest rows, it wants ALL of them, and asking
23021
+ * a KNN for "all" is the wrong question twice over. It hits the backend's `k`
23022
+ * ceiling — 4,096 on sqlite-vec against a 22,128-row index — and it needs a
23023
+ * probe vector it does not have, so the audit passed a ZERO vector whose cosine
23024
+ * distance to every row is degenerate. `examined: 4096` then read as "we
23025
+ * looked" for as long as anyone cared to read it.
23026
+ *
23027
+ * This is the primitive that question actually needs: a bounded page, ordered
23028
+ * by the backend's own row order, costing no distance computation at all.
23029
+ * Vectors are NOT returned — an enumeration that shipped 2 KB per row would be
23030
+ * the full-table read this capability was built to stop.
23031
+ */
23032
+ var VectorScanInputSchema = zod.z.object({
23033
+ index: zod.z.string(),
23034
+ /** Opaque resume point. `0` starts at the top; pass back `nextCursor`. */
23035
+ cursor: zod.z.number().int().nonnegative().default(0),
23036
+ limit: zod.z.number().int().positive()
23037
+ });
23038
+ var VectorScanResultSchema = zod.z.object({
23039
+ items: zod.z.array(zod.z.object({
23040
+ id: zod.z.string(),
23041
+ metadata: VectorMetadataSchema
23042
+ })),
23043
+ /**
23044
+ * Where the next page starts, or `null` when the walk reached the end.
23045
+ *
23046
+ * `null` is the ONLY end-of-index signal. A caller must not infer the end
23047
+ * from a short page: a backend is free to return fewer rows than asked.
23048
+ */
23049
+ nextCursor: zod.z.number().int().nonnegative().nullable()
23050
+ });
22509
23051
  var VectorStatsInputSchema = zod.z.object({ index: zod.z.string() });
22510
23052
  var VectorStatsResultSchema = zod.z.object({
22511
23053
  /** Provider id, so an operator can tell brute force from an ANN index. */
@@ -22544,6 +23086,10 @@ var vectorStoreCapability = {
22544
23086
  query: require_sleep.method(VectorQueryInputSchema, VectorQueryResultSchema, { auth: "admin" }),
22545
23087
  /** Metadata by id, no vectors — see {@link VectorGetResultSchema}. */
22546
23088
  getByIds: require_sleep.method(VectorGetInputSchema, VectorGetResultSchema, { auth: "admin" }),
23089
+ /** Metadata AND vectors, by named id — see {@link VectorFetchInputSchema}. */
23090
+ fetchByIds: require_sleep.method(VectorFetchInputSchema, VectorFetchResultSchema, { auth: "admin" }),
23091
+ /** One page of the whole index, unranked — see {@link VectorScanInputSchema}. */
23092
+ scan: require_sleep.method(VectorScanInputSchema, VectorScanResultSchema, { auth: "admin" }),
22547
23093
  deleteByIds: require_sleep.method(VectorDeleteInputSchema, VectorDeleteResultSchema, {
22548
23094
  kind: "mutation",
22549
23095
  auth: "admin"
@@ -30506,6 +31052,20 @@ var recordingCapability = {
30506
31052
  kind: "query",
30507
31053
  auth: "admin"
30508
31054
  }),
31055
+ /**
31056
+ * What a location STILL holds, asked of the durable hour ledger.
31057
+ *
31058
+ * The number behind "drain remaining": segments and bytes that would still
31059
+ * have to move off `fromLocationId`. It is a ledger aggregate — the archive
31060
+ * — because the resident index is not the archive (D295), and a drain sized
31061
+ * off the index is exactly what reported `done` over 80.3 GB on 2026-08-29.
31062
+ * `null` means the archive could not be asked (no ledger on this node, or
31063
+ * the aggregate failed) and is never conflated with an empty source.
31064
+ */
31065
+ getRelocateResidue: require_sleep.method(RelocateResidueInputSchema, RelocateResidueSchema, {
31066
+ kind: "query",
31067
+ auth: "admin"
31068
+ }),
30509
31069
  /** Cancel a running or queued relocate job. A queued job never runs. */
30510
31070
  cancelRelocateJob: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
30511
31071
  kind: "mutation",
@@ -40739,6 +41299,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
40739
41299
  addonId: null,
40740
41300
  access: "create"
40741
41301
  },
41302
+ "pipelineAnalytics.countRelocatableMedia": {
41303
+ capName: "pipeline-analytics",
41304
+ capScope: "device",
41305
+ addonId: null,
41306
+ access: "view"
41307
+ },
41308
+ "pipelineAnalytics.countUnstampedEventMedia": {
41309
+ capName: "pipeline-analytics",
41310
+ capScope: "device",
41311
+ addonId: null,
41312
+ access: "view"
41313
+ },
40742
41314
  "pipelineAnalytics.deleteDeviceEvents": {
40743
41315
  capName: "pipeline-analytics",
40744
41316
  capScope: "device",
@@ -41897,6 +42469,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
41897
42469
  addonId: null,
41898
42470
  access: "view"
41899
42471
  },
42472
+ "recording.getRelocateResidue": {
42473
+ capName: "recording",
42474
+ capScope: "system",
42475
+ addonId: null,
42476
+ access: "view"
42477
+ },
41900
42478
  "recording.getStorageMigrationMoveStatus": {
41901
42479
  capName: "recording",
41902
42480
  capScope: "system",
@@ -42443,12 +43021,30 @@ var METHOD_ACCESS_MAP = Object.freeze({
42443
43021
  addonId: null,
42444
43022
  access: "create"
42445
43023
  },
43024
+ "storageMigration.drain": {
43025
+ capName: "storage-migration",
43026
+ capScope: "system",
43027
+ addonId: null,
43028
+ access: "create"
43029
+ },
43030
+ "storageMigration.movers": {
43031
+ capName: "storage-migration",
43032
+ capScope: "system",
43033
+ addonId: null,
43034
+ access: "view"
43035
+ },
42446
43036
  "storageMigration.plan": {
42447
43037
  capName: "storage-migration",
42448
43038
  capScope: "system",
42449
43039
  addonId: null,
42450
43040
  access: "view"
42451
43041
  },
43042
+ "storageMigration.residue": {
43043
+ capName: "storage-migration",
43044
+ capScope: "system",
43045
+ addonId: null,
43046
+ access: "view"
43047
+ },
42452
43048
  "storageMigration.start": {
42453
43049
  capName: "storage-migration",
42454
43050
  capScope: "system",
@@ -43283,6 +43879,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
43283
43879
  addonId: null,
43284
43880
  access: "delete"
43285
43881
  },
43882
+ "vectorStore.fetchByIds": {
43883
+ capName: "vector-store",
43884
+ capScope: "system",
43885
+ addonId: null,
43886
+ access: "view"
43887
+ },
43286
43888
  "vectorStore.getByIds": {
43287
43889
  capName: "vector-store",
43288
43890
  capScope: "system",
@@ -43295,6 +43897,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
43295
43897
  addonId: null,
43296
43898
  access: "view"
43297
43899
  },
43900
+ "vectorStore.scan": {
43901
+ capName: "vector-store",
43902
+ capScope: "system",
43903
+ addonId: null,
43904
+ access: "view"
43905
+ },
43298
43906
  "vectorStore.stats": {
43299
43907
  capName: "vector-store",
43300
43908
  capScope: "system",
@@ -46521,6 +47129,7 @@ function createSystemProxy(api) {
46521
47129
  cancelStorageMigrationMove: (input) => dispatch("recording", "cancelStorageMigrationMove", "mutation", input),
46522
47130
  relocateFootage: (input) => dispatch("recording", "relocateFootage", "mutation", input),
46523
47131
  listRelocateJobs: (input) => dispatch("recording", "listRelocateJobs", "query", input),
47132
+ getRelocateResidue: (input) => dispatch("recording", "getRelocateResidue", "query", input),
46524
47133
  cancelRelocateJob: (input) => dispatch("recording", "cancelRelocateJob", "mutation", input),
46525
47134
  planStorageRebalance: (input) => dispatch("recording", "planStorageRebalance", "query", input),
46526
47135
  startStorageRebalance: (input) => dispatch("recording", "startStorageRebalance", "mutation", input)
@@ -46584,7 +47193,10 @@ function createSystemProxy(api) {
46584
47193
  plan: (input) => dispatch("storageMigration", "plan", "query", input),
46585
47194
  start: (input) => dispatch("storageMigration", "start", "mutation", input),
46586
47195
  status: (input) => dispatch("storageMigration", "status", "query", input),
46587
- cancel: (input) => dispatch("storageMigration", "cancel", "mutation", input)
47196
+ cancel: (input) => dispatch("storageMigration", "cancel", "mutation", input),
47197
+ movers: (input) => dispatch("storageMigration", "movers", "query", input),
47198
+ residue: (input) => dispatch("storageMigration", "residue", "query", input),
47199
+ drain: (input) => dispatch("storageMigration", "drain", "mutation", input)
46588
47200
  },
46589
47201
  streamBroker: {
46590
47202
  fetchEventMedia: (input) => dispatch("streamBroker", "fetchEventMedia", "mutation", input),
@@ -51104,6 +51716,7 @@ exports.MediaFileSchema = MediaFileSchema;
51104
51716
  exports.MediaPlayerRepeatSchema = MediaPlayerRepeatSchema;
51105
51717
  exports.MediaPlayerStateSchema = MediaPlayerStateSchema;
51106
51718
  exports.MediaPlayerStatusSchema = MediaPlayerStatusSchema;
51719
+ exports.MediaRelocateModeSchema = MediaRelocateModeSchema;
51107
51720
  exports.MeshPeerSchema = MeshPeerSchema;
51108
51721
  exports.MeshStatusSchema = MeshStatusSchema;
51109
51722
  exports.MethodAccessSchema = MethodAccessSchema;
@@ -51327,6 +51940,7 @@ exports.REACHABILITY_POLL_INTERVAL_MS = REACHABILITY_POLL_INTERVAL_MS;
51327
51940
  exports.REACHABILITY_PROBE_TIMEOUT_MS = REACHABILITY_PROBE_TIMEOUT_MS;
51328
51941
  exports.RECOGNITION_TYPES = RECOGNITION_TYPES;
51329
51942
  exports.RECORDING_EXPORT_MAX_READ_BYTES = RECORDING_EXPORT_MAX_READ_BYTES;
51943
+ exports.REDACTED_SECRET = REDACTED_SECRET;
51330
51944
  exports.RESERVED_BINDING_NAMES = RESERVED_BINDING_NAMES;
51331
51945
  exports.RESTORED_CAP_NAMES = RESTORED_CAP_NAMES;
51332
51946
  exports.ROOT_BUCKET_KEY = ROOT_BUCKET_KEY;
@@ -51365,11 +51979,15 @@ exports.RecordingStorageUsageSchema = RecordingStorageUsageSchema;
51365
51979
  exports.RecordingTriggersSchema = RecordingTriggersSchema;
51366
51980
  exports.RecordingWeekdaySchema = RecordingWeekdaySchema;
51367
51981
  exports.RedirectLoginMethodSchema = RedirectLoginMethodSchema;
51982
+ exports.RelocatableMediaCountInputSchema = RelocatableMediaCountInputSchema;
51983
+ exports.RelocatableMediaCountSchema = RelocatableMediaCountSchema;
51368
51984
  exports.RelocateFootageClassSchema = RelocateFootageClassSchema;
51369
51985
  exports.RelocateFootageInputSchema = RelocateFootageInputSchema;
51370
51986
  exports.RelocateJobSchema = RelocateJobSchema;
51371
51987
  exports.RelocateJobStateSchema = RelocateJobStateSchema;
51372
51988
  exports.RelocateMediaInputSchema = RelocateMediaInputSchema;
51989
+ exports.RelocateResidueInputSchema = RelocateResidueInputSchema;
51990
+ exports.RelocateResidueSchema = RelocateResidueSchema;
51373
51991
  exports.RenderedAsSchema = RenderedAsSchema;
51374
51992
  exports.ReportMotionInputSchema = ReportMotionInputSchema;
51375
51993
  exports.ReportedFailureContributionSchema = ReportedFailureContributionSchema;
@@ -51420,6 +52038,7 @@ exports.SOURCE_CAP_ACTIVE_FIELD = SOURCE_CAP_ACTIVE_FIELD;
51420
52038
  exports.SOURCE_CAP_CHANGED_AT_FIELD = SOURCE_CAP_CHANGED_AT_FIELD;
51421
52039
  exports.SOURCE_DEVICE_TYPES = SOURCE_DEVICE_TYPES;
51422
52040
  exports.SOURCE_INFO_METADATA_KEY = SOURCE_INFO_METADATA_KEY;
52041
+ exports.STORAGE_ACCESS_FALLBACK = STORAGE_ACCESS_FALLBACK;
51423
52042
  exports.STREAM_PROFILE_META = STREAM_PROFILE_META;
51424
52043
  exports.STREAM_QUALITY_LABELS = STREAM_QUALITY_LABELS;
51425
52044
  exports.SUB_DETECTION_TYPES = SUB_DETECTION_TYPES;
@@ -51469,6 +52088,7 @@ exports.SsoBridgeClaimsSchema = SsoBridgeClaimsSchema;
51469
52088
  exports.StartEmbeddedInputSchema = StartEmbeddedInputSchema;
51470
52089
  exports.StationaryObjectSchema = StationaryObjectSchema;
51471
52090
  exports.StorageAbortUploadInputSchema = AbortUploadInputSchema;
52091
+ exports.StorageAccessSchema = StorageAccessSchema;
51472
52092
  exports.StorageBeginDownloadInputSchema = BeginDownloadInputSchema;
51473
52093
  exports.StorageBeginDownloadResultSchema = BeginDownloadResultSchema;
51474
52094
  exports.StorageBeginUploadInputSchema = BeginUploadInputSchema;
@@ -51481,15 +52101,23 @@ exports.StorageLocationSchema = StorageLocationSchema;
51481
52101
  exports.StorageLocationTypeSchema = StorageLocationTypeSchema;
51482
52102
  exports.StorageMigrationClassSchema = StorageMigrationClassSchema;
51483
52103
  exports.StorageMigrationDestinationsSchema = StorageMigrationDestinationsSchema;
52104
+ exports.StorageMigrationDrainInputSchema = StorageMigrationDrainInputSchema;
52105
+ exports.StorageMigrationFindingCodeSchema = StorageMigrationFindingCodeSchema;
52106
+ exports.StorageMigrationFindingSchema = StorageMigrationFindingSchema;
51484
52107
  exports.StorageMigrationFootageMoveInputSchema = StorageMigrationFootageMoveInputSchema;
51485
52108
  exports.StorageMigrationInputSchema = StorageMigrationInputSchema;
51486
52109
  exports.StorageMigrationJobSchema = StorageMigrationJobSchema;
52110
+ exports.StorageMigrationLaneSchema = StorageMigrationLaneSchema;
51487
52111
  exports.StorageMigrationLeaseInputSchema = StorageMigrationLeaseInputSchema;
51488
52112
  exports.StorageMigrationMediaMoveInputSchema = StorageMigrationMediaMoveInputSchema;
52113
+ exports.StorageMigrationModeSchema = StorageMigrationModeSchema;
52114
+ exports.StorageMigrationMoveProgressSchema = StorageMigrationMoveProgressSchema;
51489
52115
  exports.StorageMigrationMoveSchema = StorageMigrationMoveSchema;
52116
+ exports.StorageMigrationMoverSchema = StorageMigrationMoverSchema;
51490
52117
  exports.StorageMigrationParticipantSchema = StorageMigrationParticipantSchema;
51491
52118
  exports.StorageMigrationPhaseSchema = StorageMigrationPhaseSchema;
51492
52119
  exports.StorageMigrationPlanSchema = StorageMigrationPlanSchema;
52120
+ exports.StorageMigrationResidueSchema = StorageMigrationResidueSchema;
51493
52121
  exports.StorageProviderInfoSchema = ProviderInfoSchema;
51494
52122
  exports.StorageReadChunkInputSchema = ReadChunkInputSchema;
51495
52123
  exports.StorageTestLocationResultSchema = TestLocationResultSchema;
@@ -51561,6 +52189,7 @@ exports.UNATTRIBUTED_BUCKET_KEY = UNATTRIBUTED_BUCKET_KEY;
51561
52189
  exports.UNIT_TABLE = UNIT_TABLE;
51562
52190
  exports.UnifiedBrokerInfoSchema = BrokerInfoSchema$1;
51563
52191
  exports.UnitConversionError = UnitConversionError;
52192
+ exports.UnstampedEventMediaCountSchema = UnstampedEventMediaCountSchema;
51564
52193
  exports.UpdateIntegrationInputSchema = UpdateIntegrationInputSchema;
51565
52194
  exports.UpdateStatusSchema = UpdateStatusSchema;
51566
52195
  exports.UpdateUserInputSchema = UpdateUserInputSchema;
@@ -51682,6 +52311,7 @@ exports.clusterStepSettingFieldsFor = clusterStepSettingFieldsFor;
51682
52311
  exports.clusterStepSettingKey = clusterStepSettingKey;
51683
52312
  exports.collectHydratedFieldEntries = require_sleep.collectHydratedFieldEntries;
51684
52313
  exports.collectHydratedFieldValues = require_sleep.collectHydratedFieldValues;
52314
+ exports.collectSecretConfigKeys = collectSecretConfigKeys;
51685
52315
  exports.colorCapability = colorCapability;
51686
52316
  exports.colorForKind = colorForKind;
51687
52317
  exports.commitWatchdogRestart = commitWatchdogRestart;
@@ -51822,6 +52452,7 @@ exports.isOccupancyRule = isOccupancyRule;
51822
52452
  exports.isRestoredCap = isRestoredCap;
51823
52453
  exports.isSameAddonId = isSameAddonId;
51824
52454
  exports.isScheduleActive = isScheduleActive;
52455
+ exports.isSecretConfigField = isSecretConfigField;
51825
52456
  exports.isSoftwareDecode = require_canonical_hash.isSoftwareDecode;
51826
52457
  exports.isSourceCap = isSourceCap;
51827
52458
  exports.isSystemDelivery = isSystemDelivery;
@@ -51969,6 +52600,7 @@ exports.runInferenceStep = runInferenceStep;
51969
52600
  exports.runtimeDevices = runtimeDevices;
51970
52601
  exports.runtimeStatePolicyFor = runtimeStatePolicyFor;
51971
52602
  exports.sceneMonitorCapability = sceneMonitorCapability;
52603
+ exports.schemaDeclaresAnyField = schemaDeclaresAnyField;
51972
52604
  exports.scopeInherits = scopeInherits;
51973
52605
  exports.scopeKey = require_sleep.scopeKey;
51974
52606
  exports.scopesAllowAddon = scopesAllowAddon;