seo-drift — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited seo-drift (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 two snapshots of SEO performance data — separated by weeks, a Core Update, a content refresh, or an algorithm change — and produce a structured drift report: top gainers, top losers, classifications (growth / decline / reshuffle / stable / new / lost), and diagnostic patterns. Works with classic GSC, the new GSC AI Performance Report, rank-tracker exports, and aeo-audit probe results.
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.
aeo-audit outputs to see which queries gained / lost AI Mode citations (Google AI Mode citation diff is a leading indicator for organic decline)Don't use for single-point-in-time analysis (use the source skill — seo-audit, aeo-audit, gsc-ai-performance).
~/.claude-marketing/brands/_active-brand.json for the active slug, then load ~/.claude-marketing/brands/{slug}/profile.jsonskills/context-engine/industry-profiles.md for industry-specific noise thresholds (YMYL industries should use higher --noise to filter out routine Quality Rater Guidelines volatility)| Input | Source | Required? |
|---|---|---|
| Baseline CSV | Older snapshot | yes |
| Current CSV | Newer snapshot | yes |
| Join keys | Auto-detected (query, keyword, page, url) or --join-on flag | optional |
| Noise threshold | --noise (default 5%) — % below which a metric is "stable" | optional |
| Top-N | --top (default 20) — gainers/losers per metric | optional |
Both snapshots must come from the same source. Mixing a GSC export with an Ahrefs export will produce nonsense — different sources count different things.
All outputs go to ${CLAUDE_PLUGIN_DATA}/{brand}/seo/seo-drift/{YYYY-MM-DD}/.
python "scripts/seo_drift.py" \
--baseline "${CLAUDE_PLUGIN_DATA}/{brand}/seo/seo-drift/{date}/01-baseline.csv" \
--current "${CLAUDE_PLUGIN_DATA}/{brand}/seo/seo-drift/{date}/02-current.csv" \
--top 30 --noise 5 \
--out "${CLAUDE_PLUGIN_DATA}/{brand}/seo/seo-drift/{date}/03-drift-run.json"quality_scorecard from 03-drift-run.json. If status: needs_review, diagnose:date_range_distinct: warn → script couldn't auto-validate. Manually confirm in 00-input.md that baseline and current cover non-overlapping windows.sample_size: fail → either input has < 50 rows. Re-export without row limits.metric_compatibility: fail → no numeric metrics in BOTH inputs. Column-name mismatch — re-export from the same source.no_lookup_collisions: fail → duplicate keys in one input (e.g., same query × page row twice). Re-export with deduplication or use --join-on to add a distinguishing column./digital-marketing-pro:content-engine for amplification.is_yMYL × had_recent_change × Core_Update_window → action (refresh content / restore reverted change / wait for next algo cycle / accept and reallocate)./digital-marketing-pro:aeo-audit to verify citation loss in synthetic probes./digital-marketing-pro:seo-audit for diagnosis./digital-marketing-pro:aeo-geo to align with new intent patterns.${CLAUDE_PLUGIN_DATA}/{brand}/seo/seo-drift/2026-06-04/
├── 00-input.md
├── 01-baseline.csv
├── 02-current.csv
├── 03-drift-run.json
├── 04-quality-scorecard.md
├── 05-biggest-gainers.md
├── 05-biggest-losers.md
├── 06-ai-mode-shift.md (only when input is GSC AI Performance Report)
├── 07-classification-distribution.md
└── PLAN.md| Gate | What it checks | Why it matters |
|---|---|---|
| date_range_distinct | Baseline and current cover non-overlapping windows | Overlapping windows produce false-positive deltas — same data on both sides |
| sample_size | Each input has ≥ 50 rows | Below this, drift is noise |
| metric_compatibility | ≥ 1 numeric metric exists in both inputs | If columns differ (e.g., Ahrefs vs GSC), there's nothing to compare |
| no_lookup_collisions | No duplicate keys within an input | Duplicates make the delta math ambiguous |
status: ready requires sample, metric compatibility, and no-collision gates pass (date-range-distinct is warn not fail — the script can't always autodetect dates).
Each row in the report falls into one bucket:
| Classification | Trigger | Interpretation |
|---|---|---|
| growth | ≥ 2 metrics moved up > noise%, no metric down > 10% | Clear win — investigate for amplification |
| decline | ≥ 2 metrics moved down > noise%, no metric up > 10% | Clear loss — triage by YMYL × Core-Update-window |
| reshuffle | Significant moves in opposite directions (e.g., impressions up, position down) | AI Mode signature — content is being shown more broadly but for slightly different intents |
| stable | No metric moved more than noise% | No action |
| new | Absent in baseline, present in current | New content or new SERP coverage — track |
| lost | Present in baseline, absent in current | Content removed, deindexed, or fell out of tracking window |
Position is special: for position, lower numbers are better. The script automatically inverts position-delta direction for gain/loss ranking — you'll see -85.9% under position as a top gainer (page moved from position 12 to position 2).
This skill is typically a consumer + diagnostician:
/digital-marketing-pro:gsc-ai-performance or seo-audit or aeo-audit — generates the snapshots/digital-marketing-pro:seo-audit for technical-side check + /digital-marketing-pro:content-decay-scan for content-side/digital-marketing-pro:aeo-geo for intent realignment/digital-marketing-pro:content-engine for amplification briefsanalytics-analyst (primary) — interpretation + cause hypothesesseo-specialist — for technical-cause hypotheses on loserscompetitive-intel — when decline correlates with a competitor's winmarket-intelligence — for algo-update context (was there a Core Update in the window?)/digital-marketing-pro:gsc-ai-performance — pull the GSC AI Performance Report (input source)/digital-marketing-pro:seo-audit — diagnose decline causes/digital-marketing-pro:aeo-audit — diagnose AI Mode citation loss/digital-marketing-pro:content-decay-scan — for content-side decline triage/digital-marketing-pro:content-engine — for amplifying gainersscripts/seo_drift.py — the underlying drift engine~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.