import { type DetectorSpec, type Finding, type GuardContext, type GuardrailAction, type GuardrailRule, type GuardrailStage, type Segment } from './types.js';
import { Vault } from './vault.js';
/**
 * One reported hit. `values` holds the distinct matched values so a caller can fingerprint them
 * (a keyed hash correlates repeats without storing the value) — never persist them as they are.
 */
export interface GuardHit {
    ruleId: string;
    ruleName: string;
    action: GuardrailAction;
    detector: string;
    category: string;
    score: number;
    count: number;
    /** Distinct values found (at most 20). In-memory only. */
    values: string[];
    /** Found in the newest turn (false: only in re-sent history, already reported once). */
    fresh: boolean;
    /** `detector_error` hits: what failed, and what the rule's fail mode made of it. */
    error?: string;
    failMode?: 'open' | 'closed';
}
export interface ScanResult {
    stage: GuardrailStage;
    /** Most severe action among the rules that fired. */
    action: GuardrailAction;
    /** The rule that decided a block / approval, and the message for the person. */
    decisive?: {
        id: string;
        name: string;
        message: string;
    };
    /** Segment texts after redaction (same order as the input). */
    segments: string[];
    /** Whether any segment changed. */
    changed: boolean;
    hits: GuardHit[];
    vault: Vault;
    /** Redacted spans. */
    redactions: number;
    latencyMs: number;
}
export interface ScanOptions {
    /** Per-stage refusal messages, for rules that set none. */
    messages?: Partial<Record<GuardrailStage, string>>;
    /** Refusal message for `approve`, for rules that set none. */
    approvalMessage?: string;
    /**
     * Stages whose redactions are reversible (unless the rule sets `restore: false`). Default
     * `['llm_request']`: what the caller sent is theirs to get back; what a tool or the model produced
     * is removed one-way. A caller whose tool results are its own data may add `tool_result`.
     */
    restorableStages?: readonly GuardrailStage[];
}
export declare const DEFAULT_MESSAGES: Record<GuardrailStage, string>;
export declare const DEFAULT_APPROVAL_MESSAGE = "This needs approval under your organization's AI guardrails before it can go ahead.";
/** What replaces an instruction-like finding: it is removed, not tokenized. */
export declare const INJECTION_REPLACEMENT = "[removed: suspected prompt injection]";
/** Whether a rule's scope covers the context (stage, tool, `when`). Segments are filtered apart. */
export declare function ruleApplies<C extends GuardContext>(rule: GuardrailRule<C>, ctx: C): boolean;
export declare function orderRules<C extends GuardContext>(rules: readonly GuardrailRule<C>[]): GuardrailRule<C>[];
/** Runs one detector on one text. A custom detector's throw is the rule's fail mode to decide. */
export declare function runDetector<C extends GuardContext>(spec: DetectorSpec<C>, text: string, ctx: C): Promise<Finding[]>;
/**
 * The in-process detectors of a rule set, as one span locator — what a stream window must never
 * cut through (see `StreamGuard`'s `locate`). Custom detectors are left out: they may be remote.
 */
export declare function spanLocator<C extends GuardContext>(rules: readonly GuardrailRule<C>[]): ((text: string) => Finding[]) | undefined;
/**
 * Non-overlapping spans. Overlapping findings are merged into their union (nothing that any
 * detector found is left uncovered), labelled by the longer finding (ties: the higher score) —
 * an injected HTML comment that contains an email address is removed as a whole. With `text`, a
 * merged span's value is re-read from it.
 */
export declare function resolveOverlaps(findings: readonly Finding[], text?: string): Finding[];
export declare function applyRedactions(text: string, findings: readonly Finding[], vault: Vault, restorable: boolean): {
    text: string;
    count: number;
};
/**
 * Evaluates the rules for one stage over a set of segments. Rules run by ascending priority; an
 * `allow` rule that fires stops evaluation; otherwise every firing rule contributes and the most
 * severe action wins (block > approve > redact > log). Detector results are shared between rules.
 *
 * Blocking applies to the NEWEST turn: content found only in re-sent history (`fresh: false`) was
 * already refused once, so it is removed one-way instead — the conversation can go on and the value
 * still never reaches the model.
 */
export declare function scan<C extends GuardContext>(rules: readonly GuardrailRule<C>[], ctx: C, segments: readonly Segment[], vault?: Vault, options?: ScanOptions): Promise<ScanResult>;
//# sourceMappingURL=engine.d.ts.map