@camstack/system 1.2.441 → 1.2.442

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 (85) hide show
  1. package/dist/addon-runner.js +72 -2
  2. package/dist/addon-runner.mjs +72 -2
  3. package/dist/auth/totp-manager.d.ts +46 -1
  4. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  6. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  8. package/dist/builtins/alerts/alerts.addon.d.ts +41 -1
  9. package/dist/builtins/alerts/alerts.addon.js +638 -26
  10. package/dist/builtins/alerts/alerts.addon.mjs +638 -26
  11. package/dist/builtins/alerts/critical-push.d.ts +86 -0
  12. package/dist/builtins/alerts/runner-alert.d.ts +71 -0
  13. package/dist/builtins/autotrack/index.js +1 -1
  14. package/dist/builtins/autotrack/index.mjs +1 -1
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  16. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  17. package/dist/builtins/calendars/calendars.addon.js +1 -1
  18. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  19. package/dist/builtins/camera-grid/index.js +1 -1
  20. package/dist/builtins/camera-grid/index.mjs +1 -1
  21. package/dist/builtins/composer/composer.addon.js +2 -2
  22. package/dist/builtins/composer/composer.addon.mjs +2 -2
  23. package/dist/builtins/console-logging/index.js +1 -1
  24. package/dist/builtins/console-logging/index.mjs +1 -1
  25. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  26. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  27. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  28. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  29. package/dist/builtins/hub-forwarder/index.js +1 -1
  30. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  31. package/dist/builtins/keychain/index.js +3 -3
  32. package/dist/builtins/keychain/index.mjs +3 -3
  33. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  34. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  35. package/dist/builtins/local-auth/auth-schema.d.ts +1 -1
  36. package/dist/builtins/local-auth/local-auth.addon.js +226 -17
  37. package/dist/builtins/local-auth/local-auth.addon.mjs +226 -17
  38. package/dist/builtins/local-network/local-network.addon.js +2 -2
  39. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  40. package/dist/builtins/loki-logging/index.js +1 -1
  41. package/dist/builtins/loki-logging/index.mjs +1 -1
  42. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  43. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  44. package/dist/builtins/platform-probe/index.js +1 -1
  45. package/dist/builtins/platform-probe/index.mjs +1 -1
  46. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  47. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  48. package/dist/builtins/snapshot/index.js +1 -1
  49. package/dist/builtins/snapshot/index.mjs +1 -1
  50. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  51. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  52. package/dist/builtins/sqlite-storage/index.js +1 -1
  53. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  54. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  55. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  56. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  57. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  58. package/dist/builtins/system-config/system-config.addon.js +2 -2
  59. package/dist/builtins/system-config/system-config.addon.mjs +2 -2
  60. package/dist/builtins/winston-logging/index.js +1 -1
  61. package/dist/builtins/winston-logging/index.mjs +1 -1
  62. package/dist/{composition-sources-ByNISOnW.mjs → composition-sources-CftPpY4O.mjs} +1 -1
  63. package/dist/{composition-sources-BG-W2U0d.js → composition-sources-DmSEMtUD.js} +1 -1
  64. package/dist/{constants-DJILnUSb.mjs → constants-2iWQ-Nx-.mjs} +1 -1
  65. package/dist/{constants-UojhAJcm.js → constants-b7kpjuO4.js} +1 -1
  66. package/dist/{device-ca-D8Ri9TVz.mjs → device-ca-BJpYTAPg.mjs} +1 -1
  67. package/dist/{device-ca-196DAEZT.js → device-ca-tKY_ZS9H.js} +1 -1
  68. package/dist/{dist-BiTCcaf-.js → dist-CyIHDLCg.js} +158 -8
  69. package/dist/{dist-BWvkuc31.mjs → dist-DsrQYcLm.mjs} +153 -9
  70. package/dist/file-host-worker.js +1 -1
  71. package/dist/file-host-worker.mjs +1 -1
  72. package/dist/{hub-mdns-ciao-Cnd0bTB9.mjs → hub-mdns-ciao-BS2akjWx.mjs} +1 -1
  73. package/dist/{hub-mdns-ciao-DOBTq8qr.js → hub-mdns-ciao-Da-0NEyr.js} +1 -1
  74. package/dist/index.js +142 -13
  75. package/dist/index.mjs +137 -14
  76. package/dist/kernel/addon-refused-error.d.ts +30 -0
  77. package/dist/kernel/index.d.ts +3 -0
  78. package/dist/kernel/legacy-blob-guard.d.ts +6 -1
  79. package/dist/kernel/moleculer/process-service.d.ts +16 -1
  80. package/dist/kernel/moleculer/runner-refusal.d.ts +27 -0
  81. package/dist/{restore-archive-CfSSjKnA.js → restore-archive-Cdf09dHm.js} +1 -1
  82. package/dist/{restore-archive-4ziluTU3.mjs → restore-archive-RaA3uZ7H.mjs} +1 -1
  83. package/dist/{wal-maintenance-CgZTNWAz.js → wal-maintenance-C-bmkDhm.js} +0 -0
  84. package/dist/{wal-maintenance-B57SAp4a.mjs → wal-maintenance-DE8QrreK.mjs} +0 -0
  85. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import "node:crypto";
3
- //#region ../types/dist/event-category-C4hVnRo8.mjs
3
+ //#region ../types/dist/event-category-BvOFi6PY.mjs
4
4
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
5
5
  EventCategory["SystemBoot"] = "system.boot";
6
6
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -64,6 +64,24 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
64
64
  * consumes this category and maps it to the `addon-crash-loop` kind.
65
65
  */
66
66
  EventCategory["AddonRunnerFailed"] = "addon.runner-failed";
67
+ /**
68
+ * A runner whose addon refused to start with a typed reason (D877) - parked
69
+ * in `refused`, never counted by the crash breaker, retried on operator
70
+ * action. One event per refusal.
71
+ */
72
+ EventCategory["AddonRunnerRefused"] = "addon.runner-refused";
73
+ /**
74
+ * A runner settled on a state (D877): `running` (READY), `crashed`, `failed` or
75
+ * `refused`. In-process telemetry for the boot check (re-evaluate while any
76
+ * runner is still pending) and the alert centre (close a recovered runner).
77
+ */
78
+ EventCategory["ProcessStateChanged"] = "process.state-changed";
79
+ /**
80
+ * The node's one-shot runner boot check (D877): planned runners against the
81
+ * process service, `degraded` when any is failed, refused or missing. The
82
+ * alert centre turns it into one alert and a direct critical push.
83
+ */
84
+ EventCategory["SystemRunnerCheck"] = "system.runner-check";
67
85
  EventCategory["AddonError"] = "addon.error";
68
86
  EventCategory["AddonPageReady"] = "addon.page-ready";
69
87
  EventCategory["AddonWidgetReady"] = "addon.widget-ready";
@@ -718,7 +736,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
718
736
  return EventCategory;
719
737
  }({});
720
738
  //#endregion
721
- //#region ../types/dist/sleep-bwsTj221.mjs
739
+ //#region ../types/dist/sleep-bgZLodYc.mjs
722
740
  /**
723
741
  * The audio chunk plane's byte format, and the ONE expansion from a coded
724
742
  * window to float samples (D455).
@@ -41046,6 +41064,36 @@ var llmRuntimeCapability = {
41046
41064
  }
41047
41065
  };
41048
41066
  /**
41067
+ * The report of a one-shot "move this owner's plaintext secrets into the
41068
+ * keychain" run (D878). COUNTS only - never a value, never a ref.
41069
+ *
41070
+ * The owner runs it on its own rows, through its own write path; an operator
41071
+ * script (`scripts/hub/migrate-raw-secrets.ts`) calls the owner's cap method.
41072
+ * Dry run (`apply: false`) reports what WOULD move and changes nothing.
41073
+ */
41074
+ var RawSecretMigrationInputSchema = z.object({
41075
+ /** `false` (the default of the script) = report only. */
41076
+ apply: z.boolean() });
41077
+ var RawSecretMigrationReportSchema = z.object({
41078
+ apply: z.boolean(),
41079
+ /** Rows that can carry a secret (a profile, an enrolment). */
41080
+ rows: z.number().int(),
41081
+ /** Rows whose secret was plaintext when the run started. */
41082
+ raw: z.number().int(),
41083
+ /** Rows that already held a keychain marker when the run started. */
41084
+ markers: z.number().int(),
41085
+ /** Plaintext rows moved by THIS run (always 0 on a dry run). */
41086
+ migrated: z.number().int(),
41087
+ /** Plaintext rows left in place because the move or its read-back failed. */
41088
+ failed: z.number().int(),
41089
+ /** After the run: rows still holding plaintext. */
41090
+ remainingRaw: z.number().int(),
41091
+ /** After the run: markers the keychain could not resolve right now. */
41092
+ unresolvedMarkers: z.number().int(),
41093
+ /** True when nothing is raw and every marker resolves. */
41094
+ verified: z.boolean()
41095
+ });
41096
+ /**
41049
41097
  * `llm` — consumer-facing LLM surface (spec §1-§3). Collection-mode: array
41050
41098
  * methods concat-fan across providers; single-row methods route to ONE
41051
41099
  * provider by the `addonId` in the call input (the notification-output
@@ -41252,6 +41300,16 @@ var llmCapability = {
41252
41300
  kind: "mutation",
41253
41301
  auth: "admin"
41254
41302
  }),
41303
+ /**
41304
+ * D878: move every profile's plaintext `apiKey` into the keychain (owner
41305
+ * `ai`), leaving a marker in the row. Dry run unless `apply`; idempotent;
41306
+ * counts only. The plaintext is cleared only after the keychain read-back
41307
+ * matched.
41308
+ */
41309
+ migrateRawSecrets: method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
41310
+ kind: "mutation",
41311
+ auth: "admin"
41312
+ }),
41255
41313
  deleteProfile: method(ProfileRefInputSchema, z.void(), {
41256
41314
  kind: "mutation",
41257
41315
  auth: "admin"
@@ -54032,6 +54090,41 @@ var ServerRollbackInfoSchema = z.object({
54032
54090
  atMs: z.number(),
54033
54091
  reason: z.string()
54034
54092
  });
54093
+ /**
54094
+ * The runner boot check (D877): the runners this node PLANNED (hub: one per
54095
+ * `resolveRunnerId` over its forked addons; agent: the runners its process
54096
+ * service holds, because only the hub plans) against the states the process
54097
+ * service reports. Kept in memory, recomputed by the same one-shot check after
54098
+ * every boot, served on `getServerPackageStatus`.
54099
+ *
54100
+ * `failed` is the D6 breaker's terminal state, `refused` a deterministic Init
54101
+ * refusal (an addon that said "I will not start, and here is why"), `missing` a
54102
+ * planned runner the process service has no entry for.
54103
+ */
54104
+ var RunnerRefusalSchema = z.object({
54105
+ runnerId: z.string(),
54106
+ addonIds: z.array(z.string()),
54107
+ reason: z.string()
54108
+ });
54109
+ var RunnerBootCheckSchema = z.object({
54110
+ checkedAtMs: z.number(),
54111
+ /** Runners planned for this node. */
54112
+ expected: z.number(),
54113
+ /** Planned runners whose process is `running`. */
54114
+ running: z.number(),
54115
+ failed: z.array(z.string()),
54116
+ refused: z.array(RunnerRefusalSchema),
54117
+ missing: z.array(z.string()),
54118
+ /**
54119
+ * Runners still on their way: `starting`, or `crashed` waiting on a backoff
54120
+ * respawn. The check is FINAL only when this is empty; until then nothing is
54121
+ * pushed and the verdict is re-evaluated on the next runner state change.
54122
+ * Optional for version skew (absent = settled).
54123
+ */
54124
+ pending: z.array(z.string()).optional(),
54125
+ /** True when the plan is the hub's (`missing` is then meaningful); false on an agent. */
54126
+ planKnown: z.boolean()
54127
+ });
54035
54128
  var ServerPackageStatusSchema = z.object({
54036
54129
  /** Root package name (`@camstack/server` on the hub). */
54037
54130
  packageName: z.string(),
@@ -54094,7 +54187,14 @@ var ServerPackageStatusSchema = z.object({
54094
54187
  * for version skew: an older provider's payload simply omits it, and an
54095
54188
  * absent wrapper is unknown — never `native`.
54096
54189
  */
54097
- wrapper: WrapperIdentitySchema.optional()
54190
+ wrapper: WrapperIdentitySchema.optional(),
54191
+ /**
54192
+ * What this node PLANNED to run against what its process service reports
54193
+ * (D877). Absent until the one-shot boot check has run (~60 s after boot) and
54194
+ * on a provider that predates it. Absent is "not checked yet", never "all
54195
+ * well": a consumer that needs the answer treats it as pending.
54196
+ */
54197
+ runners: RunnerBootCheckSchema.optional()
54098
54198
  });
54099
54199
  var ServerUpdateCheckResultSchema = z.object({
54100
54200
  packageName: z.string(),
@@ -54145,6 +54245,13 @@ var ServerUpdateOutcomeSchema = z.enum([
54145
54245
  "refused",
54146
54246
  "failed"
54147
54247
  ]);
54248
+ /** One addon the pre-flight found the target version would refuse (D877). */
54249
+ var UpdateBlockerSchema = z.object({
54250
+ addonId: z.string(),
54251
+ reason: z.string(),
54252
+ /** What the operator does about it. */
54253
+ remedy: z.string()
54254
+ });
54148
54255
  var ServerUpdateActionResultSchema = z.object({
54149
54256
  accepted: z.boolean(),
54150
54257
  targetVersion: z.string().nullable(),
@@ -54162,7 +54269,13 @@ var ServerUpdateActionResultSchema = z.object({
54162
54269
  * The failure itself, verbatim enough to act on (the npm output for a
54163
54270
  * staging install). Non-null only for `failed`.
54164
54271
  */
54165
- error: z.string().nullable().optional()
54272
+ error: z.string().nullable().optional(),
54273
+ /**
54274
+ * The addons the target version would refuse to start on this node's live
54275
+ * store (D877), present when the pre-flight refused the update
54276
+ * (`reason: 'addon-would-refuse'`). Optional for version skew.
54277
+ */
54278
+ blockers: z.array(UpdateBlockerSchema).optional()
54166
54279
  });
54167
54280
  var serverManagementCapability = {
54168
54281
  name: "server-management",
@@ -54174,9 +54287,16 @@ var serverManagementCapability = {
54174
54287
  kind: "mutation",
54175
54288
  auth: "admin"
54176
54289
  }),
54177
- applyServerUpdate: method(z.object({
54178
- /** Explicit target version; omitted = latest from the registry. */
54179
- version: z.string().optional() }), ServerUpdateActionResultSchema, {
54290
+ applyServerUpdate: method(z.object({
54291
+ /** Explicit target version; omitted = latest from the registry. */
54292
+ version: z.string().optional(),
54293
+ /**
54294
+ * Apply even though the pre-flight (D877) found addons the target would
54295
+ * refuse to start. Off by default: those addons stay down until the
54296
+ * remedy is run, which is the incident this gate exists to prevent.
54297
+ */
54298
+ acknowledgeRefusals: z.boolean().optional()
54299
+ }), ServerUpdateActionResultSchema, {
54180
54300
  kind: "mutation",
54181
54301
  auth: "admin",
54182
54302
  timeoutMs: 16 * 6e4
@@ -57498,7 +57618,9 @@ var ManifestShapeSchema = z.object({
57498
57618
  var AddonProcessSchema = z.object({
57499
57619
  pid: z.number().optional(),
57500
57620
  mode: z.string(),
57501
- state: z.string()
57621
+ state: z.string(),
57622
+ /** Why the runner is `refused` (an addon's own words), when it is (D877). */
57623
+ reason: z.string().optional()
57502
57624
  });
57503
57625
  /**
57504
57626
  * Per-addon health snapshot from the kernel's AddonHealthMonitor.
@@ -70104,6 +70226,16 @@ var userManagementCapability = {
70104
70226
  access: "delete"
70105
70227
  }),
70106
70228
  getTotpStatus: method(z.object({ userId: z.string() }), TotpStatusSchema, { auth: "admin" }),
70229
+ /**
70230
+ * D878: move every TOTP seed stored in plaintext into the keychain (owner
70231
+ * `system`), leaving a marker in the row. Dry run unless `apply`;
70232
+ * idempotent; counts only.
70233
+ */
70234
+ migrateRawSecrets: method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
70235
+ kind: "mutation",
70236
+ auth: "admin",
70237
+ access: "create"
70238
+ }),
70107
70239
  verifyTotp: method(z.object({
70108
70240
  userId: z.string(),
70109
70241
  code: z.string()
@@ -76483,6 +76615,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
76483
76615
  addonId: null,
76484
76616
  access: "view"
76485
76617
  },
76618
+ "llm.migrateRawSecrets": {
76619
+ capName: "llm",
76620
+ capScope: "system",
76621
+ addonId: null,
76622
+ access: "create"
76623
+ },
76486
76624
  "llm.resolveModelRef": {
76487
76625
  capName: "llm",
76488
76626
  capScope: "system",
@@ -81025,6 +81163,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
81025
81163
  addonId: null,
81026
81164
  access: "view"
81027
81165
  },
81166
+ "userManagement.migrateRawSecrets": {
81167
+ capName: "user-management",
81168
+ capScope: "system",
81169
+ addonId: null,
81170
+ access: "create"
81171
+ },
81028
81172
  "userManagement.oauthExchangeCode": {
81029
81173
  capName: "user-management",
81030
81174
  capScope: "system",
@@ -86126,4 +86270,4 @@ function enumerateInferenceDevices(hw) {
86126
86270
  return out;
86127
86271
  }
86128
86272
  //#endregion
86129
- export { StorageCleanupJobSchema as $, splitTranslationRef as $n, formatSecretScope as $r, gbToBytes as $t, DeclaredDevices as A, pickAppLinkHub as An, errMsg as Ar, databaseSnapshotCapability as At, METHOD_ACCESS_MAP as B, resolveCoreBlockFiles as Bn, WELL_KNOWN_TAB_MAP as Br, deviceStatusCapability as Bt, DAY_NAMES as C, modeMayWrite as Cn, compositionSourceKey as Cr, coreBlockAddonId as Ct, DEVICE_SAN_CREDENTIAL_PREFIX as D, objectInputDeclaresAddonId as Dn, DeviceFeature as Dr, coreBlocksCapability as Dt, DEVICE_NONCE_TTL_MS as E, normalizeUnit as En, toExpressionValue as Er, coreBlockSourceKind as Et, HUB_MDNS_SERVICE_TYPE as F, reducePoints as Fn, REDACTED_SECRET as Fr, describeComposableCaps as Ft, RecordingStatusSchema as G, runtimeStatePolicyFor as Gn, collectSecretConfigKeys as Gr, evictionPolicyOfLocation as Gt, MOTION_CLOSE_AFTER_MS as H, resolveLocationMode as Hn, asNumber as Hr, enumerateItemArrayFields as Ht, HUB_MDNS_TXT_KEYS as I, replacedFieldKeys as In, RUNTIME_DEFAULTS as Ir, deviceCredentialsCapability as It, STORAGE_ADMIN_SCOPED_BASES as J, scoreRuntimes as Jn, customAction as Jr, extractNestedAddonId as Jt, STORAGE_ACCESS_FALLBACK as K, scopesAllowAddon as Kn, collectZodSecretPaths as Kr, expandContainer as Kt, KEYCHAIN_RESET_TRIGGER_ACTOR as L, resolveAppConnections as Ln, ReadinessRegistry as Lr, deviceExtensionCapability as Lt, FIRST_LEVEL_MACRO_CLASSES as M, platformProbeCapability as Mn, DATAPLANE_SECRET_HEADER as Mr, decodeVectorBase64 as Mt, FieldClaimModeSchema as N, procedureAuthKey as Nn, DEVICE_SETTINGS_CONTRIBUTION_METHODS as Nr, defineExtensionSlotProvider as Nt, DEVICE_SAN_USER_PREFIX as O, objectInputDeclaresRequiredDeviceId as On, DeviceRole as Or, createDeviceExtensionProvider as Ot, FieldClaimSchema as P, ptzAutotrackCapability as Pn, DEVICE_STATUS_METHOD as Pr, deriveBatteryPresence as Pt, SsoBridgeClaimsSchema as Q, snapshotCapability as Qn, expandCapMethods as Qr, formatMinutes as Qt, LOG_LEVEL_RANK as R, resolveBucketMs as Rn, ReadinessTimeoutError as Rr, deviceManagerCapability as Rt, DATA_STORE_DATABASES as S, EventCategory as Si, metricsProviderCapability as Sn, compositionSliceKey as Sr, compositionSourceRefs as St, DEVICE_ENROLLMENT_TTL_MS as T, normalizeCoreBlockWrite as Tn, disarmRoseMemory as Tr, coreBlockIdFromAddonId as Tt, NetworkTunnelStartedDataSchema as U, resolveMethodAuth as Un, asString$1 as Ur, enumerateSchemaFields as Ut, MINUTES_PER_DAY as V, resolveHubAddressRoles as Vn, asJsonObject as Vr, enumerateInferenceDevices as Vt, RECORDING_SOURCE_CAMSTACK_ADDON as W, resolveNotificationTapAddress as Wn, buildSecretRef as Wr, evaluateCompositionField as Wt, ScopedTokenSchema as X, shortHostname as Xn, emitDownForOwnedCaps as Xr, foldSnapshotByFunction as Xt, STREAM_PROFILE_META as Y, settingsStoreCapability as Yn, defineCustomActions as Yr, filesystemBrowseCapability as Yt, ServerNameSchema as Z, siteZoneKey as Zn, emitReadiness as Zr, formatDeviceRevoker as Zt, CatalogFileSchema as _, sleep as _i, logLevelAtMost as _n, cloneStatefulExpressionMemory as _r, cameraGridLayoutCapability as _t, ApiKeyRecordSchema as a, isSecretMarker as ai, isLocationEnabled as an, streamCatalogCapability as ar, addonSettingsCapability as at, DATABASE_SNAPSHOT_SUFFIX as b, transformSecretWrite as bi, mayWriteToLocation as bn, compositionFeatureEnabled as br, composerCapability as bt, CAMERA_SWITCH_ORDER as c, normalizeSecretOwner as ci, kebabToCamel as cn, userManagementCapability as cr, authProviderCapability as ct, CATALOG_LANGS as d, parseSecretRef as di, legacyAutoLinkIds as dn, vectorDimFromBase64 as dr, batteryCapability as dt, hydrateSchema as ei, interpolate as en, storageAdminCapability as er, StorageLocationModeSchema as et, COMPOSED_ITEM_FIXED_FIELDS as f, readinessKey as fi, legacyModeOf as fn, vectorIndexDimConflictError as fr, buildCapabilityLookup as ft, CalendarPreferencesSchema as g, secretTreeFromPaths as gi, logDestinationCapability as gn, buildFfmpegArgs as gr, calendarsCapability as gt, CORE_BLOCK_ADDON_PREFIX as h, scopeKey as hi, locationIconKey as hn, COMPOSER_ADDON_ID as hr, buildStreamParamsConfigSchema as ht, AlertSchema as i, isSecretClear as ii, isDefaultAppConnectionEndpoint as in, storageProviderCapability as ir, addonPagesCapability as it, DeviceStatusSchema as j, planComposition as jn, BaseAddon as jr, declarationOwnerNodeId as jt, DEVICE_TOMBSTONE_RETENTION_MS as k, parseStreamParamsFormPatch as kn, DeviceType as kr, dataStoreProviderCapability as kt, CAMSTACK_APP_LINK_ORIGIN as l, parseJsonObject as li, keychainAdminCapability as ln, validateComposition as lr, backupCapability as lt, CORE_BLOCKS_ADDON_ID as m, resolveSecretMarkers as mi, localNetworkCapability as mn, withLocationMode as mr, buildDeviceSignatureMessage as mt, AGENT_MDNS_TXT_KEYS as n, isEvent as ni, isArrayOutputSchema as nn, storageMigrationCapability as nr, StorageMigrationJobSchema as nt, BaseDevice as o, isSecretMarkerLike as oi, isObjectInput as on, streamQualityLabel as or, addonWidgetsCapability as ot, COMPOSER_RUNNER_ID as p, resolveCapMount as pi, lifecycleJobSchema as pn, vectorStoreCapability as pr, buildDeviceEnrollmentLink as pt, STORAGE_ADMIN_MOVED_COLLECTIONS as q, scopesAllowDeviceCap as qn, createEvent as qr, expressionContainsBuiltinCall as qt, ALL_CAPABILITY_DEFINITIONS as r, isKeychainStoredField as ri, isCollectionArrayMethod as rn, storageOccupancyCapability as rr, UserRecordSchema as rt, BatteryStatusSchema as s, nodePin as si, isVoidInput as sn, supportedRuntimes as sr, alertsCapability as st, AGENT_MDNS_SERVICE_TYPE as t, isDeviceConfigCap as ti, isAppLinkBase as tn, storageCapability as tr, StorageLocationTypeSchema as tt, CAP_NAMES_WITH_STATUS as u, parseJsonUnknown as ui, keychainCapability as un, validateCustomAddress as ur, bareAddonId as ut, CoreBlockSchema as v, toNodeId as vi, looseSchema as vn, composedDeviceRef as vr, canonicalIconKey as vt, DERIVED_CAMERA_SILENCED_CAP_NAMES as w, motionCapability as wn, createStatefulExpressionMemory as wr, coreBlockComposition as wt, DATABASE_SNAPSHOT_TIMEOUT_MS as x, userError as xi, memoizePinnedFfmpeg as xn, compositionItemFieldPath as xr, compositionFieldKey as xt, DATABASE_SNAPSHOT_PARTIAL_SUFFIX as y, toSecretFieldView as yi, mayReadLocation as yn, composedDeviceStableId as yr, checkRoleAddress as yt, LegacyStorageLocationDefaultSchema as z, resolveCoreBlockEntry as zn, SECRET_CLEAR as zr, deviceStateCapability as zt };
86273
+ export { StorageCleanupJobSchema as $, splitTranslationRef as $n, formatSecretScope as $r, gbToBytes as $t, DeclaredDevices as A, pickAppLinkHub as An, errMsg as Ar, databaseSnapshotCapability as At, METHOD_ACCESS_MAP as B, resolveCoreBlockFiles as Bn, WELL_KNOWN_TAB_MAP as Br, deviceStatusCapability as Bt, DAY_NAMES as C, EventCategory as Ci, modeMayWrite as Cn, compositionSourceKey as Cr, coreBlockAddonId as Ct, DEVICE_SAN_CREDENTIAL_PREFIX as D, objectInputDeclaresAddonId as Dn, DeviceFeature as Dr, coreBlocksCapability as Dt, DEVICE_NONCE_TTL_MS as E, normalizeUnit as En, toExpressionValue as Er, coreBlockSourceKind as Et, HUB_MDNS_SERVICE_TYPE as F, reducePoints as Fn, REDACTED_SECRET as Fr, describeComposableCaps as Ft, RecordingStatusSchema as G, runtimeStatePolicyFor as Gn, collectSecretConfigKeys as Gr, evictionPolicyOfLocation as Gt, MOTION_CLOSE_AFTER_MS as H, resolveLocationMode as Hn, asNumber as Hr, enumerateItemArrayFields as Ht, HUB_MDNS_TXT_KEYS as I, replacedFieldKeys as In, RUNTIME_DEFAULTS as Ir, deviceCredentialsCapability as It, STORAGE_ADMIN_SCOPED_BASES as J, scoreRuntimes as Jn, customAction as Jr, extractNestedAddonId as Jt, STORAGE_ACCESS_FALLBACK as K, scopesAllowAddon as Kn, collectZodSecretPaths as Kr, expandContainer as Kt, KEYCHAIN_RESET_TRIGGER_ACTOR as L, resolveAppConnections as Ln, ReadinessRegistry as Lr, deviceExtensionCapability as Lt, FIRST_LEVEL_MACRO_CLASSES as M, platformProbeCapability as Mn, DATAPLANE_SECRET_HEADER as Mr, decodeVectorBase64 as Mt, FieldClaimModeSchema as N, procedureAuthKey as Nn, DEVICE_SETTINGS_CONTRIBUTION_METHODS as Nr, defineExtensionSlotProvider as Nt, DEVICE_SAN_USER_PREFIX as O, objectInputDeclaresRequiredDeviceId as On, DeviceRole as Or, createDeviceExtensionProvider as Ot, FieldClaimSchema as P, ptzAutotrackCapability as Pn, DEVICE_STATUS_METHOD as Pr, deriveBatteryPresence as Pt, SsoBridgeClaimsSchema as Q, snapshotCapability as Qn, expandCapMethods as Qr, formatMinutes as Qt, LOG_LEVEL_RANK as R, resolveBucketMs as Rn, ReadinessTimeoutError as Rr, deviceManagerCapability as Rt, DATA_STORE_DATABASES as S, userError as Si, metricsProviderCapability as Sn, compositionSliceKey as Sr, compositionSourceRefs as St, DEVICE_ENROLLMENT_TTL_MS as T, normalizeCoreBlockWrite as Tn, disarmRoseMemory as Tr, coreBlockIdFromAddonId as Tt, NetworkTunnelStartedDataSchema as U, resolveMethodAuth as Un, asString$1 as Ur, enumerateSchemaFields as Ut, MINUTES_PER_DAY as V, resolveHubAddressRoles as Vn, asJsonObject as Vr, enumerateInferenceDevices as Vt, RECORDING_SOURCE_CAMSTACK_ADDON as W, resolveNotificationTapAddress as Wn, buildSecretRef as Wr, evaluateCompositionField as Wt, ScopedTokenSchema as X, shortHostname as Xn, emitDownForOwnedCaps as Xr, foldSnapshotByFunction as Xt, STREAM_PROFILE_META as Y, settingsStoreCapability as Yn, defineCustomActions as Yr, filesystemBrowseCapability as Yt, ServerNameSchema as Z, siteZoneKey as Zn, emitReadiness as Zr, formatDeviceRevoker as Zt, CatalogFileSchema as _, secretTreeFromPaths as _i, logLevelAtMost as _n, cloneStatefulExpressionMemory as _r, cameraGridLayoutCapability as _t, ApiKeyRecordSchema as a, isSecretMarker as ai, isLocationEnabled as an, streamCatalogCapability as ar, addonSettingsCapability as at, DATABASE_SNAPSHOT_SUFFIX as b, toSecretFieldView as bi, mayWriteToLocation as bn, compositionFeatureEnabled as br, composerCapability as bt, CAMERA_SWITCH_ORDER as c, nodePin as ci, kebabToCamel as cn, userManagementCapability as cr, authProviderCapability as ct, CATALOG_LANGS as d, parseJsonUnknown as di, legacyAutoLinkIds as dn, vectorDimFromBase64 as dr, batteryCapability as dt, hydrateSchema as ei, interpolate as en, storageAdminCapability as er, StorageLocationModeSchema as et, COMPOSED_ITEM_FIXED_FIELDS as f, parseSecretRef as fi, legacyModeOf as fn, vectorIndexDimConflictError as fr, buildCapabilityLookup as ft, CalendarPreferencesSchema as g, scopeKey as gi, logDestinationCapability as gn, buildFfmpegArgs as gr, calendarsCapability as gt, CORE_BLOCK_ADDON_PREFIX as h, resolveSecretMarkers as hi, locationIconKey as hn, COMPOSER_ADDON_ID as hr, buildStreamParamsConfigSchema as ht, AlertSchema as i, isSecretClear as ii, isDefaultAppConnectionEndpoint as in, storageProviderCapability as ir, addonPagesCapability as it, DeviceStatusSchema as j, planComposition as jn, BaseAddon as jr, declarationOwnerNodeId as jt, DEVICE_TOMBSTONE_RETENTION_MS as k, parseStreamParamsFormPatch as kn, DeviceType as kr, dataStoreProviderCapability as kt, CAMSTACK_APP_LINK_ORIGIN as l, normalizeSecretOwner as li, keychainAdminCapability as ln, validateComposition as lr, backupCapability as lt, CORE_BLOCKS_ADDON_ID as m, resolveCapMount as mi, localNetworkCapability as mn, withLocationMode as mr, buildDeviceSignatureMessage as mt, AGENT_MDNS_TXT_KEYS as n, isEvent as ni, isArrayOutputSchema as nn, storageMigrationCapability as nr, StorageMigrationJobSchema as nt, BaseDevice as o, isSecretMarkerLike as oi, isObjectInput as on, streamQualityLabel as or, addonWidgetsCapability as ot, COMPOSER_RUNNER_ID as p, readinessKey as pi, lifecycleJobSchema as pn, vectorStoreCapability as pr, buildDeviceEnrollmentLink as pt, STORAGE_ADMIN_MOVED_COLLECTIONS as q, scopesAllowDeviceCap as qn, createEvent as qr, expressionContainsBuiltinCall as qt, ALL_CAPABILITY_DEFINITIONS as r, isKeychainStoredField as ri, isCollectionArrayMethod as rn, storageOccupancyCapability as rr, UserRecordSchema as rt, BatteryStatusSchema as s, makeSecretMarker as si, isVoidInput as sn, supportedRuntimes as sr, alertsCapability as st, AGENT_MDNS_SERVICE_TYPE as t, isDeviceConfigCap as ti, isAppLinkBase as tn, storageCapability as tr, StorageLocationTypeSchema as tt, CAP_NAMES_WITH_STATUS as u, parseJsonObject as ui, keychainCapability as un, validateCustomAddress as ur, bareAddonId as ut, CoreBlockSchema as v, sleep as vi, looseSchema as vn, composedDeviceRef as vr, canonicalIconKey as vt, DERIVED_CAMERA_SILENCED_CAP_NAMES as w, motionCapability as wn, createStatefulExpressionMemory as wr, coreBlockComposition as wt, DATABASE_SNAPSHOT_TIMEOUT_MS as x, transformSecretWrite as xi, memoizePinnedFfmpeg as xn, compositionItemFieldPath as xr, compositionFieldKey as xt, DATABASE_SNAPSHOT_PARTIAL_SUFFIX as y, toNodeId as yi, mayReadLocation as yn, composedDeviceStableId as yr, checkRoleAddress as yt, LegacyStorageLocationDefaultSchema as z, resolveCoreBlockEntry as zn, SECRET_CLEAR as zr, deviceStateCapability as zt };
@@ -1,5 +1,5 @@
1
1
  require("./chunk-Cek0wNdY.js");
2
- const require_wal_maintenance = require("./wal-maintenance-CgZTNWAz.js");
2
+ const require_wal_maintenance = require("./wal-maintenance-C-bmkDhm.js");
3
3
  let node_worker_threads = require("node:worker_threads");
4
4
  //#region src/builtins/sqlite-storage/file-host-worker.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { C as callData, S as callControl, T as controlTargetOf, a as WalMaintenance, b as trustInput, c as SqliteSettingsBackend, g as collectTransferables, m as serializeError, o as createVectorIndex, s as vectorProviderOf, v as isFileHostRequest, w as callVector, y as isFileHostWorkerData } from "./wal-maintenance-B57SAp4a.mjs";
1
+ import { C as callData, S as callControl, T as controlTargetOf, a as WalMaintenance, b as trustInput, c as SqliteSettingsBackend, g as collectTransferables, m as serializeError, o as createVectorIndex, s as vectorProviderOf, v as isFileHostRequest, w as callVector, y as isFileHostWorkerData } from "./wal-maintenance-DE8QrreK.mjs";
2
2
  import { parentPort, threadId, workerData } from "node:worker_threads";
3
3
  //#region src/builtins/sqlite-storage/file-host-worker.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { o as __toESM } from "./chunk-CNf5ZN-e.mjs";
2
- import { xi as userError } from "./dist-BWvkuc31.mjs";
2
+ import { Si as userError } from "./dist-DsrQYcLm.mjs";
3
3
  import { f as X509Certificate$1 } from "./x509.es-DK__ETIe.mjs";
4
4
  import { A as isConstrainedCa, E as reasonRequiresNewCa, M as permitsIdentity, P as readNameConstraints, T as evaluateExistingCert, _ as issueLeaf, g as generateCa, v as loadCa, y as collectCertIdentity } from "./agent-https-U0d4uvn2.mjs";
5
5
  import { X509Certificate, createPrivateKey } from "node:crypto";
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require("./chunk-Cek0wNdY.js");
2
- const require_dist = require("./dist-BiTCcaf-.js");
2
+ const require_dist = require("./dist-CyIHDLCg.js");
3
3
  const require_x509_es = require("./x509.es-C4cOo48M.js");
4
4
  const require_agent_https = require("./agent-https-DlpTMDqA.js");
5
5
  let node_crypto = require("node:crypto");
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-BiTCcaf-.js");
4
- const require_device_ca = require("./device-ca-196DAEZT.js");
3
+ const require_dist = require("./dist-CyIHDLCg.js");
4
+ const require_device_ca = require("./device-ca-tKY_ZS9H.js");
5
5
  const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
6
6
  require("./builtins/alerts/index.js");
7
7
  const require_builtins_calendars_calendars_addon = require("./builtins/calendars/calendars.addon.js");
@@ -25,21 +25,21 @@ require("./builtins/local-auth/index.js");
25
25
  const require_builtins_loki_logging_index = require("./builtins/loki-logging/index.js");
26
26
  const require_builtins_native_metrics_native_metrics_addon = require("./builtins/native-metrics/native-metrics.addon.js");
27
27
  const require_builtins_sqlite_storage_filesystem_storage_addon = require("./builtins/sqlite-storage/filesystem-storage.addon.js");
28
- const require_wal_maintenance = require("./wal-maintenance-CgZTNWAz.js");
28
+ const require_wal_maintenance = require("./wal-maintenance-C-bmkDhm.js");
29
29
  const require_builtins_sqlite_storage_sqlite_settings_addon = require("./builtins/sqlite-storage/sqlite-settings.addon.js");
30
30
  const require_builtins_sqlite_storage_index = require("./builtins/sqlite-storage/index.js");
31
31
  const require_builtins_storage_orchestrator_storage_orchestrator_addon = require("./builtins/storage-orchestrator/storage-orchestrator.addon.js");
32
32
  require("./builtins/storage-orchestrator/index.js");
33
33
  const require_agent_https = require("./agent-https-DlpTMDqA.js");
34
- const require_constants = require("./constants-UojhAJcm.js");
34
+ const require_constants = require("./constants-b7kpjuO4.js");
35
35
  const require_builtins_system_config_system_config_addon = require("./builtins/system-config/system-config.addon.js");
36
36
  require("./builtins/system-config/index.js");
37
37
  const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
38
38
  const require_custom_action_registry = require("./custom-action-registry-BKmoaqG0.js");
39
- const require_hub_mdns_ciao = require("./hub-mdns-ciao-DOBTq8qr.js");
39
+ const require_hub_mdns_ciao = require("./hub-mdns-ciao-Da-0NEyr.js");
40
40
  const require_platform_key_source = require("./platform-key-source-Di7HrlGR.js");
41
41
  const require_resource_monitor = require("./resource-monitor-mio9dSCT.js");
42
- const require_restore_archive = require("./restore-archive-CfSSjKnA.js");
42
+ const require_restore_archive = require("./restore-archive-Cdf09dHm.js");
43
43
  let zod = require("zod");
44
44
  let node_crypto = require("node:crypto");
45
45
  node_crypto = require_chunk.__toESM(node_crypto);
@@ -23020,6 +23020,50 @@ function createRunnerAddonSettings(client, addonId, before = async () => {}) {
23020
23020
  };
23021
23021
  }
23022
23022
  //#endregion
23023
+ //#region src/kernel/addon-refused-error.ts
23024
+ /**
23025
+ * A deterministic Init refusal (D877): an addon that says, in a typed way,
23026
+ * "I will not start, and here is why" - as opposed to a crash.
23027
+ *
23028
+ * The difference matters to the supervisor. A crash may be transient (a camera
23029
+ * dropping mid-handshake) and is bounded by the D6 circuit-breaker; a refusal
23030
+ * repeats identically until somebody changes the world (runs a migration,
23031
+ * fixes a setting), so counting it toward the breaker only turns "waiting for
23032
+ * the operator" into a terminal `failed` with a stack trace nobody needed.
23033
+ * On 2026-10-17 twenty-eight addons refused on an unmigrated store, exited five
23034
+ * times in ten seconds and were marked `failed` as if they had crashed.
23035
+ *
23036
+ * The runner reports a refusal to its parent (see `runner-refusal.ts`); the
23037
+ * process service parks the runner in `refused` with the reason and retries it
23038
+ * only when an operator acts.
23039
+ */
23040
+ var AddonRefusedError = class extends Error {
23041
+ /** Stable, greppable cause, e.g. `unmigrated-settings`. */
23042
+ code;
23043
+ /** What the operator does about it. */
23044
+ remedy;
23045
+ constructor(code, message, remedy, options) {
23046
+ super(message, options);
23047
+ this.name = "AddonRefusedError";
23048
+ this.code = code;
23049
+ this.remedy = remedy;
23050
+ }
23051
+ };
23052
+ /**
23053
+ * The refusal in `err`'s cause chain, if any. An addon that wraps the error it
23054
+ * got from the kernel (`new Error('init failed', { cause })`) is still refusing.
23055
+ */
23056
+ function findAddonRefusal(err) {
23057
+ const seen = /* @__PURE__ */ new Set();
23058
+ let current = err;
23059
+ while (current !== null && current !== void 0 && !seen.has(current)) {
23060
+ if (current instanceof AddonRefusedError) return current;
23061
+ seen.add(current);
23062
+ current = current instanceof Error ? current.cause : void 0;
23063
+ }
23064
+ return null;
23065
+ }
23066
+ //#endregion
23023
23067
  //#region src/kernel/legacy-blob-guard.ts
23024
23068
  /** Root keys retired long before D870: they never count as "settings still to migrate". */
23025
23069
  var OWN_RETIRED_ROOT_KEYS = new Set([
@@ -23035,9 +23079,13 @@ function isRetiredRootKey(addonId, key) {
23035
23079
  if (OWN_RETIRED_ROOT_KEYS.has(key)) return true;
23036
23080
  return require_retired_settings_keys.RETIRED_SETTINGS_KEYS.some((spec) => spec.namespace === addonId && (spec.keys.includes(key) || spec.perNodeKeys.some((k) => key === k || key.startsWith(`${k}@`))));
23037
23081
  }
23038
- var UnmigratedSettingsError = class extends Error {
23082
+ /** Stable `code` of the D870 refusal. */
23083
+ var UNMIGRATED_SETTINGS_CODE = "unmigrated-settings";
23084
+ /** The remedy the refusal (and the update pre-flight) names. */
23085
+ var UNMIGRATED_SETTINGS_REMEDY = "Run scripts/hub/migrate-device-store.ts --copy --apply (D870), then restart the addon.";
23086
+ var UnmigratedSettingsError = class extends AddonRefusedError {
23039
23087
  constructor(addonId, what) {
23040
- super(`addon "${addonId}" refuses to start: ${what} - the settings it had are still in the per-addon tables and the standard store holds none. Run scripts/hub/migrate-device-store.ts --copy --apply (D870) before starting it.`);
23088
+ super(UNMIGRATED_SETTINGS_CODE, `addon "${addonId}" refuses to start: ${what} - the settings it had are still in the per-addon tables and the standard store holds none. Run scripts/hub/migrate-device-store.ts --copy --apply (D870) before starting it.`, UNMIGRATED_SETTINGS_REMEDY);
23041
23089
  this.name = "UnmigratedSettingsError";
23042
23090
  }
23043
23091
  };
@@ -25010,6 +25058,27 @@ var AddonHealthMonitor = class {
25010
25058
  }
25011
25059
  };
25012
25060
  //#endregion
25061
+ //#region src/kernel/moleculer/runner-refusal.ts
25062
+ var REFUSED_PREFIX = "REFUSED:";
25063
+ function isReport(value) {
25064
+ if (typeof value !== "object" || value === null) return false;
25065
+ const rec = value;
25066
+ return typeof rec["addonId"] === "string" && typeof rec["code"] === "string" && typeof rec["reason"] === "string" && typeof rec["remedy"] === "string";
25067
+ }
25068
+ /** The refusals announced in a chunk of runner stdout; lines that are not one are ignored. */
25069
+ function parseRunnerRefusals(nodeId, chunk) {
25070
+ const prefix = `${REFUSED_PREFIX}${nodeId}:`;
25071
+ const out = [];
25072
+ for (const line of chunk.split("\n")) {
25073
+ if (!line.startsWith(prefix)) continue;
25074
+ try {
25075
+ const parsed = JSON.parse(line.slice(prefix.length));
25076
+ if (isReport(parsed)) out.push(parsed);
25077
+ } catch {}
25078
+ }
25079
+ return out;
25080
+ }
25081
+ //#endregion
25013
25082
  //#region src/kernel/moleculer/crash-supervisor.ts
25014
25083
  /** Per-runner crash circuit-breaker. Replaces the old infinite-respawn loop. */
25015
25084
  var CrashSupervisor = class {
@@ -25648,6 +25717,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25648
25717
  const groupOps = deps?.processGroups ?? defaultProcessGroupOps;
25649
25718
  const runnersOwnGroups = runnerOwnsProcessGroup(deps?.platform ?? process.platform);
25650
25719
  const processes = /* @__PURE__ */ new Map();
25720
+ const backingOff = /* @__PURE__ */ new Map();
25651
25721
  const pendingGroupReaps = /* @__PURE__ */ new Map();
25652
25722
  const runnerLocks = /* @__PURE__ */ new Map();
25653
25723
  function withRunnerLock(runnerId, fn) {
@@ -25688,6 +25758,19 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25688
25758
  }, data));
25689
25759
  }
25690
25760
  /**
25761
+ * Every transition a supervisor or a boot check can settle on (D877):
25762
+ * `running` (READY), `crashed`, `failed`, `refused`. In-process telemetry - the
25763
+ * boot check re-evaluates on it and the alert centre closes a recovered runner.
25764
+ */
25765
+ function emitStateChange(entry) {
25766
+ emitRunnerEvent(require_dist.EventCategory.ProcessStateChanged, entry.name, {
25767
+ runnerId: entry.name,
25768
+ nodeId: parentNodeId,
25769
+ addonIds: entry.runnerAddons.map((addon) => addon.addonId),
25770
+ state: entry.state
25771
+ });
25772
+ }
25773
+ /**
25691
25774
  * One line per reap that found something, or that failed. An empty group is the
25692
25775
  * normal case after a clean stop and stays quiet at debug. The kernel cannot say
25693
25776
  * which device a child served — the runner id is the finest attribution it has.
@@ -25752,6 +25835,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25752
25835
  */
25753
25836
  function spawnRunner(runnerId, addons, env) {
25754
25837
  const nodeId = buildNodeId(runnerId);
25838
+ backingOff.delete(runnerId);
25755
25839
  const runnerPath = node_path.resolve(__dirname, "addon-runner.js");
25756
25840
  const heavy = isHeavyRunner(addons);
25757
25841
  const rssBudgetMb = runnerRssBudgetMb(addons);
@@ -25792,6 +25876,8 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25792
25876
  startedAt: Date.now(),
25793
25877
  restartCount: 0,
25794
25878
  state: "starting",
25879
+ refusal: null,
25880
+ announcedRefusal: null,
25795
25881
  child,
25796
25882
  ownsGroup,
25797
25883
  groupReap: null
@@ -25801,7 +25887,13 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25801
25887
  kill: groupOps.kill
25802
25888
  });
25803
25889
  child.stdout?.on("data", (data) => {
25804
- if (data.toString().includes(`READY:${nodeId}`) && entry.state === "starting") entry.state = "running";
25890
+ const text = data.toString();
25891
+ const refusals = parseRunnerRefusals(nodeId, text);
25892
+ if (refusals[0] !== void 0) entry.announcedRefusal = refusals[0];
25893
+ if (text.includes(`READY:${nodeId}`) && entry.state === "starting") {
25894
+ entry.state = "running";
25895
+ emitStateChange(entry);
25896
+ }
25805
25897
  });
25806
25898
  child.stderr?.on("data", (data) => {
25807
25899
  process.stderr.write(`[${runnerId}] ${data.toString()}`);
@@ -25810,7 +25902,33 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25810
25902
  console.error(`[process-service EXIT] runner=${runnerId} code=${String(code)} signal=${String(signal)} state=${entry.state}`);
25811
25903
  const groupReap = reapRunnerGroup(entry);
25812
25904
  if (entry.state === "stopped") return;
25905
+ const announced = entry.announcedRefusal;
25906
+ entry.announcedRefusal = null;
25907
+ if (code === 78) {
25908
+ const refusal = announced ?? {
25909
+ addonId: entry.runnerAddons[0]?.addonId ?? runnerId,
25910
+ code: "unknown",
25911
+ reason: "the runner exited with the refusal code without saying why",
25912
+ remedy: "Read the runner log, fix the cause, then restart the addon."
25913
+ };
25914
+ entry.refusal = refusal;
25915
+ entry.state = "refused";
25916
+ capturedBroker?.logger.error(`[${runnerId}] Addon refused to start (${refusal.code}): ${refusal.reason} Not respawning; ${refusal.remedy}`, { tags: { runnerId } });
25917
+ processes.set(runnerId, entry);
25918
+ if (capturedBroker) forceMoleculerDisconnect(capturedBroker, entry.nodeId);
25919
+ emitRunnerEvent(require_dist.EventCategory.AddonRunnerRefused, runnerId, {
25920
+ runnerId,
25921
+ nodeId: parentNodeId,
25922
+ addonIds: entry.runnerAddons.map((addon) => addon.addonId),
25923
+ code: refusal.code,
25924
+ reason: refusal.reason,
25925
+ remedy: refusal.remedy
25926
+ });
25927
+ emitStateChange(entry);
25928
+ return;
25929
+ }
25813
25930
  entry.state = "crashed";
25931
+ emitStateChange(entry);
25814
25932
  capturedBroker?.logger.error(`[${runnerId}] Process exited (code=${code}, signal=${signal})`);
25815
25933
  const decision = crashSupervisor.recordCrash(runnerId);
25816
25934
  emitRunnerEvent(require_dist.EventCategory.ProcessCrashed, runnerId, {
@@ -25820,6 +25938,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25820
25938
  });
25821
25939
  if (decision.action === "failed") {
25822
25940
  entry.state = "failed";
25941
+ emitStateChange(entry);
25823
25942
  capturedBroker?.logger.error(`[${runnerId}] Crash circuit-breaker tripped — ${decision.crashesInWindow} crashes in ${CRASH_WINDOW_MS}ms. Not respawning.`);
25824
25943
  processes.set(runnerId, entry);
25825
25944
  if (capturedBroker) forceMoleculerDisconnect(capturedBroker, entry.nodeId);
@@ -25844,10 +25963,12 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25844
25963
  delayMs: decision.backoffMs
25845
25964
  });
25846
25965
  processes.delete(runnerId);
25966
+ backingOff.set(runnerId, entry);
25847
25967
  if (capturedBroker) forceMoleculerDisconnect(capturedBroker, entry.nodeId);
25848
25968
  setTimeout(() => {
25849
25969
  withRunnerLock(runnerId, async () => {
25850
25970
  await groupReap;
25971
+ backingOff.delete(runnerId);
25851
25972
  if (processes.has(runnerId)) return;
25852
25973
  const restarted = spawnRunner(runnerId, addons, env);
25853
25974
  restarted.restartCount = entry.restartCount + 1;
@@ -25887,7 +26008,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25887
26008
  reason: "not found"
25888
26009
  };
25889
26010
  const deadNodeId = target.nodeId;
25890
- const alreadyDead = target.state === "failed" || target.child.exitCode !== null || target.child.signalCode !== null;
26011
+ const alreadyDead = target.state === "failed" || target.state === "refused" || target.child.exitCode !== null || target.child.signalCode !== null;
25891
26012
  target.state = "stopped";
25892
26013
  if (!alreadyDead) {
25893
26014
  target.child.kill("SIGTERM");
@@ -25924,7 +26045,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25924
26045
  const { runnerAddons } = target;
25925
26046
  const deadNodeId = target.nodeId;
25926
26047
  const prevRestartCount = target.restartCount;
25927
- const alreadyDead = target.state === "failed" || target.child.exitCode !== null || target.child.signalCode !== null;
26048
+ const alreadyDead = target.state === "failed" || target.state === "refused" || target.child.exitCode !== null || target.child.signalCode !== null;
25928
26049
  target.state = "stopped";
25929
26050
  if (!alreadyDead) {
25930
26051
  target.child.kill("SIGTERM");
@@ -25953,7 +26074,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25953
26074
  });
25954
26075
  } },
25955
26076
  list: { async handler() {
25956
- const entries = [...processes.values()];
26077
+ const entries = [...processes.values(), ...backingOff.values()];
25957
26078
  const stats = await getPidStats$1(entries.filter((p) => p.pid > 0).map((p) => p.pid));
25958
26079
  return entries.map((p) => {
25959
26080
  const s = stats.get(p.pid);
@@ -25969,6 +26090,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25969
26090
  startedAt: p.startedAt,
25970
26091
  restartCount: p.restartCount,
25971
26092
  state: p.state,
26093
+ ...p.refusal !== null ? { refusal: p.refusal } : {},
25972
26094
  cpuPercent: s?.cpu ?? 0,
25973
26095
  memoryRss: s?.memoryRss ?? 0,
25974
26096
  uptimeSeconds: Math.floor((Date.now() - p.startedAt) / 1e3)
@@ -25985,7 +26107,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
25985
26107
  if (!entry) return;
25986
26108
  const { runnerAddons } = entry;
25987
26109
  const prevRestartCount = entry.restartCount;
25988
- if (!(entry.state === "failed" || entry.child.exitCode !== null || entry.child.signalCode !== null)) {
26110
+ if (!(entry.state === "failed" || entry.state === "refused" || entry.child.exitCode !== null || entry.child.signalCode !== null)) {
25989
26111
  entry.state = "stopped";
25990
26112
  entry.child.kill("SIGTERM");
25991
26113
  await new Promise((resolve) => {
@@ -26040,6 +26162,7 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
26040
26162
  startedAt: p.startedAt,
26041
26163
  restartCount: p.restartCount,
26042
26164
  state: p.state,
26165
+ ...p.refusal !== null ? { refusal: p.refusal } : {},
26043
26166
  cpuPercent: s?.cpu ?? 0,
26044
26167
  memoryRss: s?.memoryRss ?? 0,
26045
26168
  uptimeSeconds: Math.floor((Date.now() - p.startedAt) / 1e3)
@@ -27176,6 +27299,7 @@ exports.AddonHealthMonitor = AddonHealthMonitor;
27176
27299
  exports.AddonInstaller = AddonInstaller;
27177
27300
  exports.AddonLoader = AddonLoader;
27178
27301
  exports.AddonManifest = AddonManifest;
27302
+ exports.AddonRefusedError = AddonRefusedError;
27179
27303
  exports.AddonRouteRegistry = AddonRouteRegistry;
27180
27304
  exports.AdminTokenManager = require_builtins_local_auth_local_auth_addon.AdminTokenManager;
27181
27305
  exports.AgentHttpsInstallError = require_agent_https.AgentHttpsInstallError;
@@ -27366,11 +27490,14 @@ exports.TlsTcpTransporter = require_builtins_system_config_system_config_addon.T
27366
27490
  exports.ToastService = ToastService;
27367
27491
  exports.UDS_NO_ROUTE_PREFIX = UDS_NO_ROUTE_PREFIX;
27368
27492
  exports.UNCLAIMED = UNCLAIMED;
27493
+ exports.UNMIGRATED_SETTINGS_CODE = UNMIGRATED_SETTINGS_CODE;
27494
+ exports.UNMIGRATED_SETTINGS_REMEDY = UNMIGRATED_SETTINGS_REMEDY;
27369
27495
  exports.UPLOADED_CA_FILE = require_hub_mdns_ciao.UPLOADED_CA_FILE;
27370
27496
  exports.USER_MANAGEMENT_INTERNAL = require_builtins_local_auth_local_auth_addon.USER_MANAGEMENT_INTERNAL;
27371
27497
  exports.UdsLocalTransportClient = UdsLocalTransportClient;
27372
27498
  exports.UdsLocalTransportServer = UdsLocalTransportServer;
27373
27499
  exports.UnlockTicketJtiStore = require_builtins_system_config_system_config_addon.UnlockTicketJtiStore;
27500
+ exports.UnmigratedSettingsError = UnmigratedSettingsError;
27374
27501
  exports.UserManager = require_builtins_local_auth_local_auth_addon.UserManager;
27375
27502
  exports.WinstonDestination = require_builtins_winston_logging_index.WinstonDestination$1;
27376
27503
  exports.WinstonLoggingAddon = require_builtins_winston_logging_index.WinstonLoggingAddon$1;
@@ -27387,6 +27514,7 @@ exports.allFamiliesListenHost = require_hub_mdns_ciao.allFamiliesListenHost;
27387
27514
  exports.answerClaimedGetStatus = answerClaimedGetStatus;
27388
27515
  exports.applyCertificateToListener = require_hub_mdns_ciao.applyCertificateToListener;
27389
27516
  exports.applyLanHttp = require_hub_mdns_ciao.applyLanHttp;
27517
+ exports.assertLegacyBlobsMigrated = assertLegacyBlobsMigrated;
27390
27518
  exports.attachUserManagementInternal = require_builtins_local_auth_local_auth_addon.attachUserManagementInternal;
27391
27519
  exports.attributeStall = require_custom_action_registry.attributeStall;
27392
27520
  exports.bindPendingLanHttp = require_hub_mdns_ciao.bindPendingLanHttp;
@@ -27544,6 +27672,7 @@ exports.evaluateExistingCert = require_agent_https.evaluateExistingCert;
27544
27672
  exports.expandCapMethods = require_dist.expandCapMethods;
27545
27673
  exports.exportMeshPrivateKeyPem = require_builtins_system_config_system_config_addon.exportMeshPrivateKeyPem;
27546
27674
  exports.fetchJson = require_custom_action_registry.fetchJson;
27675
+ exports.findAddonRefusal = findAddonRefusal;
27547
27676
  Object.defineProperty(exports, "findInPath", {
27548
27677
  enumerable: true,
27549
27678
  get: function() {