The project's README from github.com/xai-org/x-algorithm. As one markdown file: README.md.
This repository contains the core code that determines which posts a viewer sees in the For You feed on X. It combines in-network content (from accounts the viewer follows) with out-of-network content (discovered through ML-based retrieval and other mechanisms), filters content based on a variety of inputs, and ranks posts using a transformer model.
Notable updates:
Brazil2026ElectionFilter, which removes posts from accounts reported to Brazil's Electoral Court for the 2026 election, unless the viewer explicitly follows the account. (Account list updated August 27, 2026.) A benefit of open-source is that you can see that changes like this exist, and exactly how they work — take a look at the code.This release:
Among new systems included are:
visibility-filtering/ determines whether to show a post, drop it, or show it behind an interstitial.botmaker/, botmaker-rules/, scarecrow/), models that score accounts on various dimensions (agatha/, bdsm/, user-cred-v2/), models that examine images and video (media-model-proxy/, clip/), and enforcement (abuse-enforcement-service/).phoenix/ now contains code that trains and runs the model, plus synthetic data generation.simclusters/, an additional source of posts from accounts the viewer does not follow that is called in retrieval alongside Thunder and Phoenix retrieval.This update is also paired with a new Under the Hood transparency tool that allows people to see aggregate statistics about the labels on their account and posts that can limit visibility.
The For You feed is assembled per request. Posts come from two places:
thunder/ keeps recent posts from the accounts a viewer follows in memoryphoenix/ retrieval and simclusters/ find posts from accounts the viewer does not followBoth are ranked together by the same model. Phoenix reads the viewer's recent engagement history and predicts, for each post, how likely the viewer is to take each action on it. Those predictions are combined into one score using weights held in the code — see Scoring and Ranking.
Two pipelines do the work. The Post Pipeline finds, ranks and filters posts. The Blending Pipeline wraps it and adds what the model does not rank: ads, Who to Follow recommendations, prompts.
Ranking sets the order. Whether a post can be shown at all is decided separately, by visibility-filtering/, from the viewer's own actions such as blocks and mutes and from labels that other systems here attach to posts and accounts.
┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ FOR YOU FEED REQUEST │
└──────────────────────────────────────────────────────────────────────────────────────────┘
▼
┌──────────────────────────────── HOME MIXER home-mixer/ ────────────────────────────────┐
│ │
├─────────────────────── POST PIPELINE PhoenixCandidatePipeline ───────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 1. QUERY HYDRATION │ │
│ │ user action sequence — the viewer's recent engagements, and the │ │
│ │ main input to the model · following list · blocks and mutes · muted │ │
│ │ keywords · posts already seen and served · followed topics, etc. │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 2. CANDIDATE SOURCES — queried in parallel │ │
│ │ ┌───────────────────────────────┐ ┌────────────────────────────────────────┐ │ │
│ │ │ IN-NETWORK │ │ OUT-OF-NETWORK │ │ │
│ │ │ Thunder │ │ Phoenix retrieval retrieval model │ │ │
│ │ │ recent posts from the │ │ SimClusters cluster similarity │ │ │
│ │ │ accounts the viewer follows │ │ │ │ │
│ │ └───────────────────────────────┘ └────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 3. CANDIDATE HYDRATION │ │
│ │ post text and media · author details and account labels · quoted post · │ │
│ │ language · engagement counts · subscription status, etc. │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 4. PRE-SCORING FILTERS │ │
│ │ duplicates across sources · older than 48 hours · the viewer's own │ │
│ │ posts · blocked and muted accounts · muted keywords · already seen │ │
│ │ or served · subscriber-only posts the viewer cannot access, etc. │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 5. SCORING │ │
│ │ PhoenixScorer a probability for each action the viewer might take │ │
│ │ RankingScorer weighted sum, then repeated-author decay, an │ │
│ │ out-of-network discount, a new-author boost │ │
│ │ VMRanker calls the reranking service in vm-ranker/ │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 6. SELECTION — TopKScoreSelector │ │
│ │ sort by final score, keep the top K │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ 7. POST-SELECTION FILTERS — after the order is fixed │ │
│ │ VFCandidateHydrator asks visibility-filtering/ per post and viewer │ │
│ │ VFFilter removes the posts it said to drop │ │
│ │ DedupConversationFilter collapses branches of one conversation │ │
│ │ ◄── these labels come from the Labeling Path │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
├───────────────────── BLENDING PIPELINE ForYouCandidatePipeline ──────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ the ranked posts are one source here; the others add non-post items: │ │
│ │ ads · Who to Follow · prompts · push-to-home, etc. │ │
│ │ │ │
│ │ BlenderSelector interleaves them. The default ads blender reorders │ │
│ │ posts for ad adjacency. Who to Follow and prompts go at fixed positions. │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ SIDE EFFECTS — after the response is sent │ │
│ │ record which posts were served · refresh the post cache · log ad │ │
│ │ and client events, etc. │ │
│ └────────────────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────────────────────────────────┐
│ RANKED FOR YOU TIMELINE │
└──────────────────────────────────────────────────────────────────────────────────────────┘
Stages can be switched on and off individually, with defaults in home-mixer/params/param.rs — see Experiments and Configuration for how those defaults relate to what runs in production.
┌─────── 1. CONTENT UNDERSTANDING — happens continuously, not on the request path ───────┐ │ │ │ POSTS AND MEDIA ACCOUNTS │ │ grox/ classifiers for agatha/ blocks and reports │ │ text and media relative to favorites │ │ media-model- image and video bdsm/ inauthentic behavior │ │ proxy/ models user-c