import type { AgentRuntime, RunningOrg } from './daemon.js'; /** Checkpoint state for a single agent role */ export interface RoleCheckpoint { /** Message queue content (actual messages, not just count) */ mailboxQueue: string[]; /** Whether the mailbox was closed */ mailboxClosed: boolean; /** Why it was closed, if given a reason (e.g. 'token-budget') — see * isRecoverableCloseReason in mailbox.ts; resume checks this before * re-closing the restored mailbox. */ mailboxCloseReason?: string; /** Token usage counter from policy engine */ tokensUsed: number; /** Cost tracking */ costUsd: number; /** Last message ID for threading */ lastMessageId?: string; /** Session ID for SDK resume */ sessionId?: string; /** Agent status */ status: 'running' | 'ended' | 'crashed'; /** Error message if crashed */ error?: string; /** Terminal scrollback — last N lines of agent output. */ scrollback?: string[]; } /** Full checkpoint state for an org */ export interface OrgCheckpoint { /** R6: schema version — bumped on any breaking shape change so a future * consumer can detect an old-shape checkpoint instead of failing the * checksum and silently returning null. */ version: number; status: 'running' | 'stopped' | 'crashed'; run: string; pid: number; updated: string; /** Per-role checkpoint state */ roleState: Record; /** Roles not yet spawned (lazy spawn) */ pendingRoles: string[]; /** Roles that failed resource gates and won't spawn */ abandonedRoles: string[]; /** Checksum for state validation */ checksum: string; } /** Current checkpoint format version. Bump on breaking shape changes. */ export declare const CHECKPOINT_VERSION = 1; /** Checkpoint TTL config */ export declare const CHECKPOINT_TTL_MS: number; /** * Extract full checkpoint state from a RunningOrg * Called by persistState() to capture complete state for resume */ export declare function captureCheckpoint(org: RunningOrg, status?: 'running' | 'stopped' | 'crashed'): OrgCheckpoint; /** * Validate checkpoint integrity using checksum * Returns true if checksum matches AND the schema version is current. * * R6: a version field was added so future shape changes can be detected * explicitly. Old checkpoints (no version field) fail with a clear cause * instead of the silent checksum-mismatch → null return that masked the * real reason resume was impossible. */ export declare function validateCheckpoint(checkpoint: OrgCheckpoint): boolean; /** * Check if checkpoint has expired based on TTL * Returns true if checkpoint is stale and should not be used */ export declare function isCheckpointExpired(checkpoint: OrgCheckpoint, ttlMs?: number): boolean; /** * Generate checksum over checkpoint state. * * Uses a stable recursive stringify so semantically-equal checkpoints * (same keys + values, regardless of insertion order) hash identically. * Hashed with SHA-256 (truncated to 16 hex chars = 64 bits — plenty for * tamper detection across realistic checkpoint counts). * * T3 (and a real latent bug): the previous implementation called * `JSON.stringify(state, Object.keys(state).sort())`. Passing an array * as the second argument makes it a *whitelist* — but JSON.stringify * applies that whitelist at every level, not just the top. Since nested * keys like `tokensUsed` / `mailboxQueue` aren't in the top-level keys * list, they were silently stripped from the canonical form. Result: the * checksum was identical for any two checkpoints sharing the same * top-level shape, regardless of roleState values — validateCheckpoint * provided ZERO integrity guarantee. */ export declare function generateChecksum(state: Omit): string; /** * Restore mailbox queue from checkpoint * Replays messages into the mailbox in order */ export declare function restoreMailboxQueue(runtime: AgentRuntime, queue: string[]): void; /** * Merge checkpoint state into running org * Used for resume operations to restore previous state * * NOT currently called from production code — daemon.ts's spawnRole builds * each role's mailbox inline (its own roleCheckpoint-driven restore logic, * duplicating the mailboxClosed/mailboxCloseReason handling below) rather * than calling this. Exercised today only by tests. If you change the * recoverable-close handling here, change it in daemon.ts's spawnRole too — * see isRecoverableCloseReason's doc comment in mailbox.ts. */ export declare function mergeCheckpoint(org: RunningOrg, checkpoint: OrgCheckpoint, restoreMailboxes?: boolean, restorePolicy?: boolean): void; //# sourceMappingURL=checkpoint.d.ts.map