import { StorageManager } from './storage.js';
import { PluginConfig, BufferTurn } from './types.js';
import './page-versioning.js';
import './consolidation-operator.js';
import './memory-projection-store-CY8TU40w.js';
import 'better-sqlite3';
import './index-1qIcnbG1.js';

type TriggerDecision = "extract_now" | "extract_batch" | "keep_buffering";
/**
 * Optional surprise probe injected into `SmartBuffer`.
 *
 * Computes a D-MEM-style novelty score in `[0, 1]` for an incoming turn.
 * The buffer treats the probe as purely additive: if it is not provided, if
 * the feature flag is off, or if the probe throws/times out, the buffer
 * falls back to the existing signal/turn-count/time triggers unchanged.
 *
 * Callers are responsible for sampling recent memories and passing them
 * through the embedding pipeline — the buffer does not want to know about
 * storage, embeddings, or QMD.
 *
 * @param bufferKey Identifier for the active buffer (session/thread).
 * @param turn      The incoming turn whose novelty is being scored.
 * @param recentTurns Turns already buffered for this key (most recent first
 *                    is NOT guaranteed — treat as unordered corpus).
 * @returns A surprise score in `[0, 1]`, or `null` if no score could be
 *          produced (e.g. empty corpus, probe declined to embed).
 */
interface BufferSurpriseProbe {
    scoreTurn(bufferKey: string, turn: BufferTurn, recentTurns: readonly BufferTurn[]): Promise<number | null>;
}
declare class SmartBuffer {
    private readonly config;
    private readonly storage;
    private state;
    private loaded;
    private readonly surpriseProbe;
    /**
     * Serialized write chain for `BUFFER_SURPRISE` telemetry events.
     *
     * The telemetry path is fire-and-forget (`addTurn` does not await the
     * ledger append), but multiple concurrent appends would still settle
     * out of order under variable filesystem latency. The report path
     * assumes chronological ordering — it slices the tail of the ledger
     * and treats the most recent entry as the current threshold in force.
     * Chaining ensures each append only runs after the previous settles,
     * preserving wall-clock order.
     *
     * We include a `.catch` on every link so a rejected append does not
     * poison the chain (CLAUDE.md rule #40).
     */
    private surpriseTelemetryWriteChain;
    constructor(config: PluginConfig, storage: StorageManager, surpriseProbe?: BufferSurpriseProbe | null);
    private entryFor;
    private peekEntry;
    private normalizeState;
    private entryActivityAt;
    private pruneEntries;
    load(): Promise<void>;
    /**
     * Reset the buffer to an empty, usable state.
     * Called when the persisted buffer file is corrupt and load() fails,
     * so the buffer can still accept new turns for the rest of the session.
     */
    resetToEmpty(): void;
    save(): Promise<void>;
    addTurn(bufferKey: string, turn: BufferTurn): Promise<TriggerDecision>;
    /**
     * Enqueue a telemetry append on the serialized write chain.
     *
     * The chain is a classic `writeChain = writeChain.then(fn).catch(...)`
     * — each link waits for the previous to settle before its append
     * starts, so out-of-order chronology cannot happen even under
     * variable filesystem latency. We always attach `.catch` so one
     * rejection does not poison the chain for the rest of the session
     * (CLAUDE.md rule #40). The error is logged through
     * `emitSurpriseEventSafe` itself, which swallows its own rejections.
     *
     * Public surface is deliberately narrow — only `addTurn` should call
     * this, so the surprise telemetry path stays centralized.
     */
    private queueSurpriseTelemetryWrite;
    /**
     * Append a single `BUFFER_SURPRISE` telemetry row (issue #563 PR 3).
     *
     * Deliberately swallows write errors: the buffer must never fail to
     * record a turn because the observation ledger is read-only, out of
     * disk, or otherwise unhappy. The log line at debug lets operators
     * confirm the path fired without polluting the error channel.
     */
    private emitSurpriseEventSafe;
    /**
     * Invoke the injected surprise probe defensively. Any error (probe throws,
     * embedder unavailable, timeout) is swallowed and logged at debug: the
     * surprise path must never crash the happy-path trigger evaluation. A
     * `null` return indicates "no score available, fall through to existing
     * triggers".
     */
    private computeSurpriseSafe;
    private evaluate;
    getTurns(bufferKey?: string): BufferTurn[];
    /**
     * Retain a subset of the current turns across `clearAfterExtraction` so a
     * future extraction pass sees the context behind a deferred candidate
     * (issue #562, PR 2). Callers pass the turns that were seen during the
     * current extraction; the buffer keeps the tail (latest `max` turns) as
     * the retention window. Passing an empty array or `max <= 0` clears the
     * retention slot instead.
     */
    retainDeferredTurns(bufferKey: string, turns: BufferTurn[], max?: number): Promise<void>;
    /**
     * Return the current retention window (issue #562, PR 2). Primarily for
     * tests and diagnostics.
     */
    getRetainedDeferredTurns(bufferKey?: string): BufferTurn[];
    findBufferKeyForSession(sessionKey: string): Promise<string | null>;
    findBufferKeysForSession(sessionKey: string): Promise<string[]>;
    clearAfterExtraction(bufferKey?: string): Promise<void>;
    getExtractionCount(bufferKey?: string): number;
    /**
     * Await any pending `BUFFER_SURPRISE` telemetry writes.
     *
     * The telemetry path is fire-and-forget from the hot path's point of
     * view, but tests and before-exit hooks sometimes need to make sure
     * the ledger has been flushed before they assert on its contents or
     * close the process. This method resolves once the current chain
     * head has settled; new writes scheduled after this call return a
     * separate, later settlement.
     *
     * Never throws — the chain already catches its own rejections.
     */
    flushSurpriseTelemetry(): Promise<void>;
}

export { type BufferSurpriseProbe, SmartBuffer, type TriggerDecision };
