# Show HN: XViral – Post virality predictor based on X's For You Ranking pipeline

> Source: <https://github.com/ninjahawk/XViral>
> Published: 2026-07-15 15:00:58+00:00

*Let AI grade your post before the algorithm does. Based on X's open source For You ranking pipeline, rebuilt from the official source release.*

Star us, and you will receive all release notifications from GitHub without any delay!

In May 2026, X published the production code of its For You feed — Home Mixer (orchestration), Thunder (in-network store), Phoenix (the Grok-based ranking transformer), and Grox (the content-understanding service) — together with a 2.9 GB pre-trained mini Phoenix checkpoint, frozen from the same continuous training process as the production model. The release contains the complete scoring formula and its nineteen engagement heads, the output schemas and thresholds of the Grok content judges, and the pipeline's filters and penalties. It withholds the numbers: the head weights, the judge prompts, and the operational thresholds.

XViral vendors that release unmodified, audits it file by file
([FINDINGS.md](/ninjahawk/XViral/blob/main/FINDINGS.md)), and rebuilds the pipeline locally as a
draft-post scorer: the Grok judge layer is emulated by an LLM against the
exact published schemas, the weighted scorer applies the exact published
formula, and every withheld number is a provenance-tagged free parameter
([simulator/weights.json](/ninjahawk/XViral/blob/main/simulator/weights.json)) to be fitted against the
outcomes of real posts.

This differs from the algorithm-guide genre in that nothing here is folklore: each mechanic traces to a file in X's own code, each assumed value is labeled as assumed, and the simulator's accuracy is treated as a measurable quantity with a target (pairwise ranking accuracy against published posts), not a claim.

**1. The platform scores slop.** Every post passes a Grok vision-language
judge whose output schema includes `quality_score`

(a "banger" screen with a
hard threshold at 0.4) and an integer `slop_score`

— template filler is
measured, not merely disliked (`grox/classifiers/content/banger_initial_screen.py`

).

**2. Small accounts face a dedicated spam judge.** A classifier named
`SpamSystemLowFollower`

renders binary spam verdicts specifically for
low-follower authors — the exact cohort, and the exact phrasing patterns, of
template giveaway posts (`grox/classifiers/content/spam.py`

).

**3. Negative predictions are first-class.** The final score is a weighted sum
over heads that include `not_interested`

, `block_author`

, `mute_author`

, and
`report`

— a post that provokes mutes does not merely underperform, it is
actively suppressed, and legacy-published weights put `report`

at −369 against
0.5 for a like (`home-mixer/scorers/weighted_scorer.rs`

).

**4. Video earns nothing below a duration floor.** The video-quality-view head
is weight-gated on `video_duration_ms > MIN_VIDEO_DURATION_MS`

; the widely
recycled "video gets 10× engagement" figure appears nowhere in the code and
traces to a 2019 Twitter Ads marketing post.

**Grox judges**— the emulated banger screen (`quality_score`

against the source threshold 0.4),`slop_score`

0–10, and the low-follower spam verdict with its reason.**Weighted score**— the source formula applied to per-impression action probabilities: an in-network score and an out-of-network score (the OON multiplier from`oon_scorer.rs`

applied).**The head table**— each action's probability, weight, and signed contribution, sorted by magnitude; the negative-head net is printed separately because it usually decides the total.**Top fixes**— the three highest-impact edits, from the judge.

```
draft text (+ media flags)
    → Grok-judge emulation (claude -p | local ollama, temp 0)
         banger {quality_score, slop_score, tags}   [schema: source]
         spam   {decision, reason}                  [schema: source]
         P(action) per impression × 19 heads        [head list: source]
    → weighted scorer:  Σ weight_i × P(action_i)    [formula: source]
         vqv head gated by video duration           [mechanism: source]
    → OON view: score × OON_WEIGHT_FACTOR           [mechanism: source]
```

**Provenance.** Everything marked *source* is verbatim from the vendored
release. Weight values carry tags in `weights.json`

: `legacy_2023`

(the
published weights of the previous open-sourcing, used as priors) or `assumed`

(our priors, first to move under calibration). The judge prompts are
reconstructions against the published output schemas; X's actual prompt text
is withheld from the release.

**Real outcomes, no API.** `--tweet <url>`

pulls live public engagement
numbers for any post through X's syndication CDN — the endpoint that powers
embedded tweets — with no authentication and no account contact. This is the
calibration data path.

A 23-variant, 3-generation evolutionary search over giveaway formats
([experiments/RESULTS.md](/ninjahawk/XViral/blob/main/simulator/experiments/RESULTS.md)) ran through an
identical judge at temperature 0 and converged in two generations on a single
family (attached payout-proof video × no-strings ask), with clean negative
results isolating the drivers — evidence the instrument produces consistent,
discriminating rankings rather than noise. The account it is tuned for
reports that these rankings track observed post behavior (directional
validation). Current status: pipeline structure, head list, schemas, and
thresholds are source-faithful; absolute scores are uncalibrated — the
negative heads in particular inherit LLM overestimation amplified by large
legacy weights. The roadmap ([PLAN.md](/ninjahawk/XViral/blob/main/PLAN.md)) defines the accuracy
contract: predictions logged before posting, outcomes fetched after, pairwise
ranking accuracy ≥ 70% out-of-sample before the scoring profile is frozen.

Requirements: Python 3.11+, and at least one judge engine — the `claude`

CLI,
or [Ollama](https://ollama.com) running any capable local model (default:
`qwen3.5:9b`

). No X API access, no GPU required for the simulator itself.

```
git clone https://github.com/ninjahawk/XViral
cd XViral/simulator
python xviral_score.py "your draft post"                    # judge: claude CLI
python xviral_score.py "your draft post" --engine ollama    # judge: local model
python xviral_score.py --tweet https://x.com/u/status/123   # real stats, no auth
```

Flags: `--video-ms 12000`

, `--image`

, `--link`

, `--audience file.txt`

, `--json`

.

**The checkpoint.** The 2.9 GB mini Phoenix (`phoenix/artifacts/`

, Git LFS) is
not committed here; re-fetch it via the LFS batch API or `git lfs pull`

in the
upstream repo. It runs under JAX (`phoenix/run_pipeline.py`

) and ranks by
hash-ID embeddings — a mechanics lab for the ranking stage, deliberately not
part of the text-scoring path.

**Other audiences.** The judge is conditioned on an audience description
(default: crypto-Twitter giveaway subculture at ~7k followers). Pass
`--audience yourfile.txt`

to re-target the instrument at any niche.

The instrument inherits the gaps of the release it is built on. Production Phoenix conditions on each individual viewer's engagement history; we approximate with audience descriptions. Early-engagement cascades, timing luck, and shadow visibility actions are not modeled and appear only as noise in outcomes. Withheld weights mean absolute scores are meaningless until calibrated; the tool rank-orders drafts and flags structural killers — it does not predict lightning strikes, and it is not a substitute for posting.

The pipeline source is by X / xAI
([x-algorithm](https://github.com/xai-org/x-algorithm), Apache 2.0), vendored
unmodified with license preserved. Legacy weight priors are from the 2023
open-sourcing ([the-algorithm-ml](https://github.com/twitter/the-algorithm-ml)).
XViral is an independent project and is not affiliated with X or xAI.

Licensed under Apache 2.0.
