/** * Watch-mode auto-migration from the personal v3 journal to AreaLedger. * * Manual conversion remains `src/bin/area-ledger-migration.ts`. This scheduler * is the background path for a box that already has an authorized realtime * event-sync session: copy/catch-up runs as a low-priority chore, and cutover * happens only after clean parity under the exclusive operation lock. * * Failures never propagate to the caller. Abandoned or composed-back manifests * are left to {@link AreaLedgerMigration}'s state machine — this module does * not force a cutover from an unready phase. */ import { AreaLedgerMigration, type LayoutPhase, type LayoutState } from "./area-ledger-migration.js"; import type { FeatureSwitch } from "./feature-flags.js"; import type { SyncJournal } from "../types.js"; export declare const AREA_AUTO_MIGRATION_STARTED_EVENT = "area_migration_started"; export declare const AREA_AUTO_MIGRATION_COMPLETED_EVENT = "area_migration_completed"; export declare const AREA_AUTO_MIGRATION_SOURCE = "sync-runner"; export declare const AREA_AUTO_MIGRATION_RETRY_MIN_MS = 1000; export declare const AREA_AUTO_MIGRATION_RETRY_MAX_MS: number; /** * Consecutive failed passes tolerated before the scheduler stops for the rest * of the runner's lifetime. Every pass re-projects the whole source journal, so * a deterministic failure (a row no area owns, a persistent parity mismatch) * retried at the backoff ceiling forever costs a full core indefinitely — the * 2026-08-31..09-05 wedge ran for five days on one machine. A runner restart * (which a fixed release always implies) starts a fresh streak. */ export declare const AREA_AUTO_MIGRATION_MAX_CONSECUTIVE_FAILURES = 5; export type AreaAutoMigrationPassStatus = "skipped" | "copied" | "cut-over" | "parity-mismatch" | "lock-busy" | "error"; export interface AreaAutoMigrationBridge { copyAndCatchUp(): { state: Pick; }; verifyParity(legacy: SyncJournal): unknown; cutOver(): Pick; readLegacyJournal(): SyncJournal; } export interface AreaAutoMigrationDeps { now(): number; hasActiveRealtimeSession(): boolean; areaStorageSwitch(): FeatureSwitch; readPhase(): LayoutPhase | undefined; /** True once a personal-vault v3 journal exists to copy. */ hasLegacyJournal(): boolean; createMigration(): AreaAutoMigrationBridge; withExclusiveLock(fn: () => T): T; enqueueChore(run: () => void): void; log(message: string): void; emitTelemetry(eventName: typeof AREA_AUTO_MIGRATION_STARTED_EVENT | typeof AREA_AUTO_MIGRATION_COMPLETED_EVENT): void; /** Fired after a durable area-authoritative cutover. */ onCutOver?: () => void; } export interface AreaAutoMigrationScheduler { /** Called once per watch-loop tick. Never throws. */ onTick(): void; } export declare function openPersonalVaultAreaMigration(hqRoot: string, stateDir: string, journalSlug: string): { migration: AreaLedgerMigration; readLegacyJournal: () => SyncJournal; }; export declare function readPersonalVaultLayoutPhase(stateDir: string, journalSlug: string): LayoutPhase | undefined; export declare function createAreaAutoMigrationScheduler(deps: AreaAutoMigrationDeps): AreaAutoMigrationScheduler; //# sourceMappingURL=area-ledger-auto-migration.d.ts.map