partly or unimplemented features - now implemented
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// CrossDistroCoverageModels.cs
|
||||
// Sprint: SPRINT_20260208_027_BinaryIndex_cross_distro_golden_set_for_backport_validation
|
||||
// Task: T1 — Cross-distro coverage matrix models for backport validation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.BinaryIndex.GoldenSet;
|
||||
|
||||
/// <summary>
|
||||
/// Supported Linux distributions for cross-distro backport validation.
|
||||
/// </summary>
|
||||
public enum DistroFamily
|
||||
{
|
||||
/// <summary>Alpine Linux (musl libc, APK).</summary>
|
||||
Alpine = 0,
|
||||
|
||||
/// <summary>Debian / Ubuntu (glibc, DEB).</summary>
|
||||
Debian = 1,
|
||||
|
||||
/// <summary>RHEL / CentOS / Fedora (glibc, RPM).</summary>
|
||||
Rhel = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Backport status for a given CVE on a specific distribution version.
|
||||
/// </summary>
|
||||
public enum BackportStatus
|
||||
{
|
||||
/// <summary>Fix has not been applied (still vulnerable).</summary>
|
||||
NotPatched = 0,
|
||||
|
||||
/// <summary>Fix has been backported to the package version.</summary>
|
||||
Backported = 1,
|
||||
|
||||
/// <summary>The component was removed or is not applicable.</summary>
|
||||
NotApplicable = 2,
|
||||
|
||||
/// <summary>Backport status is unknown or not yet validated.</summary>
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single distro-version coverage entry in the cross-distro matrix.
|
||||
/// Tracks whether a given CVE's fix has been backported to a specific distro version.
|
||||
/// </summary>
|
||||
public sealed record DistroCoverageEntry
|
||||
{
|
||||
/// <summary>Distribution family (Alpine, Debian, RHEL).</summary>
|
||||
public required DistroFamily Distro { get; init; }
|
||||
|
||||
/// <summary>Distro release version (e.g., "3.18", "bookworm", "9").</summary>
|
||||
public required string Version { get; init; }
|
||||
|
||||
/// <summary>Package name in the distro's packaging system.</summary>
|
||||
public required string PackageName { get; init; }
|
||||
|
||||
/// <summary>Package version string in the distro's format.</summary>
|
||||
public required string PackageVersion { get; init; }
|
||||
|
||||
/// <summary>Backport status for this entry.</summary>
|
||||
public required BackportStatus Status { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the golden set definition has been validated against
|
||||
/// a real binary from this distro version.
|
||||
/// </summary>
|
||||
public bool Validated { get; init; }
|
||||
|
||||
/// <summary>When this entry was last validated (null if never).</summary>
|
||||
public DateTimeOffset? ValidatedAt { get; init; }
|
||||
|
||||
/// <summary>Optional notes (e.g., patch commit hash, advisory URL).</summary>
|
||||
public string? Notes { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A curated high-impact CVE entry with cross-distro coverage information.
|
||||
/// Represents one row in the "golden set" of curated cross-distro test cases.
|
||||
/// </summary>
|
||||
public sealed record CuratedCveEntry
|
||||
{
|
||||
/// <summary>CVE identifier (e.g., "CVE-2014-0160").</summary>
|
||||
public required string CveId { get; init; }
|
||||
|
||||
/// <summary>Affected component (e.g., "openssl", "sudo").</summary>
|
||||
public required string Component { get; init; }
|
||||
|
||||
/// <summary>Human-readable vulnerability name (e.g., "Heartbleed").</summary>
|
||||
public string? CommonName { get; init; }
|
||||
|
||||
/// <summary>CVSS score (0.0 – 10.0).</summary>
|
||||
public double? CvssScore { get; init; }
|
||||
|
||||
/// <summary>CWE identifiers associated with this CVE.</summary>
|
||||
public ImmutableArray<string> CweIds { get; init; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Per-distro coverage entries showing backport status.
|
||||
/// Keyed by (Distro, Version) for efficient lookup.
|
||||
/// </summary>
|
||||
public required ImmutableArray<DistroCoverageEntry> Coverage { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the golden set definition for this CVE.
|
||||
/// Null if not yet linked to a validated golden set.
|
||||
/// </summary>
|
||||
public string? GoldenSetId { get; init; }
|
||||
|
||||
/// <summary>When this curated entry was created.</summary>
|
||||
public required DateTimeOffset CreatedAt { get; init; }
|
||||
|
||||
/// <summary>When this curated entry was last updated.</summary>
|
||||
public DateTimeOffset? UpdatedAt { get; init; }
|
||||
|
||||
/// <summary>Number of distro-version entries that have been validated.</summary>
|
||||
public int ValidatedCount => Coverage.IsDefaultOrEmpty ? 0 : Coverage.Count(c => c.Validated);
|
||||
|
||||
/// <summary>Total number of distro-version entries.</summary>
|
||||
public int TotalEntries => Coverage.IsDefaultOrEmpty ? 0 : Coverage.Length;
|
||||
|
||||
/// <summary>Coverage ratio [0.0, 1.0].</summary>
|
||||
public double CoverageRatio => TotalEntries == 0 ? 0.0 : (double)ValidatedCount / TotalEntries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggregated coverage summary across all curated CVEs.
|
||||
/// </summary>
|
||||
public sealed record CrossDistroCoverageSummary
|
||||
{
|
||||
/// <summary>Total curated CVEs in the matrix.</summary>
|
||||
public required int TotalCves { get; init; }
|
||||
|
||||
/// <summary>Total distro-version entries across all CVEs.</summary>
|
||||
public required int TotalEntries { get; init; }
|
||||
|
||||
/// <summary>Number of validated entries.</summary>
|
||||
public required int ValidatedEntries { get; init; }
|
||||
|
||||
/// <summary>Number of entries where the fix is backported.</summary>
|
||||
public required int BackportedCount { get; init; }
|
||||
|
||||
/// <summary>Number of entries where the component is not patched.</summary>
|
||||
public required int NotPatchedCount { get; init; }
|
||||
|
||||
/// <summary>Per-distro breakdown.</summary>
|
||||
public required ImmutableDictionary<DistroFamily, DistroBreakdown> ByDistro { get; init; }
|
||||
|
||||
/// <summary>Overall validation coverage ratio [0.0, 1.0].</summary>
|
||||
public double OverallCoverage => TotalEntries == 0 ? 0.0 : (double)ValidatedEntries / TotalEntries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Per-distro breakdown within the coverage summary.
|
||||
/// </summary>
|
||||
public sealed record DistroBreakdown
|
||||
{
|
||||
/// <summary>Number of entries for this distro family.</summary>
|
||||
public required int EntryCount { get; init; }
|
||||
|
||||
/// <summary>Number of validated entries for this distro.</summary>
|
||||
public required int ValidatedCount { get; init; }
|
||||
|
||||
/// <summary>Number of backported entries for this distro.</summary>
|
||||
public required int BackportedCount { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query parameters for filtering curated CVE entries.
|
||||
/// </summary>
|
||||
public sealed record CuratedCveQuery
|
||||
{
|
||||
/// <summary>Filter by component name (case-insensitive substring).</summary>
|
||||
public string? Component { get; init; }
|
||||
|
||||
/// <summary>Filter by distro family.</summary>
|
||||
public DistroFamily? Distro { get; init; }
|
||||
|
||||
/// <summary>Filter by backport status.</summary>
|
||||
public BackportStatus? Status { get; init; }
|
||||
|
||||
/// <summary>Only return entries that haven't been validated yet.</summary>
|
||||
public bool OnlyUnvalidated { get; init; }
|
||||
|
||||
/// <summary>Maximum results to return.</summary>
|
||||
public int Limit { get; init; } = 100;
|
||||
|
||||
/// <summary>Offset for paging.</summary>
|
||||
public int Offset { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user