-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrules.json
More file actions
82 lines (82 loc) · 16.5 KB
/
Copy pathrules.json
File metadata and controls
82 lines (82 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{
"meta": {
"source": "https://github.com/xai-org/x-algorithm",
"extracted": "2026-08-14",
"note": "Default weights mirrored from X's feature-switch defaults (synced 2026-08-12). Values are live-tunable server-side and can be overridden per-user by experiments.",
"license": "Apache-2.0 (upstream)"
},
"engagement_weights": [
{"id": "share-via-copy-link", "name": "Copy-link share", "value": 20.0, "explanation": "The single most valuable positive action — 40x a like. Content people copy the link to send elsewhere wins.", "source": "home-mixer/params/param.rs:325-330"},
{"id": "reply", "name": "Reply", "value": 5.0, "explanation": "A reply is worth 10x a like — conversation is king.", "source": "home-mixer/params/param.rs:283"},
{"id": "quote", "name": "Quote post", "value": 5.0, "explanation": "Quotes are rewarded like replies.", "source": "home-mixer/params/param.rs:332"},
{"id": "share-via-dm", "name": "Share via DM", "value": 5.0, "explanation": "Posts people DM to friends are rewarded like replies.", "source": "home-mixer/params/param.rs:319-324"},
{"id": "follow-author", "name": "Follow from post", "value": 4.0, "explanation": "A post that makes someone follow you is worth 8x a like.", "source": "home-mixer/params/param.rs:346-350"},
{"id": "share", "name": "Share (share sheet)", "value": 2.0, "explanation": "Shares count 4x a like.", "source": "home-mixer/params/param.rs:318"},
{"id": "retweet", "name": "Retweet", "value": 1.0, "explanation": "A retweet is worth 2x a like.", "source": "home-mixer/params/param.rs:296"},
{"id": "favorite", "name": "Like", "value": 0.5, "explanation": "Likes barely move the needle relative to everything else.", "source": "home-mixer/params/param.rs:282"},
{"id": "click", "name": "Click into post", "value": 0.4, "explanation": "Detail clicks are worth slightly less than a like.", "source": "home-mixer/params/param.rs:309"},
{"id": "open-link", "name": "Open external link", "value": 0.2, "explanation": "External link clicks are one of the weakest positive signals.", "source": "home-mixer/params/param.rs:310"},
{"id": "photo-expand", "name": "Photo expand", "value": 0.05, "explanation": "Expanding a photo gives a tiny boost.", "source": "home-mixer/params/param.rs:297-302"},
{"id": "video-open", "name": "Video open", "value": 0.05, "explanation": "Opening a video gives a tiny boost.", "source": "home-mixer/params/param.rs:303-308"},
{"id": "vqv", "name": "Quality video view", "value": 0.05, "explanation": "Quality video views count a little, and only on videos longer than 10 seconds.", "source": "home-mixer/params/param.rs:317"},
{"id": "cont-dwell-time", "name": "Dwell time (per second)", "value": 0.004, "explanation": "Each predicted second spent on your post adds value — held attention accumulates.", "source": "home-mixer/params/param.rs:375-380"},
{"id": "profile-click", "name": "Profile click", "value": 0.0, "explanation": "Profile clicks currently contribute nothing.", "source": "home-mixer/params/param.rs:311-316"}
],
"penalties": [
{"id": "report", "name": "Report", "value": -234.0, "explanation": "Catastrophic — a predicted report outweighs ~468 likes. Rage-bait that gets reported dies.", "source": "home-mixer/params/param.rs:442"},
{"id": "mute-author", "name": "Mute author", "value": -58.8, "explanation": "Being mute-worthy is punished almost 2x harder than being block-worthy.", "source": "home-mixer/params/param.rs:436-441"},
{"id": "not-interested", "name": "Not interested", "value": -43.2, "explanation": "A 'Not interested' click costs the equivalent of ~86 likes.", "source": "home-mixer/params/param.rs:424-429"},
{"id": "block-author", "name": "Block author", "value": -31.2, "explanation": "A predicted block wipes out ~62 likes of value.", "source": "home-mixer/params/param.rs:430-435"},
{"id": "not-dwelled", "name": "Scrolled past", "value": -0.02, "explanation": "Posts people scroll straight past take a small deduction.", "source": "home-mixer/params/param.rs:443-448"}
],
"boosts_and_rescoring": [
{"id": "mutual-follow-reply-boost", "name": "Mutual-follow reply boost", "value": "reply weight 5 → 20 for mutuals", "explanation": "Original posts from authors who mutually follow the viewer get 4x the conversation reward — build real mutuals.", "source": "home-mixer/params/param.rs:284-289"},
{"id": "oon-multiplier", "name": "Out-of-network discount", "value": 0.75, "explanation": "Posts shown to non-followers are scored at 75% — going viral outside your audience is an uphill battle by design.", "source": "home-mixer/params/param.rs:246-251"},
{"id": "reply-retweet-discount", "name": "Reply/retweet discount", "value": 0.75, "explanation": "Your replies and retweets are scored at 75% even for your own followers — original posts are structurally favored.", "source": "home-mixer/params/param.rs:260-265"},
{"id": "author-diversity-decay", "name": "Author diversity decay", "value": "(1-0.25)*0.5^k + 0.25", "explanation": "Your 2nd post in one feed load is worth ~62%, 3rd ~44%, floored at 25% — flooding the timeline doesn't stack.", "source": "home-mixer/params/param.rs:228-239"},
{"id": "cold-start-boost", "name": "Small-account discovery boost", "value": "1 post/feed lifted to slot ~15-16", "explanation": "One post per feed load from an author with ≤1,000 followers and <1,000 views (<24h old) gets guaranteed mid-feed placement.", "source": "home-mixer/scorers/author_cold_start.rs:86-191"},
{"id": "negative-squash", "name": "Net-negative squash", "value": "net<0 → score compressed into (0, 0.001)", "explanation": "If penalties outweigh positives, the post ranks below every net-positive post, period.", "source": "home-mixer/scorers/ranking_scorer.rs:525-533"},
{"id": "dpp-diversity", "name": "Feed diversity rerank", "value": "DPP, theta 0.65", "explanation": "Posts too similar to others already picked for the feed get demoted — near-duplicate takes lose.", "source": "vm-ranker/dpp.rs:94-124"}
],
"account_signals": [
{"id": "cred-pagerank", "name": "Credibility = PageRank over follows", "value": "score = clamp(165.2 + 7.07*ln(mass), 0, 100)", "explanation": "Your account credibility comes from who follows you — follows and likes from credible accounts pass credibility to you.", "source": "user-cred-v2/UserCredV2App.scala:195"},
{"id": "cred-premium-floor", "name": "Verified accounts get a credibility floor", "value": "teleport bias, beta 0.5", "explanation": "Premium/verified accounts get built-in baseline credibility that unverified accounts must earn through the graph.", "source": "user-cred-v2/UserCredV2App.scala:173-192"},
{"id": "cred-selective-likes", "name": "Selective likes count more", "value": "normalized by engager's total engagement", "explanation": "A like from a selective account is worth more to your credibility than a like from someone who likes everything.", "source": "user-cred-v2/UserCredV2App.scala:79-99"},
{"id": "grox-engagement-bait", "name": "Engagement-baiting is a policy violation", "value": "SpamEngagementBaiting / SpamEngagementFarming", "explanation": "LLM classifiers explicitly flag engagement-bait and engagement-farming as spam violation types.", "source": "grox/flows/ptos/state.py:11-54"},
{"id": "grox-traction-review", "name": "Going viral triggers AI review", "value": "min-traction streams; high-fav bucket at 128 likes", "explanation": "Posts get LLM safety/quality review once they gain traction — virality invites scrutiny.", "source": "grox/flows/ptos/constants.py:1-25"},
{"id": "grox-slop-score", "name": "AI grades posts for quality and 'slop'", "value": "isHighQuality, slop_score", "explanation": "A model assigns quality and slop scores to notable posts, written back as labels ranking acts on.", "source": "grox/flows/upa/state_initial_banger.py:7-14"},
{"id": "label-standard-penalty", "name": "Standard penalty: hidden from non-followers", "value": "most labels", "explanation": "Most enforcement isn't deletion — labeled accounts' posts stop being recommended to non-followers.", "source": "under-the-hood/strato/lib/underTheHoodLabels.strato:3-190"},
{"id": "nsfw-avatar-label", "name": "NSFW avatar/banner limits the whole account", "value": "NsfwAvatarImage / NsfwBannerImage", "explanation": "An explicit profile picture or banner alone hides ALL your posts from non-followers' recommendations.", "source": "under-the-hood/strato/lib/underTheHoodLabels.strato:138-152"},
{"id": "bot-detection-rhythm", "name": "Bot detection reads your activity rhythm", "value": "transformer over last 512 actions", "explanation": "A transformer reads the literal timing/cadence of your actions — mechanical patterns (follow-churn, like-drips, reply spam) get flagged.", "source": "bdsm/README.md:19-34"}
],
"reach_killers": [
{"id": "shadowban-mechanics", "name": "Most limits hide you from non-followers only", "value": "TimelineHomeRecommendations drop rules", "explanation": "Spam/NSFW/do-not-amplify labels usually don't hide posts from your followers — they silently remove you from strangers' For You feeds. That's why reach 'mysteriously' dies while followers still engage.", "source": "visibility-filtering/rules/registry.rs:138-170"},
{"id": "unsafe-url-quad", "name": "One unsafe link = 4 labels, retroactively", "value": "SEARCH_BLACKLIST + DO_NOT_AMPLIFY + UNSAFE_URL + MALICIOUS_URL", "explanation": "Linking a flagged URL removes the post from search, recommendations, and amplification — applied retroactively to every old post with that link.", "source": "botmaker-rules/scarecrow/bot/rtf_tweets_on_unsafe_verdict.bot:19-22"},
{"id": "bad-url-spam", "name": "Low-quality links + tagging strangers = spam label", "value": "SPAM_HIGH_RECALL", "explanation": "Linking low-quality domains while @-mentioning non-followers gets the post spam-labeled and dropped from recommendations.", "source": "botmaker-rules/scarecrow/bot/LQ_Tweets_With_LQ_URL_Verdict_At_Mention_To_NonFollower.bot:46"},
{"id": "copypasta", "name": "Duplicate text = copypasta spam", "value": "COPYPASTA_SPAM", "explanation": "Posting the same text many other accounts post gets it labeled copypasta and downranked.", "source": "botmaker-rules/scarecrow/bot/BBQDuplicateTextProd.bot:37-108"},
{"id": "llm-slop", "name": "AI slop gets labeled", "value": "SpamHighRecall 30 days (account-wide)", "explanation": "Accounts that mostly post AI-generated slop get an account-wide 30-day recommendations ban; slop replies get downranked 30 days.", "source": "abuse-enforcement-service/service-lib/rules/enforcement_user.yaml:51-69"},
{"id": "nsfw-account-agg", "name": "3 of last 5 posts NSFW = account flagged 7 days", "value": "NSFW_HIGH_PRECISION account label", "explanation": "Repeated NSFW posts flag your whole account for a week, ending recommendation reach for everything.", "source": "safety-label-user-agg/postToUserLabelRules.strato:360-428"},
{"id": "reply-spam-downrank", "name": "Spammy replies downranked 14 days", "value": "spamScore >= 0.97 → RISKY_HIGH_VIZ_REPLY", "explanation": "Replies the Grok-based spam model flags get buried in conversation threads for two weeks.", "source": "botmaker-rules/scarecrow/bot/GroxTweetProcessor.bot:5-28"},
{"id": "notification-filter", "name": "Extreme spam ratios kill your notifications", "value": "AGATHA_SPAM_TOP_USER, 1 week", "explanation": "Accounts with extreme report-per-like ratios stop generating notifications — their likes/follows/replies notify no one.", "source": "botmaker-rules/scarecrow/bot/ProductionAgatha__FilterOutOrganicNotifications.bot:12-31"},
{"id": "big-account-exemption", "name": "Big/credible accounts are exempt", "value": "cred >= 54 or > 25k followers, gray/gold verified", "explanation": "High-credibility, government, and business-verified accounts are exempt from nearly all automated demotion — they get human review instead.", "source": "botmaker-rules/scarecrow/derived-feature/IsHighPageRankUser.df"},
{"id": "labels-are-temporary", "name": "Most limits expire", "value": "7-day (botmaker) / 30-day (enforcement) TTLs", "explanation": "Most automated labels have expiry timers — reach limits are usually temporary if behavior changes.", "source": "botmaker-rules/scarecrow/bot/NsfwTweetMediaProcessor.bot:5-27"}
],
"discovery": [
{"id": "early-likers-define-community", "name": "Early likers define your post's community", "value": "8-hour half-life fav-based embedding", "explanation": "A post's community identity is built in real time from the interests of whoever likes it, decaying with an 8-hour half-life — a clean niche audience in the first hours gives a strong discovery signal.", "source": "simclusters/simclusters_v2/summingbird/storm/TweetJob.scala:59-85"},
{"id": "min-8-favs", "name": "8 likes to enter the discovery index", "value": "MinFavoriteCount=8", "explanation": "A post needs at least 8 likes before it enters the community-discovery index at all.", "source": "simclusters/simclusters_v2/summingbird/common/Configs.scala:39"},
{"id": "known-for-400-followers", "name": "~400 active followers to join communities", "value": "minActiveFollowers=400, 145K communities, weekly", "explanation": "Creators need roughly 400 active followers before the weekly community-clustering job assigns them to any of the ~145,000 interest communities.", "source": "simclusters/simclusters_v2/scalding/update_known_for/UpdateKnownFor20M145K2020.scala:38-61"},
{"id": "retrieval-trained-on-favs", "name": "Likes teach retrieval to fetch your posts", "value": "positive_actions=[SERVER_TWEET_FAV]", "explanation": "The out-of-network retrieval model trains on likes as its positive signal — likes are weak for ranking but they're what gets you fetched for new audiences.", "source": "phoenix/xrex/configs/xrecsys_two_tower.py:280-292"},
{"id": "retrieval-hard-negatives", "name": "Reports/mutes train retrieval to avoid you", "value": "hard negatives: report, block, mute, not-interested", "explanation": "Negative feedback doesn't just sink one post — it trains the retrieval model to stop fetching content like yours.", "source": "phoenix/xrex/models/recsys_two_tower_model.py:1599-1616"},
{"id": "history-1022", "name": "The model's picture of a user: last ~1000 engagements", "value": "history_seq_len=1022", "explanation": "Ranking is a transformer over each viewer's last ~1000 engaged posts — your post wins by fitting that sequence.", "source": "phoenix/xrex/configs/xrecsys.py:241-242"},
{"id": "per-author-caps", "name": "Per-author caps: 50 originals / 30 replies per 48h", "value": "MAX_ORIGINAL_POSTS_PER_AUTHOR=50", "explanation": "Only your latest ~50 original posts and ~30 replies within the 48h window can even be served in-network — volume beyond that is wasted.", "source": "thunder/config.rs:5-8"},
{"id": "no-follower-quota", "name": "No guaranteed follower quota", "value": "~1200 in-network vs ~1800 OON candidates, one ranker", "explanation": "Followed-account posts and stranger posts compete in one ranker with no quota — following you doesn't guarantee seeing you.", "source": "home-mixer/params/param.rs:4-22"},
{"id": "screenshots-tracked", "name": "Screenshots and translations are tracked actions", "value": "TAKE_SCREENSHOT, TRANSLATE_CLICK in ActionName enum", "explanation": "The model's action vocabulary includes screenshots, translate clicks, and how long people stay on links you share.", "source": "phoenix/crates/serving/xai-recsys-proto/proto/recsys.proto:229"}
],
"filters_and_gates": [
{"id": "age-48h", "name": "48-hour age filter", "value": "172800s", "explanation": "Posts older than 48 hours are dropped from For You entirely.", "source": "home-mixer/params/config.rs:36"},
{"id": "oon-retweet-reply-filter", "name": "OON retweet/reply filter", "value": "drop", "explanation": "Your retweets and replies never reach non-followers' For You feeds — only original posts travel.", "source": "home-mixer/filters/oon_retweet_reply_filter.rs:13-22"},
{"id": "conversation-dedup", "name": "Thread dedup", "value": "top post per thread", "explanation": "Only the highest-scoring post from a thread survives into a feed.", "source": "home-mixer/filters/dedup_conversation_filter.rs"},
{"id": "vqv-10s", "name": "10-second video threshold", "value": "10000ms", "explanation": "Video-view credit only applies to videos longer than 10 seconds.", "source": "home-mixer/params/param.rs:677-682"},
{"id": "top-k", "name": "Top-50 selection", "value": 50, "explanation": "Only the top 50 scored posts move forward; a feed page shows at most 35.", "source": "home-mixer/params/config.rs:17-18"}
]
}