a7da8362ab
- goodnews/daily.py: shared helpers for the daily "small joys" (http_json, date-seeded deterministic pick, dedup key) so each joy is a small self-contained module. - goodnews/onthisday.py: harvest today's MM-DD from Wikimedia's On-this-day feed → tone-filter to good/neutral (keyword floor + optional LLM refine) → pool → deterministic daily pick (idempotent, respects blocked/featured) → cached row. Network/LLM before any DB write. Multi-source ready (source column). - db.py: onthisday_pool + daily_onthisday tables. - api.py: GET /api/onthisday/today (edge-cacheable). - cli.py: cycle step (run after Daily Art; --no-joys to skip), LLM client for tone refine. - tests/test_onthisday.py: 7 tests (filter+dedup, pick idempotent, blocked/featured, never-empty, empty-pool, LLM-narrow). 382 backend tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>