/**
 * importRunner.ts — the end-to-end Phase-2/4 AS-IS import executor (spec §2.4).
 *
 * `importIntegrity.ts` ships the pure integrity-gate CORE (checksums, fingerprint
 * scan, schema-equivalence, FK check, sequence plan); this module is the RUNNER
 * that drives a real import through it: read the full source export → pre-import
 * fingerprint-uniqueness scan (abort BEFORE any write on a collision) → import
 * rows AS-IS parent-before-child → read back what actually landed → run the full
 * integrity gate over source-vs-readback. The gate verdict therefore attests what
 * the TARGET stores, never what the runner intended to write.
 *
 * Two execution modes share this one code path:
 *   - DRY-RUN (available now): target = {@link InMemoryImportTarget}. Proves the
 *     import pipeline on REAL production data with zero durable writes. Its report
 *     persists to a SEPARATE dry-run path and NEVER greens the canonical
 *     `integrity-gate-pass` readiness condition — readiness honesty: `ready` must
 *     mean the real data migration ran, not a rehearsal.
 *   - REAL (creds-gated, Phase 0/G1.4): target = the cloud Prisma adapter (a thin
 *     {@link ImportTarget} shim wrapping one transaction + the synthetic
 *     post-import insert). Only THAT run records to the canonical report path.
 *
 * Rows are handled as raw `Record<string, unknown>` end to end — AS-IS means every
 * field survives verbatim, including fields this codebase has never heard of.
 */
import { type FingerprintCollision, type IntegrityReport, type SchemaDescriptor } from './importIntegrity.js';
/** A raw row exactly as the source export delivered it. */
export type RawRow = Record<string, unknown>;
/** The full source export the import consumes (clusters + the feedback rows that reference them). */
export interface ImportSourceData {
    clusters: RawRow[];
    feedback: RawRow[];
}
/**
 * The write/readback seam an import target must provide. The REAL adapter wraps a
 * cloud DB transaction; tests and dry-runs use {@link InMemoryImportTarget}. The
 * readback methods are load-bearing: the integrity gate verifies what the target
 * RETURNS, so an adapter that silently mangles a row on write is caught by the
 * per-row checksum comparison — intent is never trusted over observation.
 */
export interface ImportTarget {
    /** Persist one cluster row AS-IS (every field verbatim). Throws on a duplicate clusterId (PK). */
    importClusterAsIs(row: RawRow): void;
    /** Persist one feedback row AS-IS. Throws on a duplicate feedbackId (PK). */
    importFeedbackAsIs(row: RawRow): void;
    /** Every cluster row as the target now stores it. */
    readBackClusters(): RawRow[];
    /** Every feedback row as the target now stores it. */
    readBackFeedback(): RawRow[];
    /**
     * The target's real schema descriptor, when it has one (the Prisma adapter
     * reports its actual enum + column types). Null → the runner derives a
     * descriptor from the readback rows (dry-run mode).
     */
    schemaDescriptor(): SchemaDescriptor | null;
}
/** Duplicate-PK import error (mirrors the DB constraint the real adapter would hit). */
export declare class DuplicateImportIdError extends Error {
    constructor(kind: 'cluster' | 'feedback', id: string);
}
/**
 * In-memory ImportTarget — the dry-run/test implementation. Deep-copies on write
 * AND on readback so neither side can mutate stored state through a shared
 * reference; refuses duplicate ids the way the real PK constraint would.
 */
export declare class InMemoryImportTarget implements ImportTarget {
    private clusters;
    private feedback;
    importClusterAsIs(row: RawRow): void;
    importFeedbackAsIs(row: RawRow): void;
    readBackClusters(): RawRow[];
    readBackFeedback(): RawRow[];
    /** No real schema — the runner derives one from readback (dry-run mode). */
    schemaDescriptor(): SchemaDescriptor | null;
}
/**
 * Every status literal the canonical (Instar) instance accepts on an AS-IS import:
 * the v2 lifecycle states, the full legacy v1 vocabulary (AS-IS preserves the raw
 * literal; the processor normalizes at READ time via `normalizeStatus`), and the
 * terminal-only legacy literal `legacy_closed`.
 */
export declare function canonicalAcceptedStatusValues(): string[];
/**
 * Derive a SchemaDescriptor by OBSERVATION: the distinct status literals the rows
 * actually use + a field→typeof map over `fields`. Mixed-type fields surface as
 * 'mixed' (a divergence the equivalence check will flag, by design). null/undefined
 * are skipped — absence is not a type.
 */
export declare function deriveSchemaDescriptor(rows: RawRow[], fields: readonly string[]): SchemaDescriptor;
export interface ImportRunResult {
    /** The full integrity-gate verdict over source-vs-readback (null when aborted pre-import). */
    report: IntegrityReport | null;
    /** What the run actually wrote. Zero on a pre-import abort. */
    imported: {
        clusters: number;
        feedback: number;
    };
    /**
     * Non-null when the run aborted BEFORE any write: the pre-import
     * fingerprint-uniqueness scan found collisions a human must resolve first
     * (spec §2.4 — an AS-IS import would abort on @unique mid-transaction or
     * silently collapse the colliding clusters).
     */
    abortedPreImport: {
        reason: 'fingerprint-collision';
        collisions: FingerprintCollision[];
    } | null;
    /** True only when the run imported AND the integrity gate passed. */
    passed: boolean;
}
/**
 * Execute the AS-IS import end to end. Parent-before-child (clusters, then the
 * feedback rows that FK onto them); the integrity gate runs over what the target
 * READS BACK, not what was sent. Source schema is derived from the source rows;
 * target schema comes from the adapter when it has one, else from the readback.
 */
export declare function runImport(source: ImportSourceData, target: ImportTarget): ImportRunResult;
//# sourceMappingURL=importRunner.d.ts.map