import type { ContextDatabase } from "../../features/magic-context/storage";
import type { RawMessageParts } from "./read-session-raw";
export interface ModuleWatermarks {
    compartment_sequence: number;
    memory_id: number;
    m0_mutation_id: number;
    memory_mutation_id: number;
    last_todo_state_hash: string;
}
export interface ModuleWorkspacePayload {
    fingerprint: string;
    members: Array<{
        project_path: string;
        share_categories: string[];
    }>;
}
export interface ModuleStateSyncPayload {
    method: "state_sync";
    params: {
        session_id?: string;
        shadow_generation: number;
        expected_shadow_seq: number;
        seed_id?: string;
        seed_generation?: number;
        seed_batch_index?: number;
        seed_batch_total?: number;
        seed_complete?: boolean;
        seed_boundary_id?: string | null;
        compartments: unknown[];
        memories: unknown[];
        memory_mutations: unknown[];
        user_profile: string[];
        workspace?: ModuleWorkspacePayload | null;
        last_todo_state?: string;
        acked_watermarks?: ModuleWatermarks;
    };
    watermarks: ModuleWatermarks;
    wireBatches?: ModuleStateSyncPayload[];
}
/** The subset of sender state needed to serialize a state-sync payload. */
export interface ModuleStateSyncState {
    shadowGeneration: number;
    lastAckedSeq: number;
    lastAckedWatermarks: ModuleWatermarks | null;
    idOrdinalMemoGeneration: number;
    idOrdinalMemo: Map<string, number>;
    seedPassPending?: boolean;
}
export interface ModuleStateSyncPass {
    db: ContextDatabase;
    sessionId: string;
    projectPath?: string;
    nowMs: number;
}
export interface ModuleStateSyncOptions {
    beforeSerializeCompartment?: () => void;
    yieldEveryCompartments?: number;
    shouldAbortSeed?: () => boolean;
    /** Enable the authority sender's one-time durable-sequence adoption. */
    authority?: boolean;
    /** Share adoption state across every authority sync attempt in one transform pass. */
    authoritySeqAdoption?: {
        used: boolean;
    };
}
export interface ModuleCompartmentMirrorRow {
    sequence: number;
    start_message: number;
    end_message: number;
    start_message_id: string;
    end_message_id: string;
    title: string;
    content: string;
    p1?: string | null;
    p2?: string | null;
    p3?: string | null;
    p4?: string | null;
    importance?: number | null;
    episode_type?: string | null;
    legacy?: number | null;
    created_at?: number;
}
export interface ModuleCompartmentMirrorResponse {
    max_sequence: number;
    compartments: ModuleCompartmentMirrorRow[];
}
/**
 * The module owns its SQLite file, so TS cannot read rows directly. This narrow
 * reader is the seam for the module's future `session.status` compartment page.
 * It deliberately returns typed rows instead of pretending the TS database is
 * authoritative for module-published content.
 */
export interface ModuleCompartmentReader {
    getCompartmentsAfter(sessionId: string, afterSequence: number): Promise<ModuleCompartmentMirrorResponse>;
}
export declare function mirrorModuleCompartments(args: {
    db: ContextDatabase;
    sessionId: string;
    reader: ModuleCompartmentReader;
}): Promise<number>;
export declare function loadModuleWatermarks(args: {
    db: ContextDatabase;
    sessionId: string;
    projectPath?: string;
}): ModuleWatermarks;
export declare function moduleWatermarksEqual(left: ModuleWatermarks | null, right: ModuleWatermarks): boolean;
/**
 * Compartment rows retain ordinals from the TS storage basis, which can include
 * synthetic summary rows. Resolve module boundaries from the summary-excluding
 * basis so the shared memo compares one canonical value everywhere.
 */
export declare function canonicalOrdinalForMessageId(args: {
    sessionId: string;
    raw: RawMessageParts | null;
    messageId: string;
    generation: number;
    state: ModuleStateSyncState;
}): number | null | "mismatch";
export declare function buildPagedModuleStateSyncPayloads(args: {
    shadowGeneration: number;
    expectedShadowSeq: number;
    seedId: string;
    seedBoundaryId: string | null;
    compartments: unknown[];
    memories: unknown[];
    memoryMutations: unknown[];
    userProfile: string[];
    workspace: ModuleWorkspacePayload | null;
    lastTodoState: string;
    watermarks: ModuleWatermarks;
}): ModuleStateSyncPayload[];
export declare function buildModuleStateSyncPayload(args: {
    state: ModuleStateSyncState;
    pass: ModuleStateSyncPass;
    force: boolean;
    options?: ModuleStateSyncOptions;
    seedId?: string;
}): Promise<ModuleStateSyncPayload | null | "m0_mutation" | "mismatch" | "unresolved" | "seed_budget">;
export interface ModuleStateSyncClient {
    call(args: {
        sessionId: string;
        projectRoot: string;
        method: "state_sync" | "transform" | "session.status" | "session.flush" | "session.recomp" | "session.wrapup" | "todo_state.set" | "agent_drops.append";
        body: unknown;
        signal?: AbortSignal;
    }): Promise<unknown>;
}
/**
 * Mode-neutral state synchronization: the same watermark-triggered assembly is
 * used by the mirror sender and the Rust authority path. Callers own retries and
 * lineage handling because shadow and authority have different failure policy.
 */
export declare function syncModuleState(args: {
    client: ModuleStateSyncClient;
    state: ModuleStateSyncState;
    pass: ModuleStateSyncPass;
    projectRoot: string;
    force: boolean;
    options?: ModuleStateSyncOptions;
}): Promise<ModuleWatermarks | null>;
export declare const __moduleStateSyncTest: {
    buildModuleStateSyncPayload: typeof buildModuleStateSyncPayload;
    buildPagedModuleStateSyncPayloads: typeof buildPagedModuleStateSyncPayloads;
    canonicalOrdinalForMessageId: typeof canonicalOrdinalForMessageId;
    loadModuleWatermarks: typeof loadModuleWatermarks;
    moduleWatermarksEqual: typeof moduleWatermarksEqual;
    syncModuleState: typeof syncModuleState;
};
//# sourceMappingURL=module-state-sync.d.ts.map