@lostgradient/weft 0.23.1 → 0.24.0

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 (294) 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/generated/operation-catalog.snapshot.json +287 -3
  12. package/dist/cli/generated/operation-client.generated.d.ts +324 -10
  13. package/dist/cli/generated/operation-client.generated.js +12 -0
  14. package/dist/cli/output.js +1 -1
  15. package/dist/cli/storage-factory.js +2 -0
  16. package/dist/cli/workflow-commands.js +2 -0
  17. package/dist/cli-main.js +1 -1
  18. package/dist/core/application-payload-digest.d.ts +42 -0
  19. package/dist/core/application-payload-digest.js +76 -0
  20. package/dist/core/application-primitive-abort.d.ts +50 -0
  21. package/dist/core/application-primitive-abort.js +40 -0
  22. package/dist/core/application-primitive-attempt-registry.d.ts +74 -0
  23. package/dist/core/application-primitive-attempt-registry.js +73 -0
  24. package/dist/core/application-primitive-codec.d.ts +36 -0
  25. package/dist/core/application-primitive-codec.js +56 -0
  26. package/dist/core/application-primitive-commit.d.ts +67 -0
  27. package/dist/core/application-primitive-commit.js +66 -0
  28. package/dist/core/application-primitive-guards.d.ts +62 -0
  29. package/dist/core/application-primitive-guards.js +89 -0
  30. package/dist/core/application-primitive-payload.d.ts +29 -0
  31. package/dist/core/application-primitive-payload.js +65 -0
  32. package/dist/core/application-primitive-timing.d.ts +18 -0
  33. package/dist/core/application-primitive-timing.js +22 -0
  34. package/dist/core/atomic-state.js +2 -0
  35. package/dist/core/catalog/codec.d.ts +40 -0
  36. package/dist/core/catalog/codec.js +45 -0
  37. package/dist/core/catalog/errors.d.ts +104 -0
  38. package/dist/core/catalog/errors.js +41 -0
  39. package/dist/core/catalog/index.d.ts +25 -0
  40. package/dist/core/catalog/index.js +15 -0
  41. package/dist/core/catalog/reference-counts.d.ts +105 -0
  42. package/dist/core/catalog/reference-counts.js +28 -0
  43. package/dist/core/catalog/removal.d.ts +52 -0
  44. package/dist/core/catalog/removal.js +14 -0
  45. package/dist/core/catalog/storage-io.d.ts +78 -0
  46. package/dist/core/catalog/storage-io.js +106 -0
  47. package/dist/core/catalog/types.d.ts +108 -0
  48. package/dist/core/catalog/types.js +0 -0
  49. package/dist/core/catalog/workflow-catalog.d.ts +165 -0
  50. package/dist/core/catalog/workflow-catalog.js +198 -0
  51. package/dist/core/compare-codepoint.d.ts +13 -0
  52. package/dist/core/compare-codepoint.js +7 -0
  53. package/dist/core/compression.js +2 -0
  54. package/dist/core/context/attributes.d.ts +1 -1
  55. package/dist/core/context/durable-operations.d.ts +2 -2
  56. package/dist/core/context/index.js +5 -3
  57. package/dist/core/context/state-namespace.d.ts +1 -1
  58. package/dist/core/contract/build.d.ts +64 -0
  59. package/dist/core/contract/build.js +99 -0
  60. package/dist/core/contract/compatibility.d.ts +187 -0
  61. package/dist/core/contract/compatibility.js +37 -0
  62. package/dist/core/contract/failure.d.ts +64 -0
  63. package/dist/core/contract/failure.js +4 -0
  64. package/dist/core/contract/hash.d.ts +92 -0
  65. package/dist/core/contract/hash.js +34 -0
  66. package/dist/core/contract/index.d.ts +21 -0
  67. package/dist/core/contract/index.js +22 -0
  68. package/dist/core/contract/limits.d.ts +74 -0
  69. package/dist/core/contract/limits.js +1 -0
  70. package/dist/core/contract/manifest-parse-schema.d.ts +37 -0
  71. package/dist/core/contract/manifest-parse-schema.js +106 -0
  72. package/dist/core/contract/manifest-parse.d.ts +76 -0
  73. package/dist/core/contract/manifest-parse.js +189 -0
  74. package/dist/core/contract/manifest.d.ts +56 -0
  75. package/dist/core/contract/manifest.js +31 -0
  76. package/dist/core/contract/normalize.d.ts +97 -0
  77. package/dist/core/contract/normalize.js +127 -0
  78. package/dist/core/contract/revision.d.ts +29 -0
  79. package/dist/core/contract/revision.js +5 -0
  80. package/dist/core/contract/types.d.ts +274 -0
  81. package/dist/core/contract/types.js +1 -0
  82. package/dist/core/engine/catalog-activation.d.ts +40 -0
  83. package/dist/core/engine/catalog-activation.js +17 -0
  84. package/dist/core/engine/catalog-events.d.ts +36 -0
  85. package/dist/core/engine/catalog-events.js +15 -0
  86. package/dist/core/engine/catalog-readiness.d.ts +49 -0
  87. package/dist/core/engine/catalog-readiness.js +59 -0
  88. package/dist/core/engine/catalog-removal.d.ts +132 -0
  89. package/dist/core/engine/catalog-removal.js +70 -0
  90. package/dist/core/engine/construction.d.ts +1 -1
  91. package/dist/core/engine/construction.js +4 -2
  92. package/dist/core/engine/disposal.js +9 -0
  93. package/dist/core/engine/engine-workflows-namespace.d.ts +130 -0
  94. package/dist/core/engine/engine-workflows-namespace.js +49 -0
  95. package/dist/core/engine/finalizer-metadata.d.ts +22 -0
  96. package/dist/core/engine/finalizer-metadata.js +12 -0
  97. package/dist/core/engine/handle-result.js +2 -0
  98. package/dist/core/engine/index.d.ts +83 -0
  99. package/dist/core/engine/index.js +61 -0
  100. package/dist/core/engine/internals.d.ts +44 -1
  101. package/dist/core/engine/internals.js +6 -0
  102. package/dist/core/engine/lifecycle/start.js +3 -0
  103. package/dist/core/engine/registration.d.ts +76 -0
  104. package/dist/core/engine/registration.js +12 -6
  105. package/dist/core/engine/source-registration.d.ts +42 -0
  106. package/dist/core/engine/source-registration.js +36 -0
  107. package/dist/core/engine/source-resolution.d.ts +85 -0
  108. package/dist/core/engine/source-resolution.js +119 -0
  109. package/dist/core/engine/validation.js +2 -2
  110. package/dist/core/events/catalog-events.d.ts +117 -0
  111. package/dist/core/events/catalog-events.js +62 -0
  112. package/dist/core/events/event-map.d.ts +6 -0
  113. package/dist/core/events/index.d.ts +1 -0
  114. package/dist/core/events/index.js +1 -0
  115. package/dist/core/mailbox-admission.d.ts +26 -0
  116. package/dist/core/mailbox-admission.js +130 -0
  117. package/dist/core/mailbox-claims.d.ts +251 -0
  118. package/dist/core/mailbox-claims.js +0 -0
  119. package/dist/core/mailbox-codec.d.ts +32 -0
  120. package/dist/core/mailbox-codec.js +221 -0
  121. package/dist/core/mailbox-contract.d.ts +290 -0
  122. package/dist/core/mailbox-contract.js +0 -0
  123. package/dist/core/mailbox-delivery.d.ts +37 -0
  124. package/dist/core/mailbox-delivery.js +193 -0
  125. package/dist/core/mailbox-guards.d.ts +78 -0
  126. package/dist/core/mailbox-guards.js +58 -0
  127. package/dist/core/mailbox-index-codec.d.ts +41 -0
  128. package/dist/core/mailbox-index-codec.js +71 -0
  129. package/dist/core/mailbox-internals.d.ts +156 -0
  130. package/dist/core/mailbox-internals.js +154 -0
  131. package/dist/core/mailbox-maintenance.d.ts +29 -0
  132. package/dist/core/mailbox-maintenance.js +196 -0
  133. package/dist/core/mailbox-settlement.d.ts +69 -0
  134. package/dist/core/mailbox-settlement.js +206 -0
  135. package/dist/core/mailbox-storage.d.ts +117 -0
  136. package/dist/core/mailbox-storage.js +115 -0
  137. package/dist/core/mailbox-transition-helpers.d.ts +70 -0
  138. package/dist/core/mailbox-transition-helpers.js +43 -0
  139. package/dist/core/mailbox-transitions-recovery.d.ts +28 -0
  140. package/dist/core/mailbox-transitions-recovery.js +64 -0
  141. package/dist/core/mailbox-transitions.d.ts +138 -0
  142. package/dist/core/mailbox-transitions.js +180 -0
  143. package/dist/core/mailbox-types.d.ts +406 -0
  144. package/dist/core/mailbox-types.js +16 -0
  145. package/dist/core/mailbox-validation.d.ts +65 -0
  146. package/dist/core/mailbox-validation.js +73 -0
  147. package/dist/core/mailbox-waits.d.ts +50 -0
  148. package/dist/core/mailbox-waits.js +97 -0
  149. package/dist/core/mailbox.d.ts +163 -0
  150. package/dist/core/mailbox.js +211 -0
  151. package/dist/core/outbox-claims.d.ts +307 -0
  152. package/dist/core/outbox-claims.js +0 -0
  153. package/dist/core/outbox-codec.d.ts +24 -0
  154. package/dist/core/outbox-codec.js +257 -0
  155. package/dist/core/outbox-contract.d.ts +346 -0
  156. package/dist/core/outbox-contract.js +0 -0
  157. package/dist/core/outbox-delivery.d.ts +34 -0
  158. package/dist/core/outbox-delivery.js +149 -0
  159. package/dist/core/outbox-drain.d.ts +29 -0
  160. package/dist/core/outbox-drain.js +158 -0
  161. package/dist/core/outbox-enqueue.d.ts +24 -0
  162. package/dist/core/outbox-enqueue.js +115 -0
  163. package/dist/core/outbox-guards.d.ts +76 -0
  164. package/dist/core/outbox-guards.js +60 -0
  165. package/dist/core/outbox-index-codec.d.ts +33 -0
  166. package/dist/core/outbox-index-codec.js +71 -0
  167. package/dist/core/outbox-internals.d.ts +99 -0
  168. package/dist/core/outbox-internals.js +159 -0
  169. package/dist/core/outbox-listing.d.ts +12 -0
  170. package/dist/core/outbox-listing.js +38 -0
  171. package/dist/core/outbox-maintenance.d.ts +28 -0
  172. package/dist/core/outbox-maintenance.js +191 -0
  173. package/dist/core/outbox-operations.d.ts +18 -0
  174. package/dist/core/outbox-operations.js +46 -0
  175. package/dist/core/outbox-runner.d.ts +30 -0
  176. package/dist/core/outbox-runner.js +217 -0
  177. package/dist/core/outbox-settlement.d.ts +57 -0
  178. package/dist/core/outbox-settlement.js +183 -0
  179. package/dist/core/outbox-storage.d.ts +107 -0
  180. package/dist/core/outbox-storage.js +127 -0
  181. package/dist/core/outbox-transition-helpers.d.ts +83 -0
  182. package/dist/core/outbox-transition-helpers.js +63 -0
  183. package/dist/core/outbox-transitions-recovery.d.ts +30 -0
  184. package/dist/core/outbox-transitions-recovery.js +42 -0
  185. package/dist/core/outbox-transitions.d.ts +145 -0
  186. package/dist/core/outbox-transitions.js +236 -0
  187. package/dist/core/outbox-types.d.ts +400 -0
  188. package/dist/core/outbox-types.js +20 -0
  189. package/dist/core/outbox-validation.d.ts +101 -0
  190. package/dist/core/outbox-validation.js +127 -0
  191. package/dist/core/outbox-waits.d.ts +39 -0
  192. package/dist/core/outbox-waits.js +88 -0
  193. package/dist/core/outbox.d.ts +156 -0
  194. package/dist/core/outbox.js +234 -0
  195. package/dist/core/registry-limits.d.ts +49 -0
  196. package/dist/core/registry-limits.js +10 -0
  197. package/dist/core/registry-schema-conversion.d.ts +20 -0
  198. package/dist/core/registry-schema-conversion.js +22 -0
  199. package/dist/core/registry-snapshot.d.ts +91 -42
  200. package/dist/core/registry-snapshot.js +39 -77
  201. package/dist/core/registry-workflow-contract-draft.d.ts +32 -0
  202. package/dist/core/registry-workflow-contract-draft.js +28 -0
  203. package/dist/core/registry-workflow-manifest.d.ts +122 -0
  204. package/dist/core/registry-workflow-manifest.js +92 -0
  205. package/dist/core/source/errors.d.ts +55 -0
  206. package/dist/core/source/errors.js +13 -0
  207. package/dist/core/source/index.d.ts +19 -0
  208. package/dist/core/source/index.js +4 -0
  209. package/dist/core/source/resolvers.d.ts +45 -0
  210. package/dist/core/source/resolvers.js +9 -0
  211. package/dist/core/source/types.d.ts +211 -0
  212. package/dist/core/source/types.js +0 -0
  213. package/dist/core/source/validate.d.ts +91 -0
  214. package/dist/core/source/validate.js +62 -0
  215. package/dist/core/source/workflow-source.d.ts +43 -0
  216. package/dist/core/source/workflow-source.js +16 -0
  217. package/dist/core/types/workflow-registries.d.ts +7 -0
  218. package/dist/core/types/workflow-registry.d.ts +12 -0
  219. package/dist/core/versioning.js +2 -0
  220. package/dist/core/weft-error.d.ts +1 -1
  221. package/dist/core/weft-error.js +9 -1
  222. package/dist/http.js +2 -2
  223. package/dist/index.d.ts +23 -2
  224. package/dist/index.js +50 -0
  225. package/dist/indexeddb.js +1 -1
  226. package/dist/json-schema.js +3 -3
  227. package/dist/mcp/resources.js +2 -0
  228. package/dist/runtime/portable.d.ts +9 -1
  229. package/dist/server/fault-to-json-rpc.js +3 -1
  230. package/dist/server/handler/auth-context-principal.js +4 -0
  231. package/dist/server/json-rpc-http.js +2 -0
  232. package/dist/server/json-rpc-websocket.js +6 -4
  233. package/dist/server/operation-catalog/index.d.ts +1 -1
  234. package/dist/server/operation-catalog/pipeline-helpers.js +2 -0
  235. package/dist/server/operation-catalog/types.d.ts +17 -0
  236. package/dist/server/operation-fault.d.ts +3 -0
  237. package/dist/server/operation-fault.js +3 -1
  238. package/dist/server/operations/activate-workflow-revision.d.ts +30 -0
  239. package/dist/server/operations/activate-workflow-revision.js +69 -0
  240. package/dist/server/operations/fleet-events-subscription.js +1 -1
  241. package/dist/server/operations/fork-workflow.js +1 -1
  242. package/dist/server/operations/get-active-workflow-revision.d.ts +32 -0
  243. package/dist/server/operations/get-active-workflow-revision.js +46 -0
  244. package/dist/server/operations/get-catalog-diagnostics.d.ts +85 -0
  245. package/dist/server/operations/get-catalog-diagnostics.js +57 -0
  246. package/dist/server/operations/get-registry.js +17 -4
  247. package/dist/server/operations/get-workflow-revision.d.ts +25 -0
  248. package/dist/server/operations/get-workflow-revision.js +50 -0
  249. package/dist/server/operations/install-workflow-revision.d.ts +27 -0
  250. package/dist/server/operations/install-workflow-revision.js +46 -0
  251. package/dist/server/operations/list-workflow-revisions.d.ts +20 -0
  252. package/dist/server/operations/list-workflow-revisions.js +40 -0
  253. package/dist/server/operations/start-or-signal-workflow.js +1 -1
  254. package/dist/server/operations/start-workflow.js +1 -1
  255. package/dist/server/operations/static-registrations.js +36 -0
  256. package/dist/server/operations/storage.js +2 -2
  257. package/dist/server/operations/submit-review-decision.js +1 -1
  258. package/dist/server/operations/workflow-catalog-operation-helpers.d.ts +59 -0
  259. package/dist/server/operations/workflow-catalog-operation-helpers.js +135 -0
  260. package/dist/server/runtime/websocket-upgrade.js +2 -0
  261. package/dist/storage/bun-sql.js +49 -6
  262. package/dist/storage/catalog-keys.d.ts +45 -0
  263. package/dist/storage/catalog-keys.js +6 -0
  264. package/dist/storage/compressed-storage.js +1 -1
  265. package/dist/storage/derived-operations.js +1 -1
  266. package/dist/storage/index.d.ts +26 -1
  267. package/dist/storage/interface.d.ts +26 -1
  268. package/dist/storage/interface.js +1 -1
  269. package/dist/storage/key-encoding.d.ts +15 -0
  270. package/dist/storage/key-encoding.js +3 -0
  271. package/dist/storage/key-prefixes.d.ts +1 -1
  272. package/dist/storage/key-prefixes.js +15 -0
  273. package/dist/storage/lmdb.d.ts +26 -1
  274. package/dist/storage/lmdb.js +1 -1
  275. package/dist/storage/mailbox-keys.d.ts +80 -0
  276. package/dist/storage/mailbox-keys.js +14 -0
  277. package/dist/storage/memory.js +1 -1
  278. package/dist/storage/neon.js +2 -2
  279. package/dist/storage/node-sqlite-loader.d.ts +1 -1
  280. package/dist/storage/node-sqlite.js +49 -6
  281. package/dist/storage/outbox-keys.d.ts +77 -0
  282. package/dist/storage/outbox-keys.js +14 -0
  283. package/dist/storage/postgres.js +2 -2
  284. package/dist/storage/resolve.js +1 -1
  285. package/dist/storage/scoped-storage.js +1 -1
  286. package/dist/storage/storage-configuration.d.ts +6 -0
  287. package/dist/storage/testing.js +1 -1
  288. package/dist/storage/turso.js +2 -2
  289. package/dist/version.d.ts +1 -1
  290. package/dist/version.js +1 -1
  291. package/dist/web-extension.js +1 -1
  292. package/dist/worker/manifest/registry-contract-builder.d.ts +21 -3
  293. package/dist/worker/manifest/registry-contract-builder.js +40 -31
  294. package/package.json +1 -1
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ import { defineOperation } from "../operation-registry.js";
3
+ import {
4
+ readWorkflowCatalogRestBody,
5
+ throwWorkflowCatalogOperationFault,
6
+ validateManifestField,
7
+ workflowsAdminAccess
8
+ } from "./workflow-catalog-operation-helpers.js";
9
+ const installWorkflowRevisionInput = z.object({
10
+ manifest: z.unknown().describe("An untrusted WorkflowRevisionManifest, validated at invoke time.")
11
+ }), installWorkflowRevisionOutput = z.unknown();
12
+ export const installWorkflowRevisionOperation = defineOperation({
13
+ name: "weft.workflows.revisions.install",
14
+ mcpExposable: !1,
15
+ summary: "Durably install a workflow revision manifest",
16
+ description: "Validate and durably install a `WorkflowRevisionManifest` for a workflow the engine already has an in-process definition for. Idempotent on a byte-identical reinstall of the same (name, revision). Faults with InvalidParams when the manifest fails validation or names a workflow with no in-process definition, and Conflict when (name, revision) is already installed with different contract content. Does not check `manifest.workflowVersion` " + "against the in-process definition's own version \u2014 that mismatch is a normal " + "activation-time `incompatible` refusal, not an install-time error. Never changes which in-process handler `engine.start()` dispatches to.",
17
+ destructive: !1,
18
+ tags: ["Workflow Catalog"],
19
+ inputSchema: installWorkflowRevisionInput,
20
+ outputSchema: installWorkflowRevisionOutput,
21
+ access: workflowsAdminAccess,
22
+ producibleFaults: ["InvalidParams", "Conflict"],
23
+ discoverable: !0,
24
+ transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
25
+ unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
26
+ invoke: async ({ input, engine }) => {
27
+ const e = engine, manifest = await validateManifestField(input.manifest);
28
+ try {
29
+ return await e.workflows.install(manifest);
30
+ } catch (error) {
31
+ return throwWorkflowCatalogOperationFault(error);
32
+ }
33
+ }
34
+ }), installWorkflowRevisionRestBinding = {
35
+ method: "POST",
36
+ path: "/v1/registry/revisions",
37
+ pathParamNames: [],
38
+ operationName: "weft.workflows.revisions.install",
39
+ inputSources: {
40
+ manifest: { kind: "body-field", bodyField: "manifest" }
41
+ },
42
+ extractInput: async (request, _pathParams, context) => {
43
+ return { manifest: (await readWorkflowCatalogRestBody(request, context)).manifest };
44
+ },
45
+ success: { kind: "json", status: 201 }
46
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `weft.workflows.revisions.list` operation + REST binding.
3
+ *
4
+ * Lists every durably installed revision of one workflow name.
5
+ *
6
+ * @module server/operations/list-workflow-revisions
7
+ */
8
+ import { z } from 'zod';
9
+ import type { WorkflowRevisionRecord } from '../../core/catalog/index.ts';
10
+ import type { UnknownRestBinding } from '../rest-bindings.ts';
11
+ declare const listWorkflowRevisionsInput: z.ZodObject<{
12
+ name: z.ZodUnknown;
13
+ }, z.core.$strip>;
14
+ export type ListWorkflowRevisionsInput = z.infer<typeof listWorkflowRevisionsInput>;
15
+ export type ListWorkflowRevisionsOutput = readonly WorkflowRevisionRecord[];
16
+ export declare const listWorkflowRevisionsOperation: import("../operation-catalog.ts").OperationDefinition<{
17
+ name: unknown;
18
+ }, ListWorkflowRevisionsOutput, unknown>;
19
+ export declare const listWorkflowRevisionsRestBinding: UnknownRestBinding;
20
+ export {};
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import { defineOperation } from "../operation-registry.js";
3
+ import {
4
+ validateWorkflowNameField,
5
+ workflowsReadAccess
6
+ } from "./workflow-catalog-operation-helpers.js";
7
+ const listWorkflowRevisionsInput = z.object({
8
+ name: z.unknown().describe("Workflow name. Runtime validation requires a wire-safe identifier.")
9
+ }), listWorkflowRevisionsOutput = z.unknown();
10
+ export const listWorkflowRevisionsOperation = defineOperation({
11
+ name: "weft.workflows.revisions.list",
12
+ mcpExposable: !1,
13
+ summary: "List every installed revision of a workflow",
14
+ description: "Read every durably installed revision of `name`, sorted deterministically by revision. Read-only. Returns an empty array for a name with no installed revisions, rather than a " + "NotFound fault \u2014 an empty catalog is not an error.",
15
+ destructive: !1,
16
+ tags: ["Workflow Catalog"],
17
+ inputSchema: listWorkflowRevisionsInput,
18
+ outputSchema: listWorkflowRevisionsOutput,
19
+ access: workflowsReadAccess,
20
+ producibleFaults: ["InvalidParams"],
21
+ discoverable: !0,
22
+ transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
23
+ unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
24
+ invoke: async ({ input, engine }) => {
25
+ const e = engine, name = validateWorkflowNameField(input.name);
26
+ return e.workflows.listRevisions(name);
27
+ }
28
+ }), listWorkflowRevisionsRestBinding = {
29
+ method: "GET",
30
+ path: "/v1/registry/workflows/:name/revisions",
31
+ pathParamNames: ["name"],
32
+ operationName: "weft.workflows.revisions.list",
33
+ inputSources: {
34
+ name: { kind: "path", pathParam: "name" }
35
+ },
36
+ extractInput: async (_request, pathParams) => ({
37
+ name: pathParams.name ?? ""
38
+ }),
39
+ success: { kind: "json", status: 200 }
40
+ };
@@ -103,7 +103,7 @@ export const startOrSignalWorkflowOperation = defineOperation({
103
103
  const { handle, outcome } = await typedEngine.startOrSignal(type, input.input, signal, options);
104
104
  return { id: handle.id, outcome };
105
105
  } catch (error) {
106
- resolveStartOrSignalWorkflowFault(error);
106
+ return resolveStartOrSignalWorkflowFault(error);
107
107
  }
108
108
  }
109
109
  }), startOrSignalWorkflowRestBinding = {
@@ -77,7 +77,7 @@ export const startWorkflowOperation = defineOperation({
77
77
  try {
78
78
  return { id: (await typedEngine.start(type, input.input, options)).id };
79
79
  } catch (error) {
80
- resolveStartWorkflowAccess(error);
80
+ return resolveStartWorkflowAccess(error);
81
81
  }
82
82
  }
83
83
  }), startWorkflowRestBinding = {
@@ -1,3 +1,7 @@
1
+ import {
2
+ activateWorkflowRevisionOperation,
3
+ activateWorkflowRevisionRestBinding
4
+ } from "./activate-workflow-revision.js";
1
5
  import { addWorkflowTagsOperation, addWorkflowTagsRestBinding } from "./add-workflow-tags.js";
2
6
  import {
3
7
  aggregateWorkflowsOperation,
@@ -30,6 +34,14 @@ import { createScheduleOperation, createScheduleRestBinding } from "./create-sch
30
34
  import { fleetEventsSseOperation, fleetEventsSseRestBinding } from "./fleet-events-sse.js";
31
35
  import { fleetEventsSubscriptionOperation } from "./fleet-events-subscription.js";
32
36
  import { forkWorkflowOperation, forkWorkflowRestBinding } from "./fork-workflow.js";
37
+ import {
38
+ getActiveWorkflowRevisionOperation,
39
+ getActiveWorkflowRevisionRestBinding
40
+ } from "./get-active-workflow-revision.js";
41
+ import {
42
+ getCatalogDiagnosticsOperation,
43
+ getCatalogDiagnosticsRestBinding
44
+ } from "./get-catalog-diagnostics.js";
33
45
  import { getCheckpointAtOperation, getCheckpointAtRestBinding } from "./get-checkpoint-at.js";
34
46
  import { getPrincipalOperation, getPrincipalRestBinding } from "./get-principal.js";
35
47
  import { getRegistryOperation, getRegistryRestBinding } from "./get-registry.js";
@@ -55,15 +67,27 @@ import {
55
67
  import { getWorkflowEventsOperation, getWorkflowEventsRestBinding } from "./get-workflow-events.js";
56
68
  import * as workflowObservability from "./get-workflow-observability.js";
57
69
  import { getWorkflowResultOperation, getWorkflowResultRestBinding } from "./get-workflow-result.js";
70
+ import {
71
+ getWorkflowRevisionOperation,
72
+ getWorkflowRevisionRestBinding
73
+ } from "./get-workflow-revision.js";
58
74
  import {
59
75
  getWorkflowTimelineOperation,
60
76
  getWorkflowTimelineRestBinding
61
77
  } from "./get-workflow-timeline.js";
62
78
  import { getWorkflowOperation, getWorkflowRestBinding } from "./get-workflow.js";
79
+ import {
80
+ installWorkflowRevisionOperation,
81
+ installWorkflowRevisionRestBinding
82
+ } from "./install-workflow-revision.js";
63
83
  import { listAlertsOperation, listAlertsRestBinding } from "./list-alerts.js";
64
84
  import { listCheckpointsOperation, listCheckpointsRestBinding } from "./list-checkpoints.js";
65
85
  import { listReviewsOperation, listReviewsRestBinding } from "./list-reviews.js";
66
86
  import { listSchedulesOperation, listSchedulesRestBinding } from "./list-schedules.js";
87
+ import {
88
+ listWorkflowRevisionsOperation,
89
+ listWorkflowRevisionsRestBinding
90
+ } from "./list-workflow-revisions.js";
67
91
  import { listWorkflowsOperation, listWorkflowsRestBinding } from "./list-workflows.js";
68
92
  import { pauseScheduleOperation, pauseScheduleRestBinding } from "./pause-schedule.js";
69
93
  import { purgeWorkflowsOperation, purgeWorkflowsRestBinding } from "./purge-workflows.js";
@@ -130,6 +154,7 @@ export const STATIC_REST_BINDINGS = [
130
154
  bulkRetryFailedWorkflowsRestBinding,
131
155
  bulkDeleteWorkflowsRestBinding,
132
156
  bulkMutateWorkflowTagsRestBinding,
157
+ getCatalogDiagnosticsRestBinding,
133
158
  getWorkflowRestBinding,
134
159
  cancelWorkflowRestBinding,
135
160
  getWorkflowResultRestBinding,
@@ -151,6 +176,11 @@ export const STATIC_REST_BINDINGS = [
151
176
  createScheduleRestBinding,
152
177
  updateScheduleRestBinding,
153
178
  getRegistryRestBinding,
179
+ installWorkflowRevisionRestBinding,
180
+ activateWorkflowRevisionRestBinding,
181
+ getWorkflowRevisionRestBinding,
182
+ listWorkflowRevisionsRestBinding,
183
+ getActiveWorkflowRevisionRestBinding,
154
184
  getSystemLeaseRestBinding,
155
185
  getRetentionOverviewRestBinding,
156
186
  getUpdateResultRestBinding,
@@ -194,6 +224,7 @@ export const STATIC_REST_BINDINGS = [
194
224
  bulkRetryFailedWorkflowsOperation,
195
225
  bulkDeleteWorkflowsOperation,
196
226
  bulkMutateWorkflowTagsOperation,
227
+ getCatalogDiagnosticsOperation,
197
228
  getWorkflowOperation,
198
229
  cancelWorkflowOperation,
199
230
  getWorkflowResultOperation,
@@ -214,6 +245,11 @@ export const STATIC_REST_BINDINGS = [
214
245
  createScheduleOperation,
215
246
  updateScheduleOperation,
216
247
  getRegistryOperation,
248
+ installWorkflowRevisionOperation,
249
+ activateWorkflowRevisionOperation,
250
+ getWorkflowRevisionOperation,
251
+ listWorkflowRevisionsOperation,
252
+ getActiveWorkflowRevisionOperation,
217
253
  getSystemLeaseOperation,
218
254
  getRetentionOverviewOperation,
219
255
  getUpdateResultOperation,
@@ -42,14 +42,14 @@ const rawStorageAccess = {
42
42
  }), emptyOutput = z.null(), storageGetOutput = binaryValueSchema.nullable(), storageScanOutput = z.custom((value) => typeof value === "object" && value !== null && (Symbol.asyncIterator in value) && typeof value[Symbol.asyncIterator] === "function", "Storage scan output must be an async iterable."), storageConditionalBatchOutput = z.object({ applied: z.boolean() });
43
43
  function resolveAuthorizedStorage(engine, principal, operation) {
44
44
  if (!isAuthenticated(principal))
45
- raiseFault(operation, {
45
+ return raiseFault(operation, {
46
46
  code: "Unauthorized",
47
47
  message: "authentication required",
48
48
  data: { reason: "authentication required" }
49
49
  });
50
50
  if (principal.hasScope("storage:admin"))
51
51
  return engine.storage;
52
- raiseFault(operation, {
52
+ return raiseFault(operation, {
53
53
  code: "Forbidden",
54
54
  message: "Raw storage access requires storage:admin.",
55
55
  data: { reason: "Raw storage access requires storage:admin." }
@@ -89,7 +89,7 @@ export const submitReviewDecisionOperation = defineOperation({
89
89
  await e.submitReview(input.reviewId, reviewOptions);
90
90
  return { ok: !0 };
91
91
  } catch (error) {
92
- mapReviewDecisionError(error, input.reviewId);
92
+ return mapReviewDecisionError(error, input.reviewId);
93
93
  }
94
94
  }
95
95
  }), submitReviewDecisionRestBinding = {
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shared validation and fault mapping for the five `weft.workflows.revisions.*`
3
+ * / `weft.workflows.active.*` operations (WFT-11): `install-workflow-revision.ts`,
4
+ * `activate-workflow-revision.ts`, `get-workflow-revision.ts`,
5
+ * `list-workflow-revisions.ts`, `get-active-workflow-revision.ts`.
6
+ *
7
+ * @module server/operations/workflow-catalog-operation-helpers
8
+ */
9
+ import { type WorkflowCatalogActivationResult } from '../../core/catalog/index.ts';
10
+ import type { WorkflowCompatibilityPolicy } from '../../core/contract/compatibility.ts';
11
+ import type { WorkflowRevisionManifest } from '../../core/contract/types.ts';
12
+ import type { AccessPolicy } from '../authorization.ts';
13
+ import type { OperationFault } from '../operation-fault.ts';
14
+ import type { RestInputContext } from '../rest-binding.ts';
15
+ /** `workflows:admin` — required by `install` and `activate` (mutating). */
16
+ export declare const workflowsAdminAccess: AccessPolicy;
17
+ /** `workflows:read` — required by `get`/`list`/`active.get` (read-only). */
18
+ export declare const workflowsReadAccess: AccessPolicy;
19
+ /**
20
+ * Validate one `name` field per the wire-safe name grammar, raising the
21
+ * same `InvalidParams` fault both REST and JSON-RPC callers see for every
22
+ * other malformed identifier in this operation family. Bounded by
23
+ * `validateWorkflowOrActivityName` itself (`MAX_CONTRACT_IDENTIFIER_BYTES`).
24
+ */
25
+ export declare function validateWorkflowNameField(name: unknown): string;
26
+ /** Validate one `revision` field: a non-empty, bounded opaque string. */
27
+ export declare function validateWorkflowRevisionField(revision: unknown): string;
28
+ /** Validate an optional `expectedGeneration` field: a non-negative safe integer. */
29
+ export declare function validateExpectedGenerationField(value: unknown): number | undefined;
30
+ /** Validate an optional `policy` field against the one tunable compatibility axis. */
31
+ export declare function validatePolicyField(value: unknown): WorkflowCompatibilityPolicy | undefined;
32
+ /**
33
+ * Validate an untrusted `manifest` field via {@link parseWorkflowRevisionManifest} —
34
+ * the same hostile-input validation path (bounded sizes, recomputed
35
+ * `contractHash`) every other manifest consumer in this codebase uses.
36
+ */
37
+ export declare function validateManifestField(value: unknown): Promise<WorkflowRevisionManifest>;
38
+ /**
39
+ * Map one `applied: false` {@link WorkflowCatalogActivationResult} variant to
40
+ * the canonical `Conflict` fault. Exhaustive over all four refusal reasons —
41
+ * adding a fifth is a compile error here, forcing a deliberate wire mapping.
42
+ */
43
+ export declare function activationRefusalToFault(result: Extract<WorkflowCatalogActivationResult, {
44
+ applied: false;
45
+ }>): OperationFault;
46
+ /**
47
+ * Map an error thrown by `engine.workflows.install()`/`activate()` to the
48
+ * canonical operation fault, or rethrow unchanged when it is neither typed
49
+ * error this family can produce (letting the operation pipeline's generic
50
+ * `EngineFailure` wrapping handle anything else).
51
+ */
52
+ export declare function throwWorkflowCatalogOperationFault(error: unknown): never;
53
+ /**
54
+ * Read a REST request body as a JSON object, raising `InvalidParams` for
55
+ * malformed JSON or a non-object top-level value — shared by
56
+ * `install-workflow-revision.ts` (body-only) and
57
+ * `activate-workflow-revision.ts` (path `name` plus body fields).
58
+ */
59
+ export declare function readWorkflowCatalogRestBody(request: Request, context: RestInputContext): Promise<Record<string, unknown>>;
@@ -0,0 +1,135 @@
1
+ import { z } from "zod";
2
+ import {
3
+ WorkflowCatalogConflictError,
4
+ WorkflowRevisionNotInstalledError
5
+ } from "../../core/catalog/index.js";
6
+ import { MAX_CONTRACT_IDENTIFIER_BYTES } from "../../core/contract/limits.js";
7
+ import { parseWorkflowRevisionManifest } from "../../core/contract/manifest-parse.js";
8
+ import { WorkflowNotRegisteredError } from "../../core/engine/errors.js";
9
+ import { validateWorkflowOrActivityName } from "../../core/types/name-grammar.js";
10
+ import { readRestJsonBody } from "../rest-body.js";
11
+ import { invalidParamsFault, isOperationFault } from "./operation-helpers.js";
12
+ export const workflowsAdminAccess = {
13
+ kind: "scoped",
14
+ scopes: { kind: "anyOf", scopes: ["workflows:admin"] }
15
+ }, workflowsReadAccess = {
16
+ kind: "scoped",
17
+ scopes: { kind: "anyOf", scopes: ["workflows:read"] }
18
+ };
19
+ export function validateWorkflowNameField(name) {
20
+ if (typeof name !== "string" || name.length === 0)
21
+ throw invalidParamsFault('Field "name" must be a non-empty string');
22
+ try {
23
+ validateWorkflowOrActivityName(name, "workflow");
24
+ } catch (error) {
25
+ throw invalidParamsFault(error instanceof Error ? error.message : String(error));
26
+ }
27
+ return name;
28
+ }
29
+ export function validateWorkflowRevisionField(revision) {
30
+ if (typeof revision !== "string" || revision.length === 0)
31
+ throw invalidParamsFault('Field "revision" must be a non-empty string');
32
+ if (new TextEncoder().encode(revision).byteLength > MAX_CONTRACT_IDENTIFIER_BYTES)
33
+ throw invalidParamsFault(`Field "revision" exceeds the maximum identifier size of ${String(MAX_CONTRACT_IDENTIFIER_BYTES)} bytes`);
34
+ return revision;
35
+ }
36
+ export function validateExpectedGenerationField(value) {
37
+ if (value === void 0)
38
+ return;
39
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
40
+ throw invalidParamsFault('Field "expectedGeneration" must be a non-negative integer');
41
+ return value;
42
+ }
43
+ const compatibilityPolicyShape = z.object({ requireExactRevision: z.boolean().optional() }).strict();
44
+ export function validatePolicyField(value) {
45
+ if (value === void 0)
46
+ return;
47
+ const parsed = compatibilityPolicyShape.safeParse(value);
48
+ if (!parsed.success)
49
+ throw invalidParamsFault('Field "policy" must be an object with an optional boolean "requireExactRevision"');
50
+ return parsed.data.requireExactRevision === void 0 ? {} : { requireExactRevision: parsed.data.requireExactRevision };
51
+ }
52
+ export async function validateManifestField(value) {
53
+ const result = await parseWorkflowRevisionManifest(value);
54
+ if (!result.ok)
55
+ throw manifestValidationFailureFault(result);
56
+ return result.manifest;
57
+ }
58
+ function manifestValidationFailureFault(failure) {
59
+ return {
60
+ code: "InvalidParams",
61
+ message: failure.message,
62
+ data: {
63
+ issues: [
64
+ {
65
+ path: failure.path === void 0 ? [] : failure.path.split("."),
66
+ message: failure.message,
67
+ code: failure.reason
68
+ }
69
+ ]
70
+ }
71
+ };
72
+ }
73
+ export function activationRefusalToFault(result) {
74
+ switch (result.reason) {
75
+ case "incompatible": {
76
+ const { verdict } = result, reasons = verdict.compatible ? [] : verdict.reasons;
77
+ return {
78
+ code: "Conflict",
79
+ message: `Candidate revision is incompatible with the currently active revision: ${reasons.join(", ")}`,
80
+ data: { reason: result.reason, compatibilityReasons: reasons }
81
+ };
82
+ }
83
+ case "stale-generation":
84
+ return {
85
+ code: "Conflict",
86
+ message: `Stale expectedGeneration: the current durable generation is ${String(result.currentGeneration)}`,
87
+ data: { reason: result.reason, currentGeneration: result.currentGeneration }
88
+ };
89
+ case "expected-generation-required":
90
+ return {
91
+ code: "Conflict",
92
+ message: "expectedGeneration is required once a workflow has an active revision \u2014 current " + `generation is ${String(result.currentGeneration)}`,
93
+ data: { reason: result.reason, currentGeneration: result.currentGeneration }
94
+ };
95
+ case "conflict":
96
+ return {
97
+ code: "Conflict",
98
+ message: "Activation lost a concurrent write race; re-read the active pointer and retry",
99
+ data: { reason: result.reason }
100
+ };
101
+ default:
102
+ throw Error(`Unknown activation refusal reason: ${JSON.stringify(result)}`);
103
+ }
104
+ }
105
+ export function throwWorkflowCatalogOperationFault(error) {
106
+ if (error instanceof WorkflowRevisionNotInstalledError)
107
+ throw {
108
+ code: "NotFound",
109
+ message: error.message,
110
+ data: {
111
+ resource: "workflow-revision",
112
+ identifier: `${error.workflowName}:${error.revision}`,
113
+ weftCode: error.code
114
+ }
115
+ };
116
+ if (error instanceof WorkflowNotRegisteredError)
117
+ throw invalidParamsFault(error.message, error.code);
118
+ if (error instanceof WorkflowCatalogConflictError)
119
+ throw {
120
+ code: "Conflict",
121
+ message: error.message,
122
+ data: { reason: "catalog-conflict", weftCode: error.code }
123
+ };
124
+ throw error;
125
+ }
126
+ export async function readWorkflowCatalogRestBody(request, context) {
127
+ const body = await readRestJsonBody(request, context).catch((error) => {
128
+ if (isOperationFault(error))
129
+ throw error;
130
+ return null;
131
+ });
132
+ if (typeof body !== "object" || body === null || Array.isArray(body))
133
+ throw invalidParamsFault("Request body must be a JSON object.");
134
+ return body;
135
+ }
@@ -69,6 +69,8 @@ function upgradeScope(connectionType) {
69
69
  case "generic":
70
70
  case void 0:
71
71
  return null;
72
+ default:
73
+ throw Error(`Unknown WebSocket connection type: ${JSON.stringify(connectionType)}`);
72
74
  }
73
75
  }
74
76
  export function handleWebSocketUpgrade(server, context, options, request, url, authContext) {
@@ -9,6 +9,21 @@ function requireStorageCapability(storage, capability, featureName) {
9
9
  }
10
10
  }
11
11
 
12
+ // src/storage/key-encoding.ts
13
+ function encodeStorageKeyComponent(value) {
14
+ return encodeURIComponent(value);
15
+ }
16
+ function formatSortableStorageTimestamp(timestamp) {
17
+ return String(timestamp).padStart(16, "0");
18
+ }
19
+
20
+ // src/storage/catalog-keys.ts
21
+ var WORKFLOW_CATALOG_KEYS = {
22
+ catalogEntry: (name, revision) => `catalog-entry:${encodeStorageKeyComponent(name)}:${encodeStorageKeyComponent(revision)}`,
23
+ catalogEntryPrefix: (name) => `catalog-entry:${encodeStorageKeyComponent(name)}:`,
24
+ catalogActive: (name) => `catalog-active:${encodeStorageKeyComponent(name)}`
25
+ };
26
+
12
27
  // src/storage/default-scope.ts
13
28
  var DEFAULT_SCOPE = "default";
14
29
 
@@ -23,7 +38,7 @@ async function* storageKeysCore(storage, prefix, options) {
23
38
  }
24
39
  async function storageCountCore(storage, prefix) {
25
40
  let count = 0;
26
- for await (const _key of storageKeysCore(storage, prefix)) {
41
+ for await (const _ of storageKeysCore(storage, prefix)) {
27
42
  count++;
28
43
  }
29
44
  return count;
@@ -51,10 +66,35 @@ async function storageDeleteRangeCore(storage, prefix, options) {
51
66
  return operations.length;
52
67
  }
53
68
 
54
- // src/storage/key-encoding.ts
55
- function encodeStorageKeyComponent(value) {
56
- return encodeURIComponent(value);
57
- }
69
+ // src/storage/mailbox-keys.ts
70
+ var MAILBOX_KEYS = {
71
+ applicationMailbox: (namespace, resourceId) => `appmbx:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}`,
72
+ applicationMailboxSinkProbe: (namespace, resourceId, nonce) => `appprobe:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${encodeStorageKeyComponent(nonce)}`,
73
+ applicationCommandPrefix: (namespace, resourceId) => `appcmd:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:`,
74
+ applicationCommand: (namespace, resourceId, commandId) => `appcmd:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${encodeStorageKeyComponent(commandId)}`,
75
+ applicationCommandReadyPrefix: (namespace, resourceId) => `appready:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:`,
76
+ applicationCommandReady: (namespace, resourceId, sequence) => `appready:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${formatSortableStorageTimestamp(sequence)}`,
77
+ applicationCommandIdempotency: (namespace, resourceId, key) => `appidem:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${encodeStorageKeyComponent(key)}`,
78
+ applicationCommandBySequencePrefix: (namespace, resourceId) => `appseq:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:`,
79
+ applicationCommandBySequence: (namespace, resourceId, sequence) => `appseq:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${formatSortableStorageTimestamp(sequence)}`,
80
+ applicationCommandTerminalPrefix: (namespace, resourceId) => `appterm:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:`,
81
+ applicationCommandTerminal: (namespace, resourceId, terminalAt, commandId) => `appterm:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(resourceId)}:${formatSortableStorageTimestamp(terminalAt)}:${encodeStorageKeyComponent(commandId)}`
82
+ };
83
+
84
+ // src/storage/outbox-keys.ts
85
+ var OUTBOX_KEYS = {
86
+ applicationOutbox: (namespace, ownerId) => `appobx:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}`,
87
+ applicationOutboxSinkProbe: (namespace, ownerId, nonce) => `appprobe:v1:outbox:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${encodeStorageKeyComponent(nonce)}`,
88
+ applicationDeliveryPrefix: (namespace, ownerId) => `appdlv:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:`,
89
+ applicationDelivery: (namespace, ownerId, deliveryId) => `appdlv:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${encodeStorageKeyComponent(deliveryId)}`,
90
+ applicationDeliveryDuePrefix: (namespace, ownerId) => `appdue:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:`,
91
+ applicationDeliveryDue: (namespace, ownerId, availableAt, deliveryId) => `appdue:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${formatSortableStorageTimestamp(availableAt)}:${encodeStorageKeyComponent(deliveryId)}`,
92
+ applicationDeliveryIdempotency: (namespace, ownerId, key) => `appdidem:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${encodeStorageKeyComponent(key)}`,
93
+ applicationDeliveryBySequencePrefix: (namespace, ownerId) => `appdseq:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:`,
94
+ applicationDeliveryBySequence: (namespace, ownerId, sequence) => `appdseq:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${formatSortableStorageTimestamp(sequence)}`,
95
+ applicationDeliveryTerminalPrefix: (namespace, ownerId) => `appdterm:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:`,
96
+ applicationDeliveryTerminal: (namespace, ownerId, terminalAt, deliveryId) => `appdterm:v1:${encodeStorageKeyComponent(namespace)}:${encodeStorageKeyComponent(ownerId)}:${formatSortableStorageTimestamp(terminalAt)}:${encodeStorageKeyComponent(deliveryId)}`
97
+ };
58
98
 
59
99
  // src/storage/ownership-keys.ts
60
100
  var OWNERSHIP_CLAIM_KEYS = {
@@ -132,7 +172,7 @@ async function storageConditionalBatch(storage, conditions, operations) {
132
172
  }
133
173
  return storage.conditionalBatch(conditions, operations);
134
174
  }
135
- var formatSortableTimestamp = (timestamp) => String(timestamp).padStart(16, "0");
175
+ var formatSortableTimestamp = formatSortableStorageTimestamp;
136
176
  var SIGNAL_SORT_CLASS_START = "0";
137
177
  var SIGNAL_SORT_CLASS_NORMAL = "1";
138
178
  var signalStorageKey = (workflowId, name, id, sortClass) => `sig:${encodeStorageKeyComponent(workflowId)}:${encodeStorageKeyComponent(name)}:${sortClass}:${encodeStorageKeyComponent(id)}`;
@@ -195,7 +235,10 @@ var KEYS = {
195
235
  leasePrefix: () => "lease:",
196
236
  leaseEpoch: () => "lease:epoch",
197
237
  leaseHolder: () => "lease:holder",
238
+ ...MAILBOX_KEYS,
239
+ ...OUTBOX_KEYS,
198
240
  ...OWNERSHIP_CLAIM_KEYS,
241
+ ...WORKFLOW_CATALOG_KEYS,
199
242
  budget: (namespace, period, date) => `budget:${namespace}:${period}:${date}`,
200
243
  review: (workflowId, reviewId) => `review:${encodeStorageKeyComponent(workflowId)}:${reviewId}`,
201
244
  workflowHeaders: (workflowId) => `wf-headers:${encodeStorageKeyComponent(workflowId)}`,
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Storage key builders for the durable workflow catalog (WFT-9/WFT-10).
3
+ *
4
+ * Spread into `KEYS` in `interface.ts` rather than declared there, mirroring
5
+ * `ownership-keys.ts`'s pattern — the catalog keyspace can carry its full
6
+ * rationale without pushing `interface.ts` past its documented line ceiling.
7
+ * Callers reach these through `KEYS`, which keeps one import contract for
8
+ * storage keys.
9
+ *
10
+ * `catalog-entry:<name>:<revision>` is one immutable record per installed
11
+ * `(name, revision)` pair, never overwritten once written. `catalog-active:<name>`
12
+ * is the single mutable `{ revision, generation, activatedAt }` pointer per
13
+ * workflow name, written only through `conditionalBatch` CAS — the exact
14
+ * store-wide-singleton precedent `ownership-mode-marker.ts` establishes for
15
+ * `KEYS.ownershipModeMarker()`.
16
+ *
17
+ * @module storage/catalog-keys
18
+ */
19
+ /**
20
+ * Workflow catalog key builders. Spread into `KEYS`; not intended to be
21
+ * imported directly by engine code.
22
+ */
23
+ export declare const WORKFLOW_CATALOG_KEYS: {
24
+ /**
25
+ * One immutable installed-revision record for `name`. The initial write
26
+ * IS `conditionalBatch` CAS-guarded ({@link import('../core/catalog/storage-io.ts').writeCatalogEntry}),
27
+ * not a plain `put` — a caller-supplied, non-content-derived `revision`
28
+ * (`buildWorkflowRevisionManifest`'s `options.revision` escape hatch)
29
+ * means two racing writers are not guaranteed to agree on this key's
30
+ * content, so the write must fail closed on a genuine conflict rather than
31
+ * last-write-win. This key is also deleted, CAS-guarded on its own exact
32
+ * bytes, by `removeCatalogEntry` (WFT-12) once a revision is no longer
33
+ * active and no longer referenced.
34
+ */
35
+ readonly catalogEntry: (name: string, revision: string) => string;
36
+ /** Scan prefix for every installed revision of `name`. */
37
+ readonly catalogEntryPrefix: (name: string) => string;
38
+ /**
39
+ * The active-revision pointer for `name`: a single mutable
40
+ * `{ revision, generation, activatedAt }` record, written only through
41
+ * `conditionalBatch` — the same CAS/store-wide-singleton precedent
42
+ * `KEYS.ownershipModeMarker()` uses.
43
+ */
44
+ readonly catalogActive: (name: string) => string;
45
+ };
@@ -0,0 +1,6 @@
1
+ import { encodeStorageKeyComponent } from "./key-encoding.js";
2
+ export const WORKFLOW_CATALOG_KEYS = {
3
+ catalogEntry: (name, revision) => `catalog-entry:${encodeStorageKeyComponent(name)}:${encodeStorageKeyComponent(revision)}`,
4
+ catalogEntryPrefix: (name) => `catalog-entry:${encodeStorageKeyComponent(name)}:`,
5
+ catalogActive: (name) => `catalog-active:${encodeStorageKeyComponent(name)}`
6
+ };