// Licensed to StellaOps under the BUSL-1.1 license. using StellaOps.ReachGraph.Schema; namespace StellaOps.ReachGraph.Deduplication; /// /// Extensions for edge deduplication. /// public static class EdgeDeduplicatorExtensions { /// /// Deduplicates edges using default extractors based on edge properties. /// /// The deduplicator instance. /// The edges to deduplicate. /// The vulnerability ID to associate with edges. /// Default source ID if not specified. /// Time provider for timestamps. /// Deduplicated edges. public static IReadOnlyList DeduplicateWithDefaults( this IEdgeDeduplicator deduplicator, IEnumerable edges, string vulnerabilityId, string defaultSource = "unknown", TimeProvider? timeProvider = null) { var time = timeProvider ?? TimeProvider.System; var now = time.GetUtcNow(); return deduplicator.Deduplicate( edges, keyExtractor: e => new EdgeSemanticKey(e.From, e.To, vulnerabilityId), sourceExtractor: _ => defaultSource, strengthExtractor: e => GetEdgeStrength(e.Why), timestampExtractor: _ => now); } private static double GetEdgeStrength(EdgeExplanation explanation) { var typeMultiplier = explanation.Type switch { EdgeExplanationType.DirectCall => 1.0, EdgeExplanationType.Import => 0.95, EdgeExplanationType.DynamicLoad => 0.9, EdgeExplanationType.Ffi => 0.85, EdgeExplanationType.Reflection => 0.8, EdgeExplanationType.LoaderRule => 0.75, EdgeExplanationType.TaintGate => 0.7, EdgeExplanationType.EnvGuard => 0.65, EdgeExplanationType.FeatureFlag => 0.6, EdgeExplanationType.PlatformArch => 0.6, EdgeExplanationType.Unknown => 0.5, _ => 0.5 }; return explanation.Confidence * typeMultiplier; } }