/**
 * RelationshipAnomalyScorer — the REAL relationship-aware second factor (Pillar 3,
 * §7.2). It implements the existing `AnomalyScorer` interface (same slot the gate
 * already consumes) and scores how far a request deviates from the principal's
 * DETERMINISTIC behavioral baseline (RelationshipBehaviorStore), with a confidence.
 *
 * This is the production scorer that goes beyond the placeholder HeuristicAnomalyScorer:
 * the Heuristic one reads a hand-injected baseline and only checks urgency + a single
 * "never made this action" flag. This one reads a baseline built from real recorded
 * history and composes FIVE deterministic, privacy-respecting SHAPE signals:
 *
 *   1. Out-of-character ACTION   — this principal has an established repertoire but has
 *                                  never (or rarely) made this kind of request.
 *   2. Tier ESCALATION           — the request's tier is far above the principal's
 *                                  normal ceiling (they suddenly reach for the floor).
 *   3. Off-CADENCE timing        — the request arrives at an hour this principal almost
 *                                  never operates in.
 *   4. Sudden URGENCY/pressure   — urgency language from someone who is normally calm.
 *   5. STYLE deviation           — message length far outside their normal envelope
 *                                  (a coarse, content-free style fingerprint).
 *
 * ── Deny-by-default / conservative direction (documented choice) ────────────────
 * Pillar 3 ships OBSERVE-ONLY (§7.6): a step-up is LOGGED, never live-challenged yet.
 * The safe direction while observing is to AVOID FABRICATING step-ups: a no-baseline
 * or thin-baseline principal scores LOW with LOW confidence, so we never invent a
 * step-up we can't justify from history. Rationale: in observe mode an over-fire just
 * pollutes the FP-rate measurement we're trying to take, and an under-fire is harmless
 * (nothing is blocked). Once the FP rate is measured good and enforcement is enabled,
 * the conservative-low-confidence stance is the right one too: a brand-new principal
 * has no "out of character" because there is no "character" yet — flagging them as
 * anomalous would be authority-by-suspicion, which the spec forbids (anomaly only
 * RAISES the bar on a would-be-allowed floor action; it never invents one). The floor
 * (RolePolicy) already protects the dangerous actions regardless of anomaly.
 *
 * ── Optional LLM style-check (fail-closed) ──────────────────────────────────────
 * An LLM voice/style comparison MAY be added behind the established no-silent-
 * degradation pattern (docs/specs/no-silent-degradation-to-brittle-fallback.md):
 * the call is marked gating:true so the IntelligenceRouter provider-swaps on failure,
 * and on ANY failure (no provider, throw, timeout, unparseable) we DO NOT widen — we
 * simply omit the LLM's contribution and keep the deterministic score. The LLM can
 * only ever ADD to the anomaly score (raise the bar), never lower it. It is OFF by
 * default; the deterministic signals stand alone.
 *
 * Design: docs/specs/SLACK-ORG-INTEGRATION-SPEC.md §7.1–7.4, §7.6.
 */
import type { Principal, RequestIntent, AnomalyAssessment } from './types.js';
import type { IntelligenceProvider } from '../core/types.js';
import { RelationshipBehaviorStore, type PrincipalBehaviorProfile } from './RelationshipBehaviorStore.js';
/** Tunable signal weights + thresholds. Defaults are conservative (lean toward NOT firing). */
export interface RelationshipAnomalyConfig {
    /** Weight of the out-of-character-action signal. Default 0.45. */
    atypicalActionWeight?: number;
    /** Weight of the tier-escalation signal. Default 0.4. */
    tierEscalationWeight?: number;
    /** Weight of the off-cadence (unusual hour) signal. Default 0.2. */
    offCadenceWeight?: number;
    /** Weight of the sudden-urgency signal. Default 0.25. */
    urgencyWeight?: number;
    /** Weight of the style-deviation (length z-score) signal. Default 0.2. */
    styleWeight?: number;
    /**
     * Minimum interaction count for a baseline to be "established" enough to make
     * an out-of-character claim. Below this, action/style signals are suppressed
     * (no character yet → no out-of-character). Default 5.
     */
    establishedMin?: number;
    /**
     * Minimum baseline calendar AGE (days) before a baseline counts as "established"
     * (poisoning-resistance #3a). "Established" now requires BOTH this age AND
     * `establishedMin` count — so a patient attacker can't rapidly manufacture a
     * trusted baseline in a single burst (a high COUNT accrued in minutes is still
     * YOUNG → not established → the action/tier/style signals stay suppressed, and the
     * scorer never gains false confidence from a rapid burst). Default 7 days.
     * Set to 0 to require count only (legacy behavior). Backward-compat: a profile
     * whose firstSeen predates the request by ≥ this age satisfies it automatically.
     */
    minBaselineAgeDays?: number;
    /**
     * Decay half-life in bucket-windows for the recency weighting (#2). A recent burst
     * of attacker observations decays relative to long-standing behavior. Default 30
     * (≈30 days at the store's 1-day bucket). Larger = slower decay (older behavior
     * keeps weight longer). Read-time only; the store records raw counts.
     */
    decayHalfLifeWindows?: number;
    /**
     * Bucket-window length (ms) the baseline was recorded with. Must match the store's
     * `bucketWindowMs`. Default reads from the store; falls back to 1 day. Exposed for
     * tests that inject a custom window.
     */
    bucketMs?: number;
    /**
     * Share floor for the out-of-character-action signal (poisoning resistance).
     * The signal fires when the requested action's SHARE of the principal's history is
     * BELOW this (not only when never-seen) — so a patient attacker can't disable the
     * highest-weight signal by seeding a single prior observation. Weight scales by how
     * far below the floor the share sits (full at never-seen, →0 at the floor) so a
     * genuinely-routine action never trips it. Default 0.10. (Phase-3 adversarial fix.)
     */
    rareActionShareFloor?: number;
    /** Length z-score above which a message reads as style-deviant. Default 2.5. */
    styleZThreshold?: number;
    /** Hour fraction at/below which an arrival hour is "off-cadence". Default 0.02. */
    offCadenceHourFraction?: number;
    /** Now() for deterministic tests (drives hour-of-day). */
    now?: () => Date;
    /**
     * Optional LLM style check (fail-closed). When provided, an out-of-style request
     * may add to the anomaly score; any failure simply omits it (never widens).
     */
    intelligence?: IntelligenceProvider;
    /** Enable the optional LLM style check. Default false (deterministic only). */
    useLlmStyleCheck?: boolean;
    /** LLM call timeout (ms). Default 6000. */
    llmTimeoutMs?: number;
}
export declare class RelationshipAnomalyScorer {
    private readonly store;
    private readonly cfg;
    constructor(store: RelationshipBehaviorStore, config?: RelationshipAnomalyConfig);
    /**
     * Score how out-of-character (principal, intent, text) is. Deterministic except
     * for the OPTIONAL LLM style check (which only ever adds, and fails closed).
     *
     * Returns an `AnomalyAssessment` with a 0..1 score, reasons, and a `confidence`
     * piggybacked onto the reasons via the score being suppressed under thin baselines.
     * The gate consumes `score` against its `stepUpThreshold` and only ever RAISES a
     * would-be-allowed floor action to step-up — never lowers any bar.
     */
    assess(principal: Principal, intent: RequestIntent, text: string): Promise<AnomalyAssessment>;
    /**
     * Pure deterministic scoring. Exposed via `assess`; broken out for unit testing.
     * Returns the raw score, the contributing reasons, and a coarse confidence band
     * derived from baseline depth.
     */
    deterministicScore(profile: PrincipalBehaviorProfile | undefined, intent: RequestIntent, text: string): {
        score: number;
        reasons: string[];
        confidence: 'none' | 'low' | 'medium' | 'high';
    };
    /**
     * Optional LLM style hit — fail-closed, add-only. Asks a fast model whether the
     * message's VOICE matches a coarse description of the principal's normal style.
     * On ANY failure or an unparseable / "matches" answer, returns null (no widening).
     */
    private llmStyleHit;
}
//# sourceMappingURL=RelationshipAnomalyScorer.d.ts.map