Users who subscribe to infrequent-but-high-quality RSS feeds (e.g. Gwern, Karpathy, Wait But Why, colah) effectively lose them in the river because prolific feeds dominate the chronological feed. This feature ensures slow posters never get silently dropped.
The newsreader river is sorted by recency. A feed that posts once a month will appear once among potentially hundreds of items that week, and if the user doesn't scroll far enough, they miss it. There's no way to distinguish "this feed has been quiet" from "I stopped reading it."
Add a *Slow Feed Digest* view to the newsreader web UI. This view surfaces articles from feeds that haven't appeared in the user's main river for a configurable threshold period (default: 14 days).
New route: GET /newsreader/slow-feeds
Query: Find all feeds where:
1. The feed has at least one article in the DB, AND
2. The most recent article's published_at or fetched_at is older than N days (configurable, default 14), OR
3. The feed has never been fetched (last_fetched IS NULL) and created_at is older than 7 days
Display: Same card layout as the main index. Group by feed (show feed title as a section header). Within each feed, show up to 3 most recent articles. Sort feeds by "most stale first" (longest gap at top).
DB query (SQLite):
SELECT
f.id as feed_id,
f.title as feed_title,
f.url as feed_url,
MAX(a.published_at) as last_article_date,
COUNT(a.id) as article_count
FROM feeds f
LEFT JOIN articles a ON a.feed_id = f.id
GROUP BY f.id
HAVING
last_article_date IS NULL
OR last_article_date < datetime('now', '-14 days')
ORDER BY last_article_date ASC NULLS FIRST;
Then for each matching feed, fetch its 3 most recent articles.
Navigation: Add a "Slow Feeds" link in the nav bar next to the existing links.
Config: The threshold (14 days) should be a constant at the top of Web.hs, not hardcoded inline. Call it slowFeedThresholdDays.
Omni/Newsreader/Web.hs — add new route + handler + HTML templateOmni/Newsreader/Db.hs — add getSlowFeeds :: Connection -> Int -> IO [(Feed, [Article])] query/newsreader/slow-feeds returns HTTP 200 with correct HTMLNo activity yet.