Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
216
src/__Libraries/StellaOps.Metrics/Kpi/KpiModels.cs
Normal file
216
src/__Libraries/StellaOps.Metrics/Kpi/KpiModels.cs
Normal file
@@ -0,0 +1,216 @@
|
||||
namespace StellaOps.Metrics.Kpi;
|
||||
|
||||
/// <summary>
|
||||
/// Quality KPIs for explainable triage.
|
||||
/// </summary>
|
||||
public sealed record TriageQualityKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Reporting period start.
|
||||
/// </summary>
|
||||
public required DateTimeOffset PeriodStart { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reporting period end.
|
||||
/// </summary>
|
||||
public required DateTimeOffset PeriodEnd { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Tenant ID (null for global).
|
||||
/// </summary>
|
||||
public string? TenantId { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reachability KPIs.
|
||||
/// </summary>
|
||||
public required ReachabilityKpis Reachability { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Runtime KPIs.
|
||||
/// </summary>
|
||||
public required RuntimeKpis Runtime { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Explainability KPIs.
|
||||
/// </summary>
|
||||
public required ExplainabilityKpis Explainability { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Replay/Determinism KPIs.
|
||||
/// </summary>
|
||||
public required ReplayKpis Replay { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Unknown budget KPIs.
|
||||
/// </summary>
|
||||
public required UnknownBudgetKpis Unknowns { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Operational KPIs.
|
||||
/// </summary>
|
||||
public required OperationalKpis Operational { get; init; }
|
||||
}
|
||||
|
||||
public sealed record ReachabilityKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Total findings analyzed.
|
||||
/// </summary>
|
||||
public required int TotalFindings { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Findings with non-UNKNOWN reachability.
|
||||
/// </summary>
|
||||
public required int WithKnownReachability { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Percentage with known reachability.
|
||||
/// </summary>
|
||||
public decimal PercentKnown => TotalFindings > 0
|
||||
? (decimal)WithKnownReachability / TotalFindings * 100
|
||||
: 0;
|
||||
|
||||
/// <summary>
|
||||
/// Breakdown by reachability state.
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<string, int> ByState { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Findings confirmed unreachable.
|
||||
/// </summary>
|
||||
public int ConfirmedUnreachable =>
|
||||
ByState.GetValueOrDefault("ConfirmedUnreachable", 0);
|
||||
|
||||
/// <summary>
|
||||
/// Noise reduction (unreachable / total).
|
||||
/// </summary>
|
||||
public decimal NoiseReductionPercent => TotalFindings > 0
|
||||
? (decimal)ConfirmedUnreachable / TotalFindings * 100
|
||||
: 0;
|
||||
}
|
||||
|
||||
public sealed record RuntimeKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Total findings in environments with sensors.
|
||||
/// </summary>
|
||||
public required int TotalWithSensorDeployed { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Findings with runtime observations.
|
||||
/// </summary>
|
||||
public required int WithRuntimeCorroboration { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Coverage percentage.
|
||||
/// </summary>
|
||||
public decimal CoveragePercent => TotalWithSensorDeployed > 0
|
||||
? (decimal)WithRuntimeCorroboration / TotalWithSensorDeployed * 100
|
||||
: 0;
|
||||
|
||||
/// <summary>
|
||||
/// Breakdown by posture.
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<string, int> ByPosture { get; init; }
|
||||
}
|
||||
|
||||
public sealed record ExplainabilityKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Total verdicts generated.
|
||||
/// </summary>
|
||||
public required int TotalVerdicts { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Verdicts with reason steps.
|
||||
/// </summary>
|
||||
public required int WithReasonSteps { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Verdicts with at least one proof pointer.
|
||||
/// </summary>
|
||||
public required int WithProofPointer { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Verdicts that are "complete" (both reason steps AND proof pointer).
|
||||
/// </summary>
|
||||
public required int FullyExplainable { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Explainability completeness percentage.
|
||||
/// </summary>
|
||||
public decimal CompletenessPercent => TotalVerdicts > 0
|
||||
? (decimal)FullyExplainable / TotalVerdicts * 100
|
||||
: 0;
|
||||
}
|
||||
|
||||
public sealed record ReplayKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Total replay attempts.
|
||||
/// </summary>
|
||||
public required int TotalAttempts { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Successful replays (identical verdict).
|
||||
/// </summary>
|
||||
public required int Successful { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Replay success rate.
|
||||
/// </summary>
|
||||
public decimal SuccessRate => TotalAttempts > 0
|
||||
? (decimal)Successful / TotalAttempts * 100
|
||||
: 0;
|
||||
|
||||
/// <summary>
|
||||
/// Common failure reasons.
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<string, int> FailureReasons { get; init; }
|
||||
}
|
||||
|
||||
public sealed record UnknownBudgetKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Total environments tracked.
|
||||
/// </summary>
|
||||
public required int TotalEnvironments { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Budget breaches by environment.
|
||||
/// </summary>
|
||||
public required IReadOnlyDictionary<string, int> BreachesByEnvironment { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Total overrides/exceptions granted.
|
||||
/// </summary>
|
||||
public required int OverridesGranted { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Average override age (days).
|
||||
/// </summary>
|
||||
public decimal AvgOverrideAgeDays { get; init; }
|
||||
}
|
||||
|
||||
public sealed record OperationalKpis
|
||||
{
|
||||
/// <summary>
|
||||
/// Median time to first verdict (seconds).
|
||||
/// </summary>
|
||||
public required double MedianTimeToVerdictSeconds { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Cache hit rate for graphs/proofs.
|
||||
/// </summary>
|
||||
public required decimal CacheHitRate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Average evidence size per scan (bytes).
|
||||
/// </summary>
|
||||
public required long AvgEvidenceSizeBytes { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 95th percentile verdict time (seconds).
|
||||
/// </summary>
|
||||
public required double P95VerdictTimeSeconds { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user