feat(feed): make For You inclusive + ranked by your lists (G1-G5)

The For You feed was chronological, hashtag-interest-EXCLUSIVE, and ignored
follows entirely (docs/feed-algo-audit.md). Now it is inclusive + ranked:

- createForYouScorerStage scores each video: follows-boost (author you follow)
  + interest/watch-topic affinity (cosine vs your interests+watch-history vector)
  + freshness - disinterest penalty. Reuses Explore's vector/similarity helpers.
- createForYouScoreSorter ranks by that score (muted last, recency tiebreak).
- For You pipeline: interests now BOOST not exclude (enforceInterests:false);
  scorer added; chronological sorter replaced. Never empty (falls back to
  recency when you have no follows/interests/history).
- buildForYouFeedRuntime now feeds subscriptionAuthors + watchHistoryTagCounts.

Watched/blocked/muted are still removed (suppression/blacklist/moderation
stages unchanged). Cheat-resistant tests (older boosted items only win via the
boost). Grid renders end-to-end (~1.3s). Weight tuning is a follow-up.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-14 16:57:05 -04:00
1 parent 44bf88cf88
commit c0a8636678
8 files changed
+322 -7

No files matched your search

+20 -1
View File
@@ -35,7 +35,26 @@ Runtime inputs (`buildForYouFeedRuntime`): `blacklistedEventIds`,
So the refactor's payoff is real: these lists now load and *do* shape For You.
## Gaps (the deliverable)
## Resolution (2026-06-14)
Product decision: **For You = inclusive + ranked**. Implemented:
- New `createForYouScorerStage` (in `exploreScoring.js`) scores each video by
**follows-boost + interest/watch-topic affinity + freshness − disinterest**
(reusing Explore's vector/similarity/freshness helpers; affinity uses the
combined interests+watch-history user vector).
- New `createForYouScoreSorter` ranks by that score (muted last, recency tiebreak).
- `registerForYouFeed`: interests now **boost** instead of exclude
(`enforceInterests:false`); scorer added; chronological sorter replaced.
- `buildForYouFeedRuntime` now supplies `subscriptionAuthors` (follows) and
`watchHistoryTagCounts`.
- Result: **G1 follows, G2 ranking, G3 inclusivity (never empty), G4 watch-topic
affinity, G5 blending — all addressed.** Cheat-resistant tests in
`tests/for-you-scorer.test.mjs`.
Tuning of the weights is a follow-up (currently follows .4 / affinity .35 /
freshness .25 / disinterest .3).
## Gaps (original audit)
### G1 — Follows/subscriptions have ZERO effect on For You *(highest impact)*
For You's source is `createActiveNostrSource` (all videos); the runtime passes no