@camstack/addon-matter-broker 0.2.124 → 0.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.
Files changed (3) hide show
  1. package/dist/addon.js +422 -139
  2. package/dist/addon.mjs +422 -139
  3. package/package.json +1 -1
package/dist/addon.mjs CHANGED
@@ -5389,7 +5389,7 @@ var ZodIssueCode = {
5389
5389
  var ZodFirstPartyTypeKind;
5390
5390
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5391
5391
  //#endregion
5392
- //#region ../types/dist/sleep-r3RWkGVx.mjs
5392
+ //#region ../types/dist/sleep-DwAQ9sqX.mjs
5393
5393
  /**
5394
5394
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5395
5395
  * window to float samples (D455).
@@ -9395,6 +9395,16 @@ var CompositionSchema = object({
9395
9395
  seen.add(feature.cap);
9396
9396
  });
9397
9397
  });
9398
+ var NodeColorIdSchema = _enum([
9399
+ "node-a",
9400
+ "node-b",
9401
+ "node-c",
9402
+ "node-d",
9403
+ "node-e",
9404
+ "node-f",
9405
+ "node-g",
9406
+ "node-h"
9407
+ ]);
9398
9408
  new Set([
9399
9409
  "track",
9400
9410
  "face",
@@ -18490,14 +18500,14 @@ var LlmProfileSchema = object({
18490
18500
  /** ConfigUISchema tree passed through untyped on the wire (the
18491
18501
  * notification-output `ConfigSchemaPassthrough` precedent at
18492
18502
  * notification-output.cap.ts:151); the exported TS type re-tightens it. */
18493
- var ConfigSchemaPassthrough$1 = unknown();
18503
+ var ConfigSchemaPassthrough$3 = unknown();
18494
18504
  var LlmProfileKindDescriptorSchema = object({
18495
18505
  kind: LlmProfileKindSchema,
18496
18506
  label: string$2(),
18497
18507
  icon: string$2(),
18498
18508
  /** Stamped by each provider so the concat-fanned catalog stays routable. */
18499
18509
  addonId: string$2(),
18500
- configSchema: ConfigSchemaPassthrough$1
18510
+ configSchema: ConfigSchemaPassthrough$3
18501
18511
  });
18502
18512
  var LlmDefaultSelectorSchema = union([object({ consumer: string$2() }), object({ purpose: _enum(["text", "vision"]) })]);
18503
18513
  var LlmDefaultSchema = object({
@@ -19618,7 +19628,7 @@ var TargetKindCapsSchema = object({
19618
19628
  * the union is large and not meant for runtime validation here; the exported
19619
19629
  * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
19620
19630
  */
19621
- var ConfigSchemaPassthrough = unknown();
19631
+ var ConfigSchemaPassthrough$2 = unknown();
19622
19632
  var TargetKindSchema = object({
19623
19633
  kind: string$2(),
19624
19634
  label: string$2(),
@@ -19655,7 +19665,7 @@ var TargetKindSchema = object({
19655
19665
  * its raster path, which is the safe default for an unknown image.
19656
19666
  */
19657
19667
  iconMediaType: string$2().optional(),
19658
- configSchema: ConfigSchemaPassthrough,
19668
+ configSchema: ConfigSchemaPassthrough$2,
19659
19669
  /**
19660
19670
  * The config keys that decide WHERE this kind's secrets are sent (server,
19661
19671
  * base URL, instance, chat, recipient). A save that changes any of them
@@ -22992,6 +23002,61 @@ var OauthIntegrationDescriptorSchema = object({
22992
23002
  });
22993
23003
  method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
22994
23004
  /**
23005
+ * `oidc-connections` — CRUD for IdP rows under `auth-oidc` (D828 sibling).
23006
+ *
23007
+ * One hub-only singleton (`auth-oidc`). The Settings UI is a DataTable +
23008
+ * ItemFormDialog; there is no `editable-array` in `globalSettingsSchema`.
23009
+ * Operator-chosen `id` is the URL slug (`/addon/auth-oidc/<id>/…`) and is
23010
+ * immutable after create.
23011
+ */
23012
+ var ConfigSchemaPassthrough$1 = unknown();
23013
+ var OidcConnectionSchema = object({
23014
+ id: string$2().min(1),
23015
+ displayName: string$2(),
23016
+ icon: string$2(),
23017
+ issuerUrl: string$2(),
23018
+ clientId: string$2(),
23019
+ /** Client id + secret present — never the secret value. */
23020
+ configured: boolean(),
23021
+ /**
23022
+ * Values for the connection form schema. `clientSecret` is a keychain
23023
+ * {@link SecretFieldView} or `null` / `''`, never plaintext (D789).
23024
+ */
23025
+ formValues: record(string$2(), unknown()).optional()
23026
+ });
23027
+ /**
23028
+ * Patch one connection. Omitted or empty `clientSecret` keeps the stored
23029
+ * secret (D787). `{ $secretClear: true }` clears it. `id` is never renamed.
23030
+ */
23031
+ var OidcConnectionUpdateInputSchema = object({
23032
+ id: string$2().min(1),
23033
+ displayName: string$2().min(1),
23034
+ icon: string$2().optional(),
23035
+ issuerUrl: string$2().optional(),
23036
+ clientId: string$2().optional(),
23037
+ clientSecret: union([string$2(), object({ $secretClear: literal(true) })]).optional(),
23038
+ redirectUri: string$2().optional(),
23039
+ scopes: string$2().optional(),
23040
+ usernameClaim: _enum([
23041
+ "preferred_username",
23042
+ "email",
23043
+ "sub"
23044
+ ]).optional()
23045
+ });
23046
+ method(object({}), ConfigSchemaPassthrough$1, { auth: "admin" }), method(object({}), array(OidcConnectionSchema).readonly(), { auth: "admin" }), method(object({
23047
+ id: string$2().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug"),
23048
+ displayName: string$2().min(1)
23049
+ }), object({ id: string$2() }), {
23050
+ kind: "mutation",
23051
+ auth: "admin"
23052
+ }), method(OidcConnectionUpdateInputSchema, object({ ok: literal(true) }), {
23053
+ kind: "mutation",
23054
+ auth: "admin"
23055
+ }), method(object({ id: string$2().min(1) }), object({ ok: literal(true) }), {
23056
+ kind: "mutation",
23057
+ auth: "admin"
23058
+ });
23059
+ /**
22995
23060
  * What started a camera's onboard motion (D672). `camera` is the camera's own
22996
23061
  * firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
22997
23062
  * wire means the camera: only the camera-sensors bridge ever says `sensor`.
@@ -24348,24 +24413,69 @@ var RetrainFrameListSchema = object({
24348
24413
  /** What the page pre-selects — the native key frame when one survives. */
24349
24414
  autoPickMediaId: number().int().optional()
24350
24415
  });
24416
+ /** Exclusive partition of a corpus copy's annotation progress (design §4.2). */
24417
+ var RetrainFrameWorkStateSchema = _enum([
24418
+ "unannotated",
24419
+ "annotated",
24420
+ "complete"
24421
+ ]);
24422
+ /**
24423
+ * Filters for paginated corpus list, KPI, and matching export (design §4.4).
24424
+ * Every narrowing field is ANDed; omitted fields impose no constraint.
24425
+ */
24426
+ var RetrainCorpusFilterSchema = object({
24427
+ workState: RetrainFrameWorkStateSchema.optional(),
24428
+ deviceIds: array(number()).max(500).optional(),
24429
+ /** When set, only frames in this named collection. */
24430
+ collectionId: string$2().optional(),
24431
+ /** Frames that carry at least one saved annotation in one of these classes. */
24432
+ classes: array(RetrainMacroClassSchema).optional(),
24433
+ page: number().int().positive().default(1),
24434
+ pageSize: number().int().positive().max(100).default(50)
24435
+ });
24436
+ var RetrainCorpusPageSchema = object({
24437
+ frames: array(RetrainFrameSchema.extend({ workState: RetrainFrameWorkStateSchema })).readonly(),
24438
+ total: number().int().nonnegative(),
24439
+ page: number().int().positive(),
24440
+ pageSize: number().int().positive()
24441
+ });
24442
+ var RetrainCorpusKpiCameraRowSchema = object({
24443
+ deviceId: number(),
24444
+ unannotated: number().int().nonnegative(),
24445
+ annotated: number().int().nonnegative(),
24446
+ complete: number().int().nonnegative(),
24447
+ /** This camera's `complete` count divided by corpus `total`, in `[0,1]`.
24448
+ * `null` when the corpus is empty (no ratio). */
24449
+ pctOfCorpus: number().min(0).max(1).nullable()
24450
+ });
24451
+ var RetrainCorpusKpiSchema = object({
24452
+ total: number().int().nonnegative(),
24453
+ unannotated: number().int().nonnegative(),
24454
+ annotated: number().int().nonnegative(),
24455
+ complete: number().int().nonnegative(),
24456
+ cameras: array(RetrainCorpusKpiCameraRowSchema).readonly()
24457
+ });
24351
24458
  /**
24352
24459
  * Which frames an annotated export carries. Every field narrows; an empty
24353
- * filter is every annotated copy. A dataset VERSION is a frozen `frameIds`
24354
- * list owned by whoever trains (the training orchestrator), so `frameIds` is
24355
- * the primitive a version export uses; `batchId` re-selects what an earlier
24356
- * export carried (`exportedInBatch`).
24460
+ * filter is every annotated copy. `frameIds` is the primitive a job or
24461
+ * download uses; `batchId` re-selects what an earlier export carried
24462
+ * (`exportedInBatch`). Frozen dataset versions were removed — live selection
24463
+ * resolves to `frameIds` at plan/start.
24357
24464
  */
24358
24465
  var RetrainExportFilterSchema = object({
24359
24466
  deviceIds: array(number()).optional(),
24360
24467
  frameIds: array(string$2()).max(2e4).optional(),
24361
24468
  /** Only frames in at least one of these named collections. */
24362
24469
  collectionIds: array(string$2()).max(200).optional(),
24363
- /** Exactly the frames of this dataset version (and its completeOnly). An
24364
- * unknown id selects nothing. */
24365
- datasetVersionId: string$2().optional(),
24470
+ /** Single collection (Frames filter bar). ANDed with `collectionIds` when both set. */
24471
+ collectionId: string$2().optional(),
24366
24472
  batchId: string$2().optional(),
24367
24473
  /** Only frames the operator marked complete (all subjects boxed). */
24368
- completeOnly: boolean().optional()
24474
+ completeOnly: boolean().optional(),
24475
+ /** Exclusive work-state partition (`workStateOf`); same as the corpus list. */
24476
+ workState: RetrainFrameWorkStateSchema.optional(),
24477
+ /** Frames with at least one saved annotation in one of these classes. */
24478
+ classes: array(RetrainMacroClassSchema).optional()
24369
24479
  });
24370
24480
  /**
24371
24481
  * `frames`: the full frame copies, boxes in `annotations.json`.
@@ -24565,8 +24675,7 @@ var RetrainDatasetStatsSchema = object({
24565
24675
  completeFrames: number().int()
24566
24676
  })).readonly()
24567
24677
  });
24568
- /** An immutable dataset version, without its frame list. */
24569
- var RetrainDatasetVersionSchema = object({
24678
+ object({
24570
24679
  id: string$2(),
24571
24680
  name: string$2(),
24572
24681
  createdAt: number(),
@@ -24574,22 +24683,33 @@ var RetrainDatasetVersionSchema = object({
24574
24683
  layout: RetrainExportLayoutSchema,
24575
24684
  completeOnly: boolean(),
24576
24685
  frameCount: number().int(),
24577
- /** sha256 of what the frames taught when the version was frozen. */
24578
24686
  annotationHash: string$2(),
24579
- /** The export manifest schema the version was cut under. */
24580
24687
  manifestSchema: string$2(),
24581
24688
  stats: RetrainDatasetStatsSchema
24582
24689
  });
24583
- var CreateRetrainDatasetVersionResultSchema = discriminatedUnion("kind", [object({
24584
- kind: literal("created"),
24585
- version: RetrainDatasetVersionSchema
24690
+ /**
24691
+ * Live training corpus criteria — same shape as `TrainingCorpusSelection` on
24692
+ * the training cap. Resolved here so plan/start and the annotated export share
24693
+ * one definition of "the frames" (`buildRetrainExportPlan`).
24694
+ */
24695
+ var RetrainTrainingCorpusSelectionSchema = object({
24696
+ collectionIds: array(string$2()).min(1),
24697
+ workState: _enum([
24698
+ "complete",
24699
+ "annotated_or_complete",
24700
+ "any_annotated"
24701
+ ]).default("complete")
24702
+ });
24703
+ var RetrainTrainingCorpusResolveResultSchema = discriminatedUnion("kind", [object({
24704
+ kind: literal("resolved"),
24705
+ frameIds: array(string$2()).max(2e4).readonly(),
24706
+ stats: RetrainDatasetStatsSchema,
24707
+ annotationHash: string$2(),
24708
+ layout: RetrainExportLayoutSchema
24586
24709
  }), object({
24587
24710
  kind: literal("refused"),
24588
- reason: _enum([
24589
- "empty-name",
24590
- "duplicate-name",
24591
- "no-frames"
24592
- ])
24711
+ reason: _enum(["unknown-collection", "no-frames"]),
24712
+ detail: string$2()
24593
24713
  })]);
24594
24714
  /** The outcome of a lifecycle move owned by the retrain page. */
24595
24715
  var RetrainTransitionResultSchema = object({
@@ -25296,6 +25416,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25296
25416
  }), array(RetrainTrackSchema).readonly(), {
25297
25417
  kind: "query",
25298
25418
  auth: "admin"
25419
+ }), method(RetrainCorpusFilterSchema, RetrainCorpusPageSchema, {
25420
+ kind: "query",
25421
+ auth: "admin"
25422
+ }), method(object({}), RetrainCorpusKpiSchema, {
25423
+ kind: "query",
25424
+ auth: "admin"
25299
25425
  }), method(object({ trackId: string$2() }), RetrainFrameListSchema, {
25300
25426
  kind: "query",
25301
25427
  auth: "admin"
@@ -25391,36 +25517,6 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25391
25517
  kind: "mutation",
25392
25518
  auth: "admin",
25393
25519
  timeoutMs: 12e4
25394
- }), method(object({
25395
- selection: RetrainDatasetSelectionSchema,
25396
- completeOnly: boolean().optional()
25397
- }), RetrainDatasetStatsSchema, {
25398
- kind: "query",
25399
- auth: "admin"
25400
- }), method(object({
25401
- name: string$2().max(120),
25402
- selection: RetrainDatasetSelectionSchema,
25403
- layout: RetrainExportLayoutSchema,
25404
- completeOnly: boolean()
25405
- }), CreateRetrainDatasetVersionResultSchema, {
25406
- kind: "mutation",
25407
- auth: "admin",
25408
- timeoutMs: 12e4
25409
- }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), {
25410
- kind: "query",
25411
- auth: "admin"
25412
- }), method(object({ id: string$2() }), object({ deleted: boolean() }), {
25413
- kind: "mutation",
25414
- auth: "admin"
25415
- }), method(object({ id: string$2() }), object({
25416
- found: boolean(),
25417
- annotationHash: string$2(),
25418
- matches: boolean(),
25419
- missingFrames: number().int()
25420
- }), {
25421
- kind: "query",
25422
- auth: "admin",
25423
- timeoutMs: 12e4
25424
25520
  }), method(object({}), array(RetrainAssistProfileSchema).readonly(), {
25425
25521
  kind: "query",
25426
25522
  auth: "admin"
@@ -25447,6 +25543,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
25447
25543
  }), method(object({}), array(RetrainCollectionSchema).readonly(), {
25448
25544
  kind: "query",
25449
25545
  auth: "admin"
25546
+ }), method(RetrainTrainingCorpusSelectionSchema, RetrainTrainingCorpusResolveResultSchema, {
25547
+ kind: "query",
25548
+ auth: "admin",
25549
+ timeoutMs: 6e4
25450
25550
  }), method(object({
25451
25551
  id: string$2(),
25452
25552
  name: string$2().max(120)
@@ -26063,11 +26163,14 @@ var HardwareClassIdSchema = _enum([
26063
26163
  "intel-n-series",
26064
26164
  "apple-m-base",
26065
26165
  "apple-m-pro",
26166
+ "amd-phoenix",
26066
26167
  "unknown"
26067
26168
  ]);
26068
26169
  var AcceleratorKindSchema = _enum([
26069
26170
  "intel-npu",
26070
26171
  "intel-igpu",
26172
+ "amd-igpu",
26173
+ "amd-npu",
26071
26174
  "x86-cpu",
26072
26175
  "arm-cpu",
26073
26176
  "apple-ane",
@@ -27997,6 +28100,8 @@ var AgentPipelineSettingsSchema = object({
27997
28100
  * address is wrong (multi-homed host, NAT, custom interface).
27998
28101
  */
27999
28102
  reachableHost: string$2().optional(),
28103
+ /** Hub-persisted UI colour (`--color-node-*` theme tokens). */
28104
+ color: NodeColorIdSchema.optional(),
28000
28105
  /**
28001
28106
  * Multi-device inference opt-in (Phase 4). Per-node map deviceKey → {enabled,
28002
28107
  * weight, steps}. Absent / all-disabled ⇒ the node's single default
@@ -28546,8 +28651,9 @@ method(object({
28546
28651
  auth: "admin"
28547
28652
  }), method(object({
28548
28653
  agentNodeId: string$2(),
28549
- reachableHost: string$2().nullable()
28550
- }), object({ success: literal(true) }), {
28654
+ reachableHost: string$2().nullable().optional(),
28655
+ color: NodeColorIdSchema.nullable().optional()
28656
+ }).refine((v) => v.reachableHost !== void 0 || v.color !== void 0, { message: "reachableHost or color required" }), object({ success: literal(true) }), {
28551
28657
  kind: "mutation",
28552
28658
  auth: "admin"
28553
28659
  }), method(object({
@@ -31623,7 +31729,7 @@ var CustomActionInputSchema = object({
31623
31729
  action: string$2().min(1),
31624
31730
  input: unknown()
31625
31731
  });
31626
- method(_void(), array(AddonListItemSchema).readonly()), method(object({
31732
+ method(object({ nodeId: string$2().optional() }).optional(), array(AddonListItemSchema).readonly()), method(object({
31627
31733
  addonId: string$2(),
31628
31734
  limit: number().min(1).max(500).default(100),
31629
31735
  level: LogLevelSchema$2.optional()
@@ -36702,7 +36808,13 @@ var TopologyNodeSchema = object({
36702
36808
  })).readonly(),
36703
36809
  processes: array(TopologyProcessSchema).readonly(),
36704
36810
  categories: array(TopologyCategorySchema).readonly(),
36705
- rootPackage: TopologyRootPackageSchema.nullable()
36811
+ rootPackage: TopologyRootPackageSchema.nullable(),
36812
+ /**
36813
+ * How an online AGENT reaches the hub (mesh mTLS Release A): `tls` once it has
36814
+ * completed a mutual-TLS handshake, `clear` otherwise. Absent for the hub,
36815
+ * for offline rows and when the hub cannot tell.
36816
+ */
36817
+ meshTransport: _enum(["tls", "clear"]).optional()
36706
36818
  });
36707
36819
  var CapUsageEdgeSchema = object({
36708
36820
  callerAddonId: string$2(),
@@ -37115,6 +37227,7 @@ var OsdNamedTemplateSchema = object({
37115
37227
  });
37116
37228
  /** Where a slot's value comes from. */
37117
37229
  var OsdSourceSchema = discriminatedUnion("kind", [
37230
+ object({ kind: literal("none") }),
37118
37231
  object({
37119
37232
  kind: literal("static"),
37120
37233
  text: string$2().max(64)
@@ -37241,6 +37354,13 @@ method(object({ deviceId: number().int() }), object({
37241
37354
  }), object({ success: literal(true) }), {
37242
37355
  kind: "mutation",
37243
37356
  auth: "admin"
37357
+ }), method(object({
37358
+ deviceId: number().int(),
37359
+ slotId: string$2().min(1),
37360
+ enabled: boolean()
37361
+ }), object({ success: literal(true) }), {
37362
+ kind: "mutation",
37363
+ auth: "admin"
37244
37364
  }), method(object({
37245
37365
  sourceDeviceId: number().int(),
37246
37366
  targetDeviceId: number().int()
@@ -37672,7 +37792,15 @@ var GpuInfoSchema = object({
37672
37792
  name: string$2(),
37673
37793
  memoryMB: number().optional()
37674
37794
  });
37675
- var NpuInfoSchema = object({ type: _enum(["apple-ane", "intel-npu"]) });
37795
+ var NpuInfoSchema = object({
37796
+ type: _enum([
37797
+ "apple-ane",
37798
+ "intel-npu",
37799
+ "amd-xdna"
37800
+ ]),
37801
+ name: string$2().optional(),
37802
+ generation: _enum(["xdna1", "xdna2"]).optional()
37803
+ });
37676
37804
  var CoralInfoSchema = object({
37677
37805
  type: literal("coral-edgetpu"),
37678
37806
  bus: string$2().optional()
@@ -42415,9 +42543,11 @@ var zoneRulesCapability = {
42415
42543
  * once is what makes a second provider (RunPod, a local NVIDIA node) a new
42416
42544
  * manifest entry and nothing else.
42417
42545
  *
42418
- * Collection, routed by the `addonId` in every single-row input (the `llm` /
42419
- * `notification-output` posture); `describe` concat-fans across providers.
42420
- * Every method is `admin`: these spend money.
42546
+ * Collection of provider **types** (addons). Each addon owns zero or more
42547
+ * **entries** (credentials + defaults). Concat-fans: `describe`,
42548
+ * `describeTypes`, `listEntries`, `listJobs`. Single-row work is keyed by
42549
+ * `entryId`; callers also pass the owning `addonId` as the collection
42550
+ * selector (broker posture). Every method is `admin`: these spend money.
42421
42551
  *
42422
42552
  * Every cloud object a provider creates is tagged with the orchestrator's
42423
42553
  * `jobKey`, so a retried submit finds the job it already started instead of
@@ -42441,8 +42571,8 @@ var TrainingRegionOptionSchema = object({
42441
42571
  priceMultiplier: number().positive()
42442
42572
  });
42443
42573
  /**
42444
- * The provider's per-account settings, as the orchestrator reads them. They
42445
- * live in the PROVIDER addon's settings (operator decision 2026-10-08: they
42574
+ * The provider's per-entry settings, as the orchestrator reads them. They
42575
+ * live on the PROVIDER addon's entry (operator decision 2026-10-08: they
42446
42576
  * depend on the user's account), never hard-coded in the orchestrator.
42447
42577
  */
42448
42578
  var TrainingProviderDefaultsSchema = object({
@@ -42453,9 +42583,44 @@ var TrainingProviderDefaultsSchema = object({
42453
42583
  /** Hours a FAILED job's cloud dataset is kept for debugging; 0 = delete at once. */
42454
42584
  failedDatasetGraceHours: number().nonnegative()
42455
42585
  });
42586
+ /**
42587
+ * Entry form schema for a provider type — same seam as notification
42588
+ * `TargetKind.configSchema` (`z.unknown()` at the wire; callers tighten to
42589
+ * {@link ConfigUISchema}). Drives `ConfigFormBuilder` on Training → Providers.
42590
+ */
42591
+ var ConfigSchemaPassthrough = unknown();
42592
+ /** One creatable provider type, for the Add-entry dialog. */
42593
+ var TrainingProviderTypeSchema = object({
42594
+ typeId: string$2(),
42595
+ label: string$2(),
42596
+ /** Path under the addon package (e.g. `assets/training-modal/icon.svg`). */
42597
+ iconAsset: string$2(),
42598
+ /** Owning `training-provider` addon — collection selector for createEntry. */
42599
+ addonId: string$2(),
42600
+ /**
42601
+ * Fields for one entry of this type (credentials + defaults). Absent on a
42602
+ * type that only needs a name. Password fields are keychain-backed on the
42603
+ * provider addon (`secretStatePaths`), not D634 plaintext.
42604
+ */
42605
+ configSchema: ConfigSchemaPassthrough.optional()
42606
+ });
42607
+ /** One configured account / workspace under a provider type. */
42608
+ var TrainingProviderEntrySchema = object({
42609
+ entryId: string$2(),
42610
+ typeId: string$2(),
42611
+ name: string$2(),
42612
+ addonId: string$2(),
42613
+ /** Credentials are present — never the values. */
42614
+ configured: boolean()
42615
+ });
42456
42616
  var TrainingProviderDescriptorSchema = object({
42457
42617
  addonId: string$2(),
42458
- /** `modal`, `runpod`, `fake`, … */
42618
+ entryId: string$2(),
42619
+ typeId: string$2(),
42620
+ /** Operator-chosen entry name. */
42621
+ name: string$2(),
42622
+ iconAsset: string$2(),
42623
+ /** `modal`, `runpod`, `fake`, … — same as typeId for current providers. */
42459
42624
  kind: string$2(),
42460
42625
  label: string$2(),
42461
42626
  gpuTypes: array(TrainingGpuOptionSchema).readonly(),
@@ -42467,7 +42632,30 @@ var TrainingProviderDescriptorSchema = object({
42467
42632
  dataResidencyNote: string$2(),
42468
42633
  /** Credentials are present — never the values. */
42469
42634
  configured: boolean(),
42470
- defaults: TrainingProviderDefaultsSchema
42635
+ defaults: TrainingProviderDefaultsSchema,
42636
+ /**
42637
+ * Values for {@link TrainingProviderTypeSchema}'s `configSchema` — password
42638
+ * fields are keychain {@link SecretFieldView} or `null` / `''` (create),
42639
+ * never plaintext. Same hydrate contract as settings forms (D789).
42640
+ */
42641
+ formValues: record(string$2(), unknown()).optional()
42642
+ });
42643
+ /**
42644
+ * Patch one entry's name, credentials and defaults. Pin with owning `{ addonId }`.
42645
+ * An omitted or empty `tokenSecret` means KEEP the stored secret (D787).
42646
+ * `{ $secretClear: true }` clears it.
42647
+ */
42648
+ var TrainingProviderUpdateEntryInputSchema = object({
42649
+ entryId: string$2().min(1),
42650
+ name: string$2().min(1),
42651
+ tokenId: string$2().optional(),
42652
+ tokenSecret: union([string$2(), object({ $secretClear: literal(true) })]).optional(),
42653
+ environment: string$2().optional(),
42654
+ gpuType: string$2().optional(),
42655
+ region: string$2().optional(),
42656
+ costCapUsd: number().nonnegative().optional(),
42657
+ maxRuntimeSec: number().int().positive().optional(),
42658
+ failedDatasetGraceHours: number().nonnegative().optional()
42471
42659
  });
42472
42660
  var TrainingCredentialCheckSchema = object({
42473
42661
  ok: boolean(),
@@ -42519,20 +42707,33 @@ var TrainerSourceRefSchema = object({
42519
42707
  /** A commit sha (never a branch) — the job must be reproducible. */
42520
42708
  revision: string$2().regex(/^[0-9a-f]{7,64}$/)
42521
42709
  });
42710
+ /** Cloud job identity — route with the owning addon's `addonId` selector. */
42522
42711
  var JobRef = {
42523
- addonId: string$2(),
42712
+ entryId: string$2().min(1),
42524
42713
  jobKey: string$2().uuid()
42525
42714
  };
42526
42715
  var TrainingLogLineSchema = object({
42527
42716
  ts: number(),
42528
42717
  text: string$2()
42529
42718
  });
42530
- method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({ addonId: string$2() }), TrainingCredentialCheckSchema, {
42719
+ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderTypeSchema).readonly(), { auth: "admin" }), method(object({}), array(TrainingProviderEntrySchema).readonly(), { auth: "admin" }), method(object({
42720
+ typeId: string$2().min(1),
42721
+ name: string$2().min(1)
42722
+ }), object({ entryId: string$2() }), {
42723
+ kind: "mutation",
42724
+ auth: "admin"
42725
+ }), method(object({ entryId: string$2().min(1) }), object({ ok: literal(true) }), {
42726
+ kind: "mutation",
42727
+ auth: "admin"
42728
+ }), method(TrainingProviderUpdateEntryInputSchema, object({ ok: literal(true) }), {
42729
+ kind: "mutation",
42730
+ auth: "admin"
42731
+ }), method(object({ entryId: string$2().min(1) }), TrainingCredentialCheckSchema, {
42531
42732
  kind: "mutation",
42532
42733
  auth: "admin",
42533
42734
  timeoutMs: 3e4
42534
42735
  }), method(object({
42535
- addonId: string$2(),
42736
+ entryId: string$2().min(1),
42536
42737
  gpuType: string$2(),
42537
42738
  region: string$2(),
42538
42739
  datasetBytes: number().int().nonnegative(),
@@ -42598,7 +42799,7 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42598
42799
  kind: "mutation",
42599
42800
  auth: "admin",
42600
42801
  timeoutMs: 5 * 6e4
42601
- }), method(object({ addonId: string$2() }), array(ProviderJobStatusSchema).readonly(), {
42802
+ }), method(object({ entryId: string$2().min(1).optional() }), array(ProviderJobStatusSchema).readonly(), {
42602
42803
  auth: "admin",
42603
42804
  timeoutMs: 2 * 6e4
42604
42805
  });
@@ -42608,20 +42809,31 @@ method(object({}), array(TrainingProviderDescriptorSchema).readonly(), { auth: "
42608
42809
  *
42609
42810
  * It owns what every provider must agree on, written once:
42610
42811
  *
42611
- * - **Dataset versions.** Taken over from pipeline-analytics (D796): the rows
42612
- * live here (D808); pipeline-analytics still CUTS a version (it owns the corpus and
42613
- * the export plan) and reaches this store through the five row methods
42614
- * below, so the Retrain page and the export did not change.
42615
42812
  * - **Jobs.** A persisted state machine, a reconcile loop against the
42616
42813
  * provider, a cost guard, a daily orphan sweep and the retention rules.
42617
42814
  * - **The return flow.** Verified artefacts → Model Studio
42618
42815
  * (`custom-model-registry.importModelBundle`) → canary on cameras →
42619
42816
  * rollback. Nothing is ever registered automatically.
42620
42817
  *
42818
+ * Plan/start takes a live {@link TrainingCorpusSelection} (collections +
42819
+ * work-state rule); frame ids are resolved via pipeline-analytics at that
42820
+ * moment and snapshotted on the job. No frozen dataset version.
42821
+ *
42621
42822
  * Every method is `admin`.
42622
42823
  */
42623
- /** A version WITH its frame list — what the export and a job read. */
42624
- var TrainingDatasetVersionRowSchema = RetrainDatasetVersionSchema.omit({ frameCount: true }).extend({ frameIds: array(string$2()).max(2e4).readonly() });
42824
+ /**
42825
+ * Live corpus criteria for plan/start (design §5.2). Default is complete-only.
42826
+ * Frame ids are resolved at plan/start — never a frozen version id.
42827
+ */
42828
+ var TrainingCorpusSelectionSchema = object({
42829
+ collectionIds: array(string$2()).min(1),
42830
+ /** Default complete-only for v1 */
42831
+ workState: _enum([
42832
+ "complete",
42833
+ "annotated_or_complete",
42834
+ "any_annotated"
42835
+ ]).default("complete")
42836
+ });
42625
42837
  /** A base model a detector job can fine-tune, and the baseline it is judged against. */
42626
42838
  var TrainingBaseModelSchema = object({
42627
42839
  modelId: string$2(),
@@ -42639,9 +42851,13 @@ var TrainingPresetSchema = _enum([
42639
42851
  "thorough"
42640
42852
  ]);
42641
42853
  var TrainingJobRequestSchema = object({
42642
- datasetVersionId: string$2().min(1),
42643
- /** The `training-provider` addon that runs it. */
42644
- addonId: string$2().min(1),
42854
+ /** Live collection + work-state criteria; resolved at plan/start. */
42855
+ selection: TrainingCorpusSelectionSchema,
42856
+ /**
42857
+ * The provider **entry** that runs it (credentials + defaults).
42858
+ * Resolve to an owning addon via `training-provider.describe` / `listEntries`.
42859
+ */
42860
+ entryId: string$2().min(1),
42645
42861
  gpuType: string$2().min(1),
42646
42862
  region: string$2(),
42647
42863
  baseModelId: string$2().min(1),
@@ -42700,6 +42916,7 @@ var TrainingJobPlanSchema = object({
42700
42916
  * result lives after the operator acted on it.
42701
42917
  */
42702
42918
  var TrainingJobStateSchema = _enum([
42919
+ "queued",
42703
42920
  "uploading",
42704
42921
  "submitted",
42705
42922
  "starting",
@@ -42753,6 +42970,11 @@ var TrainingJobSchema = object({
42753
42970
  createdAt: number(),
42754
42971
  updatedAt: number(),
42755
42972
  state: TrainingJobStateSchema,
42973
+ /**
42974
+ * Shared by every job enqueued together via `startJobBatch`.
42975
+ * `null` for a lone `startJob`. The engine advances queued siblings by this id.
42976
+ */
42977
+ batchId: string$2().nullable().default(null),
42756
42978
  stage: TrainingStageSchema.nullable(),
42757
42979
  failure: object({
42758
42980
  reason: TrainingFailureReasonSchema,
@@ -42764,6 +42986,12 @@ var TrainingJobSchema = object({
42764
42986
  maxRuntimeSec: number().int().positive(),
42765
42987
  trainer: TrainerSourceRefSchema,
42766
42988
  datasetLayout: RetrainExportLayoutSchema,
42989
+ /** Frame count snapshotted when the job started (audit; equals `frameIds.length`). */
42990
+ frameCount: number().int().nonnegative(),
42991
+ /** Resolved frame ids at start — the archive ships exactly these. */
42992
+ frameIds: array(string$2()).max(2e4).readonly(),
42993
+ /** Hash of what those frames taught at start (trainer `dataset.annotationHash`). */
42994
+ annotationHash: string$2(),
42767
42995
  dataset: object({
42768
42996
  bytes: number().int(),
42769
42997
  sha256: string$2(),
@@ -42805,13 +43033,7 @@ var TrainingJobSchema = object({
42805
43033
  canary: TrainingCanarySchema.nullable()
42806
43034
  });
42807
43035
  var IdInput = object({ id: string$2().min(1) });
42808
- method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42809
- kind: "mutation",
42810
- auth: "admin"
42811
- }), method(IdInput, TrainingDatasetVersionRowSchema.nullable(), { auth: "admin" }), method(object({}), array(RetrainDatasetVersionSchema).readonly(), { auth: "admin" }), method(object({ name: string$2() }), object({ id: string$2().nullable() }), { auth: "admin" }), method(IdInput, object({ removed: boolean() }), {
42812
- kind: "mutation",
42813
- auth: "admin"
42814
- }), method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
43036
+ method(object({}), array(TrainingBaseModelSchema).readonly(), { auth: "admin" }), method(TrainingJobRequestSchema, TrainingJobPlanSchema, {
42815
43037
  auth: "admin",
42816
43038
  timeoutMs: 6e4
42817
43039
  }), method(TrainingJobRequestSchema.extend({
@@ -42830,6 +43052,24 @@ method(TrainingDatasetVersionRowSchema, object({ stored: boolean() }), {
42830
43052
  kind: "mutation",
42831
43053
  auth: "admin",
42832
43054
  timeoutMs: 12e4
43055
+ }), method(TrainingJobRequestSchema.omit({ baseModelId: true }).extend({
43056
+ baseModelIds: array(string$2().min(1)).min(1),
43057
+ name: string$2().min(1).max(120),
43058
+ maxCostUsd: number().positive(),
43059
+ maxRuntimeSec: number().int().positive(),
43060
+ idempotencyKey: string$2().min(8).max(80)
43061
+ }), discriminatedUnion("kind", [object({
43062
+ kind: literal("started"),
43063
+ batchId: string$2(),
43064
+ jobs: array(TrainingJobSchema).min(1).readonly()
43065
+ }), object({
43066
+ kind: literal("refused"),
43067
+ reason: TrainingRefusalReasonSchema,
43068
+ detail: string$2()
43069
+ })]), {
43070
+ kind: "mutation",
43071
+ auth: "admin",
43072
+ timeoutMs: 12e4
42833
43073
  }), method(object({}), array(TrainingJobSchema).readonly(), { auth: "admin" }), method(IdInput, TrainingJobSchema.nullable(), { auth: "admin" }), method(IdInput, TrainingJobSchema, {
42834
43074
  kind: "mutation",
42835
43075
  auth: "admin",
@@ -48388,6 +48628,36 @@ Object.freeze({
48388
48628
  addonId: null,
48389
48629
  access: "view"
48390
48630
  },
48631
+ "oidcConnections.connectionFormSchema": {
48632
+ capName: "oidc-connections",
48633
+ capScope: "system",
48634
+ addonId: null,
48635
+ access: "view"
48636
+ },
48637
+ "oidcConnections.createConnection": {
48638
+ capName: "oidc-connections",
48639
+ capScope: "system",
48640
+ addonId: null,
48641
+ access: "create"
48642
+ },
48643
+ "oidcConnections.deleteConnection": {
48644
+ capName: "oidc-connections",
48645
+ capScope: "system",
48646
+ addonId: null,
48647
+ access: "delete"
48648
+ },
48649
+ "oidcConnections.listConnections": {
48650
+ capName: "oidc-connections",
48651
+ capScope: "system",
48652
+ addonId: null,
48653
+ access: "view"
48654
+ },
48655
+ "oidcConnections.updateConnection": {
48656
+ capName: "oidc-connections",
48657
+ capScope: "system",
48658
+ addonId: null,
48659
+ access: "create"
48660
+ },
48391
48661
  "osd.getStatus": {
48392
48662
  capName: "osd",
48393
48663
  capScope: "device",
@@ -48460,6 +48730,12 @@ Object.freeze({
48460
48730
  addonId: null,
48461
48731
  access: "create"
48462
48732
  },
48733
+ "osdManager.setSlotCameraEnabled": {
48734
+ capName: "osd-manager",
48735
+ capScope: "system",
48736
+ addonId: null,
48737
+ access: "create"
48738
+ },
48463
48739
  "osdManager.upsertTemplate": {
48464
48740
  capName: "osd-manager",
48465
48741
  capScope: "system",
@@ -48598,12 +48874,6 @@ Object.freeze({
48598
48874
  addonId: null,
48599
48875
  access: "create"
48600
48876
  },
48601
- "pipelineAnalytics.createRetrainDatasetVersion": {
48602
- capName: "pipeline-analytics",
48603
- capScope: "device",
48604
- addonId: null,
48605
- access: "create"
48606
- },
48607
48877
  "pipelineAnalytics.deleteDeviceEvents": {
48608
48878
  capName: "pipeline-analytics",
48609
48879
  capScope: "device",
@@ -48616,12 +48886,6 @@ Object.freeze({
48616
48886
  addonId: null,
48617
48887
  access: "delete"
48618
48888
  },
48619
- "pipelineAnalytics.deleteRetrainDatasetVersion": {
48620
- capName: "pipeline-analytics",
48621
- capScope: "device",
48622
- addonId: null,
48623
- access: "delete"
48624
- },
48625
48889
  "pipelineAnalytics.deleteTracks": {
48626
48890
  capName: "pipeline-analytics",
48627
48891
  capScope: "device",
@@ -48724,6 +48988,12 @@ Object.freeze({
48724
48988
  addonId: null,
48725
48989
  access: "view"
48726
48990
  },
48991
+ "pipelineAnalytics.getRetrainCorpusKpi": {
48992
+ capName: "pipeline-analytics",
48993
+ capScope: "device",
48994
+ addonId: null,
48995
+ access: "view"
48996
+ },
48727
48997
  "pipelineAnalytics.getRetrainExportUrl": {
48728
48998
  capName: "pipeline-analytics",
48729
48999
  capScope: "device",
@@ -48844,7 +49114,7 @@ Object.freeze({
48844
49114
  addonId: null,
48845
49115
  access: "view"
48846
49116
  },
48847
- "pipelineAnalytics.listRetrainDatasetVersions": {
49117
+ "pipelineAnalytics.listRetrainCorpusPage": {
48848
49118
  capName: "pipeline-analytics",
48849
49119
  capScope: "device",
48850
49120
  addonId: null,
@@ -48898,12 +49168,6 @@ Object.freeze({
48898
49168
  addonId: null,
48899
49169
  access: "create"
48900
49170
  },
48901
- "pipelineAnalytics.previewRetrainDataset": {
48902
- capName: "pipeline-analytics",
48903
- capScope: "device",
48904
- addonId: null,
48905
- access: "view"
48906
- },
48907
49171
  "pipelineAnalytics.proposeRetrainAnnotations": {
48908
49172
  capName: "pipeline-analytics",
48909
49173
  capScope: "device",
@@ -48982,6 +49246,12 @@ Object.freeze({
48982
49246
  addonId: null,
48983
49247
  access: "create"
48984
49248
  },
49249
+ "pipelineAnalytics.resolveRetrainTrainingCorpus": {
49250
+ capName: "pipeline-analytics",
49251
+ capScope: "device",
49252
+ addonId: null,
49253
+ access: "view"
49254
+ },
48985
49255
  "pipelineAnalytics.restageRetrainTrack": {
48986
49256
  capName: "pipeline-analytics",
48987
49257
  capScope: "device",
@@ -49042,12 +49312,6 @@ Object.freeze({
49042
49312
  addonId: null,
49043
49313
  access: "create"
49044
49314
  },
49045
- "pipelineAnalytics.verifyRetrainDatasetVersion": {
49046
- capName: "pipeline-analytics",
49047
- capScope: "device",
49048
- addonId: null,
49049
- access: "view"
49050
- },
49051
49315
  "pipelineAnalytics.wipeAllAnalytics": {
49052
49316
  capName: "pipeline-analytics",
49053
49317
  capScope: "device",
@@ -51442,18 +51706,6 @@ Object.freeze({
51442
51706
  addonId: null,
51443
51707
  access: "create"
51444
51708
  },
51445
- "training.findDatasetVersionIdByName": {
51446
- capName: "training",
51447
- capScope: "system",
51448
- addonId: null,
51449
- access: "view"
51450
- },
51451
- "training.getDatasetVersion": {
51452
- capName: "training",
51453
- capScope: "system",
51454
- addonId: null,
51455
- access: "view"
51456
- },
51457
51709
  "training.getJob": {
51458
51710
  capName: "training",
51459
51711
  capScope: "system",
@@ -51472,12 +51724,6 @@ Object.freeze({
51472
51724
  addonId: null,
51473
51725
  access: "view"
51474
51726
  },
51475
- "training.listDatasetVersions": {
51476
- capName: "training",
51477
- capScope: "system",
51478
- addonId: null,
51479
- access: "view"
51480
- },
51481
51727
  "training.listJobs": {
51482
51728
  capName: "training",
51483
51729
  capScope: "system",
@@ -51490,54 +51736,66 @@ Object.freeze({
51490
51736
  addonId: null,
51491
51737
  access: "view"
51492
51738
  },
51493
- "training.putDatasetVersion": {
51739
+ "training.registerResult": {
51494
51740
  capName: "training",
51495
51741
  capScope: "system",
51496
51742
  addonId: null,
51497
51743
  access: "create"
51498
51744
  },
51499
- "training.registerResult": {
51745
+ "training.rollbackCanary": {
51500
51746
  capName: "training",
51501
51747
  capScope: "system",
51502
51748
  addonId: null,
51503
51749
  access: "create"
51504
51750
  },
51505
- "training.removeDatasetVersion": {
51751
+ "training.startJob": {
51506
51752
  capName: "training",
51507
51753
  capScope: "system",
51508
51754
  addonId: null,
51509
- access: "delete"
51755
+ access: "create"
51510
51756
  },
51511
- "training.rollbackCanary": {
51757
+ "training.startJobBatch": {
51512
51758
  capName: "training",
51513
51759
  capScope: "system",
51514
51760
  addonId: null,
51515
51761
  access: "create"
51516
51762
  },
51517
- "training.startJob": {
51518
- capName: "training",
51763
+ "trainingProvider.cancelJob": {
51764
+ capName: "training-provider",
51519
51765
  capScope: "system",
51520
51766
  addonId: null,
51521
51767
  access: "create"
51522
51768
  },
51523
- "trainingProvider.cancelJob": {
51769
+ "trainingProvider.cleanupJob": {
51524
51770
  capName: "training-provider",
51525
51771
  capScope: "system",
51526
51772
  addonId: null,
51527
51773
  access: "create"
51528
51774
  },
51529
- "trainingProvider.cleanupJob": {
51775
+ "trainingProvider.createEntry": {
51530
51776
  capName: "training-provider",
51531
51777
  capScope: "system",
51532
51778
  addonId: null,
51533
51779
  access: "create"
51534
51780
  },
51781
+ "trainingProvider.deleteEntry": {
51782
+ capName: "training-provider",
51783
+ capScope: "system",
51784
+ addonId: null,
51785
+ access: "delete"
51786
+ },
51535
51787
  "trainingProvider.describe": {
51536
51788
  capName: "training-provider",
51537
51789
  capScope: "system",
51538
51790
  addonId: null,
51539
51791
  access: "view"
51540
51792
  },
51793
+ "trainingProvider.describeTypes": {
51794
+ capName: "training-provider",
51795
+ capScope: "system",
51796
+ addonId: null,
51797
+ access: "view"
51798
+ },
51541
51799
  "trainingProvider.estimateJob": {
51542
51800
  capName: "training-provider",
51543
51801
  capScope: "system",
@@ -51550,6 +51808,12 @@ Object.freeze({
51550
51808
  addonId: null,
51551
51809
  access: "view"
51552
51810
  },
51811
+ "trainingProvider.listEntries": {
51812
+ capName: "training-provider",
51813
+ capScope: "system",
51814
+ addonId: null,
51815
+ access: "view"
51816
+ },
51553
51817
  "trainingProvider.listJobEvents": {
51554
51818
  capName: "training-provider",
51555
51819
  capScope: "system",
@@ -51580,6 +51844,12 @@ Object.freeze({
51580
51844
  addonId: null,
51581
51845
  access: "create"
51582
51846
  },
51847
+ "trainingProvider.updateEntry": {
51848
+ capName: "training-provider",
51849
+ capScope: "system",
51850
+ addonId: null,
51851
+ access: "create"
51852
+ },
51583
51853
  "trainingProvider.uploadDataset": {
51584
51854
  capName: "training-provider",
51585
51855
  capScope: "system",
@@ -54786,6 +55056,11 @@ Object.freeze({
54786
55056
  form: "single",
54787
55057
  optional: false
54788
55058
  }],
55059
+ "osdManager.setSlotCameraEnabled": [{
55060
+ name: "deviceId",
55061
+ form: "single",
55062
+ optional: false
55063
+ }],
54789
55064
  "petFeeder.callPet": [{
54790
55065
  name: "deviceId",
54791
55066
  form: "single",
@@ -55006,6 +55281,11 @@ Object.freeze({
55006
55281
  form: "array",
55007
55282
  optional: false
55008
55283
  }],
55284
+ "pipelineAnalytics.listRetrainCorpusPage": [{
55285
+ name: "deviceIds",
55286
+ form: "array",
55287
+ optional: true
55288
+ }],
55009
55289
  "pipelineAnalytics.listRetrainStaging": [{
55010
55290
  name: "deviceIds",
55011
55291
  form: "array",
@@ -56115,6 +56395,7 @@ Object.freeze({
56115
56395
  });
56116
56396
  Object.freeze({
56117
56397
  "broker": "broker",
56398
+ "calendar-source": "calendar",
56118
56399
  "device-export": "device-export",
56119
56400
  "llm": "ai",
56120
56401
  "mesh-network": "mesh",
@@ -56600,6 +56881,8 @@ var STATE_SUMMARY_VARS = [
56600
56881
  [...RULE_TEXT],
56601
56882
  [...RULE_TEXT],
56602
56883
  [...RULE_TEXT],
56884
+ [...RULE_TEXT],
56885
+ [...RULE_TEXT],
56603
56886
  ([...RULE_TEXT], [...UPDATES]),
56604
56887
  ([...RULE_TEXT], [...PACKAGE_UPDATES]),
56605
56888
  ([...RULE_TEXT], [...PACKAGE_UPDATES]),