up
This commit is contained in:
@@ -30,8 +30,10 @@ internal static class ReachabilityFactDigestCalculator
|
||||
EntryPoints: NormalizeList(fact.EntryPoints),
|
||||
States: NormalizeStates(fact.States),
|
||||
RuntimeFacts: NormalizeRuntimeFacts(fact.RuntimeFacts),
|
||||
UncertaintyStates: NormalizeUncertaintyStates(fact.Uncertainty),
|
||||
Metadata: NormalizeMetadata(fact.Metadata),
|
||||
Score: fact.Score,
|
||||
RiskScore: fact.RiskScore,
|
||||
UnknownsCount: fact.UnknownsCount,
|
||||
UnknownsPressure: fact.UnknownsPressure,
|
||||
ComputedAt: fact.ComputedAt);
|
||||
@@ -122,6 +124,44 @@ internal static class ReachabilityFactDigestCalculator
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private static List<CanonicalUncertaintyState> NormalizeUncertaintyStates(UncertaintyDocument? uncertainty)
|
||||
{
|
||||
if (uncertainty?.States is not { Count: > 0 })
|
||||
{
|
||||
return new List<CanonicalUncertaintyState>();
|
||||
}
|
||||
|
||||
return uncertainty.States
|
||||
.Where(s => s is not null && !string.IsNullOrWhiteSpace(s.Code))
|
||||
.Select(s => new CanonicalUncertaintyState(
|
||||
Code: s.Code.Trim(),
|
||||
Name: s.Name?.Trim() ?? string.Empty,
|
||||
Entropy: Math.Clamp(s.Entropy, 0.0, 1.0),
|
||||
Evidence: NormalizeUncertaintyEvidence(s.Evidence),
|
||||
Timestamp: s.Timestamp))
|
||||
.OrderBy(s => s.Code, StringComparer.Ordinal)
|
||||
.ThenBy(s => s.Name, StringComparer.Ordinal)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static List<CanonicalUncertaintyEvidence> NormalizeUncertaintyEvidence(IEnumerable<UncertaintyEvidenceDocument>? evidence)
|
||||
{
|
||||
if (evidence is null)
|
||||
{
|
||||
return new List<CanonicalUncertaintyEvidence>();
|
||||
}
|
||||
|
||||
return evidence
|
||||
.Select(e => new CanonicalUncertaintyEvidence(
|
||||
Type: e.Type?.Trim() ?? string.Empty,
|
||||
SourceId: e.SourceId?.Trim() ?? string.Empty,
|
||||
Detail: e.Detail?.Trim() ?? string.Empty))
|
||||
.OrderBy(e => e.Type, StringComparer.Ordinal)
|
||||
.ThenBy(e => e.SourceId, StringComparer.Ordinal)
|
||||
.ThenBy(e => e.Detail, StringComparer.Ordinal)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private sealed record CanonicalReachabilityFact(
|
||||
string CallgraphId,
|
||||
string SubjectKey,
|
||||
@@ -129,8 +169,10 @@ internal static class ReachabilityFactDigestCalculator
|
||||
List<string> EntryPoints,
|
||||
List<CanonicalState> States,
|
||||
List<CanonicalRuntimeFact> RuntimeFacts,
|
||||
List<CanonicalUncertaintyState> UncertaintyStates,
|
||||
SortedDictionary<string, string?> Metadata,
|
||||
double Score,
|
||||
double RiskScore,
|
||||
int UnknownsCount,
|
||||
double UnknownsPressure,
|
||||
DateTimeOffset ComputedAt);
|
||||
@@ -167,4 +209,16 @@ internal static class ReachabilityFactDigestCalculator
|
||||
int HitCount,
|
||||
DateTimeOffset? ObservedAt,
|
||||
SortedDictionary<string, string?> Metadata);
|
||||
|
||||
private sealed record CanonicalUncertaintyState(
|
||||
string Code,
|
||||
string Name,
|
||||
double Entropy,
|
||||
List<CanonicalUncertaintyEvidence> Evidence,
|
||||
DateTimeOffset? Timestamp);
|
||||
|
||||
private sealed record CanonicalUncertaintyEvidence(
|
||||
string Type,
|
||||
string SourceId,
|
||||
string Detail);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user