/** * `weft.tasks.diagnostics` operation + REST binding. * * Scans the durable task ledger (WFT-24 — previously the retired * `op:queued:`/`op:inflight:`/`op:resolved:`/`op:dead-letter:` keys, which * nothing has written since the WFT-22 ledger cutover) and live worker state * to identify queue pressure, expected delayed attempts, stale in-flight * work, retry storms, elapsed terminal non-adoption, dead letters, and worker * capacity saturation. Results are intentionally bounded and low-cardinality * so operators can use them in a dashboard without turning workflow or worker * identifiers into metrics labels. * * `leased`, `completing`, and `cancelling` ledger states are all reported as * diagnostic `state: 'inflight'`: they share the same lease-holder/heartbeat * shape and the same operator question ("is a worker still making progress on * this attempt?"), so exposing the ledger's more granular internal states * here would add distinctions operators cannot act on differently. Terminal * records reported as `unadopted-terminal` use the coarse `resolved` state and * expose no attempt-count history. * * Retry-storm detection (`kind: 'retry-storm'`) no longer covers `terminal` * records: `RemoteTaskTerminal` carries no `retryCount`/`requeueCount` (WFT-25 * deliberately dropped attempt-count history once a task resolves), so * there is nothing left to detect a storm from once an attempt reaches a * disposition. Terminal records are classified only by elapsed non-adoption; * that diagnostic does not claim an adoption attempt failed. `dead-lettered` * diagnostics remain a distinct kind for result-persistence exhaustion. * * Unlike the pre-ledger scan, the full ledger scan this operation performs * is one combined keyspace across every state (queued through terminal), * not separate per-state prefixes — there is no time-bounded history index * to limit how many terminal records get walked past on the way to * classifying the ones that still matter. Operators who dispatch high * volumes of tasks and want this scan to stay cheap should set * {@link ServeOptions.taskRetentionWindowMs} so adopted terminal records * are reaped rather than accumulating indefinitely. * * @module server/operations/get-task-diagnostics */ import { z } from 'zod'; import type { WorkerRegistry } from '../../worker/registry.ts'; import type { UnknownRestBinding } from '../rest-bindings.ts'; import type { TaskQueue } from '../task-queue.ts'; declare const taskDiagnosticKindSchema: z.ZodEnum<{ "dead-lettered": "dead-lettered"; "stuck-queued": "stuck-queued"; "stale-inflight": "stale-inflight"; "retry-storm": "retry-storm"; "all-workers-at-capacity": "all-workers-at-capacity"; delayed: "delayed"; "unadopted-terminal": "unadopted-terminal"; }>; declare const taskDiagnosticItemSchema: z.ZodUnion; state: z.ZodEnum<{ "dead-lettered": "dead-lettered"; resolved: "resolved"; queued: "queued"; inflight: "inflight"; capacity: "capacity"; }>; operationId: z.ZodOptional; workflowId: z.ZodOptional; activityName: z.ZodOptional; queue: z.ZodOptional; workerId: z.ZodOptional; retryCount: z.ZodNumber; requeueCount: z.ZodNumber; queueLatencyMs: z.ZodOptional; executionLatencyMs: z.ZodOptional; heartbeatAgeMs: z.ZodOptional; lastRequeueReason: z.ZodOptional; resolutionReason: z.ZodOptional; deadLetteredAt: z.ZodOptional; deadLetterReason: z.ZodOptional>; storageError: z.ZodOptional; retryAttempts: z.ZodOptional; evidence: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"delayed">; state: z.ZodLiteral<"queued">; operationId: z.ZodString; workflowId: z.ZodOptional; queue: z.ZodString; retryCount: z.ZodNumber; requeueCount: z.ZodNumber; availableAt: z.ZodNumber; evidence: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"unadopted-terminal">; state: z.ZodLiteral<"resolved">; operationId: z.ZodString; workflowId: z.ZodOptional; queue: z.ZodString; terminalAt: z.ZodNumber; adopted: z.ZodLiteral; evidence: z.ZodArray; }, z.core.$strict>]>; declare const taskDiagnosticsSummarySchema: z.ZodObject<{ stuckQueued: z.ZodNumber; staleInflight: z.ZodNumber; retryStorms: z.ZodNumber; allWorkersAtCapacity: z.ZodNumber; deadLettered: z.ZodNumber; delayed: z.ZodNumber; unadoptedTerminal: z.ZodNumber; }, z.core.$strict>; declare const getTaskDiagnosticsOutput: z.ZodObject<{ items: z.ZodArray; state: z.ZodEnum<{ "dead-lettered": "dead-lettered"; resolved: "resolved"; queued: "queued"; inflight: "inflight"; capacity: "capacity"; }>; operationId: z.ZodOptional; workflowId: z.ZodOptional; activityName: z.ZodOptional; queue: z.ZodOptional; workerId: z.ZodOptional; retryCount: z.ZodNumber; requeueCount: z.ZodNumber; queueLatencyMs: z.ZodOptional; executionLatencyMs: z.ZodOptional; heartbeatAgeMs: z.ZodOptional; lastRequeueReason: z.ZodOptional; resolutionReason: z.ZodOptional; deadLetteredAt: z.ZodOptional; deadLetterReason: z.ZodOptional>; storageError: z.ZodOptional; retryAttempts: z.ZodOptional; evidence: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"delayed">; state: z.ZodLiteral<"queued">; operationId: z.ZodString; workflowId: z.ZodOptional; queue: z.ZodString; retryCount: z.ZodNumber; requeueCount: z.ZodNumber; availableAt: z.ZodNumber; evidence: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"unadopted-terminal">; state: z.ZodLiteral<"resolved">; operationId: z.ZodString; workflowId: z.ZodOptional; queue: z.ZodString; terminalAt: z.ZodNumber; adopted: z.ZodLiteral; evidence: z.ZodArray; }, z.core.$strict>]>>; summary: z.ZodObject<{ stuckQueued: z.ZodNumber; staleInflight: z.ZodNumber; retryStorms: z.ZodNumber; allWorkersAtCapacity: z.ZodNumber; deadLettered: z.ZodNumber; delayed: z.ZodNumber; unadoptedTerminal: z.ZodNumber; }, z.core.$strict>; limit: z.ZodNumber; }, z.core.$strict>; declare const getTaskDiagnosticsInput: z.ZodObject<{ operationId: z.ZodOptional; workflowId: z.ZodOptional; queue: z.ZodOptional; staleQueuedAfterMs: z.ZodDefault; staleHeartbeatAfterMs: z.ZodDefault; retryStormMinimumAttempts: z.ZodDefault; includeExpectedDelayed: z.ZodDefault; unadoptedAfterMs: z.ZodDefault; limit: z.ZodDefault; }, z.core.$strip>; declare const clearTaskDeadLetterInput: z.ZodObject<{ operationId: z.ZodString; }, z.core.$strip>; declare const okOutput: z.ZodObject<{ ok: z.ZodLiteral; }, z.core.$strict>; export type GetTaskDiagnosticsInput = z.infer; export type TaskDiagnosticKind = z.infer; export type TaskDiagnosticItem = z.infer; export type TaskDiagnosticsSummary = z.infer; export type GetTaskDiagnosticsOutput = z.infer; export type ClearTaskDeadLetterInput = z.infer; export type ClearTaskDeadLetterOutput = z.infer; interface GetTaskDiagnosticsOptions { registry?: WorkerRegistry | undefined; taskQueue?: TaskQueue | undefined; now?: (() => number) | undefined; } export declare function createGetTaskDiagnosticsOperation(options?: GetTaskDiagnosticsOptions): import("../operation-catalog.ts").OperationDefinition<{ staleQueuedAfterMs: number; staleHeartbeatAfterMs: number; retryStormMinimumAttempts: number; includeExpectedDelayed: boolean; unadoptedAfterMs: number; limit: number; operationId?: string | undefined; workflowId?: string | undefined; queue?: string | undefined; }, { items: ({ kind: "dead-lettered" | "stuck-queued" | "stale-inflight" | "retry-storm" | "all-workers-at-capacity"; state: "dead-lettered" | "resolved" | "queued" | "inflight" | "capacity"; retryCount: number; requeueCount: number; evidence: string[]; operationId?: string | undefined; workflowId?: string | undefined; activityName?: string | undefined; queue?: string | undefined; workerId?: string | undefined; queueLatencyMs?: number | undefined; executionLatencyMs?: number | undefined; heartbeatAgeMs?: number | undefined; lastRequeueReason?: string | undefined; resolutionReason?: string | undefined; deadLetteredAt?: number | undefined; deadLetterReason?: "result-resolution-storage-exhausted" | undefined; storageError?: string | undefined; retryAttempts?: number | undefined; } | { kind: "delayed"; state: "queued"; operationId: string; queue: string; retryCount: number; requeueCount: number; availableAt: number; evidence: string[]; workflowId?: string | undefined; } | { kind: "unadopted-terminal"; state: "resolved"; operationId: string; queue: string; terminalAt: number; adopted: false; evidence: string[]; workflowId?: string | undefined; })[]; summary: { stuckQueued: number; staleInflight: number; retryStorms: number; allWorkersAtCapacity: number; deadLettered: number; delayed: number; unadoptedTerminal: number; }; limit: number; }, unknown>; export declare const getTaskDiagnosticsOperation: import("../operation-catalog.ts").OperationDefinition<{ staleQueuedAfterMs: number; staleHeartbeatAfterMs: number; retryStormMinimumAttempts: number; includeExpectedDelayed: boolean; unadoptedAfterMs: number; limit: number; operationId?: string | undefined; workflowId?: string | undefined; queue?: string | undefined; }, { items: ({ kind: "dead-lettered" | "stuck-queued" | "stale-inflight" | "retry-storm" | "all-workers-at-capacity"; state: "dead-lettered" | "resolved" | "queued" | "inflight" | "capacity"; retryCount: number; requeueCount: number; evidence: string[]; operationId?: string | undefined; workflowId?: string | undefined; activityName?: string | undefined; queue?: string | undefined; workerId?: string | undefined; queueLatencyMs?: number | undefined; executionLatencyMs?: number | undefined; heartbeatAgeMs?: number | undefined; lastRequeueReason?: string | undefined; resolutionReason?: string | undefined; deadLetteredAt?: number | undefined; deadLetterReason?: "result-resolution-storage-exhausted" | undefined; storageError?: string | undefined; retryAttempts?: number | undefined; } | { kind: "delayed"; state: "queued"; operationId: string; queue: string; retryCount: number; requeueCount: number; availableAt: number; evidence: string[]; workflowId?: string | undefined; } | { kind: "unadopted-terminal"; state: "resolved"; operationId: string; queue: string; terminalAt: number; adopted: false; evidence: string[]; workflowId?: string | undefined; })[]; summary: { stuckQueued: number; staleInflight: number; retryStorms: number; allWorkersAtCapacity: number; deadLettered: number; delayed: number; unadoptedTerminal: number; }; limit: number; }, unknown>; export declare const clearTaskDeadLetterOperation: import("../operation-catalog.ts").OperationDefinition<{ operationId: string; }, { ok: true; }, unknown>; export declare const getTaskDiagnosticsRestBinding: UnknownRestBinding; export declare const clearTaskDeadLetterRestBinding: UnknownRestBinding; export {};