# How BidirectionalFollowReplyWeightBoost Amplifies Mutual Follows in X's Home Mixer

> Learn how BidirectionalFollowReplyWeightBoost increases mutual follows on X. Discover how reciprocal follow relationships boost post rankings in the home mixer feed.

- Repository: [SpaceXAI Org/x-algorithm](https://github.com/xai-org/x-algorithm)
- Tags: deep-dive
- Published: 2026-09-10

---

**BidirectionalFollowReplyWeightBoost adds a configurable constant to the reply weight of original posts when the viewer and author maintain a reciprocal follow relationship, directly increasing the candidate's ranking score in the home-mixer feed.**

The home-mixer ranking system in the [xai-org/x-algorithm](https://github.com/xai-org/x-algorithm) repository prioritizes content from mutual connections through specific weight boost mechanisms. By modifying the scoring weights for reply and dwell metrics, the system surfaces original posts from users who share a bidirectional follow relationship with the viewer while explicitly excluding replies and retweets from this amplification.

## Detecting Mutual Follow Relationships

Before any weight boost applies, the system must identify whether the viewer and post author follow each other. The `BidirectionalFollowHydrator` in [`home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs) handles this detection by querying the social graph and populating the `is_mutual_follow_author` field on each `PostCandidate`.

According to the source code, the hydrator checks that the viewer follows the author **and** the author follows the viewer, storing the result as `candidate.is_mutual_follow_author` (lines 57-63). This boolean flag becomes the primary signal for downstream scoring components to apply mutual-follow preferences.

## Eligibility Criteria for Weight Boosting

Not all mutual-follow content receives the boost. The `bidirectional_boost_eligible` helper function in [`home-mixer/scorers/ranking_scorer.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/scorers/ranking_scorer.rs) (lines 44-48) enforces strict eligibility requirements:

- The candidate must have **no** `in_reply_to_tweet_id` (not a reply)
- The candidate must have **no** `retweeted_tweet_id` (not a retweet)  
- The `is_mutual_follow_author` field must be `Some(true)`

This filtering ensures that **BidirectionalFollowReplyWeightBoost** and its companion parameter **BidirectionalFollowDwellWeightBoost** apply exclusively to original posts, preventing amplification of conversational or redistributed content within mutual-follow relationships.

## Applying the Boost to Scoring Weights

Once eligibility is confirmed, the `ScoringWeights` struct modifies the base weights through two dedicated methods in [`home-mixer/scorers/ranking_scorer.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/scorers/ranking_scorer.rs).

**Reply Weight Enhancement**
The `reply_weight_for` method (lines 50-55) increases the base reply weight by adding `self.bidirectional_follow_reply_weight_boost` when the candidate meets the mutual-follow criteria.

**Dwell Weight Enhancement**  
Similarly, `dwell_weight_for` (lines 78-84) adds `self.bidirectional_follow_dwell_weight_boost` to the base dwell weight under the same conditions.

These boosted values feed into `RankingScorer::compute_weighted_score`, where higher reply and dwell contributions directly increase the candidate's `weighted_score` and final ranking position.

## Implementation Examples

### Hydrating Mutual Follow Status

The following example demonstrates how `BidirectionalFollowHydrator` sets the mutual-follow flag that enables downstream boosting:

```rust
use home_mixer::candidate_hydrators::bidirectional_follow_hydrator::BidirectionalFollowHydrator;
use home_mixer::models::{candidate::PostCandidate, query::ScoredPostsQuery};
use std::sync::Arc;

// Mock social graph where author (id 42) follows viewer (id 1)
let hydrator = BidirectionalFollowHydrator {
    socialgraph_client: Arc::new(MockSocialGraph { followers: vec![42] })
};

let query = ScoredPostsQuery {
    user_id: 1,
    user_features: UserFeatures { followed_user_ids: vec![42], ..Default::default() },
    ..Default::default()
};

let candidate = PostCandidate { author_id: 42, ..Default::default() };
let hydrated = hydrator.hydrate(&query, &[candidate]).await;

assert_eq!(hydrated[0].as_ref().unwrap().is_mutual_follow_author, Some(true));

```

*The hydrator populates `is_mutual_follow_author = Some(true)`, marking the candidate for weight boosting.*

### Computing Boosted Weights

This example shows how `ScoringWeights` applies the configured boost value to the reply weight:

```rust
use home_mixer::scorers::ranking_scorer::ScoringWeights;
use home_mixer::params::BidirectionalFollowReplyWeightBoost;

// Feature switches enable a +3.0 boost
let params = FeatureSwitches::new(vec![
    ("rust_home_mixer_bidirectional_follow_reply_weight_boost", "3.0"),
    ("rust_home_mixer_reply_weight", "1.0"),
]).unwrap().match_recipient(&RecipientBuilder::new().build());

let weights = ScoringWeights::from_params(&params);
let base_reply = params.get(ReplyWeight); // 1.0

let boosted = weights.reply_weight_for(&mutual_original_candidate);
assert!((boosted - (base_reply + 3.0)).abs() < 1e-9);

```

*The `reply_weight_for` method adds the configured 3.0 boost to the base 1.0 weight for eligible mutual-follow original posts.*

### End-to-End Scoring Impact

The boosted weights ultimately influence the final ranking through the `RankingScorer`:

```rust
let scorer = RankingScorer { author_cold_start: Default::default() };
let scored = scorer.score(&query, &candidates).await;
let score_with_boost = scored[0].as_ref().unwrap().score.unwrap();

// score_with_boost reflects increased reply and dwell contributions

```

*The final score incorporates the bidirectional follow weight boosts, elevating the candidate's position in the feed.*

## Summary

- **BidirectionalFollowReplyWeightBoost** specifically targets original posts from mutual-follow relationships, excluding replies and retweets.
- The `BidirectionalFollowHydrator` in [`home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs) detects mutual follows by verifying reciprocal following relationships.
- Eligibility logic in [`home-mixer/scorers/ranking_scorer.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/scorers/ranking_scorer.rs) ensures only original content (no `in_reply_to_tweet_id` or `retweeted_tweet_id`) receives the boost.
- The boost adds configurable constants to both reply and dwell weights, directly increasing the candidate's final score in the ranking computation.

## Frequently Asked Questions

### What is BidirectionalFollowReplyWeightBoost?

**BidirectionalFollowReplyWeightBoost** is a configurable ranking parameter in the x-algorithm home-mixer system that adds a constant value to the reply weight of posts when the viewer and author follow each other. This mechanism prioritizes original content from mutual connections by increasing the post's overall weighted score during the ranking phase.

### Does the boost apply to replies and retweets?

No. The boost explicitly applies only to **original posts**. The `bidirectional_boost_eligible` function checks that the candidate has no `in_reply_to_tweet_id` and no `retweeted_tweet_id` before applying either the reply or dwell weight boost. Replies and retweets are filtered out to ensure the amplification targets only standalone content from mutual follows.

### How does the system detect mutual follows?

The system uses the `BidirectionalFollowHydrator` to query the social graph and verify that the viewer follows the author **and** the author follows the viewer. This hydrator sets the `is_mutual_follow_author` field on `PostCandidate` objects, which downstream scorers check before applying any weight boosts.

### Where is the boost logic implemented?

The core boost logic resides in [`home-mixer/scorers/ranking_scorer.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/scorers/ranking_scorer.rs), specifically within the `ScoringWeights` implementation. The `reply_weight_for` and `dwell_weight_for` methods handle the addition of boost values, while the `bidirectional_boost_eligible` helper enforces content type restrictions. The mutual-follow detection occurs in [`home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs`](https://github.com/xai-org/x-algorithm/blob/main/home-mixer/candidate_hydrators/bidirectional_follow_hydrator.rs).