# ARCHIVED > **Archived:** 2025-12-22 > **Reason:** Gap analysis complete. Recommendations incorporated into sprints and documentation. > > **Implementation Artifacts:** > - SPRINT_2000_0003_0001: Alpine connector and APK comparator > - SPRINT_2000_0003_0002: Comprehensive distro version tests (50-100 per distro) > - SPRINT_4000_0002_0001: Backport UX explainability ("Compared with" badge, "Why Fixed" popover) > - SPRINT_6000_SUMMARY.md: Updated to reference existing Concelier comparators > - `src/Concelier/AGENTS.md`: Added distro backport version handling section > > **Existing Implementations Validated:** > - `src/Concelier/__Libraries/StellaOps.Concelier.Merge/Comparers/Nevra.cs` (RPM) > - `src/Concelier/__Libraries/StellaOps.Concelier.Merge/Comparers/DebianEvr.cs` (Debian/Ubuntu) > - Distro connectors: Debian, Ubuntu, RedHat, SUSE --- Here's a quick, practical heads-up on **patch-aware backport handling** so your vulnerability verdicts don't go sideways. ![Package versions concept diagram](attachment\:image) ### Why this matters Distros often **backport fixes** without bumping the upstream version. If you compare versions with a generic SemVer library, you can mislabel **fixed** builds as **vulnerable** (or the reverse). ### Use distro-native comparators (not SemVer) * **RPM (RHEL/CentOS/Fedora/openSUSE):** compare using **EVR** (`epoch:version-release`) via `rpmvercmp`. Tilde `~` sorts **before** anything; releases matter (e.g., `1.2-3.el9_2` > `1.2-3`). * **Debian/Ubuntu:** compare **epoch >> upstream_version >> debian_revision** using `dpkg --compare-versions` rules. Tilde `~` sorts **lower** than empty, so `2.0~rc1` < `2.0`. * **Alpine (APK):** follows its own comparator; treat `-r` (pkgrel) as part of ordering, similar in spirit to RPM release. ### Practical rules for your scanner (Stella Ops / Feedser -> Vexer) 1. **Normalize the package coordinate** * RPM: `name:evr.arch` (epoch default 0 if missing). * DEB: `name:epoch:upstream_version-debian_revision arch`. * Keep the **distro release**/revision; it encodes backports. 2. **Compare with native engines** * On Linux hosts/containers, call the system tool when possible: * RPM: `rpm --qf '%{EPOCH}:%{VERSION}-%{RELEASE}\n' -q ` then use `rpmdev-vercmp`/`rpmvercmp`. * DEB/Ubuntu: `dpkg-query -W -f='${Version}\n' ` and `dpkg --compare-versions`. * In offline analysis, embed battle-tested comparators (ports of `rpmvercmp` and `dpkg` logic) in your evaluator. 3. **Model advisories with distro ranges** * Store **per-ecosystem fixed ranges**: * RPM example: `fixed >= 2:1.4.3-5.el9_3` * DEB example: `fixed >= 1:1.4.3-5+deb12u2` * Do **not** rewrite to SemVer; keep native forms. 4. **VEX/decisioning** * When upstream says "fixed in 1.4.4" but **distro claims fixed in 1.4.3-5~deb12u2**, prefer distro channel **if source is trusted**. * Record **evidence**: source (DSA/RHSA/USN), comparator used, installed EVR/DEB version, fixed threshold, and result. Attach to the verdict. 5. **Edge cases to test** * Epoch jumps: `1:1.2-1` > `0:9.9-9`. * Tilde pre-releases: `2.0~rc1` < `2.0`. * Release qualifiers: `1.2-3.el9_2` < `1.2-3.el9_3`. * Rebuilds/backports: `1.2-3ubuntu0.1` vs `1.2-3`. ### Minimal implementation sketch (C#) * **Strategy pattern**: `IVersionComparator` with implementations `RpmComparator`, `DpkgComparator`, `ApkComparator`. * **Selector** by package source (`rpmdb`, `dpkg-status`, `apk info`). * **Evidence struct**: ```csharp record VersionVerdict( string Pkg, string Distro, string Installed, string Fixed, string Comparator, bool IsFixed, string EvidenceSource, string[] ProofLines); ``` * **Fallback**: If native comparator unavailable, use embedded ports of `rpmvercmp` and Debian's algorithm; never SemVer. ### CI tests you should pin * A table-driven test set with 50-100 cases covering epochs, tildes, and distro revisions. * Golden files per distro to prevent regressions. * Cross-check installed values from real images (e.g., `ubi9`, `debian:12`, `ubuntu:22.04`, `alpine:3.20`). ### UX nudge * In the UI, show **"Compared with: RPM EVR / dpkg rules"** and link the **exact fixed threshold** that matched. Provide a "why fixed" popover showing the string compare steps. If you like, I can drop in ready-to-use C# comparators (rpmvercmp/dpkg) and a test corpus so you can wire this straight into Feedser/Vexer.