{
  "suite": "cve-import",
  "description": "CVE Record 5.x documents and the loss report a conforming importer must produce. `expect.losses` names every loss code, and `expect.kinds` the categories present. The categories are the point of this suite: `dropped` means the record is poorer than the source, `inferred` means the record now asserts something the source did not say, and `refused` means the document cannot become a valid record at all. An importer that reports a dropped where it inferred is understating a fabricated claim on a security document, so the corpus pins the kind and not only the code.",
  "cases": [
    {
      "id": "accept-minimal",
      "note": "One description, one product, nothing to infer or drop.",
      "input": {
        "cveMetadata": {
          "cveId": "CVE-2026-1000",
          "state": "PUBLISHED"
        },
        "containers": {
          "cna": {
            "descriptions": [
              {
                "lang": "en",
                "value": "An attacker can read arbitrary memory."
              }
            ],
            "affected": [{ "vendor": "acme", "product": "widget" }]
          }
        }
      },
      "expect": { "imported": true, "losses": [], "kinds": [] }
    },
    {
      "id": "refuse-rejected",
      "note": "GAVR-R-007. A rejected CVE names no citable identifier in its own namespace, so the document cannot become a valid record. Refusing is more useful than importing something that fails validation later.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1001", "state": "REJECTED" },
        "containers": {
          "cna": {
            "descriptions": [{ "lang": "en", "value": "Withdrawn." }]
          }
        }
      },
      "expect": {
        "imported": false,
        "losses": ["rejected-record-not-importable"],
        "kinds": ["refused"]
      }
    },
    {
      "id": "infer-unaffected-reason",
      "note": "GAVR-R-015. CVE has no unaffected reason and GAVR refuses an unaffected range without one, so a value must be supplied. `not-assessed` is the only member literally true of an import; anything stronger would be a fabricated security claim.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1002", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [{ "lang": "en", "value": "A description." }],
            "affected": [
              {
                "vendor": "acme",
                "product": "widget",
                "versions": [
                  {
                    "version": "1.0.0",
                    "status": "unaffected",
                    "lessThan": "2.0.0"
                  }
                ]
              }
            ]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": ["unaffected-reason-inferred"],
        "kinds": ["inferred"]
      }
    },
    {
      "id": "infer-primary-description",
      "note": "GAVR-R-010/011. CVE leaves multi-language behaviour undefined, so which description is authoritative is a choice the importer makes rather than a fact it reads.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1003", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [
              { "lang": "en", "value": "English." },
              { "lang": "de", "value": "Deutsch." }
            ]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": ["primary-description-inferred"],
        "kinds": ["inferred"]
      }
    },
    {
      "id": "drop-nonconforming-markdown",
      "note": "GAVR-R-013. CVE carries the plain rendering AND the markdown, so a profile violation costs formatting rather than forcing the strip-or-refuse choice. Stripping would silently alter somebody's advisory.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1004", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [
              {
                "lang": "en",
                "value": "Plain rendering.",
                "supportingMedia": [
                  {
                    "type": "text/markdown",
                    "base64": false,
                    "value": "See <script>alert(1)</script>"
                  }
                ]
              }
            ]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": ["markdown-profile-violation"],
        "kinds": ["dropped"]
      }
    },
    {
      "id": "drop-free-text-timeline",
      "note": "A GAVR timeline entry requires a typed event and CVE entries are free text, so the entry is carried under the `other` member with the prose as its required note. Inferring an event from that prose would be fabrication; carrying it loses the type and nothing else. `dropped` rather than `inferred` because `other` is the member that declines to classify, so nothing is asserted the source does not support.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1005", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [{ "lang": "en", "value": "A description." }],
            "timeline": [
              {
                "time": "2026-01-02T03:04:05.000Z",
                "lang": "en",
                "value": "vendor acknowledged the report"
              }
            ]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": ["timeline-event-untyped"],
        "kinds": ["dropped"]
      }
    },
    {
      "id": "drop-prose-solution",
      "note": "Every OTHER remediation kind makes a specific claim, so recording one for CVE's free-prose `solutions` would assert a fix type the source did not state. `other` exists for exactly this and requires a description, so the prose is carried and only the kind is lost.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1006", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [{ "lang": "en", "value": "A description." }],
            "solutions": [{ "lang": "en", "value": "Upgrade when convenient." }]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": ["solution-kind-untyped"],
        "kinds": ["dropped"]
      }
    },
    {
      "id": "accept-workaround",
      "note": "A workaround has an exact counterpart, so it maps with no loss at all. Included so the corpus proves the drop above is about the missing kind rather than about remediations generally.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1007", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [{ "lang": "en", "value": "A description." }],
            "workarounds": [{ "lang": "en", "value": "Disable the feature." }]
          }
        }
      },
      "expect": { "imported": true, "losses": [], "kinds": [] }
    },
    {
      "id": "mixed-inferred-and-dropped",
      "note": "The realistic case: a document that costs both. A caller must be able to tell the two apart, because only one of them can put a claim in the record that nobody made.",
      "input": {
        "cveMetadata": { "cveId": "CVE-2026-1008", "state": "PUBLISHED" },
        "containers": {
          "cna": {
            "descriptions": [
              { "lang": "en", "value": "English." },
              { "lang": "en", "value": "A second English one." }
            ],
            "affected": [
              {
                "vendor": "acme",
                "product": "widget",
                "versions": [{ "version": "1.0.0", "status": "unaffected" }]
              }
            ],
            "timeline": [
              { "time": "2026-01-02T03:04:05.000Z", "lang": "en", "value": "x" }
            ]
          }
        }
      },
      "expect": {
        "imported": true,
        "losses": [
          "duplicate-language-description-dropped",
          "timeline-event-untyped",
          "unaffected-reason-inferred"
        ],
        "kinds": ["dropped", "inferred"]
      }
    }
  ]
}
