Skip to main content
Glama

EchelonGraph CVE & Exposure

CVE detail

get_cve
Read-onlyIdempotent

One CVE's record: description, severity, cvss_v3_score, cvss_v4_score and cvss_v4_severity, echelongraph_score, echelongraph_severity and score_confidence, epss_score and epss_percentile, CISA-KEV status (kev_listed, kev_added_date, kev_due_date, kev_ransomware) and, if KEV-listed, CISA's own text relayed verbatim (kev_required_action, not EchelonGraph's advice; kev_short_description; kev_notes_urls), ghsa_id, references, cpe_match (one flat list) and cpe_configurations (NVD's configurations as NVD sent them, with each AND/OR operator; absent where none is stored, which is not a finding that no product is affected), remediation (a capped summary of its fix), published, modified and updated_at; each field only where the record has it. Pass a CVE ID like CVE-2023-44487. echelongraph_score, echelongraph_severity and echelongraph_risk are EchelonGraph's score only when score_assessed is true. With score_assessed false the CVE is NOT YET SCORED, not scored 0: any of those three it carries (0, NONE, 0) is a placeholder, not a rating, and does not mean the CVE is harmless; score_unassessed_reason says why, and the note labels each such CVE NOT YET SCORED. An answer with no score_assessed (an API older than that field) does not say whether the CVE was scored, the note says so, and a 0 there is not a rating either. patch_available is true when EchelonGraph holds, or once held, fix evidence for the CVE; patch_evidence is what it holds now, strongest first. patch_available false means no fix evidence is on record, which is not a finding that no fix exists. freshness is null: this answer carries no poll-completion time. Past 30,000 characters of JSON, the first text block holds data cut to fit, and the note says what the cut leaves out and where to read it (TEXT CUT); so is structured data (DATA CUT), unless full: true. Cut, each list in the record keeps its first entries, and the note names each list cut with its full length.

Input Schema

NameRequiredDescriptionDefault
fullNotrue: data in the structured result is the answer whole, however long. Without it, a structured result past 30,000 characters of JSON has its data cut (DATA CUT): in an order the note states, the entries of its longest lists keep only some of their fields, and then the lists only some of their entries; data_truncated is true, and truncated gives each list cut with its total, the number returned and whether its entries are thinned. Whole data is for a program; a client that sizes structured results, as Claude Code does against MAX_MCP_OUTPUT_TOKENS, can refuse an answer past its cap.
cve_idYesa CVE ID, e.g. CVE-2023-44487

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": {},
      -    "properties": {
      -      "coverage": {
      -        "description": "What the answer covers; null where the answer says nothing about it.",
      -        "type": "null"
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cna": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {
      -                  "name": {
      -                    "type": [
      -                      "string",
      -                      "null"
      -                    ]
      -                  },
      -                  "short_name": {
      -                    "type": [
      -                      "string",
      -                      "null"
      -                    ]
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      -          },
      -          "cna_solution": {
      -            "description": "The sentence of the CVE record's solutions or workarounds, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. cna_solution_section says which of the two sections it is. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cna_solution_section": {
      -            "anyOf": [
      -              {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "solution",
      -                      "workaround"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "string"
      -                  }
      -                ]
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "Which section of the CVE record cna_solution was read from: solution (the record's solutions) or workaround (its workarounds, read only where its solutions name no fix: a temporary measure the CNA lists beside its fix). A workaround's sentence is the record's workaround, never its solution. Present whenever cna_solution is; absent from an API older than the field."
      -          },
      -          "cpe_configurations": {
      -            "anyOf": [
      -              {
      -                "items": {},
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -          },
      -          "cpe_match": {
      -            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -          },
      -          "cve_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cvss_v3_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "date_public": {
      -            "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "date_public_source": {
      -            "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "description": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_risk": {
      -            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_score": {
      -            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_severity": {
      -            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_ssvc_decision": {
      -            "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "epss_percentile": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "epss_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "ghsa_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_added_date": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_due_date": {
      -            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_listed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_notes_urls": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      -          },
      -          "kev_ransomware": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_required_action": {
      -            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_short_description": {
      -            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "modified": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "patch_available": {
      -            "description": "true: EchelonGraph holds, or once held, evidence of a fix for the CVE; patch_evidence names the sources it holds now. true beside an empty patch_evidence means evidence of a fix once held has since been withdrawn (patch_available is never set back to false), and fix_status (remediation.fix_status in the CVE's record) is the current reading, not patch_available. false: no fix evidence is on record, which is not a finding that no fix exists. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "patch_evidence": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "anyOf": [
      -                    {
      -                      "enum": [
      -                        "vendor_patch",
      -                        "fixed_version",
      -                        "release_reference",
      -                        "vendor_advisory_fix",
      -                        "nvd_patch_reference",
      -                        "cna_patch_reference",
      -                        "cna_solution",
      -                        "description_fix",
      -                        "vendor_fix_released"
      -                      ],
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "string"
      -                    }
      -                  ]
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions or workarounds, written by its CNA, that names a fixed version; relayed as cna_solution), description_fix (a sentence of the CVE description that names a fixed version) and vendor_fix_released (the vendor states, in the CVE record, that a fix is released and the record names no fixed version; check the vendor's advisory). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      -          },
      -          "published": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "references": {},
      -          "remediation": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {
      -                  "fix_status": {
      -                    "anyOf": [
      -                      {
      -                        "additionalProperties": {},
      -                        "properties": {
      -                          "basis": {
      -                            "type": [
      -                              "string",
      -                              "null"
      -                            ]
      -                          },
      -                          "described_by": {
      -                            "type": [
      -                              "string",
      -                              "null"
      -                            ]
      -                          },
      -                          "listed_in_patch_table": {
      -                            "type": [
      -                              "boolean",
      -                              "null"
      -                            ]
      -                          },
      -                          "solution_by": {
      -                            "anyOf": [
      -                              {
      -                                "additionalProperties": {},
      -                                "properties": {
      -                                  "cna": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  },
      -                                  "section": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  },
      -                                  "statement": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  }
      -                                },
      -                                "type": "object"
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          },
      -                          "state": {
      -                            "anyOf": [
      -                              {
      -                                "anyOf": [
      -                                  {
      -                                    "enum": [
      -                                      "available",
      -                                      "fix_referenced",
      -                                      "fix_merged",
      -                                      "none_confirmed",
      -                                      "unknown"
      -                                    ],
      -                                    "type": "string"
      -                                  },
      -                                  {
      -                                    "type": "string"
      -                                  }
      -                                ]
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          },
      -                          "stated_in_record": {
      -                            "type": [
      -                              "boolean",
      -                              "null"
      -                            ]
      -                          },
      -                          "unread_inputs": {
      -                            "anyOf": [
      -                              {
      -                                "items": {
      -                                  "type": "string"
      -                                },
      -                                "type": "array"
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          },
      -                          "vendor_released": {
      -                            "anyOf": [
      -                              {
      -                                "additionalProperties": {},
      -                                "properties": {
      -                                  "statement": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  }
      -                                },
      -                                "type": "object"
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          }
      -                        },
      -                        "type": "object"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read. vendor_released (basis vendor_fix_released) is the vendor's own statement that a fix is released where the CVE record names no fixed version: its sentence, verbatim (statement, or null), never a version, so the fixed release is the vendor advisory's to name. solution_by's section is workarounds when the fix sentence is the record's workaround, not its solution."
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      -          },
      -          "score_assessed": {
      -            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "score_confidence": {
      -            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "score_factors": {
      -            "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed."
      -          },
      -          "score_unassessed_reason": {
      -            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "updated_at": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "data_truncated": {
      -        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      -        "type": "boolean"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      },
      -      "truncated": {
      -        "additionalProperties": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "returned": {
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            },
      -            "thinned": {
      -              "const": true,
      -              "type": "boolean"
      -            },
      -            "total": {
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            }
      -          },
      -          "required": [
      -            "total",
      -            "returned"
      -          ],
      -          "type": "object"
      -        },
      -        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data_truncated",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "type": "null"
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": {},
      +    "properties": {
      +      "coverage": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "What the answer covers; null where the answer says nothing about it."
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cna": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "short_name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      +          },
      +          "cna_solution": {
      +            "description": "The sentence of the CVE record's solutions or workarounds, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. cna_solution_section says which of the two sections it is. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cna_solution_section": {
      +            "anyOf": [
      +              {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "solution",
      +                      "workaround"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "string"
      +                  }
      +                ]
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Which section of the CVE record cna_solution was read from: solution (the record's solutions) or workaround (its workarounds, read only where its solutions name no fix: a temporary measure the CNA lists beside its fix). A workaround's sentence is the record's workaround, never its solution. Present whenever cna_solution is; absent from an API older than the field."
      +          },
      +          "cpe_configurations": {
      +            "anyOf": [
      +              {
      +                "items": {},
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +          },
      +          "cpe_match": {
      +            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +          },
      +          "cve_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cvss_v3_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public": {
      +            "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public_source": {
      +            "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_risk": {
      +            "description": "EchelonGraph's 0-100 risk priority, fused from impact severity (eg_severity, from scorer v4.0; the score before it), exploitation and automatability, with EchelonGraph's hand-set weights: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_score": {
      +            "description": "EchelonGraph's 0-10 score for the CVE: severity, escalated by confirmed exploitation (a CISA KEV listing floors it at 9.0) and lifted toward 9.0 by EPSS; eg_severity is the impact severity alone. A score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_severity": {
      +            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_ssvc_decision": {
      +            "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "eg_likelihood": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "exploited": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "exploited_sources": {
      +                    "anyOf": [
      +                      {
      +                        "items": {
      +                          "type": "string"
      +                        },
      +                        "type": "array"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "horizon_days": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "null_reason": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "probability": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "source": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "A probability with a horizon (scorer v4.0): probability is FIRST's EPSS probability of exploitation activity in the next 30 days (source first_epss, horizon_days 30, with epss_percentile, epss_score_date and epss_model_version where stored), not EchelonGraph's own model. null, with null_reason no_epss_on_record, where no EPSS is on record: the likelihood is unknown, not low. exploited (true when CISA KEV lists the CVE or EG-KEV rates it Tier 1) and exploited_sources report confirmed exploitation apart from it; it is never folded into probability. Absent from a record scored before v4.0."
      +          },
      +          "eg_priority": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "bod_26_04": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": {},
      +                        "properties": {
      +                          "if_not_publicly_exposed": {
      +                            "anyOf": [
      +                              {
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "if_publicly_exposed": {
      +                            "anyOf": [
      +                              {
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  },
      +                  "inputs": {},
      +                  "ssvc": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": {},
      +                        "properties": {
      +                          "decision": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "mission": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The decision (scorer v4.0): ssvc, the decision CISA's SSVC table gives as EchelonGraph applies it (decision at medium mission impact, as echelongraph_ssvc_decision, and by_mission), null with null_reason not_assessed for a CVE EchelonGraph has not assessed; bod_26_04, CISA BOD 26-04's timeline if_publicly_exposed and if_not_publicly_exposed (CERT/CC's keys 3DF, 3D, 14D, 60D, FSU); inputs, kev, exploitation, automatable and technical_impact, each with its source. Absent from a record scored before v4.0."
      +          },
      +          "eg_severity": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "assessed": {
      +                    "type": [
      +                      "boolean",
      +                      "null"
      +                    ]
      +                  },
      +                  "provider": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "score": {
      +                    "type": [
      +                      "number",
      +                      "null"
      +                    ]
      +                  },
      +                  "severity": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "source": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "unassessed_reason": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Impact severity alone (scorer v4.0): the CVSS base score from the best-provenance CVSS EchelonGraph holds, which no CISA KEV listing, EPSS probability or EG-KEV tier raises. score (0-10) and severity (the CVSS band), with metric cvss_base, cvss_version, vector, source and provider. assessed false, with score and severity null and unassessed_reason, where no CVSS of any version is published: kev_listed_no_cvss reads exploited, severity not yet published. Absent from a record scored before v4.0."
      +          },
      +          "epss_percentile": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "epss_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "ghsa_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_added_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_due_date": {
      +            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_listed": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_notes_urls": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +          },
      +          "kev_ransomware": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_required_action": {
      +            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_short_description": {
      +            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "modified": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "patch_available": {
      +            "description": "true: EchelonGraph holds, or once held, evidence of a fix for the CVE; patch_evidence names the sources it holds now. true beside an empty patch_evidence means evidence of a fix once held has since been withdrawn (patch_available is never set back to false), and fix_status (remediation.fix_status in the CVE's record) is the current reading, not patch_available. false: no fix evidence is on record, which is not a finding that no fix exists. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "patch_evidence": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "anyOf": [
      +                    {
      +                      "enum": [
      +                        "vendor_patch",
      +                        "fixed_version",
      +                        "release_reference",
      +                        "vendor_advisory_fix",
      +                        "nvd_patch_reference",
      +                        "cna_patch_reference",
      +                        "cna_solution",
      +                        "description_fix",
      +                        "vendor_fix_released"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "string"
      +                    }
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions or workarounds, written by its CNA, that names a fixed version; relayed as cna_solution), description_fix (a sentence of the CVE description that names a fixed version) and vendor_fix_released (the vendor states, in the CVE record, that a fix is released and the record names no fixed version; check the vendor's advisory). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +          },
      +          "published": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "references": {},
      +          "remediation": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "fix_status": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": {},
      +                        "properties": {
      +                          "basis": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "described_by": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "listed_in_patch_table": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "solution_by": {
      +                            "anyOf": [
      +                              {
      +                                "additionalProperties": {},
      +                                "properties": {
      +                                  "cna": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "section": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "statement": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  }
      +                                },
      +                                "type": "object"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "state": {
      +                            "anyOf": [
      +                              {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "available",
      +                                      "fix_referenced",
      +                                      "fix_merged",
      +                                      "none_confirmed",
      +                                      "unknown"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "string"
      +                                  }
      +                                ]
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "stated_in_record": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "unread_inputs": {
      +                            "anyOf": [
      +                              {
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "vendor_released": {
      +                            "anyOf": [
      +                              {
      +                                "additionalProperties": {},
      +                                "properties": {
      +                                  "statement": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  }
      +                                },
      +                                "type": "object"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read. vendor_released (basis vendor_fix_released) is the vendor's own statement that a fix is released where the CVE record names no fixed version: its sentence, verbatim (statement, or null), never a version, so the fixed release is the vendor advisory's to name. solution_by's section is workarounds when the fix sentence is the record's workaround, not its solution."
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +          },
      +          "score_assessed": {
      +            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "score_confidence": {
      +            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "score_factors": {
      +            "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed. eg_severity, eg_likelihood and eg_priority (scorer v4.0): the same objects as the record's top-level fields. eg_risk.severity_source (v4.0): what EG Risk's severity term read, eg_severity, vendor_severity, or unknown_kev_most_urgent (no severity published for a CISA KEV CVE, so the most urgent value)."
      +          },
      +          "score_unassessed_reason": {
      +            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "updated_at": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "data_truncated": {
      +        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      +        "type": "boolean"
      +      },
      +      "freshness": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": {},
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one."
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      },
      +      "truncated": {
      +        "additionalProperties": {
      +          "additionalProperties": {},
      +          "properties": {
      +            "returned": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "thinned": {
      +              "const": true,
      +              "type": "boolean"
      +            },
      +            "total": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "total",
      +            "returned"
      +          ],
      +          "type": "object"
      +        },
      +        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data_truncated",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "type": "null"
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  2. Changed1 schema field changed
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "description": "What the answer covers; null where the answer says nothing about it.",
      -        "type": "null"
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cna": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {
      -                  "name": {
      -                    "type": [
      -                      "string",
      -                      "null"
      -                    ]
      -                  },
      -                  "short_name": {
      -                    "type": [
      -                      "string",
      -                      "null"
      -                    ]
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      -          },
      -          "cna_solution": {
      -            "description": "The sentence of the CVE record's solutions, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cpe_configurations": {
      -            "anyOf": [
      -              {
      -                "items": {},
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -          },
      -          "cpe_match": {
      -            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -          },
      -          "cve_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cvss_v3_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "date_public": {
      -            "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "date_public_source": {
      -            "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "description": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_risk": {
      -            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_score": {
      -            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_severity": {
      -            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_ssvc_decision": {
      -            "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "epss_percentile": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "epss_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "ghsa_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_added_date": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_due_date": {
      -            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_listed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_notes_urls": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      -          },
      -          "kev_ransomware": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_required_action": {
      -            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_short_description": {
      -            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "modified": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "patch_available": {
      -            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "patch_evidence": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "anyOf": [
      -                    {
      -                      "enum": [
      -                        "vendor_patch",
      -                        "fixed_version",
      -                        "release_reference",
      -                        "vendor_advisory_fix",
      -                        "nvd_patch_reference",
      -                        "cna_patch_reference",
      -                        "cna_solution",
      -                        "description_fix"
      -                      ],
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "string"
      -                    }
      -                  ]
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions, written by its CNA, that names a fixed version; relayed as cna_solution) and description_fix (a sentence of the CVE description that names a fixed version). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      -          },
      -          "published": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "references": {},
      -          "remediation": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {
      -                  "fix_status": {
      -                    "anyOf": [
      -                      {
      -                        "additionalProperties": {},
      -                        "properties": {
      -                          "basis": {
      -                            "type": [
      -                              "string",
      -                              "null"
      -                            ]
      -                          },
      -                          "described_by": {
      -                            "type": [
      -                              "string",
      -                              "null"
      -                            ]
      -                          },
      -                          "listed_in_patch_table": {
      -                            "type": [
      -                              "boolean",
      -                              "null"
      -                            ]
      -                          },
      -                          "solution_by": {
      -                            "anyOf": [
      -                              {
      -                                "additionalProperties": {},
      -                                "properties": {
      -                                  "cna": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  },
      -                                  "statement": {
      -                                    "type": [
      -                                      "string",
      -                                      "null"
      -                                    ]
      -                                  }
      -                                },
      -                                "type": "object"
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          },
      -                          "state": {
      -                            "anyOf": [
      -                              {
      -                                "anyOf": [
      -                                  {
      -                                    "enum": [
      -                                      "available",
      -                                      "fix_referenced",
      -                                      "fix_merged",
      -                                      "none_confirmed",
      -                                      "unknown"
      -                                    ],
      -                                    "type": "string"
      -                                  },
      -                                  {
      -                                    "type": "string"
      -                                  }
      -                                ]
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          },
      -                          "stated_in_record": {
      -                            "type": [
      -                              "boolean",
      -                              "null"
      -                            ]
      -                          },
      -                          "unread_inputs": {
      -                            "anyOf": [
      -                              {
      -                                "items": {
      -                                  "type": "string"
      -                                },
      -                                "type": "array"
      -                              },
      -                              {
      -                                "type": "null"
      -                              }
      -                            ]
      -                          }
      -                        },
      -                        "type": "object"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read."
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      -          },
      -          "score_assessed": {
      -            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "score_confidence": {
      -            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "score_factors": {
      -            "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed."
      -          },
      -          "score_unassessed_reason": {
      -            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "updated_at": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "data_truncated": {
      -        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      -        "type": "boolean"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      },
      -      "truncated": {
      -        "additionalProperties": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "returned": {
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            },
      -            "thinned": {
      -              "const": true,
      -              "type": "boolean"
      -            },
      -            "total": {
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            }
      -          },
      -          "required": [
      -            "total",
      -            "returned"
      -          ],
      -          "type": "object"
      -        },
      -        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data_truncated",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "type": "null"
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": {},
      +    "properties": {
      +      "coverage": {
      +        "description": "What the answer covers; null where the answer says nothing about it.",
      +        "type": "null"
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cna": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "short_name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      +          },
      +          "cna_solution": {
      +            "description": "The sentence of the CVE record's solutions or workarounds, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. cna_solution_section says which of the two sections it is. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cna_solution_section": {
      +            "anyOf": [
      +              {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "solution",
      +                      "workaround"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "string"
      +                  }
      +                ]
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "Which section of the CVE record cna_solution was read from: solution (the record's solutions) or workaround (its workarounds, read only where its solutions name no fix: a temporary measure the CNA lists beside its fix). A workaround's sentence is the record's workaround, never its solution. Present whenever cna_solution is; absent from an API older than the field."
      +          },
      +          "cpe_configurations": {
      +            "anyOf": [
      +              {
      +                "items": {},
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +          },
      +          "cpe_match": {
      +            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +          },
      +          "cve_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cvss_v3_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public": {
      +            "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public_source": {
      +            "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_risk": {
      +            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_score": {
      +            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_severity": {
      +            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_ssvc_decision": {
      +            "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "epss_percentile": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "epss_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "ghsa_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_added_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_due_date": {
      +            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_listed": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_notes_urls": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +          },
      +          "kev_ransomware": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_required_action": {
      +            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_short_description": {
      +            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "modified": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "patch_available": {
      +            "description": "true: EchelonGraph holds, or once held, evidence of a fix for the CVE; patch_evidence names the sources it holds now. true beside an empty patch_evidence means evidence of a fix once held has since been withdrawn (patch_available is never set back to false), and fix_status (remediation.fix_status in the CVE's record) is the current reading, not patch_available. false: no fix evidence is on record, which is not a finding that no fix exists. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "patch_evidence": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "anyOf": [
      +                    {
      +                      "enum": [
      +                        "vendor_patch",
      +                        "fixed_version",
      +                        "release_reference",
      +                        "vendor_advisory_fix",
      +                        "nvd_patch_reference",
      +                        "cna_patch_reference",
      +                        "cna_solution",
      +                        "description_fix",
      +                        "vendor_fix_released"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "string"
      +                    }
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions or workarounds, written by its CNA, that names a fixed version; relayed as cna_solution), description_fix (a sentence of the CVE description that names a fixed version) and vendor_fix_released (the vendor states, in the CVE record, that a fix is released and the record names no fixed version; check the vendor's advisory). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +          },
      +          "published": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "references": {},
      +          "remediation": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "fix_status": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": {},
      +                        "properties": {
      +                          "basis": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "described_by": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "listed_in_patch_table": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "solution_by": {
      +                            "anyOf": [
      +                              {
      +                                "additionalProperties": {},
      +                                "properties": {
      +                                  "cna": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "section": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "statement": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  }
      +                                },
      +                                "type": "object"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "state": {
      +                            "anyOf": [
      +                              {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "available",
      +                                      "fix_referenced",
      +                                      "fix_merged",
      +                                      "none_confirmed",
      +                                      "unknown"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "string"
      +                                  }
      +                                ]
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "stated_in_record": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "unread_inputs": {
      +                            "anyOf": [
      +                              {
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "vendor_released": {
      +                            "anyOf": [
      +                              {
      +                                "additionalProperties": {},
      +                                "properties": {
      +                                  "statement": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  }
      +                                },
      +                                "type": "object"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read. vendor_released (basis vendor_fix_released) is the vendor's own statement that a fix is released where the CVE record names no fixed version: its sentence, verbatim (statement, or null), never a version, so the fixed release is the vendor advisory's to name. solution_by's section is workarounds when the fix sentence is the record's workaround, not its solution."
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +          },
      +          "score_assessed": {
      +            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "score_confidence": {
      +            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "score_factors": {
      +            "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed."
      +          },
      +          "score_unassessed_reason": {
      +            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "updated_at": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "data_truncated": {
      +        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      +        "type": "boolean"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      },
      +      "truncated": {
      +        "additionalProperties": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "returned": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "thinned": {
      +              "const": true,
      +              "type": "boolean"
      +            },
      +            "total": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "total",
      +            "returned"
      +          ],
      +          "type": "object"
      +        },
      +        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data_truncated",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "type": "null"
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. Changed2 schema fields changed
    • addedInput schema / properties / full
      Added value: +{
      +  "description": "true: data in the structured result is the answer whole, however long. Without it, a structured result past 30,000 characters of JSON has its data cut (DATA CUT): in an order the note states, the entries of its longest lists keep only some of their fields, and then the lists only some of their entries; data_truncated is true, and truncated gives each list cut with its total, the number returned and whether its entries are thinned. Whole data is for a program; a client that sizes structured results, as Claude Code does against MAX_MCP_OUTPUT_TOKENS, can refuse an answer past its cap.",
      +  "type": "boolean"
      +}
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "description": "What the answer covers; null where the answer says nothing about it.",
      -        "type": "null"
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cpe_configurations": {
      -            "anyOf": [
      -              {
      -                "items": {},
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -          },
      -          "cpe_match": {
      -            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -          },
      -          "cve_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cvss_v3_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "description": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_risk": {
      -            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_score": {
      -            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_severity": {
      -            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "epss_percentile": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "epss_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "ghsa_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_added_date": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_due_date": {
      -            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_listed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_notes_urls": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "type": "string"
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      -          },
      -          "kev_ransomware": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_required_action": {
      -            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 22-01, by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_short_description": {
      -            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "modified": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "patch_available": {
      -            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "patch_evidence": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "anyOf": [
      -                    {
      -                      "enum": [
      -                        "vendor_patch",
      -                        "fixed_version",
      -                        "release_reference",
      -                        "nvd_patch_reference",
      -                        "cna_patch_reference"
      -                      ],
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "string"
      -                    }
      -                  ]
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), nvd_patch_reference (an NVD reference tagged Patch) and cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      -          },
      -          "published": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "references": {},
      -          "remediation": {
      -            "anyOf": [
      -              {
      -                "additionalProperties": {},
      -                "properties": {},
      -                "type": "object"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      -          },
      -          "score_assessed": {
      -            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "score_confidence": {
      -            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "score_unassessed_reason": {
      -            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "updated_at": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "type": "null"
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "description": "What the answer covers; null where the answer says nothing about it.",
      +        "type": "null"
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cna": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  },
      +                  "short_name": {
      +                    "type": [
      +                      "string",
      +                      "null"
      +                    ]
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The CNA that wrote the CVE record: short_name as the record gives it, and name, the CVE Program's name for that CNA (the short name where its list does not hold it). Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field."
      +          },
      +          "cna_solution": {
      +            "description": "The sentence of the CVE record's solutions, written by its CNA, that names a released fix, verbatim: what makes cna_solution patch evidence. It is the CNA's text, not EchelonGraph's advice. Absent where the record's solutions name no fixed version, as well as where the field itself is: Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cpe_configurations": {
      +            "anyOf": [
      +              {
      +                "items": {},
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +          },
      +          "cpe_match": {
      +            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +          },
      +          "cve_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cvss_v3_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public": {
      +            "description": "When the vulnerability was made public, as the CVE record's CNA states it (the record's datePublic: \"if known, the date/time the vulnerability was disclosed publicly\"). It is the CNA's date, not the record's own publication date, which is published. Absent where EchelonGraph has not read the CVE record's CNA container yet, where the record has none, for a REJECTED CVE, and from an API older than the field.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "date_public_source": {
      +            "description": "Whose date date_public is: cna, the CVE record's CNA. Absent whenever date_public is.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_risk": {
      +            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_score": {
      +            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_severity": {
      +            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_ssvc_decision": {
      +            "description": "The SSVC decision (Act, Attend, Track* or Track) EchelonGraph computes with CISA's decision table at medium mission impact. CISA publishes the table and, for some CVEs, its inputs, not a decision for a CVE. score_factors.ssvc gives the decision at low, medium and high mission impact, with each input and its source.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "epss_percentile": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "epss_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "ghsa_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_added_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_due_date": {
      +            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_listed": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_notes_urls": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +          },
      +          "kev_ransomware": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_required_action": {
      +            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 26-04 (which replaced BOD 22-01 on 10 June 2026), by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_short_description": {
      +            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "modified": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "patch_available": {
      +            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "patch_evidence": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "anyOf": [
      +                    {
      +                      "enum": [
      +                        "vendor_patch",
      +                        "fixed_version",
      +                        "release_reference",
      +                        "vendor_advisory_fix",
      +                        "nvd_patch_reference",
      +                        "cna_patch_reference",
      +                        "cna_solution",
      +                        "description_fix"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "string"
      +                    }
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), vendor_advisory_fix (a vendor advisory that lists a fix for the CVE under the vendor's own structured category: Red Hat's CSAF vendor_fix, Microsoft's Vendor Fix), nvd_patch_reference (an NVD reference tagged Patch), cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record), cna_solution (a sentence of the CVE record's solutions, written by its CNA, that names a fixed version; relayed as cna_solution) and description_fix (a sentence of the CVE description that names a fixed version). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +          },
      +          "published": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "references": {},
      +          "remediation": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {
      +                  "fix_status": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": {},
      +                        "properties": {
      +                          "basis": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "described_by": {
      +                            "type": [
      +                              "string",
      +                              "null"
      +                            ]
      +                          },
      +                          "listed_in_patch_table": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "solution_by": {
      +                            "anyOf": [
      +                              {
      +                                "additionalProperties": {},
      +                                "properties": {
      +                                  "cna": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  },
      +                                  "statement": {
      +                                    "type": [
      +                                      "string",
      +                                      "null"
      +                                    ]
      +                                  }
      +                                },
      +                                "type": "object"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "state": {
      +                            "anyOf": [
      +                              {
      +                                "anyOf": [
      +                                  {
      +                                    "enum": [
      +                                      "available",
      +                                      "fix_referenced",
      +                                      "fix_merged",
      +                                      "none_confirmed",
      +                                      "unknown"
      +                                    ],
      +                                    "type": "string"
      +                                  },
      +                                  {
      +                                    "type": "string"
      +                                  }
      +                                ]
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          },
      +                          "stated_in_record": {
      +                            "type": [
      +                              "boolean",
      +                              "null"
      +                            ]
      +                          },
      +                          "unread_inputs": {
      +                            "anyOf": [
      +                              {
      +                                "items": {
      +                                  "type": "string"
      +                                },
      +                                "type": "array"
      +                              },
      +                              {
      +                                "type": "null"
      +                              }
      +                            ]
      +                          }
      +                        },
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "The API's fix-status rule for the CVE, the one CVE Pulse pages show: state is available (a fix is on record), fix_referenced (a reference tagged Patch, often a source commit, and no release confirmed), fix_merged (an upstream fix merged, not yet in a tagged release), none_confirmed (no fix evidence on record, which is not a finding that no fix exists) or unknown (an input could not be read). basis is the step of the rule that decided it; described_by is the CVE description's sentence naming the fix, solution_by the CVE record's solution sentence naming it (statement) and the CNA that wrote it (cna), stated_in_record that patch_evidence counts a fix the CVE record states with no sentence to quote, listed_in_patch_table that a fixed version or patch row is on record; unread_inputs names any input the API could not read."
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: fix_status first (the API's fix-status rule: state, basis, described_by, solution_by, stated_in_record, listed_in_patch_table and unread_inputs), vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation by NVD, or patch or mitigation by the CNA), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +          },
      +          "score_assessed": {
      +            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "score_confidence": {
      +            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "score_factors": {
      +            "description": "EchelonGraph's evidence for its score. ssvc: the SSVC decision at every mission impact level, each input with its source. bod_26_04 (scorer v3.4 and later): CISA BOD 26-04's remediation timeline, if_publicly_exposed and if_not_publicly_exposed, each a list of CERT/CC's keys (3DF, 3D, 14D, 60D, FSU) named in timelines, with kev, automatable and technical_impact, each with its source; source cisa_bod_26_04_default is CISA's own default for a CVE not in KEV that nobody has assessed."
      +          },
      +          "score_unassessed_reason": {
      +            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "updated_at": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "data_truncated": {
      +        "description": "false: data is the answer whole. true: the structured result would pass 30,000 characters of JSON with data whole, so data is cut (DATA CUT): the entries of some of its lists keep only some of their fields, or the lists only some of their entries, truncated gives each, and no string is shortened. The same call with full: true returns data whole.",
      +        "type": "boolean"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      },
      +      "truncated": {
      +        "additionalProperties": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "returned": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "thinned": {
      +              "const": true,
      +              "type": "boolean"
      +            },
      +            "total": {
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "total",
      +            "returned"
      +          ],
      +          "type": "object"
      +        },
      +        "description": "Present when data_truncated is true: each list of data that was cut, by its path in data (a dot between the names of an object and a list inside it), with total, its entries in the answer, returned, the entries data holds, and thinned, true when each of them keeps only some of its fields.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data_truncated",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "type": "null"
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "description": "What the answer covers; null where the answer says nothing about it.",
      -        "type": "null"
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cpe_configurations": {
      -            "anyOf": [
      -              {
      -                "items": {},
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -          },
      -          "cpe_match": {
      -            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -          },
      -          "cve_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cvss_v3_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "description": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_risk": {
      -            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_score": {
      -            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_severity": {
      -            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "epss_percentile": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "epss_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "ghsa_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_added_date": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_listed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_ransomware": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "modified": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "patch_available": {
      -            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "patch_evidence": {
      -            "anyOf": [
      -              {
      -                "items": {
      -                  "anyOf": [
      -                    {
      -                      "enum": [
      -                        "vendor_patch",
      -                        "fixed_version",
      -                        "nvd_patch_reference"
      -                      ],
      -                      "type": "string"
      -                    },
      -                    {
      -                      "type": "string"
      -                    }
      -                  ]
      -                },
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range) and nvd_patch_reference (an NVD reference tagged Patch). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      -          },
      -          "published": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "references": {},
      -          "score_assessed": {
      -            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "score_confidence": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "score_unassessed_reason": {
      -            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "updated_at": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "type": "null"
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "description": "What the answer covers; null where the answer says nothing about it.",
      +        "type": "null"
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cpe_configurations": {
      +            "anyOf": [
      +              {
      +                "items": {},
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +          },
      +          "cpe_match": {
      +            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +          },
      +          "cve_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cvss_v3_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_risk": {
      +            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_score": {
      +            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_severity": {
      +            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "epss_percentile": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "epss_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "ghsa_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_added_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_due_date": {
      +            "description": "CISA's dueDate: when US federal civilian agencies must have applied kev_required_action. Absent where the CVE is not CISA-KEV-listed.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_listed": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_notes_urls": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The https links in CISA's notes for the CVE, in CISA's order, de-duplicated, at most 10: the references CISA's catalog entry gives, such as the vendor's advisory or instructions and NVD's page. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none)."
      +          },
      +          "kev_ransomware": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_required_action": {
      +            "description": "CISA's requiredAction for the CVE, verbatim from its Known Exploited Vulnerabilities catalog: the action CISA requires of US federal civilian agencies under Binding Operational Directive 22-01, by kev_due_date. It is CISA's text, not EchelonGraph's advice. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_short_description": {
      +            "description": "CISA's shortDescription of the vulnerability, verbatim from its Known Exploited Vulnerabilities catalog. Absent where the CVE is not CISA-KEV-listed, where CISA's entry has none, or where EchelonGraph has not stored it yet (an API older than the field serves none).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "modified": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "patch_available": {
      +            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false. An answer with no patch_evidence (an API older than that field) does not name the evidence, and a false there is not a finding that no fix exists either.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "patch_evidence": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "anyOf": [
      +                    {
      +                      "enum": [
      +                        "vendor_patch",
      +                        "fixed_version",
      +                        "release_reference",
      +                        "nvd_patch_reference",
      +                        "cna_patch_reference"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "string"
      +                    }
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range), release_reference (a reference that EchelonGraph confirmed through the GitHub API is a published release containing the fix, or a pull request or commit that a published release contains), nvd_patch_reference (an NVD reference tagged Patch) and cna_patch_reference (a reference the CVE's CNA tagged patch in its CVE record). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +          },
      +          "published": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "references": {},
      +          "remediation": {
      +            "anyOf": [
      +              {
      +                "additionalProperties": {},
      +                "properties": {},
      +                "type": "object"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "A capped summary (at most 1,500 characters of JSON) of how the CVE is fixed, as its sources state it: vendor_remediation_kinds (per kind, the vendor advisories listing one for this CVE, by the vendor's own category), vendor_advisories, vendors_not_parsed, kev_required_action (CISA's, verbatim), fixed_branches_count, fixed_versions (per package, fixed versions on record), fix_references (URLs tagged Patch or Mitigation), failed_sections, truncated, and see, the name of the tool that returns the whole, with each text. A kind missing from vendor_remediation_kinds is not a finding that no such remediation exists. Absent for a REJECTED CVE and from an API older than the field."
      +          },
      +          "score_assessed": {
      +            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "score_confidence": {
      +            "description": "How confident EchelonGraph is in its score: NONE when score_assessed is false.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "score_unassessed_reason": {
      +            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "updated_at": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "type": "null"
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  5. Changed1 schema field changed
    • changedOutput schema / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "description": "What the answer covers; null where the answer says nothing about it.",
      -        "type": "null"
      -      },
      -      "data": {
      -        "additionalProperties": {},
      -        "properties": {
      -          "cpe_configurations": {
      -            "anyOf": [
      -              {
      -                "items": {},
      -                "type": "array"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      -          },
      -          "cpe_match": {
      -            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      -          },
      -          "cve_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "cvss_v3_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "cvss_v4_severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "description": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_risk": {
      -            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_score": {
      -            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "echelongraph_severity": {
      -            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "epss_percentile": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "epss_score": {
      -            "type": [
      -              "number",
      -              "null"
      -            ]
      -          },
      -          "ghsa_id": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_added_date": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "kev_listed": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "kev_ransomware": {
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "modified": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "published": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "references": {},
      -          "score_assessed": {
      -            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      -            "type": [
      -              "boolean",
      -              "null"
      -            ]
      -          },
      -          "score_confidence": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "score_unassessed_reason": {
      -            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "severity": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "updated_at": {
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "anyOf": [
      -          {
      -            "description": "An RFC 3339 instant.",
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      -      },
      -      "method": {
      -        "description": "How the numbers were produced.",
      -        "type": "string"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      -        "enum": [
      -          "measured",
      -          "not_assessed"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "data"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "coverage": {
      -        "type": "null"
      -      },
      -      "error": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "kind": {
      -            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      -            "enum": [
      -              "network",
      -              "timeout",
      -              "http",
      -              "not_json",
      -              "not_object",
      -              "invalid_input",
      -              "internal",
      -              "unexpected_shape",
      -              "radars"
      -            ],
      -            "type": "string"
      -          },
      -          "message": {
      -            "description": "The cause: the API's own message, or what went wrong.",
      -            "type": "string"
      -          },
      -          "path": {
      -            "description": "The API path requested, when a request was made.",
      -            "type": [
      -              "string",
      -              "null"
      -            ]
      -          },
      -          "status": {
      -            "anyOf": [
      -              {
      -                "maximum": 9007199254740991,
      -                "minimum": -9007199254740991,
      -                "type": "integer"
      -              },
      -              {
      -                "type": "null"
      -              }
      -            ],
      -            "description": "The HTTP status, when the API answered one."
      -          }
      -        },
      -        "required": [
      -          "kind",
      -          "path",
      -          "status",
      -          "message"
      -        ],
      -        "type": "object"
      -      },
      -      "freshness": {
      -        "type": "null"
      -      },
      -      "measured_at": {
      -        "type": "null"
      -      },
      -      "method": {
      -        "type": "null"
      -      },
      -      "notes": {
      -        "description": "Caveats, one sentence each.",
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "state": {
      -        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      -        "enum": [
      -          "failed",
      -          "invalid_input"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "state",
      -      "measured_at",
      -      "method",
      -      "coverage",
      -      "freshness",
      -      "notes",
      -      "error"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "description": "What the answer covers; null where the answer says nothing about it.",
      +        "type": "null"
      +      },
      +      "data": {
      +        "additionalProperties": {},
      +        "properties": {
      +          "cpe_configurations": {
      +            "anyOf": [
      +              {
      +                "items": {},
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "NVD's configurations array as NVD sent it: each configuration and node with its operator (AND, OR) and negate, and each cpeMatch with criteria, vulnerable, versionStartIncluding, versionStartExcluding, versionEndIncluding, versionEndExcluding and matchCriteriaId. A cpeMatch with vulnerable false inside an AND configuration is the platform the vulnerable product runs on, not an affected product. Absent: EchelonGraph holds no stored NVD configuration for the CVE, which is not a finding that no product is affected."
      +          },
      +          "cpe_match": {
      +            "description": "The record's CPE match criteria as one flat list, every configuration's cpeMatch entries together: the AND/OR operator and negate of each configuration and node, versionStartExcluding and matchCriteriaId are not in it, so a CPE that is only a platform a product runs on reads as one more entry."
      +          },
      +          "cve_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "cvss_v3_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "cvss_v4_severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "description": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_risk": {
      +            "description": "EchelonGraph's 0-100 risk priority, fused from the score, exploitation and automatability: a rating only when score_assessed is true. With score_assessed false it is a placeholder.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_score": {
      +            "description": "EchelonGraph's 0-10 score for the CVE: a score only when score_assessed is true. With score_assessed false it is a placeholder, not a rating.",
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "echelongraph_severity": {
      +            "description": "The severity band of echelongraph_score: a rating only when score_assessed is true. With score_assessed false it is a placeholder (NONE).",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "epss_percentile": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "epss_score": {
      +            "type": [
      +              "number",
      +              "null"
      +            ]
      +          },
      +          "ghsa_id": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_added_date": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "kev_listed": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "kev_ransomware": {
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "modified": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "patch_available": {
      +            "description": "true: EchelonGraph holds evidence of a fix for the CVE, its sources named in patch_evidence. false: no fix evidence is on record, which is not a finding that no fix exists. Once true it is never set back to false.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "patch_evidence": {
      +            "anyOf": [
      +              {
      +                "items": {
      +                  "anyOf": [
      +                    {
      +                      "enum": [
      +                        "vendor_patch",
      +                        "fixed_version",
      +                        "nvd_patch_reference"
      +                      ],
      +                      "type": "string"
      +                    },
      +                    {
      +                      "type": "string"
      +                    }
      +                  ]
      +                },
      +                "type": "array"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The sources of the fix evidence EchelonGraph holds for the CVE, strongest first: vendor_patch (a vendor patch on record, from Ubuntu or Red Hat), fixed_version (a fixed version recorded for an affected package, or the fixed bound of an affected version range) and nvd_patch_reference (an NVD reference tagged Patch). Empty where none was found when EchelonGraph last computed it. Absent (an API older than the field): the answer does not name the evidence."
      +          },
      +          "published": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "references": {},
      +          "score_assessed": {
      +            "description": "Whether EchelonGraph has scored the CVE. true: echelongraph_score, echelongraph_severity and echelongraph_risk are its score. false: the CVE is NOT YET SCORED, not scored 0, and any of those three it carries is a placeholder, not a rating; the API may leave them out. Absent (an API older than the field): the answer does not say whether the CVE was scored.",
      +            "type": [
      +              "boolean",
      +              "null"
      +            ]
      +          },
      +          "score_confidence": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "score_unassessed_reason": {
      +            "description": "Why score_assessed is false: no_signal, no source has yet published severity data EchelonGraph can score; or rejected, the record was withdrawn by its numbering authority and is never scored. Absent when the CVE is scored.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "severity": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "updated_at": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "description": "The producing radar's last completed check (last_run_at), where the API serves one.",
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "anyOf": [
      +          {
      +            "description": "An RFC 3339 instant.",
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "When the underlying observation was made, as the API states it; null when the answer does not say or holds no observation."
      +      },
      +      "method": {
      +        "description": "How the numbers were produced.",
      +        "type": "string"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "measured: a measurement of what was asked; an exposure count is measured only with measured_at and method. not_assessed: the answer holds no dated measurement of what was asked, so no count in it is presented as one; it can still relay a count, as what the source holds on record, undated, and its notes (and exposure_state, where the result carries it) say what each count is.",
      +        "enum": [
      +          "measured",
      +          "not_assessed"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "data"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "coverage": {
      +        "type": "null"
      +      },
      +      "error": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "kind": {
      +            "description": "What failed: the request (network, timeout), the answer (http, not_json, not_object, unexpected_shape), the input, or this server.",
      +            "enum": [
      +              "network",
      +              "timeout",
      +              "http",
      +              "not_json",
      +              "not_object",
      +              "invalid_input",
      +              "internal",
      +              "unexpected_shape",
      +              "radars"
      +            ],
      +            "type": "string"
      +          },
      +          "message": {
      +            "description": "The cause: the API's own message, or what went wrong.",
      +            "type": "string"
      +          },
      +          "path": {
      +            "description": "The API path requested, when a request was made.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "status": {
      +            "anyOf": [
      +              {
      +                "maximum": 9007199254740991,
      +                "minimum": -9007199254740991,
      +                "type": "integer"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ],
      +            "description": "The HTTP status, when the API answered one."
      +          }
      +        },
      +        "required": [
      +          "kind",
      +          "path",
      +          "status",
      +          "message"
      +        ],
      +        "type": "object"
      +      },
      +      "freshness": {
      +        "type": "null"
      +      },
      +      "measured_at": {
      +        "type": "null"
      +      },
      +      "method": {
      +        "type": "null"
      +      },
      +      "notes": {
      +        "description": "Caveats, one sentence each.",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "state": {
      +        "description": "failed: the lookup did not complete. invalid_input: the input was refused, so nothing was looked up. Neither is a finding.",
      +        "enum": [
      +          "failed",
      +          "invalid_input"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "state",
      +      "measured_at",
      +      "method",
      +      "coverage",
      +      "freshness",
      +      "notes",
      +      "error"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. First observed

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description adds substantial interpretive context beyond them: score_assessed=false means NOT YET SCORED rather than 0, placeholder values must not be read as harmless, KEV text is CISA's verbatim wording rather than EchelonGraph advice, patch_available=false is an absence of evidence and not evidence of absence, freshness is null, and TEXT CUT/DATA CUT truncation behavior is explained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The resource scope is front-loaded and the caveat sentences earn their place, but the long comma-separated enumeration of every returned field is redundant given the output schema exists, and several sentences are dense run-ons. It is information-dense rather than padded, yet materially longer than needed for correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations, a full input schema and an output schema already present, the description supplies exactly the missing interpretive layer: unscored-vs-zero semantics, provenance of KEV text, meaning of absent cpe_configurations and patch evidence, and truncation behavior. An agent can call this correctly and interpret the result without further context, with only sibling routing left to usage guidelines.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents both cve_id and the full/truncation parameter extensively, so the description's 'Pass a CVE ID like CVE-2023-44487' and 'unless full: true' are largely restatements. The description does add the TEXT CUT counterpart to the schema's DATA CUT explanation, but on balance it adds little semantic meaning to the parameters beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific resource and scope: 'One CVE's record', followed by an exhaustive enumeration of what that record contains (scores, KEV, GHSA, CPE, remediation, timestamps). It is clearly a single-CVE detail fetch rather than a search, but it never names a sibling such as cve_summary or cve_intel to draw the boundary explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the field-level detail signals 'call this when you need the full record', and 'Pass a CVE ID like CVE-2023-44487' gives the input shape. There is no statement of when to prefer cve_summary, cve_intel or cve_remediation over this tool, and no exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.