seo-drift
Skill10 starsChanged 27 days agoMITView on GitHub
Git-for-SEO — capture baselines of on-page SEO-critical elements and diff against them to catch regressions a deploy introduced (title changed, canonical flipped, noindex added, schema removed). Stores baselines in a local SQLite history so you can compare and trend over time. Trigger when the user says "SEO drift", "SEO baseline", "track changes", "did anything break", "SEO regression", "compare SEO", "before and after deploy", "monitor SEO changes", or "deployment check".
24 other projects use a version of this.
Adopted by
Most recently taken up by
- nowork-studio/notfair-plugintheir own version, first seen Nov 11, 2026
- seranking/seo-skillstheir own version, first seen Nov 8, 2026
- alpit-patel/seo-aeo-geo-kittheir own version, first seen Nov 8, 2026
- zhtyyx/codex-seotheir own version, first seen Nov 1, 2026
- joaoguirunas/team-ostheir own version, first seen Oct 21, 2026
- susantedit/claude-skillstheir own version, first seen Oct 20, 2026
Used with
Projects with it also use seo-maps, seo-agentic and 2 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
timruebenachSkillseo-maps
Maps intelligence for local SEO — geo-grid rank tracking, GBP profile auditing via API, review intelligence across Google/Tripadvisor/Trustpilot, cross-platform NAP verification (Google/Bing/Apple/OSM), competitor radius mapping, and LocalBusiness schema generation from API data. Three-tier capability: free (Overpass + Geoapify), DataForSEO (full intelligence), DataForSEO + Google (maximum coverage). Use when user says "maps", "geo-grid", "rank tracking", "GBP audit", "review velocity", "competitor radius", "maps analysis", "local rank tracking", "Share of Local Voice", or "SoLV".
Also in 17 projects that use this
AgriciDanielSkillseo-agentic
Audit and fix agent readiness: the Lighthouse Agentic Browsing fraction, accessibility tree for agents, robots.txt and Content-Signal for AI agents, WAF treatment of agent traffic, llms.txt, Markdown delivery, ai-catalog.json, /.well-known discovery files, and WebMCP tools. Use when the user asks whether AI agents can use or browse the site, or about llms.txt or WebMCP. Exclude AI citability and brand signals (seo-geo) and commerce protocol depth (seo-ecommerce).
Also in 4 projects that use this
timruebenachSkillseo-flow
FLOW framework integration — evidence-led SEO using the Find → Leverage → Optimize → Win loop. Surfaces stage-specific AI prompts from the FLOW knowledge base (41 prompts, CC BY 4.0). Use when user says "FLOW", "FLOW framework", "seo flow", "evidence-led SEO", "find leverage optimize win", or wants stage-specific SEO prompts.
Also in 9 projects that use this
megastepSkillseo-images
Image optimization analysis for SEO and performance. Checks alt text, file sizes, formats, responsive images, lazy loading, and CLS prevention. Use when user says "image optimization", "alt text", "image SEO", "image size", or "image audit".
Also in 17 projects that use this
Other versions24 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 24
- AgriciDaniel/claude-seo★ 30ksame name
- nowork-studio/notfair-plugin★ 4.2ksame name
- nowork-studio/toprank★ 4.1ksame name
- indranilbanerjee/digital-marketing-pro★ 934same name
- seranking/seo-skills★ 201same name
- zhtyyx/codex-seo★ 152same name
- dancolta/seo-drift-monitor★ 19same name
- joaoguirunas/team-os★ 6same name
- avalonreset/legends-seo-dungeon★ 4same name
- alpit-patel/seo-aeo-geo-kit★ 2same name
14 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository46 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- blast-promptSkill
- client-outreachSkill
- content-draftSkill
- copywritingSkill
- csv-to-reportSkill
- design-accessibilitySkill
- design-buildSkill
- design-croSkill
- design-dimensionsSkill
- design-motionSkill
- design-researchSkill
- design-system-genSkill
- design-system-persistSkill
- design-tokens-emitSkill
- design-visual-qaSkill
- html-extractSkill
- parallel-buildSkill
- portable-html-portSkill
- qa-gateSkill
- route-codex-reviewSkill
- route-gemini-contextSkill
- route-three-brainSkill
- seo-auditSkill
- seo-backlinksSkill
- seo-clusterSkill
- seo-competitor-pagesSkill
- seo-content-briefSkill
- seo-contentSkill
- seo-dataforseoSkill
- seo-ecommerceSkill
- seo-firecrawlSkill
- seo-geoSkill
- seo-googleSkill
- seo-hreflangSkill
- seo-image-auditSkill
- seo-image-genSkill
- seo-local-unifiedSkill
- seo-pageSkill
- seo-programmaticSkill
- seo-schemaSkill
- seo-sitemapSkill
- seo-strategySkill
- seo-sxoSkill
- seo-technicalSkill
The file
We split this skill into the rules it gives an agent
2 rules. 0 are common, 1 is distinctive, and 1 is very specific to this project.
0
Common
Most of the 23 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 93
Every row degrades to a real deliverable — a capture, an honest "no drift," or a clear next step — never an empty failure.
- Very specific: line 107
All standard-library only.
“Common” is measured: kept by at least 6 in 10 of the 23 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
seo-drift
Family: seo Status: Stable
Purpose
Baseline + diff for SEO state — "git for SEO." Capture a page's SEO-critical elements,
store the snapshot, then after a deploy or content change diff a fresh capture against
the stored baseline to catch silent regressions before they cost rankings. Two modes:
a quick one-off JSON baseline (drift_tools.py), or a local SQLite history
(drift_baseline/compare/history) that remembers every snapshot so you can compare and
trend over time. Works offline on local HTML or by fetching a URL through the shared
SSRF guard.
Triggers
- "seo drift" / "baseline" / "deployment check"
- "track changes" / "did anything break" / "seo regression"
- "compare seo" / "before and after" / "monitor seo changes"
Inputs
- A URL (fetched, SSRF-guarded) or local HTML file
- Mode: a one-off JSON baseline+diff, or a stored SQLite baseline / compare / trend
- Optional: a
--dbpath (default<cwd>/.seo-drift/baselines.dbunder your workspace; it refuses to default inside the plugin — run from your project, or pass--dbto a path under your workspace), a--label(e.g.prod,pre-deploy), a--baseline-id
Steps
- Capture a baseline into the SQLite store (before a deploy, or at handoff):
Records title, meta description, h1, canonical, meta robots, OG tags, schema-block count, h2 count, and word count (the canonical capture set frompython3 "${CLAUDE_PLUGIN_ROOT}/scripts/seo/drift_baseline.py" --url <URL> --db .seo-drift/baselines.db --label pre-deploy # or --file page.html; add --robots robots.txt for rule D15drift_tools.py), tagged with a timestamp and label, indexed by URL. - Compare after a change against the stored baseline:
Resolves the latest baseline for that URL (orpython3 "${CLAUDE_PLUGIN_ROOT}/scripts/seo/drift_compare.py" --url <URL> --db .seo-drift/baselines.db--label/--baseline-id), captures fresh, and runs the severity engine. It treats addingnoindex/nofollowand a canonical flip or drop as critical, title / h1 / schema-loss changes as high, and meta-description / OG / h2 / word-count drift as advisory (word-count moves under 20% are suppressed as editing noise). Full rationale:references/seo-drift/severity-model.md. - Trend the history to see drift across deploys:
Lists stored baselines, or withpython3 "${CLAUDE_PLUGIN_ROOT}/scripts/seo/drift_history.py" --url <URL> --db .seo-drift/baselines.db --trend--trendreports the per-transition change count and critical/high/advisory tally — a regression timeline where a deploy that quietly added noindex shows up as a critical-count spike. - Quick one-off (no store): for a single before/after without history, use the
original JSON path —
drift_tools.py --capture --out baseline.json, thendrift_tools.py --diff --baseline baseline.json. Same capture set; the JSON baseline is a plain file you can commit. - Interpret. Walk the regressions worst-first: intended change or accident? Fix any
critical/high immediately. The store design is documented in
references/seo-drift/sqlite-schema.md.
Outputs
| Output | What it contains | Format | Quality bar (how it is scored) |
| Stored baseline | A captured SEO-element snapshot tagged with url / label / timestamp, in a local SQLite db | SQLite row (snapshot as JSON) + --human ASCII | Capture is deterministic given the same input + --captured-at; written under the user's workspace, never the plugin |
| Compare report | Changed elements with before/after, each carrying a rule code (D1–D14), severity tier, and a plain-language note | JSON (default) + ASCII --human | Sorted critical → high → advisory; severity comes from the captured-element model, not a guess; "no SEO drift detected" when nothing material changed |
| Trend timeline | Per-transition change count + critical/high/advisory tally across the stored history | JSON transitions[] / ASCII --human | One transition per consecutive snapshot pair; counts reproduce the compare engine exactly |
| Severity verdict | The tier per change + why (de-index risk vs primary signal vs secondary) | tier label + note | No fabricated magnitude — severity is a structural judgment, never an invented traffic/ranking number |
Filed to: the user's project workspace (the SQLite db and any JSON baselines), never the plugin. The engine never estimates a traffic or ranking-position impact from a diff — that would be a synthesized number.
Error Handling
| Condition | Detection | Behavior (degrade, never fail) | User-facing message |
| No network / offline | fetch raises or --no-network set | run the offline --file path (the canonical capturer reads local HTML) | "Offline — analyzed the provided file; a live URL would capture the deployed page." |
| Blocked / internal URL | the shared net_safety.safe_open guard refuses a private/loopback/metadata host | return no body + the guard's error; never fetch it | "That URL resolves to a non-public address — refused by the SSRF guard." |
| Bad / empty input | no --file and no reachable --url → JSON {"error"} + non-zero exit | report the validation error; capture nothing | "Provide --file or a reachable --url." |
| No baseline store yet | drift_compare/drift_history find no db at --db → JSON error + non-zero | tell the user to capture first | "No baseline store at <path> — run drift_baseline.py first." |
| No matching baseline | the requested id / label / url isn't in the store → JSON error + non-zero | do not compare against an unrelated baseline | "No stored baseline matches <selector> — capture one or widen the selector." |
| Capture set evolves | drift_tools.capture() gains/loses a field | the JSON-blob store needs no migration; severity ignores unknown keys, skips absent ones | (silent — old baselines stay comparable; see the schema reference) |
Every row degrades to a real deliverable — a capture, an honest "no drift," or a clear next step — never an empty failure.
Dependencies
scripts/seo/drift_tools.py(required) — the canonical SEO-element capturer + the one-off JSON capture/diff path; Python 3.10+, standard library onlyscripts/seo/drift_baseline.py(required) — SQLite baseline store + capture-and-storescripts/seo/drift_compare.py(required) — compare a fresh capture vs a stored baselinescripts/seo/drift_history.py(required) — list/trend stored baselinesscripts/seo/drift_severity.py(required) — the change→severity engine (rules derived from the captured-element set)references/seo-drift/severity-model.md,references/seo-drift/sqlite-schema.md(severity-model + store-schema knowledge, loaded on demand)- All standard-library only; URL fetches route through the shared
scripts/workflow/net_safety.pySSRF guard
Notes
The SQLite history is the upgrade over a loose JSON file: it remembers every snapshot, so
"compare against the last prod capture" and "show me how SEO drifted across the last
five deploys" are one command. The severity tiers are derived from exactly which
on-page elements we capture — adding a captured element adds a rule, removing one
silences it (references/seo-drift/severity-model.md). A critical verdict means "a human
must confirm this was intended," not "this is a bug" — a planned migration legitimately
flips canonicals; the engine's job is to make sure that flip is never silent.
Related: pairs with design-visual-qa for a complete pre/post-deploy regression net —
drift catches SEO, visual-qa catches rendering (one-directional reference; neither
depends on the other). Baselines are plain SQLite/JSON you can commit.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

