Skill: minilozio/tweet-composer (version 1.0.0)

--- name: tweet-composer description: > Score and optimize tweets based on X's real open-source ranking algorithm. Analyzes draft tweets against the actual ranking code — not generic tips. Use when: composing tweets, optimizing drafts for reach, planning threads, analyzing why a tweet performed well/poorly, or asking for posting strategy advice. --- # Tweet Composer Score and optimize tweets using rules derived from X's open-source ranking algorithm. ## How It Works X's "For You" feed is ranked by a Grok-based transformer (Phoenix) that predicts 19 engagement actions for every candidate tweet. The final score is a weighted sum of these predictions. This skill encodes the structural rules from that pipeline into a scoring system. For the full algorithm breakdown, read `references/algorithm-rules.md`. ## Scoring a Draft Tweet When a user asks to score or optimize a tweet draft: 1. Read `references/algorithm-rules.md` for the complete rules engine 2. Analyze the draft against all rules 3. Output the score card in this format: ``` 🐦 Tweet Composer — Score: XX/100 [Category scores with ✅ ⚠️ ❌ indicators] 📊 Predicted Action Boost: ├─ P(reply): [assessment] ├─ P(favorite): [assessment] ├─ P(share): [assessment] ├─ P(dwell): [assessment] └─ P(not_interested): [assessment] 💡 Suggestions: → [actionable improvements] ✏️ Optimized version: "[rewritten tweet]" ``` ## Scoring Rubric (Quick Reference) Score 0-100 based on weighted categories: | Category | Weight | What to check | |----------|--------|---------------| | Reply potential | 25 | Questions, opinions, CTAs that drive replies | | Media | 20 | Native image/video attached (not link previews) | | Shareability | 15 | Would someone DM this or copy the link? | | Dwell time | 15 | Length that makes people stop scrolling | | Content quality | 10 | Clear, original, not generic | | Format | 10 | No links in body, no hashtags, good length | | Negative signals | 5 | Risk of not_interested/mute/block | ## Thread Optimization When composing threads: - First tweet = strongest hook (DedupConversationFilter keeps only the best per conversation) - 3-6 tweets max (short threads > mega-threads) - Each tweet self-contained (many see only the first) - Media on tweet 1 or 2 for photo_expand boost - CTA in last tweet ## Quick Rules (No Reference File Needed) - **Links:** Always in reply, never in body (learned penalty from lower engagement) - **Hashtags:** Zero. The model learns they reduce engagement - **Length:** 100-200 chars sweet spot for single tweets - **Media:** Native image/video = separate P(photo_expand) and P(video_quality_view) predictions - **Video:** Must exceed minimum duration threshold for VQV weight to apply - **Timing:** Post when your audience is active — engagement velocity in first 30 min is critical - **Frequency:** AuthorDiversityScorer penalizes exponentially: 2nd post ~55% score, 3rd ~33%. Max 3-4 strong tweets/day - **Quote tweets:** P(quote) has dedicated weight — QTs with added value outperform plain retweets - **Engagement bait:** Questions/polls drive P(reply). "What would you add?" > "Like if you agree"

path: README.md
content: <p align="center">
  <img src="assets/banner.svg" alt="Tweet Composer" width="600" />
</p>

<p align="center">
  <a href="https://clawhub.com/skills/tweet-composer"><img src="https://img.shields.io/badge/ClawHub-Install-orange?style=flat-square&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRleHQgeT0iMTgiIGZvbnQtc2l6ZT0iMTYiPvCfpp48L3RleHQ+PC9zdmc+" alt="ClawHub" /></a>
  <a href="https://github.com/minilozio/tweet-composer-skill/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License" /></a>
  <img src="https://img.shields.io/badge/version-1.0.0-brightgreen?style=flat-square" alt="v1.0.0" />
  <img src="https://img.shields.io/badge/OpenClaw-compatible-red?style=flat-square" alt="OpenClaw" />
</p>

---

An OpenClaw skill that scores and optimizes your tweets based on **X's actual open-source ranking algorithm** — not generic growth-hacker tips.

We read all ~21,000 lines of X's official open-source recommendation algorithm (released February 2026) and extracted the real ranking rules into a scoring engine your agent can use.

## 🧠 How It Works

X's "For You" feed is ranked by a **Grok-based transformer** (codename Phoenix) that predicts **19 engagement actions** for every candidate tweet. The final ranking score is:

```
score = Σ(weight_i × P(action_i))
```

This skill encodes the structural rules from that pipeline — what actions exist, how they're weighted, what gets filtered, what gets penalized — into a practical scoring system.

## ⚡ What It Does

### 📊 Tweet Scoring (0-100)

Give your agent a draft tweet and get a detailed score:

```
🐦 Tweet Composer — Score: 84/100

✅ Length: 142 chars (sweet spot 100-200)
✅ No links in body
✅ Native image attached (+P(photo_expand) boost)
✅ Ends with question (drives P(reply))
⚠️ No video (missing P(video_quality_view) signal)
❌ Posted at 22:00 CET (off-peak for EU audience)

📊 Predicted Action Boost:
├─ P(reply): HIGH — question drives discussion
├─ P(favorite): HIGH — visual + clear value
├─ P(share_via_dm): MEDIUM — niche but shareable
├─ P(dwell): HIGH — image makes people stop
└─ P(not_interested): LOW ✅

💡 Suggestions:
→ Post at 16:00 CET for peak EU engagement
→ Consider a short video walkthrough instead of screenshot

✏️ Optimized version:
"Built a doctor for my Mac. One command: health score,
security audit, cleanup suggestions. Open source.
What would you add to the checklist? 🩺"
→ Reply with: GitHub link
```

### 🧵 Thread Optimization

The algorithm's `DedupConversationFilter` keeps only the highest-scored tweet per conversation. The skill ensures your first tweet is the strongest hook.

### 📐 19-Action Analysis

For each draft, the skill estimates impact on all 19 predicted actions:
- **15 positive** (favorite, reply, repost, quote, share, share_via_dm, share_via_copy_link, click, profile_click, video_quality_view, photo_expand, dwell, dwell_time, quoted_click, follow_author)
- **4 negative** (not_interested, block_author, mute_author, report)

### 🎯 Content Strategy

Built-in content mix guidance based on empirical analysis:
- 40% entertaining, 30% educational, 20% inspirational, 10% promotional

## 🔬 Key Algorithm Insights

Discoveries from reading the actual source code:

| Finding | Details |
|---------|---------|
| **19 actions predicted simultaneously** — not just "engagement" | Each tweet gets 19 separate probability scores |
| **Author Diversity Scorer** — your 2nd tweet gets ~55% score, 3rd ~33% | Exponential decay per author in a single feed |
| **Candidate Isolation** — each tweet scored independently | Candidates can't see each other in the attention mask |
| **Video duration gate** — short clips don't get VQV weight | Video must exceed minimum duration threshold |
| **Deep reply chains filtered** — only first-level replies survive | In-network store drops reply-to-reply-to-reply |
| **Share via DM has its own weight** — separate from generic share | 3 separate share signals: generic, DM, copy link |
| **dwell_time is continuous** — not boolean, measured in seconds | Longer reading time = proportionally higher score |
| **Signed action encoding** — model knows what you did AND didn't do | Actions encoded as +1 (did) / -1 (didn't) |

## 📦 Install

### ClawHub (recommended)
```bash
clawhub install tweet-composer
```

### Manual
```bash
git clone https://github.com/minilozio/tweet-composer-skill.git
# Copy to your OpenClaw skills directory
```

## 🗂️ Skill Structure

```
tweet-composer-skill/
├── SKILL.md              # Main skill instructions + scoring rubric
├── references/
│   └── algorithm-rules.md # Complete algorithm rules engine (19 actions, filters, scorers)
├── assets/
│   └── banner.svg
├── LICENSE
└── README.md
```

## 💡 Usage Examples

```
"Score this tweet: Just shipped a new feature. Check it out!"

"Optimize this thread for maximum reach"

"What's wrong with this tweet? Why did it get low engagement?"

"Write me a tweet about [topic] that maximizes reply potential"

"Should I post this now or wait for peak hours?"
```

## 📚 Algorithm Source

All rules are derived from X's official open-source recommendation algorithm, released February 2026. We read every file — ~21K lines of Rust + Python/JAX.

## 📄 License

MIT — see [LICENSE](LICENSE)

---

<p align="center">
  Built by <a href="https://x.com/minilozio">@minilozio</a> 🦎
</p>


path: assets/banner.svg
content: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 130" width="700" height="130">
  <rect width="700" height="130" fill="white"/>
  <g transform="translate(100, 0)">
    <text x="0" y="85" font-size="80">🐦</text>
    <text x="100" y="55" font-family="Inter, -apple-system, system-ui, sans-serif" font-weight="800" font-size="32" fill="#09090b" letter-spacing="1">TWEET COMPOSER</text>
    <text x="100" y="80" font-family="Inter, -apple-system, system-ui, sans-serif" font-weight="800" font-size="32" fill="#09090b" letter-spacing="1">SKILL</text>
    <text x="100" y="105" font-family="Inter, -apple-system, system-ui, sans-serif" font-weight="400" font-size="12" fill="#71717a" letter-spacing="3">SCORE • OPTIMIZE • GROW — BASED ON X'S REAL ALGORITHM</text>
  </g>
</svg>


path: references/algorithm-rules.md
content: # X Algorithm Rules Engine

Rules derived from X's official open-source ranking algorithm (released February 2026).
This is from the **actual code**, not speculation.

## Architecture Overview

The "For You" feed pipeline:
1. **Thunder** fetches in-network posts (from accounts you follow) — sorted by recency
2. **Phoenix Retrieval** (two-tower ANN) fetches out-of-network posts — ML similarity search
3. **Phoenix Ranking** (Grok-based transformer) scores all candidates by predicting engagement
4. **Weighted Scorer** combines predictions into final score
5. **Author Diversity Scorer** penalizes repeated authors
6. **OON Scorer** adjusts out-of-network scores
7. **Filters** remove spam, duplicates, blocked authors, old posts

## The 19 Predicted Actions

Phoenix predicts these probabilities for every candidate tweet:

### Positive Actions (boost score)
| # | Action | Signal | Weight Estimate |
|---|--------|--------|----------------|
| 1 | `P(favorite)` | Like | Very High |
| 2 | `P(reply)` | Reply | Very High |
| 3 | `P(retweet)` | Repost | High |
| 4 | `P(quote)` | Quote tweet | High |
| 5 | `P(click)` | Expand tweet | Medium |
| 6 | `P(profile_click)` | Click author profile | Medium |
| 7 | `P(video_quality_view)` | Watch video (gated: only if video > min duration) | High |
| 8 | `P(photo_expand)` | Expand photo | Medium |
| 9 | `P(share)` | Share (generic) | High |
| 10 | `P(share_via_dm)` | Share via DM | High |
| 11 | `P(share_via_copy_link)` | Copy link | High |
| 12 | `P(dwell)` | Stopped scrolling (boolean) | Medium |
| 13 | `dwell_time` | How long they stopped (continuous, seconds) | Medium |
| 14 | `P(quoted_click)` | Click on quoted content | Low-Medium |
| 15 | `P(follow_author)` | Follow from tweet | Very High |

### Negative Actions (reduce score)
| # | Action | Signal | Weight Estimate |
|---|--------|--------|----------------|
| 16 | `P(not_interested)` | "Not interested" | Heavy Negative |
| 17 | `P(block_author)` | Block author | Heavy Negative |
| 18 | `P(mute_author)` | Mute author | Heavy Negative |
| 19 | `P(report)` | Report tweet | Heavy Negative |

**Note:** Exact weights are redacted in the open source release (`params` module excluded "for security reasons"). Weight estimates are based on structural analysis and industry knowledge.

## Score Formula

```
final_score = Σ(weight_i × P(action_i))
```

After combining:
- Score is normalized
- Negative offset applied to handle below-zero scores
- Then: AuthorDiversityScorer × OONScorer adjustments

## Author Diversity Scorer

Prevents feed domination by a single author:

```
For author's Nth post in a single feed:
multiplier = (1 - floor) × decay^N + floor

Example (estimated decay=0.5, floor=0.1):
1st post: 1.0 (full score)
2nd post: 0.55
3rd post: 0.325
4th post: 0.2125
```

**Implication:** Don't spam. Only your first tweet gets full score. Space tweets 4-6 hours apart.

## Out-of-Network Scorer

Posts from accounts you DON'T follow get multiplied by OON_WEIGHT_FACTOR (likely < 1.0).
But high-engagement out-of-network posts can still beat in-network ones.

**Implication for growth:** Your tweets need to be significantly better than average to appear in non-followers' feeds.

## Thunder: In-Network Post Selection

Thunder is the in-memory store for posts from accounts users follow:

- **Original posts** and **reply/retweet** posts have separate per-author limits
- **Reply chains:** Only first-level replies pass the filter. Deep reply-to-reply-to-reply gets filtered
- **Video posts** tracked separately — must have video > MIN_VIDEO_DURATION_MS and NOT be a reply
- **Retweets of the viewer's own posts** are explicitly removed

**Implications:**
- Don't rely on deep reply threads for visibility
- Video replies don't count as video posts
- Short video clips may not qualify for video boost

## Filters (Pre-Scoring)

Posts are removed before scoring if they match:
1. Duplicate tweet ID
2. Missing core data (no author, empty text)
3. Older than MAX_POST_AGE
4. Self-tweets (your own posts in your feed)
5. Duplicate retweets of same content
6. Premium content you haven't subscribed to
7. Previously seen (client sends bloom filter of impressions)
8. Previously served in current session
9. Muted keywords match
10. Author is blocked or muted

## Filters (Post-Selection)

After scoring and selection:
1. **VF Filter:** Safety check — spam, violence, deleted content removed
2. **DedupConversationFilter:** Only the highest-scored post per conversation branch survives

**Critical for threads:** The first tweet of your thread must be the strongest. If a reply in your thread scores higher, IT becomes the one shown, not your hook tweet.

## What the Model Sees

The transformer input for each candidate:
```
[User Embedding] [History_1...History_128] [Candidate_1...Candidate_32]
```

Per candidate:
- Post hash embedding (content representation)
- Author hash embedding
- Product surface (For You, Search, etc.)

Per history item (your recent engagement):
- Post hash embedding
- Author hash embedding
- What action you took (19-dim multi-hot, signed: +1 did it, -1 didn't)
- Product surface where you saw it

**Key insight:** The model knows your recent engagement patterns. If your followers interact with AI/crypto content and you post food content, the model predicts low engagement → low score.

## Candidate Isolation

Each candidate can only see:
- User embedding + engagement history
- Its own embedding

Candidates CANNOT see each other. Scores are independent and consistent.

**Implication:** Your tweet's score doesn't depend on what else is in the feed batch. Quality is absolute, not relative.

## What Changed from 2023

The old algorithm (twitter/the-algorithm, 2023) had explicit features:
- `has_image_flag`, `has_video_flag` → explicit weights
- `has_multiple_hashtags_flag` → explicit penalty
- `text_score` (entropy, readability) → explicit feature
- TweepCred (PageRank-like author score)
- SimClusters (145K community detection)
- Light Ranker (logistic regression) + Heavy Ranker (neural network)

The 2026 algorithm has **NONE of these**. Everything is learned by the Grok transformer from engagement data. But the learned behaviors align with what the old explicit features captured — images/video still boost engagement, hashtags still reduce it, quality content still wins.

## Practical Scoring Rules for Tweet Composition

### Maximize These Signals

| Rule | Why | Impact |
|------|-----|--------|
| Ask a question or prompt replies | Drives P(reply) — one of the highest-weighted actions | ⬆⬆⬆ |
| Attach native image/video | P(photo_expand) + P(video_quality_view) are separate predictions | ⬆⬆⬆ |
| Create shareable content | P(share) + P(share_via_dm) + P(share_via_copy_link) = 3 separate boosts | ⬆⬆⬆ |
| Write content that makes people pause | dwell_time is a continuous value with its own weight | ⬆⬆ |
| Quote tweet with added value | P(quote) has dedicated weight | ⬆⬆ |
| Make people click your profile | P(profile_click) has dedicated weight — "who is this?" effect | ⬆⬆ |
| Content that earns follows | P(follow_author) is predicted — likely very high weight | ⬆⬆⬆ |
| Video above minimum duration | VQV weight only applies above threshold | ⬆⬆ |

### Minimize These Signals

| Rule | Why | Impact |
|------|-----|--------|
| Don't post irrelevant content | P(not_interested) has negative weight | ⬇⬇⬇ |
| Don't be aggressive/toxic | P(block_author) + P(mute_author) + P(report) all negative | ⬇⬇⬇ |
| Don't spam tweets | AuthorDiversityScorer: 2nd post ~55%, 3rd ~33% score | ⬇⬇ |
| No links in tweet body | Model learns link tweets get less engagement | ⬇⬇ |
| No hashtags | Model learns hashtag tweets get less engagement | ⬇ |
| No short video clips | Below MIN_VIDEO_DURATION_MS = no VQV weight | ⬇ |

### Content Strategy

| Mix | Percentage | Why |
|-----|-----------|-----|
| Entertaining | 40% | Drives likes + shares + dwell |
| Educational | 30% | Drives saves + DM shares + follows |
| Inspirational | 20% | Drives profile clicks + follows |
| Promotional | 10% | Necessary but lower engagement |

### Posting Cadence

- **Max effective tweets/day:** 3-4 (AuthorDiversityScorer decay)
- **Spacing:** 4-6 hours between tweets minimum
- **Peak engagement window:** First 30 minutes (velocity determines viral potential)
- **Reply strategy:** 30 min/day replying to larger accounts in your niche (within 30 min of their post)


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)