/** * Startup task-ledger recovery (WFT-23). * * A one-shot full scan of the durable `task-ledger:` keyspace, run once per * `serve()` call before the recovery gate on `ServerContext.taskLedgerRecovery` * opens (see `buildServerContext` in `serve-internals.ts`). Reconstructs the * in-memory registry, deadline tracker, and task-queue indexes that * `restoreInflightTasks` used to rebuild from the retired `op:inflight:` * keyspace — those indexes are process-local caches; the ledger is the * durable authority, so nothing here writes state, only rehydrates memory to * match what storage already says. * * One branch per non-terminal state: * - `queued` — redispatch through the normal dispatch path so a lost * `scheduleDelayedDispatch` timer (or a record this process * never dispatched at all) still becomes runnable. * - `leased`, deadline still in the future — rehydrate registry ownership * and the deadline tracker so heartbeats and completions * from the original worker are recognized after reconnect. * - `leased`, deadline already passed — requeue or exhaust through the same * `reassignOrExpireTask` CAS path `scanExpiredTasks` and * `reconcileOrphanedRecords` use; deletion is never correct * here (see `RequeueExpiredAttemptInput`'s contract). * - `completing` — rehydrate registry ownership only. The pending result * value isn't persisted (only its digest), so recovery * cannot resolve this state itself; only the worker's * redelivered `taskResult`, landing on * `commitTaskLedgerCompletion`'s crash-resumption branch, * can. Recovery's job is to make sure that redelivery still * passes the WebSocket ownership guard after a restart. * - `cancelling` — rehydrate registry ownership only, for the same reason: * nothing in the current runtime calls `commitCancellation` * yet (a future project's scope), so there is no action to * resume, only ownership to preserve. * - `terminal`, `deadLettered` — already resolved; skipped. * * A single corrupt or unrecognized record is logged and skipped — ordinary * data hygiene, not a recovery failure. A failure in the scan itself (the * storage iterator throwing) propagates and rejects the whole gate: per the * project brief, "a scan failure leaves the remote worker plane unhealthy * and prevents new claims rather than logging and continuing with partial * indexes." * * @module server/runtime/task-ledger-recovery */ import type { ServeOptions } from '../index.ts'; import type { ServerContext } from './context.ts'; /** * Run startup task-ledger recovery to completion. Resolves once every * non-terminal record has been reconstructed; rejects if the scan itself * failed. Callers gate task-plane entry points on the resulting promise * rather than awaiting this directly from within another recovery-time * scan — see `ServerContext.taskLedgerRecovery`'s doc comment. */ export declare function runTaskLedgerRecovery(context: ServerContext, options: ServeOptions): Promise;