@lostgradient/weft 0.23.1 → 0.24.1

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 (469) hide show
  1. package/README.md +72 -4
  2. package/dist/cli/codegen-emit-dedup.d.ts +81 -0
  3. package/dist/cli/codegen-emit-dedup.js +45 -0
  4. package/dist/cli/codegen-emit-registry.d.ts +90 -0
  5. package/dist/cli/codegen-emit-registry.js +50 -0
  6. package/dist/cli/codegen-emit.d.ts +26 -39
  7. package/dist/cli/codegen-emit.js +4 -27
  8. package/dist/cli/codegen-validate.d.ts +49 -0
  9. package/dist/cli/codegen-validate.js +186 -0
  10. package/dist/cli/codegen.js +6 -87
  11. package/dist/cli/conformance.js +5 -2
  12. package/dist/cli/generated/operation-catalog.snapshot.json +381 -3
  13. package/dist/cli/generated/operation-client.generated.d.ts +350 -10
  14. package/dist/cli/generated/operation-client.generated.js +14 -0
  15. package/dist/cli/output.js +1 -1
  16. package/dist/cli/parse-schedule-arguments.js +15 -3
  17. package/dist/cli/schedule.js +2 -1
  18. package/dist/cli/storage-factory.js +2 -0
  19. package/dist/cli/types.d.ts +2 -1
  20. package/dist/cli/workflow-commands.js +2 -0
  21. package/dist/cli-main.js +1 -1
  22. package/dist/client/http-client-requests.js +6 -9
  23. package/dist/client/start-body.js +1 -0
  24. package/dist/core/application-payload-digest.d.ts +42 -0
  25. package/dist/core/application-payload-digest.js +76 -0
  26. package/dist/core/application-primitive-abort.d.ts +50 -0
  27. package/dist/core/application-primitive-abort.js +40 -0
  28. package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
  29. package/dist/core/application-primitive-attempt-registry.js +73 -0
  30. package/dist/core/application-primitive-codec.d.ts +36 -0
  31. package/dist/core/application-primitive-codec.js +56 -0
  32. package/dist/core/application-primitive-commit.d.ts +67 -0
  33. package/dist/core/application-primitive-commit.js +66 -0
  34. package/dist/core/application-primitive-guards.d.ts +62 -0
  35. package/dist/core/application-primitive-guards.js +89 -0
  36. package/dist/core/application-primitive-payload.d.ts +29 -0
  37. package/dist/core/application-primitive-payload.js +65 -0
  38. package/dist/core/application-primitive-timing.d.ts +18 -0
  39. package/dist/core/application-primitive-timing.js +22 -0
  40. package/dist/core/atomic-state.js +2 -0
  41. package/dist/core/catalog/codec.d.ts +40 -0
  42. package/dist/core/catalog/codec.js +45 -0
  43. package/dist/core/catalog/errors.d.ts +104 -0
  44. package/dist/core/catalog/errors.js +41 -0
  45. package/dist/core/catalog/index.d.ts +25 -0
  46. package/dist/core/catalog/index.js +22 -0
  47. package/dist/core/catalog/reference-counts.d.ts +120 -0
  48. package/dist/core/catalog/reference-counts.js +28 -0
  49. package/dist/core/catalog/removal.d.ts +105 -0
  50. package/dist/core/catalog/removal.js +30 -0
  51. package/dist/core/catalog/storage-io.d.ts +101 -0
  52. package/dist/core/catalog/storage-io.js +106 -0
  53. package/dist/core/catalog/types.d.ts +108 -0
  54. package/dist/core/catalog/types.js +0 -0
  55. package/dist/core/catalog/workflow-catalog.d.ts +165 -0
  56. package/dist/core/catalog/workflow-catalog.js +198 -0
  57. package/dist/core/compare-codepoint.d.ts +13 -0
  58. package/dist/core/compare-codepoint.js +7 -0
  59. package/dist/core/compression.js +2 -0
  60. package/dist/core/context/attributes.d.ts +1 -1
  61. package/dist/core/context/durable-operations.d.ts +2 -2
  62. package/dist/core/context/index.js +5 -3
  63. package/dist/core/context/state-namespace.d.ts +1 -1
  64. package/dist/core/contract/build.d.ts +64 -0
  65. package/dist/core/contract/build.js +99 -0
  66. package/dist/core/contract/compatibility.d.ts +187 -0
  67. package/dist/core/contract/compatibility.js +37 -0
  68. package/dist/core/contract/failure.d.ts +64 -0
  69. package/dist/core/contract/failure.js +4 -0
  70. package/dist/core/contract/hash.d.ts +92 -0
  71. package/dist/core/contract/hash.js +34 -0
  72. package/dist/core/contract/index.d.ts +21 -0
  73. package/dist/core/contract/index.js +22 -0
  74. package/dist/core/contract/limits.d.ts +74 -0
  75. package/dist/core/contract/limits.js +1 -0
  76. package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
  77. package/dist/core/contract/manifest-parse-schema.js +106 -0
  78. package/dist/core/contract/manifest-parse.d.ts +76 -0
  79. package/dist/core/contract/manifest-parse.js +189 -0
  80. package/dist/core/contract/manifest.d.ts +56 -0
  81. package/dist/core/contract/manifest.js +31 -0
  82. package/dist/core/contract/normalize.d.ts +97 -0
  83. package/dist/core/contract/normalize.js +127 -0
  84. package/dist/core/contract/revision.d.ts +29 -0
  85. package/dist/core/contract/revision.js +5 -0
  86. package/dist/core/contract/types.d.ts +274 -0
  87. package/dist/core/contract/types.js +1 -0
  88. package/dist/core/engine/activity-resolution.js +17 -17
  89. package/dist/core/engine/bulk-operations-purge.js +14 -20
  90. package/dist/core/engine/bulk-operations-retry.d.ts +9 -0
  91. package/dist/core/engine/bulk-operations-retry.js +177 -0
  92. package/dist/core/engine/bulk-operations-shared.d.ts +18 -0
  93. package/dist/core/engine/bulk-operations-shared.js +14 -0
  94. package/dist/core/engine/bulk-operations.js +8 -167
  95. package/dist/core/engine/callback-creators-bundles.js +4 -2
  96. package/dist/core/engine/callback-creators-core.js +9 -1
  97. package/dist/core/engine/callback-creators-schedule.js +2 -2
  98. package/dist/core/engine/catalog-activation.d.ts +40 -0
  99. package/dist/core/engine/catalog-activation.js +17 -0
  100. package/dist/core/engine/catalog-events.d.ts +36 -0
  101. package/dist/core/engine/catalog-events.js +15 -0
  102. package/dist/core/engine/catalog-readiness.d.ts +49 -0
  103. package/dist/core/engine/catalog-readiness.js +61 -0
  104. package/dist/core/engine/catalog-removal.d.ts +236 -0
  105. package/dist/core/engine/catalog-removal.js +123 -0
  106. package/dist/core/engine/catalog-tombstone-recovery.d.ts +56 -0
  107. package/dist/core/engine/catalog-tombstone-recovery.js +39 -0
  108. package/dist/core/engine/constraints.js +5 -1
  109. package/dist/core/engine/construction.d.ts +2 -2
  110. package/dist/core/engine/construction.js +4 -2
  111. package/dist/core/engine/decode-revision.d.ts +32 -0
  112. package/dist/core/engine/decode-revision.js +9 -0
  113. package/dist/core/engine/disposal.d.ts +6 -2
  114. package/dist/core/engine/disposal.js +26 -3
  115. package/dist/core/engine/dynamic-source-errors.d.ts +81 -0
  116. package/dist/core/engine/dynamic-source-errors.js +25 -0
  117. package/dist/core/engine/dynamic-source-execution.d.ts +173 -0
  118. package/dist/core/engine/dynamic-source-execution.js +108 -0
  119. package/dist/core/engine/engine-internal-types.d.ts +16 -0
  120. package/dist/core/engine/engine-workflows-namespace.d.ts +140 -0
  121. package/dist/core/engine/engine-workflows-namespace.js +51 -0
  122. package/dist/core/engine/finalizer-metadata.d.ts +22 -0
  123. package/dist/core/engine/finalizer-metadata.js +12 -0
  124. package/dist/core/engine/handle-result.js +2 -0
  125. package/dist/core/engine/index.d.ts +91 -0
  126. package/dist/core/engine/index.js +78 -6
  127. package/dist/core/engine/inline-launch-queue.js +1 -1
  128. package/dist/core/engine/internals.d.ts +54 -15
  129. package/dist/core/engine/internals.js +6 -0
  130. package/dist/core/engine/lifecycle/checkpoint-launch.d.ts +29 -0
  131. package/dist/core/engine/lifecycle/checkpoint-launch.js +75 -0
  132. package/dist/core/engine/lifecycle/delayed-start-registration.d.ts +30 -0
  133. package/dist/core/engine/lifecycle/delayed-start-registration.js +11 -0
  134. package/dist/core/engine/lifecycle/fork-helpers.d.ts +33 -1
  135. package/dist/core/engine/lifecycle/fork-helpers.js +3 -1
  136. package/dist/core/engine/lifecycle/recovery-revision-groups.d.ts +75 -0
  137. package/dist/core/engine/lifecycle/recovery-revision-groups.js +64 -0
  138. package/dist/core/engine/lifecycle/resume-generation-guard.d.ts +58 -0
  139. package/dist/core/engine/lifecycle/resume-generation-guard.js +11 -0
  140. package/dist/core/engine/lifecycle/resume.js +18 -9
  141. package/dist/core/engine/lifecycle/shared.d.ts +43 -0
  142. package/dist/core/engine/lifecycle/standalone-claim-acquire.d.ts +12 -0
  143. package/dist/core/engine/lifecycle/standalone-claim-acquire.js +6 -0
  144. package/dist/core/engine/lifecycle/start-commit-errors.d.ts +12 -0
  145. package/dist/core/engine/lifecycle/start-commit-errors.js +6 -0
  146. package/dist/core/engine/lifecycle/start-commit.d.ts +22 -7
  147. package/dist/core/engine/lifecycle/start-commit.js +49 -15
  148. package/dist/core/engine/lifecycle/start-exec.d.ts +18 -2
  149. package/dist/core/engine/lifecycle/start-exec.js +7 -5
  150. package/dist/core/engine/lifecycle/start-or-signal-create.js +1 -3
  151. package/dist/core/engine/lifecycle/start-or-signal.js +1 -1
  152. package/dist/core/engine/lifecycle/start-precondition-attribution.d.ts +49 -0
  153. package/dist/core/engine/lifecycle/start-precondition-attribution.js +13 -0
  154. package/dist/core/engine/lifecycle/start-revision-resolution.d.ts +34 -0
  155. package/dist/core/engine/lifecycle/start-revision-resolution.js +11 -0
  156. package/dist/core/engine/lifecycle/start-state.d.ts +16 -0
  157. package/dist/core/engine/lifecycle/start-state.js +60 -0
  158. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +66 -3
  159. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +13 -3
  160. package/dist/core/engine/lifecycle/start.d.ts +16 -6
  161. package/dist/core/engine/lifecycle/start.js +39 -66
  162. package/dist/core/engine/lifecycle/transition.d.ts +3 -4
  163. package/dist/core/engine/lifecycle/transition.js +30 -80
  164. package/dist/core/engine/lifecycle.d.ts +4 -2
  165. package/dist/core/engine/lifecycle.js +6 -6
  166. package/dist/core/engine/listing.js +15 -1
  167. package/dist/core/engine/memo-durable-activity.js +4 -1
  168. package/dist/core/engine/nonterminal-revision-count.d.ts +25 -0
  169. package/dist/core/engine/nonterminal-revision-count.js +16 -0
  170. package/dist/core/engine/operations-time.d.ts +5 -23
  171. package/dist/core/engine/operations-time.js +13 -11
  172. package/dist/core/engine/ownership-bootstrap.d.ts +1 -1
  173. package/dist/core/engine/pinned-schedule-revision-count.d.ts +26 -0
  174. package/dist/core/engine/pinned-schedule-revision-count.js +19 -0
  175. package/dist/core/engine/pinned-schedule-revision.d.ts +76 -0
  176. package/dist/core/engine/pinned-schedule-revision.js +53 -0
  177. package/dist/core/engine/registration.d.ts +106 -0
  178. package/dist/core/engine/registration.js +28 -7
  179. package/dist/core/engine/retention.js +9 -2
  180. package/dist/core/engine/revision-errors.d.ts +71 -0
  181. package/dist/core/engine/revision-errors.js +13 -0
  182. package/dist/core/engine/schedule-revision-fire.d.ts +17 -0
  183. package/dist/core/engine/schedule-revision-fire.js +3 -0
  184. package/dist/core/engine/schedule-run.js +2 -1
  185. package/dist/core/engine/schedules.d.ts +2 -1
  186. package/dist/core/engine/schedules.js +28 -9
  187. package/dist/core/engine/source-diagnostics.d.ts +76 -0
  188. package/dist/core/engine/source-diagnostics.js +105 -0
  189. package/dist/core/engine/source-registration.d.ts +42 -0
  190. package/dist/core/engine/source-registration.js +38 -0
  191. package/dist/core/engine/source-resolution.d.ts +101 -0
  192. package/dist/core/engine/source-resolution.js +154 -0
  193. package/dist/core/engine/source-runtime-state.d.ts +92 -0
  194. package/dist/core/engine/source-runtime-state.js +36 -0
  195. package/dist/core/engine/storage-io.d.ts +19 -2
  196. package/dist/core/engine/storage-io.js +21 -2
  197. package/dist/core/engine/termination/finalizer-registration.d.ts +18 -0
  198. package/dist/core/engine/termination/finalizer-registration.js +21 -0
  199. package/dist/core/engine/termination/finalizer.d.ts +16 -19
  200. package/dist/core/engine/termination/finalizer.js +3 -3
  201. package/dist/core/engine/time-operation-callbacks.d.ts +32 -0
  202. package/dist/core/engine/time-operation-callbacks.js +0 -0
  203. package/dist/core/engine/validation/schedule-cadence.d.ts +16 -0
  204. package/dist/core/engine/validation/schedule-cadence.js +20 -0
  205. package/dist/core/engine/validation/schedule-options.d.ts +4 -1
  206. package/dist/core/engine/validation/schedule-options.js +14 -0
  207. package/dist/core/engine/validation/schedule-revision.d.ts +24 -0
  208. package/dist/core/engine/validation/schedule-revision.js +21 -0
  209. package/dist/core/engine/validation/schedule-warnings.d.ts +11 -0
  210. package/dist/core/engine/validation/schedule-warnings.js +5 -0
  211. package/dist/core/engine/validation/schedule.d.ts +4 -3
  212. package/dist/core/engine/validation/schedule.js +15 -26
  213. package/dist/core/engine/validation.js +5 -2
  214. package/dist/core/engine/workflow-claim-reclaim-target.d.ts +1 -1
  215. package/dist/core/engine/workflow-claim-reclaim-target.js +16 -2
  216. package/dist/core/engine/workflow-retention-deadline.d.ts +16 -0
  217. package/dist/core/engine/workflow-retention-deadline.js +33 -0
  218. package/dist/core/events/catalog-events.d.ts +117 -0
  219. package/dist/core/events/catalog-events.js +62 -0
  220. package/dist/core/events/event-map.d.ts +11 -0
  221. package/dist/core/events/index.d.ts +2 -0
  222. package/dist/core/events/index.js +2 -0
  223. package/dist/core/events/workflow-source-events.d.ts +102 -0
  224. package/dist/core/events/workflow-source-events.js +57 -0
  225. package/dist/core/execution-strategy.d.ts +7 -0
  226. package/dist/core/inline-execution-strategy.context-options.d.ts +1 -1
  227. package/dist/core/inline-execution-strategy.js +1 -1
  228. package/dist/core/mailbox-admission.d.ts +26 -0
  229. package/dist/core/mailbox-admission.js +130 -0
  230. package/dist/core/mailbox-claims.d.ts +251 -0
  231. package/dist/core/mailbox-claims.js +0 -0
  232. package/dist/core/mailbox-codec.d.ts +32 -0
  233. package/dist/core/mailbox-codec.js +221 -0
  234. package/dist/core/mailbox-contract.d.ts +290 -0
  235. package/dist/core/mailbox-contract.js +0 -0
  236. package/dist/core/mailbox-delivery.d.ts +37 -0
  237. package/dist/core/mailbox-delivery.js +193 -0
  238. package/dist/core/mailbox-guards.d.ts +78 -0
  239. package/dist/core/mailbox-guards.js +58 -0
  240. package/dist/core/mailbox-index-codec.d.ts +41 -0
  241. package/dist/core/mailbox-index-codec.js +71 -0
  242. package/dist/core/mailbox-internals.d.ts +156 -0
  243. package/dist/core/mailbox-internals.js +154 -0
  244. package/dist/core/mailbox-maintenance.d.ts +29 -0
  245. package/dist/core/mailbox-maintenance.js +196 -0
  246. package/dist/core/mailbox-settlement.d.ts +69 -0
  247. package/dist/core/mailbox-settlement.js +206 -0
  248. package/dist/core/mailbox-storage.d.ts +117 -0
  249. package/dist/core/mailbox-storage.js +115 -0
  250. package/dist/core/mailbox-transition-helpers.d.ts +70 -0
  251. package/dist/core/mailbox-transition-helpers.js +43 -0
  252. package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
  253. package/dist/core/mailbox-transitions-recovery.js +64 -0
  254. package/dist/core/mailbox-transitions.d.ts +138 -0
  255. package/dist/core/mailbox-transitions.js +180 -0
  256. package/dist/core/mailbox-types.d.ts +406 -0
  257. package/dist/core/mailbox-types.js +16 -0
  258. package/dist/core/mailbox-validation.d.ts +65 -0
  259. package/dist/core/mailbox-validation.js +73 -0
  260. package/dist/core/mailbox-waits.d.ts +50 -0
  261. package/dist/core/mailbox-waits.js +97 -0
  262. package/dist/core/mailbox.d.ts +163 -0
  263. package/dist/core/mailbox.js +211 -0
  264. package/dist/core/outbox-claims.d.ts +307 -0
  265. package/dist/core/outbox-claims.js +0 -0
  266. package/dist/core/outbox-codec.d.ts +24 -0
  267. package/dist/core/outbox-codec.js +257 -0
  268. package/dist/core/outbox-contract.d.ts +346 -0
  269. package/dist/core/outbox-contract.js +0 -0
  270. package/dist/core/outbox-delivery.d.ts +34 -0
  271. package/dist/core/outbox-delivery.js +149 -0
  272. package/dist/core/outbox-drain.d.ts +29 -0
  273. package/dist/core/outbox-drain.js +158 -0
  274. package/dist/core/outbox-enqueue.d.ts +24 -0
  275. package/dist/core/outbox-enqueue.js +115 -0
  276. package/dist/core/outbox-guards.d.ts +76 -0
  277. package/dist/core/outbox-guards.js +60 -0
  278. package/dist/core/outbox-index-codec.d.ts +33 -0
  279. package/dist/core/outbox-index-codec.js +71 -0
  280. package/dist/core/outbox-internals.d.ts +99 -0
  281. package/dist/core/outbox-internals.js +159 -0
  282. package/dist/core/outbox-listing.d.ts +12 -0
  283. package/dist/core/outbox-listing.js +38 -0
  284. package/dist/core/outbox-maintenance.d.ts +28 -0
  285. package/dist/core/outbox-maintenance.js +191 -0
  286. package/dist/core/outbox-operations.d.ts +18 -0
  287. package/dist/core/outbox-operations.js +46 -0
  288. package/dist/core/outbox-runner.d.ts +30 -0
  289. package/dist/core/outbox-runner.js +217 -0
  290. package/dist/core/outbox-settlement.d.ts +57 -0
  291. package/dist/core/outbox-settlement.js +183 -0
  292. package/dist/core/outbox-storage.d.ts +107 -0
  293. package/dist/core/outbox-storage.js +127 -0
  294. package/dist/core/outbox-transition-helpers.d.ts +83 -0
  295. package/dist/core/outbox-transition-helpers.js +63 -0
  296. package/dist/core/outbox-transitions-recovery.d.ts +30 -0
  297. package/dist/core/outbox-transitions-recovery.js +42 -0
  298. package/dist/core/outbox-transitions.d.ts +145 -0
  299. package/dist/core/outbox-transitions.js +236 -0
  300. package/dist/core/outbox-types.d.ts +400 -0
  301. package/dist/core/outbox-types.js +20 -0
  302. package/dist/core/outbox-validation.d.ts +101 -0
  303. package/dist/core/outbox-validation.js +127 -0
  304. package/dist/core/outbox-waits.d.ts +39 -0
  305. package/dist/core/outbox-waits.js +88 -0
  306. package/dist/core/outbox.d.ts +156 -0
  307. package/dist/core/outbox.js +234 -0
  308. package/dist/core/registry-limits.d.ts +49 -0
  309. package/dist/core/registry-limits.js +10 -0
  310. package/dist/core/registry-schema-conversion.d.ts +20 -0
  311. package/dist/core/registry-schema-conversion.js +22 -0
  312. package/dist/core/registry-snapshot.d.ts +91 -42
  313. package/dist/core/registry-snapshot.js +39 -77
  314. package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
  315. package/dist/core/registry-workflow-contract-draft.js +28 -0
  316. package/dist/core/registry-workflow-manifest.d.ts +122 -0
  317. package/dist/core/registry-workflow-manifest.js +92 -0
  318. package/dist/core/source/errors.d.ts +55 -0
  319. package/dist/core/source/errors.js +13 -0
  320. package/dist/core/source/index.d.ts +19 -0
  321. package/dist/core/source/index.js +4 -0
  322. package/dist/core/source/resolvers.d.ts +45 -0
  323. package/dist/core/source/resolvers.js +9 -0
  324. package/dist/core/source/types.d.ts +211 -0
  325. package/dist/core/source/types.js +0 -0
  326. package/dist/core/source/validate.d.ts +91 -0
  327. package/dist/core/source/validate.js +62 -0
  328. package/dist/core/source/workflow-source.d.ts +43 -0
  329. package/dist/core/source/workflow-source.js +16 -0
  330. package/dist/core/types/checkpoint.d.ts +14 -0
  331. package/dist/core/types/schedules.d.ts +52 -1
  332. package/dist/core/types/state.d.ts +16 -0
  333. package/dist/core/types/workflow-registries.d.ts +7 -0
  334. package/dist/core/types/workflow-registry.d.ts +12 -0
  335. package/dist/core/versioning.js +2 -0
  336. package/dist/core/weft-error.d.ts +1 -1
  337. package/dist/core/weft-error.js +12 -1
  338. package/dist/core/worker-execution-strategy.d.ts +1 -0
  339. package/dist/core/worker-execution-strategy.js +13 -1
  340. package/dist/core/worker-fault-handling.d.ts +10 -0
  341. package/dist/core/worker-fault-handling.js +1 -0
  342. package/dist/core/worker-inbound-message.d.ts +1 -0
  343. package/dist/core/worker-inbound-message.js +1 -0
  344. package/dist/core/worker-protocol-guard.js +4 -0
  345. package/dist/core/worker-protocol.d.ts +7 -0
  346. package/dist/core/worker-protocol.js +2 -1
  347. package/dist/core/worker-turn-watchdog.d.ts +8 -1
  348. package/dist/core/worker-turn-watchdog.js +3 -2
  349. package/dist/diagnostics/format.js +5 -0
  350. package/dist/diagnostics/types.d.ts +24 -0
  351. package/dist/diagnostics/version-check.js +8 -2
  352. package/dist/http.js +2 -2
  353. package/dist/index.d.ts +25 -4
  354. package/dist/index.js +57 -0
  355. package/dist/indexeddb.js +1 -1
  356. package/dist/json-schema.js +3 -3
  357. package/dist/mcp/resources.js +2 -0
  358. package/dist/runtime/portable.d.ts +9 -1
  359. package/dist/server/fault-to-json-rpc.js +4 -1
  360. package/dist/server/handler/auth-context-principal.js +4 -0
  361. package/dist/server/index.d.ts +11 -0
  362. package/dist/server/json-rpc-http.js +2 -0
  363. package/dist/server/json-rpc-websocket.js +6 -4
  364. package/dist/server/operation-catalog/index.d.ts +1 -1
  365. package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
  366. package/dist/server/operation-catalog/types.d.ts +17 -0
  367. package/dist/server/operation-fault.d.ts +5 -0
  368. package/dist/server/operation-fault.js +4 -1
  369. package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
  370. package/dist/server/operations/activate-workflow-revision.js +69 -0
  371. package/dist/server/operations/create-schedule.d.ts +2 -0
  372. package/dist/server/operations/create-schedule.js +10 -6
  373. package/dist/server/operations/fleet-events-subscription.js +1 -1
  374. package/dist/server/operations/fork-workflow.js +1 -1
  375. package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
  376. package/dist/server/operations/get-active-workflow-revision.js +46 -0
  377. package/dist/server/operations/get-catalog-diagnostics.d.ts +113 -0
  378. package/dist/server/operations/get-catalog-diagnostics.js +65 -0
  379. package/dist/server/operations/get-registry.js +17 -4
  380. package/dist/server/operations/get-task-detail-schema.d.ts +8 -0
  381. package/dist/server/operations/get-task-detail-schema.js +1 -0
  382. package/dist/server/operations/get-task-detail.d.ts +8 -0
  383. package/dist/server/operations/get-task-detail.js +1 -0
  384. package/dist/server/operations/get-task-diagnostics.d.ts +4 -4
  385. package/dist/server/operations/get-workflow-revision.d.ts +25 -0
  386. package/dist/server/operations/get-workflow-revision.js +50 -0
  387. package/dist/server/operations/install-workflow-revision.d.ts +27 -0
  388. package/dist/server/operations/install-workflow-revision.js +46 -0
  389. package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
  390. package/dist/server/operations/list-workflow-revisions.js +40 -0
  391. package/dist/server/operations/preload-workflow-revision.d.ts +28 -0
  392. package/dist/server/operations/preload-workflow-revision.js +60 -0
  393. package/dist/server/operations/schedule-faults.d.ts +1 -0
  394. package/dist/server/operations/schedule-faults.js +32 -4
  395. package/dist/server/operations/schedule-rest-body.d.ts +1 -0
  396. package/dist/server/operations/schedule-rest-body.js +2 -1
  397. package/dist/server/operations/start-or-signal-workflow.js +1 -1
  398. package/dist/server/operations/start-workflow.js +1 -1
  399. package/dist/server/operations/static-registrations.js +42 -0
  400. package/dist/server/operations/storage.js +2 -2
  401. package/dist/server/operations/submit-review-decision.js +1 -1
  402. package/dist/server/operations/update-schedule.d.ts +2 -0
  403. package/dist/server/operations/update-schedule.js +4 -2
  404. package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
  405. package/dist/server/operations/workflow-catalog-operation-helpers.js +162 -0
  406. package/dist/server/runtime/task-dispatch-envelope.d.ts +14 -0
  407. package/dist/server/runtime/task-dispatch-envelope.js +32 -0
  408. package/dist/server/runtime/task-dispatch-revision.d.ts +29 -0
  409. package/dist/server/runtime/task-dispatch-revision.js +13 -0
  410. package/dist/server/runtime/task-dispatch.js +12 -37
  411. package/dist/server/runtime/task-ledger-recovery.js +1 -1
  412. package/dist/server/runtime/task-ledger-runtime.d.ts +14 -2
  413. package/dist/server/runtime/task-ledger-runtime.js +5 -3
  414. package/dist/server/runtime/task-polling.js +9 -3
  415. package/dist/server/runtime/task-reconciliation.js +2 -1
  416. package/dist/server/runtime/websocket-upgrade.js +2 -0
  417. package/dist/server/runtime/websocket-worker.js +9 -0
  418. package/dist/server/task-ledger-codec.d.ts +9 -0
  419. package/dist/server/task-ledger-codec.js +4 -1
  420. package/dist/server/task-ledger-transition-helpers.js +1 -0
  421. package/dist/server/task-ledger-types.d.ts +9 -0
  422. package/dist/server/task-ledger.d.ts +1 -1
  423. package/dist/server/task-ledger.js +2 -1
  424. package/dist/server/task-queue-types.d.ts +2 -0
  425. package/dist/storage/bun-sql.js +51 -6
  426. package/dist/storage/catalog-keys.d.ts +64 -0
  427. package/dist/storage/catalog-keys.js +8 -0
  428. package/dist/storage/compressed-storage.js +1 -1
  429. package/dist/storage/derived-operations.js +1 -1
  430. package/dist/storage/index.d.ts +28 -1
  431. package/dist/storage/interface.d.ts +28 -1
  432. package/dist/storage/interface.js +1 -1
  433. package/dist/storage/key-encoding.d.ts +15 -0
  434. package/dist/storage/key-encoding.js +3 -0
  435. package/dist/storage/key-prefixes.d.ts +1 -1
  436. package/dist/storage/key-prefixes.js +16 -0
  437. package/dist/storage/lmdb.d.ts +54 -1
  438. package/dist/storage/lmdb.js +1 -1
  439. package/dist/storage/mailbox-keys.d.ts +80 -0
  440. package/dist/storage/mailbox-keys.js +14 -0
  441. package/dist/storage/memory.js +1 -1
  442. package/dist/storage/neon.js +2 -2
  443. package/dist/storage/node-sqlite-loader.d.ts +1 -1
  444. package/dist/storage/node-sqlite.js +51 -6
  445. package/dist/storage/outbox-keys.d.ts +77 -0
  446. package/dist/storage/outbox-keys.js +14 -0
  447. package/dist/storage/postgres.js +2 -2
  448. package/dist/storage/resolve.js +1 -1
  449. package/dist/storage/scoped-storage.js +1 -1
  450. package/dist/storage/storage-configuration.d.ts +6 -0
  451. package/dist/storage/testing.js +1 -1
  452. package/dist/storage/turso.js +2 -2
  453. package/dist/version.d.ts +1 -1
  454. package/dist/version.js +1 -1
  455. package/dist/web-extension.js +1 -1
  456. package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
  457. package/dist/worker/manifest/registry-contract-builder.js +40 -31
  458. package/dist/worker/protocol-messages.d.ts +17 -0
  459. package/dist/worker/protocol-schemas.d.ts +32 -0
  460. package/dist/worker/protocol-schemas.js +7 -3
  461. package/dist/worker/protocol-task-result.js +35 -3
  462. package/dist/worker/protocol.js +1 -1
  463. package/dist/worker/registry/types.d.ts +2 -0
  464. package/dist/worker/registry.d.ts +1 -1
  465. package/dist/worker/registry.js +3 -1
  466. package/dist/workers/workflow-runner.d.ts +9 -0
  467. package/dist/workers/workflow-runner.js +9 -2
  468. package/dist/workers/workflow-worker-entry.js +9 -4
  469. package/package.json +2 -2
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The validation pipeline that turns a resolved-but-untrusted module value
3
+ * into an installable {@link WorkflowRevisionManifest}, or a bounded,
4
+ * structured rejection. Engine-agnostic and pure(-ish): no `Engine`
5
+ * instance, no storage, no catalog access — every check here operates only
6
+ * on the descriptor and the loaded module value, so it can be unit-tested
7
+ * (`validate.test.ts`) without constructing an engine.
8
+ *
9
+ * @module core/source/validate
10
+ */
11
+ import type { ActivityRegistry } from '../activity-registry.ts';
12
+ import type { WorkflowRevisionManifest } from '../contract/types.ts';
13
+ import type { WorkflowDefinition } from '../types.ts';
14
+ import type { RegisteredWorkflowDefinition } from '../types/workflow-registry.ts';
15
+ import type { WorkflowSourceRejectionReason } from './errors.ts';
16
+ import type { WorkflowSourceDescriptor } from './types.ts';
17
+ /**
18
+ * The outcome of {@link validateResolvedWorkflowSource}: either every check
19
+ * passed and this is an installable revision, or validation failed with the
20
+ * complete, ordered list of every applicable
21
+ * {@link WorkflowSourceRejectionReason} — never just the first one found.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import type { WorkflowSourceValidationOutcome } from './validate.ts';
26
+ *
27
+ * const outcome: WorkflowSourceValidationOutcome = { ok: false, reasons: ['missing-export'] };
28
+ * console.log(outcome.ok);
29
+ * ```
30
+ */
31
+ export type WorkflowSourceValidationOutcome = Readonly<{
32
+ ok: true;
33
+ manifest: WorkflowRevisionManifest;
34
+ definition: RegisteredWorkflowDefinition;
35
+ activityRegistry: ActivityRegistry;
36
+ loadedDefinition: WorkflowDefinition;
37
+ }> | Readonly<{
38
+ ok: false;
39
+ reasons: readonly WorkflowSourceRejectionReason[];
40
+ }>;
41
+ /**
42
+ * Build the synthetic "expected" manifest `checkWorkflowCompatibility`
43
+ * compares `actual` against: `name`/`revision` always overridden to the
44
+ * descriptor's values (the whole point — an actual revision that
45
+ * legitimately differs from what the descriptor expected must be reported
46
+ * as `artifact-revision-mismatch`, never silently accepted), and
47
+ * `workflowVersion`/`contractHash` overridden ONLY when the descriptor pins
48
+ * them, otherwise copied from `actual` so an unpinned field can never
49
+ * produce a false-positive mismatch.
50
+ *
51
+ * Exported (not just used internally by {@link validateResolvedWorkflowSource})
52
+ * so `core/engine/source-resolution.ts`'s catalog fast path can run the
53
+ * identical pin check against an already-cached manifest — a registered
54
+ * handle that pins `workflowVersion`/`contractHash` must reject a cached
55
+ * manifest that contradicts those pins exactly as a fresh load-and-validate
56
+ * would, never silently returning mismatched cached data.
57
+ */
58
+ export declare function buildExpectedManifest(descriptor: WorkflowSourceDescriptor, actual: WorkflowRevisionManifest): WorkflowRevisionManifest;
59
+ /**
60
+ * Validate a resolved-but-untrusted `moduleValue` (the raw value a
61
+ * {@link import('./resolvers.ts').resolveSourceModule} call produced)
62
+ * against `descriptor`'s expectations, in order:
63
+ *
64
+ * 1. `moduleValue` must be a plain record and must own `descriptor.exportName` — else `missing-export`.
65
+ * 2. The export must not itself be an ES module namespace object (an `export * as x` barrel) — else `ambiguous-export`.
66
+ * 3. The export must be a builder-produced `WorkflowDefinition` — else `invalid-definition` (covers the removed bare-handler shape).
67
+ * 4. The export's `name` must pass the wire-safe name grammar — else `invalid-definition`.
68
+ * 5. The export's activities/signals/updates/queries must normalize without error — else `invalid-definition`.
69
+ * 6. A `WorkflowRevisionManifest` must build from the normalized definition without exceeding a WFT-5 hostile-input limit — else `manifest-build-failed`.
70
+ * 7. The built manifest must be compatible with the descriptor's expectations via `checkWorkflowCompatibility` — else the returned `WorkflowCompatibilityReason`s.
71
+ *
72
+ * Every applicable reason at whichever step first fails is returned;
73
+ * later steps never run once an earlier step already failed, since each
74
+ * step's output feeds the next (there is nothing left to check once, say,
75
+ * the export cannot even be found).
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * import type { WorkflowSourceDescriptor } from '@lostgradient/weft';
80
+ *
81
+ * const descriptor: WorkflowSourceDescriptor = {
82
+ * kind: 'module',
83
+ * name: 'checkout',
84
+ * location: './checkout.ts',
85
+ * exportName: 'checkout',
86
+ * revision: 'r1',
87
+ * };
88
+ * console.log(descriptor.exportName);
89
+ * ```
90
+ */
91
+ export declare function validateResolvedWorkflowSource(descriptor: WorkflowSourceDescriptor, moduleValue: unknown): Promise<WorkflowSourceValidationOutcome>;
@@ -0,0 +1,62 @@
1
+ import { isRecord } from "../../worker/manifest/is-record.js";
2
+ import {
3
+ DEFAULT_WORKFLOW_COMPATIBILITY_POLICY,
4
+ checkWorkflowCompatibility
5
+ } from "../contract/compatibility.js";
6
+ import { copyWorkflowDefinition } from "../engine/construction.js";
7
+ import {
8
+ buildPerWorkflowActivityRegistry,
9
+ buildRegistrationEntry,
10
+ isBuilderWorkflowDefinition
11
+ } from "../engine/registration.js";
12
+ import { buildWorkflowManifestFromDefinition } from "../registry-workflow-manifest.js";
13
+ import { validateWorkflowOrActivityName } from "../types/name-grammar.js";
14
+ function readOwnExport(moduleValue, exportName) {
15
+ return Object.hasOwn(moduleValue, exportName) ? moduleValue[exportName] : void 0;
16
+ }
17
+ export function buildExpectedManifest(descriptor, actual) {
18
+ return {
19
+ ...actual,
20
+ name: descriptor.name,
21
+ revision: descriptor.revision,
22
+ ...descriptor.workflowVersion === void 0 ? {} : { workflowVersion: descriptor.workflowVersion },
23
+ ...descriptor.contractHash === void 0 ? {} : { contractHash: descriptor.contractHash }
24
+ };
25
+ }
26
+ export async function validateResolvedWorkflowSource(descriptor, moduleValue) {
27
+ if (!isRecord(moduleValue))
28
+ return { ok: !1, reasons: ["missing-export"] };
29
+ const exportValue = readOwnExport(moduleValue, descriptor.exportName);
30
+ if (exportValue === void 0)
31
+ return { ok: !1, reasons: ["missing-export"] };
32
+ if (Object.prototype.toString.call(exportValue) === "[object Module]")
33
+ return { ok: !1, reasons: ["ambiguous-export"] };
34
+ if (!isBuilderWorkflowDefinition(exportValue))
35
+ return { ok: !1, reasons: ["invalid-definition"] };
36
+ const loadedDefinition = exportValue;
37
+ let entry, activityRegistry;
38
+ try {
39
+ validateWorkflowOrActivityName(loadedDefinition.name, "workflow");
40
+ entry = buildRegistrationEntry(loadedDefinition.name, loadedDefinition);
41
+ activityRegistry = buildPerWorkflowActivityRegistry(exportValue.activities);
42
+ } catch {
43
+ return { ok: !1, reasons: ["invalid-definition"] };
44
+ }
45
+ const registeredDefinition = copyWorkflowDefinition(loadedDefinition.name, entry);
46
+ let actualManifest;
47
+ try {
48
+ actualManifest = await buildWorkflowManifestFromDefinition(registeredDefinition, activityRegistry.listDefinitions());
49
+ } catch {
50
+ return { ok: !1, reasons: ["manifest-build-failed"] };
51
+ }
52
+ const expectedManifest = buildExpectedManifest(descriptor, actualManifest), verdict = checkWorkflowCompatibility(expectedManifest, actualManifest, DEFAULT_WORKFLOW_COMPATIBILITY_POLICY);
53
+ if (!verdict.compatible)
54
+ return { ok: !1, reasons: verdict.reasons };
55
+ return {
56
+ ok: !0,
57
+ manifest: actualManifest,
58
+ definition: registeredDefinition,
59
+ activityRegistry,
60
+ loadedDefinition
61
+ };
62
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * `workflowSource()` — the typed factory pairing a serializable
3
+ * {@link WorkflowSourceDescriptor} with a host-side loader capability.
4
+ *
5
+ * @module core/source/workflow-source
6
+ */
7
+ import type { InputOf, IsAny, ModuleWorkflowDefinition, NameOf, OutputOf, ServicesOf, WorkflowSourceDescriptorInput, WorkflowSourceHandle } from './types.ts';
8
+ /**
9
+ * Build a typed {@link WorkflowSourceHandle} from a `descriptor` and a
10
+ * `loader` capability. The loader is stored on the returned handle
11
+ * unchanged (identity, not wrapped) and is never invoked by this function —
12
+ * `workflowSource()` is pure construction, matching `engine.registerSource()`'s
13
+ * own "records a candidate, never imports" contract one level up.
14
+ *
15
+ * `loader` must be a literal `() => import('./x.ts')` (or an equivalent
16
+ * statically-typed async function) for `TInput`/`TOutput`/`TName`/`TServices`
17
+ * to infer from the module's real export types. A dynamic import
18
+ * (`() => import(pathVariable)`, typed `Promise<any>`) is rejected at the
19
+ * type level via `descriptor`'s `IsAny<TModule> extends true ? never : ...`
20
+ * guard — see `workflow-source.test-d.ts`.
21
+ *
22
+ * `descriptor.location` is carried verbatim into the returned handle and
23
+ * never read, parsed, or concatenated by this function or any other
24
+ * `core/source/**` module — there is no timestamp-query-string or
25
+ * cache-busting mechanism anywhere in this package; single-flight
26
+ * deduplication in `resolveWorkflowSource` is keyed by `(name, revision)`,
27
+ * not by `location`.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { workflowSource } from '@lostgradient/weft';
32
+ *
33
+ * declare const loadCheckout: () => Promise<{
34
+ * checkout: import('@lostgradient/weft').WorkflowDefinition<{ orderId: string }, { shipped: boolean }, 'checkout'>;
35
+ * }>;
36
+ * const source = workflowSource(
37
+ * { name: 'checkout', location: './workflows/checkout.ts', exportName: 'checkout', revision: 'r1' },
38
+ * loadCheckout,
39
+ * );
40
+ * console.log(source.descriptor.kind);
41
+ * ```
42
+ */
43
+ export declare function workflowSource<TModule extends Record<string, unknown>, TExportName extends keyof TModule & string>(descriptor: IsAny<TModule> extends true ? never : WorkflowSourceDescriptorInput<TExportName>, loader: () => Promise<TModule>): WorkflowSourceHandle<InputOf<ModuleWorkflowDefinition<TModule, TExportName>>, OutputOf<ModuleWorkflowDefinition<TModule, TExportName>>, NameOf<ModuleWorkflowDefinition<TModule, TExportName>>, ServicesOf<ModuleWorkflowDefinition<TModule, TExportName>>>;
@@ -0,0 +1,16 @@
1
+ const DEFAULT_WORKFLOW_SOURCE_KIND = "module";
2
+ export function workflowSource(descriptor, loader) {
3
+ const input = descriptor;
4
+ return Object.freeze({
5
+ descriptor: Object.freeze({
6
+ kind: input.kind ?? DEFAULT_WORKFLOW_SOURCE_KIND,
7
+ name: input.name,
8
+ location: input.location,
9
+ exportName: input.exportName,
10
+ revision: input.revision,
11
+ ...input.workflowVersion === void 0 ? {} : { workflowVersion: input.workflowVersion },
12
+ ...input.contractHash === void 0 ? {} : { contractHash: input.contractHash }
13
+ }),
14
+ load: loader
15
+ });
16
+ }
@@ -199,6 +199,14 @@ export type WorkerInboundMessage = {
199
199
  maxProtocolMessageBytes?: number;
200
200
  workflowId: WorkflowId;
201
201
  workflowExecutionToken?: string;
202
+ /**
203
+ * The dispatching run's persisted `WorkflowState.revision` (WFT-20),
204
+ * when known. Captured worker-side and re-stamped on every outbound
205
+ * message for this workflow's remaining turns (including `resume`
206
+ * turns, which never resend this field) — see
207
+ * `workers/workflow-runner.ts`'s `workflowRevisions` map.
208
+ */
209
+ workflowRevision?: string;
202
210
  workflowType: string;
203
211
  checkpoint: ArrayBuffer;
204
212
  input: unknown;
@@ -236,12 +244,16 @@ export type WorkerOutboundMessage = {
236
244
  workflowId: WorkflowId;
237
245
  checkpoint: ArrayBuffer;
238
246
  operationRequest: OperationRequest | ContextOperationRequest;
247
+ /** Echo of the captured `run.workflowRevision` (WFT-20) — see that field's doc. */
248
+ workflowRevision?: string;
239
249
  } | {
240
250
  type: 'completed';
241
251
  protocolVersion?: number;
242
252
  turnId?: number;
243
253
  workflowId: WorkflowId;
244
254
  result: unknown;
255
+ /** Echo of the captured `run.workflowRevision` (WFT-20) — see that field's doc. */
256
+ workflowRevision?: string;
245
257
  } | {
246
258
  type: 'failed';
247
259
  protocolVersion?: number;
@@ -251,6 +263,8 @@ export type WorkerOutboundMessage = {
251
263
  errorStack?: string;
252
264
  /** Populated when the execution strategy can classify the failure cause. */
253
265
  failureCategory?: FailureCategory;
266
+ /** Echo of the captured `run.workflowRevision` (WFT-20) — see that field's doc. */
267
+ workflowRevision?: string;
254
268
  } | {
255
269
  /**
256
270
  * A `ctx.log` record forwarded from a worker to the engine host's
@@ -23,6 +23,27 @@ export type ScheduleStatus = 'active' | 'paused' | 'cancelled';
23
23
  * ```
24
24
  */
25
25
  export type ScheduleOverlapPolicy = 'skip' | 'queue' | 'cancel-running' | 'allow';
26
+ /**
27
+ * Which persisted workflow revision a schedule's future occurrences resolve
28
+ * against (WFT-20). `'active-at-fire'` (the default) resolves whatever
29
+ * revision is currently active at the moment each occurrence fires — this is
30
+ * the schedule's pre-WFT-20 behavior, unchanged. `'pinned'` captures the
31
+ * revision that would run right now at create/update time
32
+ * ({@link ScheduleMetadata.pinnedRevision}) and forces every future
33
+ * occurrence to resolve against exactly that revision, pausing the schedule
34
+ * (see `guides/workflow-versioning.md`'s "Schedule revision policy" section)
35
+ * if that revision later becomes unavailable rather than silently falling
36
+ * back to whatever is active.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import type { ScheduleRevisionPolicy } from '@lostgradient/weft';
41
+ *
42
+ * const policy: ScheduleRevisionPolicy = 'pinned';
43
+ * void policy;
44
+ * ```
45
+ */
46
+ export type ScheduleRevisionPolicy = 'active-at-fire' | 'pinned';
26
47
  /**
27
48
  * One occurrence waiting behind the active run of a `queue` overlap schedule.
28
49
  * `workflowId` is reserved when the occurrence enters the durable queue and is
@@ -117,12 +138,27 @@ export interface ScheduleOptions {
117
138
  * pre-jitter occurrence timestamp.
118
139
  */
119
140
  jitter?: Duration;
141
+ /**
142
+ * Which revision future occurrences resolve against. Defaults to
143
+ * `'active-at-fire'`. Passing `'pinned'` captures the revision that would
144
+ * run right now — see {@link ScheduleRevisionPolicy}. This is a
145
+ * per-schedule revision override; `StartOptions` (a one-shot
146
+ * `engine.start()` call) has no equivalent per-call revision override.
147
+ */
148
+ revisionPolicy?: ScheduleRevisionPolicy;
120
149
  }
121
150
  /**
122
151
  * Mutable options accepted when updating an existing schedule. Omitted fields
123
152
  * retain their persisted values. Schedule identity, workflow type, and input
124
153
  * are intentionally excluded.
125
154
  *
155
+ * Omitting `revisionPolicy` preserves the schedule's current policy AND its
156
+ * captured {@link ScheduleMetadata.pinnedRevision} unchanged. Passing
157
+ * `revisionPolicy: 'pinned'` — even when the schedule is already pinned —
158
+ * always RE-resolves and re-captures the pin against the revision active
159
+ * right now; it is never a no-op. Passing `revisionPolicy: 'active-at-fire'`
160
+ * clears any previously captured pin.
161
+ *
126
162
  * @example
127
163
  * ```ts
128
164
  * import { Engine, workflow, type ScheduleUpdateOptions } from '@lostgradient/weft';
@@ -135,7 +171,7 @@ export interface ScheduleOptions {
135
171
  * engine[Symbol.dispose]();
136
172
  * ```
137
173
  */
138
- export type ScheduleUpdateOptions = Pick<ScheduleOptions, 'description' | 'overlap' | 'backfill' | 'jitter'>;
174
+ export type ScheduleUpdateOptions = Pick<ScheduleOptions, 'description' | 'overlap' | 'backfill' | 'jitter' | 'revisionPolicy'>;
139
175
  /**
140
176
  * Declarative recurring schedule definition returned by {@link schedule}. Supply
141
177
  * exactly one of `cron` (cron cadence) or `every` (fixed interval).
@@ -168,6 +204,7 @@ export type ScheduleDefinition<TInput = unknown> = ScheduleSpec & {
168
204
  overlapPolicy?: ScheduleOverlapPolicy;
169
205
  backfill?: boolean;
170
206
  jitter?: Duration;
207
+ revisionPolicy?: ScheduleRevisionPolicy;
171
208
  };
172
209
  /**
173
210
  * Create a recurring schedule definition for `engine.schedule(definition)`.
@@ -206,6 +243,20 @@ export interface ScheduleMetadata {
206
243
  backfill: boolean;
207
244
  /** Normalized deterministic jitter window in milliseconds. */
208
245
  jitterMs?: number;
246
+ /**
247
+ * Which revision future occurrences resolve against. Required on every
248
+ * record this package writes; a legacy record persisted before WFT-20
249
+ * decodes as `'active-at-fire'` (see `validation/schedule-revision.ts`) —
250
+ * absence never means "unset," it means "pre-pinning."
251
+ */
252
+ revisionPolicy: ScheduleRevisionPolicy;
253
+ /**
254
+ * The exact revision every future occurrence resolves against, captured at
255
+ * the moment this schedule was created or last switched to (or re-pinned
256
+ * under) `revisionPolicy: 'pinned'`. Present only when `revisionPolicy ===
257
+ * 'pinned'`.
258
+ */
259
+ pinnedRevision?: string;
209
260
  createdAt: number;
210
261
  updatedAt: number;
211
262
  /** Most recent occurrence that started a scheduled workflow. */
@@ -53,6 +53,20 @@ export interface WorkflowState {
53
53
  * detect version drift.
54
54
  */
55
55
  versionTuple: WorkflowVersionTuple;
56
+ /**
57
+ * The exact executable artifact this run started against — the revision
58
+ * of the code actually loaded in this process at admission time (an
59
+ * eager registration's `registeredCatalogRevisions` entry, or a dynamic
60
+ * source's resolved candidate revision), NOT the catalog's cached active
61
+ * pointer. Sibling to {@link versionTuple}: `revision` answers "which
62
+ * artifact" for identity, diagnostics, and pinning; `versionTuple` remains
63
+ * the sole semantic-compatibility axis recovery checks. Every fresh start
64
+ * from this release forward sets it; `undefined` only on a record
65
+ * persisted before this field existed (a pre-upgrade run) — recovery
66
+ * treats that absence as a bounded, explicitly-classified legacy case
67
+ * rather than falling back to the currently active revision.
68
+ */
69
+ revision?: string;
56
70
  /**
57
71
  * Durable token identifying this concrete workflow run. It changes when a
58
72
  * stable workflow id is reused with `onTerminalConflict: 'start-new'`, and
@@ -291,6 +305,8 @@ export interface WorkflowSummary {
291
305
  status: WorkflowStatus;
292
306
  tags?: string[];
293
307
  version: string;
308
+ /** The exact executable artifact this run started against. See {@link WorkflowState.revision}. */
309
+ revision?: string;
294
310
  createdAt: number;
295
311
  updatedAt: number;
296
312
  /** Execution deadline (ms epoch) if set on the workflow. */
@@ -5,6 +5,13 @@ import type { StepWorkflowFunction, WorkflowDefinition, WorkflowFunction } from
5
5
  * `input` and `output` fields to make `engine.register`, `engine.start`, and
6
6
  * `WorkflowHandle.result()` type-safe for string workflow names.
7
7
  *
8
+ * `weft codegen`-generated entries additionally carry `revision`/
9
+ * `workflowVersion` string-literal fields for compile-time introspection —
10
+ * see `documentation/reference/cli.md#codegen` for the generated shape.
11
+ * Neither is required here: {@link WorkflowInput}/{@link WorkflowOutput}
12
+ * read only `input`/`output`, so a hand-authored entry (as below) never
13
+ * needs to supply them.
14
+ *
8
15
  * @example
9
16
  * ```ts
10
17
  * import type { WorkflowRegistry } from '@lostgradient/weft';
@@ -38,4 +38,16 @@ export interface RegisteredWorkflowDefinition<TInput = unknown, TOutput = unknow
38
38
  searchAttributes?: SearchAttributeSchema;
39
39
  /** Optional start admission policy for this workflow type. */
40
40
  concurrency?: WorkflowConcurrencyOptions<TInput>;
41
+ /**
42
+ * Schema-only metadata for the workflow's definition-level finalizer
43
+ * activity ({@link WorkflowDefinition.finalizer}), when registered. Carries
44
+ * only `name`/`inputSchema`/`outputSchema` — never the finalizer's
45
+ * `execute` handler — matching this interface's read-only introspection
46
+ * contract (the workflow's own handler is likewise never exposed here).
47
+ */
48
+ finalizer?: Readonly<{
49
+ name: string;
50
+ inputSchema?: DefinitionSchema;
51
+ outputSchema?: DefinitionSchema;
52
+ }>;
41
53
  }
@@ -45,6 +45,8 @@ ${diffs.map((diff) => {
45
45
  return ` - field \`${diff.field}\` was removed (was: ${diff.oldType})`;
46
46
  case "type-changed":
47
47
  return ` - field \`${diff.field}\` changed type: ${diff.oldType} \u2192 ${diff.newType}`;
48
+ default:
49
+ throw Error(`Unknown field diff change: ${JSON.stringify(diff)}`);
48
50
  }
49
51
  }).join(`
50
52
  `)}`;
@@ -25,7 +25,7 @@
25
25
  * }
26
26
  * ```
27
27
  */
28
- export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'EngineDisposalError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'PersistedDataCorruptError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError' | 'WorkerManifestBuildError' | 'OwnershipModeMismatchError';
28
+ export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'EngineDisposalError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'PersistedDataCorruptError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError' | 'WorkerManifestBuildError' | 'OwnershipModeMismatchError' | 'ApplicationCommandValidationError' | 'MailboxContentionError' | 'ApplicationDeliveryValidationError' | 'OutboxContentionError' | 'WaitBudgetElapsedError' | 'WorkflowCatalogConflictError' | 'WorkflowRevisionNotInstalledError' | 'WorkflowSourceValidationError' | 'WorkflowSourceNotRegisteredError' | 'DynamicWorkflowSourceUnavailableError' | 'WorkflowRevisionUnavailableError';
29
29
  /**
30
30
  * Generic abstract base for all Weft library errors. The `TCode` parameter
31
31
  * makes each subclass's `code` its own literal type; the exported base surface
@@ -47,7 +47,18 @@ const publicWeftErrorCodeMap = {
47
47
  WorkflowTeardownPendingError: !0,
48
48
  IdempotencyKeyPurgedError: !0,
49
49
  WorkerManifestBuildError: !0,
50
- OwnershipModeMismatchError: !0
50
+ OwnershipModeMismatchError: !0,
51
+ ApplicationCommandValidationError: !0,
52
+ MailboxContentionError: !0,
53
+ ApplicationDeliveryValidationError: !0,
54
+ OutboxContentionError: !0,
55
+ WaitBudgetElapsedError: !0,
56
+ WorkflowCatalogConflictError: !0,
57
+ WorkflowRevisionNotInstalledError: !0,
58
+ WorkflowSourceValidationError: !0,
59
+ WorkflowSourceNotRegisteredError: !0,
60
+ DynamicWorkflowSourceUnavailableError: !0,
61
+ WorkflowRevisionUnavailableError: !0
51
62
  }, PUBLIC_WEFT_ERROR_CODES = new Set(Object.keys(publicWeftErrorCodeMap));
52
63
  export function isWeftError(value) {
53
64
  return value instanceof WeftError;
@@ -11,6 +11,7 @@ export declare class WorkerExecutionStrategy implements ExecutionStrategy {
11
11
  startWorkflow(parameters: {
12
12
  workflowId: string;
13
13
  workflowExecutionToken?: string;
14
+ revision?: string;
14
15
  workflowType: string;
15
16
  input: unknown;
16
17
  checkpoint: ArrayBuffer;
@@ -45,6 +45,7 @@ export class WorkerExecutionStrategy {
45
45
  #messageHandler;
46
46
  #disposed;
47
47
  #nextTurnId;
48
+ #workflowRevisions;
48
49
  constructor(pool, options) {
49
50
  const {
50
51
  workflowTurnTimeoutMs,
@@ -58,6 +59,7 @@ export class WorkerExecutionStrategy {
58
59
  } = options ?? {};
59
60
  this.#pool = pool;
60
61
  this.#ownership = new WorkerExecutionOwnership;
62
+ this.#workflowRevisions = new Map;
61
63
  this.#workerListeners = new WorkerListenerRegistry;
62
64
  this.#checkpointResumeState = new WorkerCheckpointResumeState;
63
65
  this.#workflowTurnTimeoutMs = workflowTurnTimeoutMs;
@@ -81,6 +83,9 @@ export class WorkerExecutionStrategy {
81
83
  pool: this.#pool,
82
84
  emit: (message) => {
83
85
  this.#emit(message);
86
+ },
87
+ forgetWorkflowRevision: (workflowId) => {
88
+ this.#workflowRevisions.delete(workflowId);
84
89
  }
85
90
  });
86
91
  this.#dispatcher = new WorkerExecutionDispatcher({
@@ -97,7 +102,7 @@ export class WorkerExecutionStrategy {
97
102
  },
98
103
  ensureRealmReady: (worker, workflowId) => this.#ensureRealmReady(worker, workflowId),
99
104
  beginTurn: (worker, workflowId, turnId, kind) => {
100
- this.#turnWatchdog.begin(worker, workflowId, turnId, kind);
105
+ this.#turnWatchdog.begin(worker, workflowId, turnId, kind, void 0, this.#workflowRevisions.get(workflowId));
101
106
  },
102
107
  clearTurn: (worker) => {
103
108
  this.#turnWatchdog.clear(worker);
@@ -132,6 +137,10 @@ export class WorkerExecutionStrategy {
132
137
  startWorkflow(parameters) {
133
138
  this.#ownership.resetWorkflow(parameters.workflowId);
134
139
  this.#checkpointResumeState.resetWorkflow(parameters.workflowId);
140
+ if (parameters.revision !== void 0)
141
+ this.#workflowRevisions.set(parameters.workflowId, parameters.revision);
142
+ else
143
+ this.#workflowRevisions.delete(parameters.workflowId);
135
144
  const message = buildRunMessage(parameters, this.#inboundMessageContext());
136
145
  if (!this.#faultHandler.assertHostToWorkerMessageWithinLimit(parameters.workflowId, message))
137
146
  return;
@@ -185,6 +194,7 @@ export class WorkerExecutionStrategy {
185
194
  };
186
195
  }
187
196
  cancelWorkflow(workflowId) {
197
+ this.#workflowRevisions.delete(workflowId);
188
198
  const worker = this.#ownership.getActiveWorker(workflowId);
189
199
  if (worker) {
190
200
  this.#ownership.markCancelled(workflowId);
@@ -246,6 +256,7 @@ export class WorkerExecutionStrategy {
246
256
  this.#workerListeners.detachAll();
247
257
  this.#ownership.clear();
248
258
  this.#checkpointResumeState.clear();
259
+ this.#workflowRevisions.clear();
249
260
  this.#messageHandler = null;
250
261
  }
251
262
  async#handleWorkerMessage(worker, message) {
@@ -279,6 +290,7 @@ export class WorkerExecutionStrategy {
279
290
  return !1;
280
291
  this.#ownership.consumeCancelled(message.workflowId);
281
292
  this.#ownership.deleteParked(message.workflowId);
293
+ this.#workflowRevisions.delete(message.workflowId);
282
294
  this.#releaseActiveWorker(message.workflowId);
283
295
  this.#detachWorkerListenersIfIdle(worker);
284
296
  this.#checkpointResumeState.forgetWorkflowIfClosed(message.workflowId, this.#ownership.isWorkflowClosed(message.workflowId));
@@ -17,6 +17,16 @@ export interface WorkerFaultHandlerDependencies {
17
17
  protocolGuard: WorkerProtocolGuard;
18
18
  pool: WorkerPool;
19
19
  emit: (message: WorkerOutboundMessage) => void;
20
+ /**
21
+ * Forget a workflow's captured revision (WFT-20), mirroring
22
+ * `#settleTerminalWorkerMessage`'s real-terminal-message cleanup. Every
23
+ * fault path here (protocol violation, turn timeout, worker crash, log
24
+ * abuse, realm-ready failure) synthesizes a `failed` message directly
25
+ * rather than routing through that settle path, so without this callback
26
+ * `WorkerExecutionStrategy#workflowRevisions` would keep an entry per
27
+ * faulted workflow ID for the life of the strategy.
28
+ */
29
+ forgetWorkflowRevision: (workflowId: string) => void;
20
30
  }
21
31
  export interface WorkerDiscardOptions {
22
32
  targetWorkflowId?: string;
@@ -71,6 +71,7 @@ export class WorkerFaultHandler {
71
71
  const { ownership, checkpointResumeState } = this.#dependencies;
72
72
  ownership.forgetWorkflow(workflowId);
73
73
  checkpointResumeState.forgetWorkflowIfClosed(workflowId, !0);
74
+ this.#dependencies.forgetWorkflowRevision(workflowId);
74
75
  if (isTarget && options.skipTarget)
75
76
  return;
76
77
  this.#dependencies.emit({
@@ -20,6 +20,7 @@ export interface WorkerInboundMessageContext {
20
20
  export declare function buildRunMessage(parameters: {
21
21
  workflowId: string;
22
22
  workflowExecutionToken?: string;
23
+ revision?: string;
23
24
  workflowType: string;
24
25
  input: unknown;
25
26
  checkpoint: ArrayBuffer;
@@ -8,6 +8,7 @@ export function buildRunMessage(parameters, context) {
8
8
  ...parameters.workflowExecutionToken !== void 0 && {
9
9
  workflowExecutionToken: parameters.workflowExecutionToken
10
10
  },
11
+ ...parameters.revision !== void 0 && { workflowRevision: parameters.revision },
11
12
  workflowType: parameters.workflowType,
12
13
  checkpoint: parameters.checkpoint,
13
14
  input: parameters.input,
@@ -51,6 +51,10 @@ export class WorkerProtocolGuard {
51
51
  throw new WorkerProtocolError("Worker message arrived outside an active turn");
52
52
  if ((message.type === "log" ? void 0 : message.turnId) !== turn.turnId || message.workflowId !== turn.workflowId)
53
53
  throw new WorkerProtocolError("Worker message did not match the active turn");
54
+ if (turn.revision !== void 0) {
55
+ if ((message.type === "log" ? void 0 : message.workflowRevision) !== turn.revision)
56
+ throw new WorkerProtocolError("Worker message revision did not match the active turn");
57
+ }
54
58
  }
55
59
  }
56
60
  function protocolFailure(error, options) {
@@ -59,6 +59,13 @@ export declare function createBoundedWorkerFailureMessage(parameters: {
59
59
  error: string;
60
60
  failureCategory: FailureCategory;
61
61
  turnId?: number;
62
+ /**
63
+ * Echo of the active turn's captured revision (WFT-20). Required whenever the
64
+ * caller has one, so a bounded fallback for an oversized checkpoint/terminal
65
+ * message still passes the host's strict revision check instead of being
66
+ * discarded as a protocol violation.
67
+ */
68
+ workflowRevision?: string;
62
69
  }): WorkerOutboundMessage;
63
70
  export declare function estimateWorkerProtocolMessageBytes(message: unknown): number;
64
71
  export declare function assertWorkerProtocolMessageWithinLimit(message: unknown, maxBytes: number | undefined): number;
@@ -65,7 +65,8 @@ export function createBoundedWorkerFailureMessage(parameters) {
65
65
  ...parameters.turnId === void 0 ? {} : { turnId: parameters.turnId },
66
66
  workflowId: parameters.workflowId,
67
67
  error: truncateForProtocol(parameters.error),
68
- failureCategory: parameters.failureCategory
68
+ failureCategory: parameters.failureCategory,
69
+ ...parameters.workflowRevision === void 0 ? {} : { workflowRevision: parameters.workflowRevision }
69
70
  };
70
71
  }
71
72
  export function estimateWorkerProtocolMessageBytes(message) {
@@ -4,12 +4,19 @@ export interface WorkerTurnState {
4
4
  turnId: number;
5
5
  kind: 'run' | 'resume';
6
6
  timeoutMs: number | undefined;
7
+ /**
8
+ * The workflow's captured revision (WFT-20), when known — carried forward
9
+ * on every turn for this workflow (including `resume`, which never
10
+ * re-supplies it), for `WorkerProtocolGuard` to validate the outbound
11
+ * echo against.
12
+ */
13
+ revision?: string;
7
14
  }
8
15
  export type WorkerTurnTimeoutResolverForTesting = (turn: Pick<WorkerTurnState, 'workflowId' | 'kind'>) => number;
9
16
  export declare class WorkerTurnWatchdog {
10
17
  #private;
11
18
  constructor(timeoutMs: number | undefined, onTimeout: (turn: WorkerTurnState) => void);
12
- begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind'], timeoutMs?: number | undefined): void;
19
+ begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind'], timeoutMs?: number | undefined, revision?: string): void;
13
20
  setTimeoutResolverForTesting(resolver: WorkerTurnTimeoutResolverForTesting): void;
14
21
  clear(worker: Worker): void;
15
22
  clearAll(): void;