Skip to content

Instantly share code, notes, and snippets.

@aldrinleal
Created June 15, 2026 15:55
Show Gist options
  • Select an option

  • Save aldrinleal/612887eb1f040b4c79eeb414363ea985 to your computer and use it in GitHub Desktop.

Select an option

Save aldrinleal/612887eb1f040b4c79eeb414363ea985 to your computer and use it in GitHub Desktop.
MVP-740 Feed-per-tags v1 — Coverage Confirmation (code audit, 2026-06-15)

MVP-740 — Feed per Tags, Algorithm v1 — Coverage Confirmation (Code Audit)

Companion to: MVP-782–789 follow-up · MVP-790 & 791 follow-up · original Algo Signal Upgrades gist Date: 2026-06-15 Question audited: "Confirm this also applies to MVP-740." Verdict: 🟢 MVP-740 is satisfied, and superseded, by the current implementation. The swipe/follow mechanics shipped under 784/787/788/790/791 are the v2 evolution of exactly this v1 feature. No new backend code required.

Original Ticket (as provided)

E - Feed per tags - algorithm v1

Description

As a surfer, I want the feed to suggest posts that are relevant to tags I wanted to see more of or less of, so that I will see posts that interest me.

  • Scroll right (from left to right) - show me more of that - update the feed to show posts with at least 1 tag in common to that post
  • Scroll left (from right to left) - I'm not interested in that - update the feed randomly (in the future will remove posts based on the related tags of the current post I'm at and also based on what you know about me so far)
  • Click a tag to follow that tag and see posts relevant to that tag
  • User gets a feed and can scroll down to see many posts
  • Feed stands on post e.g. #100
  • User swipes right and the feed is updated with posts that share same tags as post #100
  • User swipes left: randomly some posts are removed from the feed and others are added.
  • User scrolls up: user can scroll up and see all the posts that they actually saw in the feed. Posts which were supposed to be in the feed but were not presented e.g. because of swiping right or left are not presented
  • User clicks a tag and the feed is updated to show posts relevant to this tag. Also the tag is marked as followed

Acceptance Criteria → Code

AC Status Where
Swipe "more" → feed shows posts with ≥1 tag in common ✅ exceeded /feed/signal adds the post's tags to FeedSession.boosted_tag_ids (feeds_http.py:1082-1085); PersonalizedFeedAdapter explicitly "finds posts sharing at least one top tag" with a 1.5× boost (feed_adapters.py:478,493), plus persistent more_like_this affinity (+1.5)
Swipe "not interested" → feed updates (v1: "randomly"; future: remove by related tags + personalization) ✅ the future behavior tags added to suppressed_tag_ids; _apply_session_filters drops posts whose whole tag set is suppressed (feed_adapters.py:235) + persistent less_like_this (−1.5) + MeSH-family reduction. Deterministic, not random
Click tag → follow it and see relevant posts create_follow writes DBFollow(follow_type=TAG) (follows.py:142-146) → marked followed; records tag_follow (+2.0) (follows.py:160-163) → that tag's affinity lifts those posts
Feed + scroll down (pagination) PaginatedList + offset/next cursor
Swipe right on #100 → feed updated with posts sharing #100's tags = AC1; session boost takes effect on the next fetch (FE passes session_id)
Swipe left → some removed, others added ✅ functionally suppressed-tag posts filtered out, page backfilled — smarter than v1's "random"
Scroll up → only posts actually seen; un-presented ones not shown ⚠️ FE-owned backend supports it (intra-request dedup via seen_ids; view tracking in post_views), but the "scroll-up history" is the frontend's rendered list — the backend doesn't reconstruct "what was presented"
Click tag → feed updated + tag followed = AC3

Closure Notes (not code gaps)

  1. Direction-mapping conflict between tickets. MVP-740 says left-to-right = "more"; MVP-790 says left-to-right = "reduce". The backend is direction-agnostic — it implements more_like_this / less_like_this events and the frontend maps the physical gesture. Not a backend conflict, but product/FE should reconcile which physical direction means what, since the two tickets specify opposites.
  2. "Random" left-swipe (literal) was intentionally replaced by tag-suppression + affinity reduction — the behavior the ticket itself flagged as the "future" version. Better, but if QA tests for literal randomness it won't match; confirm that's the accepted interpretation.
  3. AC for scroll-up history is a frontend deliverable. If 740 is backend-scoped, that AC is satisfied on the backend side (view tracking + dedup exist). If it's full-stack, the FE owns the "posts you actually saw" list.

Recommended Action

Close MVP-740 as delivered (superseded by the v2 signal/feed work), recording closure notes 1–3 above. No backend implementation outstanding.

References

  • app/sherpahealthy/posts/feeds_http.py/feed/signal (:1071-1105), _execute_feed_query
  • app/sherpahealthy/posts/feed_adapters.pyPersonalizedFeedAdapter (:455+), _apply_session_filters (:202-237)
  • app/sherpahealthy/follows.pycreate_follow (:51+)
  • app/sherpahealthy/engagement.py — swipe/follow deltas + MeSH propagation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment