/** * Gaming defences for the verified-outcome learning loop (ADR-503). * * Every rule here can only downgrade: a tainted record does not train, a * pattern that looks gamed is held back from the prompt. Nothing here can * turn an `unknown` into a verified outcome. * * - §2.1/§2.2 taints: the mod marks a `verified-success` whose turn edited a * test file or a verifier config, or narrowed its check. Ingest never * trains a tainted record unless `.claude-flow/config.json` * `learningLoop.allowTaint` lists every one of its classes. * - §2.3 re-verify settings (the runner lives in verified-reverify.ts). * - §2.4 the anomaly gate on lessons. */ export type Taint = 'edited-tests' | 'edited-verifier-config' | 'narrowed-verifier'; export declare const TAINTS: readonly Taint[]; /** A record's `taint` field, validated: known classes only, each once. Anything else is dropped. */ export declare function parseTaint(raw: unknown): Taint[]; export interface LoopConfig { /** Taint classes a project lets train (default none). */ readonly allowTaint: readonly Taint[]; /** Re-run a verifier at HEAD before a success trains (default off: it runs project code). */ readonly reverify: boolean; readonly reverifyTimeoutMs: number; } export declare const DEFAULT_REVERIFY_TIMEOUT_MS = 300000; export declare const DEFAULT_LOOP_CONFIG: LoopConfig; /** * `learningLoop` from `.claude-flow/config.json`. A missing, unreadable or * malformed file means the defaults: no taint allowed, re-verify off. Only * `reverify: true` (the boolean) turns re-verification on. */ export declare function readLoopConfig(root: string): LoopConfig; export declare function parseLoopConfig(raw: unknown): LoopConfig; /** The taint classes of a record that its project did not allow; non-empty means it never trains. */ export declare const blockedTaints: (taint: readonly Taint[], config: LoopConfig) => Taint[]; /** * What ingest knows about a verified pattern, from verified records only * (SONA's own counts include other feeders). Sessions are capped: the gate * only asks whether there were two. */ export interface PatternStats { successes: number; failures: number; /** Successes that carried an allowed taint. */ tainted: number; /** Successes decided by a narrowed command. */ narrowed: number; sessions: string[]; } export declare const MAX_PATTERN_SESSIONS = 4; export declare const emptyStats: () => PatternStats; export declare function parseStats(raw: unknown): PatternStats; /** Folds one trained record into its pattern's stats. */ export declare function addOutcome(stats: PatternStats, success: boolean, taint: readonly Taint[], session: string | null): void; export type HoldReason = 'perfect-and-tainted' | 'only-narrowed' | 'one-session'; /** §2.4 case 1: records at or above which a perfect record with half its successes tainted is held. */ export declare const PERFECT_MIN_RECORDS = 8; /** * Why a would-be lesson is held back from the prompt (ADR-503 §2.4), or null. * A held pattern stays in SONA; it only never becomes a prompt lesson. * * 1. 100% success over 8 or more records, half or more of them tainted (allowed). * 2. Every success came from a narrowed command. * 3. Every success came from one session: no independent repetition. A pattern * with no recorded sessions (a record from before ADR-503, or one without a * session) counts as one session. */ export declare function holdReason(stats: PatternStats, sonaSuccesses: number): HoldReason | null; //# sourceMappingURL=verified-guards.d.ts.map