SKILL.md
Semantic Topic Clustering
Cluster keywords by how Google actually ranks them, not by how similar the words look. Two keywords whose top-10 results share 7+ URLs are the same post; text similarity would never tell you that. The output is a hub-and-spoke architecture with an explicit internal link matrix, ready to brief or execute.
Workflow
1. Expand the seed
Grow the seed keyword to 30-50 unique variants via web search: related searches, People Also Ask questions, long-tail modifiers (best, how to, vs, for beginners, tools, examples, template, mistakes, checklist), who/what/when/where/why/how variants, and commercial modifiers (pricing, review, alternative, comparison, free). Normalize (lowercase, strip articles), dedupe. Under 30 variants: run a second pass seeded with the top PAA questions.
If the user already has a strategy document, import its keyword list instead and skip expansion. Parse its tables, validate for duplicates and gaps, then continue from step 2.
2. Cluster by SERP overlap
For candidate keyword pairs, search both and count shared URLs in the top 10 organic results (ignore ads, snippets, PAA boxes):
| Shared results | Relationship | Action |
|---|---|---|
| 7-10 | Same post | Merge into one target page |
| 4-6 | Same cluster | Group under the same spoke cluster |
| 2-3 | Adjacent | Separate clusters, add cross-links |
| 0-1 | Unrelated | Different clusters or exclude |
Full pairwise comparison explodes (40 keywords = 780 searches). Read references/serp-overlap.md for the comparison-reduction strategy and data source options before starting a run of 20+ keywords.
3. Classify intent
Informational (how, what, guide), commercial (best, review, vs), transactional (buy, price, sign up): all cluster. Navigational (brand and product names, login): exclude. Mixed-intent keywords classify by dominant intent; flag borderline cases for the user.
4. Design hub and spoke
- Pillar = highest volume, broadest intent, most overlap with other keywords.
- 2-5 clusters per pillar, each a subtopic area.
- 2-4 spoke posts per cluster.
- Template per post by intent: ultimate-guide, how-to, listicle, explainer (informational); comparison, review, best-of (commercial); landing-page (transactional).
- Word targets: pillar 2500-4000, spokes 1200-1800.
- Cannibalization check: no two posts share a primary keyword. Overlap of 7+ between two planned posts means merge them.
5. Build the link matrix
- Spoke to pillar and pillar to spoke: mandatory, every spoke.
- Spoke to spoke within a cluster: 2-3 links per post.
- Cross-cluster: 0-1 per post.
- Every post gets 3+ incoming internal links; zero orphans; everything reachable from the pillar in 2 clicks.
- Anchors use the target keyword or a close variant, never "click here". Links live in body content, not navigation.
Emit the matrix as a JSON adjacency list (from, to, type, anchor).
6. Deliver
Write to the working directory: cluster-plan.json (machine-readable), cluster-plan.md (human summary), and optionally a self-contained cluster-map.html visualization built from the plan data. If executing content: write posts pillar-first, then spokes by volume, injecting backward links into earlier posts as later ones publish. If not executing: write one brief per post to cluster-briefs/ with title, meta description, keywords, template, H2/H3 outline, word target, internal links with anchors, and competing pages to beat.
Post-execution scorecard
Coverage 100% of planned posts, 3+ internal links per post, zero orphans, zero duplicate primary keywords, all pillar-spoke links bidirectional, 80%+ of recommended cross-links placed. Report misses; do not round up.
Good vs bad
Bad: Clustering "crm software" and "crm system" into separate posts because the strings differ, and "email marketing" and "email marketing software" into one because they look alike. Text similarity guessed; both guesses are wrong in real SERPs.
Good: Searching both pairs. "crm software" vs "crm system" share 8 of 10 results: one post targeting both. "email marketing" vs "email marketing software" share 2: informational spoke and commercial spoke in adjacent clusters with a cross-link.
Verification
After building the plan, run two checks on cluster-plan.json. First, list every post's primary keyword. Expect zero duplicates; a duplicate means merge or reassign. Second, count incoming links per post from the matrix. Expect minimum 3 for every post and a spoke-pillar link in both directions for every spoke. Any orphan: add links from its nearest cluster siblings and regenerate.
Completion checklist
- [ ] 30-50 deduped variants (or imported strategy keywords)
- [ ] Clustering decisions backed by actual SERP overlap counts, not text similarity
- [ ] Navigational keywords excluded
- [ ] Pillar selected with stated rationale
- [ ] Zero cannibalization: unique primary keyword per post
- [ ] Link matrix complete: no orphans, mandatory links bidirectional
- [ ] cluster-plan.json and cluster-plan.md written
- [ ] Briefs or posts delivered per the execution decision
Any box unchecked: not done. Fix or say so.
Footguns
- Clustering by text similarity when search is available. It feels equivalent and is the whole failure mode this method exists to avoid. Fix: every merge or grouping decision cites a shared-URL count.
- Unbounded pairwise comparison. 50 keywords compared exhaustively burns 1,200+ searches. Fix: pre-group by intent and follow the reduction strategy in references/serp-overlap.md.
- Cannibalization discovered after writing. Two published posts fighting for one keyword split ranking signals permanently. Fix: the duplicate-primary-keyword check runs at plan time and again before each post is written.
- Stale SERP data on slow executions. A plan built months ago no longer matches live SERPs. Fix: re-spot-check the pillar and top spokes' overlap before executing an old plan.