/**
 * MultiStoreDeletionWorker -- P4-RET-04 Multi-store deletion enforcement
 *
 * Scheduled worker that sweeps records whose retention window has elapsed
 * across ALL configured stores: filesystem, PostgreSQL, S3 (lifecycle export),
 * and log aggregators (Splunk, Datadog, Azure Sentinel).
 *
 * Design principles:
 *   1. Abort-on-chain-append-failure (AC 16): the retention:deleted audit event
 *      must be appended to the audit chain BEFORE the delete executes.
 *      If chain append fails, the delete is aborted (fail-closed).
 *   2. Legal-hold check: LegalHoldStore.findHoldsMatching() is called per
 *      record. Any active hold emits retention.delete.refused.legal-hold and
 *      skips the record.
 *   3. Cross-store consistency (AC 16b): if FS delete succeeds but DB delete
 *      fails (PT-RET-10), the record is placed in 'failed-delete' state and
 *      a retention.delete.cross-store-failure incident event fires.
 *   4. Tick interval: 60 seconds in production; 15 seconds when any active
 *      pack has healthcareStrict=true (HIPAA/HITECH packs).
 *
 * Spec: P4-RET-01 Sections 2.4, AC 11-16
 *
 * @connexum/ai-governance
 */
/** A single record descriptor used for hold checks and deletion. */
export interface StoreRecord {
    /** Opaque record ID (within the store). */
    id: string;
    tenantId?: string;
    contractId?: string;
    agentId?: string;
    packBinding?: string[];
    /** ISO-8601 timestamp for dateRange hold scope matching. */
    timestamp?: string;
    caseTag?: string;
    /** Unix epoch ms when the record's retention window expires. */
    retentionExpiresAtMs: number;
    /** DataClass label (e.g. AuditEvent, PHIRecord). */
    dataClass?: string;
}
/**
 * Store-specific adapter that knows how to list expired records and
 * execute a deletion for a single record.
 */
export interface StoreAdapter {
    /** Stable identifier used in audit events (e.g. 'fs', 'db', 's3', 'splunk'). */
    readonly storeId: string;
    /**
     * List records whose retention window has elapsed.
     * @param cutoff Records with retentionExpiresAtMs <= cutoff.getTime() are returned.
     */
    listExpiredRecords(cutoff: Date): Promise<StoreRecord[]>;
    /**
     * Delete a single record. Throws on failure.
     */
    deleteRecord(record: StoreRecord): Promise<void>;
}
export interface AuditChainAppend {
    /**
     * Append a single event to the tamper-evident audit chain.
     * Must resolve BEFORE any destructive action executes.
     * Throws on failure -- callers treat throw as abort signal.
     */
    append(event: DeletionAuditEvent): Promise<string>;
}
export interface DeletionAuditEvent {
    eventType: string;
    recordId: string;
    packBindings: string[];
    deletedAt: string;
    storesAffected?: string[];
    verifier: string;
    tenantId?: string;
    dataClass?: string;
    /** Set when a delete fails mid-flight (PT-RET-10). */
    failedStore?: string;
    reason?: string;
}
export interface HoldCheckable {
    findHoldsMatching(descriptor: {
        tenantId?: string;
        contractId?: string;
        agentId?: string;
        packBinding?: string[];
    }): Promise<Array<{
        holdId: string;
        status: string;
    }>>;
}
export interface MultiStoreDeletionWorkerConfig {
    /** Store adapters to sweep in order. */
    stores: StoreAdapter[];
    /** Audit chain used for fail-closed append-before-delete. */
    auditChain: AuditChainAppend;
    /** Legal hold store used to check for active holds. */
    holdStore: HoldCheckable;
    /**
     * Active pack IDs. If any pack has healthcareStrict semantics
     * (hipaa, hitech), the tick interval is shortened to 15s.
     */
    activePackIds?: string[];
    /**
     * Tick interval override in milliseconds. If omitted, the worker
     * computes the appropriate interval from activePackIds.
     */
    tickIntervalMs?: number;
}
export interface DeletionWorkerRunResult {
    jobId: string;
    startedAt: string;
    completedAt: string;
    durationMs: number;
    totalScanned: number;
    totalDeleted: number;
    totalHeld: number;
    totalFailed: number;
    storeResults: Record<string, StoreRunResult>;
}
export interface StoreRunResult {
    scanned: number;
    deleted: number;
    held: number;
    failed: number;
    failedRecordIds: string[];
}
/** P4-RET-04 AC 16b -- state for records where cross-store delete failed. */
export interface FailedDeleteRecord {
    recordId: string;
    tenantId?: string;
    dataClass?: string;
    failedStore: string;
    succeededStores: string[];
    failedAt: string;
    reason: string;
}
export declare class MultiStoreDeletionWorker {
    private readonly config;
    private timer;
    /** In-memory log of records that entered failed-delete state. */
    private readonly failedDeletes;
    constructor(config: MultiStoreDeletionWorkerConfig);
    start(): void;
    stop(): void;
    getTickIntervalMs(): number;
    getFailedDeletes(): readonly FailedDeleteRecord[];
    /**
     * Execute a single deletion sweep across all stores.
     *
     * For each expired record (per store):
     *   1. Check legal holds. If any active hold matches -- emit refused event,
     *      skip, continue.
     *   2. Append retention:deleted to the audit chain. If append fails --
     *      abort the delete for this record (PT-RET-9 fail-closed).
     *   3. Execute the deletion in the primary store.
     *   4. If deletion in a secondary store fails -- emit
     *      retention.delete.cross-store-failure incident event and record
     *      the failed-delete state (PT-RET-10).
     */
    runOnce(): Promise<DeletionWorkerRunResult>;
    private sweepStore;
    private emitSafe;
}
//# sourceMappingURL=multi-store-deletion-worker.d.ts.map