````markdown
# Feedser Vulnerability Conflict Resolution Rules

This document defines the canonical, deterministic conflict resolution strategy for merging vulnerability data from **NVD**, **GHSA**, and **OSV** in Feedser.

---

## 🧭 Source Precedence

1. **Primary order:**  
   `GHSA > NVD > OSV`

   **Rationale:**  
   GHSA advisories are human-curated and fast to correct; NVD has the broadest CVE coverage; OSV excels in ecosystem-specific precision.

2. **Freshness override (≥48 h):**  
   If a **lower-priority** source is **newer by at least 48 hours** for a freshness-sensitive field, its value overrides the higher-priority one.  
   Always store the decision in a provenance record.

3. **Merge scope:**  
   Only merge data referring to the **same CVE ID** or the same GHSA/OSV advisory explicitly mapped to that CVE.

---

## 🧩 Field-Level Precedence

| Field | Priority | Freshness-Sensitive | Notes |
|-------|-----------|--------------------|-------|
| Title / Summary | GHSA → NVD → OSV | ✅ | Prefer concise structured titles |
| Description | GHSA → NVD → OSV | ✅ | |
| Severity (CVSS) | NVD → GHSA → OSV | ❌ | Keep all under `metrics[]`, mark `canonicalMetric` by order |
| Ecosystem Severity Label | GHSA → OSV | ❌ | Supplemental tag only |
| Affected Packages / Ranges | OSV → GHSA → NVD | ✅ | OSV strongest for SemVer normalization |
| CWE(s) | NVD → GHSA → OSV | ❌ | NVD taxonomy most stable |
| References / Links | Union of all | ✅ | Deduplicate by normalized URL |
| Credits / Acknowledgements | Union of all | ✅ | Sort by role, displayName |
| Published / Modified timestamps | Earliest published / Latest modified | ✅ | |
| EPSS / KEV / Exploit status | Specialized feed only | ❌ | Do not override manually |

---

## ⚖️ Deterministic Tie-Breakers

If precedence and freshness both tie:

1. **Source order:** GHSA > NVD > OSV  
2. **Lexicographic stability:** Prefer shorter normalized text; if equal, ASCIIbetical  
3. **Stable hash of payload:** Lowest hash wins  

Each chosen value must store the merge rationale:

```json
{
  "provenance": {
    "source": "GHSA",
    "kind": "merge",
    "value": "description",
    "decisionReason": "precedence"
  }
}
````

---

## 🧮 Merge Algorithm (Pseudocode)

```csharp
inputs: records = {ghsa?, nvd?, osv?}
out = new CanonicalVuln(CVE)

foreach field in CANONICAL_SCHEMA:
    candidates = collect(values, source, lastModified)
    if freshnessSensitive(field) and newerBy48h(lowerPriority):
        pick newest
    else:
        pick by precedence(field)
    if tie:
        applyTieBreakers()
    out.field = normalize(field, value)
    out.provenance[field] = decisionTrail

out.references = dedupe(union(all.references))
out.affected   = normalizeAndUnion(OSV, GHSA, NVD)
out.metrics    = rankAndSetCanonical(NVDv3 → GHSA → OSV → v2)
return out
```

---

## 🔧 Normalization Rules

* **SemVer:**
  Parse with tolerant builder; normalize `v` prefixes; map comparators (`<=`, `<`, `>=`, `>`); expand OSV events into continuous ranges.

* **Packages:**
  Canonical key = `(ecosystem, packageName, language?)`; maintain aliases (purl, npm, Maven GAV, etc.).

* **CWE:**
  Store both ID and name; validate against current CWE catalog.

* **CVSS:**
  Preserve provided vector and base score; recompute only for validation.

---

## ✅ Output Guarantees

| Property         | Description                                                                     |
| ---------------- | ------------------------------------------------------------------------------- |
| **Reproducible** | Same input → same canonical output                                              |
| **Auditable**    | Provenance stored per field                                                     |
| **Complete**     | Unions with de-duplication                                                      |
| **Composable**   | Future layers (KEV, EPSS, vendor advisories) can safely extend precedence rules |

---

## 🧠 Example

* GHSA summary updated on *2025-10-09*
* NVD last modified *2025-10-05*
* OSV updated *2025-10-10*

→ **Summary:** OSV wins (freshness override)
→ **CVSS:** NVD v3.1 remains canonical
→ **Affected:** OSV ranges canonical; GHSA aliases merged

---

## 🧰 Optional C# Helper Class

`StellaOps.Feedser.Core/CanonicalMerger.cs`

Implements:

* `FieldPrecedenceMap`
* `FreshnessSensitiveFields`
* `ApplyTieBreakers()`
* `NormalizeAndUnion()`

Deterministically builds `CanonicalVuln` with full provenance tracking.

```
```
