/** * Shared types for the real-time verification pipeline. * * Phase 2 of the 10x roadmap: verify code as it streams from the LLM, * not after generation completes. */ import type { BayesianAnomalyScore, VerificationDepth } from '../bayesian/types.js'; export type { BayesianAnomalyScore, VerificationDepth } from '../bayesian/types.js'; export type CodeUnitKind = 'statement' | 'function' | 'block' | 'line'; export interface CodeUnit { /** The complete code text for this unit */ text: string; /** What kind of code structure completed */ kind: CodeUnitKind; /** Byte offset in the full buffer where this unit starts */ startOffset: number; /** Byte offset in the full buffer where this unit ends */ endOffset: number; /** Detected or configured language */ language: string; } export type CheckSeverity = 'critical' | 'high' | 'medium' | 'low'; export interface StreamingCheck { /** Unique identifier (e.g. 'sql_parameterized', 'learned_rule_42') */ id: string; /** Human-readable name */ name: string; /** Languages this check applies to (empty = all) */ languages: string[]; /** Pre-compiled regex pattern */ pattern: RegExp; /** What a match means */ verdict: 'FAIL' | 'PASS'; /** Severity when this check triggers a FAIL */ severity: CheckSeverity; /** Human-readable evidence template (may include $1, $2 for captures) */ evidenceTemplate: string; /** Optional fix suggestion */ suggestion?: string; /** Source: 'formal' (hand-crafted) or 'learned' (from rule catalog) */ source: 'formal' | 'learned'; /** * Optional context keywords for relevance filtering. * If set, this check only runs when at least one keyword appears * in the code unit text (case-insensitive). If unset, the check * runs against all code units (no filtering). */ contextKeywords?: string[]; /** * Optional suppression patterns. If ANY pattern matches the code unit text, * the check is suppressed (finding is not emitted). Used for safe-by-design * libraries like postgres.js tagged template literals. */ suppressWhen?: RegExp[]; } export interface CompiledCheckSet { /** All checks, pre-filtered by language and pre-compiled */ checks: StreamingCheck[]; /** Language these checks are filtered for */ language: string; /** Time taken to compile (ms) */ compileTimeMs: number; } export interface VerificationEvent { /** Finding or pass */ type: 'finding' | 'pass'; /** The code unit that was checked */ codeUnit: CodeUnit; /** Which check produced this event */ checkId: string; /** Check name */ checkName: string; /** Pass or fail */ verdict: 'PASS' | 'FAIL'; /** Evidence string explaining the verdict */ evidence: string; /** Severity (only meaningful for FAIL) */ severity: CheckSeverity; /** Fix suggestion if available */ suggestion?: string; /** How long this check took (ms) */ latencyMs: number; /** * Entropy context from logprob analysis (only present when provider='openai'). * Provides model confidence signal alongside pattern-based findings. */ entropyContext?: EntropyContext; } /** * Per-code-unit entropy context from the logprob stream. * Attached to VerificationEvents to combine pattern checks with * model confidence signals. * * The combination creates a 2D signal: * - Pattern match + high entropy = escalated (model is uncertain AND code looks bad) * - Pattern match + low entropy = confident bad code (most dangerous — model doesn't doubt it) * - No pattern + high entropy = review flag (model is uncertain, may be confabulating) * - No pattern + low entropy = likely correct (model is confident, no bad patterns) */ export interface EntropyContext { /** Mean per-token entropy for the tokens in this code unit */ meanEntropy: number; /** Fraction of tokens with entropy > tokenThreshold */ highEntropyFraction: number; /** Max single-token entropy in this unit */ maxEntropy: number; /** Number of tokens in this unit */ tokenCount: number; /** Confidence label derived from entropy */ confidence: 'high' | 'medium' | 'low'; /** Entropy standard deviation — hallucinated code has different variance */ entropyStd: number; /** Mean absolute first derivative of entropy (token-to-token change rate) */ entropyDiffMean: number; /** Max absolute first derivative (largest single entropy jump) */ entropyDiffMax: number; /** Mean absolute second derivative (acceleration of entropy changes) */ entropyAccelMean: number; /** Max variance within 16-token sliding windows (top feature for GPT-5.4) */ windowMaxVariance: number; /** Logprob gap std — variation in how decisive the model's top choice is */ logprobGapStd: number; /** Fraction of tokens where second-best choice > 30% probability of first */ competitiveFraction: number; /** Hallucination probability from dynamics-based classifier (0-1) */ dynamicsScore: number; /** Full BAS result when computed (null when logprobs unavailable) */ bas?: BayesianAnomalyScore; /** Adaptive verification depth derived from BAS score */ verificationDepth?: VerificationDepth; } export interface StreamingVerifierStats { /** Total code units processed */ unitsProcessed: number; /** Total individual checks run */ checksRun: number; /** Total findings (FAIL verdicts) */ findings: number; /** Average latency per code unit (ms) */ avgLatencyMs: number; /** Max latency for any single code unit (ms) */ maxLatencyMs: number; /** Total elapsed time (ms) */ totalTimeMs: number; } export interface CorrectionResult { /** The re-generated segment after correction */ correctedText: string; /** The original text that was wrong */ originalText: string; /** The finding that triggered correction */ finding: VerificationEvent; /** Tokens consumed for the correction */ tokensUsed: number; }