- Sources read: 1
- Canon files updated: 1
- Radar entries: 0
1The visibility filter drops posts by action value instead of reason — X
Source xai-org/x-algorithm@75d93d9 — public source code, 2026-09-09, 28 files, +801/−252. These notes number X commits after the Gen4 release in sequence, and this commit (2026-09-09, 75d93d9) is Gen4+18.
Background X mirrors the For You pipeline source code to xai-org/x-algorithm about twice a day (since the Gen4 release on 2026-08-13). This commit is mid-sized at 28 files, but it touched five different axes at once.
- The visibility verdict is now decided by the action value, not the reason. visibility-filtering (VF) is the service that decides, post by post, "may this viewer see it?".
- The VF client added an explicit
Actionfield toTweetVisibility, andVFFilterin home-mixer (the service that assembles the For You feed) now decides drop/keep by theActionenum instead ofFilteredReason. - The verdict axis moved from "action derived from the reason" to "the action decides, and the reason is an annotation for logging".
- The VF client added an explicit
- A new ad format made of a header image, body text, and one or two CTA (call-to-action) buttons appeared as a first-class format in the home timeline. It is the sixth variant, and it is not a promoted-tweet format that wraps a tweet.
- A branch that handles ads carrying
header_image_prompt_ad_infoin a separate marshaller was introduced inhome-mixer/util/urt/ad_marshaller.rs.
- A branch that handles ads carrying
- On the content classification side, the first frame of long videos now goes into the LLM prompt separately.
- The media loader of
grox(the Grok-based nearline classifier sub-repo) downloads and resizes a first-frame preview image for videos of 30+ seconds. - This image is placed before the storyboard (an image of uniformly sampled frames tiled in a grid) in the LLM prompt, with the label
[Video Preview Thumbnail].
- The media loader of
- Live broadcast frames became formal verdict targets of two safety pipelines.
BroadcastLoaderwas newly added to grox and extracts frames of live broadcasts (X's live video, the successor to Periscope).- Two safety pipelines, PTOS (policy-based violation category verdict) adult-content leading-frames and the sex/nudity safemodel, accept broadcast frames as a formal payload.
- The multimodal post embedding was dropped from the training input in both registered ranking training configs.
- In the nano training config table of
phoenix/README.md, the documentation of Phoenix (the ranking model of X For You), the line saying the multimodal post embedding is on as v5 inxrecsys_seqpackchanged to "off (home_direct_packedandxrecsys_seqpack)".
- In the nano training config table of
- Incidentally, phoenix NUMA pinning was fixed to exclude isolated CPUs from the sched_setaffinity target, and six feature-gated
quiet-spanslogs incandidate-pipelinewere deleted.
What we learnedA. VF verdicts gained an explicit action value, and the filter uses it to decide what to drop
- The VF verdict axis was refactored from the filtering reason to an explicit action value verified —
visibility-filtering-client/vf_client.rs(+130/−62).- The verdict axis moved from
FilteredReasontoAction. - Files changed together:
visibility-filtering-client/models.rs(+7),home-mixer/filters/vf_filter.rs(+27/−69),home-mixer/candidate_hydrators/vf_candidate_hydrator.rs(+159/−23),home-mixer/candidate_hydrators/vf_following_candidate_hydrator.rs(+6/−11),home-mixer/models/candidate.rs(+1).
- The verdict axis moved from
- The verdict result the client returns is now a tuple of three values verified.
- The deterministic verdict
Action(Allow / Interstitial / Avoid / Downrank / Drop / Tombstone / NotEvaluated) - The annotation
FilteredReasonfor logging and downstream use - The label lookup result
SafetyLabelMap
TweetVisibilitynow has anaction: Actionfield as a formal member, in addition to the existingreason: Option<FilteredReason>andsafety_labels.- A new helper,
TweetVisibility::to_visibility_reason(), combines the action and the reason to derive the value of thevisibility_reasonfield.
- The deterministic verdict
- On the Strato path (Strato is the X internal system that code goes through to look up or store data), the client computes the action from the reason it receives from Strato verified. There are three rules.
Strato is defined in the services/x.md glossary.
StratoVfClient::get_resultcomputes the action from theFilteredReasonreceived from Strato viaaction_from_strato_reason.fn action_from_strato_reason(reason: &Option<FilteredReason>) -> Action { match reason { None => Action::Allow, Some(FilteredReason::SafetyResult(safety_result)) => match safety_result.action { Action::NotEvaluated => Action::Allow, _ => safety_result.action.clone(), }, Some(_) => Action::Drop(DropReason {}), } }If the reason Strato gave is
SafetyResult, the action inside it is used as is, and every other non-SafetyResult reason (mute, block, null-cast, exclusive, etc.) becomesDropunconditionally.If Strato returns
NotEvaluated, the client layer promotes it toAllow. This means Strato treats a verdict that was not run as fail-open.
- On the gRPC path, the action in the response is used as is verified. On the new gRPC path, the standard is for the server to decide the action and send it down.
result_to_visibilitymapsresult.actionof the gRPC response directly toAction.- If there is no
actionfield, it becomesAction::NotEvaluated.
- The filter layer now decides what to drop by the candidate's action value verified. Allow, Interstitial, Avoid, and Downrank are kept; Drop, Tombstone, and NotEvaluated are filtered out.
VFFilter::filteris now a function of candidate.visibility_action. The verdict function is the following:pub(crate) fn should_drop_action(action: &Action) -> bool { match action { Action::Allow | Action::Interstitial | Action::Avoid | Action::Downrank => false, Action::Drop(_) | Action::Tombstone | Action::NotEvaluated => true, } }The previous version matched
FilteredReasonvariants. ForSafetyResultit filtered only whenaction == Drop, and every other non-SafetyResult reason (mute, block, null-cast, exclusive, etc.) was an unconditional drop.The new version is far more readable because the verdict axis is explicit.
- Filtering of ancestor, quoted, and retweeted source posts also looks at the action value verified.
should_drop_ancillaryinvf_candidate_hydrator.rslooks atvisibility.actionof ancestor, quoted, and retweeted posts to decide whether to drop.- The previous
should_drop_reason(reason: &FilteredReason)was removed, and the filter layer'sshould_drop_actionis shared.
- An action field was added to the candidate object verified.
PostCandidateincandidate.rsnow hasvisibility_action: Option<Action>, and the existingvisibility_reason: Option<FilteredReason>is kept.- The two hydrator update functions (
VFCandidateHydrator::updateandVFFollowingCandidateHydrator::update) fill this field as well.
- A new reason name for the case where the viewer blocks the author was introduced verified.
- The new
FilteredReasonvariant isFilteredReason::ViewerBlocksAuthor. Previously onlyAuthorBlockViewer(the author blocks the viewer) existed. Now the symmetric direction, "the viewer blocks the author", also has a formal reason name. vf_pb::FilteredReason::ViewerBlocksAuthorand the proto to/from mappings were also added.
- The new
⚠ Claim changed (the "fail-closed" statement at services/x.md line 392): the fail-closed character is kept, but the verdict granularity is much clearer.
- The previous canon said "
VFFilteris fail-closed. EveryFilteredReasonvariant other thanSafetyResultis an unconditional drop". - The new verdict function has completely different syntax, but the results are mostly identical. On the Strato path, non-SafetyResult reasons are already converted to
Dropat the client layer, andNotEvaluatedis also dropped. - The previous filter also dropped a verdict that arrived as
SafetyResultonly when the action wasDropverified —vf_filter.rs:22-30. It kept Allow, Interstitial, Avoid, Downrank, Tombstone, and NotEvaluated. - What changed is that the filter layer now drops
TombstoneandNotEvaluatedverified —vf_filter.rs:16-21, quoted below.
"match action { Action::Allow | Action::Interstitial | Action::Avoid | Action::Downrank => false, Action::Drop(_) | Action::Tombstone | Action::NotEvaluated => true, }" — home-mixer/filters/vf_filter.rs:16-21, 2026-09-09
Why it matters (A) This refactor narrows the verdict to a unified action value at the client layer so that only the action flows downstream.
- The type of the unified action value is the
Actionenum. - Since the Gen4 release (2026-08-13), three paths have been entangled in VF's verdict function: a path that must read
SafetyResult.action, a path that must read theFilteredReasonvariant, and a path that must map the gRPC action. - In the shadow comparison that Gen4+7 (2026-08-24, d011592) introduced with
reference_compare.rs, the cause of the diffs was likely mostly "reason variant matching differs slightly per pipeline" inferred, and this refactor reads as a follow-up that reduces those diffs. - No code in this commit actually uses
Downrankyet. The door is open forDownrankto appear in theSafetyResult.actionthat Strato returns, but whether it is actually wired up is something to check in the next commit.
What we learnedB. The home timeline gained a sixth ad format that does not wrap a tweet
- A new ad format was introduced in the home timeline verified —
home-mixer/util/urt/ad_marshaller.rs(+258/−3).- The format name is
header-image-prompt-ad.
- The format name is
- Home timeline ads previously had five formats, and this commit added the sixth verified.
- Promoted tweet (
promoted-tweet-<post_id>-<impression>) - Preroll video ad
- SSP tweet/RTB Trend Takeover
- RTB image ad (
rtb-image-ad-<impression>) - Google SDK Native ad(
GoogleSDKNativeAd)
- The entry name of the sixth is
header-image-prompt-ad-<impression>.
- Promoted tweet (
- If the ad carries information for this format, the dedicated marshaller handles it first verified. The branch is mutually exclusive with promoted tweets.
This branch is at the top of the
marshal_ad()function.if let Some(info) = &ad.header_image_prompt_ad_info { return marshal_header_image_prompt_ad(ad, info, sort_index, request_type, &impression_string); }The criterion is whether the
AdIndexInfo.header_image_prompt_ad_info: Option<HeaderImagePromptAdInfo>field is present.
- The input (HeaderImagePromptAdInfo) is a proto message filled in by the ad index service, and its field composition can be reconstructed from the form the marshaller consumes verified.
- Header image:
image_url: String,image_width/height - Header and body text:
header_text: String,body_text: String - Primary CTA:
button_text: String,landing_url: String - Secondary CTA (not shown if empty):
secondary_button_text: String,secondary_landing_url: String - Whether to dismiss the ad after a click:
dismiss_on_click: bool - Impression tracking callbacks:
impression_callback_endpoints: Vec<String> - Primary CTA click tracking callbacks:
click_callback_endpoints: Vec<String>
- Header image:
- This ad is carried in URT (Universal Response Tree, X's response rendering schema) as a Message-type item, not a tweet verified. It is a separate type called "message prompt".
- The entry structure is
TimelineEntryContent::Item(TimelineItem { content: TimelineItemContent::Message(MessagePrompt { content: MessageContent::HeaderImagePrompt(HeaderImagePrompt { .. }), impression_callbacks }) }). MessageContent::HeaderImagePromptis the content variant dedicated to this ad.
- The entry structure is
- The prompt content (HeaderImagePrompt) carries the image, text, and button actions verified.
- Image (image_variants holds the URL, width, and height):
header_image: MessageImage - Header text:
header_text: String,header_rich_text: RichText. Both forms are carried together: plain text and a RichText without entities. - Body (only when present):
body_text: Option<String>,body_rich_text: Option<RichText> - Primary button (required):
primary_button_action: MessageTextAction - Secondary button (only when
secondary_button_textis not empty):secondary_button_action: Option<MessageTextAction>
- Image (image_variants holds the URL, width, and height):
- Each button has its own click event information and callback list verified.
- The button structure (MessageTextAction) consists of
text: Stringandaction: MessageAction { dismiss_on_click, url, client_event_info, on_click_callbacks, on_click_reactive_trigger }. - In each button's
ClientEventInfo, the action is "primary_cta" or "secondary_cta".
- The button structure (MessageTextAction) consists of
- Three tests pin down this contract verified.
header_image_prompt_ad_marshals_to_message_prompt_entry: asserts the entry_id format ("header-image-prompt-ad-fa4ead01"), the impression callback, the HeaderImagePrompt content variant, the image URL/dimensions, the text, and the primary CTA URL/dismiss/callback.header_image_prompt_ad_emits_secondary_button_when_set: whensecondary_button_text = "Learn more"is set, secondary_button_action exists and its action is secondary_cta.header_image_prompt_ad_info_absent_stays_a_tweet_item: whenheader_image_prompt_ad_info: None, it falls through to the existing promoted-tweet marshaller.
Why it matters (B) The X home timeline formally added a new ad format that does not wrap a tweet.
- RTB image ad was already an image ad separate from tweets, but header-image-prompt-ad has a much richer component composition made of a header image, body text, and up to 2 CTA buttons.
- This format is the first ad to use a separate content type, URT
MessageContent. From the client rendering side, it is likely rendered as in-feed announcement/dialog UI rather than as a tweet inferred. - This is also the first time an ad format that supports a secondary CTA has entered the home timeline.
- This commit does not show when or under what conditions the ad index system (not public) fills this ad format. It also does not show which of the five ad blenders (
safe_gap,partition_organic,partition_organic_low_risk,time_gap,multi_risk) it enters.
What we learnedC. grox prepends a preview image of videos over 30 seconds before the storyboard
- The grox media loader attaches a preview thumbnail to long videos verified —
grox/core/data_loaders/media_loader.py(+100/−19).- Also changed:
grox/core/lm/convo.py(+18)
- Also changed:
- A threshold length, an image field, and a label were newly introduced verified.
- The threshold length constant is
_VIDEO_PREVIEW_MIN_DURATION_MS = 30_000(30 seconds). - A
preview_image: bytes | None = Nonefield was added to theVideopydantic model. - The label constant is
PREVIEW_IMAGE_LABEL = "[Video Preview Thumbnail]".
- The threshold length constant is
- The preview is attached after passing four entry conditions (a 4-way gate) when the config switch is on verified.
- After the existing frame hydration,
hydrate_videorunsif grox_config.media_hydration.enable_video_preview_image: await cls.hydrate_video_preview(video, is_main_post and is_high_fav). - The entry conditions of
hydrate_video_previeware the following four:video.convo_video is not Nonevideo.urlexistsvideo.videoInfoexists(video.videoInfo.durationMillis or 0) > _VIDEO_PREVIEW_MIN_DURATION_MS: more than 30 seconds
- After the existing frame hydration,
- If it is a main post with high fav, the image is resized to the deluxe-only tile size verified.
- If
is_deluxe = is_main_post and is_high_fav,resize_tile(bs, tile_size)usesdeluxe_image_tile_size; otherwise it usesimage_tile_size. - If the download fails,
media_loader.hydrate_video_preview_failed.countincreases. - On success,
media_loader.hydrate_video_preview.countincreases andvideo.convo_video.preview_image = previewis set.
- If
- In the LLM input, the label, image, and newline go before the storyboard verified.
- When preview_image exists,
Video.interleave_storyboardadds three elements,[f"{PREVIEW_IMAGE_LABEL} ", self.preview_image, "\n"], to the front of the storyboard list. The label, the original image bytes, and a newline come in order before the storyboard composite. - In the
_image_part-based chat marshaling path too, a text label is attached before the image viaif c.preview_image: parts.append({"type": "text", "text": PREVIEW_IMAGE_LABEL}); parts.append(_image_part(c.preview_image)).
- When preview_image exists,
Why it matters (C) This commit added a third media representation: one representative frame of a long video, placed before the storyboard.
- Since Gen4+12 (2026-09-01, 6384ca7), where motion-reveal frames (static/dynamic split) were added to the storyboard (from Gen4), the media representations grox passes to the LLM were these two forms.
- A short video already has few storyboard frames and is representative enough. For a long video of 30+ seconds, however, a frame grid can blur the first impression, so the preview thumbnail first establishes "what this is".
- Using a larger-tile preview for the Deluxe tier (main post with high fav) is also consistent with the existing design of tying LLM verdict cost to representativeness.
What we learnedD. Live broadcast frames became targets of two safety verdict pipelines
- grox extracts frames of live broadcasts, and two PTOS safety pipelines judge these frames verified —
grox/core/data_loaders/media_loader.py(broadcast part).- Files changed together:
grox/flows/ptos/task_safety_ptos_adult_content_leading_frames_filter.py(+18/−8),grox/flows/ptos/task_safety_ptos_safemodel_sex_nudity.py(+21/−2)
- Files changed together:
- A broadcast loader was newly added to the media loader verified.
from broadcast_tools.broadcast import BroadcastLoaderwas added tomedia_loader.py, andMediaLoader._broadcast_loader: BroadcastLoader | None = Noneis the class cache._get_broadcast_loader()initializes it lazily. It uses thebearer_token=X_API_BEARERandguest_token=BROADCAST_GUEST_TOKENenvironment variables.
- Frames taken from a broadcast are normalized into a Video object verified.
_extract_broadcast_video(broadcast_metadata: BroadcastMetadata) -> Videoextracts frames withBroadcastLoader.load_broadcast(broadcast_id, media_key=..., max_frames=config.video_max_frames, tile_size=config.video_tile_size, max_duration=broadcast_metadata.crop_seconds).- The extracted frames are normalized into
Video(convo_video=ConvoVideo(frames=..., duration=interval, total_duration=result.video.sampled_duration)). - The duration is computed as
(frames[-1].time_sec - frames[0].time_sec) / (len(frames) - 1).
- The entry conditions of the adult-content leading-frames filter changed in two places verified. The target is the 6-gate condition folded into the canon at Gen4+17 (2026-09-08).
- The conditions are in
TaskSafetyPtosAdultContentLeadingFramesFilter._eligible_with_post.
- The conditions are in
- First, the Deluxe fav gate is gone. The post now enters regardless of the fav threshold verified.
- The old gate #2,
post.get_fav_count() < grox_config.media_hydration.deluxe_fav_count_threshold: return cls._skip(post, "not_high_fav"), was deleted entirely.
- The old gate #2,
- Second, the post enters if a broadcast exists even without a long video verified.
- The old code only looked at
long_videos = [m for m in media if m.type == "video" and durationMillis >= 30s]and skipped withno_long_videoif there were none. - The new code also computes
broadcasts = [p.broadcast_metadata for p in (post, post.quoted_post) if p is not None and p.broadcast_metadata is not None and p.broadcast_metadata.broadcast_id]. The post enters if eitherlong_videosorbroadcastsis non-empty. crop_seconds = 10.0is also set for broadcasts, and amedia = "both" | "broadcast" | "video"tag is attached toMetrics.counter("...eligible.count").
- The old code only looked at
- The sex/nudity safemodel verdict also receives broadcast frames as payload when the config switch is on verified.
- A branch
if grox_config.media_hydration.enable_local_broadcast_frame_extraction:was added toTaskSafetyPtosSafemodelSexNudity._collect_payloads. - This branch uniformly samples
_MAX_FRAMES_PER_VIDEO = 8fromconvo_video.framesof broadcast videos via_iter_broadcast_videos(post)and appends them as("broadcast_frame", frame)payloads. - With the constant
_FRAME_KINDS = {"video_frame", "broadcast_frame"}, both kinds are treated equally when computinghas_videoandn_video_frames. _iter_broadcast_videosyields only those withbroadcast_metadata.video.convo_video.framesfor each ofpostandpost.quoted_post.
- A branch
Why it matters (D) With this commit, live broadcasts were promoted to a formal media payload and became verdict targets of two safety pipelines (adult-content leading-frames and safemodel sex/nudity) that were already applied to static video.
- X's live video (broadcast, the successor of Periscope) was a blind spot of the grox safety pipelines until this commit. PTOS judged only the static media of tweets (photos, uploaded video), and live broadcasts were likely handed to other systems or left unjudged.
- The Deluxe fav threshold, one of the 6 gates introduced in Gen4+17, was deleted a day later. The conditions of the leading-frames pipeline shrank to the following 5-gate set:
- (a) prior PTOS result exists
- (b) prior result is not NSFW
- (c) video of 30+ seconds or broadcast
- (d) prior AdultContent policy or fav ≥ 512
- That is, the pool of candidates for re-judgment grows sharply. This decision reads as moving load control away from managing re-judgment load with the fav threshold and onto (d)'s
ADULT_CONTENT_LEADING_FRAMES_UNCONDITIONAL_FAV = 512and the prior conditions of (a)/(b) inferred.
What we learnedE. The multimodal post embedding was turned off in both registered ranking training configs
- The multimodal post embedding was turned off in all ranking training configs verified —
phoenix/README.md(+3/−3). - The "Multimodal post embedding" row of the nano training config table changed verified.
| Before (49815da) | After (75d93d9) | |
|---|---|---|
| ranking nano | v5 on xrecsys_seqpack; off on home_direct_packed |
off (home_direct_packed and xrecsys_seqpack) |
- The accompanying explanatory text also changed verified.
"the multimodal-embedding input is off in both, and on every registered ranking config, as the table shows" — phoenix/README.md, 2026-09-09
- The
onin the text must be read as a grammatical ellipsis of "off" ("off in both, and [off] on every registered ranking config") verified. Otherwise it contradicts the table. - That is, the multimodal post embedding was dropped from the training input in both registered ranking training configs (
home_direct_packedflagship,xrecsys_seqpackseqpack) verified.
Why it matters (E) Gen4+17 (2026-09-08, 49815da) introduced a v8-search multimodal embedding stack dedicated to the grox search surface, opening a vector space next to ranking that is separate from v5 and v8.2. One day later, in this commit, the v5 input was turned off in the only ranking config that had v5 on.
- That config is
xrecsys_seqpack, and v5 had been on in it since the Gen4 release verified —phoenix/README.mdtable. - Combining the two events narrows the scenarios: we infer that v5 either did not deliver a meaningful improvement as a ranking input or lost out in the latency/quality tradeoff, and was temporarily removed from the training config midway through the move to v8-search inferred.
- This commit has no code that connects v8-search to a ranking config. Whether the search surface embedding and the ranking embedding stay in separate vector spaces, or v8-search replaces v5, is something to check in the next commit.
What we learnedOther changes
- A previous Phoenix bug that tried to schedule threads on isolated cores (isolcpus) inside a NUMA node was fixed verified.
- The fix is in the NUMA CPU affinity handling in
phoenix/xrex/utils/gpu.py. Two helpers,_parse_cpulist(text: str) -> set[int]andschedulable_cpus(*nodes: int) -> set[int], were introduced. schedulable_cpusreads the CPU set of node N from/sys/devices/system/node/nodeN/cpulist, subtracts/sys/devices/system/cpu/isolated, and returns the result.pin_process_to_local_numasplit the existingnuma.schedule.run_on_nodes(node) → numa.memory.set_membind_nodes(node)into two steps. It runsnuma.memory.set_membind_nodes(node)first andos.sched_setaffinity(0, schedulable_cpus(node))second, layering the exception handling.- If the node has no non-isolated CPU, it logs a warning and keeps only membind.
- This appears to be the result of Phoenix training encountering an isolated-core configuration on real production hosts inferred.
- The fix is in the NUMA CPU affinity handling in
- Six feature-gated info logs that were emitted per component of the candidate pipeline were deleted verified.
- These are the
quiet-spanslogs ofcandidate-pipeline. One#[cfg(feature = "quiet-spans")] tracing::info!(...)block was removed from each offilter.rs,hydrator.rs,query_hydrator.rs,scorer.rs,selector.rs, andsource.rs(−40 lines in total). - They were quiet info-level logs emitted on each pipeline component execution. They appear to have been removed because they duplicate span records while the quiet-spans feature condition is always active inferred.
- The string format of the error log also reverted from
error!(component = self.name(), error = %err, "source_failed")toerror!("{} Failed: {}", self.name(), err). The structured fields were removed and it regressed to a string log.
- These are the
- Phoenix inference code also changed slightly verified. This commit appears to have made a minor cleanup of the API surface.
- The changed files are
phoenix/xrex/configs/xrecsys.py(−1),phoenix/xrex/inference/model_runner.py(+2/−1), andphoenix/xrex/models/recsys_model.py(+5). - This may be work to wire up consumption of the
ContentFeaturesfrom Gen4+17 (2026-09-08), so it is something to revisit in the next commit.
- The changed files are
Canon update services/x.md Updated the VF fail-closed statement at line 392 of the ranking and filter section. Also created one new subsection (introduced the "Gen4+18" subsection under ## Pipeline). Added the 75d93d9 sources to ## Sources.
Why it matters (overall) In this commit, the biggest code-quality improvement is the VF Action refactor, and the most visible product change is header-image-prompt-ad. Removing the multimodal embedding training config is the heaviest signal on how the input schema of X's ranking model is decided. Because the v5 input, on since the Gen4 release, was turned off one day after the v8-search stack was introduced, the follow-up on v8-search wiring needs watching.
- If Gen4+17 was a large commit that moved five axes at once in a single day, Gen4+18 carries cleanup, follow-up, and expansion evenly across each axis.
- VF unified the verdict axis (the largest and most fundamental refactor).
- Ads added a new format (a new product feature).
- grox improved LLM input with a preview thumbnail and widened safety pipeline coverage through broadcast unification.
- The training config removed the multimodal embedding (a design-direction decision).
Corrections
- The canon statement "VFFilter is fail-closed" was not fully negated; its wording changed.
- It is at line 392 of
services/x.md. - The verdict axis moved from matching on
FilteredReasonto an explicitActionenum. - The fail-closed character is retained (NotEvaluated → drop; in the Strato path, a non-SafetyResult reason is converted to Drop). However, the filter layer now newly filters out
TombstoneandNotEvaluated. - Folded into the canon.
- It is at line 392 of
Radar
No items were added to the radar today. We parsed 30 arXiv cs.IR papers, and 0 passed the acceptance criteria (platform-company authors or production A/B claims). The four notable candidates are:
SequenceO1: End-to-End Ultra-Long (100K) Sequence Modeling in Recommendation with Low-Rank Caching- Already mentioned in the daily covering Gen4+17. It still has no production A/B.
PDMR: Passage-Driven Multi-ID Document Retrieval- It belongs to the Generative Retrieval family. It has no platform affiliation and no production results. Rejected.
Exploring Bottom-Up Clustering for Creating Semantic IDs- It is a clustering methodology for the Semantic ID line. It has no platform affiliation and is a theoretical increment. Rejected.
Q2D-Web: A Large-Scale Benchmark for Retrieval in Agentic RAG Systems- It is an Agentic RAG benchmark, outside the domain.
What to check next
- Where the Downrank action is actually used — In this commit Downrank was promoted to a proper variant, but no code returns this action yet.
- The promoted variant is
Action::Downrank. - We will watch whether one of the rules under VF
visibility-filtering/rules/is changed to return Downrank, or whether the gRPC server starts returning this action under certain conditions.
- The promoted variant is
- The ads blender that header-image-prompt-ad enters — In the next commit, we will observe which of the five ads blenders (
safe_gap,partition_organic,partition_organic_low_risk,time_gap,multi_risk) this ad format enters, and how it is counted together with promoted tweets in the slot budget calculation. - When v8-search attaches to the ranking config — Since v5 was turned off in
xrecsys_seqpack, the only config where v5 was on, v8-search is a likely candidate for the follow-up wiring. We will watch whether a consumer of thegrox-multimodal-embedding-v8-searchtopic is attached inphoenix/xrex/data/retrieval_dataset.py, and whether v8-search is added to the table inphoenix/README.md. - The PTOS re-judging rate for broadcast — This is the first commit where live broadcast became a proper payload. If a dashboard for
task.safety_ptos_adult_content_leading_frames.eligible.count{media=broadcast}and the broadcast_frame counters oftask.safety_ptos_safemodel_sex_nudityis exposed somewhere, the actual scale of re-judging could be observed. Direct observation is difficult. - The rule that returns
FilteredReason::ViewerBlocksAuthor— It is a new variant, but this commit attaches no code showing which rule will return it. We will watch the next diff ofvisibility-filtering/rules/author_rules.rs. - The actual host configuration behind the NUMA isolated CPU problem — We will watch whether the real production configuration is published anywhere, and why the Phoenix training host placed isolated CPUs inside a node (RT workload? DPDK? SR-IOV VF driver?).
Lookup failed: none.