How does X score post quality?
Every post gets judged by a Grok vision model that returns a quality score, descriptive tags — and, by name in the released code, a slop score. The release even shows a rare hard number: a post clears the initial quality screen at score ≥ 0.4, and the same result feeds the Grok ranker. What the model is told to value is withheld with the rest of the prompts.
What the model returns about your post
The "banger initial screen" is the quality gate in the released Grox code, and its result schema is a finding in itself:
30class BangerInitialScreenResult(BaseModel): 31 quality_score: float 32 description: str 33 tags: list[str] 34 taxonomy_categories: list[dict] | None = None 35 tweet_bool_metadata: TweetBoolMetadata | None = None 36 is_image_editable_by_grok: bool | None = None 37 slop_score: int | None = None 38 has_minor_score: float | None = None
Read line 37 again: slop_score. X's released code scores posts for slop, by that
word. Line 38 — has_minor_score — is a child-safety screening signal attached to the
same pass. The banger screen's result schema includes slop_score (an integer — the released code scores posts for slop, by that name) and has_minor_score (a child-safety screening signal), alongside quality_score, tags, and taxonomy categories.
The 0.4 line
Numeric thresholds are almost entirely absent from this release — the famous engagement weights are referenced through a withheld module. Which makes this line one of the only hard numbers in the open:
112 score = result.quality_score 129 banger_initial_positive = score >= 0.4
A post passes the initial quality screen when its model-judged quality score reaches
0.4 — deterministically, every time, at temperature one-millionth.
The banger initial screen has a public numeric threshold — one of the only hard numbers in the release: a post is positive when its model-judged quality score is >= 0.4 (banger_initial_positive = score >= 0.4).
And the result does double duty: the classifier registers under both
BANGER_INITIAL_SCREEN and GROK_RANKER — the same judgment feeds the
ranking pathway. The banger screen result does double duty: the classifier registers under both BANGER_INITIAL_SCREEN and GROK_RANKER categories — the same quality judgment feeds the ranking pathway.
Signal by signal
| in the code | in plain english | where xDoctor surfaces it |
|---|---|---|
| quality_score ≥ 0.4 | The quality gate has a real number, and this is it. | Coach · draft scoring |
| slop_score | Low-effort, mass-produced-looking content is scored as such, by name. | Coach · patterns |
| tags + taxonomy | Your post is auto-tagged into topic categories at judgment time — the model decides what your post is about. | Coach · niches |
| UserRenderer in prompt | Your profile is in the judging context. Quality is scored with the author visible. | Coach · Account |
Grox content classifiers render the post's AUTHOR into the judging prompt: UserRenderer.render(post.user) places the user's profile in the model's context alongside the post, in the PTOS, banger, and post-safety-screen classifiers alike.
What the code doesn't say
What "quality" means. The system prompt — BangerMiniVlmScreenScore — imports from
the absent grox.prompts.template module, so the rubric behind the 0.4 line is
withheld. The gate's number is public; the judging criteria are not. Anyone selling you "the
banger formula" is reading a number and inventing the rest.
The actual spam criteria are withheld: spam.py imports its system prompt (SpamSystemLowFollower) from grox.prompts.template, and the entire grox/prompts/ module is absent from the public release — the classifier machinery is open, the rules it enforces are not.
What to do about it
You can't read the rubric, but the schema tells you what gets measured: quality, slop, topical identity — judged with your profile in frame. That is the exact shape of what Coach scores drafts against, and why the niches surface tracks the topical identity the model assigns you.