How Visibility-Filtering Makes ALLOW, INTERSTITIAL, or DROP Decisions in the X Algorithm
Visibility-filtering applies a strict hierarchy where DROP overrides INTERSTITIAL and INTERSTITIAL overrides ALLOW, using hydrated context data and policy-based rule evaluation to determine content visibility.
The visibility-filtering system in the xai-org/x-algorithm repository serves as the gatekeeper for tweet distribution, determining whether content appears directly in user feeds, behind a warning interstitial, or is suppressed entirely. Written in Rust, this module processes every tweet through a multi-stage pipeline that evaluates safety labels, author relationships, and media content against declarative rule sets. Understanding this decision flow reveals how the platform balances content moderation with user choice.
Core Concepts: RuleSpec, Policy, and Verdict
The architecture rests on three fundamental abstractions that separate rule definition from execution logic:
-
RuleSpec: A declarative rule that defines both a predicate condition (e.g., "tweet contains NSFW media") and the resulting action. These specifications live in
visibility-filtering/rules/tweet_rules.rsand include concrete implementations likeNSFW_MEDIA_INTERSTITIALSandNSFW_AUTHOR_INTERSTITIAL. -
Policy: An ordered collection of
RuleSpecinstances evaluated sequentially. The system maintains two primary policies invisibility-filtering/rules/registry.rs:INTERSTITIALSfor rules triggering warning screens, andDROP_AFTER_INTERSTITIALfor rules requiring permanent suppression. -
Verdict: The enumeration result returned after policy evaluation, containing one of three variants:
ALLOW,INTERSTITIAL, orDROP.
The Decision Pipeline: From Hydration to Final Verdict
When a viewer requests a tweet, the system executes a four-stage pipeline to reach a visibility decision:
1. Context Hydration
First, hydrators in visibility-filtering/hydration/ gather all relevant metadata including the tweet content, author information, viewer relationship data (blocks, mutes), and safety labels. This raw data feeds into an in-memory TestContext snapshot that rules consume during evaluation.
2. Policy Selection
The system selects between two static policies defined in visibility-filtering/rules/registry.rs:
INTERSTITIALS: Contains rules likeNSFW_MEDIA_INTERSTITIALSthat trigger warning screensDROP_AFTER_INTERSTITIAL: Contains rules likeNSFW_MEDIA_DROPthat enforce permanent removal
3. Sequential Rule Evaluation
Each policy evaluates its RuleSpec array in order against the TestContext. The evaluation follows strict precedence rules where the first matching rule determines the initial verdict, though subsequent checks may override it for drop conditions.
4. Hierarchy Resolution
The final verdict follows a DROP > INTERSTITIAL > ALLOW hierarchy. If any rule in the drop policy matches, the content is suppressed regardless of interstitial eligibility. If no rules match, the default state is ALLOW.
Decision Hierarchy and Precedence
The precedence logic ensures that safety-critical restrictions always take priority over warning screens. As implemented in visibility-filtering/filter.rs, the filter_tweets function orchestrates this hierarchy:
- Evaluate the
INTERSTITIALSpolicy first - If the result is
INTERSTITIAL, subsequently evaluateDROP_AFTER_INTERSTITIAL - If the drop policy matches, upgrade the verdict to
DROP - If the initial evaluation returns
ALLOW, skip further checks
This two-phase evaluation ensures that borderline content receives appropriate warnings, while clear policy violations result in immediate suppression.
Source Code Implementation
The decision logic spans three primary files in the repository:
visibility-filtering/rules/tweet_rules.rs
This file defines the concrete RuleSpec constants that check for NSFW media, author labels, and relationship flags. These specifications contain the predicate logic that inspects the TestContext for specific safety labels or user interactions.
visibility-filtering/rules/registry.rs
The registry aggregates individual rules into policies and provides the Policy::evaluate method. It declares the static arrays INTERSTITIAL_ROWS and DROP_AFTER_INTERSTITIAL_ROWS, then composes them into the INTERSTITIALS and DROP_AFTER_INTERSTITIAL policy instances used by the filtering engine.
visibility-filtering/filter.rs
This module exposes the public entry point filter_tweets, which accepts a Viewer and Tweet reference, constructs the TestContext, and executes the policy evaluation chain. The function returns the final Verdict that downstream systems use to render content, display interstitials, or hide tweets.
Code Example: The Filtering Flow
Below is the core logic from visibility-filtering/filter.rs demonstrating how the hierarchy works in practice:
pub fn filter_tweets(viewer: &Viewer, tweet: &Tweet) -> Verdict {
let ctx = TestContext::new(viewer, tweet);
// First check if content requires an interstitial
let verdict = INTERSTITIALS.evaluate(&ctx);
match verdict {
Verdict::Allow => Verdict::Allow,
Verdict::Interstitial => {
// Check if drop rules override the interstitial
DROP_AFTER_INTERSTITIAL.evaluate(&ctx)
}
other => other,
}
}
And the policy definitions from visibility-filtering/rules/registry.rs:
static INTERSTITIAL_ROWS: [RuleSpec; 2] = [
RuleSpec::Tweet { rules: NSFW_MEDIA_INTERSTITIALS },
RuleSpec::Tweet { rules: NSFW_AUTHOR_INTERSTITIAL },
];
static INTERSTITIALS: Policy = Policy::new(&[&INTERSTITIAL_ROWS]);
static DROP_AFTER_INTERSTITIAL_ROWS: [RuleSpec; 2] = [
RuleSpec::Tweet { rules: NSFW_MEDIA_DROP },
RuleSpec::Tweet { rules: NSFW_AUTHOR_DROP },
];
static DROP_AFTER_INTERSTITIAL: Policy = Policy::new(&[&DROP_AFTER_INTERSTITIAL_ROWS]);
Summary
- Visibility-filtering determines tweet distribution through a rule-based pipeline that evaluates hydrated context data against declarative policies.
- The system maintains a strict decision hierarchy: DROP overrides INTERSTITIAL, which overrides ALLOW.
- Three core abstractions—RuleSpec, Policy, and Verdict—separate rule definition from execution logic.
- The implementation spans
visibility-filtering/filter.rs(entry point),visibility-filtering/rules/registry.rs(policy aggregation), andvisibility-filtering/rules/tweet_rules.rs(rule definitions). - Context hydration in
visibility-filtering/hydration/supplies the safety labels and relationship data required for rule evaluation.
Frequently Asked Questions
What is the difference between INTERSTITIAL and DROP decisions?
An INTERSTITIAL decision places content behind a warning screen that users can click through to view the material, typically used for sensitive but not prohibited content. A DROP decision completely prevents the content from appearing in the user's feed, reserved for severe policy violations or blocked relationships. According to the source code, the system checks interstitial rules first, then applies drop rules only if an interstitial was triggered, ensuring that suppression takes precedence over warnings.
How does visibility-filtering handle multiple conflicting rules?
The system processes rules sequentially within each policy, but the DROP > INTERSTITIAL > ALLOW hierarchy resolves conflicts across policy boundaries. If the INTERSTITIALS policy flags content for a warning screen, but the DROP_AFTER_INTERSTITIAL policy subsequently matches a drop rule, the final verdict becomes DROP. This ensures that the most restrictive applicable rule always governs the outcome.
Where are the NSFW detection rules defined in the codebase?
NSFW-related rules are defined as RuleSpec constants in visibility-filtering/rules/tweet_rules.rs, including NSFW_MEDIA_INTERSTITIALS, NSFW_AUTHOR_INTERSTITIAL, NSFW_MEDIA_DROP, and NSFW_AUTHOR_DROP. These rules inspect the TestContext for safety labels applied during the hydration phase, checking both media content and author metadata to determine appropriate visibility restrictions.
Can the visibility-filtering rules be customized or extended?
Yes, the architecture uses declarative RuleSpec structures aggregated in static arrays within visibility-filtering/rules/registry.rs. Developers can extend the system by adding new rule specifications to tweet_rules.rs and including them in either the INTERSTITIAL_ROWS or DROP_AFTER_INTERSTITIAL_ROWS arrays. The Policy::evaluate method automatically incorporates new rules into the evaluation pipeline without requiring changes to the core filtering logic in filter.rs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →