feedecoderby @SidneyCur

What raises and lowers your reach on X's For You feed: the tables

The reference tables from the report, on one page. Every value traces to a file in the repository. The calculator and simulation are on the main page.

Version 2026.10.03 · commit b412112 (2026-10-03) · Created by @SidneyCur

Action weights

The weight the ranker multiplies by a predicted probability.

#ActionWeightParameterNote
01Reply5.0ReplyWeightEvery reply action
02Reply on an original post from a mutual follow20.05.0 + 15.0 boostOriginal posts only, not replies or reposts
03Quote5.0QuoteWeight—
04Share via DM5.0ShareViaDmWeight—
05Share via copy link20.0ShareViaCopyLinkWeightLargest non-reply gain
06Share2.0ShareWeight—
07Follow author4.0FollowAuthorWeightPredicted follow after seeing the post
08Repost1.0RetweetWeightIn-network only
09Favorite0.5FavoriteWeight—
10Click0.3ClickWeight—
11Original post (no action)noneno weightPosting itself is not scored

Penalties (malus)

Negative weights. Each one lowers a post's score in proportion to the predicted chance of that action.

#ActionWeightParameterExample
01Not interested−47.52NotInterestedWeightA viewer taps not interested. P = 0.03 → −47.52 × 0.03 = −1.43
02Block−31.2BlockAuthorWeightA viewer blocks you. P = 0.005 → −31.2 × 0.005 = −0.16
03Mute−58.8MuteAuthorWeightA viewer mutes you. P = 0.02 → −58.8 × 0.02 = −1.18
04Report−234ReportWeightA viewer reports you. P = 0.01 → −234 × 0.01 = −2.34
05Not dwelled (scrolled past)−0.02NotDwelledWeightA viewer scrolls past. P = 0.50 → −0.02 × 0.50 = −0.01

Enforcement outcomes

What happens to an account or post after a flag, with an example of what the author sees.

#OutcomeEffectDurationExample
01SpamHighRecall (account)Drops your posts for people who don't follow you30 daysYour account is labelled. Strangers' For You feeds skip your new posts for 30 days. Your followers still see them.Source: enforcement_user.yaml, author_rules.rs
02SpamHighRecall (post)Drops that post as spam30 daysOne reply is labelled as spam and disappears from feeds for 30 days. Your other posts are not affected.Source: enforcement_post.yaml, registry.rs
03RiskyHighVizReply (reply)Applied to a flagged reply30 daysA reply under a popular post is labelled risky. The repo does not trace its visibility effect, so treat it as a warning flag.Source: enforcement_post.yaml
04Liveness check / CAPTCHA / ArkoseChallenge before continuingUntil passedThe account must complete a check before it can post again.Source: enforcement_user.yaml
05Temporary suspensionperm: false, policy PlatformManipulationTemporaryThe account is locked under the platform-manipulation policy. The repo does not set the length.Source: enforcement_user.yaml
06Permanent suspensionCSE and campaign casesPermanentReserved for the most serious cases, such as child-safety reports and campaign abuse. The account does not return.Source: enforcement_user.yaml

Reply-related triggers

Reply behaviours the classifiers and rules flag, with an example of each.

#TriggerWhat is flaggedLabelExample
01Fast reply spamReplies in quick burstsSpamHighRecallA burst of replies in a few minutes, under many different posts. The repo does not publish the speed threshold.Source: enforcement_post.yaml
02LLM-written text (llm_slop_post)Machine-generated lookRiskyHighVizReply + account labelThe same polished, generic line, "Great point, totally agree!", posted under many posts.Source: enforcement_post.yaml, enforcement_user.yaml
03GibberishNonsense textSpamHighRecallA reply like "asdf asdf 🔥🔥" that carries no meaning.Source: enforcement_post.yaml
04Multi-step reply spamPatterns across a threadClassifier flagA chain of replies under one post, each adding a little more promotion. The newest reply in the chain must be flagged for the label to stick.Source: grox/flows/reply_spam/
05Coordinated spamPatterns across accountsClassifier flagA group of accounts that reply to each other's posts within minutes.Source: grox/flows/reply_spam/

Exemptions

Accounts that skip some reply-spam labels or enforcement.

#ExemptionEffectTypeSource
01High PageRank (score ≥ 50)Skips RiskyHighVizReplyPageRanktask_write.py, constants.py
02Grey badgeSkips RiskyHighVizReplyBadgetask_write.py
03Very high follower countSkips some enforcement (threshold in YAML is a mock value)Follower countenforcement_user.yaml

Author diversity multiplier

Applied to your 2nd, 3rd, and later posts in one feed. Decay 0.5, floor 0.25.

#Post positionMultiplierCalculationNote
011st1.000k = 0: 0.75 × 1 + 0.25No penalty
022nd0.625k = 1: 0.75 × 0.5 + 0.25Score is 62.5% of base
033rd0.438k = 2: 0.75 × 0.25 + 0.25—
044th0.344k = 3: 0.75 × 0.125 + 0.25Same as the worked example
055th0.297k = 4: 0.75 × 0.0625 + 0.25—
066th0.273k = 5: 0.75 × 0.03125 + 0.25—
077th and after→ 0.250Floor: decay 0.5, floor 0.25Never reaches zero

Final report: DO

Actions that raise the score. Numbers pair with the DON'T table.

#ActionScoreHow the code uses itExample
01Post original posts to mutual followsGain5 → 20 (boost +15)bidirectional_boost_eligible() needs !is_reply && !is_retweet && is_mutual_follow_author. reply_weight_for adds 15 (xai-value-model/weights.rs).Your original post "Shipping v2 today" reaches a mutual follow with predicted reply P = 0.10. Contribution: 0.10 × 20 = **2.00** (instead of 0.10 × 5 = 0.50).
02Earn copy-link sharesGain20ShareViaCopyLinkWeight = 20.0 (home-mixer/params/param.rs).A viewer copies the link to your post. P = 0.05 → 0.05 × 20 = **+1.00**.
03Earn DM sharesGain5ShareViaDmWeight = 5.0.A viewer sends your thread to a friend by DM. P = 0.04 → **+0.20**.
04Earn quotesGain5QuoteWeight = 5.0.A viewer quote-posts your take with their own comment. P = 0.02 → **+0.10**.
05Earn replies on your postsGain5ReplyWeight = 5.0."Which tool did you use?" invites replies. P = 0.03 → **+0.15**.
06Earn followsGain4.0FollowAuthorWeight = 4.0.After a post that shows expertise and a clear bio, a viewer follows. P = 0.01 → **+0.04**.
07Earn shares (share sheet)Gain2.0ShareWeight = 2.0.A viewer uses the share sheet. P = 0.02 → **+0.04**.
08Earn reposts (in-network)Gain1.0RetweetWeight = 1.0. Only in-network, because out-of-network reposts are filtered.A follower reposts you. P = 0.05 → **+0.05**.
09Earn favoritesGain0.5FavoriteWeight = 0.5.A viewer likes the post. P = 0.10 → **+0.05**.
10Earn clicksGain0.3ClickWeight = 0.3.A viewer taps your link. P = 0.08 → **+0.024**.
11Earn link opensGain0.2OpenLinkWeight = 0.2.A viewer opens the link card. P = 0.05 → **+0.01**.
12Earn video opensGain0.07VideoOpenWeight = 0.07.A viewer taps to open your video. P = 0.10 → **+0.007**.
13Earn photo expandsGain0.05PhotoExpandWeight = 0.05.A viewer expands your image. P = 0.20 → **+0.01**.
14Earn dwell and click-dwell timeGain0.05 dwell · 0.4 click-dwellDwellWeight = 0.05, ContClickDwellTimeWeight = 0.4, ContDwellTimeWeight = 0.004 (multiplied by predicted time).A viewer clicks in and reads. Predicted click-dwell time 2 (model units) × 0.4 = **+0.80**.
15Earn quoted-post clicksGain0.05QuotedClickWeight = 0.05.A viewer clicks the post you quoted. P = 0.10 → **+0.005**.
16Earn in-network posts the viewer hasn't exploredGain0.02PostUnexploredWeight = 0.02, applied only when in_network = true.A follower who has never engaged with your topic sees your post. P = 0.30 → **+0.006**.
17Post original posts for new audiencesNo weightNo fixed weightPhoenix and SimClusters retrieve out-of-network original posts. OONRetweetReplyFilter removes out-of-network replies and reposts.A stranger in France sees your original thread through retrieval. Your reply to someone else's post would be filtered for that stranger.
18Reply to followers and mutualsNo weightNo fixed weightIn-network replies pass OONRetweetReplyFilter. Out-of-network replies don't, unless EnablePhoenixOonReplies is on (default false).Your reply to a follower's post is visible to your followers. Your reply to a stranger's post is dropped for strangers.
19Reply within 48 hours of the postFilterMAX_POST_AGE = 48 × 60 × 60 seconds, enforced by AgeFilter.Reply at 3 hours: eligible. Reply to a post from 3 days ago: removed before scoring.
20Post regularlyNo weightNo fixed weightThunder keeps recent posts from followed accounts in memory (thunder/, README).Four posts a week keeps your last 48 hours of posts ready for your followers' in-network feed.

Final report: DON'T

Actions that lower the score or trigger enforcement. Paired by number with the DO table.

#ActionOutcomeHow the code uses itExample
01Automate or schedule repliesLabelPost label SpamHighRecall, 30 daysenforcement_post.yaml: fast_reply_spam_post → act_add_fast_reply_spam_post_label, TTL 2,592,000,000 ms.A script posts 200 replies in an hour. Flagged replies get the post label, which drops them as spam for 30 days.
02Post LLM-written or templated repliesLabelPost label RiskyHighVizReply, 30 days. Account label SpamHighRecall if flagged llm_slop_userenforcement_post.yaml: llm_slop_post → RiskyHighVizReply. enforcement_user.yaml: llm_slop_user → SpamHighRecall."Great point, totally agree!" under many posts is flagged llm_slop_post, so the reply is labeled RiskyHighVizReply.
03Post gibberish or fillerLabelPost label SpamHighRecall, 30 daysenforcement_post.yaml: gibberish_post → SpamHighRecall.A reply of "asdf asdf 🔥🔥" is flagged gibberish_post and gets the post label.
04Repeat near-identical replies across threadsClassifierClassifier flag (threshold not published)grox/flows/reply_spam/classifier_multi_step_reply_spam.py. It drops flags unless the newest reply is flagged.The same "Totally agree!" posted under 30 threads is flagged by the multi-step classifier.
05Coordinate engagement with groups or swapsClassifierClassifier flag (threshold not published)grox/flows/reply_spam/classifier_coordinated_spam.py and plan_coordinated_spam.py.Ten accounts that reply to each other within minutes match the coordinated-spam pattern.
06Burst many replies in minutesLabelPost label SpamHighRecall, 30 daysenforcement_post.yaml: fast_reply_spam_post (same rule as the automation row).Fifteen replies in two minutes, by hand, can still trigger the fast-reply rule.
07Trigger a blockLoss−31.2BlockAuthorWeight = −31.2 (home-mixer/params/param.rs).A viewer blocks you. P = 0.005 → 0.005 × −31.2 = **−0.16**.
08Trigger a muteLoss−58.8MuteAuthorWeight = −58.8.A viewer mutes you. P = 0.02 → **−1.18**.
09Trigger a reportLoss−234ReportWeight = −234.0.A viewer reports you. P = 0.01 → **−2.34**.
10Trigger "not interested"Loss−47.52NotInterestedWeight = −47.52.A viewer taps not interested. P = 0.03 → **−1.43**.
11Lose dwell time (not dwelled)Loss−0.02NotDwelledWeight = −0.02.A viewer scrolls past in under a second. P = 0.50 → **−0.01**.
12Post spam or malicious linksDropDroppedvisibility-filtering/rules/registry.rs: malicious_url/drop/undesirable and spam_high_recall/drop/undesirable.A link to a flagged domain removes the post from feeds.
13Run multiple or inauthentic accountsDropTemporary suspension (PlatformManipulation)enforcement_user.yaml: act_inauthentic_detection_v45_suspend → act_suspend_user, perm: false.Two accounts that only like and reply to each other trip inauthentic detection and get suspended.
14Keep the same pattern after a reach dropLabelLabels last 30 days regardlessAll label rules use ttl_msec: 2592000000 (30 days).Changing your pattern now doesn't shorten a label that's already set. Wait out the 30 days.
15Expect replies to reach strangersFilterFiltered for out-of-network viewersOONRetweetReplyFilter with EnablePhoenixOonReplies = false.Your reply to a follower's post is removed from a stranger's For You feed.
16Expect reposts to reach strangersFilterFiltered for out-of-network viewersOONRetweetReplyFilter: is_retweet && in_network == false is removed.Your repost of someone you follow is removed from a stranger's feed.
17Count on video viewsNo weightAdds 0 through VQVVqvWeight = 0.0 and QuotedVqvWeight = 0.0.A 40-second video with 10,000 plays adds nothing through VQV.
18Count on profile clicksNo weightAdds 0 directlyProfileClickWeight = 0.0. Only the follow action (4.0) counts.500 profile visits add 0. One follow adds 4.0 × P(follow).
19Post into a viewer's muted keywordsFilterRemoved for that viewerViewerMutedKeywordFilter.A viewer muted "crypto". Your crypto post is removed for that viewer.
20Post a 4th or later item from you in one feedLossScore × 0.344 at 4th, floor × 0.25vm-ranker/params.rs: EnableAuthorDiversity = true, decay 0.5, floor 0.25.Four of your posts rank for one viewer. The 4th is multiplied by 0.344 before the final sort.

Final report: worked examples

Illustrative probabilities, not measured values.

#ScenarioCalculationResultWhat it means
01Largest single gain: boosted reply on your original post20 × P(reply) = 20 × 0.10+2.00The biggest positive single term.
02Large gain: copy-link share20 × P(share) = 20 × 0.05+1.00Copy-link shares are the largest non-reply gain.
03Largest single loss: report−234 × P(report) = −234 × 0.01−2.34The biggest negative single term.
04Break-even report probability2.00 ÷ 234P ≈ 0.85%About one report-likely viewer in 117 cancels one boosted reply.
05Mute vs. favorite−58.8 × 0.02 vs +0.5 × 0.30−1.18 vs +0.15One mute costs about 8 favorites.
06Combined post2.00 (boosted reply) + 0.15 (favorite) + 0.04 (follow) − 1.18 (mute)+1.01Positive and negative terms add up before the final sort.
07Out-of-network penalty2.00 × 0.75 (OonWeightFactor)1.50Out-of-network posts keep 75% of their score.
084th post from you in one feed2.00 × 0.3440.69Multiplier from decay^k, with k = 3.
0910th post from you in one feed0.25 + 0.75 × 0.5^90.2515Approaches the 0.25 floor and never reaches zero.
10New-account out-of-network penalty0.00001 (NewUserOonWeightFactor)Off in repoOnly applies when NewUserAgeThresholdSecs > 0. The repo default is 0.