0x00 한

Research / Daily reports

  • Sources read: 2
  • Canon files updated: 3
  • Radar entries: 1
In one lineX reverted the For You default ads blender, which it had changed to slot-spread three days earlier, back to multi-risk. In the same commit, the home ranker training preset turned on an elapsed-time input.

Other changes reviewed today:

  • X's Under the Hood score response now shows only up to three heads that contribute most to the weighted sum, instead of all head probabilities.
  • Alibaba 1688 reported a 3.4% GMV increase after using two teachers to reduce the popularity skew of generative recommendation.

1The default ads blender went back to multi-risk after three days — X

Source xai-org/x-algorithm b220448 — X (xAI), 2026-11-03, code. In the numbering these notes use, this is Gen4+55 (Gen4+N is the number these notes assigned in sequence to commits after the Gen4 release on 2026-08-13).

Background X For You (the recommendation timeline that also mixes in posts from accounts the user does not follow) places ads among organic posts and decides their position by looking at the brand safety grades of the posts above and below each ad. The component that does this is the ads blender, and the 2026-10-31 commit changed the default blender from multi_risk to the newly built slot_spread. At that time, this note pointed out that it was raised to the default within two days without an experiment. This commit reverts the default blender to multi_risk and turns on an elapsed-time input in the training preset of the Phoenix (X's Grok-based ranking model) home ranker.

What we learnedA. The default ads blender is multi_risk again

  • The default of the switch that selects the ads blender went back from slot_spread to multi_risk verified — home-mixer/params/param.rs:937-942.

    • The switch name is AdsBlenderType (rust_home_mixer_ads_blender).
    • The slot_spread blender code remains, so it can be selected again through the switch value.
    param!(
        AdsBlenderType,
        String,
        "rust_home_mixer_ads_blender",
        "multi_risk"
    );
    
  • multi_risk places no ads next to HighRisk posts, and next to MediumRisk posts it places only ads whose advertiser allows sensitive contexts (BSR-high) verified — x.md Ads section.

    • slot_spread kept the same safety conditions; the difference was whether ad slots were first fixed evenly across the whole page.
  • The reason for the revert after three days is not in the public code inferred. The basis is that this file mirrors the defaults of the internal feature switches (settings that turn features on and off without a code deployment) and contains no experiment results.

    • The mirror sync time changed from 2026-10-30T22:59:56Z to 2026-11-02T16:00:39Z.

What we learnedB. The H100 home ranker training preset turned on an elapsed-time input

  • The home ranker training preset for H100 GPUs turned on "how far a history item precedes the request" and "how far after the last history item the candidate falls" as inputs verified — phoenix/xrex/configs/xrecsys.py:479-512.

    • The preset name is home_direct_packed, and the options it turns on are enable_time_gap=True and time_gap_lr_scale=4.0.
    • The global default of FeaturePrepConfig is enable_time_gap=False — recsys_feature_prep.py.
  • The gap is split into buckets with boundaries that start at 1 minute and double at each step, and a learned embedding for each bucket is added to the history and candidate tokens verified — recsys_feature_prep.py:73-78.

    • There are 19 buckets, and bucket 0 is for the case where the time is unknown. The last boundary is 60×2^16 seconds, about 45 days.
    • The embedding is initialized to 0 and given a 4× learning rate. The history-side name is hist_time_gap_emb and the candidate-side name is cand_time_since_history_emb (same file, lines 1026-1039, 1083-1098).
    def _compute_time_gap_bucket(request_ts, impr_ts):
        gap = request_ts - impr_ts
        edges = jnp.asarray([60 * 2**k for k in range(TIME_GAP_CARDINALITY - 2)], dtype=gap.dtype)
        bucket = 1 + jnp.searchsorted(edges, gap, side="right", method="compare_all")
        known = (request_ts > 0) & (impr_ts > 0) & (gap >= 0)
        return jnp.where(known, bucket, 0).astype(jnp.int32)
    
  • The serving-side input buffer also fills in the request time and the most recent history time verified — xai-recsys/src/util.rs:409-446.

    • The request time is set to the earliest of the candidates' impression times.
    • The training data loader computes the two values with the same rule — recsys_batch.py.
    • The build script turns this code on only when the feature definition has both fields, and stops the build if only one is present — build.rs:166-186.
  • This is a different path from the time input in the 2026-10-30 commit (wallclock_recency, off by default) verified. That one could not be turned on together with the existing feature preparation path, and this input went inside that feature preparation path.

  • The same preset lowered the training loss weight of three heads, dwell, not-dwelled, and video quality view (VQV), to 0.5 verified — recsys_model.py:5004-5010.

    • The target actions are CLIENT_TWEET_RECAP_DWELLED, CLIENT_TWEET_RECAP_NOT_DWELLED, and CLIENT_TWEET_VIDEO_QUALITY_VIEW — constants.py:553-557.
    • The global default of the option view_loss_weight is 1.0.
  • Whether this preset is used as is for production home ranker training cannot be determined from the code inferred. The basis is that the repo has several hardware-specific training presets, and the code does not disclose which of them is used for production training.

What we learnedC. The Under the Hood score response shows only the heads with large contributions

  • The Under the Hood score response of home-mixer (the service that receives For You requests and coordinates everything from candidate collection to placement) carries the top contributing heads instead of all head probabilities verified — home-mixer/util/under_the_hood.rs.

    • Under the Hood is the transparency path X built to show the basis for ranking and impression verdicts, and EnableUnderTheHood, which turns on this score response, has been off by default since the 2026-10-06 commit.
    • A head is the prediction probability Phoenix produces for each action, and the final score is a weighted sum that multiplies the head probabilities by weights and adds them.
  • The contribution is "head probability × weight"; up to 3 are chosen in descending order of absolute value, stopping if one falls below 10% of the sum of all absolute values verified — vm-ranker/scoring/value_model.rs:220-240.

    • VMRanker (the X ranking service that computes the weighted sum and the DPP diversity reordering) computes it and puts it in the response. A function weighted_terms, which returns the weighted sum split into 29 terms, was added to the shared crate xai-value-model.
    const TOP_HEADS: usize = 3;
    const MIN_HEAD_SHARE: f64 = 0.10;
    
  • Under the Hood requests apply debias (a correction that readjusts head probabilities by each viewer's baseline tendency) and recompute the score even when a cached post exists verified — home-mixer/scorers/vm_ranker_request.rs:19-20.

    • As before, regular requests do not send the debias input when a cached post exists.

What we learnedOther changes

  • A switch that excludes MediumRisk posts from the candidates of the video carousel (a module in For You for swiping through several videos horizontally) was introduced, off by default verified — home-mixer/filters/video_carousel_filter.rs:26-41.
  • Ad impression logs always carry line item, campaign, and ad objective fields verified — home-mixer/ads/drops.rs.
  • The learning rate multipliers of the H100 preset (0.25 each for the Transformer matrices, output heads, and hidden projections) and the embedding optimizer settings changed verified — xrecsys.py:495-506.
  • A long-dwell aggregation that filters out duplicate attribution was added to the user action aggregation types verified — recsys.proto.
  • VF (the visibility-filtering service that decides post impressions) records deleted posts separately from 'not found', but the verdict is the same as before verified — visibility-filtering/models/verdict.rs.
  • The SID (Semantic ID, which represents an item as a short sequence of semantic tokens) lookup cache can now be split into several pieces verified — sid_client.rs.

"// mirrored from config feature-switch defaults; last sync 2026-11-02T16:00:39Z" — home-mixer/params/param.rs:1, 2026-11-03 (code)

Canon update services/x.md In the blender bullet under ## Re-ranking, diversity, and filters, changed the default to multi_risk and updated the reference commit, and added a MediumRisk switch bullet below the carousel filter bullet. Rewrote the default blender sentence in the ## Ads intro and added 2026-11-03 to the default blender line of the section change log. Added a top-contributing-heads response bullet to the Under the Hood section, and an elapsed-time input sentence and paragraph to the intro of the ranker input features section. Raised the reference commit in ## Summary and ## Sources to b220448 and added one row to the change log summary table. In the brand safety bullet of topics/llm-in-recsys.md, corrected the default blender claim.

Why it matters ⚠ Claim changed: the 2026-11-01 claim "X's default ads blender is slot-spread" no longer holds as of the 2026-11-03 commit. slot-spread was the default for only three days, and the reason for the revert is not public verified. Because the elapsed-time input is on in only one training preset, we do not assume that the production ranker already uses this input inferred.

Radar

  • Alibaba 1688 HERO reduced the popularity skew of generative recommendation with two dedicated teachers, one for popular and one for unpopular items, and reported GMV (gross merchandise value) +3.412% in a 15-day A/B test on the 1688 home recommendation surface. Added as additional evidence to the radar.md "generative retrieval / semantic ID" thread — arXiv 2611.03272.
    • The key point is the diagnosis that on-policy distillation (training in which the student learns the teacher's token distribution on outputs the student generated itself) amplifies the skew toward popular items.
  • Triaged 30 arXiv cs.IR papers. Kuaishou's agentic recommendation for local-service ads (EvoRec) and Microsoft's search experiment metric (SSR) have A/B statements but are far from feed mechanisms, so they were not included.

What to check next