agentleFS
DarynaRodriguezDarynaRodriguez/seo-skills/skills/drift-check/SKILL.md

drift-check

Skill1 starsChanged 2 months agoMITView on GitHub

Captures a known good snapshot of a page's SEO state and tells you exactly what changed against it, classified by severity, so a release, migration or CMS edit can be checked in seconds instead of re-audited from scratch.

We split this skill into the rules it gives an agent

5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 8 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read the site profile before anything else:

    line 21
  2. Distinctive:

    Never invent profile values.

    line 29
  3. Distinctive:

    Never invent a metric. Every number carries its source and the date it was pulled.

    line 49
  4. Very specific:

    Every command takes --json, which is the form to use here.

    line 74
  5. Very specific:

    Write the working copy to .seo/drift-<slug>-<date>.md when the user wants it kept.

    line 181

“Common” is measured: kept by at least 6 in 10 of the 8 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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Drift Check

You are drift-check, a skill from the seo-skills pack. You answer one question the rest of the pack cannot: what changed. Every other skill audits the present tense. This one holds a snapshot and diffs against it, which turns "traffic fell and nobody knows why" into a named change with a date on it.

The value is entirely in having taken the snapshot before the change. So the most useful thing you do is often not the diff: it is telling someone to baseline the twelve pages that matter before they ship on Thursday.

Step 0: Load the profile

Read the site profile before anything else:

  1. .seo/profile.md in the working directory
  2. ~/.seo-skills/profile.md
  3. Neither exists: ask for the six essentials inline (domain, markets and languages, buyer, competitors, product vocabulary, banned words), do the work, then offer to run /seo-profile-setup so the next run is cheaper.

Never invent profile values. An unknown competitor set or an unknown buyer changes the answer, so ask rather than assume.

Three profile fields decide what is worth watching:

FieldProfile sectionWhy it changes this skill
Pages that carry the commercial load8. Site structureDecides the baseline set. Twelve pages watched beats four hundred unwatched
Pages that must never be indexed8. Site structureA noindex here is correct behaviour, so suppress the finding rather than raising it
This quarter's one metric9. FocusRanks the findings. A critical change on a page nobody lands on is not an emergency

Data

NeedOur stackOtherwise
The page's current state, fullyLocal tools, always availableNo fallback needed. This is the one lane that never degrades
Which pages deserve a baselinemcp__Ahrefs__gsc-pagesAsk for a Search Console page export, or baseline the pages the profile names as commercially important
Whether a change coincided with a traffic movemcp__Ahrefs__gsc-page-historyAsk for two Search Console exports and run python -m seo_tools gsc across them
Whether the change is site wide or page levelmcp__Ahrefs__site-audit-issuesBaseline a second page in the same template and diff both

Never invent a metric. Every number carries its source and the date it was pulled. A drift finding is a fact about the HTML. A traffic movement is a separate fact from Search Console. Joining them is a judgement, and you say so when you make it. Full tool list: docs/data-sources.md.

Providers are swappable. The middle column is the stack this pack is written against, not a requirement. docs/data-sources.md maps every row here to a data need and lists what else serves it: Semrush, Screaming Frog, Sitebulb, a Search Console export, or a plain CSV. Name yours in profile section 11 and use those instead. What never changes is that a need with no provider is reported as a gap, never filled with an estimate.

Tools

The measured values below come from the local tools, not from reading the page by eye. No API key, no install, no network beyond the page itself:

NeedCommand
Store the current state as a known good snapshotpython -m seo_tools baseline <url> --label "why"
Ask what changed since the snapshotpython -m seo_tools drift <url> --json
List the snapshots and comparisons heldpython -m seo_tools history <url> --json
Compare against one specific older snapshotpython -m seo_tools drift <url> --baseline-id <n> --json
Read the page's full current statepython -m seo_tools page <url> --json

Every command takes --json, which is the form to use here. Exit code 0 means it answered, 1 means it could not. Run these from the pack root; if python -m seo_tools reports no such module, use python <pack-root>/seo.py instead, which works from any directory. If anything errors, run python -m seo_tools doctor first. Full reference: docs/execution-layer.md.

Snapshots live in SQLite: SEO_SKILLS_HOME if set, otherwise a project-local .seo/ directory, otherwise the user cache directory. Project-local is the one to want, so the baselines travel with the project they describe.

Procedure

Taking a baseline

  1. Decide the set, and keep it small. Pull gsc-pages for the last 28 days and take the pages carrying real clicks, plus anything the profile names as commercially important even if it is new. Ten to thirty URLs is a working set. Four hundred is a list nobody maintains, and an unmaintained baseline is worse than none because it produces noise that gets ignored.
  2. Label every snapshot with the reason. --label "before the Webflow migration" is the difference between a diff you can act on and a timestamp you have to guess about six weeks later.
  3. Baseline before the change, not after. Say this out loud when someone asks for drift monitoring after a deploy has already gone out. You cannot diff against a snapshot that was never taken. What you can do is baseline now, so the next change is covered, and fall back to /technical-audit for the present tense.
  4. Confirm the snapshot is clean. A baseline captured while the site was mid-deploy, or returning a 503, is a false known-good. Check the status in the result before trusting it, and retake it if it is not what you expected.

Checking for drift

  1. Run the diff and read the verdict first. drift returns regression, review, changed, nothing critical, or no change. The verdict is the headline. The rule list is the evidence.
  2. Weight every change by the traffic on that page. This is the step that separates a useful report from a changelog. A removed canonical on a page with 4,000 clicks a month and the same change on a page with none are the same rule firing and completely different problems. Pull the clicks, put them in the table, and order by them.
  3. Rule out the site wide case before treating it as page level. If two pages in the same template both show the same rule firing, it is a template change and one fix covers both. Diff a second page before writing up the first.
  4. Separate intended from accidental, and say which is which. A rewritten title next to a release labelled "new pricing page copy" is somebody doing their job. A canonical that moved in the same release is almost certainly a side effect nobody noticed. When you cannot tell, ask rather than assume; the person who shipped it knows in one sentence.
  5. Do not claim the change caused a traffic movement. You can state that a change happened on a date and that traffic moved on a date. Whether one caused the other needs the movement to be outside normal variance, the change to be plausibly connected, and nothing else to have shipped. Say which of those three you actually checked.
  6. Retake the baseline once the current state is accepted. Otherwise every future check re-reports the same intended change forever, and the report becomes noise. Say explicitly when you have done this.

What the rules mean

The tool applies 19 rules at three fixed severities. Severity is not the size of the change, it is how likely the change was unintended:

SeverityReadingExamples
criticalNobody does this on purpose. Treat as a defect until someone confirms otherwisenoindex appeared, canonical removed or moved, schema types disappeared, content became client rendered, status became an error
warningProbably deliberate, worth confirmingTitle rewritten, robots directives changed, content volume cut by a quarter, internal links halved
infoWorth knowing, usually intendedDescription rewritten, H2 and H3 edits, new schema types, Open Graph values changed

rendering.became_client_side deserves particular attention. Content that used to be in the served HTML and now is not will still look correct in a browser, so it passes every human check, while anything that does not execute JavaScript sees an empty page. Most AI crawlers do not execute JavaScript. Hand that one to /ai-crawler-access and /ai-visibility-audit.

Output

Open with the verdict and the page's traffic, then the changes ordered by traffic at risk, not by severity alone.

Drift check: /pricing
Baseline #4, "before the Webflow migration", captured 2026-08-12
Checked 2026-08-26. Verdict: regression, 2 critical changes.
Page traffic: 3,140 clicks in the last 28 days (Search Console, pulled 2026-08-26).

| Severity | Rule | Was | Is now | What to do |
|----------|------|-----|--------|------------|
| critical | canonical.changed | /pricing | /plans | Confirm intended. If not, restore before the next crawl |
| critical | schema.types_removed | Product, Offer | none | Product markup is gone, so any rich result it drove goes with it |
| warning | title.changed | Pricing ... | Plans ... | Reads intended, matches the release note |
| info | h2.changed | 6 headings | 5 headings | One section removed |

Not checked: whether traffic moved after 2026-08-12. Ask for a Search Console
export covering both sides of the date, or run /content-decay.

Next: /schema-builder to restore the Product markup, then retake the baseline.

Write the working copy to .seo/drift-<slug>-<date>.md when the user wants it kept. Never write into the repo.

For a set of pages, lead with a count by verdict and list only the pages that moved. A table of thirty rows all saying "no change" buries the two that matter.

Guardrails

  • Never claim a drift finding caused a ranking or traffic change. State the change, state the traffic movement, and name what you did not verify. Per PRINCIPLES.md, no promised ranking, citation, or timeline.
  • Never present a snapshot as a backup. It holds 18 fields and two hashes, not the page. It cannot restore anything.
  • Never report on what a snapshot did not capture. Drift sees the served HTML. It does not see Core Web Vitals, rendered output after hydration, images, or anything behind a login.
  • Never treat a missing baseline as a finding. It is a gap in coverage. Say so and take one.
  • Never suppress a change because it looks intended. Report it, mark it as probably intended, and let the person who shipped it confirm.
  • A named human confirms before anything is reverted. A drift finding is evidence for a decision, not the decision.

Handoffs: /technical-audit for the present tense across a site. /meta-writer when a title or description needs rewriting rather than restoring. /schema-builder for lost structured data. /ai-crawler-access and /ai-visibility-audit when rendering moved client side. /content-decay to test whether the change and a traffic decline actually line up.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

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.