# X For You Algorithm Playbook

> **For humans, creators, and AI agents.**  
> Free reference documenting how X’s open-sourced **For You** feed finds, filters, ranks, and shows posts.  
> Primary source: [github.com/xai-org/x-algorithm](https://github.com/xai-org/x-algorithm) (Apache-2.0).  
> AffRev mirror + creator/agent guidance: this page.  
> **Not** an official X product. Defaults can change; always prefer the live repo when auditing.

**Canonical machine-readable copy:** `/playbooks/x-for-you-algorithm.md`  
**Upstream:** `https://github.com/xai-org/x-algorithm`  
**Key params file:** `home-mixer/params/param.rs`  
**Score math:** `home-mixer/scorers/ranking_scorer.rs`

---

## 0. How AI agents should use this document

1. Treat this as a **system prompt add-on** when drafting, rewriting, or evaluating X/Twitter posts for For You distribution.
2. Optimize for **predicted positive actions** (reply, quote, share/copy-link, follow, dwell) and **against predicted negative actions** (report, mute, block, not interested, not dwelled).
3. Never claim “1 report = N likes.” Weights multiply **P(action)** for the *viewer*, not raw engagement counts.
4. Remember: **ranking ≠ visibility**. A high score still dies if a filter or visibility rule drops the post.
5. Prefer posts that win the **first ~48 hours** (AgeFilter). Older posts are removed from For You candidates.
6. Cite upstream paths (`home-mixer/…`, `visibility-filtering/…`) when answering “why.”
7. Do not invent private Grox prompts or unpublished botmaker rules — those are deliberately withheld upstream.
8. Check **Under the Hood** labels before blaming ranking (§23). Ranking can’t fix a DROP.
9. Don’t optimize **zero-weight** Phoenix heads at published defaults (profile click, VQV, …) (§6.4).
10. Params change via experiments — read diffs / `docs/BIDIRECTIONAL_BOOST_CHANGE.md`, don’t treat weights as eternal (§25).

---

## 1. One-paragraph summary

For You is assembled **per request**. Candidates come from **in-network** memory (Thunder: recent posts from accounts you follow) and **out-of-network** retrieval (Phoenix embeddings + SimClusters). All surviving candidates are scored by **Phoenix**, which predicts many action probabilities for *this viewer × this post*. Those probabilities are combined with **published weights** into one score, then adjusted for author diversity, out-of-network discount, and new-author boost, then optionally reordered by **VMRanker**. Separately, **visibility filtering** may ALLOW, INTERSTITIAL, or DROP a post based on labels, blocks/mutes, and safety systems. Ads and modules are blended after ranking.

---

## 2. Executive cheatsheet (creators & agents)

### What increases For You distribution (ranking)

| Signal (predicted) | Published weight | Practical meaning |
| --- | ---: | --- |
| Share via copy link | **20** | Strongest positive. Make posts people paste into chats/docs. |
| Reply | **5** | Conversation >> likes. Ask, provoke thoughtful replies. |
| Quote | **5** | Quotable takes travel with someone else’s audience. |
| Share via DM | **5** | Private forwards count. |
| Follow author | **4** | Hooks that earn follows compound later (Thunder). |
| Share (generic) | **2** | Still valuable. |
| Repost / retweet | **1** | Helps; weaker than reply/quote/share. |
| Favorite / like | **0.5** | Weakest common positive. Do not optimize only for likes. |
| Post click | **0.4** | Open the post. |
| Open link | **0.2** | Outbound clicks help a bit. |
| Video open | **0.07** | Media people open. |
| Photo expand | **0.05** | Media people expand. |
| Dwell | **0.05** | Attention / read time. |
| Quoted click | **0.05** | Click into quoted post. |
| Continuous dwell time | **0.004** | Small continuous attention term. |

**Mutual-follow boost (default +15 on reply weight):** applies to **original** posts (not replies/reposts) from authors you **mutually** follow — `ReplyWeight` becomes `5 + 15 = 20` for those candidates. Dwell boost param exists but defaults to **0**. See §17.

### What decreases distribution (ranking)

| Signal (predicted) | Published weight | Practical meaning |
| --- | ---: | --- |
| Report | **−234** | Nuclear *on probability*, because reports are rare. |
| Mute author | **−58.8** | Hard suppress. |
| Not interested | **−43.2** | Hard suppress. |
| Block author | **−31.2** | Hard suppress. |
| Not dwelled | **−0.02** | Mild skim-past penalty. |

### Hard gates (not ranking — filters)

- Posts **older than ~48 hours** → removed (`AgeFilter`).
- Viewer **blocks/mutes** author → removed.
- **Muted keywords** → removed.
- Already seen / served → removed.
- Own posts → removed from own For You.
- OON NSFW SimClusters authors → removed for non-followers.
- **Brazil 2026 election filter** → certain reported accounts removed for non-followers (compliance).
- Visibility filtering **DROP** → removed after selection (and can cascade to quotes/replies ancestors).

### Post-score multipliers

- **Author diversity:** later posts from same author × decaying factor (decay **0.5**, floor **0.25**).
- **Out-of-network factor:** OON candidates × **0.75** (topic OON × **0.5**). With `EnableOonRescoreForInNetworkRepliesRetweets=true`, **in-network replies/reposts can also get OON-style rescore** — thread strategy matters (§18).
- **Cold-start / low-impression boost:** authors under impression/follower thresholds can be lifted toward target slots (§19).
- **VMRanker:** DPP over embeddings (`VMRankerDppTheta=0.65`) — trades a bit of score for less near-duplicate neighbors (§20).
- **Zero-weight heads:** Phoenix still predicts some actions (profile click, VQV, …) but **weight 0** → they don’t move score at defaults (§6.4).

---

## 3. Critical misconceptions (read this)

### 3.1 Weights are not “engagement exchange rates”

From upstream comments in `param.rs`:

- Weights scale **predicted probabilities** (or continuous values like watch time).
- They do **not** scale raw like/report counts.
- It is **incorrect** to say “1 report cancels 468 likes” by dividing |−234| / 0.5.

Why report weight is huge: baseline P(report) is often **>1000× lower** than P(like). The large weight exists so a small predicted report probability can still move the final score.

### 3.2 Mass report / block brigades

Upstream notes multiple inhibitors:

1. Personalization: predictions are about *this viewer*. Bad-actor reports mainly hurt recommendations for users **similar to those actors**, not a global “everyone sees less of this” count dump.
2. Only engagements on posts **served in Home Timeline** count for the recommendation system. Coordinated drive-bys from people who navigated directly (e.g. via group chat links) **do not** have the ranking impact people assume.
3. You cannot reliably force a post into timelines just to farm coordinated engagement.

### 3.3 Ranking vs visibility

- **Ranking** orders candidates that survived filters.
- **Visibility filtering** decides ALLOW / INTERSTITIAL / DROP using labels + graph + settings.
- Spam rules for **out-of-network recommendations** can be stricter than for followers: the same post may show to followers but DROP for OON.

---

## 4. Request path (For You pipeline)

High-level stages inside **Home Mixer** (`home-mixer/`), built on `candidate-pipeline/`:

### 4.1 Query hydration

Viewer context loaded first, including roughly:

- Recent engagement action sequence (main Phoenix input)
- Following list
- Blocks and mutes
- Muted keywords
- Posts already seen / served
- Followed topics
- Other request features

### 4.2 Candidate sources (parallel)

| Source | Network | Role |
| --- | --- | --- |
| **Thunder** | In-network | In-memory recent posts from accounts the viewer follows |
| **Phoenix retrieval** | Out-of-network | Embedding similarity: posts near the viewer vector |
| **SimClusters** | Out-of-network | Cluster similarity from who-engages-with-what |

### 4.3 Candidate hydration

Attach post text/media, author details/labels, quoted post, language, engagement counts, subscription status, etc.

### 4.4 Pre-scoring filters

Remove ineligible candidates **before** expensive scoring (see §7).

### 4.5 Scoring

1. **PhoenixScorer** — P(action) for many actions  
2. **RankingScorer** — weighted sum + diversity / OON / new-author adjustments  
3. **VMRanker** — diversity rerank via DPP service (`vm-ranker/`)

### 4.6 Selection

`TopKScoreSelector` — sort by final score, keep top K.

### 4.7 Post-selection filters

Visibility filtering drops, ancillary drops (if parent/quote/repost dropped), conversation dedupe.

### 4.8 Blending pipeline (not Phoenix rank)

After the post pipeline, **`ForYouCandidatePipeline`** blends:

| Module | Typical behavior |
| --- | --- |
| Ranked organic posts | One source among several |
| Ads | `BlenderSelector` interleaves; default ads blender may **reorder posts for ad adjacency** |
| Who to Follow | Often fixed positions |
| Prompts / push-to-home | Often fixed positions |

**Creator implication:** a “weird slot” or gap next to an ad is often **blending**, not a Phoenix score mystery. Organic score still matters for which posts enter the organic slate before blending.

### 4.9 Side effects

Record served posts, refresh caches, log events — after response. Seen/served stores feed **PreviouslySeen / PreviouslyServed** filters on later requests (§26).

---

## 5. Labeling path (offline / continuous)

Runs continuously, not only on the request path:

### 5.1 Content understanding

| Component | Role |
| --- | --- |
| `grox/` | Publish-time classifiers (spam, adult, violent, …) + numeric text/image reps |
| `media-model-proxy/` | Image/video models: adult, violence/gore, hateful symbols, subject, known-media match |
| `clip/` | Image/text embeddings feeding media classifiers |
| `agatha/` | Account labels from blocks/reports/spam relative to favorites; adult/spam suspension labels |
| `bdsm/` | Sequence model for inauthentic / abusive account behavior |
| `user-cred-v2/` | PageRank over follow + engagement graph → account score |
| `adult-content/` | Adult media classifier training/calibration |
| `pnsfwmedia/` | Adult media using CLIP embeddings + account scores |

### 5.2 Labeling rules

| Component | Role |
| --- | --- |
| `scarecrow/` | Event-time label rules; embeds botmaker |
| `botmaker/` | Rule language, compiler, runtime |
| `botmaker-rules/` | Rules scarecrow loads (**some unpublished** to reduce gaming) |
| `abuse-enforcement-service/` | Acts on account model scores: label, challenge, suspend |
| `safety-label-user-agg/` | Account labels from aggregate post labels |

### 5.3 Visibility filtering answers

For each (post, viewer):

| Decision | Meaning |
| --- | --- |
| **ALLOW** | Show normally |
| **INTERSTITIAL** | Show behind tap-through (e.g. adult/graphic) |
| **DROP** | Do not show |

Rules consider labels, blocks/mutes/follows, protected/suspended/deactivated, subscriber-only, viewer settings/country. Some DROP rules apply **only** to OON recommendations.

---

## 6. Scoring formula (exact conceptual model)

```
FinalScore ≈ Σ_i ( weight_i × P_viewer(action_i | post) )
           then × author_diversity_multiplier
           then × oon_multiplier (when applicable)
           then new-author position boost (when applicable)
           then VMRanker reorder
```

### 6.1 Action families Phoenix predicts

```
Engagement    favorite · reply · repost · quote · share · share via DM · share via copy link
Clicks        post · profile · link · photo expand · video open · quoted post
Attention     video quality view · dwell · dwell time · click dwell time · active seconds
Author        follow author
Negative      not interested · mute author · block author · report · not dwelled
```

### 6.2 Published default weights (`home-mixer/params/param.rs`)

Snapshot of production defaults mirrored in the public repo (verify upstream if auditing):

#### Positive / neutral

| Param | Default |
| --- | ---: |
| ShareViaCopyLinkWeight | 20.0 |
| ReplyWeight | 5.0 |
| QuoteWeight | 5.0 |
| ShareViaDmWeight | 5.0 |
| FollowAuthorWeight | 4.0 |
| ShareWeight | 2.0 |
| RetweetWeight | 1.0 |
| FavoriteWeight | 0.5 |
| ClickWeight | 0.4 |
| OpenLinkWeight | 0.2 |
| VideoOpenWeight | 0.07 |
| PhotoExpandWeight | 0.05 |
| DwellWeight | 0.05 |
| QuotedClickWeight | 0.05 |
| ContDwellTimeWeight | 0.004 |
| PostUnexploredWeight | 0.02 |
| ProfileClickWeight | 0.0 |
| VqvWeight | 0.0 |
| QuotedVqvWeight | 0.0 |
| ContClickDwellTimeWeight | 0.0 |
| ContActiveSecs5mResidualNormWeight | 0.0 |
| BidirectionalFollowReplyWeightBoost | 15.0 |
| BidirectionalFollowDwellWeightBoost | 0.0 |

#### Negative

| Param | Default |
| --- | ---: |
| ReportWeight | −234.0 |
| MuteAuthorWeight | −58.8 |
| NotInterestedWeight | −43.2 |
| BlockAuthorWeight | −31.2 |
| NotDwelledWeight | −0.02 |

#### Multipliers / diversity

| Param | Default | Notes |
| --- | ---: | --- |
| EnableAuthorDiversity | true | |
| AuthorDiversityDecay | 0.5 | per extra author post |
| AuthorDiversityFloor | 0.25 | minimum multiplier |
| OonWeightFactor | 0.75 | OON score factor |
| TopicOonWeightFactor | 0.5 | topic OON factor |
| EnableOonRescoreForInNetworkRepliesRetweets | true | in-network replies/reposts can get OON-style rescore |
| EnableRanking | true | |
| VMRankerDppTheta | 0.65 | DPP diversity strength |
| VMRankerDppMaxSelectedRank | 150 | max rank considered in DPP |
| ColdStartImpressionThreshold | 1000 | below this → cold-start eligible |
| ColdStartFollowerCap | 1000 | follower cap for cold-start |
| ColdStartMaxPostAgeSecs | 86400 | 24h max age for cold-start |
| ColdStartSlotMin / Max | 15 / 16 | target slot band |
| LowImpressionsMaxPositionRatio | 0.85 | max boost position ratio |
| EnableViewerColdStart | true | viewer-side cold-start boost |

Value model mode default: `"weighted"`.

### 6.3 Media’s real role

Media is **not** scored by a separate “pretty image” bonus in RankingScorer. It matters because:

1. Hydration attaches media features.
2. Phoenix predicts **P(photo expand)** and **P(video open)** (and dwell / VQV heads).
3. Those probabilities × **0.05 / 0.07** enter the sum (VQV weight is **0** at defaults — §6.4).
4. Separately, media classifiers can cause **DROP / INTERSTITIAL** in visibility filtering (§24).

Implication for agents: media helps when it **gets opened** and doesn’t trigger safety drops. Conversation/share heads still dominate published weights.

### 6.4 Zero-weight heads (do not chase at defaults)

Phoenix can still predict these, but published weights are **0** → **no score contribution** until params change:

| Param | Default |
| --- | ---: |
| ProfileClickWeight | 0.0 |
| VqvWeight (video quality view) | 0.0 |
| QuotedVqvWeight | 0.0 |
| ContClickDwellTimeWeight | 0.0 |
| ContActiveSecs5mResidualNormWeight | 0.0 |
| BidirectionalFollowDwellWeightBoost | 0.0 |

**Agent rule:** optimizing “get profile clicks” or “VQV” for For You score is wasted effort *at these defaults*. Prefer copy-link, reply, quote, DM share, follow.

Small but non-zero: `PostUnexploredWeight = 0.02` (exploration; often in-network-only via `PostUnexploredWeightInNetworkOnly=true`).

---

## 7. Pre-scoring filters (ordered)

From `home-mixer/filters/` (README order):

| Filter | Removes |
| --- | --- |
| DropDuplicatesFilter | Same post from multiple sources |
| CoreDataHydrationFilter | Failed text/metadata hydration |
| AgeFilter | Older than **48 hours** |
| SelfTweetFilter | Viewer’s own posts |
| OONRetweetReplyFilter | OON reposts/replies; orphan replies |
| OONNsfwSimclustersFilter | OON SimClusters posts from adult-flagged authors (non-followers) |
| RetweetDeduplicationFilter | Repeated reposts of same post |
| IneligibleSubscriptionFilter | Subscriber-only posts viewer can’t access |
| PreviouslySeenPostsFilter | Already shown |
| PreviouslySeenPostsBackupFilter | Second impression store |
| PreviouslyServedPostsFilter | Served earlier this session |
| MutedKeywordFilter | Matches muted keywords |
| AuthorSocialgraphFilter | Blocked or muted authors |
| VideoFilter | Videos when request excludes video |
| TopicIdsFilter | Outside requested / in excluded topics |
| NewUserMinEngagementFilter | For new users: weak OON posts |
| InventoryHoldoutFilter | Deterministic holdout % (param-gated; defaults often off / 0%) |
| Brazil2026ElectionFilter | Compliance: posts from accounts on Brazil’s Electoral Court report list removed **unless the viewer follows** them (`home-mixer/filters/brazil_2026_election_filter.rs`) |

Note: Thunder also excludes already-seen when queried; other sources rely on filters. Geo/law filters prove **rank can be overridden by policy** without changing Phoenix weights.

---

## 8. Post-selection filters

| Filter | Removes |
| --- | --- |
| VFFilter | visibility-filtering answered DROP |
| AncillaryVFFilter | Parent / quoted / reposted ancestor was dropped |
| DedupConversationFilter | Extra branches of same conversation |

Visibility rule evaluation (`visibility-filtering/rules/registry.rs`):

- **Safety levels:** `TimelineHome` (followers / home shared rules) vs `TimelineHomeRecommendations` (shared rules **+** OON-only drops).
- First **DROP** short-circuits later rules.
- **INTERSTITIAL** does not short-circuit the same way; a later DROP can still win.
- DROPs are ordered before interstitials in the wired home policy.
- Extra **recommendation-only** rules are DROPs only (high-recall spam/NSFW amplify blocks for non-followers).

See §22 for the public rule name walkthrough creators/agents should use.

---

## 9. Component map (encyclopedia)

### Home mixer & framework

| Path | Role |
| --- | --- |
| `home-mixer/` | Builds For You: stages, weights, request-path calls |
| `candidate-pipeline/` | Stage framework: source, hydrator, filter, scorer, selector, side effect |

### Candidate sources & index

| Path | Role |
| --- | --- |
| `thunder/` | In-memory recent in-network posts |
| `phoenix/` retrieval | Viewer/post embeddings; nearest posts |
| `simclusters/` | Engagement-graph clusters for OON candidates |
| `phoenix-rankall/` | Maintains Phoenix retrieval index |
| `phoenix-rankall-strato/` | Event layer; consults visibility before index membership |

### Ranking

| Path | Role |
| --- | --- |
| `phoenix/` ranking | Train/serve multi-action predictor (JAX + Rust serve) |
| `vm-ranker/` | DPP diversity rerank service |

### Safety / labels / visibility

See §5 tables (`grox`, `media-model-proxy`, `clip`, `agatha`, `bdsm`, `user-cred-v2`, `scarecrow`, `botmaker`, `visibility-filtering`, `under-the-hood`, …).

---

## 10. Design decisions (upstream)

1. **Multi-action prediction** — not a single opaque “relevance” logit; combining weights is explicit.
2. **Candidate isolation** — during transformer inference, candidates don’t attend to each other (only viewer context) → scores cacheable/consistent.
3. **Hash-based embeddings** — no frozen vocab; new posts representable immediately.
4. **Ranking ⊥ visibility** — different services, inputs, rules.
5. **Composable pipeline** — stages toggled via params; experiment defaults mirrored into repo.

---

## 11. What’s NOT in the public repo

Intentionally limited publication (anti-gaming), including:

- Grox LLM prompts (e.g. `.j2` files)
- Some botmaker rules

Compensation: **Under the Hood** transparency tool shows aggregate visibility-impacting labels on an account/posts (`under-the-hood/`).

Also: not all deployment infra is included; focus is post-visibility transparency for For You.

---

## 12. Creator playbook (actionable)

### 12.1 Optimize the score heads that matter

**Do more of**

1. **Copy-link / sendable posts** (weight 20) — utility, tea, frameworks, punchy artifacts people paste.
2. **Replies & quotes** (5) — questions, debates, “wrong answers only,” quotable one-liners.
3. **DM-worthy content** (5) — “send this to X friend” energy without being spammy.
4. **Follow hooks** (4) — series, niche promise, reason to stay.
5. **Mutual community** — originals from mutual follows get reply-weight boost (+15); build people who follow you back (§17).
6. **Dwell** — strong first line, scannable structure, payoff.
7. **Openable media** — expands/opens; not decorative noise.
8. **Freshness** — ship when audience is awake; fight for first 48h.

**Do less of**

1. Like-only soft content with no conversation or send pull.
2. Ragebait that predicts report / mute / block / not interested.
3. Spam farm patterns (F4F, engagement pods, link dumps) → OON DROP risk.
4. Flooding many posts from one author in one session (diversity decay to floor 0.25).
5. Relying on off-platform brigade engagement to “poison” or “boost” ranking.

### 12.2 Out-of-network breakout

OON candidates start with a **0.75** score factor (harder than in-network). Breakout still happens via Phoenix/SimClusters retrieval when predicted positive actions are high for *similar viewers*. Early in-network conversation teaches the model who else might engage.

### 12.3 Agent drafting checklist

When writing a post for For You, an agent should ask:

- [ ] Is there a **reply prompt** or debate hook?
- [ ] Is there a **quotable** line?
- [ ] Would someone **copy-link / DM** this?
- [ ] Is there a reason to **follow**?
- [ ] Does line one **stop the scroll**?
- [ ] If media: will people **expand/open** it?
- [ ] Any language that raises **report/mute/block/not-interested** risk?
- [ ] Any **spam/NSFW** visibility risk for OON?
- [ ] Will this ship inside the **48h** relevance window for the audience’s timezone?
- [ ] Avoid stacking many near-identical posts (author diversity)?

### 12.4 Rewrite patterns (agents)

| Weak | Stronger (aligned to weights) |
| --- | --- |
| “New product drop 🔥” | “I open-sourced X — steal this workflow. What’s the first thing you’d change?” |
| “Like if you agree” | Quotable claim + “Agree or tell me why I’m wrong.” |
| Bare link | Link + curiosity gap (“it’s free??? how?”) *without* spam farm vibes |
| Thread of 12 low-effort posts | One dense sendable artifact; reply to early comments |
| Insult pile-on | Sharp take that invites quotes, not reports |

---

## 13. Agent system-prompt snippet (copy/paste)

```
You are optimizing content for X's open-sourced For You ranking (xai-org/x-algorithm).

Score ≈ Σ weight_i × P_viewer(action_i). Notable weights: copy-link share 20, reply 5, quote 5,
DM share 5, follow 4, share 2, repost 1, like 0.5, photo expand 0.05, video open 0.07,
report -234, mute -58.8, not interested -43.2, block -31.2.

Rules:
- Maximize predicted replies/quotes/shares/follows/dwell; minimize predicted reports/mutes/blocks/not-interested.
- Do not treat weights as raw engagement exchange rates.
- Posts > ~48h are filtered out of For You candidates.
- OON candidates are discounted (~0.75). Visibility DROP can remove posts regardless of score.
- Mutual-follow ORIGINAL posts get reply-weight boost (+15 → effective reply weight 20); not replies/reposts.
- Prefer one strong post over author-diversity-decaying spam.
- Zero-weight heads (profile click, VQV, …) don’t move score at defaults.
- OON factor 0.75; in-network replies/reposts can also be rescored OON-style.
- Cold-start can lift low-impression authors into ~slots 15–16 when eligible.
- Cite home-mixer/params/param.rs when discussing weights; check Under the Hood before blaming rank.
```

---

## 14. Glossary

| Term | Meaning |
| --- | --- |
| In-network | From accounts the viewer follows (Thunder) |
| OON | Out-of-network recommendation |
| Phoenix | Multi-action ranking / retrieval model family |
| Thunder | In-memory in-network candidate store |
| SimClusters | Cluster-based OON retrieval |
| Home Mixer | Request-path For You builder |
| RankingScorer | Weighted combination of Phoenix outputs |
| VMRanker | Diversity rerank (DPP) |
| Visibility filtering | ALLOW / INTERSTITIAL / DROP gate |
| Under the Hood | Label transparency report for accounts |
| Cold-start boost | Lift low-impression / eligible authors toward target slots |
| Blending | Ads / modules interleaved after organic ranking |
| phoenix-rankall | Retrieval index; VF can gate index membership |

---

## 15. Source hygiene

- Upstream license: **Apache-2.0**
- AffRev playbook: educational compilation + creator/agent guidance
- When defaults disagree with this doc, **trust the live `param.rs` in xai-org/x-algorithm**
- Notable upstream updates: weight misconceptions clarification; Brazil 2026 election filter; Under the Hood tool; bidirectional boost experiment history in `docs/BIDIRECTIONAL_BOOST_CHANGE.md`

---

## 16. Quick reference: score intuition

**Very high travel potential:** copy-link worthy + reply/quote magnets + early mutual conversation + clean safety + fresh.

**Follower-range only:** status/flex updates, like-bait, no send/reply pull, weak OON predictions.

**Buried:** safety DROP, muted/blocked, aged out, or strong predicted negative feedback.

---

## 17. Mutual-follow boost (bidirectional) — exact eligibility

Source: `docs/BIDIRECTIONAL_BOOST_CHANGE.md`, `ranking_scorer.rs`, `bidirectional_follow_hydrator.rs`.

**What it does:** for eligible candidates, `reply_weight = ReplyWeight + BidirectionalFollowReplyWeightBoost` (defaults `5 + 15 = 20`). Optional dwell boost exists (`BidirectionalFollowDwellWeightBoost`, default **0**).

**Eligible only if all are true:**

1. Author is a **mutual** follow (`is_mutual_follow_author == true`)
2. Post is an **original** (not a reply: `in_reply_to_tweet_id` empty)
3. Post is **not** a retweet (`retweeted_tweet_id` empty)

**Not eligible:** your replies, your retweets, one-way follows, OON strangers.

**History (why defaults move):**

| Date | What happened |
| --- | --- |
| 2026-07-10 | A/B tested boost values 5 / 10 / 15 / 20 (most users at 0) |
| 2026-07-13 | Broad launch toward **20** |
| 2026-07-24 | Set to **15** after results + feedback (e.g. World Cup OON discussion felt thin) |

**Creator / agent takeaway:** invest in **mutual community** and **original** posts that invite replies. Don’t expect the +15 on reply-threads or quote-RT spam.

---

## 18. OON discount nuance (replies & reposts)

Defaults:

- `OonWeightFactor = 0.75` — typical OON score multiplier
- `TopicOonWeightFactor = 0.5` — topic OON harder
- `EnableOonRescoreForInNetworkRepliesRetweets = true` — **in-network replies and retweets can be rescored with OON-style factors**

**Why it matters:** a reply under a viral OON post, or a retweet you push to followers, is **not** automatically treated like a clean original Thunder post. Originals in-network have an easier path than reply/RT inventory.

**Practical:**

- Prefer **original** posts for breakout, then use replies to retain conversation (mutual boost only on originals anyway).
- Don’t assume “I follow them, so their RT of spam is full in-network scored.”
- OON breakout still happens when Phoenix/SimClusters retrieve you and predicted positives overcome the 0.75 factor.

---

## 19. Cold-start / low-impression author boost

After weighted scoring (+ diversity/OON), eligible low-impression authors can be **lifted toward a target position band**.

Published defaults (`param.rs`):

| Param | Default | Meaning |
| --- | ---: | --- |
| ColdStartImpressionThreshold | 1000 | impression threshold for eligibility |
| ColdStartFollowerCap | 1000 | follower cap |
| ColdStartMaxPostAgeSecs | 86400 | post ≤ ~24h |
| ColdStartSlotMin / Max | 15 / 16 | target slot band |
| LowImpressionsMaxPositionRatio | 0.85 | how far boost may pull |
| EnableViewerColdStart | true | viewer-side boost enabled |
| EnableColdStartThompsonSampling | false | optional exploration sampler |
| ColdStartImpressionScale | 1.0 | scale |

**Creator takeaway:** early impressions matter; first-day freshness compounds with AgeFilter (48h) and cold-start (often 24h window). New accounts aren’t helpless, but spam/NSFW DROPs still win.

**Agent takeaway:** for small accounts, write for **early reply/share** in the first hours — boost helps position, Phoenix still needs positive P(action).

---

## 20. VMRanker (DPP diversity)

`VMRanker` calls `vm-ranker/`: a **determinantal point process** over embeddings reorders the scored list, giving up a little score for **less similar neighbors**.

Defaults:

- `VMRankerDppTheta = 0.65`
- `VMRankerDppMaxSelectedRank = 150`

**Why your post “lost” to a lower-score neighbor:** diversity rerank, not only RankingScorer. Near-duplicate posts from you or a cluster get spread/suppressed as neighbors.

**Creator takeaway:** don’t flood near-identical angles in one window (also hits author diversity decay). Vary topic/embedding space.

---

## 21. Blending vs ranking (ads & modules)

Organic Phoenix order is an **input** to blending, not always the final UI order.

- Ads blender may reorder for **ad adjacency**
- Who to Follow / prompts often sit at **fixed positions**
- Side effects record what was **served** (feeds later seen filters)

**Diagnostic:** if analytics show impressions but odd placement, check blending/ads before rewriting the hook for “rank.”

---

## 22. Visibility registry walkthrough (public rule names)

From `visibility-filtering/rules/registry.rs` tests (wired order). Use these names when matching **Under the Hood** labels or debugging DROP.

### Shared home rules (`TimelineHome`) — drops then interstitials

**Author state / graph drops:** SuspendedAuthor, DeactivatedAuthor, ErasedAuthor, OffboardedAuthor, ProtectedAuthorDrop, ViewerBlocksAuthor, ViewerMutesAuthor, MutedRetweets.

**Tweet label / legal / TES drops:** PdnaTweetLabel, BounceTweetLabel, SpamTweetLabel, ForEmergencyUseOnlyDrop, FosnrHatefulConduct / ViolentSpeech / Abuse / CivicIntegrity, NullcastedTweet, DropStaleTweets, DropLegalTakendownPost, DropLocalLawsTakendownPost.

**Sensitive viewer drops:** SensitiveViewerLoggedOut / Underage / NoStatedAge (country-gated NSFW policies exist).

**Exclusive:** DropExclusiveTweetContent.

**Interstitials (tap-through):** NsfwHighPrecisionInterstitial, GoreAndViolenceInterstitial, NsfwCardImageInterstitial, NsfwAuthorInterstitial.

### Extra OON-only drops (`TimelineHomeRecommendations`)

Examples: DropTweetsWithDmcaMedia, DropTweetsWithGeoRestrictedMedia, DropNsfwUser/AdminAuthor, TweetNsfwUser/AdminDrop, NsfwHighRecallDrop, NsfwHighPrecisionOonDrop, GoreAndViolenceOonDrop, NsfwCardImageOonDrop, DoNotAmplifyOonDrop, MaliciousUrlOonDrop, SpamHighRecallDrop, NsfwTextTweetLabelDrop, FosnrAbuseInsultsOonDrop, user-label drops (NsfwHighRecall/Precision, SpamHighRecall, Compromised, ReadOnly, Impersonation…), NsfwAvatar/Banner, AbusiveHighRecall, NsfwNearPerfectAuthor, DoNotAmplifyNonFollower.

**Follower vs OON:** many of these **only** fire for recommendations. Followers may still see content that OON DROPs — “my followers saw it but it didn’t travel” is often **VF OON policy**, not weak copy-link weight.

**Brazil note:** `Brazil2026ElectionFilter` is a **home-mixer pre-score filter**, separate from this VF registry, but same idea: compliance can hard-remove OON distribution.

---

## 23. Under the Hood diagnostic loop

Tool: [https://x.com/i/under_the_hood](https://x.com/i/under_the_hood)  
Code: `under-the-hood/`

**Use when:** reach collapsed, OON died, interstitials appear, or an agent should not “just rewrite the hook.”

**Loop:**

1. Open Under the Hood for the account / period.
2. List visibility-impacting **labels** (automated vs manual).
3. Map label → likely rule family in §22 / `visibility-filtering/` / media / account models (§24).
4. If DROP/interstitial labels dominate → fix **safety/account state**, not Phoenix weights.
5. If clean labels + weak travel → optimize ranking heads (copy-link, reply, quote, …) and freshness.
6. Re-check after changes; labels can lag (batch jobs).

**Agent rule:** never prescribe “post more controversial takes” when Under the Hood shows spam/NSFW/DoNotAmplify-class labels.

---

## 24. Media models & account models (what labels you)

### Media / content understanding

| System | Role | Creator risk if triggered |
| --- | --- | --- |
| `grox/` | Publish-time text/media classifiers (spam, adult, violent, …) + reps | Labels → VF |
| `media-model-proxy/` | Adult, violence/gore, hateful symbols, subject, **known-media match** | INTERSTITIAL / DROP |
| `clip/` | Image/text embeddings feeding media classifiers + retrieval-ish signals | Similarity / NSFW pathways |
| `adult-content/`, `pnsfwmedia/` | Adult media calibration (CLIP + account scores) | Adult gating |

**Creative checklist:** avoid gore/hateful-symbol bait; don’t repost known banned media hashes; NSFW may interstitial for followers and **DROP for OON**.

### Account-level models

| System | Role | Creator risk |
| --- | --- | --- |
| `agatha/` | Blocks/reports/spam relative to favorites; adult/spam suspension labels | Account-wide visibility |
| `bdsm/` | Sequence model: inauthentic / abusive behavior over time | Challenges / labels / limits |
| `user-cred-v2/` | PageRank over follow + engagement graph → account score | Downstream trust / enforcement |
| `abuse-enforcement-service/` | Acts on account model scores: label, challenge, suspend | Hard limits |
| `safety-label-user-agg/` | Aggregate post labels onto the account | Reputation bleed |

**Takeaway:** one toxic post can stain the **account**, which then poisons future OON via user-label DROP rules — even if later posts are clean.

---

## 25. Experiments, params, and reading diffs

- Many tunables live in a config system; cron mirrors **primary production defaults** into `home-mixer/params/param.rs`.
- Notable experiments (≥ ~10% traffic) are intended to appear in the public repo.
- Example narrative + diffs: [`docs/BIDIRECTIONAL_BOOST_CHANGE.md`](https://github.com/xai-org/x-algorithm/blob/main/docs/BIDIRECTIONAL_BOOST_CHANGE.md).

**Agent rule:** when citing weights, say “as of mirrored defaults in `param.rs`” and prefer live file over this playbook if they diverge.

---

## 26. Seen / served stores & inventory holdout

**Why a viewer never saw you (non-ranking):**

| Mechanism | Effect |
| --- | --- |
| PreviouslySeenPostsFilter (+ backup) | Already shown → removed |
| PreviouslyServedPostsFilter | Served earlier in session → removed |
| ThunderSource | Also skips already-seen at source |
| InventoryHoldoutFilter | Deterministic % holdout per post×viewer when enabled |

Holdout params (defaults often **disabled / 0%**):

- `EnableInventoryHoldout` (default false)
- `InventoryHoldoutOriginalsPercent` / `RepliesPercent` / `RetweetsPercent` (default 0)

**Takeaway:** absence of impressions ≠ always “bad score.” Could be seen-before, session dedupe, holdout experiment, VF DROP, or never retrieved.

---

## 27. SimClusters, retrieval index, and VF-before-index

| Piece | Role |
| --- | --- |
| `phoenix/` retrieval | Embed viewer + posts; nearest neighbors |
| `simclusters/` | Clusters from who-engages-with-what; OON candidates |
| `phoenix-rankall/` | Maintains retrieval index as events arrive |
| `phoenix-rankall-strato/` | Event layer chooses which index a post belongs in — **consults visibility filtering first** |

**Critical:** a post can be blocked from **retrieval index membership**, not only dropped after TopK. If VF says the post shouldn’t be amplified, Phoenix retrieval may never surface it to strangers.

**SimClusters creator note:** you get into clusters by **who engages**, not by hashtags alone. Early quality engagement from real communities teaches OON who else might care — engagement pods / brigades are the wrong lesson (§3.2).

---

## 28. Phoenix training surface (for technical agents)

Public `phoenix/` includes training + serving code (JAX + Rust), synthetic data, and [`phoenix/QUICKSTART.md`](https://github.com/xai-org/x-algorithm/blob/main/phoenix/QUICKSTART.md).

What the quickstart proves end-to-end (nano, **not** production quality):

1. Generate synthetic world snapshots + dumps  
2. Train ranking checkpoint  
3. Resume training  
4. Serve ranking  
5. Train two-tower retrieval  
6. `retrieve_then_rank` loop over synthetic sessions  

**Implications for understanding (not for “train your own For You”):**

- Ranking consumes a **viewer action sequence** + candidates (candidate isolation: candidates don’t attend to each other).
- Retrieval is a **separate** two-tower path; index + SID services matter.
- Hash-based embeddings → new posts representable without a frozen vocab.
- Production data, checkpoints, and scale are **not** in the repo.

**Creator myth to kill:** you cannot download Phoenix weights and “predict your virality score” for a draft with production fidelity from this alone. Use published **weights + filters + VF** as the actionable layer.

---

## 29. Expanded agent drafting checklist

Use with §12.3:

- [ ] Original post (not relying on RT/reply inventory for score)?
- [ ] Mutual graph: will mutuals want to **reply** (boost path)?
- [ ] Copy-link / DM / quote hooks present?
- [ ] Not near-duplicate of your last posts (diversity + DPP)?
- [ ] Fresh inside cold-start (~24h) and AgeFilter (~48h)?
- [ ] Zero-weight heads ignored?
- [ ] Media clear of gore / hateful symbols / known banned media?
- [ ] Account Under the Hood clean of spam/NSFW/DoNotAmplify-class labels?
- [ ] Avoid OON-only poison (malicious URLs, high-recall spam patterns)?
- [ ] Geo/compliance: any election/law filters relevant to audience?
- [ ] If diagnosing failure: retrieval/VF/seen/holdout considered before “write harder”?

---

## 30. Failure-mode map (what to fix)

| Symptom | Likely layer | First check |
| --- | --- | --- |
| Followers see it, strangers don’t | VF OON / SimClusters NSFW / index gate | Under the Hood + §22 OON rules |
| Nobody sees it incl. you | Age, self filter, VF DROP, protected/suspended | Account state + VF |
| High likes, weak travel | Optimized likes (0.5) not copy/reply/quote | Rewrite for send/reply |
| Good score feel, odd slots | Blending / ads adjacency | §21 |
| Second post in hour dies | Author diversity decay | Space posts / vary |
| Small account never breaks out | Retrieval + OON 0.75 + cold-start window | Early replies, cluster fit, clean labels |
| Worked yesterday, dead today | Param experiment / new label / seen saturation | Diff `param.rs`, Under the Hood |
| Replies under viral posts flop | OON rescore on replies | Prefer originals (§18) |

---

*Maintained for AffRev free tools so creators and AI agents can reason about For You distribution without paying for closed “algorithm myth” products. Always pair with the upstream repository for audits. Raw markdown: `/playbooks/x-for-you-algorithm.md`.*
