import type { SessionLearningCandidate } from './sessionLearning';
import type { EvalTraceRun } from './evalTrace';
export type SafetyViolationSeverity = 'low' | 'medium' | 'high';
export interface SafetyViolation {
    /** Stable id of the rule that fired. */
    ruleId: string;
    /** Human-readable rule label. */
    ruleLabel: string;
    severity: SafetyViolationSeverity;
    /** Source string the rule matched against (truncated for the UI). */
    matchedIn: string;
    /** First 80 chars of the matching span, useful when debugging. */
    excerpt: string;
}
/**
 * One entry in the bundled safety pattern library. Patterns are
 * intentionally conservative — we only fire on phrases / shapes that
 * either ARE secrets (looking up secret formats) or are common
 * prompt-injection / dangerous-shell markers.
 */
export interface SafetyRule {
    id: string;
    label: string;
    severity: SafetyViolationSeverity;
    pattern: RegExp;
    /** Fields to scan: 'prompt' | 'outcome' | 'tool_name'. */
    scopes: Array<'prompt' | 'outcome' | 'tool_name'>;
}
/** Built-in rule set. Conservative on purpose — extend in dedicated files later. */
export declare const DEFAULT_SAFETY_RULES: SafetyRule[];
export interface PromotionGateConfig {
    /** Required successful eval runs against the frozen dataset. Defaults to 3. */
    requiredPasses?: number;
    /** Trials window — how many recent runs to consider. Defaults to 5. */
    trialsWindow?: number;
    /** Custom rule set; defaults to DEFAULT_SAFETY_RULES. */
    safetyRules?: SafetyRule[];
    /** Highest severity that does NOT block promotion. Default 'low' so 'medium' and 'high' are blocking. */
    maxAllowedSeverity?: SafetyViolationSeverity;
}
export interface PromotionGateInput {
    candidate: SessionLearningCandidate;
    /** Recent eval runs the gate considers (oldest → newest is fine; we just count). */
    recentEvalRuns: EvalTraceRun[];
    /** Optional extra strings the gate should scan for safety violations beyond candidate.prompt/outcome (e.g. recent assistant messages). */
    extraScannedContent?: Array<{
        source: 'prompt' | 'outcome' | 'tool_name';
        text: string;
    }>;
    config?: PromotionGateConfig;
}
export interface PromotionGateResult {
    allowed: boolean;
    reason: string;
    /** Number of fully-passing runs in the trials window. */
    passCount: number;
    /** Number of runs considered. */
    consideredRuns: number;
    /** Required passes per config. */
    requiredPasses: number;
    /** Highest-severity violations that fired. */
    safetyViolations: SafetyViolation[];
    /** Pass^k metric (Claw-Eval style): every considered trial passed. */
    passAtAll: boolean;
}
/**
 * Run all safety rules against the candidate + extra content. Returns
 * every match (sorted high → low so the UI can show worst first).
 */
export declare function scanSafety(candidate: SessionLearningCandidate, extraScannedContent?: Array<{
    source: 'prompt' | 'outcome' | 'tool_name';
    text: string;
}>, rules?: SafetyRule[]): SafetyViolation[];
/**
 * Same as `scanSafety` but accepts arbitrary text snippets so callers
 * outside the learning-candidate flow (curator, heartbeat skill checks,
 * agent definition validators) can reuse the rule engine without
 * fabricating a fake candidate.
 */
export declare function scanSafetyText(text: string, scope?: 'prompt' | 'outcome' | 'tool_name', rules?: SafetyRule[]): SafetyViolation[];
/**
 * Count how many of the most-recent N runs passed every result. A run
 * "passes" iff every result inside it is `pass` (no failures), so the
 * counter mirrors the Claw-Eval Pass@k semantics with a threshold of 1.
 */
export declare function countPassingRuns(runs: EvalTraceRun[], window: number): {
    considered: number;
    passing: number;
};
/**
 * Evaluate the promotion gate. Pure — returns a structured verdict that
 * the HTTP layer decides whether to honour.
 */
export declare function evaluatePromotionGate(input: PromotionGateInput): PromotionGateResult;
export interface SerializedSafetyRule {
    id: string;
    label: string;
    severity: SafetyViolationSeverity;
    pattern: string;
    flags?: string;
    scopes: Array<'prompt' | 'outcome' | 'tool_name'>;
}
/**
 * Compile a serialized rule into a SafetyRule. Returns null when the
 * pattern is invalid; callers can choose whether to log + skip.
 */
export declare function compileSafetyRule(serialized: SerializedSafetyRule): SafetyRule | null;
/**
 * Load `.harness/safety-rules.json` from `projectDir`. Returns the
 * default rule set merged with any valid custom rules. Custom rules
 * with the same id as a built-in REPLACE the built-in (last-write-wins
 * by id) so users can tighten or relax shipping rules.
 *
 * Pure I/O wrapper: returns DEFAULT_SAFETY_RULES when the file is
 * missing or unreadable so callers never have to handle the empty case.
 */
export declare function loadSafetyRules(projectDir: string): Promise<SafetyRule[]>;
//# sourceMappingURL=promotionGate.d.ts.map