/** * `cleo doctor repair` orchestrator — detect malformed CLEO databases and * restore each from its freshest validated snapshot (T11829 · DHQ-060). * * ## Why this exists * * The corruption-resilience pipeline ALREADY existed before T11829: * * - {@link recoverMalformedDb} (quarantine → snapshot-restore → `quick_check`), * - `autoRecoverFromBackup` (catches `"database disk image is malformed"` at * open and restores the freshest VACUUM snapshot), and * - the operator verb `cleo backup recover ` ({@link runBackupRecover}). * * The ONLY gap vs the DHQ-060 ask was a discoverable `cleo doctor` entry point * that DETECTS corruption across the fleet and repairs only what is broken. This * module is that orchestrator — it adds NO new recovery logic. It probes each * role's live DB with `PRAGMA quick_check` (the same probe the pipeline runs on * snapshot candidates, via {@link probeSnapshot}) and delegates every actual * repair to {@link runBackupRecover} → {@link recoverMalformedDb}. * * ## WAL-specific corruption is covered * * A torn WAL frame surfaces as `"database disk image is malformed"` and makes * `PRAGMA quick_check` return a non-`ok` result — so {@link probeSnapshot} * detects it. The quarantine step ({@link quarantineCorruptDb}) already moves the * `-wal`/`-shm` sidecars alongside the main file, so the WAL case is fully * handled by the existing pipeline; this orchestrator does not need to special-case it. * * @module * @task T11829 (DHQ-060 — `cleo doctor repair` entry point over the recovery pipeline) * @epic T11833 * @saga T11242 (SG-DB-SUBSTRATE-V2) * @see packages/core/src/store/recover-malformed-db.ts — the recovery pipeline * @see packages/core/src/store/backup-recover.ts — `cleo backup recover ` wrapper */ import { type DbRole, type DoctorRepairResult } from '@cleocode/contracts'; import { type RecoveryLogger } from './recover-malformed-db.js'; /** * Options accepted by {@link repairMalformedDbs}. * * @task T11829 * @public */ export interface RepairMalformedDbsOptions { /** Absolute path to the project root (resolves `` inventory tokens). */ projectRoot: string; /** * Roles to inspect. When omitted, EVERY role in {@link DB_INVENTORY} whose live * file exists is probed. An explicit single-role list (from `--role`) is probed * even when absent (so the operator gets a clear "not present" report). */ roles?: DbRole[]; /** * When `true`, detect + plan only — corruption is reported with * `action: 'would-repair'` but NO quarantine/restore is performed. * * @default false */ dryRun?: boolean; /** Pino-shaped logger for recovery announcements. */ logger: RecoveryLogger; } /** * Detect and repair malformed CLEO databases across the fleet (T11829 · DHQ-060). * * For each requested role (or every present role in {@link DB_INVENTORY} when none * are specified) this probes the live DB with `PRAGMA quick_check` and, when * corruption is found, restores the freshest validated snapshot via the existing * {@link runBackupRecover} pipeline. No new recovery logic is introduced — this is * the discoverable `cleo doctor repair` entry point requested by DHQ-060. * * @param opts - Repair inputs (project root, optional role filter, dry-run, logger). * @returns A {@link DoctorRepairResult} aggregate with per-role outcomes. * * @example * ```ts * const report = repairMalformedDbs({ projectRoot: '/repo', logger }); * if (report.failedCount > 0) process.exitCode = 1; * ``` * * @task T11829 * @epic T11833 * @saga T11242 * @public */ export declare function repairMalformedDbs(opts: RepairMalformedDbsOptions): DoctorRepairResult; //# sourceMappingURL=repair-malformed-dbs.d.ts.map