import type { BoberConfig } from "../config/schema.js"; import type { SecurityFinding } from "./security-audit-types.js"; import type { AuditDiff } from "./security-knowledge/diff-provider.js"; /** * Adversarial, fresh-context, contract-free finder->verifier stage * (spec-20260714 sprint 8, ADR-2/ADR-6 default-off). * * Runs sequentially AFTER the security auditor ("finder") inside * `runSecurityAudit`, fed ONLY the finder's `critical`+`important` findings * (never `minor`/`approvedAreas`, never the sprint contract — that strips * the sycophancy framing a favorably-worded contract creates). It is told * to DISPROVE each finding and may only downgrade (`critical`->`important`) * or drop a finding — never promote or manufacture a clean pass. * * Fail-closed, mirroring the finder's own `parsed:false => blocked` * inversion: any parse failure, provider error, refusal, or abort resolves * `ran:false`, and the caller (`runSecurityAudit`'s fold) KEEPS the finder's * findings unchanged. */ /** Downgrade-only, fail-closed verifier result. `ran:false` => finder criticals kept. */ export interface VerifierResult { /** Confirmed by the verifier — stays at the finder's original severity. */ verified: SecurityFinding[]; /** Real but not critical-severity — moves critical->important in the fold. */ downgraded: SecurityFinding[]; /** Disproved against the evidence — removed entirely in the fold. */ dropped: SecurityFinding[]; /** False on parse-failure / provider error / refusal / abort (fail-closed). */ ran: boolean; } export interface VerifyParams { /** The finder's critical + important findings ONLY — never minor/approvedAreas. */ findings: SecurityFinding[]; /** The SAME AuditDiff the finder saw; hunks are the re-check evidence. Undefined in estimated-files mode. */ diff: AuditDiff | undefined; projectRoot: string; config: BoberConfig; /** Time-box for this stage, owned by the caller (keyed to config.security.timeoutMs). */ signal: AbortSignal; } /** Injectable seam so `runSecurityAudit` tests can stub the stage (mirrors `SecurityDiffProvider`). */ export interface SecurityVerifier { verify(params: VerifyParams): Promise; } export declare const runSecurityVerifier: SecurityVerifier; /** * Parse the verifier's response into a `VerifierResult`. * * Reuses the same resilient extraction ladder as * `security-auditor-agent.ts:parseSecurityAuditResult` (direct parse -> * markdown-fence -> first-bracket-to-last-bracket slice), but INVERTS which * JSON shape it accepts: the auditor rejects arrays (it wants a * `ReviewResult` object); the verifier REQUIRES an array of per-finding * verdicts — any non-array, truncated, or garbage response is fail-closed * (`ran:false`). * * A finding present in `inputFindings` but never addressed by a matched, * recognized verdict entry defaults to `verified` — fail-closed means an * unaddressed finding is never silently dropped. */ export declare function parseVerifierResult(text: string, inputFindings: SecurityFinding[]): VerifierResult; //# sourceMappingURL=security-verifier-agent.d.ts.map