/**
 * loop-recall — L3: the per-loop RECALL shortlist (proposal 006, the validated subset of 003).
 *
 * A per-loop influence scorer that RESCUES early-entered culprits into the top-k shortlist so
 * ablation has the right candidates to convict — a **recall booster that narrows before ablation,
 * NOT a #1 ranker** (H2 measured the #1-ranker as a loss; recall as a win: top-3 10/10 vs 9/10).
 *
 * Home: `context-bisect` (NOT influence-core — it consumes the `Trajectory` + `defaultSuspectClassifier`,
 * and influence-core is a leaf; context-bisect already depends on influence-core). Sibling to the
 * `contrastive` opt-in scorer pattern: a separate scorer, not a mutation of `scoreInfluence`.
 *
 * Mechanism (per loop, in order):
 *   1. Reuse `defaultSuspectClassifier` on the frame's contextSources → the SAME suspect identity
 *      the localizer emits (injectionId / toolName) — so a candidate joins 1:1 with a `Suspect`.
 *   2. Score each suspect's content vs the loop's OWN output (`intermediateText`, the per-loop
 *      anchor — NOT the final answer) via `scoreInfluence`. This per-loop signal is the win over
 *      plain final-answer influence: it catches a source in the loop it actually fed.
 *   3. Recency-weighted SUM: `score(s) = Σ_N recencyDecay^(lastLoop − N) · perLoop_N(s)`. Recent
 *      loops weigh more; rank descending for recall, return top-k.
 *
 * MECHANISM NOTE (the gate earned this): proposal 006 first proposed a FORWARD eligibility sum.
 * The recall@k gate measured it against the H2 prototype and it FAILED (forward up-weights early
 * loops → top-3 4/10). The H2 winner was a BACKWARD recency-weighted sum (top-3 10/10) — so that is
 * what ships. Measure-before-promote in action.
 *
 * HONESTY (must-read — folded in from review):
 * - **Correlational only.** Every `recallScore` is an embedding-geometry PROXY, never "because".
 *   The causal claim stays in ablation (`localizeContextBug`).
 * - **FA-dominated, not four-signal.** Per-loop sources carry `ancestorTexts: []`, so `adaptWeights`
 *   zeroes AVG+PERSIST (DEPTH constant) — the per-loop score is in practice cosine-to-the-loop-output.
 * - **Gate-validated mechanism.** The shipped recency sum reproduces H2 (top-3 10/10 vs plain 9/10)
 *   at the default recencyDecay; the gate FAILS promotion otherwise.
 * - **Thin, single-setup.** The recall win is 10/10 vs 9/10 (n=10, one fixture, one embedder/model).
 */
import type { Embedder, InfluenceWeights } from '../influence-core/index.js';
import { type SuspectClassifier } from './localize.js';
import type { Trajectory } from './trajectory.js';
import type { HonestyFlag, SuspectKind } from './types.js';
/**
 * Default recency decay for the per-loop aggregation. A loop N's per-suspect score is weighted by
 * `recencyDecay^(lastLoop − N)` — recent loops weigh more. H2 swept `{0.5, 0.7, 0.9, 1.0}`; the
 * recall@k gate (running THIS shipped scorer) confirmed `0.5` and `0.7` reproduce top-3 10/10 vs
 * plain 9/10, while `≥0.9` does not — so the validated band is `[0.5, 0.7]` and the default is the
 * lowest measured winner, `0.5`. (We do NOT ship an unmeasured value.) `1` = uniform; `0` = last-loop-only.
 */
export declare const DEFAULT_RECENCY_DECAY = 0.5;
/** One recall-shortlist candidate — joins 1:1 with a localizer `Suspect` via `suspectId`. */
export interface LoopCandidate {
    /** The suspect identity the default classifier emits — `injectionId` / `toolName`. The join key. */
    readonly suspectId: string;
    /** Suspect kind (injection / memory / tool) — from the classifier. */
    readonly kind: SuspectKind;
    /** Normalized recall score in [0, 1] (= eligibility / max across candidates) — the display/threshold headline. */
    readonly recallScore: number;
    /** RAW backward recency-weighted sum (pre-normalization) — `Σ_N recencyDecay^(lastLoop−N)·perLoop_N`, the actual computed proxy magnitude. (Field name kept for back-compat; the shipped mechanism is the BACKWARD sum, not the original forward-eligibility proposal — see module doc.) */
    readonly eligibility: number;
    /** First loop index this suspect fed — why recall rescues early-entered culprits. */
    readonly enteredLoop: number;
    /** Per-loop track: the clamped per-loop score in each loop the suspect appeared. */
    readonly perLoop: readonly {
        readonly loopIndex: number;
        readonly recallScore: number;
    }[];
    /** True if a loop it fed read untracked sources, or the trajectory was frame-truncated. */
    readonly incomplete: boolean;
}
/** The recall shortlist — ranked recall-first; `candidates` is already top-`k`. */
export interface LoopRecallShortlist {
    readonly candidates: readonly LoopCandidate[];
    readonly k: number;
    readonly recencyDecay: number;
    /** Standing caveats passed through from the trajectory (literal — review must-fix #4). */
    readonly honestyFlags: readonly HonestyFlag[];
}
export interface ShortlistEarlyCulpritsOptions {
    /** Embedder; wrap in an `EmbeddingCache` (scoring is O(frames × suspects)). */
    readonly embedder: Embedder;
    /** Recency decay; default {@link DEFAULT_RECENCY_DECAY}. Loop N weighted `recencyDecay^(lastLoop−N)`
     *  (1 = uniform, 0 = last-loop-only). Validated band `[0.5, 0.7]`. */
    readonly recencyDecay?: number;
    /** Shortlist size. Default 5. recall@k is the headline metric. */
    readonly k?: number;
    /** Override the suspect classifier (default `defaultSuspectClassifier`). */
    readonly classifier?: SuspectClassifier;
    /** Composite weights forwarded to `scoreInfluence`. */
    readonly weights?: InfluenceWeights;
    readonly signal?: AbortSignal;
}
/**
 * Score a recorded agent run into a per-loop RECALL shortlist (L3). Works on BOTH flat and grouped
 * trajectories (it reads each frame's contextSources + intermediateText regardless of shape).
 *
 * Returns the top-`k` candidates ranked recall-first, each joinable 1:1 with a localizer `Suspect`
 * via `suspectId`. Feed it to `localizeContextBug({ shortlist })` to REORDER suspects before the
 * ablation budget is spent — narrow (recall), then convict (causal).
 */
export declare function shortlistEarlyCulprits(trajectory: Trajectory, opts: ShortlistEarlyCulpritsOptions): Promise<LoopRecallShortlist>;
