/** * Exodus pre-flight plan builder. * * `buildExodusPlan()` computes the full migration plan — source DB paths, * combined size, free-disk availability, staging directory — BEFORE any * writes occur. A `--dry-run` caller can print the plan and exit early. * * ## Disk pre-flight (AC8 · right-sized T11838) * * The original gate required `availableBytes >= 3 * totalSourceBytes` — an * over-estimate that blocked large-fleet migrations even with ample headroom: * exodus never holds 3× the SUM of every source on disk at once. It copies one * source into staging at a time (lock released before the next) and writes a * single consolidated cleo.db whose size approximates the sum of source ROW data. * * The right-sized requirement is therefore * `STAGING_HEADROOM_FACTOR * largestSourceBytes + consolidatedEstimate`, where * `consolidatedEstimate ≈ totalSourceBytes` ({@link computeRequiredBytes}). The * check uses `statvfs` via `node:fs.statfsSync()` (Node 18+). * * @task T11248 (E5 · SG-DB-SUBSTRATE-V2) * @task T11838 (right-sized preflight + optional staging copy for large sources) * @saga T11242 */ import type { ExodusPlan, LegacyDbDescriptor } from './types.js'; /** * Headroom multiplier applied to the LARGEST single source when sizing the * staging-copy footprint. The staging dir only ever holds ONE source backup at a * time (its advisory lock is released before the next source is touched), so the * peak staging footprint is the largest source plus a small slack for the * write-then-rename journal + SQLite sidecars — hence `1.2×`, not `3×` of the SUM. * * @task T11838 */ export declare const STAGING_HEADROOM_FACTOR: 1.2; /** * Per-source byte threshold above which the full staging `copyFileSync` backup * is skipped (the source is archived, not deleted, on success). Sized at 256 MiB * — comfortably above the small project DBs (tasks/conduit/skills/signaldock are * sub-MB to low-MB) but below the large global stores (a multi-GB `brain.db` or * `nexus.db`) whose redundant full-file copy is the costly case T11838 removes. * * @task T11838 */ export declare const STAGING_COPY_SKIP_THRESHOLD_BYTES: number; /** * Compute the right-sized free-disk requirement for an exodus run (T11838). * * `STAGING_HEADROOM_FACTOR * largestSourceBytes` covers the peak staging-copy * footprint (one source at a time, plus slack), and `totalSourceBytes` is the * consolidated-cleo.db estimate (every source's row data lands there). The two * are additive because staging and the consolidated DB coexist on disk until the * sources are archived. * * @param totalSourceBytes - Combined size of all source DB files in bytes. * @param largestSourceBytes - Size of the single largest source DB in bytes. * @returns The minimum free bytes the target filesystem must have. */ export declare function computeRequiredBytes(totalSourceBytes: number, largestSourceBytes: number): number; /** * Derive the staging directory name from the current ISO-8601 timestamp. * * Pattern: `.cleo/exodus-staging-`. * Colons are replaced with empty string (NTFS + shell-safe). */ export declare function deriveStagingDirName(): string; /** * Build the complete exodus plan. * * This is a pure read operation — no files are created or modified. * Pass the result to `runExodusMigrate()` to execute the migration. * * @param cwd - Working directory used to resolve the project root. Defaults to * `process.cwd()`. * @returns {@link ExodusPlan} describing sources, disk availability, and paths. * * @task T11248 (AC8 — disk pre-flight) * @task T11838 (right-sized: largest-source factor + consolidated estimate) */ export declare function buildExodusPlan(cwd?: string): ExodusPlan; /** * Check whether all required source DBs exist. * * Returns `true` if at least one source file is present (partial sets are * acceptable — empty tables simply copy zero rows). */ export declare function sourcesPresent(sources: LegacyDbDescriptor[]): boolean; //# sourceMappingURL=plan.d.ts.map