docs(nadezhda): fix learn/ weight-split and Log4Shell CWE

The 70% news bloc is recency+velocity+source+keyword, not recency+velocity alone (which sum to 0.50). Log4Shell surfaces as CWE-502 (first CNA problemType, per TestCVEListParsesLog4Shell), not CWE-20. Also reword the 04-CHALLENGES weight aside to match.
This commit is contained in:
CarterPerez-dev 2026-07-09 07:19:31 -04:00
parent 5ece03699b
commit 679a86d593
2 changed files with 3 additions and 3 deletions

View File

@ -27,7 +27,7 @@ The subtle part is *where* the score lives. In the CVE Program record for **Log4
### CWE: what kind of weakness is it
Where CVSS scores severity, the Common Weakness Enumeration classifies the *kind* of flaw. CVE-2025-5777 is CWE-125, an out of bounds read. Log4Shell enriches to CWE-20, improper input validation. CWE is what lets you say "we keep shipping the same class of bug" across many CVEs, and it is a natural axis to filter or group on.
Where CVSS scores severity, the Common Weakness Enumeration classifies the *kind* of flaw. CVE-2025-5777 is CWE-125, an out of bounds read. Log4Shell is CWE-502, deserialization of untrusted data. CWE is what lets you say "we keep shipping the same class of bug" across many CVEs, and it is a natural axis to filter or group on.
### CISA KEV: is it being exploited right now
@ -71,7 +71,7 @@ score = w_recency * recency_decay(age)
`recency_decay` is an exponential half life function, so a story loses half its recency weight every configured number of hours. Every weight lives in configuration, not in the code, so there are no magic numbers to hunt for and the model is fully tunable.
The default weights are news first: recency and velocity together carry 70 percent, and the CVE signals (KEV, CVSS, EPSS) carry the remaining 30. This reflects a specific product decision. Nadezhda is a security *news* tool. A breach or a campaign with no CVE at all should not be buried beneath a routine patch note just because the patch note has a number attached. The CVE data is intelligence that enriches a story, not the reason the story matters.
The default weights are news first: recency, velocity, source, and keyword together carry 70 percent, and the CVE signals (KEV, CVSS, EPSS) carry the remaining 30. This reflects a specific product decision. Nadezhda is a security *news* tool. A breach or a campaign with no CVE at all should not be buried beneath a routine patch note just because the patch note has a number attached. The CVE data is intelligence that enriches a story, not the reason the story matters.
Because ranking is a pure function of stored inputs, the same corpus always produces the same order. That property is what lets the project assert its ranking with golden order tests: feed fixed inputs, expect one exact ordering.

View File

@ -9,7 +9,7 @@ Ways to extend the project, ordered roughly from an afternoon to a serious under
**Add a source.** The source list is `sources.yaml`, embedded by default. Add an entry with a name, feed URL, type, and weight, then run `nadezhda sources` to persist it and `nadezhda scrape` to pull it. Pick a feed that overlaps with the existing seven (say, a second general security outlet) and watch it start joining clusters. The source `weight` feeds ranking, so a source you trust more nudges its stories up.
**Retune the ranking.** Every weight lives in `config`, under `rank.weights`. The defaults are news first (recency and velocity dominate). Flip that: crank `cvss`, `kev`, and `epss` up and `recency` down, scrape, and compare the top of `nadezhda digest`. You will see the list reorder toward raw severity. There is no code change here, which is the point: the model is data, not logic.
**Retune the ranking.** Every weight lives in `config`, under `rank.weights`. The defaults are news first (recency and velocity are the heaviest weights). Flip that: crank `cvss`, `kev`, and `epss` up and `recency` down, scrape, and compare the top of `nadezhda digest`. You will see the list reorder toward raw severity. There is no code change here, which is the point: the model is data, not logic.
**Add a keyword watchlist.** Set `watchlist` in config to the vendors and products you actually run. `matchesWatchlist` in `internal/rank` scores a cluster higher when a term appears in its titles or CVEs. Confirm it works by adding a vendor you know is in today's news and watching its stories climb.