Serving & subscriptions
Feeds owns the serving surface and stays out of the ranking business — the chronological feed is assembled from what a reader follows, and the personalized feed is ranked by the Recommendations subsystem.
Subscriptions
A subscription links a reader's profile to a source. Together with the sources they own outright, it defines what their Following feed contains.
subscribe(sourceId) is idempotent — calling it twice is safe and returns the subscribed source either way.unsubscribe(sourceId) is honest — it returns false when the caller wasn't subscribed.mySubscriptions lists the caller's subscribed sources, newest subscription first; mySources lists the ones they own.mutation Subscribe($sourceId: UUID!) { feeds { mySubscriptions { subscribe(sourceId: $sourceId) { id name } } } }
Serving surfaces
Every surface returns items as content records — so a client reads the normalized body, the attributes, and the featured-image relationship the same way it reads any other content.
myFeed — the assembled Following feed: items from subscribed and owned sources, newest first.forYou — the personalized feed, ranked by the Recommendations subsystem for this reader.recommended(metadataId) — item-context recommendations for a given article, re-ranked for the caller.query MyFeeds { feeds { myFeed(offset: 0, limit: 25) { id name attributes } forYou(offset: 0, limit: 25) { id name attributes } } }
The ranking seam
The boundary is deliberate: ingested items become recommendable through the standard content lifecycle events, and the personalized surfaces delegate to the recommendations service.
forYou and recommended hand ranking to the Recommendations subsystem, then resolve the resulting ids back to content.feeds.items(sourceId) lists a source's ingested items newest-first, gated on the feeds admin group.myFeed → subscribed + owned, newest firstforYou → ranked by Recommendationsrecommended(id) → related, re-rankedPreview readerKeep exploring