/** * Incident-cluster detector. Promoted from the inline TopPatternRow-coupled * implementation at `src/lib/top-patterns-render.ts:526-575` into a * generic, callable detector. Same algorithm; same conservative thresholds. * * Why it lives here: * - top_patterns and top_volume surface an "N incident cluster(s) * detected" callout when consecutive high-cost patterns share an * incident root. They import `detectIncidents` from this module. * - there is no standalone `log10x_find_incident_cluster` tool (the * agent could not act on its output); the library exists for the * in-tool callout described above. * * Algorithm summary: * Two patterns join into a cluster when they SHARE A SERVICE and meet * any of three thresholds on their descriptor tokens (length >= 3, * non-numeric): * 1. Jaccard >= 0.5 (strong direct overlap) * 2. overlap-coefficient >= 0.6 AND shared-tokens >= 3 (one * descriptor's vocabulary is contained in the other; e.g., raw * error vs same error wrapped in retry/flush text) * 3. Jaccard >= 0.2 AND Pearson correlation on the volume time * series >= 0.75 (weak text overlap but co-moving curves) * * Union-find collapses transitive joins. Conservative thresholds: * over-merging is the trap SIEMs fall into (Datadog Patterns, * Splunk clustering) and the differentiation comes from being * honest about distinct failures. * * Confidence reported per cluster reflects the strongest signal that * fired: * - 'jaccard_direct' → confidence = Jaccard (>= 0.5) * - 'overlap_shared' → confidence = overlap coef (>= 0.6) * - 'jaccard_with_correlation' → confidence = Pearson (>= 0.75) * * Returns only multi-member clusters (singletons are not "incidents"). */ /** Generic input row for incident clustering. */ export interface IncidentInput { /** Pattern identity (symbolMessage when available, templateHash otherwise). */ identity: string; /** Same-service requirement: only members of the same service can cluster. */ service?: string; /** Human-readable description; tokens drive overlap measures. */ descriptor: string; /** $/mo cost for this pattern, summed across cluster members in the output. */ costPerMonthUsd: number; /** Volume time series for Pearson correlation; can be empty. */ trendBytesPerSec?: number[]; } export interface IncidentCluster { members: Array<{ identity: string; costPerMonthUsd: number; descriptor: string; }>; /** Verbatim descriptor of the highest-cost member; not synthesized. */ representativeLabel: string; service: string; combinedMonthlyUsd: number; joinSignal: 'jaccard_direct' | 'overlap_shared' | 'jaccard_with_correlation'; /** Strength of the join signal that fired (Jaccard, overlap, or Pearson). */ confidence: number; } export declare const INCIDENT_JACCARD_DIRECT = 0.5; export declare const INCIDENT_OVERLAP_COEF = 0.6; export declare const INCIDENT_MIN_SHARED = 3; export declare const INCIDENT_JACCARD_WITH_CORR = 0.2; export declare const INCIDENT_CORR = 0.75; /** * Cluster a set of inputs into multi-member incidents. * * Cost: O(n^2) on token-set comparisons. Acceptable up to ~100 inputs * (the typical top_patterns limit). For larger inputs (e.g., wider * service slices), the caller should pre-slice by service first to * cap n. */ export declare function detectIncidents(inputs: IncidentInput[]): IncidentCluster[];