03 — X Algorithm
Phoenix already scores actions. Pulse multiplies the final score.
xai-org/x-algorithm is the public For You stack: Home Mixer assembles candidates, Phoenix predicts actions, the value model takes a weighted sum. A heartbeat does not replace that model. When the posterior is narrow enough, it multiplies the score that sum already produced.
Source: github.com/xai-org/x-algorithm, Apache 2.0. Weights below are from home-mixer/params/param.rs (sync stamp in the mirrored file: 2026-09-21). They can change. Treat them as a snapshot, not a promise.
Request path
- Query hydration: actions, follows, blocks, mutes, keywords, topics.
- Candidates: in-network from thunder/; out-of-network from Phoenix retrieval and simclusters/.
- Hydration: text, media, author, labels, engagement.
- Pre-scoring filters: duplicates, age (~48h), self, blocks, mutes, seen posts.
- Scoring: Phoenix predicts P(action). The value model (PhoenixScoresRankingScorer) writes the weighted sum, then author diversity, the out-of-network discount, and a new-author boost. VMRanker may replace the final score with a remote rerank and falls back to the local sum if that call fails. The file named RankingScorer was removed upstream.
- Top-K selection, then visibility-filtering (ALLOW / INTERSTITIAL / DROP).
- Blending: ads, Who to Follow, prompts.
The formula
Published weights (snapshot)
| Head | Weight | Role |
|---|---|---|
| Share via copy link | 20 | Largest positive. Farms attack this. |
| Reply | 5 | Conversation. Mutual-follow reply boost +15. |
| Quote | 5 | Public conversation. |
| Share via DM | 5 | Private pass-along. |
| Follow author | 4 | Rare, high-intent. |
| Repost | 1 | Amplification. |
| Share | 2.0 | Generic share. |
| Favorite / like | 0.5 | Cheap positive. |
| Click | 0.4 | Open the post. |
| Open link | 0.2 | Off-platform. |
| Photo expand | 0.05 | Attention. |
| Video open | 0.07 | Attention. |
| Dwell (binary) | 0.05 | Lingered. |
| Continuous dwell | 0.004 | How long. |
| Profile click | 0.0 | Currently zero. |
| VQV | 0.0 | Currently zero. |
| Not interested | −43.2 | Negative head. |
| Block author | −31.2 | Negative head. |
| Mute author | −58.8 | Stronger than block in this snapshot. |
| Report | -234 | Strongest negative. |
| Not dwelled | −0.02 | Soft negative. |
Adjustments after the sum
- Author diversity. Each extra post from the same author is multiplied by a decaying factor (0.5) down to a floor (0.25).
- Out-of-network discount. 0.75 for accounts the viewer does not follow. Replies and reposts from followed accounts can also be treated as OON. New-user OON factor is effectively a gate (1e-5).
- New-author boost. Authors below an impression threshold are lifted toward a target position.
Phoenix, briefly
Transformer retrieval then ranking. Ranking candidates cannot attend to each other, so a post’s score does not depend on who else is in the batch. Production ranking uses a large embedding width and a long viewer history (on the order of a thousand actions). The public repo ships nano twins and synthetic dumps because the real Kafka / multimodal / SID plumbing cannot.
Candidate isolation matters for a heartbeat: liveness can be an author-side or edge-side feature without creating slate-dependent gaming of “who else is in this batch.” Causal q_t is compatible with that isolation. A non-causal P(E) is not.
Labeling, not just ranking
Content understanding runs continuously (grox classifiers, media models, CLIP-style embeddings). Accounts get signals from blocks/reports (agatha), inauthentic-behavior models (bdsm), and a credibility graph (user-cred-v2). Scarecrow / botmaker apply event-driven rules. Some botmaker rules are withheld from the public repo specifically to reduce gaming. Visibility filtering can DROP a post as a recommendation while ALLOWING it to a follower.
Where a heartbeat plugs in
q_t multiplies the final score, after author diversity and the out-of-network discount, on both the value-model scorer and VMRanker. The Phoenix weighted sum is left alone so it can still be audited. If the flag is off, evidence is missing, or σ_L is above 0.18, the multiplier is exactly 1. The lagged field is P(E, [t−W, t)): an action at the scoring instant is not a reaction yet.
Before that evidence is built, reactions from accounts the viewer has blocked or muted are subtracted. That is preference isolation, not a bot label. Upstream already drops those authors from the candidate list. It does not drop them as reactors on someone else’s post. Out-of-network posts from people you simply do not follow stay in the pool. The fork’s current branch and what is still unwired are on the status page.
In the current slice an unlabeled posterior keeps σ_L ≥ 0.22, including a synchronized reaction field and a high counterfactual lift. Those are visible. They do not move rank. Only a declared agent or service is narrow enough (σ = 0.08) for causal q to run. Early posts, with lagged n under 4, use author state alone — and still only after the width gate. The lab uses this gate. Fire a viral event: the split EKG updates, and unlabeled rows stay at q_t = 1.