Cybersecurity-Projects/PROJECTS/intermediate/security-news-scraper/internal
CarterPerez-dev 8713712bf9 feat(nadezhda): M4 ranking + digest + Markdown/JSON export
Turn the aggregated store into a ranked, exportable digest of story clusters.

- internal/rank: pure deterministic Score(Signals, cfg.Rank) — recency
  (exp half-life decay), cvss/10, kev, epss, velocity (cluster size/age), source
  weight, watchlist keyword. Every signal clamped to [0,1]; all weights +
  half_life + velocity_norm from config, no literals. recency/velocity are total
  (guard half_life<1 and norm<=0). Rank() scores each cluster and stable-sorts
  desc, tiebreak freshest. Research 06's two worked examples are the golden-order
  test (A ~0.99 strictly above B ~0.13).
- internal/export: per-cluster (story) digest. Headline = freshest member, distinct
  sorted outlets, CVEs sorted KEV-first then CVSS. Markdown + deterministic JSON.
- store.DigestClusters: 3-query per-cluster aggregation (clusters by since, member
  articles, union of CVE signals) with explicit ORDER BY; per-cluster CVE dedup
  via SELECT DISTINCT.
- digest command: --top/--since/--format md|json/--out. Off the stub list.
- Proven live: scrape -> digest --format md and json render correctly, per-cluster
  (FortiBleed shows 3 outlets). Suite offline + -race.

One read-only audit agent; 0 Crit/High/Med, golden-order math verified; Low/Nit
fixed in-phase (top<=0 count, pure-fn guards, ORDER BY, headline sanitize, 2-cluster
attach test).

Digest ranks per-cluster (Carter's choice), not per-article.
2026-07-05 18:42:57 -04:00
..
cluster feat(nadezhda): M2 cross-source dedup + clustering 2026-07-05 15:11:29 -04:00
config feat(nadezhda): M3 CVE extraction + NVD/KEV/EPSS enrichment 2026-07-05 15:54:49 -04:00
cve feat(nadezhda): M3 CVE extraction + NVD/KEV/EPSS enrichment 2026-07-05 15:54:49 -04:00
enrich feat(nadezhda): M3 CVE extraction + NVD/KEV/EPSS enrichment 2026-07-05 15:54:49 -04:00
export feat(nadezhda): M4 ranking + digest + Markdown/JSON export 2026-07-05 18:42:57 -04:00
fetch feat(nadezhda): M1 ingestion core (fetch, parse, normalize, dedup) 2026-07-05 14:51:57 -04:00
ingest feat(nadezhda): M3 CVE extraction + NVD/KEV/EPSS enrichment 2026-07-05 15:54:49 -04:00
normalize feat(nadezhda): M1 ingestion core (fetch, parse, normalize, dedup) 2026-07-05 14:51:57 -04:00
parse feat(nadezhda): M1 ingestion core (fetch, parse, normalize, dedup) 2026-07-05 14:51:57 -04:00
rank feat(nadezhda): M4 ranking + digest + Markdown/JSON export 2026-07-05 18:42:57 -04:00
source feat(nadezhda): M0 scaffold for security news + CVE aggregator 2026-07-05 13:22:08 -04:00
store feat(nadezhda): M4 ranking + digest + Markdown/JSON export 2026-07-05 18:42:57 -04:00
version feat(nadezhda): M0 scaffold for security news + CVE aggregator 2026-07-05 13:22:08 -04:00