save progress

This commit is contained in:
StellaOps Bot
2026-01-02 21:06:27 +02:00
parent f46bde5575
commit 3f197814c5
441 changed files with 21545 additions and 4306 deletions

View File

@@ -0,0 +1,185 @@
// -----------------------------------------------------------------------------
// DistroDerivative.cs
// Sprint: SPRINT_20251230_001_BE_backport_resolver (BP-301, BP-302, BP-303, BP-304)
// Task: Create DistroDerivativeMapping model for cross-distro OVAL/CSAF evidence
// -----------------------------------------------------------------------------
using System.Collections.Frozen;
using System.Collections.Immutable;
namespace StellaOps.DistroIntel;
/// <summary>
/// Confidence level for derivative distro mappings.
/// Determines the confidence penalty applied when using evidence from a derivative.
/// </summary>
public enum DerivativeConfidence
{
/// <summary>
/// High confidence - ABI-compatible rebuilds.
/// Examples: AlmaLinux/Rocky → RHEL, CentOS → RHEL
/// Confidence multiplier: 0.95
/// </summary>
High,
/// <summary>
/// Medium confidence - Modified derivatives with some customizations.
/// Examples: Linux Mint → Ubuntu, Ubuntu → Debian
/// Confidence multiplier: 0.80
/// </summary>
Medium
}
/// <summary>
/// Represents a relationship between a canonical (parent) distro and a derivative.
/// Used for Tier 1 evidence fallback when native OVAL/CSAF is unavailable.
/// </summary>
/// <param name="CanonicalDistro">The parent/upstream distro identifier (e.g., "rhel", "debian").</param>
/// <param name="DerivativeDistro">The derivative distro identifier (e.g., "almalinux", "ubuntu").</param>
/// <param name="MajorRelease">The major release version for which this mapping applies.</param>
/// <param name="Confidence">Confidence level of the derivative relationship.</param>
public sealed record DistroDerivative(
string CanonicalDistro,
string DerivativeDistro,
int MajorRelease,
DerivativeConfidence Confidence);
/// <summary>
/// Static registry of distro derivative mappings for cross-distro evidence sharing.
/// </summary>
public static class DistroMappings
{
/// <summary>
/// All known distro derivative relationships.
/// Maps parent distros to their derivatives for OVAL/CSAF fallback.
/// </summary>
public static readonly ImmutableArray<DistroDerivative> Derivatives =
[
// RHEL family - High confidence (ABI-compatible rebuilds)
new DistroDerivative("rhel", "almalinux", 8, DerivativeConfidence.High),
new DistroDerivative("rhel", "almalinux", 9, DerivativeConfidence.High),
new DistroDerivative("rhel", "almalinux", 10, DerivativeConfidence.High),
new DistroDerivative("rhel", "rocky", 8, DerivativeConfidence.High),
new DistroDerivative("rhel", "rocky", 9, DerivativeConfidence.High),
new DistroDerivative("rhel", "rocky", 10, DerivativeConfidence.High),
new DistroDerivative("rhel", "centos", 7, DerivativeConfidence.High),
new DistroDerivative("rhel", "centos", 8, DerivativeConfidence.High), // CentOS 8 (EOL)
new DistroDerivative("rhel", "oracle", 7, DerivativeConfidence.High),
new DistroDerivative("rhel", "oracle", 8, DerivativeConfidence.High),
new DistroDerivative("rhel", "oracle", 9, DerivativeConfidence.High),
// Debian family - Medium confidence (modified derivatives)
new DistroDerivative("debian", "ubuntu", 10, DerivativeConfidence.Medium), // Debian 10 -> Ubuntu derivation
new DistroDerivative("debian", "ubuntu", 11, DerivativeConfidence.Medium), // Debian 11 (Bullseye)
new DistroDerivative("debian", "ubuntu", 12, DerivativeConfidence.Medium), // Debian 12 (Bookworm)
// Ubuntu derivatives - Medium confidence
new DistroDerivative("ubuntu", "linuxmint", 20, DerivativeConfidence.Medium), // Ubuntu 20.04 base
new DistroDerivative("ubuntu", "linuxmint", 21, DerivativeConfidence.Medium), // Ubuntu 21.04 base
new DistroDerivative("ubuntu", "linuxmint", 22, DerivativeConfidence.Medium), // Ubuntu 22.04 base
new DistroDerivative("ubuntu", "pop", 20, DerivativeConfidence.Medium), // Pop!_OS
new DistroDerivative("ubuntu", "pop", 22, DerivativeConfidence.Medium),
// SUSE family
new DistroDerivative("sles", "opensuse-leap", 15, DerivativeConfidence.High),
];
private static readonly FrozenDictionary<(string, int), ImmutableArray<DistroDerivative>> _byCanonicalIndex =
Derivatives
.GroupBy(d => (d.CanonicalDistro.ToLowerInvariant(), d.MajorRelease))
.ToFrozenDictionary(
g => g.Key,
g => g.ToImmutableArray());
private static readonly FrozenDictionary<(string, int), DistroDerivative?> _byDerivativeIndex =
Derivatives
.ToFrozenDictionary(
d => (d.DerivativeDistro.ToLowerInvariant(), d.MajorRelease),
d => (DistroDerivative?)d);
/// <summary>
/// Finds derivatives for a canonical (parent) distro at a specific major release.
/// Use this to find alternative evidence sources when native OVAL/CSAF is unavailable.
/// </summary>
/// <param name="canonicalDistro">The canonical distro identifier (e.g., "rhel").</param>
/// <param name="majorRelease">The major release version.</param>
/// <returns>Matching derivative mappings, ordered by confidence (High first).</returns>
/// <example>
/// var derivatives = DistroMappings.FindDerivativesFor("rhel", 9);
/// // Returns: [(rhel, almalinux, 9, High), (rhel, rocky, 9, High), (rhel, oracle, 9, High)]
/// </example>
public static IEnumerable<DistroDerivative> FindDerivativesFor(string canonicalDistro, int majorRelease)
{
var key = (canonicalDistro.ToLowerInvariant(), majorRelease);
if (_byCanonicalIndex.TryGetValue(key, out var derivatives))
{
return derivatives.OrderByDescending(d => d.Confidence);
}
return [];
}
/// <summary>
/// Finds the canonical (parent) distro for a derivative distro.
/// Use this to map a derivative back to its upstream source.
/// </summary>
/// <param name="derivativeDistro">The derivative distro identifier (e.g., "almalinux").</param>
/// <param name="majorRelease">The major release version.</param>
/// <returns>The canonical mapping if found, null otherwise.</returns>
/// <example>
/// var canonical = DistroMappings.FindCanonicalFor("almalinux", 9);
/// // Returns: (rhel, almalinux, 9, High)
/// </example>
public static DistroDerivative? FindCanonicalFor(string derivativeDistro, int majorRelease)
{
var key = (derivativeDistro.ToLowerInvariant(), majorRelease);
return _byDerivativeIndex.GetValueOrDefault(key);
}
/// <summary>
/// Gets the confidence multiplier for a derivative relationship.
/// Apply this to the base confidence when using derivative evidence.
/// </summary>
/// <param name="confidence">The derivative confidence level.</param>
/// <returns>Multiplier value (0.95 for High, 0.80 for Medium).</returns>
public static decimal GetConfidenceMultiplier(DerivativeConfidence confidence)
{
return confidence switch
{
DerivativeConfidence.High => 0.95m,
DerivativeConfidence.Medium => 0.80m,
_ => 0.70m // Unknown - conservative
};
}
/// <summary>
/// Checks if a distro is a known canonical (parent) distro.
/// </summary>
/// <param name="distro">The distro identifier to check.</param>
/// <returns>True if the distro is a known canonical distro.</returns>
public static bool IsCanonicalDistro(string distro)
{
var lower = distro.ToLowerInvariant();
return lower is "rhel" or "debian" or "ubuntu" or "sles" or "alpine";
}
/// <summary>
/// Normalizes a distro name to its canonical form.
/// </summary>
/// <param name="distro">The distro name to normalize.</param>
/// <returns>Lowercase canonical form.</returns>
public static string NormalizeDistroName(string distro)
{
var lower = distro.ToLowerInvariant();
return lower switch
{
"redhat" or "red hat" or "red-hat" => "rhel",
"alma" or "almalinux-os" => "almalinux",
"rockylinux" or "rocky-linux" => "rocky",
"oracle linux" or "oraclelinux" => "oracle",
"opensuse" or "opensuse-tumbleweed" => "opensuse-leap",
"mint" => "linuxmint",
"popos" or "pop_os" => "pop",
_ => lower
};
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RootNamespace>StellaOps.DistroIntel</RootNamespace>
</PropertyGroup>
</Project>