About Divergence

Reading the news is weird. You can read the same story from five different outlets and walk away with completely different impressions of what happened. Divergence shows you those differences side by side.

What it does

Every 30 minutes, Divergence pulls articles from 14 news outlets across the political spectrum. When multiple sources cover the same story, those articles get grouped into a single event. Each event is then analyzed to extract the facts being reported and how each outlet is framing the story.

The goal is to let you see the same news event from multiple angles at once, without having to tab between a bunch of different sites.


The divergence score

Each event gets a score from 0 to 100 based on how differently the sources are covering it.

0 to 33 Sources are basically telling the same story
34 to 66 Noticeably different framing or emphasis
67 to 100 Sources are presenting genuinely different pictures of what happened

The score is calculated by an AI model that reads all the articles in a cluster and looks for differences in framing, emphasis, and factual claims. It's not perfect, but it gives a reliable signal for which stories have the most disagreement worth reading.


The fact breakdown

Each event includes a list of specific claims labeled as confirmed, claimed, or disputed. Confirmed means multiple credible sources agree and there's an official basis. Claimed means one source reported it without corroboration. Disputed means sources directly contradict each other on it.

This is also AI-generated, so treat it as a starting point, not a final verdict. Click through to the original articles when something matters to you.


Sources

We pull from 946 articles across these outlets, refreshing every 30 minutes:

Left
The Guardian, HuffPost
Center-left
BBC, NPR, CNN, PBS NewsHour
Center / Wire
ABC News, AP News, Axios, Politico, The Hill
Right
Fox News, NY Post
International
Al Jazeera

Bias labels are our rough classifications based on widely-cited media bias research. They're meant to give you context for the coverage spectrum, not to judge individual articles.


How stories get grouped

Articles are grouped using text similarity, not keyword matching. Two articles about the same event will have similar language and context even if the headlines use completely different words. We run a lightweight local embedding model to detect that similarity and cluster the articles together.

A story needs at least 2 sources to show up in the feed. Events drop off after 7 days but stay searchable in the archive.


Pipeline overview

1
RSS ingestion, every 30 minutes
feedparser polls 14 RSS feeds. Raw HTML is fetched with browser-spoofed headers, then full article text is extracted via trafilatura. If that fails, newspaper3k is tried as a fallback, then the Wayback Machine snapshot, then the RSS summary field. New articles are deduplicated by URL and written to SQLite.
2
Embedding + clustering
Each article's headline and description are encoded into a 384-dimensional vector using all-MiniLM-L6-v2 running locally via sentence-transformers. A greedy agglomerative pass groups articles with cosine similarity ≥ 0.60. New articles are first checked against existing events (7-day window) before forming new clusters.
3
Claude analysis
Each new event cluster (≥ 2 sources) is sent to claude-sonnet-4-20250514 via the Anthropic API. The model extracts a neutral event title, 2 to 3 sentence summary, category, fact list with confirmation status, per-outlet framing labels, and the divergence score. The response is constrained to JSON with no markdown.
4
Storage + serving
Results are written to a local SQLite database with three tables: articles, events, and event_articles. A Flask app reads from the DB and renders events sorted by divergence score. The page auto-refreshes every 5 minutes; the pipeline re-runs every 30.

AP News feed via RSSHub

AP News does not publish a public RSS feed and blocks most scrapers. Divergence runs a self-hosted RSSHub instance in a Docker container on localhost:1200, which generates live RSS feeds from AP's website.

Feed endpoint: http://localhost:1200/apnews/topics/apf-topnews


Divergence score rubric

Claude scores each event across four independent dimensions, then sums them. The model is explicitly instructed not to round to multiples of 5.

Framing
0 to 40 pts: how differently outlets characterize the same core facts
Fact selection
0 to 30 pts: whether outlets include or omit different facts
Causal attribution
0 to 20 pts: disagreement on cause, blame, or context
Factual disputes
0 to 10 pts: direct contradictions between outlets