# Myths: links, hashtags, bookmarks, Premium

People repeat fixed penalties for links, hashtags, bookmarks, and Premium. The open-source For You tree at [`cb45b55`](https://github.com/xai-org/x-algorithm/commit/cb45b55) does not contain those penalties. Citations below are the ones gathered in [`X_ALGORITHM_BOOST_PLAYBOOK.md`](https://github.com/abhirupghosh/tweet-factory/blob/main/X_ALGORITHM_BOOST_PLAYBOOK.md). This page does not add a percentage the repo does not publish.

tweet-factory’s draft score is a separate local heuristic. It uses these published weights and does not reintroduce the retired penalties below. [How drafts are scored](how-tweet-factory-scores-drafts.md) is that heuristic. This page is the ranker.

## Do links hurt reach on X?

`open_link` is a positive head with published weight **+0.2**. There is no median-engagement constant, and no “link in the body means near-zero reach” constant, in the repo.

Leaving the app can still change other predictions. `dwell` (binary weight 0.05) and `click_dwell_time` (continuous weight 0.4) are separate heads. A scorer that predicts less dwell after an off-site click is scoring those heads, not applying a secret link penalty.

`SpamScamLinks` is a Grox spam subtype. It is a safety label, not a dwell rule. The prompt that fires it is not in the repo, so there is no published numeric cutoff.

The prompt `tf generate` sends says open-link is a small positive and that a URL does not zero the post. `scoreDraft` has no open-link row. A URL only withholds a 0.1 copy-link strength bonus. `roast()` calls that same function, without account calibration. The formula is on [how drafts are scored](how-tweet-factory-scores-drafts.md).

## Do hashtags cut reach by a fixed percent?

There is no hashtag counter in the ranking sum. The myth that “3+ hashtags cut reach 40%” is unsupported as a fixed penalty. No 40% figure appears in the playbook’s reading of this tree.

`SpamHashTagAbuse` is a classifier label. Its prompt is unpublished. `MutedKeywordFilter` can drop a post when the **viewer** has muted that keyword, including a hashtag keyword. That is the viewer’s mute list, not a global hashtag tax.

`scoreDraft` treats three or more `#` characters as stuffing: it raises report, mute, and not-interested strength, and adds more report strength at six or more. That is an editorial risk on the negative heads. It is not a percentage cut, and it is not a counter in the ranking sum. The old quality-classifier file (`grox/classifiers/content/banger_initial_screen.py`) is not in the current tree.

## Do bookmarks raise the author’s score?

There is no bookmark head in `xai-value-model/phoenix_scores.rs`.

Bookmarks are a viewer-history feature: `EngagementSignalType::Bookmark` in `home-mixer/models/engagement_signals.rs`, capped at 15 per type by `EngagementSignalsMaxPerType`. They steer what **that viewer** is retrieved next. They are not a term in the author’s score.

SimClusters candidate embeddings are favorite-based (`LOG_FAV_BASED_TWEET`), not bookmark-based.

Saving a post can still matter to the person who saved it. It does not show up as a coefficient next to reply or copy-link.

## Does Premium change the organic score?

The playbook’s check: there is no Premium term, and no sentiment term, in the weighted sum. Subscription state gates subscriber-only posts (`IneligibleSubscriptionFilter`) and ad spacing. It does not add an organic-score bonus in this tree.

“RealGraph” does not appear in the repo. Advice that says “reply to bigger accounts so RealGraph compounds” is not grounded in this code. Out-of-network replies are dropped before scoring. See [why replies stay in network](why-replies-stay-in-network.md).

## Other retired lines

| Claim that used to circulate | In commit cb45b55 |
|---|---|
| A VLM quality score under 0.4 drops the post | That file is gone. The current screen emits `slop_score` with no published cutoff. |
| Images are worth about 2.5× engagement | No such coefficient. `photo_expand` is 0.05 and `video_open` is 0.07. `vqv` is 0. |
| Phoenix out-of-network retrieval returns only the top 200 | `PhoenixMaxResults` is 1000. 200 is the cold-start retrieval cap and the SimClusters ANN cap. |
| Posting four times a day is a hard penalty | Author decay is per request pool (second post ×0.625). DPP can separate near-duplicates in one slate. Neither is a daily cap. |
| Tuesday to Thursday, 9–10am, is a ranker constant | No day-of-week constant. Cold start is two hours and 200 impressions, for authors under 50,000 followers. |

## Related

- [The weight table](x-algorithm-engagement-weights.md)
- [How a For You request is built](how-the-x-algorithm-works.md)
- [How tweet-factory scores drafts](how-tweet-factory-scores-drafts.md)

## FAQ

### Do links hurt reach on X?

The published ranker has `open_link` at +0.2. It does not contain a percentage penalty or a “near-zero median engagement” constant for a link in the post. Dwell and click-dwell are separate predictions, and `SpamScamLinks` is an unpublished safety classifier, not a dwell rule.

### Does the X algorithm punish hashtags?

Not with a counter in the score. Three or more hashtags are not a coded demotion in this tree. `SpamHashTagAbuse` is a safety label whose prompt is not published, and a viewer can mute a hashtag keyword on their own account.

### Do bookmarks or Premium boost a post’s For You score?

Bookmarks are not a scoring head. They are capped viewer-history features. Premium is not a term in the sum. Subscription state decides who can see a subscriber-only post, and it affects ad spacing. It is not an organic ranking bonus in the published defaults.

### Why does “twitter algorithm reddit” disagree with this page?

Search for that phrase is people comparing anecdotes. This page does not summarize a forum. It answers from commit cb45b55: there is no coded “links cut reach” percentage, no hashtag counter in the sum, no bookmark head, and no Premium term in the organic score. A thread can still be describing dwell after a click, a viewer’s muted keyword, or a visibility label whose prompt is not in the repo. Those are different mechanisms, listed above. The dated code changes are on [X algorithm changes in 2026](x-algorithm-changes-2026.md).

### Is the Twitter algorithm messed up?

The repository does not contain a broken-flag or a status field by that name. What it does contain, as of 2026-10-09, is a weighted sum of predicted actions, a 48-hour age filter, out-of-network reply filtering, and a separate visibility service. Several 2026 commits changed defaults (popular posts turned on, `post_unexplored` moved from 0.02 to 0.015, the mutual reply boost settled at +15). A feed that feels different can be one of those defaults, or an experiment bucket the public tree does not name for a given viewer. The commit list is [the 2026 changelog](x-algorithm-changes-2026.md).
