@capybara-hq/kernel 0.1.0-rc.23 → 0.1.0-rc.25

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 (293) hide show
  1. package/bootstrap.json +25 -25
  2. package/dist/admin/admin.module.d.ts +2 -1
  3. package/dist/admin/admin.module.js +9 -3
  4. package/dist/admin/health.service.d.ts +2 -2
  5. package/dist/admin/health.service.js +6 -2
  6. package/dist/admin/outbox-dead.controller.d.ts +23 -0
  7. package/dist/admin/outbox-dead.controller.js +62 -0
  8. package/dist/admin/outbox-dead.schemas.d.ts +8 -0
  9. package/dist/admin/outbox-dead.schemas.js +18 -0
  10. package/dist/admin/outbox-dead.service.d.ts +66 -0
  11. package/dist/admin/outbox-dead.service.js +179 -0
  12. package/dist/admin/overview.service.d.ts +40 -5
  13. package/dist/admin/overview.service.js +41 -7
  14. package/dist/agents/agents.module.js +3 -0
  15. package/dist/agents/agents.service.d.ts +6 -1
  16. package/dist/agents/agents.service.js +11 -2
  17. package/dist/agents/from-template.js +1 -1
  18. package/dist/background/finish.d.ts +5 -2
  19. package/dist/background/finish.js +14 -3
  20. package/dist/background/launch.d.ts +2 -1
  21. package/dist/background/launch.js +5 -2
  22. package/dist/background/store.d.ts +8 -0
  23. package/dist/background/store.js +24 -0
  24. package/dist/catalog/admin-catalog.controller.d.ts +21 -2
  25. package/dist/catalog/admin-catalog.controller.js +45 -6
  26. package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
  27. package/dist/catalog/admin-catalog.schemas.js +8 -0
  28. package/dist/catalog/catalog-import.module.js +0 -4
  29. package/dist/catalog/catalog-scope.service.d.ts +63 -26
  30. package/dist/catalog/catalog-scope.service.js +146 -71
  31. package/dist/catalog/catalog.module.d.ts +2 -1
  32. package/dist/catalog/catalog.module.js +9 -4
  33. package/dist/catalog/catalog.service.d.ts +11 -4
  34. package/dist/catalog/catalog.service.js +21 -5
  35. package/dist/catalog/cli.d.ts +4 -3
  36. package/dist/catalog/cli.js +8 -13
  37. package/dist/catalog/job-ids.d.ts +8 -20
  38. package/dist/catalog/job-ids.js +11 -16
  39. package/dist/catalog/marketplaces.service.d.ts +1 -1
  40. package/dist/catalog/org-plugin-uploads.d.ts +11 -4
  41. package/dist/catalog/org-plugin-uploads.js +21 -6
  42. package/dist/catalog/owned-items.d.ts +6 -13
  43. package/dist/catalog/owned-items.js +11 -29
  44. package/dist/catalog/owned-plugin-cleanup.d.ts +8 -17
  45. package/dist/catalog/owned-plugin-cleanup.js +12 -66
  46. package/dist/catalog/platform-components.d.ts +56 -34
  47. package/dist/catalog/platform-components.js +68 -78
  48. package/dist/catalog/platform-import-update.d.ts +50 -0
  49. package/dist/catalog/platform-import-update.js +116 -0
  50. package/dist/catalog/plugin-import.d.ts +64 -26
  51. package/dist/catalog/plugin-import.js +113 -77
  52. package/dist/catalog/plugin-upgrade.d.ts +22 -4
  53. package/dist/catalog/plugin-upgrade.js +26 -19
  54. package/dist/catalog/scope-jobs.d.ts +59 -0
  55. package/dist/catalog/scope-jobs.js +65 -0
  56. package/dist/catalog/scope-sync-workers.d.ts +22 -0
  57. package/dist/catalog/scope-sync-workers.js +58 -2
  58. package/dist/catalog/scope-sync.d.ts +40 -65
  59. package/dist/catalog/scope-sync.js +114 -122
  60. package/dist/channels/channels.module.d.ts +5 -2
  61. package/dist/channels/channels.module.js +9 -2
  62. package/dist/channels/deliver-job.d.ts +25 -0
  63. package/dist/channels/deliver-job.js +25 -0
  64. package/dist/channels/inbound.d.ts +1 -1
  65. package/dist/channels/inbound.js +4 -17
  66. package/dist/channels/jobs.d.ts +28 -18
  67. package/dist/channels/jobs.js +63 -26
  68. package/dist/channels/threads.d.ts +4 -3
  69. package/dist/channels/threads.js +4 -3
  70. package/dist/config/schema.d.ts +0 -3
  71. package/dist/config/schema.js +11 -20
  72. package/dist/conversations/agent-tree.d.ts +16 -0
  73. package/dist/conversations/agent-tree.js +36 -0
  74. package/dist/conversations/conversations.controller.js +4 -2
  75. package/dist/conversations/conversations.service.d.ts +61 -19
  76. package/dist/conversations/conversations.service.js +69 -43
  77. package/dist/conversations/event-log.d.ts +7 -10
  78. package/dist/conversations/event-log.js +24 -15
  79. package/dist/conversations/events.d.ts +21 -0
  80. package/dist/conversations/events.js +26 -2
  81. package/dist/conversations/queue.service.d.ts +8 -3
  82. package/dist/conversations/queue.service.js +37 -13
  83. package/dist/conversations/source.d.ts +10 -0
  84. package/dist/conversations/source.js +17 -0
  85. package/dist/conversations/titles.d.ts +21 -8
  86. package/dist/conversations/titles.js +42 -15
  87. package/dist/conversations/tree.d.ts +10 -0
  88. package/dist/conversations/tree.js +35 -0
  89. package/dist/db/kernel-schema.d.ts +35 -22
  90. package/dist/devices/devices.service.d.ts +23 -11
  91. package/dist/devices/devices.service.js +34 -26
  92. package/dist/errors.d.ts +11 -0
  93. package/dist/errors.js +11 -0
  94. package/dist/evals/run-replay.d.ts +13 -2
  95. package/dist/evals/run-replay.js +42 -9
  96. package/dist/evals/snapshot.d.ts +7 -1
  97. package/dist/evals/snapshot.js +2 -1
  98. package/dist/extensions/extensions.module.js +3 -0
  99. package/dist/extensions/hooks.d.ts +22 -3
  100. package/dist/extensions/hooks.js +15 -1
  101. package/dist/extensions/lifecycle-hooks.d.ts +99 -0
  102. package/dist/extensions/lifecycle-hooks.js +273 -0
  103. package/dist/extensions/lifecycle.d.ts +6 -1
  104. package/dist/extensions/lifecycle.js +9 -2
  105. package/dist/extensions/org-config.d.ts +13 -1
  106. package/dist/extensions/org-config.js +19 -2
  107. package/dist/extensions/permission-view.d.ts +9 -5
  108. package/dist/extensions/permission-view.js +9 -4
  109. package/dist/extensions/point-defaults.d.ts +28 -1
  110. package/dist/extensions/point-defaults.js +44 -13
  111. package/dist/extensions/usage-subscribers.d.ts +43 -0
  112. package/dist/extensions/usage-subscribers.js +108 -0
  113. package/dist/http/api.module.js +2 -0
  114. package/dist/inbox/inbox.service.d.ts +6 -20
  115. package/dist/inbox/inbox.service.js +0 -3
  116. package/dist/inbox/org-notices.d.ts +1 -1
  117. package/dist/inbox/platform-inbox.service.d.ts +3 -32
  118. package/dist/inbox/platform-inbox.service.js +5 -54
  119. package/dist/index.d.ts +1 -0
  120. package/dist/index.js +1 -0
  121. package/dist/infra/cli/kernel-cli.module.js +5 -0
  122. package/dist/infra/events/kernel-events.d.ts +9 -35
  123. package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
  124. package/dist/infra/outbox/outbox-relay.module.js +18 -0
  125. package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
  126. package/dist/infra/outbox/outbox.dispatcher.js +310 -0
  127. package/dist/infra/outbox/outbox.module.d.ts +24 -0
  128. package/dist/infra/outbox/outbox.module.js +50 -0
  129. package/dist/infra/outbox/outbox.relay.d.ts +31 -0
  130. package/dist/infra/outbox/outbox.relay.js +76 -0
  131. package/dist/infra/outbox/outbox.service.d.ts +51 -0
  132. package/dist/infra/outbox/outbox.service.js +131 -0
  133. package/dist/infra/outbox/registry.d.ts +244 -0
  134. package/dist/infra/outbox/registry.js +234 -0
  135. package/dist/infra/queue/queue-names.d.ts +8 -0
  136. package/dist/infra/queue/queue-names.js +17 -0
  137. package/dist/kernel.module.js +3 -0
  138. package/dist/local-devices/device-policy.service.d.ts +4 -0
  139. package/dist/local-devices/device-policy.service.js +61 -3
  140. package/dist/local-devices/machines.d.ts +13 -5
  141. package/dist/local-devices/machines.js +45 -7
  142. package/dist/local-devices/policy-summary.d.ts +44 -1
  143. package/dist/local-devices/policy-summary.js +69 -0
  144. package/dist/models/embeddings.d.ts +9 -9
  145. package/dist/models/embeddings.js +11 -18
  146. package/dist/models/models.module.js +3 -0
  147. package/dist/orgs/directory-sync.js +1 -1
  148. package/dist/orgs/members.service.js +1 -1
  149. package/dist/orgs/offboarding.d.ts +50 -57
  150. package/dist/orgs/offboarding.js +117 -162
  151. package/dist/orgs/orgs.module.js +3 -0
  152. package/dist/orgs/orgs.service.d.ts +11 -5
  153. package/dist/orgs/orgs.service.js +22 -6
  154. package/dist/overrides.d.ts +23 -3
  155. package/dist/overrides.js +12 -2
  156. package/dist/platform/exclusions.js +5 -0
  157. package/dist/platform/ops/admin.ops.js +18 -2
  158. package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
  159. package/dist/platform/ops/catalog-admin.ops.js +32 -4
  160. package/dist/platform/ops/inbox.ops.js +4 -20
  161. package/dist/platform/ops/outbox.ops.d.ts +21 -0
  162. package/dist/platform/ops/outbox.ops.js +125 -0
  163. package/dist/platform/ops/platform.ops.d.ts +1 -0
  164. package/dist/platform/ops/platform.ops.js +6 -3
  165. package/dist/platform/ops/schedules.ops.js +40 -1
  166. package/dist/platform/platform-ops.module.d.ts +2 -1
  167. package/dist/platform/platform-ops.module.js +3 -0
  168. package/dist/platform/route-schemas.js +3 -0
  169. package/dist/roles/worker-role.d.ts +10 -5
  170. package/dist/roles/worker-role.js +19 -9
  171. package/dist/roles/worker.module.js +11 -8
  172. package/dist/runtime/context/build.d.ts +3 -0
  173. package/dist/runtime/context/build.js +15 -0
  174. package/dist/runtime/context/plugin-context.d.ts +20 -0
  175. package/dist/runtime/context/plugin-context.js +30 -0
  176. package/dist/runtime/langgraph-loop.js +17 -5
  177. package/dist/runtime/limits.d.ts +15 -0
  178. package/dist/runtime/limits.js +25 -0
  179. package/dist/runtime/loop.d.ts +16 -3
  180. package/dist/runtime/loop.js +2 -1
  181. package/dist/runtime/maintenance.d.ts +7 -3
  182. package/dist/runtime/maintenance.js +52 -12
  183. package/dist/runtime/model-call.d.ts +20 -17
  184. package/dist/runtime/model-call.js +15 -24
  185. package/dist/runtime/plugin-context.service.d.ts +69 -0
  186. package/dist/runtime/plugin-context.service.js +208 -0
  187. package/dist/runtime/queue-lost-jobs.d.ts +24 -0
  188. package/dist/runtime/queue-lost-jobs.js +51 -0
  189. package/dist/runtime/run-control.d.ts +47 -5
  190. package/dist/runtime/run-control.js +79 -12
  191. package/dist/runtime/run-finish.d.ts +39 -12
  192. package/dist/runtime/run-finish.js +97 -14
  193. package/dist/runtime/run-jobs.d.ts +95 -13
  194. package/dist/runtime/run-jobs.js +199 -28
  195. package/dist/runtime/run-orphan-check.job.d.ts +142 -0
  196. package/dist/runtime/run-orphan-check.job.js +339 -0
  197. package/dist/runtime/run-processors.d.ts +16 -9
  198. package/dist/runtime/run-processors.js +1 -1
  199. package/dist/runtime/run-queue.d.ts +75 -53
  200. package/dist/runtime/run-queue.js +189 -263
  201. package/dist/runtime/run-steps.d.ts +1 -2
  202. package/dist/runtime/run-steps.js +8 -11
  203. package/dist/runtime/run-worker.d.ts +26 -16
  204. package/dist/runtime/run-worker.js +132 -37
  205. package/dist/runtime/runtime.module.d.ts +2 -3
  206. package/dist/runtime/runtime.module.js +7 -6
  207. package/dist/runtime/step-log.d.ts +16 -4
  208. package/dist/runtime/step-log.js +26 -6
  209. package/dist/runtime/stream.controller.d.ts +2 -4
  210. package/dist/runtime/stream.controller.js +5 -11
  211. package/dist/runtime/subagents/child.js +1 -1
  212. package/dist/runtime/subagents/definition.d.ts +2 -1
  213. package/dist/runtime/subagents/definition.js +4 -2
  214. package/dist/runtime/subagents/deliveries.d.ts +6 -3
  215. package/dist/runtime/subagents/deliveries.js +16 -7
  216. package/dist/runtime/subagents/dispatch.d.ts +12 -12
  217. package/dist/runtime/subagents/dispatch.js +14 -38
  218. package/dist/runtime/subagents/messages.d.ts +5 -1
  219. package/dist/runtime/subagents/messages.js +11 -3
  220. package/dist/runtime/subagents/skill-fork.d.ts +3 -3
  221. package/dist/runtime/subagents/skill-fork.js +8 -5
  222. package/dist/runtime/subagents/subagents.service.js +1 -1
  223. package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
  224. package/dist/runtime/subagents/tree-jobs.js +86 -0
  225. package/dist/runtime/usage-report-jobs.d.ts +23 -48
  226. package/dist/runtime/usage-report-jobs.js +67 -119
  227. package/dist/runtime/usage-report.d.ts +28 -77
  228. package/dist/runtime/usage-report.js +35 -213
  229. package/dist/runtime/waits.d.ts +48 -198
  230. package/dist/runtime/waits.js +103 -805
  231. package/dist/sandbox/jobs.d.ts +20 -10
  232. package/dist/sandbox/jobs.js +23 -17
  233. package/dist/sandbox/sandbox.service.d.ts +17 -4
  234. package/dist/sandbox/sandbox.service.js +55 -14
  235. package/dist/schedules/calendar.d.ts +134 -0
  236. package/dist/schedules/calendar.js +410 -0
  237. package/dist/schedules/fire.d.ts +26 -7
  238. package/dist/schedules/fire.js +91 -22
  239. package/dist/schedules/job-ids.d.ts +66 -17
  240. package/dist/schedules/job-ids.js +81 -13
  241. package/dist/schedules/run-tracker.d.ts +0 -5
  242. package/dist/schedules/run-tracker.js +2 -14
  243. package/dist/schedules/scan.job.d.ts +13 -32
  244. package/dist/schedules/scan.job.js +50 -164
  245. package/dist/schedules/schedule-math.d.ts +42 -0
  246. package/dist/schedules/schedule-math.js +52 -0
  247. package/dist/schedules/scheduled-tasks.service.d.ts +22 -6
  248. package/dist/schedules/scheduled-tasks.service.js +70 -14
  249. package/dist/schedules/schedules.controller.d.ts +5 -1
  250. package/dist/schedules/schedules.controller.js +15 -1
  251. package/dist/schedules/schedules.module.js +0 -4
  252. package/dist/schedules/schedules.schemas.d.ts +35 -0
  253. package/dist/schedules/schedules.schemas.js +27 -0
  254. package/dist/schedules/store.d.ts +5 -0
  255. package/dist/schedules/store.js +20 -0
  256. package/dist/skills/changes.controller.d.ts +1 -1
  257. package/dist/skills/changes.controller.js +1 -1
  258. package/dist/tools/approvals.service.d.ts +41 -11
  259. package/dist/tools/approvals.service.js +108 -14
  260. package/dist/tools/builtin-names.d.ts +5 -3
  261. package/dist/tools/builtin-names.js +12 -4
  262. package/dist/tools/builtins/builtin-tools.d.ts +1 -2
  263. package/dist/tools/builtins/builtin-tools.js +21 -17
  264. package/dist/tools/builtins/sandbox/bash.js +9 -3
  265. package/dist/tools/builtins/sandbox/common.d.ts +18 -1
  266. package/dist/tools/builtins/sandbox/common.js +14 -1
  267. package/dist/tools/builtins/sandbox/index.d.ts +2 -1
  268. package/dist/tools/builtins/sandbox/index.js +4 -1
  269. package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
  270. package/dist/tools/builtins/sandbox/task-list.js +130 -0
  271. package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
  272. package/dist/tools/builtins/sandbox/task-output.js +21 -3
  273. package/dist/tools/builtins/web/extract.d.ts +2 -4
  274. package/dist/tools/builtins/web/extract.js +2 -5
  275. package/dist/tools/pipeline.d.ts +12 -3
  276. package/dist/tools/pipeline.js +6 -1
  277. package/dist/tools/questions.service.d.ts +30 -10
  278. package/dist/tools/questions.service.js +41 -27
  279. package/dist/tools/registry.d.ts +12 -3
  280. package/dist/tools/registry.js +13 -3
  281. package/dist/tools/tools.module.js +4 -3
  282. package/package.json +3 -3
  283. package/src/migrations/0118_device_policy_ops.sql +6 -0
  284. package/src/migrations/0119_outbox.sql +22 -0
  285. package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
  286. package/src/migrations/0121_drop_platform_migration_runs.sql +12 -0
  287. package/src/migrations/0122_drop_scheduled_task_runs_rechecked_at.sql +5 -0
  288. package/src/migrations/0123_pgvector.sql +27 -0
  289. package/src/migrations/0124_conversation_source.sql +36 -0
  290. package/dist/catalog/platform-migration.d.ts +0 -115
  291. package/dist/catalog/platform-migration.js +0 -583
  292. package/dist/infra/queue/add-job-once.d.ts +0 -14
  293. package/dist/infra/queue/add-job-once.js +0 -16
@@ -178,14 +178,14 @@ export type UpdateTarget = VersionRow;
178
178
  * the extension first (`ExtensionAdminOps.install`, enabled when the update installs it; added
179
179
  * permissions wait for the admin's approval as for any extension upgrade), then one transaction
180
180
  * under the item name's lock that recomputes the diff (`plugin.upgrade_stale` on a difference)
181
- * and writes the platform versions (`PlatformComponents.syncFromVersion`, which records
181
+ * and writes the platform versions (`PlatformComponents.applySyncIn`, which records
182
182
  * `platform_synced_version`), the removals (a component no agent uses is soft-deleted, so
183
183
  * unpinned linked copies go with it; pinned copies keep their own version; a removed connector
184
184
  * template leaves its connectors as the orgs' own), clears the pins of linked copies, fans
185
185
  * changed templates out to every connector made from them (`applyTemplateIn`, under each org's
186
186
  * row lock, credentials cleared only for a changed credential shape), moves every org install to the version and audits
187
- * `plugin.platform_updated`; the scope sync of the item and its dependencies is enqueued after
188
- * the commit (orgs get new dependencies by rule 9). A failure rolls the transaction back and
187
+ * `plugin.platform_updated`; the scope sync of the item and its dependencies is owed in that
188
+ * transaction (orgs get new dependencies by rule 9). A failure rolls the transaction back and
189
189
  * puts the extension back where it was (audit `plugin.platform_update_failed`, 502
190
190
  * `plugin.upgrade_failed`); files copied to `deployment/platform/` stay unreferenced.
191
191
  * Storage is never read or written inside the transaction: the target's contents (and the
@@ -230,6 +230,13 @@ export declare class PlatformPluginUpdater {
230
230
  private get db();
231
231
  /** The update preview (see the class comment); writes nothing. */
232
232
  preview(itemId: string, version: string): Promise<PlatformUpdatePreview>;
233
+ /**
234
+ * The update preview of a version staged for import, not imported yet (the platform's import and
235
+ * update, `PlatformImportUpdate`): the same diff as {@link preview}, with the target read from the
236
+ * staging (`target`, whose files are where the import's version row will point), so the
237
+ * `diffHash` is the one {@link updateHeld} recomputes after the import. Writes nothing.
238
+ */
239
+ previewStaged(itemId: string, version: string, target: UpdateTarget): Promise<PlatformUpdatePreview>;
233
240
  /** The preview of a diff with the template guides it changes. */
234
241
  private withGuideChanges;
235
242
  /**
@@ -292,6 +299,17 @@ export declare class PlatformPluginUpdater {
292
299
  * upload runs every step under it (ruling P3-35).
293
300
  */
294
301
  withItemLock<T>(itemId: string, f: () => Promise<T>): Promise<T>;
302
+ /**
303
+ * {@link update} for a caller already holding the item's update lock ({@link withItemLock}):
304
+ * the platform's import and update runs its import and this update under one hold.
305
+ */
306
+ updateHeld(actor: string, itemId: string, input: {
307
+ version: string;
308
+ diffHash: string;
309
+ }, opts?: {
310
+ actorTokenId?: string;
311
+ auditDetail?: Record<string, unknown>;
312
+ }): Promise<PlatformUpdateResult>;
295
313
  /**
296
314
  * Runs an update confirmed with the preview's `diffHash` (see the class comment). A version an
297
315
  * org upload waits with, or an item whose first version waits, -> 409 `catalog.item_pending`
@@ -345,7 +363,7 @@ export declare class PlatformPluginUpdater {
345
363
  /**
346
364
  * Other platform plugins depending on this one must accept the target (their platform version's
347
365
  * dependency range); returns the catalog items of the target's own dependencies (their scope
348
- * sync is enqueued after the update: rule 9).
366
+ * sync is owed with the update: rule 9).
349
367
  */
350
368
  private checkDependents;
351
369
  /** The plugin's live platform components with their current versions. */
@@ -26,7 +26,6 @@ import { audit } from "../identity/audit.js";
26
26
  import { SuperAdminLock } from "../identity/super-admin.js";
27
27
  import { addOrgNotice, itemDisplayName, notifySharedUpdate } from "../inbox/org-notices.js";
28
28
  import { KernelConfigService } from "../infra/config/kernel-config.service.js";
29
- import { afterCommit } from "../infra/database/after-commit.js";
30
29
  import { KernelDb } from "../infra/database/kernel-db.js";
31
30
  import { TransactionHost } from "../infra/database/transaction-host.js";
32
31
  import { Transactional } from "../infra/database/transactional.decorator.js";
@@ -105,14 +104,14 @@ const filesDigest = (row) => skillFilesDigest(row.files.map((f) => ({ path: f.pa
105
104
  * the extension first (`ExtensionAdminOps.install`, enabled when the update installs it; added
106
105
  * permissions wait for the admin's approval as for any extension upgrade), then one transaction
107
106
  * under the item name's lock that recomputes the diff (`plugin.upgrade_stale` on a difference)
108
- * and writes the platform versions (`PlatformComponents.syncFromVersion`, which records
107
+ * and writes the platform versions (`PlatformComponents.applySyncIn`, which records
109
108
  * `platform_synced_version`), the removals (a component no agent uses is soft-deleted, so
110
109
  * unpinned linked copies go with it; pinned copies keep their own version; a removed connector
111
110
  * template leaves its connectors as the orgs' own), clears the pins of linked copies, fans
112
111
  * changed templates out to every connector made from them (`applyTemplateIn`, under each org's
113
112
  * row lock, credentials cleared only for a changed credential shape), moves every org install to the version and audits
114
- * `plugin.platform_updated`; the scope sync of the item and its dependencies is enqueued after
115
- * the commit (orgs get new dependencies by rule 9). A failure rolls the transaction back and
113
+ * `plugin.platform_updated`; the scope sync of the item and its dependencies is owed in that
114
+ * transaction (orgs get new dependencies by rule 9). A failure rolls the transaction back and
116
115
  * puts the extension back where it was (audit `plugin.platform_update_failed`, 502
117
116
  * `plugin.upgrade_failed`); files copied to `deployment/platform/` stay unreferenced.
118
117
  * Storage is never read or written inside the transaction: the target's contents (and the
@@ -176,6 +175,18 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
176
175
  async preview(itemId, version) {
177
176
  return this.withGuideChanges(await this.diff(itemId, version));
178
177
  }
178
+ /**
179
+ * The update preview of a version staged for import, not imported yet (the platform's import and
180
+ * update, `PlatformImportUpdate`): the same diff as {@link preview}, with the target read from the
181
+ * staging (`target`, whose files are where the import's version row will point), so the
182
+ * `diffHash` is the one {@link updateHeld} recomputes after the import. Writes nothing.
183
+ */
184
+ async previewStaged(itemId, version, target) {
185
+ if (target.version !== version) {
186
+ throw new Error(`internal: previewStaged got the staged target of version ${target.version} for version ${version}`);
187
+ }
188
+ return this.withGuideChanges(await this.diff(itemId, version, { target }));
189
+ }
179
190
  /** The preview of a diff with the template guides it changes. */
180
191
  async withGuideChanges(d) {
181
192
  return {
@@ -335,6 +346,13 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
335
346
  throw itemNotFound();
336
347
  return this.locked(itemId, f);
337
348
  }
349
+ /**
350
+ * {@link update} for a caller already holding the item's update lock ({@link withItemLock}):
351
+ * the platform's import and update runs its import and this update under one hold.
352
+ */
353
+ async updateHeld(actor, itemId, input, opts = {}) {
354
+ return this.updateLocked(actor, itemId, input, opts);
355
+ }
338
356
  /**
339
357
  * Runs an update confirmed with the preview's `diffHash` (see the class comment). A version an
340
358
  * org upload waits with, or an item whose first version waits, -> 409 `catalog.item_pending`
@@ -650,20 +668,9 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
650
668
  ...opts.auditDetail,
651
669
  },
652
670
  });
653
- const enqueue = [itemId, ...diff.dependencies];
654
- afterCommit(async () => {
655
- for (const id of enqueue) {
656
- try {
657
- await this.sync.enqueueItem(id);
658
- }
659
- catch (err) {
660
- this.log.warn("enqueueing the scope sync after a platform update failed", {
661
- itemId: id,
662
- err,
663
- });
664
- }
665
- }
666
- });
671
+ // The scope sync of the item and its dependencies is owed with the update (outbox spec §8.1)
672
+ for (const id of [itemId, ...diff.dependencies])
673
+ await this.sync.enqueueItem(id);
667
674
  return diff;
668
675
  }
669
676
  /**
@@ -1321,7 +1328,7 @@ let PlatformPluginUpdater = class PlatformPluginUpdater {
1321
1328
  /**
1322
1329
  * Other platform plugins depending on this one must accept the target (their platform version's
1323
1330
  * dependency range); returns the catalog items of the target's own dependencies (their scope
1324
- * sync is enqueued after the update: rule 9).
1331
+ * sync is owed with the update: rule 9).
1325
1332
  */
1326
1333
  async checkDependents(name, to) {
1327
1334
  const rows = await this.db
@@ -0,0 +1,59 @@
1
+ import type { KernelSchemaDb } from "../db/kernel-schema.js";
2
+ import type { OutboxService } from "../infra/outbox/outbox.service.js";
3
+ /**
4
+ * The plugin scope sync's jobs as the outbox owes them (transactional outbox spec §8.1): a leaf
5
+ * module (type imports only), so the import confirm (`PluginImport`, below the scope service) and
6
+ * the CLI owe them without the sync. `scope-sync.ts` (the consumer side) re-exports these names.
7
+ */
8
+ /** The scope sync queue (no `:` in the name). */
9
+ export declare const PLUGIN_SCOPE_QUEUE = "cap-kernel-plugin-scope";
10
+ /** The job converging one item in every org. */
11
+ export declare const SCOPE_ITEM_JOB = "scope-item";
12
+ /** The job converging every item in one org. */
13
+ export declare const SCOPE_ORG_JOB = "scope-org";
14
+ /**
15
+ * The delayed backstop of an item job owed by a confirmation's commit (ruling R24): it converges
16
+ * the item as {@link SCOPE_ITEM_JOB} does once the extension is deployed, and fails (BullMQ
17
+ * retries it with its backoff) while the extension is not enabled on the deployment yet.
18
+ */
19
+ export declare const SCOPE_BACKSTOP_JOB = "scope-item-backstop";
20
+ /** How long after the confirmation's commit the backstop runs (the deploy has finished by then). */
21
+ export declare const SCOPE_BACKSTOP_DELAY_MS: number;
22
+ /**
23
+ * Optional provider (a test seam): the backstop's delay (ms) instead of
24
+ * {@link SCOPE_BACKSTOP_DELAY_MS}, so a long test file never has a backstop fire in a later test.
25
+ */
26
+ export declare const SCOPE_BACKSTOP_DELAY: unique symbol;
27
+ /** One item job per scope version (no `:`: item ids are UUIDs). */
28
+ export declare const scopeItemJobId: (itemId: string, version: number) => string;
29
+ /** The backstop of the item job of a scope version (distinct from the immediate one). */
30
+ export declare const scopeBackstopJobId: (itemId: string, version: number) => string;
31
+ /** One org job at a time per org. */
32
+ export declare const scopeOrgJobId: (orgId: string) => string;
33
+ /**
34
+ * The delayed retry `n` of an item job whose extension this replica had not loaded yet (ruling
35
+ * P3-38); deterministic, so replicas deferring the same item add it once.
36
+ */
37
+ export declare const scopeRetryJobId: (itemId: string, version: number, n: number) => string;
38
+ /**
39
+ * The job's data. `retry`: the item job's delayed retry number (P3-38). `backstop`: a
40
+ * {@link SCOPE_BACKSTOP_JOB}.
41
+ */
42
+ export type ScopeJob = {
43
+ kind: "item";
44
+ itemId: string;
45
+ retry?: number;
46
+ backstop?: true;
47
+ } | {
48
+ kind: "org";
49
+ orgId: string;
50
+ };
51
+ /**
52
+ * Owes the item's scope sync in the transaction in context, once per scope version (read in that
53
+ * transaction, so after its own bump); `backstop` owes the delayed backstop instead, due
54
+ * `backstopDelayMs` later (default {@link SCOPE_BACKSTOP_DELAY_MS}). A missing item owes nothing.
55
+ */
56
+ export declare function oweScopeItem(outbox: Pick<OutboxService, "add">, db: KernelSchemaDb, itemId: string, opts?: {
57
+ backstop?: boolean;
58
+ backstopDelayMs?: number;
59
+ }): Promise<void>;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The plugin scope sync's jobs as the outbox owes them (transactional outbox spec §8.1): a leaf
3
+ * module (type imports only), so the import confirm (`PluginImport`, below the scope service) and
4
+ * the CLI owe them without the sync. `scope-sync.ts` (the consumer side) re-exports these names.
5
+ */
6
+ /** The scope sync queue (no `:` in the name). */
7
+ export const PLUGIN_SCOPE_QUEUE = "cap-kernel-plugin-scope";
8
+ /** The job converging one item in every org. */
9
+ export const SCOPE_ITEM_JOB = "scope-item";
10
+ /** The job converging every item in one org. */
11
+ export const SCOPE_ORG_JOB = "scope-org";
12
+ /**
13
+ * The delayed backstop of an item job owed by a confirmation's commit (ruling R24): it converges
14
+ * the item as {@link SCOPE_ITEM_JOB} does once the extension is deployed, and fails (BullMQ
15
+ * retries it with its backoff) while the extension is not enabled on the deployment yet.
16
+ */
17
+ export const SCOPE_BACKSTOP_JOB = "scope-item-backstop";
18
+ /** How long after the confirmation's commit the backstop runs (the deploy has finished by then). */
19
+ export const SCOPE_BACKSTOP_DELAY_MS = 5 * 60_000;
20
+ /**
21
+ * Optional provider (a test seam): the backstop's delay (ms) instead of
22
+ * {@link SCOPE_BACKSTOP_DELAY_MS}, so a long test file never has a backstop fire in a later test.
23
+ */
24
+ export const SCOPE_BACKSTOP_DELAY = Symbol("SCOPE_BACKSTOP_DELAY");
25
+ /** One item job per scope version (no `:`: item ids are UUIDs). */
26
+ export const scopeItemJobId = (itemId, version) => `scope-item-${itemId}-${version}`;
27
+ /** The backstop of the item job of a scope version (distinct from the immediate one). */
28
+ export const scopeBackstopJobId = (itemId, version) => `${scopeItemJobId(itemId, version)}-backstop`;
29
+ /** One org job at a time per org. */
30
+ export const scopeOrgJobId = (orgId) => `scope-org-${orgId}`;
31
+ /**
32
+ * The delayed retry `n` of an item job whose extension this replica had not loaded yet (ruling
33
+ * P3-38); deterministic, so replicas deferring the same item add it once.
34
+ */
35
+ export const scopeRetryJobId = (itemId, version, n) => `scope-item-${itemId}-${version}-r${n}`;
36
+ /**
37
+ * Owes the item's scope sync in the transaction in context, once per scope version (read in that
38
+ * transaction, so after its own bump); `backstop` owes the delayed backstop instead, due
39
+ * `backstopDelayMs` later (default {@link SCOPE_BACKSTOP_DELAY_MS}). A missing item owes nothing.
40
+ */
41
+ export async function oweScopeItem(outbox, db, itemId, opts = {}) {
42
+ const row = await db
43
+ .selectFrom("catalog_items")
44
+ .select("scope_version")
45
+ .where("id", "=", itemId)
46
+ .executeTakeFirst();
47
+ if (!row)
48
+ return;
49
+ if (opts.backstop === true) {
50
+ await outbox.add({
51
+ queue: PLUGIN_SCOPE_QUEUE,
52
+ name: SCOPE_BACKSTOP_JOB,
53
+ jobId: scopeBackstopJobId(itemId, row.scope_version),
54
+ data: { kind: "item", itemId, backstop: true },
55
+ runAt: new Date(Date.now() + (opts.backstopDelayMs ?? SCOPE_BACKSTOP_DELAY_MS)),
56
+ });
57
+ return;
58
+ }
59
+ await outbox.add({
60
+ queue: PLUGIN_SCOPE_QUEUE,
61
+ name: SCOPE_ITEM_JOB,
62
+ jobId: scopeItemJobId(itemId, row.scope_version),
63
+ data: { kind: "item", itemId },
64
+ });
65
+ }
@@ -1,3 +1,25 @@
1
+ import { WorkerHost } from "@nestjs/bullmq";
2
+ import type { Job, Worker } from "bullmq";
3
+ import type { KernelLogger } from "../log.js";
4
+ import { PluginScopeSync, type ScopeJob } from "./scope-sync.js";
5
+ /**
6
+ * The consumer of {@link PLUGIN_SCOPE_QUEUE}: {@link PluginScopeSync} runs the `scope-item`,
7
+ * `scope-item-backstop` and `scope-org` jobs the outbox delivers (any other name fails the job; a
8
+ * backstop whose extension is not deployed yet throws, so BullMQ retries it).
9
+ */
10
+ export declare class PluginScopeSyncProcessor extends WorkerHost<Worker<ScopeJob>> {
11
+ private readonly sync;
12
+ private readonly log;
13
+ private readonly stopping;
14
+ constructor(sync: PluginScopeSync, log: Pick<KernelLogger, "error">);
15
+ process(job: Job<ScopeJob>): Promise<void>;
16
+ /** Starts consuming (worker role, after the extensions loaded; built with `autorun: false`). */
17
+ start(): void;
18
+ /** Stops between pairs and closes the worker. */
19
+ close(): Promise<void>;
20
+ failed(job: Job<ScopeJob> | undefined, err: Error): void;
21
+ error(err: Error): void;
22
+ }
1
23
  /**
2
24
  * The plugin scope queue's consumer: {@link PluginScopeSyncProcessor}. Imported only by the worker
3
25
  * role (`WorkerModule`), so other roles get no processor and no BullMQ worker. It never starts by
@@ -4,10 +4,66 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { Module } from "@nestjs/common";
7
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
+ return function (target, key) { decorator(target, key, paramIndex); }
9
+ };
10
+ import { OnWorkerEvent, WorkerHost } from "@nestjs/bullmq";
11
+ import { Inject, Injectable, Module } from "@nestjs/common";
8
12
  import { configuredProcessor } from "../infra/queue/configured-processor.js";
13
+ import { runJob } from "../infra/queue/run-job.js";
14
+ import { KERNEL_LOGGER } from "../infra/tokens.js";
9
15
  import { CatalogModule } from "./catalog.module.js";
10
- import { PLUGIN_SCOPE_CONCURRENCY, PLUGIN_SCOPE_QUEUE, PluginScopeSyncProcessor, } from "./scope-sync.js";
16
+ import { PLUGIN_SCOPE_CONCURRENCY, PLUGIN_SCOPE_QUEUE, PluginScopeSync, SCOPE_BACKSTOP_JOB, SCOPE_ITEM_JOB, SCOPE_ORG_JOB, } from "./scope-sync.js";
17
+ /**
18
+ * The consumer of {@link PLUGIN_SCOPE_QUEUE}: {@link PluginScopeSync} runs the `scope-item`,
19
+ * `scope-item-backstop` and `scope-org` jobs the outbox delivers (any other name fails the job; a
20
+ * backstop whose extension is not deployed yet throws, so BullMQ retries it).
21
+ */
22
+ let PluginScopeSyncProcessor = class PluginScopeSyncProcessor extends WorkerHost {
23
+ sync;
24
+ log;
25
+ stopping = new AbortController();
26
+ constructor(sync, log) {
27
+ super();
28
+ this.sync = sync;
29
+ this.log = log;
30
+ }
31
+ process(job) {
32
+ return runJob(PLUGIN_SCOPE_QUEUE, job, () => {
33
+ if (![SCOPE_ITEM_JOB, SCOPE_BACKSTOP_JOB, SCOPE_ORG_JOB].includes(job.name)) {
34
+ throw new Error(`unknown plugin scope job ${job.name}`);
35
+ }
36
+ return this.sync.process(job.data, this.stopping.signal);
37
+ });
38
+ }
39
+ /** Starts consuming (worker role, after the extensions loaded; built with `autorun: false`). */
40
+ start() {
41
+ void this.worker.run().catch((err) => this.error(err));
42
+ }
43
+ /** Stops between pairs and closes the worker. */
44
+ async close() {
45
+ this.stopping.abort();
46
+ await this.worker.close();
47
+ }
48
+ failed(job, err) {
49
+ this.log.error("plugin scope job failed", { name: job?.name, jobId: job?.id, err });
50
+ }
51
+ error(err) {
52
+ this.log.error("plugin scope worker error", { err });
53
+ }
54
+ };
55
+ __decorate([
56
+ OnWorkerEvent("failed")
57
+ ], PluginScopeSyncProcessor.prototype, "failed", null);
58
+ __decorate([
59
+ OnWorkerEvent("error")
60
+ ], PluginScopeSyncProcessor.prototype, "error", null);
61
+ PluginScopeSyncProcessor = __decorate([
62
+ Injectable(),
63
+ __param(0, Inject(PluginScopeSync)),
64
+ __param(1, Inject(KERNEL_LOGGER))
65
+ ], PluginScopeSyncProcessor);
66
+ export { PluginScopeSyncProcessor };
11
67
  /**
12
68
  * The plugin scope queue's consumer: {@link PluginScopeSyncProcessor}. Imported only by the worker
13
69
  * role (`WorkerModule`), so other roles get no processor and no BullMQ worker. It never starts by
@@ -1,13 +1,12 @@
1
- import { WorkerHost } from "@nestjs/bullmq";
2
- import type { Job, Queue, Worker } from "bullmq";
3
1
  import { ExtensionLifecycle } from "../extensions/lifecycle.js";
4
2
  import { ExtensionRegistry } from "../extensions/registry.js";
5
3
  import { KernelDb } from "../infra/database/kernel-db.js";
6
4
  import { TransactionHost } from "../infra/database/transaction-host.js";
7
5
  import { LockService } from "../infra/lock/lock.service.js";
8
- import type { OneJob } from "../infra/queue/add-job-once.js";
6
+ import { OutboxService } from "../infra/outbox/outbox.service.js";
9
7
  import type { KernelLogger } from "../log.js";
10
8
  import { PluginInstaller } from "./plugin-install.js";
9
+ import { type ScopeJob } from "./scope-jobs.js";
11
10
  /**
12
11
  * The plugin scope sync (plugin and component management spec §5, phase 1): converges every org
13
12
  * to each platform plugin's scope. In phase 1 "on in an org" is the org's plugin install, so for
@@ -30,55 +29,29 @@ import { PluginInstaller } from "./plugin-install.js";
30
29
  * super admin's inbox, until a later sync of the pair does not fail) and not retried until the next
31
30
  * enqueue. An error outside those steps (a read, the failure write itself) ends the attempt without
32
31
  * touching the pair's row, so an older failure stays open.
33
- * Every worker start enqueues every live item once ({@link PluginScopeSync.enqueueAll}), which
34
- * also catches a lost enqueue.
35
32
  *
36
33
  * Jobs (queue {@link PLUGIN_SCOPE_QUEUE}): one per item and scope version
37
34
  * (`scope-item-<itemId>-<scope_version>`, every org), one per org (`scope-org-<orgId>`, every item,
38
- * enqueued after the org is created). Both are removed when done, so the next enqueue with the same
35
+ * owed by the org's creation). Both are owed in the outbox by the transaction that changes what
36
+ * they converge to (transactional outbox spec §8.1), so none is lost; a migration that changes a
37
+ * scope inserts its outbox rows itself. A confirmation (import, permissions, org upload) owes the
38
+ * immediate item job after its deploy and, in its commit, a backstop `scope-item-backstop` due
39
+ * five minutes later (ruling R24) that waits, retrying, for the extension to be enabled. Both are removed when done, so the next add with the same
39
40
  * id is not swallowed. Pairs of one org are serialized across replicas by a Redis lock per org; the
40
41
  * installer's org row lock and its one-live-install rule are the backstop.
41
42
  */
42
- /** The scope sync queue (no `:` in the name). */
43
- export declare const PLUGIN_SCOPE_QUEUE = "cap-kernel-plugin-scope";
44
- /** The job converging one item in every org. */
45
- export declare const SCOPE_ITEM_JOB = "scope-item";
46
- /** The job converging every item in one org. */
47
- export declare const SCOPE_ORG_JOB = "scope-org";
48
- /** One item job per scope version (no `:`: item ids are UUIDs). */
49
- export declare const scopeItemJobId: (itemId: string, version: number) => string;
50
- /** One org job at a time per org. */
51
- export declare const scopeOrgJobId: (orgId: string) => string;
52
- /**
53
- * The delayed retry `n` of an item job whose extension this replica had not loaded yet (ruling
54
- * P3-38); deterministic, so replicas deferring the same item add it once.
55
- */
56
- export declare const scopeRetryJobId: (itemId: string, version: number, n: number) => string;
43
+ export { PLUGIN_SCOPE_QUEUE, SCOPE_BACKSTOP_DELAY, SCOPE_BACKSTOP_DELAY_MS, SCOPE_BACKSTOP_JOB, SCOPE_ITEM_JOB, SCOPE_ORG_JOB, type ScopeJob, scopeBackstopJobId, scopeItemJobId, scopeOrgJobId, scopeRetryJobId, } from "./scope-jobs.js";
57
44
  /** How many delayed retries an item job gets while its extension is not loaded here (P3-38). */
58
45
  export declare const SCOPE_LOAD_RETRIES = 6;
59
46
  /** The delay of each such retry. */
60
47
  export declare const SCOPE_LOAD_RETRY_DELAY_MS = 5000;
61
48
  /** How long a pair waits for this replica's reconcile before deferring (P3-38). */
62
49
  export declare const SCOPE_RECONCILE_WAIT_MS = 10000;
63
- /**
64
- * The job's data. `retry`: the item job's delayed retry number (P3-38); at
65
- * {@link SCOPE_LOAD_RETRIES} an extension still not loaded is a failure as before.
66
- */
67
- export type ScopeJob = {
68
- kind: "item";
69
- itemId: string;
70
- retry?: number;
71
- } | {
72
- kind: "org";
73
- orgId: string;
74
- };
75
50
  /**
76
51
  * Awaits this replica's extension reconcile for at most `ms` (a slower one carries on in the
77
52
  * background); a failure only warns.
78
53
  */
79
54
  export declare function reconcileWithin(lifecycle: Pick<ExtensionLifecycle, "reconcile">, reason: string, ms: number, log: Pick<KernelLogger, "warn">): Promise<void>;
80
- /** The item job of a scope version (what {@link PluginScopeSync.enqueueItem} adds). */
81
- export declare function scopeItemJob(itemId: string, version: number): OneJob<ScopeJob>;
82
55
  /**
83
56
  * What a sync of one (item, org) did. `deferred`: the plugin's extension is enabled on the
84
57
  * deployment but not loaded on this replica yet (P3-38); the item job retries later.
@@ -88,7 +61,7 @@ export type ScopeSyncResult = "installed" | "removed" | "needs_config" | "unchan
88
61
  export declare const PLUGIN_SCOPE_CONCURRENCY = 2;
89
62
  export declare class PluginScopeSync {
90
63
  private readonly kdb;
91
- private readonly queue;
64
+ private readonly outbox;
92
65
  private readonly installer;
93
66
  private readonly registry;
94
67
  /** This replica's reconcile, awaited (bounded) before deferring an install (P3-38). */
@@ -96,23 +69,44 @@ export declare class PluginScopeSync {
96
69
  private readonly locks;
97
70
  private readonly log;
98
71
  readonly txHost: TransactionHost;
99
- constructor(kdb: KernelDb, queue: Queue<ScopeJob>, installer: PluginInstaller, registry: ExtensionRegistry,
72
+ /** The backstop's delay (a test seam; default {@link SCOPE_BACKSTOP_DELAY_MS}). */
73
+ private readonly backstopDelayMs;
74
+ constructor(kdb: KernelDb, outbox: Pick<OutboxService, "add">, installer: PluginInstaller, registry: ExtensionRegistry,
100
75
  /** This replica's reconcile, awaited (bounded) before deferring an install (P3-38). */
101
- lifecycle: ExtensionLifecycle, locks: LockService, log: KernelLogger, txHost: TransactionHost);
76
+ lifecycle: ExtensionLifecycle, locks: LockService, log: KernelLogger, txHost: TransactionHost,
77
+ /** The backstop's delay (a test seam; default {@link SCOPE_BACKSTOP_DELAY_MS}). */
78
+ backstopDelayMs?: number);
102
79
  private get db();
103
- /** Enqueues the sync of an item in every org, once per scope version. Call after the commit. */
80
+ /**
81
+ * Owes the sync of an item in every org, once per scope version (the version read in the
82
+ * caller's transaction, so after its own bump), in the transaction that changes the scope.
83
+ */
104
84
  enqueueItem(itemId: string): Promise<void>;
105
85
  /**
106
- * Enqueues the sync of every live, not builtin item (a worker start): retries what failed or was
107
- * never enqueued (a lost `afterCommit` enqueue, a migrated scope). The job ids are the items'
108
- * scope versions, so replicas starting together add each one once.
86
+ * Owes the delayed backstop of the item's sync (ruling R24) in the transaction in context: a
87
+ * confirmation owes it before (or with) its deploy, so a crash before its post-deploy add still
88
+ * converges the orgs.
109
89
  */
110
- enqueueAll(): Promise<void>;
111
- /** Enqueues the sync of every item in an org (a new org). Call after the commit. */
90
+ enqueueBackstop(itemId: string): Promise<void>;
91
+ /** Owes the sync of every item in an org, in the transaction that creates the org. */
112
92
  enqueueOrg(orgId: string): Promise<void>;
113
- /** One job: every org of an item, or every item of an org; `signal` stops between pairs. */
93
+ /**
94
+ * One job: every org of an item, or every item of an org; `signal` stops between pairs. A
95
+ * backstop job first checks the item's extension is deployed ({@link assertDeployed}).
96
+ */
114
97
  process(data: ScopeJob, signal?: AbortSignal): Promise<void>;
115
- /** The delayed retry `n` of an item job (deterministic id, P3-38). */
98
+ /**
99
+ * A backstop job (ruling R24) runs only once the item's extension is loaded here or enabled on
100
+ * the deployment; otherwise it throws, so BullMQ retries it with its backoff (bounded by its
101
+ * attempts) and no pair records a `catalog.not_deployed` failure that nothing would retry. An item without an
102
+ * extension, or one no longer live (deleted, disabled, still waiting, builtin), passes: its pairs
103
+ * converge (or change nothing) as for an immediate job.
104
+ */
105
+ private assertDeployed;
106
+ /**
107
+ * Owes the delayed retry `n` of an item job (deterministic id, P3-38) in a transaction of its
108
+ * own: the job's own follow-up, delivered by the relay once due.
109
+ */
116
110
  private enqueueRetry;
117
111
  /**
118
112
  * Whether the install of the item's `version` may go ahead on this replica (P3-38): its
@@ -155,22 +149,3 @@ export declare class PluginScopeSync {
155
149
  private failed;
156
150
  private recordFailure;
157
151
  }
158
- /** The consumer of {@link PLUGIN_SCOPE_QUEUE}: {@link PluginScopeSync}. */
159
- export declare class PluginScopeSyncProcessor extends WorkerHost<Worker<ScopeJob>> {
160
- private readonly sync;
161
- private readonly log;
162
- private readonly stopping;
163
- constructor(sync: PluginScopeSync, log: Pick<KernelLogger, "error">);
164
- process(job: Job<ScopeJob>): Promise<void>;
165
- /** Starts consuming (worker role, after the extensions loaded; built with `autorun: false`). */
166
- start(): void;
167
- /**
168
- * Enqueues every live item's sync once (the worker role, after the start gate opened), in the
169
- * background; a failure is only logged (the next worker start, or the next change, enqueues).
170
- */
171
- resync(): void;
172
- /** Stops between pairs and closes the worker. */
173
- close(): Promise<void>;
174
- failed(job: Job<ScopeJob> | undefined, err: Error): void;
175
- error(err: Error): void;
176
- }