Local-first Brief: the landing leads with good news from your home

Per the owner's call (overrides the earlier "Brief sacred" stance): when a home is
set, the homepage opens with local good news first, not global. This is the hook —
you land and see awesome stories from YOUR corner first.

- queries.home_brief: local-first highlights (high/medium-confidence near, blended
  out to country then world so it's always a full, strong set), preferring already-
  summarized stories so the calm read stays rich. Recent window, ranked within tier.
- /api/brief gains a `home` param: private/no-store when set; over-fetches + caps so
  dismissal/boundary filtering never thins it; falls back to global top-up if needed.
- Landing UI: a Local <-> Global toggle ("📍 Near you / 🌍 Everywhere") when a home
  is set, the calm picker invite when not (dismissible), and Change. Default leads
  local; one tap back to the global brief. No home set => exactly today's behavior.

Backend + frontend tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-19 21:36:18 -04:00
parent 2239549799
commit d2a6293a13
7 changed files with 1784 additions and 16 deletions
+8 -2
View File
@@ -213,10 +213,16 @@ def tag_articles(conn: sqlite3.Connection, client: LocalModelClient, limit: int
for r in rows:
try:
store_geo(conn, r["id"], classify_geo(client, r))
# Keep live auth/admin writes healthy while the scheduled cycle runs.
# Geo classification calls the LLM per article; if we batch commits, the
# first stored article opens a write transaction that can stay open while
# the next several LLM calls run. That starves login/session writes long
# enough to trip SQLite's busy timeout. Commit each successful article so
# the writer lock is held for milliseconds, not minutes.
conn.commit()
tagged += 1
except Exception: # noqa: BLE001 — non-fatal, like other cycle steps
conn.rollback()
errors += 1
if (tagged + errors) % 25 == 0:
conn.commit()
conn.commit()
return {"candidates": len(rows), "tagged": tagged, "errors": errors}