/** * Record cold-storage archival engine. * * Archival relocates a sealed record's **encrypted envelope** from the * primary store to a cold archive store — no re-encryption, the envelope * is opaque ciphertext. Because relocation goes through low-level store * ops (and the collection's `_internalDelete`), it bypasses guards (an * issued/immutable record can still be archived) and never fires * materialized-view dispatch (finalized aggregates over a sealed period * don't recompute). The archive store's contents are themselves the * archived-set index — `listArchived` lists it; `restore` relocates an * envelope back to the primary store. * * A `legalHold` predicate blocks archival; `archiveWhen` (typically * derived from the record's fiscal period / business date) selects * eligible records. */ import type { NoydbStore, EncryptedEnvelope } from '../../kernel/types.js'; export interface ArchivePolicy { /** Select records eligible for archival — typically a business-date / period test. */ readonly archiveWhen: (record: T) => boolean; /** Block archival while true (litigation / audit hold). Fail-closed on throw. */ readonly legalHold?: (record: T) => boolean; } export interface ArchiveResult { /** Records relocated to the archive store. */ readonly archived: number; /** Records eligible by `archiveWhen` but retained by a `legalHold`. */ readonly held: number; /** Records scanned across policy collections. */ readonly scanned: number; readonly byCollection: Record; } export interface ArchiveRunOptions { /** Stop after this many archivals. `undefined` = unbounded. */ readonly maxArchives?: number; /** Preview without relocating. */ readonly dryRun?: boolean; } /** * Everything the engine needs from the Vault, injected so the engine * stays unit-testable without a live vault. */ export interface ArchiveContext { readonly vaultId: string; readonly archiveStore: NoydbStore; /** Collections that declared an `archive` policy. */ collectionsWithPolicy(): readonly string[]; getPolicy(collection: string): ArchivePolicy | null; listRecordIds(collection: string): Promise; /** Decrypted record for policy evaluation, or null if unreadable. */ getRecord(collection: string, id: string): Promise | null>; /** Raw encrypted envelope from the primary store. */ getEnvelope(collection: string, id: string): Promise; /** Remove from the primary store + cache, bypassing guards/MV (`_internalDelete`). */ removeFromPrimary(collection: string, id: string): Promise; /** Write an envelope back to the primary store + refresh cache. */ restoreToPrimary(collection: string, id: string, env: EncryptedEnvelope): Promise; } /** Sweep eligible records into the archive store. */ export declare function runArchive(ctx: ArchiveContext, options?: ArchiveRunOptions): Promise; /** Relocate one archived record back to the primary store. Returns false if not archived. */ export declare function runRestore(ctx: ArchiveContext, collection: string, id: string): Promise; /** List archived record ids for a collection (or all policy collections). */ export declare function runListArchived(ctx: ArchiveContext, collection?: string): Promise>;