Reject branded/generic share images; hero prefers a clean illustrated story

- og:image enrichment now skips branded/generic share images (BBC 'branded_news'
  with its burned-in logo, NPR 'facebook-default', etc.) and keeps the first
  real article image — so no competitor logo lands on our hero. Cleared the few
  already-stored branded URLs so they re-enrich.
- Hero selection now prefers a gentle + readable story that also HAS a (clean)
  image, falling back to gentle-readable, then gentle. The lead is visual when
  possible, typographic otherwise — never branded.

(The '7 cards' report was a stale browser cache: the brief stores 7 and the
built JS requests 7; a hard refresh shows all seven.)

Tests: branded/generic image rejection (87 total).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jay
2026-05-31 13:03:20 +00:00
parent d8d665ee35
commit 7e1dfd5b3c
3 changed files with 48 additions and 6 deletions
+11
View File
@@ -69,3 +69,14 @@ def test_enrich_upgrades_existing_feed_image(tmp_path):
assert found == 1
assert c.execute("SELECT image_url FROM articles WHERE id=1").fetchone()["image_url"] == "https://bbc.com/big-og.jpg"
c.close()
def test_rejects_branded_and_generic_share_images():
assert og_image_from_html(b'<meta property="og:image" content="https://ichef.bbci.co.uk/news/1024/branded_news/x.jpg">') is None
assert og_image_from_html(b'<meta name="twitter:image" content="https://media.npr.org/include/images/facebook-default-wide-s.jpg">') is None
# a real article image still comes through
assert og_image_from_html(b'<meta property="og:image" content="https://x.com/real-photo.jpg">') == "https://x.com/real-photo.jpg"
# if the first og is branded but a later one is real, take the real one
html = (b'<meta property="og:image" content="https://x.com/branded_news/logo.jpg">'
b'<meta property="og:image" content="https://x.com/article.jpg">')
assert og_image_from_html(html) == "https://x.com/article.jpg"