import type { CanonicalFieldRole, JsonValue } from './canonical-model'; export type ComparisonLifecycle = | 'new' | 'persistent' | 'resolved' | 'reoccurred' | 'possibly-identical' | 'not-comparable'; export type ComparisonMatchMethod = | 'local-rule' | 'canonical-definition' | 'tool-rule-id' | 'framework-control' | 'rule-asset' | 'feature-combination' | 'similarity-suggestion' | 'none'; export type ComparisonDecision = 'automatic' | 'user-confirmed' | 'suggested' | 'unmatched'; export interface ComparisonMatch { method: ComparisonMatchMethod; decision: ComparisonDecision; confidence: number; reasons: string[]; } export type FindingChangeKind = 'severity' | 'status' | 'score' | 'asset' | 'evidence'; export interface FindingChange { kind: FindingChangeKind; before: JsonValue; after: JsonValue; } export interface FindingComparison { baselineOccurrenceId?: string; targetOccurrenceId?: string; historicalOccurrenceId?: string; lifecycle: ComparisonLifecycle; match: ComparisonMatch; changes: FindingChange[]; } export interface ComparisonSummary { total: number; new: number; persistent: number; resolved: number; reoccurred: number; possiblyIdentical: number; notComparable: number; changedSeverity: number; changedStatus: number; changedEvidence: number; } export interface ScanRunComparison { version: 1; baselineRunId: string; targetRunId: string; results: FindingComparison[]; summary: ComparisonSummary; diagnostics: string[]; } export interface ComparisonRuleEndpoint { toolId?: string; ruleId?: string; canonicalKey?: string; title?: string; asset?: string; } export interface LocalComparisonRule { version: 1; id: string; left: ComparisonRuleEndpoint; right: ComparisonRuleEndpoint; source: 'user-confirmed'; note?: string; } export interface ComparisonOptions { localRules?: LocalComparisonRule[]; similarityThreshold?: number; comparisonKeysByTool?: Record; }