/** * Hostile-Update Detection — R0 Wave 2A (SMI-5535) * @module @skillsmith/core/security/scanner/SecurityScanner.hostile-update * * A PURE comparator (no I/O, no clock, no mutation of its inputs) that detects a * benign→malicious "rug-pull" between two SecurityScanner scans of the SAME * skill. The scanner already blocks a skill that is malicious on first sight; * this detector catches the harder case where an initially-clean skill is * silently updated to exfiltrate credentials or execute remote payloads. * * The verdict is delta-based: it never re-scores content, it only reasons about * what changed between `previous` and `current`. "hostile" is reserved for the * benign→malicious transition — a skill that was ALREADY flagged and merely got * worse is a worsening (`suspicious`), not a fresh rug-pull. */ import type { HostileUpdateVerdict, ScanReport } from './types.js'; /** * Default risk-score threshold. Mirrors SecurityScanner's `riskThreshold` * default (SMI-5359) so the "crossed the failure bar" signal here lines up with * the `passed` computation in `SecurityScanner.scan`. */ export declare const DEFAULT_RISK_THRESHOLD = 40; /** * Compare two scans of the same skill and classify the transition. * * Ordering is hostile → suspicious → benign so the strongest signal wins. * * @param previous Scan of the prior (trusted) version. * @param current Scan of the incoming version. * @param threshold Risk-score failure bar; defaults to {@link DEFAULT_RISK_THRESHOLD}. * * CALLER CONTRACT (LOW-2): this value MUST equal the `riskThreshold` the * `SecurityScanner` instance used to produce BOTH `previous` and `current` * (i.e. the same `ScannerOptions.riskThreshold` — or the scanner's own * default of 40, which is why this parameter also defaults to * {@link DEFAULT_RISK_THRESHOLD}). `previouslyBenign` below is derived from * `previous.passed`, which was computed by the scanner against ITS OWN * `riskThreshold` at scan time — if the caller passes a `threshold` here * that differs from that value, `crossedThreshold`'s "did the score cross * the bar" signal and `previouslyBenign`'s "was it passing" signal are * reasoning about two different bars, and the hostile/suspicious/benign * verdict can disagree with what `previous.passed` / `current.passed` * would say under a freshly-run scan. */ export declare function compareScanReports(previous: ScanReport, current: ScanReport, threshold?: number): HostileUpdateVerdict; //# sourceMappingURL=SecurityScanner.hostile-update.d.ts.map