/**
 * Chat source resolver.
 *
 * Facade over ChatSourceMachine. Responsibilities:
 *   - Normalise heterogeneous provider output (v1 ad-hoc identities, v2
 *     ChatMessageV2) into ResolverNativeMessageIdentity slices the machine
 *     can compare.
 *   - Hold per-session machine state in an in-memory map (no anchor disk
 *     persistence — the machine is fully recoverable from a fresh
 *     observation).
 *   - Maintain a small ring buffer of recent transitions per session so
 *     debug surfaces (web-devconsole SourceTimeline, mesh_read_debug
 *     bundles) can show *why* the source flipped, not just what it is now.
 *
 * What this module deliberately does NOT do:
 *   - Decide which messages to display. The machine decides only between
 *     `native-history` and `pty-parser`; selecting/merging the actual
 *     message arrays stays in chat-commands.ts (A2.2).
 *   - Mutate provider modules or CLI adapters. nativeHistoryAnchoredAt on
 *     ProviderCliAdapter is gone in A2.2; the resolver is the new owner.
 *   - Persist anything to disk. A daemon restart starts every session in
 *     `Booting`, which lock-promotes on the first valid native observation
 *     of the new process.
 */
import { INITIAL_CHAT_SOURCE_STATE, transitionChatSourceState, type ChatSourceDecision, type ChatSourceObservation, type ChatSourceState, type ChatSourceTransition } from './source-machine.js';
import type { ChatContractVersion } from '../providers/transcript-v2.js';
/** Maximum transitions retained per session for debug surfaces. */
export declare const TRANSITION_HISTORY_LIMIT = 25;
/** Composite key uniquely identifying a chat surface for state purposes.
 *  We key by (providerType, sessionId) because the same provider may run
 *  multiple sessions and each has its own native/PTY interplay. */
export type ChatSourceSessionKey = string;
export declare function chatSourceSessionKey(providerType: string, sessionId: string): ChatSourceSessionKey;
/**
 * Per-session machine store. Keyed by ChatSourceSessionKey. Daemon-lifetime
 * memory; not persisted. Tests should create their own instance to keep
 * isolation; production has a module-level singleton (CHAT_SOURCE_REGISTRY)
 * exposed at the bottom of this file.
 */
export declare class ChatSourceRegistry {
    private readonly records;
    /** Snapshot of current state for diagnostics. Does not mutate. */
    getState(key: ChatSourceSessionKey): ChatSourceState;
    /**
     * Opaque snapshot of a session's FULL record (state + lock + transitions),
     * for callers that need to speculatively `observe()` and then roll back if
     * the resulting decision is undesirable (STICKY-NATIVE hold: a trusted
     * exact-identity session must not flip to PTY on a transient native gap).
     * Returns undefined when the session has no record yet. The snapshot is a
     * shallow copy — transitions array is copied so a later append does not
     * mutate it.
     */
    snapshotRecord(key: ChatSourceSessionKey): {
        state: ChatSourceState;
        lockedSince: number | undefined;
        transitions: ChatSourceTransition[];
    } | undefined;
    /** Restore a previously snapshotted record, undoing a speculative observe.
     *  Passing undefined clears the key (it had no record when snapshotted). */
    restoreRecord(key: ChatSourceSessionKey, snapshot: {
        state: ChatSourceState;
        lockedSince: number | undefined;
        transitions: ChatSourceTransition[];
    } | undefined): void;
    /** Recent transitions, newest last. Empty array when nothing has happened. */
    getTransitions(key: ChatSourceSessionKey): ReadonlyArray<ChatSourceTransition>;
    /** Drop a session. Caller should invoke this when the session is destroyed
     *  to avoid unbounded growth across long-lived daemons. */
    clear(key: ChatSourceSessionKey): void;
    /** Drop all sessions. Test helper. */
    clearAll(): void;
    /**
     * Apply one observation, returning the decision and side-effecting the
     * stored state. The returned `nextState` is the same object now stored
     * under `key`; callers may treat the decision as authoritative without
     * re-reading.
     */
    observe(key: ChatSourceSessionKey, observation: ChatSourceObservation, at?: number): ChatSourceDecision;
}
/**
 * Build a native_present observation from a v2 read_chat payload's message
 * array. v2 producers already provide stable identity (transcript-v2.ts
 * invariants), so this is a thin projection.
 */
export declare function buildV2NativePresentObservation(args: {
    messages: ReadonlyArray<{
        providerUnitKey: string;
        sequence: number;
    }>;
    coverage: 'full' | 'tail' | 'current-turn' | 'partial';
    safeMapping: boolean;
}): ChatSourceObservation;
/**
 * Build a native_present observation from v1 producer output. v1 messages
 * may have no providerUnitKey or a producer-derived one that shifts across
 * reads (index/content-hash based). We synthesise a deterministic identity
 * from the most stable fields available so the machine has *something* to
 * compare across reads. This is intentionally lossy — A2.3 retires v1
 * producers and this branch goes away.
 *
 * The synthesised key is NOT the same as the v2 contract key; never compare
 * v1-synthesised keys against v2 keys for the same logical message. The
 * registry naturally separates them by ChatSourceSessionKey so cross-version
 * leakage cannot happen in practice.
 */
export declare function buildV1NativePresentObservation(args: {
    providerType: string;
    sessionId: string;
    messages: ReadonlyArray<{
        providerUnitKey?: unknown;
        bubbleId?: unknown;
        id?: unknown;
        index?: unknown;
        role?: unknown;
        receivedAt?: unknown;
        timestamp?: unknown;
        content?: unknown;
    }>;
    coverage: 'full' | 'tail' | 'current-turn' | 'partial';
    safeMapping: boolean;
}): ChatSourceObservation;
export declare const CHAT_SOURCE_REGISTRY: ChatSourceRegistry;
export type { ChatSourceDecision, ChatSourceLockState, ChatSourceObservation, ChatSourceState, ChatSourceTransition, ChatSourceTransitionCause, ResolverNativeMessageIdentity, } from './source-machine.js';
export { transitionChatSourceState, INITIAL_CHAT_SOURCE_STATE };
export type { ChatContractVersion };
