/** * Bounded prompt reconciliation state for canonical Q26 `turn.result` with * `kind: "prompt"`, plus the legacy `turn.prompt_status` alias. * * Separate from the lifecycle delivery buffers (promptSubmissions / * promptTerminalTombstones), which exist to deliver frames and intentionally * forget outcomes. This record preserves accepted/in_flight/terminal_ok/failed * plus bounded sanitized failure metadata so a caller can reconcile a prior * `turn.prompt` after disconnect/reconnect. * * Semantics (public contract, mirrored in sdk/prompt-status.ts): * - Active records are NEVER converted to terminal by age or capacity. * - Terminal records are bounded to TERMINAL_CAPACITY and evicted * oldest-terminal-first by terminalAt; only then * does a lookup honestly report `unknown`. * - Process-local durability floor is the live session process: restart means `unknown`. * Session-scoped durable retention (kind-aware store) is provided by reconciliation-store.ts (#3032). * - The clientRef index is session-runtime scoped; a ref conflicts only while * retained and must never be reused as a retry mechanism. * - Terminal transitions settle once: first terminal outcome wins. A late * `agent_failed` may still attach its sanitized reason to an already-terminal * record that has none, but never changes status, terminalAt, or retention. */ import { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure } from "../prompt-failure"; import type { ReceiptState } from "../receipt-state"; export { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure }; export declare const PROMPT_RECONCILIATION_ACTIVE_CAPACITY = 128; export declare const PROMPT_RECONCILIATION_TERMINAL_CAPACITY = 256; export type PromptReconciliationStatus = "accepted" | "in_flight" | "terminal_ok" | "failed"; export interface PromptCorrelation { commandId: string; turnId: string; } export interface PromptReconciliationRecord extends PromptCorrelation { clientRef?: string; status: PromptReconciliationStatus; error?: { code: string; message: string; }; acceptedAt: number; startedAt?: number; terminalAt?: number; receiptState?: Exclude; } export type TurnPromptReconciliation = { status: "accepted"; receiptState: "absent"; commandId: string; turnId: string; clientRef?: string; acceptedAt: number; } | { status: "in_flight"; receiptState: "absent"; commandId: string; turnId: string; clientRef?: string; acceptedAt: number; startedAt: number; } | { status: "terminal_ok"; receiptState: Exclude; commandId: string; turnId: string; clientRef?: string; acceptedAt: number; startedAt?: number; terminalAt: number; /** Present when a late `agent_failed` supplied the only failure reason. */ error?: { code: string; message: string; }; } | { status: "failed"; receiptState: Exclude; commandId: string; turnId: string; clientRef?: string; acceptedAt: number; startedAt?: number; terminalAt: number; error: { code: string; message: string; }; } | { status: "unknown"; receiptState: "unknown"; }; export interface PromptReconciliation { /** Fail-closed admission BEFORE any execution; holds an identity-bound reservation. */ admit(clientRef?: string): void; /** Discard one admission reservation without creating a record (rejection/cancellation). */ releaseAdmission(clientRef?: string): void; /** Transition a reservation into the accepted record at preflight acceptance. */ noteAccepted(correlation: PromptCorrelation, clientRef?: string): void; /** Lifecycle transition; terminal outcomes settle exactly once. */ noteTransition(correlation: PromptCorrelation | undefined, frame: { type: "agent_start"; } | { type: "agent_end"; finalText?: string; } | { type: "agent_failed"; error: unknown; finalText?: string; }): void; lookup(selector: { commandId?: string; turnId?: string; clientRef?: string; }): TurnPromptReconciliation; cleanup(): void; activeCount(): number; } export declare function createPromptReconciliation(options?: { now?: () => number; }): PromptReconciliation;