starl3xx.fun / algo / 001
Issue № 001 (commit bc8e5f0)
Video opens, dwell, the cold-start budget, quotes and blocks, and the end of the topic-diversity penalty
Every Sunday I diff the open-source X ranking code, xai-org/x-algorithm, against last week’s mirror and write down what actually moved. This is the first issue. It covers everything between the previous mirror at d011592 (24 August) and bc8e5f0, which is four commits, dated 25, 26 and 28 August. X publishes as squashed drops rather than as its real history, so a range is the honest unit here, not a commit.
Everything below is a default in the code, not a claim about production. The repo’s own README says the two can differ. Every number is copied from the diff; where I’m inferring what a change means for posting, I say so.
If you change one thing this week
- Write a first line that stops the scroll. dwell went from
0.0to0.05, and the history the ranking model reads switched to the long-dwell variant, so the thing that decides whether someone stops counts twice over. - On video, chase the tap, not the finish. video open went
0.05to0.07while a completed quality view went to0.0, so watch-time completion is now worth exactly nothing. - Look at who you quote. A quote of someone is dropped for every viewer that person has blocked, which is the first place a third party’s blocks cost you reach.
Everything below is the evidence for those three, plus what else moved.
What moved
1. Video opens count more; finishing a “quality view” counts for nothing. In param.rs, the video-open weight went from 0.05 to 0.07 and the video-quality-view weight went from 0.05 to 0.0. Takeaway get the tap, stop optimizing for watch-time completion
2. Dwell got switched on. In param.rs, DwellWeight went from 0.0 to 0.05, alongside ContDwellTimeWeight, which was already carrying continuous dwell time, and PhoenixAggregationType moved from DENSE_WITH_SHORT_DWELL to DENSE_WITH_LONG_DWELL. Both point the same direction: a post that makes someone stop is worth more than it was a week ago. Takeaway write a first line that earns a pause; dwell now counts twice, as a weight and as history
Worth unpacking that second one, because the name hides it. Phoenix is the ranking model: in X’s own words it “reads the viewer’s recent engagement history and predicts, for each post, how likely the viewer is to take each action on it”. PhoenixAggregationType chooses which shape of that history the model is handed, from a list of variants in recsys.proto. So this is not a weight at all: the sequence of your recent behavior that the model reads now counts long dwells where it used to count short ones. The weight and the history moved the same way in the same commit.
3. The cold-start budget only counts Home-timeline views. In author_cold_start.rs, the impression count that drives the exploration budget for accounts under 1,000 followers now keys off view_count_on_home rather than total views. Views from profile visits, search, quote posts and off-platform embeds no longer consume the 24-hour budget, and no longer count toward it either. The Thompson-sampling top-k for cold-start promotion also narrowed from 5 to 2, so fewer cold-start posts are promoted per slate. Takeaway if you’re under 1k, driving traffic from outside X is now neutral to your exploration budget; what matters is engagement earned in-feed, in the first day
4. Quotes and reposts are dropped for anyone the original author has blocked. A new hydrator, following_blocked_by_hydrator.rs, checks the author of a quoted or reposted post against the viewer’s blocked-by list. If the person you quoted has blocked the viewer, your quote doesn’t reach that viewer. It applies on the Following surface too. This is the first place a third party’s block silently costs your post reach. Takeaway check who you quote
5. The topic-diversity penalty inside a slate is gone. ranking_scorer.rs lost 201 lines, among them the code that computed the semantic-ID diversity signals (sid_k_l1–l3, sid_gap_l1–l3, pool_rank_gap, fatigue) and the code that applied them, and slate diversity reverted to plain per-author counts. Worth being exact about what went: the fields are still declared in candidate.rs and still cross the proto boundary in both directions, but nothing in home-mixer reads them any more. The scoring was switched off; the plumbing was left in. In param.rs, EnableMpnScoring was replaced by MultiplierPreOffset, default false, and the MpnParts struct went with it. What remains is author-diversity decay: each additional post from you in one viewer’s feed build is multiplied by 0.5, down to a floor of 0.25. Takeaway posting repeatedly on one subject is no longer penalized as a topic, only as an author. Spacing posts out still matters; varying the subject within a session buys nothing mechanically
Three smaller things in the same range. viewer_muted_keyword_filter.rs now matches CJK muted keywords as whole tokens (a viewer muting 京都 no longer has 東京都 removed). brazil_2026_election_filter.rs had its list refreshed twice, once on 25 August and again on 28 August, the second time by 3,365 added lines against 5 removed. And candidate.rs gained three new slate-context fields, recon_cos_milli, recon_count_above and recon_gap_above, which nothing reads yet: they are carried to and from the proto and used nowhere, in the same commit that stopped reading the sid_ fields. Takeaway that is a replacement being plumbed in, and it is the thing to watch over the next few weeks
The standing numbers
For anyone new here, the weights that matter most didn’t move this week. From param.rs, each one against a like:
- share via copy link:
20.0, forty times a like - reply between two accounts that follow each other:
5.0plus a+15.0boost, also forty times - reply or quote:
5.0, ten times - like:
0.5, the unit
Nothing older than 48 hours enters the For You feed at all. A reply or a repost from an account a viewer doesn’t follow is dropped outright, so replies earn their weight from your existing followers rather than from new reach. A quote carries the same weight and does travel out of network.
Caveats
These are defaults in open-source code, overridable per experiment at runtime. The ranking model itself (Phoenix) is trained, not rule-based; the weights blend its per-viewer predictions and don’t describe what it learned. Reading weights as tactics is inherently lossy. I’d rather you know that than not.
Sources: README.md, recsys.proto, param.rs, ranking_scorer.rs, author_cold_start.rs, the filters directory, and the repo README’s “Notable Updates” section, all at bc8e5f0.