keyword-cluster — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited keyword-cluster (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Take a set of seed keywords and produce a publication-ready cluster plan: pillar pages with their spokes, intent-grouped, prioritised by an opinionated scoring formula, with an internal-link map and a four-gate quality scorecard. Output is structured for direct hand-off to /digital-marketing-pro:content-brief or /digital-marketing-pro:content-engine.
Heavy skill. Grep before Read any referenced file, then Read only matched ranges with offset + limit. List ${CLAUDE_PLUGIN_DATA}/<brand>/ before opening files. On re-invocation mid-session, skip files already in context.
Don't use when you just need keyword expansion (use /digital-marketing-pro:keyword-research) or when you need ranking analysis (use /digital-marketing-pro:rank-monitor / /digital-marketing-pro:serp-tracker).
~/.claude-marketing/brands/_active-brand.json for the active slug, then load ~/.claude-marketing/brands/{slug}/profile.jsonskills/context-engine/industry-profiles.mdskills/context-engine/compliance-rules.md to filter out banned terminology before clustering| Input | Source | Required? |
|---|---|---|
| Seed keywords (3–500) | CSV with keyword column (optional: volume, kd, intent) | yes |
| SERP results per keyword | JSON: {keyword: [top result URLs]} from any rank-tracker / Ahrefs / Semrush export | strongly recommended — without this the script falls back to lexical clustering, which is lower-confidence |
| Target country / language | From brand profile | optional override |
| Min volume / max KD filters | CLI flags | optional |
| Overlap threshold | CLI flag --overlap (default 0.4 for SERP mode, 0.3 for lexical) | optional |
If SERPs JSON is unavailable, you can build one quickly by running the brand's connected rank-tracker MCP (Ahrefs / SE Ranking / Semrush) for each seed and saving the top 10 URLs. Skip this step only if the seeds are too numerous to justify the API spend — but flag the lower-confidence mode in the final deliverable.
All outputs go to ${CLAUDE_PLUGIN_DATA}/{brand}/seo/keyword-cluster/{YYYY-MM-DD}/.
getRelatedKeywords, etc.) to ~50–200; otherwise skip. Document expansion source. python "scripts/keyword_cluster.py" \
--keywords "${CLAUDE_PLUGIN_DATA}/{brand}/seo/keyword-cluster/{date}/02-filtered.csv" \
--serps "${CLAUDE_PLUGIN_DATA}/{brand}/seo/keyword-cluster/{date}/03-serps.json" \
--overlap 0.4 \
--min-volume {profile.min_volume or 0} \
--max-kd {profile.max_kd or 100} \
--out "${CLAUDE_PLUGIN_DATA}/{brand}/seo/keyword-cluster/{date}/04-cluster-run.json"quality_scorecard block from 04-cluster-run.json. If status: needs_review, diagnose:cannibalisation: fail → two clusters share pillar+intent. Merge them or reassign the lower-priority cluster's pillar.orphan: fail → a multi-keyword cluster has 0 spokes. Re-tokenise its members or lower --overlap.coverage: fail → < 80% of seeds clustered. Lower --overlap to 0.3 or expand seeds.anchor_diversity: fail → pillar names too similar. Rewrite cluster names with synonym variation.fragmentation_warning: true (pillar-only > 50%) → overlap threshold too strict. Try --overlap 0.3 first.priority_score >= 0.5, draft a one-paragraph pillar page brief (intent, audience, length target, key questions to answer). These feed /digital-marketing-pro:content-brief.internal_link_targets from the script output. Per cluster: which other clusters to link out to + suggested anchor text. This is the file your dev team or CMS template should consume.priority_score descending. Recommended build cadence: top 10% in Q1, next 30% in Q2, remainder backlog.${CLAUDE_PLUGIN_DATA}/{brand}/seo/keyword-cluster/2026-06-04/
├── 00-input.md
├── 01-seed-expansion.md (only if seeds expanded)
├── 02-filtered.csv
├── 03-serps.json (if SERP mode)
├── 04-cluster-run.json (raw script output)
├── 05-quality-scorecard.md
├── 06-pillar-pages.md
├── 07-internal-link-map.md
├── 08-build-order.md
└── PLAN.md (the deliverable)PLAN.md is what you hand to the brand / client / next skill. Everything else is auditable intermediate state.
Every run produces a scorecard from scripts/keyword_cluster.py. All four must pass for status: ready:
| Gate | What it checks | Why it matters |
|---|---|---|
| cannibalisation | No two clusters share the same (pillar, primary_intent) pair | Prevents you from writing two pages competing for the same SERP |
| orphan | Every multi-keyword cluster has ≥1 spoke (pillar-only clusters are exempt and tagged) | Catches clustering bugs where a cluster head has no supporting topics |
| coverage | ≥ 80% of input seeds are assigned to at least one cluster | Catches "junk" seeds and overly strict thresholds |
| anchor_diversity | Each multi-keyword cluster has ≥ 2 anchor-text variants suggested | Stops anchor-text over-optimisation across the internal-link graph |
A fragmentation_warning: true (pillar-only > 50%) is a soft signal — the run is valid but you should consider lowering --overlap and re-running.
This skill is a producer in the chain:
/digital-marketing-pro:keyword-research — generate seeds/digital-marketing-pro:content-brief — consumes PLAN.md + 06-pillar-pages.md to brief each pillar/digital-marketing-pro:content-engine (or contentforge:create-content) — drafts the content/digital-marketing-pro:seo-implement — applies the internal-link map to the CMSfragmentation_warning: true, lower to 0.3 first. If you get cannibalisation: fail with too few clusters, raise to 0.5.priority_score: 0.3 may still be your highest-conversion opportunity if it maps to a high-margin product line. Use the brand profile's business_goals to override mechanically.skills/context-engine/brand-voice-controls.md).seo-specialist (primary) — interpretation + final pillar-page recommendationscompetitive-intel — for SERP-overlap reasoning when results look surprisingbrand-guardian — anchor-text review against banned-term lists/digital-marketing-pro:keyword-research — generates seeds (use first)/digital-marketing-pro:content-brief — consumes the cluster plan (use next)/digital-marketing-pro:seo-implement — applies internal-link map to CMS/digital-marketing-pro:seo-drift — re-run quarterly to detect cluster driftscripts/keyword_cluster.py — the underlying clustering engine~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.