/** * QA360 Evidence Vault Engine * SQLite WAL-based storage with idempotence and CAS integration */ import { CASArtifact } from './cas.js'; export interface VaultConfig { baseDir: string; enableWAL?: boolean; maxConnections?: number; retentionDays?: number; } export interface RunRecord { id: string; run_key?: string; started_at: number; ended_at?: number; pack_hash: string; pack_path: string; status: 'running' | 'passed' | 'failed' | 'cancelled' | 'error'; trust_score?: number; weights_json?: string; sign_alg?: string; signature_hex?: string; proof_pdf_path?: string; pinned: number; created_at: number; updated_at: number; } export interface GateRecord { id?: number; run_id: string; name: string; status: 'passed' | 'failed' | 'skipped' | 'warn'; duration_ms?: number; metrics_json?: string; budgets_json?: string; started_at?: number; ended_at?: number; created_at: number; } export interface FindingRecord { id?: number; run_id: string; gate: string; severity: 'info' | 'low' | 'medium' | 'high' | 'critical'; rule: string; location?: string; message: string; raw_output?: string; fingerprint?: string; created_at: number; } /** * Flakiness history record - tracks test reliability over time */ export interface FlakinessRecord { id?: number; run_id: string; test_id: string; test_name: string; gate: string; file_path: string; score: number; category: 'legendary' | 'solid' | 'good' | 'shaky' | 'unstable'; total_runs: number; successful_runs: number; avg_duration_ms: number; pattern_type?: string; suggested_fix?: string; confidence?: number; first_seen: number; last_seen: number; current_streak?: number; streak_type?: 'pass' | 'fail'; created_at: number; } /** * Flakiness pattern detection record */ export interface FlakinessPatternRecord { id?: number; test_id: string; test_name: string; pattern_type: 'timing' | 'race_condition' | 'external_dependency' | 'environment_specific' | 'selector_issue' | 'unknown'; description: string; suggested_fix: string; confidence: number; auto_fix_possible: boolean; first_detected: number; last_detected: number; detection_count: number; created_at: number; updated_at: number; } /** * Flakiness quarantine record */ export interface QuarantineRecord { id?: number; test_id: string; test_name: string; gate: string; file_path: string; reason: string; score: number; category: 'shaky' | 'unstable'; quarantined_at: number; quarantined_by: string; resolved_at?: number; resolved_by?: string; notes?: string; created_at: number; updated_at: number; } export interface ArtifactRecord { sha256: string; mime_type: string; size_bytes: number; cas_path: string; original_name?: string; created_at: number; last_accessed: number; } export interface RunArtifactLink { run_id: string; sha256: string; label: string; created_at: number; } export interface BeginRunOptions { run_key?: string; pack_path: string; pack_hash: string; weights?: Record; started_at?: number; } export interface FinishRunOptions { status: 'passed' | 'failed' | 'cancelled' | 'error'; trust_score?: number; signature?: string; proof_pdf_sha?: string; weights?: Record; } export interface RunFilters { status?: string[]; since?: Date; until?: Date; pack_hash?: string; limit?: number; offset?: number; } export interface VaultStats { totalRuns: number; totalGates: number; totalFindings: number; totalArtifacts: number; vaultSizeBytes: number; oldestRun?: Date; newestRun?: Date; } export declare class EvidenceVault { private db; private cas; private redactor; private readonly dbPath; private readonly baseDir; constructor(config: VaultConfig); /** * Open vault connection and initialize schema */ static open(baseDir: string, config?: Partial): Promise; /** * Begin a new run with idempotence support */ beginRun(options: BeginRunOptions): Promise<{ runId: string; isReused: boolean; }>; /** * Finish a run with final status and signature */ finishRun(runId: string, options: FinishRunOptions): Promise; /** * Record gate execution result */ recordGate(runId: string, gate: Omit): Promise; /** * Record security/quality finding */ recordFinding(runId: string, finding: Omit): Promise; /** * Record flakiness analysis result */ recordFlakiness(runId: string, flakiness: Omit): Promise; /** * Record detected flakiness pattern */ recordFlakinessPattern(pattern: Omit): Promise; /** * Add test to quarantine */ addToQuarantine(quarantine: Omit): Promise; /** * Remove test from quarantine */ removeFromQuarantine(testId: string, resolvedBy: string, notes?: string): Promise; /** * Get flakiness history for a test */ getFlakinessHistory(testId: string, limit?: number): Promise; /** * Get flakiness history for a run */ getRunFlakiness(runId: string): Promise; /** * Get all quarantined tests */ getQuarantinedTests(includeResolved?: boolean): Promise; /** * Get quarantine record for a test */ getQuarantine(testId: string): Promise; /** * Get flakiness pattern for a test */ getFlakinessPattern(testId: string, patternType: string): Promise; /** * Get flakiness trends for a test */ getFlakinessTrends(testId: string, days?: number): Promise<{ testId: string; currentScore: number; averageScore: number; trend: 'improving' | 'stable' | 'degrading'; dataPoints: Array<{ date: number; score: number; }>; }>; /** * Store artifact in CAS and link to run */ storeArtifact(runId: string, content: Buffer, mimeType: string, label: string, originalName?: string): Promise; /** * Attach existing artifact to run */ attachArtifact(runId: string, link: { sha256: string; label: string; }): Promise; /** * Get run by ID */ getRun(runId: string): Promise; /** * Get run by ID prefix (e.g., "6ce422f7" for shortened display) * Returns null if multiple or no runs match the prefix */ getRunByPrefix(prefix: string): Promise; /** * Get run by run_key */ getRunByKey(runKey: string): Promise; /** * List runs with filters */ listRuns(filters?: RunFilters): Promise; /** * Get gates for a run */ getGates(runId: string): Promise; /** * Get findings for a run */ getFindings(runId: string, gate?: string): Promise; /** * Get artifacts for a run */ getRunArtifacts(runId: string): Promise>; /** * Get artifact by SHA256 */ getArtifact(sha256: string): Promise; /** * Pin/unpin run to protect from GC */ pinRun(runId: string, pinned?: boolean): Promise; /** * Calculate pack hash for idempotence */ static calculatePackHash(packContent: string): string; /** * Get vault statistics */ getStats(): Promise; private insertRun; private updateRun; private insertGate; private insertFinding; private insertArtifact; private insertRunArtifact; private insertFlakiness; private insertFlakinessPattern; private updateFlakinessPattern; private insertQuarantine; private updateQuarantine; private generateFindingFingerprint; /** * Initialize database connection */ private initializeDatabase; /** * Initialize database schema */ initializeSchema(): Promise; /** * Ensure required directories exist */ private ensureDirectories; /** * Close database connection */ close(): Promise; }