Files
our-claude-skills/custom-skills/35-seo-signal-validation/SKILL.md

4.2 KiB

name, description
name description
seo-signal-validation Validate whether a claimed SERP / Knowledge-Graph movement for a (term, entity) is real, misattributed, an artifact, or unprovable — before reporting impact. Triggers: validate serp signal, is this ranking real, prove SEO impact, SEMrush surge real, signal validation, real impact check, 신호 검증, 순위 변화 진짜, 오가닉 급증 검증, 임팩트 검증.

SEO Signal Validation

Purpose

Given a (term/intent, entity) pair — and optionally a claim (a third-party tool's reported movement) or a baseline (a prior state) — return an evidence-backed verdict on whether SERP and Knowledge-Graph impact is real. Built because modeled third-party signals (SEMrush/Ahrefs estimated organic traffic, position snapshots) are easy to over-trust. This skill makes the measured → live → entity → attribution cascade a single repeatable procedure ending in a defensible verdict and a client-safe narrative.

When to use (boundary)

This is the conductor, not an instrument. It sequences and synthesizes the three measurement skills — it does not duplicate them.

Use instead When
20-seo-serp-analysis You only need SERP composition / features
21-seo-position-tracking You only need rank over time
28-seo-knowledge-graph You only need an entity-presence audit
this skill You must adjudicate whether a claimed movement is real across layers

Step 0 — Classify entity + pick mode

  1. Entity ownership (gates which layers exist):
    • First-party — a site/property you own or have GSC/GA4 access to (e.g. JHR sc-domain:josunhotel.com, GA4 258308769) → L1 measured available.
    • Third-party — a competitor brand or a person you do not control → L1 unavailable; lean on L2 + L3 + clearly-tiered estimates; apply the confidence cap (see Verdict). If unclear, ask once.
  2. Mode (thin wrappers over the same cascade):
    • adjudicate(claim) — a 3rd-party tool reports a move; confirm/refute.
    • prove(baseline) — after our change; before/after from GSC/GA4 history.
    • snapshot() — no claim; "where do we really stand."

The validation loop (cost-ordered cascade, short-circuiting)

Run cheapest-first; stop early when a layer is already decisive.

L1 — Measured (first-party ground truth) → via 21-seo-position-tracking

  • GSC mcp__dda__gsc_fetch_performance: the term at query level (exact) AND site-wide, for recent vs prior windows. Pull clicks / impressions / position / CTR. Day-normalize (compare windows differ in calendar-day count). Note ~43% query-level anonymization — the disclosed subset ≠ the whole.
  • GA4 mcp__dda__ga4_run_report: Organic Search sessions monthly trend (dims yearMonth + sessionDefaultChannelGroup, metric sessions). GA4 includes Naver + all engines — use it to test whether a "surge" exceeds normal month-to-month variance.
  • Compute deltas with the helper (deterministic, avoids ad-hoc parsing): save each GSC pull, then run python3 code/scripts/gsc_signal_delta.py --recent <recent.tsv> --prior <prior.tsv> --recent-days N --prior-days M --claim-term "<term>". It returns day-normalized site totals, top gainers/decliners, and whether the claimed term is among the real movers.
  • SHORT-CIRCUIT: if the claimed keyword has trivial clicks and a real position nowhere near the claim → ARTIFACT; stop unless the caller wants the full picture.

L2 — Live SERP (3rd-party measured, point-in-time) → via 20-seo-serp-analysis

  • Geo-correct Google render via claude-in-chrome (navigateread_page): force gl/hl + correct geo, pws=0; decline precise-location prompts. Confirm whether the domain actually holds the claimed position; capture the feature landscape (ads, local map-pack, PAA, knowledge panel) that explains why a brand site can't own a head term.
  • Cheap rank spot-check: mcp__ourseo__check_serp(keyword, domain).
  • [KR market] Naver SERP composition: our research naver serp (blog / cafe / 지식iN / Smart Store / brand zone) — Semrush/Ahrefs don't model Naver.