/** * peaks-code multi-signal verdict aggregator (v2.13.1 Group A). * * Implements the 4 aggregation rules documented in * `.peaks/project-scan/audit-output-schema.md:66-78` plus 3rd-party * inputs (karpathy / peaks-mut / peaks-qa). The 5 envelopes are * heterogeneous on purpose — v2.13.1 ships precedence, NOT a schema * unification (that's v2.14). * * 4 aggregation rules (verbatim from audit-output-schema.md): * 1. Verdict precedence — `block` > `warn` > `pass`. Top-level * verdict is the highest input verdict. * 2. CRITICAL count — sum of CRITICAL markers across inputs. * 3. Required fix deduplication — identical `(file, line, hint)` * tuples from different audits are merged. * 4. Handoff hash consistency — handled by the audit skills * upstream; the aggregator consumes already-verified envelopes. * * Top-level precedence: `block` > `return-to-rd` > `warn` > `pass`. * * The aggregator is intentionally pure (no I/O, no clock, no * filesystem). v2.13.1 wires the result into micro-cycle.md as the * "re-run reason" payload; v2.14 will wire it into a CLI subcommand. * * Karpathy §1 — Simplicity First: * - single file, no new imports beyond the existing * SecurityAuditEnvelope / PerfAuditEnvelope type re-exports. * - hard precedence; no scoring, no weighting, no RFC voting. */ import type { PerfAuditEnvelope, SecurityAuditEnvelope } from '../audit-independent/index.js'; import type { ThresholdViolation } from 'peaks-loop-mut'; export interface KarpathyViolation { readonly guideline: 'think-before-coding' | 'simplicity-first' | 'surgical-changes' | 'goal-driven-execution'; readonly severity: 'CRITICAL' | 'HIGH' | 'MED' | 'LOW'; readonly file: string; readonly line: number; readonly hint: string; } export interface KarpathyEnvelope { readonly passed: boolean; readonly violations: ReadonlyArray; readonly gateAction: 'pass' | 'warn' | 'block'; } export interface MutEnvelope { readonly passed: boolean; readonly killRate: number; readonly weakRate: number; readonly violations: ReadonlyArray; } export interface QaEnvelope { readonly verdict: 'pass' | 'return-to-rd' | 'blocked'; readonly reportPath?: string; } export interface AggregatorInput { readonly security?: SecurityAuditEnvelope; readonly perf?: PerfAuditEnvelope; readonly karpathy?: KarpathyEnvelope; readonly mut?: MutEnvelope; readonly qa?: QaEnvelope; } export type AggregatorVerdict = 'pass' | 'warn' | 'block' | 'return-to-rd'; export type VerdictSource = 'security-audit' | 'perf-audit' | 'karpathy-reviewer' | 'peaks-mut' | 'peaks-qa'; export interface VerdictReason { /** * Primary source — kept for the single-source case. When multiple * sources report the same (file,line,hint) tuple, `sources` carries * the full list and `source` is the first source that triggered the * reason entry (deterministic: security → perf → karpathy order). */ readonly source: VerdictSource; /** * v2.13.2 — multi-source carrier. Always non-empty when the reason * was deduped across sources; equals `[source]` for single-source * entries. The dedup key uses (file,line,hint) only — not `source` — * per `.peaks/project-scan/audit-output-schema.md:73`. */ readonly sources: ReadonlyArray; readonly signal: AggregatorVerdict | 'blocked'; readonly severity?: 'CRITICAL' | 'HIGH' | 'MED' | 'LOW'; readonly file?: string; readonly line?: number; readonly hint?: string; readonly kind?: string; readonly actual?: number; readonly threshold?: number; readonly reportPath?: string; } export interface AggregatorResult { readonly verdict: AggregatorVerdict; readonly reasons: ReadonlyArray; } export declare const VERDICT_PRECEDENCE: ReadonlyArray; export declare function aggregateVerdict(input: AggregatorInput): AggregatorResult;