@lostgradient/weft 0.18.0 → 0.20.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 (171) hide show
  1. package/README.md +3 -1
  2. package/dist/cli/conformance.js +14 -18
  3. package/dist/cli/generated/operation-catalog.snapshot.json +1597 -21
  4. package/dist/cli/generated/operation-client.generated.d.ts +37 -6
  5. package/dist/cli/generated/operation-client.generated.js +6 -0
  6. package/dist/core/context/child-workflow-pipe.d.ts +1 -1
  7. package/dist/core/context/child-workflow-pipe.js +1 -1
  8. package/dist/core/engine/construction.d.ts +2 -0
  9. package/dist/core/engine/construction.js +3 -0
  10. package/dist/core/engine/index.js +1 -0
  11. package/dist/core/engine/listing.d.ts +1 -0
  12. package/dist/core/engine/listing.js +6 -4
  13. package/dist/core/weft-error.d.ts +1 -1
  14. package/dist/core/weft-error.js +2 -1
  15. package/dist/core/worker-execution-dispatcher.d.ts +8 -0
  16. package/dist/core/worker-execution-dispatcher.js +4 -0
  17. package/dist/core/worker-execution-strategy-options.d.ts +16 -0
  18. package/dist/core/worker-execution-strategy.js +71 -89
  19. package/dist/core/worker-fault-handling.d.ts +45 -0
  20. package/dist/core/worker-fault-handling.js +88 -0
  21. package/dist/core/worker-protocol.d.ts +18 -1
  22. package/dist/core/worker-protocol.js +1 -1
  23. package/dist/core/worker-realm-readiness.d.ts +78 -0
  24. package/dist/core/worker-realm-readiness.js +127 -0
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.js +28 -1
  27. package/dist/json-schema.js +1 -1
  28. package/dist/runtime/portable.d.ts +14 -0
  29. package/dist/runtime/portable.js +10 -0
  30. package/dist/server/index.d.ts +71 -8
  31. package/dist/server/index.js +7 -3
  32. package/dist/server/operations/get-task-detail-schema.d.ts +341 -0
  33. package/dist/server/operations/get-task-detail-schema.js +118 -0
  34. package/dist/server/operations/get-task-detail.d.ts +346 -0
  35. package/dist/server/operations/get-task-detail.js +215 -0
  36. package/dist/server/operations/get-task-diagnostics.d.ts +43 -18
  37. package/dist/server/operations/get-task-diagnostics.js +87 -126
  38. package/dist/server/operations/get-worker-diagnostics.d.ts +177 -0
  39. package/dist/server/operations/get-worker-diagnostics.js +117 -0
  40. package/dist/server/operations/list-worker-registration-rejections.d.ts +79 -0
  41. package/dist/server/operations/list-worker-registration-rejections.js +60 -0
  42. package/dist/server/operations/list-workers.js +1 -3
  43. package/dist/server/operations/static-registrations.js +8 -20
  44. package/dist/server/rest-bindings.js +31 -2
  45. package/dist/server/runtime/authentication-bridge.js +6 -14
  46. package/dist/server/runtime/context.d.ts +23 -0
  47. package/dist/server/runtime/task-dispatch.d.ts +7 -1
  48. package/dist/server/runtime/task-dispatch.js +126 -55
  49. package/dist/server/runtime/task-ledger-completion.d.ts +68 -0
  50. package/dist/server/runtime/task-ledger-completion.js +72 -0
  51. package/dist/server/runtime/task-ledger-recovery.d.ts +55 -0
  52. package/dist/server/runtime/task-ledger-recovery.js +73 -0
  53. package/dist/server/runtime/task-ledger-runtime.d.ts +64 -0
  54. package/dist/server/runtime/task-ledger-runtime.js +34 -0
  55. package/dist/server/runtime/task-metrics.d.ts +6 -4
  56. package/dist/server/runtime/task-polling.d.ts +14 -12
  57. package/dist/server/runtime/task-polling.js +106 -82
  58. package/dist/server/runtime/task-reconciliation.d.ts +35 -8
  59. package/dist/server/runtime/task-reconciliation.js +75 -74
  60. package/dist/server/runtime/task-result-resolution.d.ts +2 -10
  61. package/dist/server/runtime/task-result-resolution.js +0 -67
  62. package/dist/server/runtime/task-result-view.d.ts +82 -0
  63. package/dist/server/runtime/task-result-view.js +48 -0
  64. package/dist/server/runtime/websocket-worker-messaging.d.ts +16 -0
  65. package/dist/server/runtime/websocket-worker-messaging.js +32 -0
  66. package/dist/server/runtime/websocket-worker-registration.d.ts +41 -0
  67. package/dist/server/runtime/websocket-worker-registration.js +134 -0
  68. package/dist/server/runtime/websocket-worker.d.ts +0 -1
  69. package/dist/server/runtime/websocket-worker.js +64 -116
  70. package/dist/server/serve-internals.d.ts +9 -6
  71. package/dist/server/serve-internals.js +14 -40
  72. package/dist/server/task-ledger-codec.d.ts +40 -0
  73. package/dist/server/task-ledger-codec.js +195 -0
  74. package/dist/server/task-ledger-keys.d.ts +13 -0
  75. package/dist/server/task-ledger-keys.js +5 -0
  76. package/dist/server/task-ledger-limits.d.ts +34 -0
  77. package/dist/server/task-ledger-limits.js +5 -0
  78. package/dist/server/task-ledger-transition-helpers.d.ts +38 -0
  79. package/dist/server/task-ledger-transition-helpers.js +42 -0
  80. package/dist/server/task-ledger-transitions-cancellation.d.ts +31 -0
  81. package/dist/server/task-ledger-transitions-cancellation.js +73 -0
  82. package/dist/server/task-ledger-transitions.d.ts +129 -0
  83. package/dist/server/task-ledger-transitions.js +162 -0
  84. package/dist/server/task-ledger-types.d.ts +220 -0
  85. package/dist/server/task-ledger-types.js +1 -0
  86. package/dist/server/task-ledger.d.ts +17 -0
  87. package/dist/server/task-ledger.js +24 -0
  88. package/dist/server/task-state.d.ts +25 -152
  89. package/dist/server/task-state.js +0 -188
  90. package/dist/server/worker-admission-policy.d.ts +70 -0
  91. package/dist/server/worker-admission-policy.js +0 -0
  92. package/dist/storage/compressed-storage.js +1 -1
  93. package/dist/storage/index.d.ts +0 -2
  94. package/dist/storage/interface.d.ts +0 -2
  95. package/dist/storage/interface.js +1 -1
  96. package/dist/storage/lmdb.js +1 -1
  97. package/dist/storage/memory.js +1 -1
  98. package/dist/storage/neon.js +1 -1
  99. package/dist/storage/postgres.js +1 -1
  100. package/dist/storage/resolve.js +1 -1
  101. package/dist/storage/scoped-storage.js +1 -1
  102. package/dist/storage/testing.js +1 -1
  103. package/dist/storage/turso.js +1 -1
  104. package/dist/storage/web-extension.js +2 -2
  105. package/dist/version.d.ts +1 -1
  106. package/dist/version.js +1 -1
  107. package/dist/web-extension.js +1 -1
  108. package/dist/worker/index.d.ts +2 -0
  109. package/dist/worker/index.js +30 -4
  110. package/dist/worker/manifest/canonical-json.d.ts +20 -0
  111. package/dist/worker/manifest/canonical-json.js +13 -0
  112. package/dist/worker/manifest/capabilities.d.ts +24 -0
  113. package/dist/worker/manifest/capabilities.js +74 -0
  114. package/dist/worker/manifest/content-digest.d.ts +20 -0
  115. package/dist/worker/manifest/content-digest.js +13 -0
  116. package/dist/worker/manifest/declared-shape-digest.d.ts +14 -0
  117. package/dist/worker/manifest/declared-shape-digest.js +4 -0
  118. package/dist/worker/manifest/digest.d.ts +82 -0
  119. package/dist/worker/manifest/digest.js +9 -0
  120. package/dist/worker/manifest/execution-identity.d.ts +92 -0
  121. package/dist/worker/manifest/execution-identity.js +36 -0
  122. package/dist/worker/manifest/failure.d.ts +59 -0
  123. package/dist/worker/manifest/failure.js +4 -0
  124. package/dist/worker/manifest/index.d.ts +22 -0
  125. package/dist/worker/manifest/index.js +23 -0
  126. package/dist/worker/manifest/internal-realm.d.ts +50 -0
  127. package/dist/worker/manifest/internal-realm.js +39 -0
  128. package/dist/worker/manifest/is-record.d.ts +12 -0
  129. package/dist/worker/manifest/is-record.js +6 -0
  130. package/dist/worker/manifest/json-scan.d.ts +26 -0
  131. package/dist/worker/manifest/json-scan.js +88 -0
  132. package/dist/worker/manifest/limits.d.ts +138 -0
  133. package/dist/worker/manifest/limits.js +1 -0
  134. package/dist/worker/manifest/normalize.d.ts +63 -0
  135. package/dist/worker/manifest/normalize.js +73 -0
  136. package/dist/worker/manifest/parse-json.d.ts +24 -0
  137. package/dist/worker/manifest/parse-json.js +15 -0
  138. package/dist/worker/manifest/parse.d.ts +86 -0
  139. package/dist/worker/manifest/parse.js +188 -0
  140. package/dist/worker/manifest/registry-contract-builder.d.ts +120 -0
  141. package/dist/worker/manifest/registry-contract-builder.js +65 -0
  142. package/dist/worker/manifest/types.d.ts +263 -0
  143. package/dist/worker/manifest/types.js +1 -0
  144. package/dist/worker/manifest/utf8.d.ts +13 -0
  145. package/dist/worker/manifest/utf8.js +7 -0
  146. package/dist/worker/options.d.ts +55 -8
  147. package/dist/worker/options.js +65 -9
  148. package/dist/worker/protocol-internals.d.ts +1 -2
  149. package/dist/worker/protocol-internals.js +0 -5
  150. package/dist/worker/protocol-messages.d.ts +33 -17
  151. package/dist/worker/protocol-schemas.d.ts +36 -74
  152. package/dist/worker/protocol-schemas.js +25 -18
  153. package/dist/worker/protocol-version.d.ts +18 -14
  154. package/dist/worker/protocol-version.js +1 -1
  155. package/dist/worker/protocol.js +1 -1
  156. package/dist/worker/registry/deployment-consistency.d.ts +78 -0
  157. package/dist/worker/registry/deployment-consistency.js +27 -0
  158. package/dist/worker/registry/drain.d.ts +14 -0
  159. package/dist/worker/registry/drain.js +24 -0
  160. package/dist/worker/registry/rejections.d.ts +31 -0
  161. package/dist/worker/registry/rejections.js +10 -0
  162. package/dist/worker/registry/summary.d.ts +0 -3
  163. package/dist/worker/registry/summary.js +2 -5
  164. package/dist/worker/registry/types.d.ts +10 -3
  165. package/dist/worker/registry.d.ts +47 -2
  166. package/dist/worker/registry.js +45 -32
  167. package/dist/workers/workflow-worker-entry.d.ts +12 -7
  168. package/dist/workers/workflow-worker-entry.js +9 -2
  169. package/package.json +3 -3
  170. package/dist/server/task-resolved-record.d.ts +0 -12
  171. package/dist/server/task-resolved-record.js +0 -35
@@ -0,0 +1,346 @@
1
+ /**
2
+ * `weft.tasks.get` operation + REST binding (WFT-92).
3
+ *
4
+ * Reads the full durable ledger state for one `operationId` — the wire
5
+ * counterpart to `WeftServer.getTaskResult()`, which is same-process-only
6
+ * (`src/server/runtime/task-result-view.ts`). This operation exposes the
7
+ * complete dispatch envelope and current ledger state so an HTTP/JSON-RPC
8
+ * caller — an operator console, for instance — can render one task's
9
+ * authoritative state without reconstructing it from the bounded
10
+ * `weft.tasks.diagnostics` alerting shape, which deliberately collapses
11
+ * `leased`/`completing`/`cancelling` into one `inflight` value and carries
12
+ * no attempt identity, priority, headers, retry-availability, adoption, or
13
+ * retention evidence.
14
+ *
15
+ * **Excluded fields.** `attemptToken`, `workerSessionId`, and
16
+ * `executionIdentity` are never projected here, matching
17
+ * `TaskResultView`'s own documented exclusion list — they are worker
18
+ * ownership/session internals with no business being public. `headers`
19
+ * are summarized as key names only (`headerKeys`): interceptor headers can
20
+ * carry trace context or auth material, and this is a read surface, not a
21
+ * payload inspector. The task `input` value and a dead-lettered record's
22
+ * pending result `value` are omitted for the same "digest not value"
23
+ * reason `TaskResultView` omits a resolved result's value — the ledger
24
+ * proves which attempt won, it does not re-deliver payloads. `resultDigest`
25
+ * is only projected for `disposition: 'resolved'`: the `cancelled`
26
+ * (mid-attempt) and `retryExhausted` lineages store a synthetic
27
+ * `${disposition}:${operationId}:${attemptToken}` placeholder there instead
28
+ * of a real content hash (`task-ledger-transitions(-cancellation).ts`),
29
+ * which would otherwise leak the excluded `attemptToken` verbatim.
30
+ *
31
+ * **Read-only by design.** This issue deliberately does not add an HTTP
32
+ * path to `adoptTaskResultImpl`. WFT-24 describes adoption as "an explicit
33
+ * caller assertion" that a workflow incorporated a result — a browser
34
+ * operator clicking a button cannot honestly make that assertion. If an
35
+ * HTTP adoption path is ever wanted, it needs its own design discussion,
36
+ * not a bundled addition here.
37
+ *
38
+ * @module server/operations/get-task-detail
39
+ */
40
+ import type { UnknownRestBinding } from '../rest-bindings.ts';
41
+ export { executionRequirementSchema, getTaskDetailOutputSchema, retryPolicySchema, type GetTaskDetailInput, type GetTaskDetailOutput, } from './get-task-detail-schema.ts';
42
+ export declare const getTaskDetailOperation: import("../operation-catalog.ts").OperationDefinition<{
43
+ operationId: string;
44
+ }, {
45
+ disposition: "resolved";
46
+ resultDigest: string;
47
+ resultStatus: "completed" | "failed";
48
+ state: "terminal";
49
+ terminalAt: number;
50
+ adopted: boolean;
51
+ operationId: string;
52
+ workflowType: string;
53
+ activityName: string;
54
+ queue: string;
55
+ headerKeys: string[];
56
+ visibilityTimeoutMilliseconds: number;
57
+ createdAt: number;
58
+ attempt: number;
59
+ error?: string | undefined;
60
+ adoptedAt?: number | undefined;
61
+ workflowId?: string | undefined;
62
+ workflowExecutionToken?: string | undefined;
63
+ priority?: number | undefined;
64
+ retryPolicy?: {
65
+ maxAttempts: number;
66
+ initialBackoff: string | number;
67
+ backoffMultiplier: number;
68
+ maxBackoff: string | number;
69
+ nonRetryableErrors?: string[] | undefined;
70
+ } | undefined;
71
+ scheduleToCloseDeadline?: number | undefined;
72
+ executionRequirement?: {
73
+ deploymentName?: string | undefined;
74
+ buildId?: string | undefined;
75
+ artifactDigest?: string | undefined;
76
+ workflowRevision?: string | undefined;
77
+ activityContractHash?: string | undefined;
78
+ } | undefined;
79
+ fairShareKey?: string | undefined;
80
+ stickyWorkflowId?: string | undefined;
81
+ } | {
82
+ disposition: "cancelled";
83
+ cancellationReason: string;
84
+ state: "terminal";
85
+ terminalAt: number;
86
+ adopted: boolean;
87
+ operationId: string;
88
+ workflowType: string;
89
+ activityName: string;
90
+ queue: string;
91
+ headerKeys: string[];
92
+ visibilityTimeoutMilliseconds: number;
93
+ createdAt: number;
94
+ attempt: number;
95
+ adoptedAt?: number | undefined;
96
+ workflowId?: string | undefined;
97
+ workflowExecutionToken?: string | undefined;
98
+ priority?: number | undefined;
99
+ retryPolicy?: {
100
+ maxAttempts: number;
101
+ initialBackoff: string | number;
102
+ backoffMultiplier: number;
103
+ maxBackoff: string | number;
104
+ nonRetryableErrors?: string[] | undefined;
105
+ } | undefined;
106
+ scheduleToCloseDeadline?: number | undefined;
107
+ executionRequirement?: {
108
+ deploymentName?: string | undefined;
109
+ buildId?: string | undefined;
110
+ artifactDigest?: string | undefined;
111
+ workflowRevision?: string | undefined;
112
+ activityContractHash?: string | undefined;
113
+ } | undefined;
114
+ fairShareKey?: string | undefined;
115
+ stickyWorkflowId?: string | undefined;
116
+ } | {
117
+ disposition: "retryExhausted";
118
+ error: string;
119
+ state: "terminal";
120
+ terminalAt: number;
121
+ adopted: boolean;
122
+ operationId: string;
123
+ workflowType: string;
124
+ activityName: string;
125
+ queue: string;
126
+ headerKeys: string[];
127
+ visibilityTimeoutMilliseconds: number;
128
+ createdAt: number;
129
+ attempt: number;
130
+ adoptedAt?: number | undefined;
131
+ workflowId?: string | undefined;
132
+ workflowExecutionToken?: string | undefined;
133
+ priority?: number | undefined;
134
+ retryPolicy?: {
135
+ maxAttempts: number;
136
+ initialBackoff: string | number;
137
+ backoffMultiplier: number;
138
+ maxBackoff: string | number;
139
+ nonRetryableErrors?: string[] | undefined;
140
+ } | undefined;
141
+ scheduleToCloseDeadline?: number | undefined;
142
+ executionRequirement?: {
143
+ deploymentName?: string | undefined;
144
+ buildId?: string | undefined;
145
+ artifactDigest?: string | undefined;
146
+ workflowRevision?: string | undefined;
147
+ activityContractHash?: string | undefined;
148
+ } | undefined;
149
+ fairShareKey?: string | undefined;
150
+ stickyWorkflowId?: string | undefined;
151
+ } | {
152
+ state: "queued";
153
+ availableAt: number;
154
+ firstQueuedAt: number;
155
+ lastQueuedAt: number;
156
+ retryCount: number;
157
+ requeueCount: number;
158
+ operationId: string;
159
+ workflowType: string;
160
+ activityName: string;
161
+ queue: string;
162
+ headerKeys: string[];
163
+ visibilityTimeoutMilliseconds: number;
164
+ createdAt: number;
165
+ attempt: number;
166
+ lastDispatchedAt?: number | undefined;
167
+ startedAt?: number | undefined;
168
+ lastRequeueReason?: string | undefined;
169
+ workflowId?: string | undefined;
170
+ workflowExecutionToken?: string | undefined;
171
+ priority?: number | undefined;
172
+ retryPolicy?: {
173
+ maxAttempts: number;
174
+ initialBackoff: string | number;
175
+ backoffMultiplier: number;
176
+ maxBackoff: string | number;
177
+ nonRetryableErrors?: string[] | undefined;
178
+ } | undefined;
179
+ scheduleToCloseDeadline?: number | undefined;
180
+ executionRequirement?: {
181
+ deploymentName?: string | undefined;
182
+ buildId?: string | undefined;
183
+ artifactDigest?: string | undefined;
184
+ workflowRevision?: string | undefined;
185
+ activityContractHash?: string | undefined;
186
+ } | undefined;
187
+ fairShareKey?: string | undefined;
188
+ stickyWorkflowId?: string | undefined;
189
+ } | {
190
+ leaseDeadline: number;
191
+ firstQueuedAt: number;
192
+ lastQueuedAt: number;
193
+ startedAt: number;
194
+ lastHeartbeatAt: number;
195
+ state: "leased";
196
+ retryCount: number;
197
+ requeueCount: number;
198
+ operationId: string;
199
+ workflowType: string;
200
+ activityName: string;
201
+ queue: string;
202
+ headerKeys: string[];
203
+ visibilityTimeoutMilliseconds: number;
204
+ createdAt: number;
205
+ attempt: number;
206
+ lastRequeueReason?: string | undefined;
207
+ workflowId?: string | undefined;
208
+ workflowExecutionToken?: string | undefined;
209
+ priority?: number | undefined;
210
+ retryPolicy?: {
211
+ maxAttempts: number;
212
+ initialBackoff: string | number;
213
+ backoffMultiplier: number;
214
+ maxBackoff: string | number;
215
+ nonRetryableErrors?: string[] | undefined;
216
+ } | undefined;
217
+ scheduleToCloseDeadline?: number | undefined;
218
+ executionRequirement?: {
219
+ deploymentName?: string | undefined;
220
+ buildId?: string | undefined;
221
+ artifactDigest?: string | undefined;
222
+ workflowRevision?: string | undefined;
223
+ activityContractHash?: string | undefined;
224
+ } | undefined;
225
+ fairShareKey?: string | undefined;
226
+ stickyWorkflowId?: string | undefined;
227
+ } | {
228
+ pendingStatus: "completed" | "failed";
229
+ resultDigest: string;
230
+ leaseDeadline: number;
231
+ firstQueuedAt: number;
232
+ lastQueuedAt: number;
233
+ startedAt: number;
234
+ lastHeartbeatAt: number;
235
+ state: "completing";
236
+ retryCount: number;
237
+ requeueCount: number;
238
+ operationId: string;
239
+ workflowType: string;
240
+ activityName: string;
241
+ queue: string;
242
+ headerKeys: string[];
243
+ visibilityTimeoutMilliseconds: number;
244
+ createdAt: number;
245
+ attempt: number;
246
+ lastRequeueReason?: string | undefined;
247
+ workflowId?: string | undefined;
248
+ workflowExecutionToken?: string | undefined;
249
+ priority?: number | undefined;
250
+ retryPolicy?: {
251
+ maxAttempts: number;
252
+ initialBackoff: string | number;
253
+ backoffMultiplier: number;
254
+ maxBackoff: string | number;
255
+ nonRetryableErrors?: string[] | undefined;
256
+ } | undefined;
257
+ scheduleToCloseDeadline?: number | undefined;
258
+ executionRequirement?: {
259
+ deploymentName?: string | undefined;
260
+ buildId?: string | undefined;
261
+ artifactDigest?: string | undefined;
262
+ workflowRevision?: string | undefined;
263
+ activityContractHash?: string | undefined;
264
+ } | undefined;
265
+ fairShareKey?: string | undefined;
266
+ stickyWorkflowId?: string | undefined;
267
+ } | {
268
+ cancellationReason: string;
269
+ cancellationRequestedAt: number;
270
+ leaseDeadline: number;
271
+ firstQueuedAt: number;
272
+ lastQueuedAt: number;
273
+ startedAt: number;
274
+ lastHeartbeatAt: number;
275
+ state: "cancelling";
276
+ retryCount: number;
277
+ requeueCount: number;
278
+ operationId: string;
279
+ workflowType: string;
280
+ activityName: string;
281
+ queue: string;
282
+ headerKeys: string[];
283
+ visibilityTimeoutMilliseconds: number;
284
+ createdAt: number;
285
+ attempt: number;
286
+ lastRequeueReason?: string | undefined;
287
+ workflowId?: string | undefined;
288
+ workflowExecutionToken?: string | undefined;
289
+ priority?: number | undefined;
290
+ retryPolicy?: {
291
+ maxAttempts: number;
292
+ initialBackoff: string | number;
293
+ backoffMultiplier: number;
294
+ maxBackoff: string | number;
295
+ nonRetryableErrors?: string[] | undefined;
296
+ } | undefined;
297
+ scheduleToCloseDeadline?: number | undefined;
298
+ executionRequirement?: {
299
+ deploymentName?: string | undefined;
300
+ buildId?: string | undefined;
301
+ artifactDigest?: string | undefined;
302
+ workflowRevision?: string | undefined;
303
+ activityContractHash?: string | undefined;
304
+ } | undefined;
305
+ fairShareKey?: string | undefined;
306
+ stickyWorkflowId?: string | undefined;
307
+ } | {
308
+ state: "deadLettered";
309
+ pendingStatus: "completed" | "failed";
310
+ resultDigest: string;
311
+ deadLetteredAt: number;
312
+ persistenceFailureReason: string;
313
+ retryCount: number;
314
+ requeueCount: number;
315
+ operationId: string;
316
+ workflowType: string;
317
+ activityName: string;
318
+ queue: string;
319
+ headerKeys: string[];
320
+ visibilityTimeoutMilliseconds: number;
321
+ createdAt: number;
322
+ attempt: number;
323
+ error?: string | undefined;
324
+ lastRequeueReason?: string | undefined;
325
+ workflowId?: string | undefined;
326
+ workflowExecutionToken?: string | undefined;
327
+ priority?: number | undefined;
328
+ retryPolicy?: {
329
+ maxAttempts: number;
330
+ initialBackoff: string | number;
331
+ backoffMultiplier: number;
332
+ maxBackoff: string | number;
333
+ nonRetryableErrors?: string[] | undefined;
334
+ } | undefined;
335
+ scheduleToCloseDeadline?: number | undefined;
336
+ executionRequirement?: {
337
+ deploymentName?: string | undefined;
338
+ buildId?: string | undefined;
339
+ artifactDigest?: string | undefined;
340
+ workflowRevision?: string | undefined;
341
+ activityContractHash?: string | undefined;
342
+ } | undefined;
343
+ fairShareKey?: string | undefined;
344
+ stickyWorkflowId?: string | undefined;
345
+ }, unknown>;
346
+ export declare const getTaskDetailRestBinding: UnknownRestBinding;
@@ -0,0 +1,215 @@
1
+ import { raiseFault } from "../operation-catalog/raise-fault.js";
2
+ import { defineOperation } from "../operation-registry.js";
3
+ import {
4
+ decodeRemoteTaskRecord,
5
+ taskLedgerKey
6
+ } from "../task-ledger.js";
7
+ import {
8
+ executionRequirementSchema,
9
+ getTaskDetailInput,
10
+ getTaskDetailOutputSchema,
11
+ retryPolicySchema
12
+ } from "./get-task-detail-schema.js";
13
+ export {
14
+ executionRequirementSchema,
15
+ getTaskDetailOutputSchema,
16
+ retryPolicySchema
17
+ } from "./get-task-detail-schema.js";
18
+ function projectRetryPolicy(retryPolicy) {
19
+ return {
20
+ maxAttempts: retryPolicy.maxAttempts,
21
+ initialBackoff: retryPolicy.initialBackoff,
22
+ backoffMultiplier: retryPolicy.backoffMultiplier,
23
+ maxBackoff: retryPolicy.maxBackoff,
24
+ ...retryPolicy.nonRetryableErrors !== void 0 ? { nonRetryableErrors: retryPolicy.nonRetryableErrors } : {}
25
+ };
26
+ }
27
+ function projectExecutionRequirement(executionRequirement) {
28
+ return {
29
+ ...executionRequirement.deploymentName !== void 0 ? { deploymentName: executionRequirement.deploymentName } : {},
30
+ ...executionRequirement.buildId !== void 0 ? { buildId: executionRequirement.buildId } : {},
31
+ ...executionRequirement.artifactDigest !== void 0 ? { artifactDigest: executionRequirement.artifactDigest } : {},
32
+ ...executionRequirement.workflowRevision !== void 0 ? { workflowRevision: executionRequirement.workflowRevision } : {},
33
+ ...executionRequirement.activityContractHash !== void 0 ? { activityContractHash: executionRequirement.activityContractHash } : {}
34
+ };
35
+ }
36
+ function baseEnvelopeFields(record) {
37
+ return {
38
+ operationId: record.operationId,
39
+ ...record.workflowId !== void 0 ? { workflowId: record.workflowId } : {},
40
+ ...record.workflowExecutionToken !== void 0 ? { workflowExecutionToken: record.workflowExecutionToken } : {},
41
+ workflowType: record.workflowType,
42
+ activityName: record.activityName,
43
+ queue: record.queue,
44
+ ...record.priority !== void 0 ? { priority: record.priority } : {},
45
+ headerKeys: Object.keys(record.headers),
46
+ visibilityTimeoutMilliseconds: record.visibilityTimeoutMilliseconds,
47
+ ...record.retryPolicy !== void 0 ? { retryPolicy: projectRetryPolicy(record.retryPolicy) } : {},
48
+ ...record.scheduleToCloseDeadline !== void 0 ? { scheduleToCloseDeadline: record.scheduleToCloseDeadline } : {},
49
+ ...record.executionRequirement !== void 0 ? { executionRequirement: projectExecutionRequirement(record.executionRequirement) } : {},
50
+ ...record.fairShareKey !== void 0 ? { fairShareKey: record.fairShareKey } : {},
51
+ ...record.stickyWorkflowId !== void 0 ? { stickyWorkflowId: record.stickyWorkflowId } : {},
52
+ createdAt: record.createdAt,
53
+ attempt: record.attempt
54
+ };
55
+ }
56
+ function attemptFields(record) {
57
+ return {
58
+ retryCount: record.retryCount,
59
+ requeueCount: record.requeueCount,
60
+ ...record.lastRequeueReason !== void 0 ? { lastRequeueReason: record.lastRequeueReason } : {}
61
+ };
62
+ }
63
+ function leaseHolderFields(record) {
64
+ return {
65
+ leaseDeadline: record.leaseDeadline,
66
+ firstQueuedAt: record.firstQueuedAt,
67
+ lastQueuedAt: record.lastQueuedAt,
68
+ startedAt: record.startedAt,
69
+ lastHeartbeatAt: record.lastHeartbeatAt
70
+ };
71
+ }
72
+ function projectQueued(record) {
73
+ return {
74
+ ...baseEnvelopeFields(record),
75
+ ...attemptFields(record),
76
+ state: "queued",
77
+ availableAt: record.availableAt,
78
+ firstQueuedAt: record.firstQueuedAt,
79
+ lastQueuedAt: record.lastQueuedAt,
80
+ ...record.lastDispatchedAt !== void 0 ? { lastDispatchedAt: record.lastDispatchedAt } : {},
81
+ ...record.startedAt !== void 0 ? { startedAt: record.startedAt } : {}
82
+ };
83
+ }
84
+ function projectLeased(record) {
85
+ return {
86
+ ...baseEnvelopeFields(record),
87
+ ...attemptFields(record),
88
+ ...leaseHolderFields(record),
89
+ state: "leased"
90
+ };
91
+ }
92
+ function projectCompleting(record) {
93
+ return {
94
+ ...baseEnvelopeFields(record),
95
+ ...attemptFields(record),
96
+ ...leaseHolderFields(record),
97
+ state: "completing",
98
+ pendingStatus: record.pendingStatus,
99
+ resultDigest: record.pendingResultDigest
100
+ };
101
+ }
102
+ function projectCancelling(record) {
103
+ return {
104
+ ...baseEnvelopeFields(record),
105
+ ...attemptFields(record),
106
+ ...leaseHolderFields(record),
107
+ state: "cancelling",
108
+ cancellationReason: record.cancellationReason,
109
+ cancellationRequestedAt: record.cancellationRequestedAt
110
+ };
111
+ }
112
+ function terminalDispositionFields(record) {
113
+ if (record.disposition === "resolved")
114
+ return {
115
+ disposition: "resolved",
116
+ resultDigest: record.resultDigest,
117
+ resultStatus: record.status,
118
+ ...record.error !== void 0 ? { error: record.error } : {}
119
+ };
120
+ if (record.disposition === "cancelled")
121
+ return {
122
+ disposition: "cancelled",
123
+ cancellationReason: record.cancellationReason
124
+ };
125
+ return {
126
+ disposition: "retryExhausted",
127
+ error: record.error
128
+ };
129
+ }
130
+ function projectTerminal(record) {
131
+ return {
132
+ ...baseEnvelopeFields(record),
133
+ state: "terminal",
134
+ terminalAt: record.terminalAt,
135
+ adopted: record.adopted,
136
+ ...record.adoptedAt !== void 0 ? { adoptedAt: record.adoptedAt } : {},
137
+ ...terminalDispositionFields(record)
138
+ };
139
+ }
140
+ function projectDeadLettered(record) {
141
+ return {
142
+ ...baseEnvelopeFields(record),
143
+ ...attemptFields(record),
144
+ state: "deadLettered",
145
+ pendingStatus: record.pendingStatus,
146
+ resultDigest: record.pendingResultDigest,
147
+ deadLetteredAt: record.deadLetteredAt,
148
+ persistenceFailureReason: record.persistenceFailureReason,
149
+ ...record.error !== void 0 ? { error: record.error } : {}
150
+ };
151
+ }
152
+ function projectTaskDetail(record) {
153
+ switch (record.state) {
154
+ case "queued":
155
+ return projectQueued(record);
156
+ case "leased":
157
+ return projectLeased(record);
158
+ case "completing":
159
+ return projectCompleting(record);
160
+ case "cancelling":
161
+ return projectCancelling(record);
162
+ case "terminal":
163
+ return projectTerminal(record);
164
+ case "deadLettered":
165
+ return projectDeadLettered(record);
166
+ default:
167
+ return record;
168
+ }
169
+ }
170
+ export const getTaskDetailOperation = defineOperation({
171
+ name: "weft.tasks.get",
172
+ mcpExposable: !1,
173
+ summary: "Get one task's full durable ledger state",
174
+ destructive: !1,
175
+ tags: ["Observability"],
176
+ inputSchema: getTaskDetailInput,
177
+ outputSchema: getTaskDetailOutputSchema,
178
+ access: {
179
+ kind: "scoped",
180
+ scopes: { kind: "anyOf", scopes: ["system:read"] }
181
+ },
182
+ producibleFaults: ["NotFound"],
183
+ discoverable: !0,
184
+ transports: { http: !0, jsonRpcHttp: !0, jsonRpcWebSocket: !0, jsonRpcStdio: !0 },
185
+ unknownKeyPolicy: { http: "strip", jsonRpc: "reject" },
186
+ invoke: async ({ input, engine }) => {
187
+ const raw = await engine.storage.get(taskLedgerKey(input.operationId));
188
+ if (raw === null)
189
+ raiseFault(getTaskDetailOperation, {
190
+ code: "NotFound",
191
+ message: `No task found for operation "${input.operationId}"`,
192
+ data: { resource: "task", identifier: input.operationId }
193
+ });
194
+ const decoded = decodeRemoteTaskRecord(raw);
195
+ if (decoded === null || decoded.operationId !== input.operationId)
196
+ raiseFault(getTaskDetailOperation, {
197
+ code: "EngineFailure",
198
+ message: `Task ledger record for operation "${input.operationId}" could not be decoded`,
199
+ data: {}
200
+ });
201
+ return projectTaskDetail(decoded);
202
+ }
203
+ }), getTaskDetailRestBinding = {
204
+ method: "GET",
205
+ path: "/v1/tasks/detail/:operationId",
206
+ pathParamNames: ["operationId"],
207
+ operationName: "weft.tasks.get",
208
+ inputSources: {
209
+ operationId: { kind: "path", pathParam: "operationId" }
210
+ },
211
+ extractInput: async (_request, pathParams) => ({
212
+ operationId: pathParams.operationId ?? ""
213
+ }),
214
+ success: { kind: "json", status: 200 }
215
+ };
@@ -1,10 +1,41 @@
1
1
  /**
2
2
  * `weft.tasks.diagnostics` operation + REST binding.
3
3
  *
4
- * Scans durable task records and live worker state to identify queue pressure,
5
- * stale in-flight work, retry storms, and worker capacity saturation. Results
6
- * are intentionally bounded and low-cardinality so operators can use them in a
7
- * dashboard without turning workflow or worker identifiers into metrics labels.
4
+ * Scans the durable task ledger (WFT-24 previously the retired
5
+ * `op:queued:`/`op:inflight:`/`op:resolved:`/`op:dead-letter:` keys, which
6
+ * nothing has written since the WFT-22 ledger cutover) and live worker state
7
+ * to identify queue pressure, stale in-flight work, retry storms, dead
8
+ * letters, and worker capacity saturation. Results are intentionally bounded
9
+ * and low-cardinality so operators can use them in a dashboard without
10
+ * turning workflow or worker identifiers into metrics labels.
11
+ *
12
+ * The output schema's field names and `kind`/`state` vocabulary are
13
+ * unchanged from the pre-ledger version — only the internal scan and
14
+ * classification logic changed — so existing dashboards built against this
15
+ * endpoint's shape keep working. `leased`, `completing`, and `cancelling`
16
+ * ledger states are all reported as diagnostic `state: 'inflight'`: they
17
+ * share the same lease-holder/heartbeat shape and the same operator
18
+ * question ("is a worker still making progress on this attempt?"), so
19
+ * exposing the ledger's more granular internal states here would add
20
+ * distinctions operators cannot act on differently.
21
+ *
22
+ * Retry-storm detection (`kind: 'retry-storm'`) no longer covers `terminal`
23
+ * records: `RemoteTaskTerminal` carries no `retryCount`/`requeueCount` (WFT-25
24
+ * deliberately dropped attempt-count history once a task resolves), so
25
+ * there is nothing left to detect a storm from once an attempt reaches a
26
+ * disposition. The `resolved` value in the `state` enum is kept in the
27
+ * output schema for backward compatibility but nothing produces it anymore.
28
+ * `dead-lettered` diagnostics are unaffected — that is a distinct, separate
29
+ * `kind`.
30
+ *
31
+ * Unlike the pre-ledger scan, the full ledger scan this operation performs
32
+ * is one combined keyspace across every state (queued through terminal),
33
+ * not separate per-state prefixes — there is no time-bounded history index
34
+ * to limit how many terminal records get walked past on the way to
35
+ * classifying the ones that still matter. Operators who dispatch high
36
+ * volumes of tasks and want this scan to stay cheap should set
37
+ * {@link ServeOptions.taskRetentionWindowMs} so adopted terminal records
38
+ * are reaped rather than accumulating indefinitely.
8
39
  *
9
40
  * @module server/operations/get-task-diagnostics
10
41
  */
@@ -30,8 +61,8 @@ declare const taskDiagnosticItemSchema: z.ZodObject<{
30
61
  state: z.ZodEnum<{
31
62
  "dead-lettered": "dead-lettered";
32
63
  queued: "queued";
33
- inflight: "inflight";
34
64
  resolved: "resolved";
65
+ inflight: "inflight";
35
66
  capacity: "capacity";
36
67
  }>;
37
68
  operationId: z.ZodOptional<z.ZodString>;
@@ -44,10 +75,7 @@ declare const taskDiagnosticItemSchema: z.ZodObject<{
44
75
  queueLatencyMs: z.ZodOptional<z.ZodNumber>;
45
76
  executionLatencyMs: z.ZodOptional<z.ZodNumber>;
46
77
  heartbeatAgeMs: z.ZodOptional<z.ZodNumber>;
47
- lastRequeueReason: z.ZodOptional<z.ZodEnum<{
48
- "visibility-timeout": "visibility-timeout";
49
- "worker-disconnect": "worker-disconnect";
50
- }>>;
78
+ lastRequeueReason: z.ZodOptional<z.ZodString>;
51
79
  resolutionReason: z.ZodOptional<z.ZodString>;
52
80
  deadLetteredAt: z.ZodOptional<z.ZodNumber>;
53
81
  deadLetterReason: z.ZodOptional<z.ZodLiteral<"result-resolution-storage-exhausted">>;
@@ -74,8 +102,8 @@ declare const getTaskDiagnosticsOutput: z.ZodObject<{
74
102
  state: z.ZodEnum<{
75
103
  "dead-lettered": "dead-lettered";
76
104
  queued: "queued";
77
- inflight: "inflight";
78
105
  resolved: "resolved";
106
+ inflight: "inflight";
79
107
  capacity: "capacity";
80
108
  }>;
81
109
  operationId: z.ZodOptional<z.ZodString>;
@@ -88,10 +116,7 @@ declare const getTaskDiagnosticsOutput: z.ZodObject<{
88
116
  queueLatencyMs: z.ZodOptional<z.ZodNumber>;
89
117
  executionLatencyMs: z.ZodOptional<z.ZodNumber>;
90
118
  heartbeatAgeMs: z.ZodOptional<z.ZodNumber>;
91
- lastRequeueReason: z.ZodOptional<z.ZodEnum<{
92
- "visibility-timeout": "visibility-timeout";
93
- "worker-disconnect": "worker-disconnect";
94
- }>>;
119
+ lastRequeueReason: z.ZodOptional<z.ZodString>;
95
120
  resolutionReason: z.ZodOptional<z.ZodString>;
96
121
  deadLetteredAt: z.ZodOptional<z.ZodNumber>;
97
122
  deadLetterReason: z.ZodOptional<z.ZodLiteral<"result-resolution-storage-exhausted">>;
@@ -146,7 +171,7 @@ export declare function createGetTaskDiagnosticsOperation(options?: GetTaskDiagn
146
171
  }, {
147
172
  items: {
148
173
  kind: "dead-lettered" | "stuck-queued" | "stale-inflight" | "retry-storm" | "all-workers-at-capacity";
149
- state: "dead-lettered" | "queued" | "inflight" | "resolved" | "capacity";
174
+ state: "dead-lettered" | "queued" | "resolved" | "inflight" | "capacity";
150
175
  retryCount: number;
151
176
  requeueCount: number;
152
177
  evidence: string[];
@@ -158,7 +183,7 @@ export declare function createGetTaskDiagnosticsOperation(options?: GetTaskDiagn
158
183
  queueLatencyMs?: number | undefined;
159
184
  executionLatencyMs?: number | undefined;
160
185
  heartbeatAgeMs?: number | undefined;
161
- lastRequeueReason?: "visibility-timeout" | "worker-disconnect" | undefined;
186
+ lastRequeueReason?: string | undefined;
162
187
  resolutionReason?: string | undefined;
163
188
  deadLetteredAt?: number | undefined;
164
189
  deadLetterReason?: "result-resolution-storage-exhausted" | undefined;
@@ -185,7 +210,7 @@ export declare const getTaskDiagnosticsOperation: import("../operation-catalog.t
185
210
  }, {
186
211
  items: {
187
212
  kind: "dead-lettered" | "stuck-queued" | "stale-inflight" | "retry-storm" | "all-workers-at-capacity";
188
- state: "dead-lettered" | "queued" | "inflight" | "resolved" | "capacity";
213
+ state: "dead-lettered" | "queued" | "resolved" | "inflight" | "capacity";
189
214
  retryCount: number;
190
215
  requeueCount: number;
191
216
  evidence: string[];
@@ -197,7 +222,7 @@ export declare const getTaskDiagnosticsOperation: import("../operation-catalog.t
197
222
  queueLatencyMs?: number | undefined;
198
223
  executionLatencyMs?: number | undefined;
199
224
  heartbeatAgeMs?: number | undefined;
200
- lastRequeueReason?: "visibility-timeout" | "worker-disconnect" | undefined;
225
+ lastRequeueReason?: string | undefined;
201
226
  resolutionReason?: string | undefined;
202
227
  deadLetteredAt?: number | undefined;
203
228
  deadLetterReason?: "result-resolution-storage-exhausted" | undefined;