import { type Conversation, type Executor } from "./protocol.js"; import type { TerminalControlRef } from "./terminal-agent-adapter.js"; import { type TerminalZeroInputAbortOutcome, type TerminalZeroInputFailureKind } from "./terminal-dispatch-abort.js"; import { type TerminalDispatchLedgerDocument, type TerminalOrdinaryDispatchStatus } from "./terminal-dispatch-ledger-codec.js"; import { terminalDispatchTextSummary as textSummary } from "./terminal-dispatch-receipt.js"; import type { TerminalSubmissionAcceptanceEvidence } from "./terminal-submission-facts.js"; export interface TerminalDispatchMessage { id: string; type: "task" | "answer"; body: string; } export interface TerminalDispatchAuditEvent { ts: string; conversation_id: string; event: string; message_id?: string; executor?: Executor; terminal_control?: TerminalControlRef; source_conversation_id?: string; agent?: Executor["kind"]; request_hash?: string; dispatcher_pid?: number; error?: ReturnType; delivered?: boolean; terminal_input_dispatched?: boolean; agent_acceptance?: "proven" | "unproven"; do_not_retry?: boolean; delivery_receipt?: TerminalOrdinaryDispatchStatus; safe_to_retry?: boolean; terminal_input_started?: false; message?: ReturnType; payload?: ReturnType; } export type TerminalDispatchAcceptance = { outcome: "agent_accepted"; evidence: TerminalSubmissionAcceptanceEvidence; } | { outcome: "pending_acceptance"; } | { outcome: "not_accepted"; reason: string; } | { outcome: "uncertain"; reason: string; }; export interface TerminalDispatchApplicationContext { originalConversation: Conversation; preparedConversation: Conversation; message: TerminalDispatchMessage; executor: Executor; terminalControl: TerminalControlRef; receiptTerminalControl: TerminalControlRef | undefined; requestText: string; requestHash: string; preparedAt: string; statePath: string; eventLogPath: string; previousGenerationId?: string; dispatcherPid: number; storeDir?: string; recordRawAttachmentAfterSend: boolean; ledgerBindingFields(conversation: Conversation): TerminalDispatchLedgerDocument; } export interface TerminalDispatchApplicationPorts { synchronizeStageProgress(conversation: Conversation, stage: "text_injected" | "enter_dispatched", at: string): void; state: { save(conversation: Conversation): void; }; ledger: { save(ledger: TerminalDispatchLedgerDocument, phase?: "ordinary" | "final"): void; restore(reason: string, terminalInputNotStartedAt?: string): void; }; audit: { append(event: TerminalDispatchAuditEvent): void; appendPreparedMessage(): void; log(level: "info" | "warn" | "error", event: string, fields: { [key: string]: unknown; }): void; recordBookkeepingFailure(phase: string, error: unknown): void; recordPersistenceFailure(phase: string, error: unknown, conversation: Conversation): void; }; rollbackBeforeInput(): boolean; } export interface RecordedTerminalZeroInputAbort { outcome: TerminalZeroInputAbortOutcome; reportedConversation: Conversation; receiptConversation: Conversation; errorMessage: string; dispatchLedgerRestored: boolean; abortedStatePersisted: boolean; rawAttachRolledBack: boolean; } /** * Orders already-authorized ordinary dispatch writes. Locks, terminal I/O, * acceptance observation, raw persistence adapters, and presentation stay in * the composition root. */ export declare class TerminalDispatchApplication { #private; constructor(context: TerminalDispatchApplicationContext, ports: TerminalDispatchApplicationPorts); persistPrepared(): void; recordPreparedBookkeeping(recordPreparedEvent: boolean, injectFailure?: boolean, validatePreparedEvent?: () => void): void; recordTransportStage(stage: "text_injected" | "enter_dispatched", at: string, afterDurable: () => Promise | void): Promise; applyIdentityFailure(at: string, reason: string, beforePersist?: (conversation: Conversation) => void): Conversation; applyAcceptance(submittedBase: Conversation, acceptance: TerminalDispatchAcceptance, resolvedAt: string): { conversation: Conversation; status: TerminalOrdinaryDispatchStatus; }; applyUncertain(at: string, error: unknown, proof?: { enterNotAttemptedAt?: string; enterNotAttemptedReason?: "pre_key_failure"; }): Conversation; recordZeroInputAbort({ failureKind, error, abortedAt, injectStatePersistenceFailure }: { failureKind: TerminalZeroInputFailureKind; error: unknown; abortedAt: string; injectStatePersistenceFailure?: boolean; }): RecordedTerminalZeroInputAbort; recordPostSubmissionBookkeeping(conversation: Conversation, agentAccepted: boolean, nowIso: () => string): string | undefined; }