import { type AcquireResult, type LaneId, type LaneStatus, type LaneTicket, type LaneCooldown, type LaneCooldownReason } from './lane-queue.js'; export interface LaneCoordinatorPort { readonly coordinator: 'local-sqlite' | 'cloudflare-durable-object'; acquire(params: { lane: LaneId; project: string; scene?: number | null; promptHash?: string | null; limit: number | null; ttlSec?: number; holder?: string; }): AcquireResult; status(lane: LaneId, limit?: number | null, options?: { includeReceipts?: boolean; }): LaneStatus; heartbeat(ticketId: string, ttlSec?: number): boolean; release(ticketId: string, lane?: LaneId, limit?: number | null, outcome?: LaneReleaseOutcome): boolean; /** `contentHashVerified`: the coordinator recomputed the payload hash and it matched; null from a coordinator too old to check. */ recordReceipt?(receipt: SharedLaneReceipt): { stored: boolean; deduped: boolean; contentHashVerified?: boolean | null; }; /** The render log (remote coordinator only): done tickets newest first. */ history?(lane: LaneId, options?: { limit?: number; project?: string; }): LaneHistory; /** Pause the lane for every caller (see LaneCooldown). Only an active lease may. */ cooldown?(ticketId: string, lane: LaneId, reasonCode: LaneCooldownReason, retryAfterSeconds: number): LaneCooldown; } /** What the driver saw when it gave the slot back — the render log's one word per * draw (2026-09-04). `expired` is the coordinator's own verdict, never sent. */ export declare const LANE_OUTCOMES: readonly ["completed", "failed", "timeout", "lease-lost", "not-submitted", "slot-busy", "abandoned"]; export type LaneOutcome = (typeof LANE_OUTCOMES)[number]; export interface LaneReleaseOutcome { outcome: LaneOutcome; providerJobId?: string; note?: string; } export interface LaneHistory { lane: LaneId; tickets: LaneTicket[]; terminalRetained: number; coordinator: string; } export type SharedLaneReceiptPhase = 'lease-acquired' | 'references-applied' | 'provider-submitted' | 'provider-terminal'; export interface SharedLaneReceipt { lane: string; ticketId: string; receiptId: string; contentHash: string; phase: SharedLaneReceiptPhase; payload: Record; } export interface RemoteLaneCoordinatorOptions { url: string; token: string; machineId: string; timeoutMs?: number; request?: RemoteLaneRequest; } export type RemoteLaneRequest = (input: { url: string; token: string; timeoutMs: number; body: Record; }) => { status: number; text: string; }; export interface CreateLaneCoordinatorOptions { env?: NodeJS.ProcessEnv; dbPath?: string; } /** One short attempt: see RemoteLaneCoordinator.recordReceipt. */ export declare const RECEIPT_TIMEOUT_MS = 3000; export declare function sharedLaneReceiptContentHash(payload: Record): string; export declare class RemoteLaneCoordinator implements LaneCoordinatorPort { readonly coordinator: "cloudflare-durable-object"; private readonly baseUrl; private readonly token; private readonly machineId; private readonly timeoutMs; private readonly request; private readonly claimId; private readonly namedClaim; constructor(options: RemoteLaneCoordinatorOptions); private call; acquire(params: Parameters[0]): AcquireResult; status(lane: LaneId, limit?: number | null, options?: { includeReceipts?: boolean; }): LaneStatus; cooldown(ticketId: string, lane: LaneId, reasonCode: LaneCooldownReason, retryAfterSeconds: number): LaneCooldown; heartbeat(ticketId: string, ttlSec?: number): boolean; release(ticketId: string, lane?: LaneId, limit?: number | null, outcome?: LaneReleaseOutcome): boolean; history(lane: LaneId, options?: { limit?: number; project?: string; }): LaneHistory; recordReceipt(receipt: SharedLaneReceipt): { stored: boolean; deduped: boolean; contentHashVerified: boolean | null; }; verify(lane: string, limit: number): LaneStatus; } export declare function sharedLaneCoordinatorRequired(env?: NodeJS.ProcessEnv): boolean; export declare function createLaneCoordinator(options?: CreateLaneCoordinatorOptions): LaneCoordinatorPort; //# sourceMappingURL=lane-coordinator.d.ts.map