The full operational map of X's For-You feed algorithm. Sourced from xai-org/x-algorithm (May 2026), twitter/the-algorithm (March 2023, parts still in production), twitter/communitynotes, and public analyses.
Confidence markers: 🟢 confirmed by xAI / 🟡 likely (2023 published, 2026 structurally preserved) / 🟠 reasoned from recsys literature
Two stages to survive:
- Banger screen on write — every original post is screened by a Grok classifier the moment it's published. Pass threshold =
quality_score >= 0.4. The classifier also returns an explicitslop_score(AI-slop detector) that influences distribution labels. - For-You ranker on read — the Phoenix transformer scores every candidate per viewer using ~22 action probabilities, then a weighted sum + Author Diversity + OON/VMRanker (with DPP diversity) picks the order.
The 4-rule TLDR:
- TweepCred ≥ 65 — below this, only ~3 of your tweets get distributed at a time.
reply_engaged_by_authoris +75 weight = 150× a like. Reply hand-typed within first hour.- 10+ replies in 15 minutes triggers OON cascade.
reportis −369 weight — single report kills ~700 likes of signal.
POST PUBLISHED → GROX CONTENT UNDERSTANDING (parallel, 9 plans)
│
├─ BangerInitialScreen — quality_score (≥0.4 pass), slop_score, has_minor_score
├─ SafetyPtosCategory (VLM) — 7-category policy detection
├─ SafetyPtosPolicy — per-category policy assignment
├─ PostSafetyScreenDeluxe — second-pass critical-model check
├─ GrokUpaActionWithLabels — applies distribution labels
├─ SpamDetection (replies) — follower-bucketed spam classifier
├─ ReplyRanking — VLM_MINI_CRITICAL scorer, 0.0-3.0
├─ MultimodalPostEmbedderV5 — 1024-dim text+image+transcript embedding
└─ PostEmbeddingWithSummary — text-summarized embedding for context
↓ decorates post with labels + safety + embeddings
FOR-YOU FEED REQUEST (per viewer)
│
├─ QUERY HYDRATION (21 hydrators)
│ blocked/muted users, follow list, mutual-follow MinHash (256+),
│ served history, impression bloom filter, user_action_seq (Dense
│ for retrieval / DenseWithNotInterestedIn for scoring),
│ inferred_grok_topics, followed_starter_packs, user_demographics,
│ inferred_gender, IP, past_request_timestamps
│
├─ CANDIDATE SOURCES (parallel)
│ ThunderSource — in-network (followed accounts)
│ PhoenixSource — OON two-tower retrieval
│ PhoenixMOESource — OON mixture-of-experts (new May 2026)
│ PhoenixTopicsSource — topic-targeted retrieval
│ TweetMixerSource — legacy fallback
│ AdsSource — paid candidates
│ WhoToFollowSource — 3 account recs (WTF module)
│ PromptsSource — system inline/cover prompts
│ PushToHomeSource — pinned-at-top with top-3 reply facepile
│ (SimClusters' 145k communities feed ~85% of OON candidates)
│
├─ CANDIDATE HYDRATION (17 hydrators)
│ CoreData, Author (Gizmoduck), EngagementCounts (5/10-min TTL),
│ HasMedia, VideoDuration, InNetwork, MutualFollowJaccard (256-hash),
│ Quote expansion, Subscription, AdsBrandSafety, BlockedBy,
│ FilteredTopics, FollowingRepliedUsers (≥1k follower viewers only),
│ TweetTypeMetrics bitset, LanguageCode
│
├─ PRE-SCORING FILTERS (14)
│ DropDuplicates, CoreDataHydration, Age (max 80h), SelfTweet,
│ RetweetDedup, IneligibleSubscription, PreviouslySeenPosts (bloom),
│ PreviouslyServedPostsBackup, MutedKeyword (tokenized),
│ AuthorSocialgraph (block/mute, both directions), TopicIds,
│ NewUserTopicIds, Video (opt-out), AncillaryVF
│
├─ SCORING (4 scorers chained)
│ 1. PhoenixScorer — Grok transformer, ~22 P(action)
│ 2. WeightedScorer — Σ weight × P(action) + offset
│ 3. AuthorDiversityScorer — (1−0.25) × 0.5^position + 0.25
│ 4. VMRanker (+ OON) — value model with DPP diversity
│
├─ SELECTION
│ TopKScoreSelector → top-K by final score
│ BlenderSelector → mix posts + ads + WTF + prompts + PTH
│
└─ POST-SELECTION FILTERS
VFFilter (drops on DO_NOT_AMPLIFY + 13 other Medium-Risk labels,
community notes, etc.)
DedupConversationFilter (keeps best score per conversation root)
↓
RANKED FEED RESPONSE
Before your post enters any candidate pool, Grox runs 9 plans in parallel via asyncio.gather. Their outputs decorate the post with labels and embeddings that Home Mixer downstream consumes.
- Filter: excludes replies and protected accounts. Only original public posts.
- Runs
BangerInitialScreenClassifier.classify(post, topics=cached_grok_topics)against a 1-hour-TTL cache of Grok topics. - Uses Grok
VLM_PRIMARYat temperature 0.000001 (effectively deterministic). - Sees BOTH the post (text + media) AND the author. Your author identity is a feature of your own banger screening.
Returns:
quality_score: float # 0.0–1.0, pass threshold = >= 0.4
description: str # Grok's summary
tags: list[str] # extracted tags
taxonomy_categories: list # multi-category scores
tweet_bool_metadata # boolean labels
is_image_editable_by_grok # AI-vs-real-image flag
slop_score: int # AI-slop detector
has_minor_score: float # child-safety detectorKey implications:
- Below 0.4, no distribution-label boost from downstream
GrokUpaActionWithLabels. slop_scoreis an explicit, first-class concern. Generic marketing vocabulary trips it.has_minor_scoreis an independent child-safety detector — avoid ambiguous "kid", "child", "schoolboy" language.
Runs PostSafetyDeluxeClassifier (uses VLM_PRIMARY_CRITICAL) on every eligible original post. Feeds the same GrokUpaActionWithLabels label-application step.
Two-stage:
SafetyPtosCategoryClassifier(VLM-based) flags violation categoriesSafetyPtosPolicyClassifierassigns a specific policy per violation (each category has its own Grok prompt)
The 7 enforced categories: ViolentMedia, AdultContent, Spam, IllegalAndRegulatedBehaviors, HateOrAbuse, ViolentSpeech, SuicideOrSelfHarm.
Deluxe mode uses Grok 4.2 reasoning (EAPI_REASONING) specifically for AdultContent + ViolentMedia. Always injects an AdultContent recheck for posts that didn't otherwise flag.
Note: the VLM examines BOTH text and image. A safe caption with a borderline image still trips the classifier.
Takes the union of BangerScreen + PostSafetyDeluxe outputs (a tweet_bool_metadata blob), sends it to StratoGrokUpaActionWithLabels, gets back a list of distribution-influencing labels.
No appeal mechanism in the pipeline. Labels are applied programmatically based on classifier outputs.
SpamEapiLowFollowerClassifier runs on replies where both immediate-parent AND root author have follower_count ≤ threshold. Bucketed metrics: lte_100, lte_500, lte_1000, gt_1000.
Implication: replying to big-account posts is "free" (skips spam classifier). Replying to small-account posts is heavily scrutinized.
ReplyScorer computes a 0.0–3.0 score for replies on posts whose immediate-parent OR root author exceeds the follower threshold.
Models: VLM_MINI_CRITICAL primary + VLM_PRIMARY_CRITICAL fallback (when JSON output is malformed).
Signals fed into the Grok prompt (via ThreadRenderer with include_signals=True):
is_pasted— copy-pasted reply?user_agentcomposition_sourceapp_attestation_status— proves real device?has_risky_user_safety_label(on the reply author)num_legit_blocks_received_last_24hrs(on the reply author)
Embeds text + images + optional video transcript jointly via RECSYS_EMBED_V5. Output: 1024-dim normalized embedding (truncated from larger).
Text limit: 4096 chars. Multi-image supported. Transcript appended as "\nTranscript: …".
Only embeds original posts from non-protected accounts. Replies get a separate post_embedding_with_summary_for_reply track.
Implication: posts with images and videos get richer embeddings = tighter retrieval matches into the right Phoenix clusters.
Kafka-fed in-memory store keyed per-user. Sub-millisecond reads. Returns recent posts from accounts the viewer follows. Trims posts after a retention window.
User tower encodes the viewer's retrieval_sequence into a query embedding. Candidate tower has all posts pre-embedded. Top-K retrieval by dot-product similarity, K = PhoenixMaxResults.
New users (engagement history shorter than PhoenixRetrievalNewUserHistoryThreshold) get routed to a different model cluster tuned for cold-start.
Same interface as PhoenixSource but uses a Mixture-of-Experts model cluster. Runs in parallel with main PhoenixSource when enabled. Adds an orthogonal retrieval path.
Activated for explicit topic_ids (For-You topic tabs) OR new users with inferred topic interests. Calls retrieval with topic_entity_ids constraints.
The topic universe is enumerated in home-mixer/filters/topic_ids_filter.rs (lines 113-290). 100+ topic IDs covering science, entertainment, business, sports, politics, AI, crypto, gaming, news, music, etc.
The older Tweet Mixer service. Lower-weight contributor in 2026 but still in the candidate pool.
Not in the 2026 release, but still in production from 2023. SimClusters identifies 145,000 communities via sparse non-negative matrix factorization. Produces KnownFor (clusters an author belongs to via co-engagement) and InterestedIn (clusters a viewer engages with).
PhoenixSource pulls from SimClusters' output. You enter a cluster's KnownFor set by being co-engaged-with by accounts already in that cluster.
Source: SimClusters paper (KDD 2020).
Paid candidates, "Who to Follow" module (3 user recs), system prompts (inline / full-cover / half-cover / relevance), and a pinned-to-top push-to-home slot (which includes a top-3 reply facepile from ReplyMixerClient.get_scored_replies()).
After candidates are sourced, 17 hydrators decorate each with features:
| Hydrator | What it adds | Why it matters |
|---|---|---|
CoreDataCandidateHydrator |
Text, media, timestamp | Hard requirement |
GizmoduckHydrator |
Author info (username, verification) | In-network check |
InNetworkCandidateHydrator |
in_network: bool flag |
Drives OON multiplier |
EngagementCountsHydrator |
fav/reply/repost/quote counts, 5-min TTL <30min, 10-min TTL after | Early velocity is what the model sees fresh |
HasMediaHydrator |
Boolean | Photo_expand / vqv eligibility |
VideoDurationCandidateHydrator |
min_video_duration_ms |
Required for vqv weight |
MutualFollowJaccardHydrator |
256-MinHash Jaccard between viewer and author follow sets | Tighter follow-graph overlap = better ranking |
LanguageCodeHydrator |
Language detection | Cross-language demotion |
QuoteHydrator |
Quoted post expansion | Enables quoted_click / quoted_vqv |
SubscriptionHydrator |
subscription_author_id |
IneligibleSubscriptionFilter |
AdsBrandSafetyHydrator(+Vf) |
Brand-safety annotations on ads | Paid only |
BlockedByHydrator |
Author blocks viewer? | Mutual-block surface |
FilteredTopicsHydrator |
filtered_topic_ids + unfiltered_topic_ids |
Topic filtering |
FollowingRepliedUsersHydrator |
Facepile of viewer's follows who replied — viewers with ≥1k followers only | Social proof at the highest-reach surface |
TweetTypeMetricsHydrator |
Bitset of categorical features | The model's "what kind of post is this" feature |
ANY_CANDIDATE,RETWEET,REPLY,SUBSCRIPTION_POST,HAS_ANCESTORS,IN_NETWORK,FULL_SCORING_SUCCEEDED- Author follower bucket:
AUTHOR_FOLLOWERS_0_100,100_1K,1K_10K,10K_100K,100K_1M,1M_PLUS - Video:
VIDEO,VIDEO_LTE_10_SEC,VIDEO_BT_10_60_SEC,VIDEO_GT_60_SEC - Age buckets:
TWEET_AGE_LTE_30_MINUTES,LTE_1_HOUR,LTE_6_HOURS,LTE_12_HOURS,GTE_24_HOURS - Request-state:
EMPTY_REQUEST,NEAR_EMPTY,SERVED_SIZE_LESS_THAN_20,_10,_5
Author-follower cliffs are real categorical feature transitions. Reach scales non-linearly at 100, 1k, 10k, 100k, 1M.
- Cache: 1M entry Moka cache
- 5-minute TTL for tweets < 30min old
- 10-minute TTL for tweets ≥ 30min old
Implication: the first 30 minutes of a post's life determine its trajectory. Engagement that arrives in those 30 minutes is what the Phoenix scorer sees fresh for everyone who pulls a For-You feed during that window.
| Filter | What it drops |
|---|---|
DropDuplicatesFilter |
Duplicate tweet_ids within the candidate set |
CoreDataHydrationFilter |
Posts whose core data hydration failed |
AgeFilter |
Posts older than max_age (capped by MAX_POST_AGE) |
SelfTweetFilter |
The viewer's own posts |
RetweetDeduplicationFilter |
Reposts of an already-present underlying tweet |
IneligibleSubscriptionFilter |
Paywalled posts the viewer isn't subscribed to |
PreviouslySeenPostsFilter |
Posts in seen_ids OR matching impression Bloom filter |
PreviouslyServedPostsBackupFilter |
Backup against re-serving recently-served |
MutedKeywordFilter |
Tokenized match against viewer's muted keywords |
AuthorSocialgraphFilter |
Bidirectional block/mute check |
TopicIdsFilter |
Posts not matching requested topic IDs (with super-topic expansion) |
NewUserTopicIdsFilter |
New users: keeps in-network OR topic-matching posts |
VideoFilter |
When exclude_videos is set |
AncillaryVFFilter |
Drops if upstream flagged drop_ancillary_posts |
Writer leverage notes:
- Bloom filter for previously-seen means once a viewer has scrolled past, the post won't re-surface. Edits don't help. One post = one shot per viewer.
- MutedKeywordFilter is tokenized, not substring. Compound words match the muted root.
- AuthorSocialgraphFilter checks both directions. If a target user has blocked your account, you don't reach them — track block rate.
Takes the viewer's scoring_sequence (engagement history with DenseWithNotInterestedIn aggregation — explicitly includes negative feedback) + candidate batch → returns ~22 action probabilities per candidate.
Candidate isolation: candidates can attend to the user and history, but NOT to each other. Scores are independent and cacheable.
New users (engagement history < PhoenixRankerNewUserHistoryThreshold) get a separate cold-start model cluster.
Production model:
- Mini config (released): 128–256 dim embeddings, 2–4 layers, 4 heads, 1M-each user/item/author vocab, 2 hashes per entity, 19 action outputs.
- Production: wider + deeper (exact dimensions not published).
history_seq_len = 128,candidate_seq_len = 32- Continuous values clamp at 30s (
NormConfig.norm_scale = 30) — dwell time saturates. - 16 product surfaces (For-You, Following, Notifications, Search, etc.). Same post scores differently on different surfaces.
mask_neg_feedback_on_negatives = True— training masks negative feedback on already-negative posts.
Phoenix retrieval (user tower): mean-pools history transformer outputs, then L2-normalizes. Recent engagement spikes pull the user vector strongly toward that cluster.
Phoenix retrieval (candidate tower): 2-layer SiLU MLP. Author embedding is mixed into the candidate embedding — same author posting similar content lands geometrically close.
score = Σ (weight_i × P(action_i)) + offset
The 22 weighted signals (full list with 2023 published weights where available):
Positive-weight (write to maximize):
favorite— +0.5 (2023)reply— +13.5 (2023)retweet— +1.0 (2023)quote— (not disclosed 2023, likely high)quoted_click— (not disclosed 2023)quoted_vqv— (not disclosed 2023)click/good_click— +10 to +11 (2023)good_profile_click— +12.0 (2023)profile_click— likely lower than good_profile_clickvqv— (not disclosed 2023, likely high — video is heavily promoted)share,share_via_dm,share_via_copy_link— (not disclosed 2023)dwell,cont_dwell_time,cont_click_dwell_time— (saturates at 30s)follow_author— (not disclosed 2023, likely high)reply_engaged_by_author— +75.0 (2023) — 150× a like
Negative-weight (write to NOT trigger):
not_interested,block_author,mute_author(individual)negative_feedback_v2— −74.0 (2023) — aggregate of block/mute/not-interestedreport— −369.0 (2023) — 5× more catastrophicnot_dwelled— scroll-past penalty
Offset behavior: Negative-predicted posts aren't fully killed; they're compressed by (combined + negative_sum) / total_sum × NEGATIVE_SCORES_OFFSET. So even a negative-predicted post can surface if nothing else fills the slot.
multiplier(position) = (1 − floor) × decay^position + floor
2023 values (likely-preserved in 2026): floor=0.25, decay=0.5.
| Position | Multiplier |
|---|---|
| 0 (first post from author this feed) | 1.000 |
| 1 | 0.625 |
| 2 | 0.438 |
| 3 | 0.344 |
| ∞ | 0.250 |
Implication: the 5th tweet in a thread runs at ~30% of standalone score in any given feed. One banger > 10-tweet thread.
A separate gRPC-served Value Model Ranker that takes Phoenix scores + raw metadata (in_network, is_retweet, is_reply, author_followers_count, vqv_ineligible flag) + viewer_following_count as input and outputs a final score.
Has an A/B-testable value_model_id — multiple value models can run in parallel.
DPP (Determinantal Point Process) diversity via two params:
dpp_theta(>0 enables — controls diversity strength). 🟠 Typical 0.3–0.7 in academic literature; most production at ~0.5.dpp_max_selected_rank(caps DPP-rerank scope). 🟠 Typical 20–40.
DPP demotes embedding-similar posts even from different authors. Same topic + same angle = DPP-attenuated. Same topic + different angle = DPP-friendly.
OON multiplier: OON candidates' final scores are multiplied by OON_WEIGHT_FACTOR = 0.75 (2023). New users get NEW_USER_OON_WEIGHT_FACTOR (higher). Topic requests use TopicOonWeightFactor. Blue Verified out-of-network: 2× extra (in-network: 4×).
Sorts by final score, takes top TOP_K_CANDIDATES_TO_SELECT.
CachedPostsSource: when a request has has_cached_posts == true (certain infinite-scroll continuations), the pipeline returns the cached posts verbatim and skips all sources, hydrators, filters, and scorers. Posts that scored well in the initial ranking pass get cached and re-surface to follow-on requests in the same session without being re-scored. Practical takeaway: your post's first scoring pass determines its re-surface eligibility for the next stretch of a viewer's session — another reason the first 30 minutes matter.
VFFilter— applies the visibility-filtering engine; drops candidates withAction::Drop(deleted, spam, gore, violence,DO_NOT_AMPLIFY, etc.). Also drops on any otherFilteredReason::*variant.DedupConversationFilter— for posts sharing a conversation root, keeps the highest-scored one and drops the rest.
Writer leverage on DedupConversation: when you reply in a viral thread, only your best-scoring post in that conversation survives into any given viewer's feed. One stellar reply > five mediocre.
- Partitions surviving items into: posts, ads, who-to-follow, prompts, push-to-home.
- Runs an
AdsBlender(defaultpartition_organic, optionalsafe_gap) to interleave ads. - Inserts prompts at the top (
PROMPTS_POSITION). - Inserts Who-to-Follow at
WHO_TO_FOLLOW_POSITION. - Pins push-to-home at position 0 if present.
Ad insertion math:
MIN_POSTS_FOR_ADS = 5— feed needs ≥5 organic posts before any ad insertsMIN_REQUESTED_GAP = 3, default spacing{ requested: 3, min: 2 }- Ads only insert between two
LowRiskposts.MediumRiskposts get excluded from ad-adjacency.
Every served candidate triggers Kafka publishes that feed back into Phoenix's continuous training:
served_candidates_kafka_side_effect.rs— served candidatesclient_events_kafka_side_effect.rs— every click, dwell, etc., with split by post_count / ad_count / wtf_count- Per-bit
tweet_typeevents (each TweetTypeMetricsHydrator bit) - Per-
served_typeevents (for_you_in_network,for_you_phoenix_retrieval,for_you_phoenix_retrieval_moe,for_you_tweet_mixer, etc.) - Query events × size buckets × request contexts (
launch,foreground,pull_to_refresh,get_older,get_newer) phoenix_request_cache_side_effect.rs+redis_post_candidate_cache_side_effect.rs— caching layers
The Phoenix model trains continuously on this stream. Yesterday's engagement shapes today's ranker.
enum BrandSafetyVerdict {
Unspecified = 0, // not yet computed
Safe = 1, // best — full distribution + ad-adjacency
LowRisk = 2, // acceptable — ad-adjacency OK, slight reach reduction
MediumRisk = 3, // suppressed — no ad-adjacency
}NSFW_HIGH_PRECISION,NSFW_HIGH_RECALLNSFA_HIGH_PRECISION,NSFA_KEYWORDS_HIGH_PRECISIONGORE_AND_VIOLENCE_HIGH_PRECISIONNSFW_REPORTED_HEURISTICS,GORE_AND_VIOLENCE_REPORTED_HEURISTICSNSFW_CARD_IMAGE(link preview was flagged)DO_NOT_AMPLIFY— the canonical formal X distribution-suppression labelNSFA_COMMUNITY_NOTE— community notes can hard-suppressPDNA— Photo DNA child-safety hash matchEGREGIOUS_NSFWGROK_NSFA— Grok itself flagged as NSFANSFW_TEXT
NSFA_LIMITED_INVENTORYGROK_NSFA_LIMITEDNSFA_HIGH_RECALL
- Default verdict = MediumRisk if NOT Grok-scored. Posts without
GROK_SFAorGROK_NSFA_LIMITEDlabels are automatically MediumRisk. If your post slips through Grok's classification queue, you're suppressed by default. - Posts newer than
tweet_id 2_054_275_414_225_846_272(late-2024 / early-2025 cutoff) withoutPTOS_REVIEWEDare auto-MediumRisk.
1000-1099: Content
1100-1199: ContentLimited
1200-1399: Safety
1400-1499: Grok
1500-1600: Quote
Rules fire automatically without human review. A single rule hit can attach a safety label that cascades to MediumRisk.
9. TweepCred — the hidden account reputation score 🟢
Not in 2026 open source but widely documented. 0–100 PageRank-adapted score per account.
Threshold 65:
- ≥ 65: ALL your tweets enter the For-You ranker candidate pool
- < 65: Only ~3 of your tweets at a time are eligible for distribution
Inputs:
- Account age (older = higher)
- Follower-to-following ratio (more followers per follow = higher)
- Engagement quality with high-TweepCred accounts (engaging with credible accounts lifts you)
- Device patterns (mobile-native engagement scores better than headless/API)
- Overall engagement quality history
Recalculated periodically (days-to-weeks), not real-time.
If your TweepCred is below 65, no individual post strategy matters much. Fix account reputation first.
twitter/the-algorithm/src/scala/com/twitter/simclusters_v2
- 145,000 communities (topic + social-relationship clusters)
- Sparse non-negative matrix factorization
KnownForassigns each producer (author) to small number of clusters they're known for. Computed from who follows them + co-engagement patterns.InterestedInassigns each consumer (viewer) to clusters they engage with.- Powers ~85% of OON candidate generation that flows into Phoenix retrieval.
You earn KnownFor status in a cluster by being co-engaged-with by accounts already in that cluster.
Fastest path: get retweets / replies from clearly-clustered figures. One retweet from a cluster-central account does more for your KnownFor than 100 retweets from peripheral accounts.
github.com/twitter/communitynotes — separately open-sourced, actively developed.
- Bridging-based matrix factorization algorithm
- Notes surfaced only when users with different latent ideological factors both rate them helpful (cross-ideological consensus)
- Re-runs hourly
- 2026 paper: "Quality-Sensitive Matrix Factorization for Community Notes" — per-rater quality-sensitivity
Once a note attaches: posts receive significantly fewer reposts, likes, replies, and views (research-confirmed). The NSFA_COMMUNITY_NOTE Medium-Risk label kicks in.
Implication: every factual claim must withstand cross-ideological scrutiny. The bridging algorithm specifically catches claims that one side will mark "helpful note" and the other side will agree on.
twitter/the-algorithm/visibilitylib (2023). The 2026 vf_filter.rs calls into xai_visibility_filtering — almost certainly its descendant.
- Centralized rule engine that instructs clients how to alter content display at read time
- Supports: legal compliance, product quality, user trust, revenue protection via hard-filtering, visible product treatments, coarse-grained downranking
- Manifestations: search ban, reply de-boosting (hidden under "show more replies"), recommendation suppression, reach-limiting
The 2023 inverted-index search system. Almost certainly still alive.
Your post text is tokenized and indexed in Earlybird. Hashtag matches, $TICKER matches, named-entity matches surface your post in search — separate from the For-You ranker.
The named-entity density tactic (P-10) lifts you in Earlybird search results, which is its own reach pool independent of the algorithmic feed.
🟢 Confirmed public (in code or 2023/2026 release):
- Pipeline structure (4 scorers, 5 candidate sources, 14 filters, 17 hydrators, 9 Grox plans)
- 7-category PTOS classification
- 14 Medium-Risk + 3 Low-Risk safety labels
- 4-level brand-safety verdict
- Default-to-MediumRisk for non-Grok-scored posts
- Banger threshold (0.4), reply score range (0–3), classifier rate limit (60s/10k posts)
- Engagement count cache TTLs (5/10 min)
- Post age horizon (80h), hourly buckets
- Dwell saturation (30s)
- Author-follower buckets (100/1k/10k/100k/1M)
- Phoenix mini config (128–256 dim, 2–4 layers, 4 heads, 19 actions, 8 continuous)
- Min posts for ads (5), default spacing (every 3rd)
- TweepCred threshold (65)
- 2023 weights: fav 0.5, retweet 1.0, reply 13.5, reply_engaged_by_author 75, profile_click 12, click 10–11, negative_feedback −74, report −369, video_playback50 0.005
🟡 Likely (2023 published, 2026 structurally preserved, exact values may have drifted):
- Author Diversity floor=0.25 / decay=0.5
- OON multiplier 0.75
- Blue Verified 4× in-network / 2× OON
- Viral threshold ~10 replies in 15 min
🟠 Reasoned (from standard recsys literature):
- DPP theta typical 0.3–0.7
- DPP max_selected_rank typical 20–40
- Phoenix production dimensions 4–8× the mini config
❌ Confirmed NOT public:
- 2026 production ranker weights (learned, not configured)
- VMRanker model architecture
- Phoenix production model dimensions
- Grox classifier prompt bodies (BangerMiniVlmScreenScore, ReplyScoringSystem, 7 PTOS prompts, PostSafetyDeluxe, SpamSystemLowFollower)
- TweepCred exact formula and recalculation cadence
- BotMaker rule definitions (only ID range categories are public)
xai-org/x-algorithm— May 2026 Grok-powered For-You rankertwitter/the-algorithm— March 2023 legacy releasetwitter/the-algorithm-ml— 2023 ML training projectstwitter/communitynotes— Birdwatch bridging algorithmigorbrigadir/awesome-twitter-algo— annotated 2023 releasexai-org/grok-1— the transformer Phoenix is ported from- SimClusters paper (KDD 2020)
- Birdwatch paper (2022)
- Quality-Sensitive MF (2026)
- Fast Greedy MAP Inference for DPP (Chen et al. 2017)
- Public analyses: Tanay Jaipuria, Knight Columbia, Sumit's Diary, Sol Messing, helloai substack, Pasquale Pillitteri