/** * One-time, read-only-to-the-source archive for retired v2 workflow runs. * * The archive deliberately stores both the byte-exact legacy tree and the * current ops projection. The legacy replay implementation can be deleted only * after `verifyV2RunArchive(..., { sourceRunsDir })` proves that both views * still match the live source. */ import { type V2RunArchiveContent, type V2RunArchiveManifest, type V2RunRetirementReceipt } from './v2-run-archive-schema.js'; export type V2RunArchiveCommitPhase = 'after-first-capture' | 'after-copy' | 'after-second-capture' | 'after-manifest' | 'after-publish' | 'after-commit-marker'; export type V2RunRetirementPhase = 'after-first-source-verification' | 'before-source-rename' | 'after-source-rename' | 'after-quarantine-verification' | 'after-retirement-receipt'; export declare class V2RunArchiveError extends Error { readonly code: string; constructor(code: string, message: string); } export interface V2RunArchivePlan { sourceRunsDir: string; content: V2RunArchiveContent; runCount: number; residualCount: number; totalPayloadBytes: number; } export interface CommitV2RunArchiveInput { runsDir: string; archiveBaseDir: string; now?: Date; /** Crash-injection seam. Production callers omit it. */ onPhase?: (phase: V2RunArchiveCommitPhase) => void | Promise; } export interface CommitV2RunArchiveResult { archiveDir: string; manifest: V2RunArchiveManifest; reused: boolean; verification: V2RunArchiveVerification; } export interface V2RunArchiveVerification { archiveDir: string; manifest: V2RunArchiveManifest; staticVerified: true; sourceVerified: boolean; fileCount: number; totalBytes: number; } export interface VerifyV2RunArchiveInput { archiveDir: string; /** When provided, also require byte/projection parity with the live source. */ sourceRunsDir?: string; /** Publication recovery uses static verification before COMMITTED exists. */ allowMissingCommitMarker?: boolean; } export interface RetireV2RunSourceInput { runsDir: string; archiveBaseDir: string; archiveDir: string; daemonStoppedAcknowledged: boolean; now?: Date; /** Crash/race-injection seam. Production callers omit it. */ onPhase?: (phase: V2RunRetirementPhase) => void | Promise; } export type RetireV2RunSourceResult = { status: 'nothing_to_retire'; sourceRunsDir: string; } | { status: 'retired' | 'already_retired'; archiveDir: string; quarantineDir: string; receiptPath: string; receipt: V2RunRetirementReceipt; verification: V2RunArchiveVerification; }; /** * Publication and retirement deliberately share one non-reentrant lock. * Keep all callers on this helper so a basename change cannot split the * serialization domain and never call it from inside another invocation. */ export declare function withV2RunArchivePublicationLock(archiveBaseDir: string, fn: () => Promise): Promise; export declare function planV2RunArchive(input: { runsDir: string; }): Promise; export declare function commitV2RunArchive(input: CommitV2RunArchiveInput): Promise; /** * Linearize v2 run-source retirement without deleting bytes. * * The advisory publication lock coordinates Botmux archive/retire commands, * but it cannot stop an old daemon from appending to an already-open journal. * Therefore non-empty retirement additionally requires an explicit operator * acknowledgement that all v2 writers are stopped, verifies source parity * twice immediately before rename, and verifies the relocated tree once more. */ export declare function retireV2RunSource(input: RetireV2RunSourceInput): Promise; export declare function verifyV2RunArchive(input: VerifyV2RunArchiveInput): Promise; //# sourceMappingURL=v2-run-archive.d.ts.map