← skills directory○ community

Skill · charliehills

post-scorer.

Score the draft against what actually performs for you, not against generic best practices.

$ git clone https://github.com/charlie947/social-media-skills.git ~/.claude/skills/social-media-skills

Most LinkedIn scoring tools rate a draft against an averaged-out set of "viral post" rules, which means they will tell every writer the same thing in roughly the same order. post-scorer is structured differently. It pulls the writer's own post history, finds the top decile by engagement, extracts the patterns that distinguish those posts from the bottom decile, and scores the draft against those patterns. The score is not "how good is this post" but "how likely is this to perform for *you*".

The mistake most LinkedIn scorers make is treating "what performs" as a universal property of posts. It is not. The hooks that work for a founder writing about hiring do not work for a marketer writing about funnels, even when both posts are well crafted. post-scorer treats performance as a property of the writer-audience pair and scores against that specifically.

§01What it does

The skill expects a draft and tries three sources of performance data in order. First, it looks for cached scrape data in the project, files matching *-all-posts.json or *-posts.txt. If a previous run pulled the writer's history, it reuses it. Second, if no cache exists, it offers to scrape the writer's last hundred posts via Apify, which takes a minute or two and costs about fifty cents. Third, if the writer prefers not to scrape, it falls back to Charlie Hills' own benchmark dataset (about 500 posts averaging 1,872 engagements), which is a useful proxy for LinkedIn writers in adjacent niches even though it is not personal data.

Once data is loaded, the skill calculates an engagement score for every post in the dataset. The formula is total_reactions + (comments x 3), which weights comments more heavily because they are higher signal than passive reactions. It then identifies the top decile and bottom decile by score and pulls the patterns that separate them: hook types that recur in winners, average word count, format distribution (text only versus image versus carousel), CTA shape, sentence rhythm, and topic clusters that over-index.

That distillation becomes a scoring profile, which is what the draft gets graded against. The output is a per-criterion score with concrete reasons and rewrite suggestions where the draft falls short.

§02Top-decile beats average every time

The reason this skill scores against the top decile rather than the mean of the writer's history is that the mean is dragged down by the same patterns the writer is trying to escape. A writer's average post represents what they currently produce on autopilot. The top decile represents the patterns they have already proven they can execute when the post lands. Scoring against the top decile is scoring against the writer's own demonstrated ceiling, which is a much more useful benchmark than scoring against an external "viral" standard.

The bottom-decile pass matters too. The skill explicitly flags patterns that recur in the writer's underperforming posts, so the rewrite suggestion has two sides. Do more of what works. Stop doing this specific thing that is dragging your average down. That asymmetry is the part most scorers miss.

§03Setup

# Required for live scrapes:
export APIFY_API_TOKEN=your_token

# Trigger phrases:
#   "score my post"
#   "review my post"
#   "rate this post"
#   "give me feedback on this draft"

The Apify call uses apimaestro/linkedin-profile-posts with total_posts: 100. Pulling more posts gives a tighter profile but increases scrape time and cost roughly linearly. The skill explicitly does not pass the fields parameter to the Apify actor, because doing so strips engagement data, which would defeat the entire scoring step.

◆ pull quote

Scoring against your average is scoring against the patterns you are trying to escape. Scoring against your top decile is scoring against the ceiling you have already proven you can hit.

§04Caveats

The skill is only as good as the data behind it. A writer with fewer than thirty posts will not have a meaningful top decile, and the resulting profile will be noisy. In that case the Charlie Hills benchmark fallback is a reasonable bridge until the writer has built up enough history.

Apify scraping costs real money in aggregate. A scrape every few weeks is fine. Scraping before every draft is not. Cache discipline matters here.

◇ summary · field notes
$ vibgineer summarize post-scorer
  1. 01
    Get the post
    • paste the draft
    • load voice files if present
  2. 02
    Get the data
    • cached scrape, fresh scrape, or
    • Charlie Hills benchmarks, or
    • generic best practices
  3. 03
    Top-decile analysis
    • score = reactions + 3x comments
    • extract hook, length, format, CTA
    • flag bottom-decile patterns
  4. 04
    Score
    • rated against the profile
    • reasons attached to every line
    • actionable rewrite suggestions
✓ 1 score · grounded in your data, not in someone else's idea of viral.
Summary: Step 01: Get the post (paste the draft, load voice files if present). Step 02: Get the data (cached scrape, fresh scrape, or, Charlie Hills benchmarks, or, generic best practices). Step 03: Top-decile analysis (score = reactions + 3x comments, extract hook, length, format, CTA, flag bottom-decile patterns). Step 04: Score (rated against the profile, reasons attached to every line, actionable rewrite suggestions). ✓ 1 score · grounded in your data, not in someone else's idea of viral.