news: harden paywall exclusion at the candidate query + add the missing regressions

Codex's two non-blocking hardening items, folded in before cutover:
- _candidate_articles() now excludes paywalled sources IN-QUERY (before LIMIT 50),
  so flagged stories can't consume candidate slots and leave a full brief thin.
  Dropped the now-redundant post-fetch filter in build_daily_brief.
- Regressions: history retains a viewed paywalled article; sitemap omits a
  paywalled source AND restores it under override="free".
- Aligned test_brief_paywall to the source-level model (paywalled sources carry a
  paywalled homepage, as in production) — it had relied on article-URL detection.

425 backend tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-28 18:54:53 -04:00
parent c600145ba5
commit 1c1ecefde8
4 changed files with 50 additions and 9 deletions
+9
View File
@@ -67,6 +67,15 @@ def test_saved_retains_paywalled():
assert 1 in [r["id"] for r in queries.saved(c, 1)] # you keep what you saved
def test_history_retains_paywalled():
c = connect(":memory:"); init_db(c)
_setup(c)
c.execute("INSERT INTO users (id,email) VALUES (1,'r@x.com')")
c.execute("INSERT INTO user_history (user_id,article_id,at) VALUES (1,1,'2026-06-28T00:00:00')")
c.commit()
assert 1 in [r["id"] for r in queries.history(c, 1)] # a viewed paywalled article stays in history
def test_free_override_restores_eligibility():
c = connect(":memory:"); init_db(c)
today = _setup(c, pay_override="free") # same domain-less source, but marked free