/**
 * SelfReflectionLoopDetector -- Anomaly detection for runaway self-reflection cycles.
 *
 * A self-reflecting agent (Tier 1, Agent Type Coverage Strategy) inspects its own
 * output, decides it is not good enough, regenerates, and inspects again. Without
 * bounds this loops indefinitely, burning tokens and never converging.
 *
 * Detection criteria (all configurable):
 *   1. N consecutive (output -> self-check -> regenerate) triplets within windowMs.
 *   2. Jaccard similarity on 5-gram shingles between successive 'output' entries
 *      >= similarityThreshold: agent is stuck, not improving (non-converging).
 *   3. Absolute output count (PT-REFLECT-LOOP-2): any cycle exceeding maxOutputCount
 *      text-bearing entries fires regardless of action-type label.
 *
 * Similarity computation:
 *   We compare successive 'output'-kind entries only (not 'regenerate' vs 'output'
 *   within the same triplet, which would be trivially identical). This measures
 *   whether each new primary output differs from the previous primary output.
 *
 * On detection:
 *   - Emits SELF_REFLECTION_LOOP audit event via AuditIntegrity (chained SHA-256).
 *   - Calls CircuitBreaker.recordFailure() to escalate toward OPEN state.
 *   - Does NOT terminate the cycle directly -- composition over duplication.
 *
 * Pack-binding invariant:
 *   recordAction() throws if packBinding is empty (UnboundDataError equivalent).
 *
 * BUILD_PLAN V3 line 258: anomaly detection for self-reflection loops.
 *
 * Similarity metric: Jaccard on 5-gram character shingles.
 *   Rationale: fast, zero external dependencies, and robust to minor surface
 *   variation (whitespace, punctuation) that would fool simpler equality checks.
 *   Cosine similarity requires vector embeddings -- explicitly out of scope.
 *
 * @connexum/ai-governance
 */
import { AuditIntegrity } from '../audit/audit-integrity';
import { CircuitBreaker } from './circuit-breaker';
/**
 * Recognised action kinds in the self-reflection taxonomy.
 *
 * NEW KINDS added here (not present elsewhere in the audit chain before P3-T1):
 *   'self-check'  -- agent invokes an internal grader / reflection prompt.
 *   'regenerate'  -- agent regenerates its output after a self-check verdict.
 *
 * 'output' was already present conceptually in the audit chain but not as an
 * explicit action-kind label. It is formalised here.
 */
export type SelfReflectionActionKind = 'output' | 'self-check' | 'regenerate';
export interface SelfReflectionAction {
    /**
     * Action kind. Unrecognised labels are treated conservatively:
     * they are counted in the absolute-output-count guard (PT-REFLECT-LOOP-2)
     * rather than mapped to the triplet pattern, to avoid label-spoofing.
     */
    kind: SelfReflectionActionKind | string;
    /**
     * Output text (for 'output' and 'regenerate' kinds).
     * NEVER logged verbatim -- only its SHA-256 fingerprint enters the audit chain.
     */
    text?: string;
    /**
     * Self-check verdict (for 'self-check' kind).
     * Only 'regenerate' triggers the triplet pattern. All other verdicts are
     * treated as convergent (loop exits naturally).
     */
    verdict?: string;
}
export interface SelfReflectionLoopConfig {
    /**
     * CircuitBreaker to call on detection. Per-agent recommended; scoped by
     * the caller. The detector does NOT own the breaker's lifecycle.
     */
    circuitBreaker: CircuitBreaker;
    /**
     * AuditIntegrity instance for chained SHA-256 audit emission.
     * If omitted, audit events are written to stderr only.
     */
    auditIntegrity?: AuditIntegrity;
    /**
     * Consecutive (output -> self-check(regenerate) -> regenerate) triplets
     * before detection fires. Default: 5.
     */
    tripletThreshold?: number;
    /**
     * Wall-clock window within which triplets are counted. Default: 60_000 ms.
     */
    windowMs?: number;
    /**
     * Jaccard 5-gram similarity threshold at or above which successive primary
     * outputs are flagged as non-converging. Default: 0.85.
     *
     * Similarity is measured between successive 'output'-kind entries only,
     * not between a 'regenerate' and the 'output' within the same triplet.
     * This ensures the metric captures cross-iteration improvement (or lack of it).
     */
    similarityThreshold?: number;
    /**
     * Absolute count of text-bearing entries per cycle before flagging regardless
     * of action label (PT-REFLECT-LOOP-2 spoofing guard).
     * Default: tripletThreshold * 3.
     */
    maxOutputCount?: number;
}
export interface SelfReflectionLoopDetection {
    orgId: string;
    agentId: string;
    cycleId: string;
    tripletCount: number;
    similarity: number;
    /** 'non-converging' when similarity >= threshold; 'evolving' otherwise. */
    convergenceState: 'non-converging' | 'evolving';
    detectedAt: string;
    packBinding: string[];
    /** SHA-256 of the detection payload (for chaining). */
    contentHash: string;
}
export declare class SelfReflectionLoopDetector {
    private readonly tripletThreshold;
    private readonly windowMs;
    private readonly similarityThreshold;
    private readonly maxOutputCount;
    private readonly circuitBreaker;
    private readonly auditIntegrity?;
    /**
     * Ring buffer: cycleId -> ordered list of recent actions.
     * Cleared by clearCycle() when the cycle ends.
     */
    private readonly buffer;
    /** Detection log (capped at 500) for inspection by tests and operators. */
    private readonly detectionLog;
    constructor(config: SelfReflectionLoopConfig);
    /**
     * Record an action in a cycle's ring buffer and check for loop patterns.
     *
     * @throws {Error} if packBinding is empty (UnboundDataError guard).
     */
    recordAction(orgId: string, agentId: string, cycleId: string, action: SelfReflectionAction, packBinding: string[]): SelfReflectionLoopDetection | null;
    /**
     * Release the ring buffer for a completed cycle.
     * Call this when the cycle ends (success or failure).
     */
    clearCycle(cycleId: string): void;
    /**
     * Get the detection log (read-only copy).
     */
    getDetectionLog(): SelfReflectionLoopDetection[];
    /**
     * Get the current ring-buffer size across all active cycles.
     * Useful for memory leak detection tests.
     */
    activeBufferCount(): number;
    private checkPattern;
    private fireDetection;
    private emitAuditEvent;
}
/**
 * Compute 5-gram character shingle set for a text string.
 * Normalises whitespace to single spaces before shingling.
 */
export declare function computeShingles(text: string): Set<string>;
/**
 * Compute Jaccard similarity between two shingle sets.
 * J(A, B) = |A intersect B| / |A union B|
 * Returns 0 when both sets are empty.
 */
export declare function jaccardSimilarity(a: Set<string>, b: Set<string>): number;
//# sourceMappingURL=anomaly-self-reflection.d.ts.map