Skip to content

03 — X Algorithm

Phoenix already scores actions. Pulse reweights evidence.

xai-org/x-algorithm is the public For You stack: Home Mixer assembles candidates, Phoenix predicts actions, RankingScorer takes a weighted sum. A heartbeat does not replace that model. It changes which predicted actions deserve to count — using only information that already exists.

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

  1. Query hydration: actions, follows, blocks, mutes, keywords, topics.
  2. Candidates: in-network from thunder/; out-of-network from Phoenix retrieval and simclusters/.
  3. Hydration: text, media, author, labels, engagement.
  4. Pre-scoring filters: duplicates, age (~48h), self, blocks, mutes, seen posts.
  5. Scoring: Phoenix predicts P(action); RankingScorer applies weights, author diversity decay, out-of-network discount, new-author boost; VMRanker may rerank with a determinantal point process.
  6. Top-K selection, then visibility-filtering (ALLOW / INTERSTITIAL / DROP).
  7. Blending: ads, Who to Follow, prompts.

The formula

score = Σi wi · P̂(actioni)
Weights multiply predicted probabilities, not raw counts.

Published weights (snapshot)

HeadWeightRole
Share via copy link20Largest positive. Farms attack this.
Reply5Conversation. Mutual-follow reply boost +15.
Quote5Public conversation.
Share via DM5Private pass-along.
Follow author4Rare, high-intent.
Repost1Amplification.
Share2.0Generic share.
Favorite / like0.5Cheap positive.
Click0.4Open the post.
Open link0.2Off-platform.
Photo expand0.05Attention.
Video open0.07Attention.
Dwell (binary)0.05Lingered.
Continuous dwell0.004How long.
Profile click0.0Currently zero.
VQV0.0Currently zero.
Not interested−43.2Negative head.
Block author−31.2Negative head.
Mute author−58.8Stronger than block in this snapshot.
Report-234Strongest negative.
Not dwelled−0.02Soft 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

score′ = Σi wi · P̂(actioni) · q(Iedge, Lactor, P(E))
Naive — uses the reaction field before it exists.
q_t = q( I_edge,t , L_actor,t⁻ , P(E, [t−W, t)) )
Streaming. Only H_<t is legal.

Early seconds: almost no event field. Author L and historical edges carry the score, shrunk by σ_L. As reactions arrive, q_t down-weights synchronized, zero-depth, high-coupling mass and up-weights delayed, specific, relational replies. Copy-link and reply already dominate the published positives — those are the heads farms attack. A liveness prior belongs there, not as a public “human %.”

Do not train Phoenix on sludge and then act surprised that sludge looks engaging. Heartbeat is a way to keep the training signal from being the closed loop. Try it in the lab: the miniature ranker uses these weights, then multiplies by causal q when the heartbeat toggle is on. Fire a viral event and compare slates.