import { type Clock, type JournalKind, type JournalRecord, type KernelPaths } from "./types.js"; export interface AppendJournalInput { readonly paths: KernelPaths; readonly runId: string; readonly kind: JournalKind; readonly payload: Readonly>; readonly operationId?: string; readonly clock: Clock; /** When true (default), duplicate operation_id returns the existing record (exactly-once). */ readonly idempotent?: boolean; } export interface IngressRejection { readonly rejected: true; readonly reason: string; readonly operation_id: string; } export interface JournalReplayResult { readonly records: readonly JournalRecord[]; readonly byOperationId: ReadonlyMap; readonly tip_hash: string | null; readonly tip_sequence: number; } export declare function appendJournal(input: AppendJournalInput): JournalRecord; /** * Append one journal record. Caller must hold the kernel lock. * Allocates a monotonic per-run sequence, chains previous content hash, and * indexes operation_id for O(1) idempotent lookup (no full journal scan). */ export declare function appendJournalUnlocked(input: AppendJournalInput): JournalRecord; export declare function readJournalRecord(paths: KernelPaths, runId: string, sequence: number): JournalRecord; export interface JournalRecoveryReport { readonly repaired: boolean; readonly reason: string | null; readonly tip_sequence: number; } /** * Crash cut-point recovery for incomplete appends: * - record written / index missing * - record + index written / head missing or lagging * Completes durable index+head from authoritative record files. O(n) only on mismatch. */ export declare function recoverJournalConsistency(paths: KernelPaths, runId: string): JournalRecoveryReport; /** * O(1) mismatch probe: incomplete cut points leave either an orphan next record * or a tip record without a durable head/index. Full rebuild is not performed here. */ export declare function detectJournalMismatchO1(paths: KernelPaths, runId: string): boolean; export declare function recoverJournalConsistencyUnlocked(paths: KernelPaths, runId: string): JournalRecoveryReport; /** Ordered list for one run by sequence; verifies each record hash but not full chain continuity. */ export declare function listJournalRecords(paths: KernelPaths, runId: string): JournalRecord[]; /** * O(1) idempotency lookup via durable ops/.json index. * Does not scan journal records. */ export declare function findByOperationId(paths: KernelPaths, operationId: string, runId: string): JournalRecord | undefined; /** * Replay one run strictly by sequence and verify the hash chain. * Gaps, hash mismatches, previous_hash breaks, or duplicate sequences fail closed. */ export declare function replayJournal(paths: KernelPaths, runId: string): JournalReplayResult; /** * Bound untrusted ingress (hooks/GitHub) before journal write. * Oversized or non-object payloads are rejected and journaled as ingress_rejected. */ export declare function acceptIngressPayload(paths: KernelPaths, runId: string, kind: JournalKind, raw: unknown, clock: Clock, operationId?: string): JournalRecord | IngressRejection; export declare function parseJournalRecord(value: unknown, label: string): JournalRecord; export declare function journalHashBody(input: { readonly schema_version: 2; readonly protocol_version: 2; readonly record_id: string; readonly sequence: number; readonly previous_hash: string | null; readonly operation_id: string; readonly kind: string; readonly recorded_at: string; readonly run_id: string; readonly payload: unknown; }): Record; export declare function sequenceFileName(sequence: number): string; export declare function journalRecordPath(paths: KernelPaths, runId: string, sequence: number): string; export declare function journalRecordsRoot(paths: KernelPaths, runId: string): string; export declare function journalOpIndexPath(paths: KernelPaths, runId: string, operationId: string): string; export declare function journalHeadPath(paths: KernelPaths, runId: string): string;