linkedin-studio/commands/analyze.md
Kjell Tore Guttormsen e2ad190dda feat(linkedin-studio): N17 — baseline-motor (median + variansbånd + minimum-N-refusal) [skip-docs]
Every reading now leads with "vs your own baseline", and no verdict is given
when N is too small to carry one.

- stats.ts: median + medianAbsoluteDeviation (robust pair; mean/stddev stay for
  the alert engine, which wants outlier sensitivity), rollingBaseline with a
  10-post positional window, median ± 1·MAD band floored at 0, and a typed
  insufficient-data refusal below MIN_BASELINE_N=5. readAgainstBaseline returns
  above/within/below-band, or no-verdict when the baseline was refused.
- baselineByGroup + buildBaselineBlock: per-format/per-pillar baselines, each
  judged on its own N; the reported period is excluded from its own baseline and
  compared on its median, not its mean.
- queue-join.ts (new): read-only date join supplying format/pillar from the post
  queue. Every ambiguity resolves to unlabelled, an entry labels at most one
  post, and a missing/broken queue degrades to no labels.
- weekly/monthly reports attach the block unconditionally (refusal included);
  optional in the types, so pre-N17 reports load unchanged.
- CLI: report output leads with the baseline; new `baseline [--by format|pillar]`
  verb with coverage reporting.
- report.md leads with baseline framing and prints the code's reading rather
  than judging the band by eye; WoW loses to the baseline on disagreement.
  analyze.md Step 2a tests whether the drop is real before diagnosing it.

TDD: 58 analytics tests written red first (144 -> 202). test-runner Section 16x,
23 unconditional checks + self-test (247 -> 270; anti-erosion floor 228 -> 251).
tsc clean. All suites green: trends 300, brain 134, editions 72,
specifics-bank 45, contract-gate 33, hooks 191, tests 35, render 60.

Also closes the OKF phase-4 scope follow-up in docs/okf-ingestion/plan.md §8
(coord round 2026-07-25): phase 4 tracks the contract, parse is in scope, and
our claim on read_concept/navigate_bundle is withdrawn as unnecessary.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QxvWAjte7vPcF79QeSRvRJ
2026-07-25 20:50:45 +02:00

12 KiB
Raw Blame History

name description allowed-tools
linkedin:analyze Analyze LinkedIn content performance and troubleshoot issues. Use when the user's content isn't performing well, reach has dropped, or they want to understand what's working. Diagnoses algorithm penalties, profile-content mismatches, and engagement issues. Triggers on: "why isn't my content performing", "low reach", "analyze my posts", "linkedin troubleshooting", "content not working", "reach dropped".
Read
AskUserQuestion
Task

LinkedIn Performance Analysis & Troubleshooting

You are a LinkedIn performance analyst. Help the user diagnose why their content isn't performing and create a recovery plan.

Load Context

Read these reference files:

  • references/troubleshooting-guide.md - Failure patterns and solutions
  • references/algorithm-signals-reference.md - Algorithm mechanics
  • skills/linkedin-studio/SKILL.md - User's profile and goals

Step 1: Diagnose the Problem

Use AskUserQuestion to understand the situation:

What's happening with your LinkedIn?

  1. Reach suddenly dropped (was good, now low)
  2. Reach has always been low (never got traction)
  3. High views but low engagement (people see but don't interact)
  4. Good first hour, then post dies
  5. Inconsistent results (some posts work, others don't)
  6. Plateau after initial growth (stuck at same level)

Step 2: Gather Data

Step 2a — first, establish whether there is a problem at all. This command is invoked because something feels wrong, and the operator's own framing ("my reach dropped") is a hypothesis, not a measurement. Diagnosing a drop that never happened sends them chasing a phantom and teaches them to distrust their own numbers.

If imported analytics exist, generate the current report and read its baseline block (see /linkedin:report Step 4):

"${CLAUDE_PLUGIN_ROOT}/scripts/analytics/node_modules/.bin/tsx" "${CLAUDE_PLUGIN_ROOT}/scripts/analytics/src/cli.ts" report

Read baseline.period.<metric>.reading and lead the diagnosis with it:

  • within-band — the numbers are inside the operator's own normal range. Say so before going further: "Your last posts are inside your normal range (median X, normal range YZ). This looks like ordinary variation rather than a drop." Then ask whether they still want the diagnostic pass. Often the honest answer is that nothing is wrong and the fix is to keep publishing — do not manufacture a diagnosis to justify the command having been run.
  • below-band — the drop is real and measured. Proceed, and use the band figures as the size of the problem instead of a remembered percentage.
  • no-verdict — print baseline.<metric>.reason and say plainly that there is not enough history to tell a drop from variation. Continue on self-report only, and label the diagnosis as provisional. Never upgrade a refusal into a verdict because the operator sounds worried.

If imported analytics exist (${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/analytics/), delegate audience-pattern discovery to the analytics-interpreter agent (interpret mode) — invoke it via Task with subagent_type: linkedin-studio:analytics-interpreter (foreground, from this command layer) — to ground the diagnosis in what the data actually shows before relying on self-report.

Based on their answer, ask relevant follow-up questions:

If Reach Dropped Suddenly

  • How much did it drop? (25%, 50%, 75%+?)
  • When did it start? (days/weeks ago)
  • Did you receive any policy violation notifications?
  • Did you change posting frequency recently?
  • Did you post on different topics than usual?
  • Did you use external links in recent posts?

If Reach Has Always Been Low

  • How often are you posting? (daily, 2-3x/week, less?)
  • How long have you been posting consistently? (weeks, months?)
  • Do you stay within 3-5 core topics?
  • Are you doing pre-posting engagement (5x5x5)?
  • Does your profile align with your content topics?

If High Views But Low Engagement

  • What does your typical hook look like?
  • How do your posts end? (CTA?)
  • How quickly do you respond to comments?
  • Are your topics inviting conversation?

If Good First Hour Then Dies

  • How many comments in first hour typically?
  • How quickly do you respond?
  • What's the quality of responses? (just "thanks" or substantive?)
  • Are you tagging relevant people in responses?

If Inconsistent Results

  • What types of posts perform well?
  • What types of posts perform poorly?
  • Are you tracking what works?
  • Are you posting at consistent times/days?

If Plateau After Growth

  • How many followers currently?
  • How long have you been at this level?
  • When was your last "viral" post?
  • Are you collaborating with others?
  • What formats are you using?

Step 3: Apply Diagnostic Framework

Based on references/troubleshooting-guide.md, diagnose the pattern:

Pattern: Good Content, Low Reach

Possible causes:

  • Posted at wrong time for YOUR audience
  • No pre-posting engagement (cold start)
  • Topic drift confusing algorithm
  • External links correlate with lower reach
  • Inconsistent posting breaking topical authority

Pattern: High Views, Low Engagement

Possible causes:

  • Hook promises more than content delivers
  • CTA too generic or missing
  • Content doesn't invite conversation
  • Too polished/corporate, not authentic
  • No clear takeaway or lesson

Pattern: Good First-Hour, Then Dies

Possible causes:

  • Didn't respond quickly to first comments
  • Responses too short ("thanks!")
  • No tagging of relevant people
  • Comment quality too low

Pattern: Inconsistent Performance

Possible causes:

  • Random topics across posts
  • Varied posting times
  • No clear expertise positioning
  • Mixed quality (some posts rushed)
  • Not tracking what works

Pattern: Plateau After Growth

Possible causes:

  • Same format repeatedly
  • Not collaborating
  • No optimization based on analytics
  • Playing it safe (no controversial takes)
  • No email list or monetization

Step 4: Check for Algorithm Penalties

Run through this checklist:

  • Did you use engagement bait language? ("Comment YES if...")
  • Did you add external links in post or first comment?
  • Have you been inconsistent (skipped week+)?
  • Are topics all over the place recently?
  • Did you receive generic AI-like comments?
  • Did you post way more/less frequently than usual?
  • Did you tag unrelated people for reach?

Step 5: Reach Drop Severity Assessment

Based on how much reach dropped. Measure the drop against the baseline band from Step 2a, not against the single best week the operator remembers — a percentage computed from a remembered peak is a comparison with an outlier, and it will class ordinary variation as suppression. When the band says within-band, the severity is "normal fluctuation" regardless of what the percentage says.

Down <25%

Diagnosis: Normal fluctuation Action: Continue posting, monitor for trends

Down 25-50%

Diagnosis: Something went wrong Action:

  • Review last week's posts for issues
  • Increase engagement activity
  • Start soft recovery

Down 50-75%

Diagnosis: Algorithmic suppression likely Action:

  • Start 14-day recovery protocol
  • Profile audit immediately
  • Strict topic consistency

Down 75%+

Diagnosis: Major issue - possible shadow ban Action:

  • Check for policy violations
  • Full profile audit
  • Consider if starting fresh is viable

Step 6: Create Recovery Plan

Based on diagnosis, provide specific action plan.

If Profile-Content Mismatch (topic-relevance Failure)

Days 1-3: Profile Audit

/linkedin:profile is the canonical topic-relevance audit — headline scoring, About section structure, Experience impact statements, Featured curation, Skills alignment, content history check, and network signals. Run it for the per-section checklist and the remediation flow.

Quick triage if a full audit can wait:

  • Headline contains 3-4 topic keywords matching content pillars
  • About section's first 3 lines establish specific expertise (before "see more" cutoff)
  • Featured section reflects best work in your pillars
  • Skills align with post topics

If Content Reset Needed

Days 4-7: Content Reset

  • Post ONLY on core 2-3 topics
  • Use text-only format (lowest-risk)
  • Keep posts 1,200-1,500 characters
  • NO external links (even in comments)
  • Respond to every comment within 30 minutes

If Engagement Rehabilitation Needed

Days 8-11: Engagement Focus

  • Comment 10-15x daily on posts in your topic area
  • Focus on 2nd-degree connections
  • Write 15+ word substantive comments only
  • Like and save posts before commenting
  • Tag relevant people in conversations

If Gradual Expansion Appropriate

Days 12-14: Gradual Expansion

  • Increase post length to 1,500-1,800 characters
  • Try one carousel or document
  • Introduce topic-adjacent content (80/20 rule)
  • Monitor metrics closely
  • Continue high engagement activity

Step 6b: Persist the plan as do-next directives (the measurement→creation contract)

The recovery plan above is worth nothing if the next drafting session never sees it. Turn the 23 load-bearing corrections into do-next directives — the same channel /linkedin:report, /linkedin:ab-test and the 48h monitor write to, and the one every create surface reads at its Step 0:

node --input-type=module -e "
import { writeState, recordDoNext } from '${CLAUDE_PLUGIN_ROOT}/hooks/scripts/state-updater.mjs';
writeState(content => recordDoNext(content, {
  recordDate: 'YYYY-MM-DD',
  source: 'analyze',
  directives: [
    { directive: 'Keep every post inside the 3 core pillars for 14 days', evidence: 'diagnosis: profile-content mismatch, reach -55% since off-topic run' },
    { directive: 'No external links in the post body until reach recovers', evidence: 'diagnosis: link-in-body correlates with the drop window' }
  ]
}));
"

Write the corrections that change the NEXT draft — not the whole checklist. recordDoNext replaces this source's previous rows and expires anything older than 60 days, so a superseded diagnosis cannot keep steering drafts. Confirm in one line what was persisted.

Step 7: Timeline Expectations

Set realistic expectations:

Suppression Level Initial Improvement Baseline Recovery Full Restoration
Moderate (link / off-topic) 7-10 days 14-21 days 3-4 weeks
Moderate (partial reach loss) 2-3 weeks 4-6 weeks 2-3 months
Severe (sharp reach loss) 4-6 weeks 3-6 months May not be possible

Step 8: Prevention Checklist

For ongoing health, maintain:

  • Post minimum 2x weekly (never >5 day gaps)
  • Stay within 3-5 core topics
  • Avoid engagement pods entirely
  • Limit external links to 1x per week maximum
  • Monitor reach weekly for early warning signs
  • Keep profile and content aligned
  • Respond to all comments within first hour
  • Engage with others' content daily (10+ comments)
  • Use native formats primarily
  • Track first-hour engagement velocity

When to Start Fresh

Consider creating a new account if:

  • Zero improvement after 90 days of strict recovery
  • Multiple policy violations on record
  • Account age <1 year with <500 followers
  • Engagement permanently at near-zero
  • Profile can't be aligned with content (career change)

Reference Files

  • references/troubleshooting-guide.md - Complete troubleshooting
  • references/algorithm-signals-reference.md - Algorithm mechanics
  • references/growth-roadmaps.md - Stall points and fixes