---
name: seo-audit
description: Orchestrate a full methodology-grade SEO audit from the SEO Audit Report Builder runbook — preflight, kickoff, data collection, the analysis skills, a 0–100 health score, synthesis, and a client-ready report. Enforces Ledger discipline and the report-only Prime Directive.
argument-hint: "[begin|collect|skills|score|synthesize|report|drift|status]"
---

# /seo-audit — audit orchestrator

The runbook (`seo-audit-runbook.md`) is the source of truth for the *method*; its Ledger (§2) is the
single source of truth for *state*. This skill is the discoverable entry point — it drives that
runbook and invokes the analysis skills at the right time. It does **not** restate their logic.

> **This skill supersedes the standalone `seo-audit` *analysis* skill.** It invokes the five other
> analysis skills and folds the SaaS-specific gap checklist in directly (see `skills` below) — so
> there is no second `seo-audit` skill to call. (That avoids two skills sharing the name `seo-audit`.)

**Playbook release: `2026-11-06.1`.**

## Playbook dependencies

Install the two public analysis variants and three helpers, including their scripts and references:

```bash
npx skills add BigChrisCooke/seo-playbook-skills --skill remove-ai-slop-without-removing-ctas-and-good-marketing-copy trend-scan claim-check ai-seo-better-than-corey-haines schema-markup-better-than-corey-haines
```

Select your agent; add `--global` for all projects. These helpers require Python 3.10+.
See https://github.com/BigChrisCooke/seo-playbook-skills for manual installation.

### Skill names and existing audit files

Use the published skills below. Older audits keep their existing evidence filenames; these filenames are storage locations, not skill commands.

| Invoke | Source | Save audit evidence as |
| --- | --- | --- |
| `/ai-seo-better-than-corey-haines` | [GitHub](https://github.com/BigChrisCooke/seo-playbook-skills/tree/main/skills/ai-seo-better-than-corey-haines) · [skills.sh](https://skills.sh/BigChrisCooke/seo-playbook-skills/ai-seo-better-than-corey-haines) | `skills/ai-seo.md` |
| `/schema-markup-better-than-corey-haines` | [GitHub](https://github.com/BigChrisCooke/seo-playbook-skills/tree/main/skills/schema-markup-better-than-corey-haines) · [skills.sh](https://skills.sh/BigChrisCooke/seo-playbook-skills/schema-markup-better-than-corey-haines) | `skills/schema-markup.md` |
| `/competitors` | [GitHub](https://github.com/coreyhaines31/marketingskills/tree/main/skills/competitors) | `skills/competitor-alternatives.md` |

Corey's comparison-page skill is now named `competitors`. Install it and the other two upstream dependencies separately:

```bash
npx skills add coreyhaines31/marketingskills --skill programmatic-seo site-architecture competitors
```

If using the standalone runbook without our optional orchestrator, also install `seo-audit` from that upstream repository. If using our orchestrator, it supplies that checklist itself; do not replace it with the upstream skill of the same name.

Before analysis, resolve each required skill by its published name. If one is missing, link its source above and provide the install command; mark it blocked until installed. Do not silently use an older local `ai-seo` or `schema-markup` copy. If an upstream skill cross-references those older names, route AI visibility and structured-data work through the published variants above. Use the runbook's audit-only scope and verification rules throughout.

### Verify this release and the complete installation

**Playbook release: `2026-11-06.1`.** The current [release manifest](https://seo-audit-site.vercel.app/handover/release.json) lists SHA-256 hashes and byte counts for the clean downloads. At session start, read this file from disk and report its absolute path and release. Compare with the live manifest; do not infer freshness from a download timestamp or file size. A working copy's hash will change when its Ledger is edited. Preserve that Ledger when upgrading instructions, and record the new release only after applying them.

For Claude Code, run these commands **from the audit project folder**. They install complete packages into that project. For Codex or Cursor, replace `claude-code` with `codex` or `cursor`.

```bash
npx --yes skills add BigChrisCooke/seo-playbook-skills --skill claim-check trend-scan remove-ai-slop-without-removing-ctas-and-good-marketing-copy ai-seo-better-than-corey-haines schema-markup-better-than-corey-haines --agent claude-code --copy --yes
npx --yes skills add coreyhaines31/marketingskills --skill programmatic-seo site-architecture competitors --agent claude-code --copy --yes
```

For the standalone runbook, also run `npx --yes skills add coreyhaines31/marketingskills --skill seo-audit --agent claude-code --copy --yes`. Skip that command if using our optional orchestrator, which supplies the checklist under the same name.

Download [check-skills.py](https://seo-audit-site.vercel.app/skill-pack/check-skills.py) into the audit project, then run:

```bash
python check-skills.py --project . --standalone
```

Omit `--standalone` when using our optional orchestrator. The checker performs no installs or network requests. It checks all five public packages against the published file hashes, verifies the three upstream entrypoints and their referenced resources, and runs the bundled Python helpers with `--help`. Missing scripts, changed package contents, or conflicting installed copies are reported with paths. `--skills-dir PATH` restricts checking to an explicitly selected skills directory; only use it after confirming that the agent will load that directory.

Save its JSON output as `audit-data/<client>/skill-preflight.json`. Record the release, selected skill paths, hashes, results, and fresh-session confirmation in the Ledger. A successful disk check does **not** prove that a running agent has refreshed its registered skill instructions. After installing or changing skills, checkpoint and start a fresh agent session, then confirm the selected paths before invoking them. Do not report an update as applied merely because a command ran.

The old editor name `edit-conversion-safe-blogs` maps to `remove-ai-slop-without-removing-ctas-and-good-marketing-copy`; use the published name. Use the two published analysis variants instead of old local `schema`, `schema-markup`, or `ai-seo` copies. `schema-detector` is not required: the published schema variant plus the two validators cover that step.

**Check delivery dependencies at the start:** a missing `claim-check` package or script blocks the delivery QA gate. Record it immediately, install the complete package, and verify it before marking delivery ready. Independent data collection may continue while it is blocked. Manual trend analysis must be labelled manual; it does not establish that `trend-scan` is installed. The conditional editor still requires its complete package when AI-written pages are in scope.

**SXO and drift setup:** a skill entrypoint alone is insufficient. If using `seo-sxo`, add `--with-sxo` to the checker; if capturing or comparing with `seo-drift`, add `--with-drift`. Use both flags when running both, and pass `--seo-bundle "<bundle>"` with the complete upstream repository root. The checker verifies the selected skill, the shared `fetch_page.py`, `parse_html.py`, and `render_page.py` files, and (for drift) `drift_baseline.py` and `drift_compare.py`. It checks managed runtime and Chromium readiness, then starts the scripts with `--help` in that runtime. It does not fetch pages or prove that a baseline was saved.

Obtain the complete shared script bundle from [the upstream repository](https://github.com/AgriciDaniel/claude-seo), following its current installation instructions, and record the source revision. Do not assume a skill-only CLI install includes repository-level scripts. Keep `requirements.txt` at the **repository root**, alongside `scripts/`; copying only `scripts/` breaks managed setup. Install the selected skill's complete folder (including references) for your agent and resolve its commands to this same bundle.

Replace `<bundle>` below with the real repository path. These Python entrypoint commands work in PowerShell and POSIX shells; the upstream Bash launcher `<bundle>/scripts/claude-seo setup` and `doctor --json` are alternatives when Bash is available:

```bash
python "<bundle>/scripts/runtime.py" setup
python "<bundle>/scripts/runtime.py" doctor --json
python check-skills.py --project . --standalone --with-sxo --with-drift --seo-bundle "<bundle>"
```

Omit `--standalone` when using our orchestrator, and omit the optional flag for any step not being run. Require **both** `ready: true` and `browser_ready: true`; a zero doctor exit code alone can still mean Chromium is missing. Use `python "<bundle>/scripts/runtime.py" run <script.py> ...` for subsequent commands so they use the managed environment, rather than the system Python. Then verify an actual rendered fetch on a target page (`run render_page.py <url> --mode always --json`): check its status, error, `mode_used`, and content. Preflight success does not substitute for this evidence.

If setup is incomplete, record the affected step as unavailable and continue independent audit work. A manual SERP/page-type review is a separately labelled fallback; for CSR/hybrid/unknown pages it needs rendered evidence, not just response HTML. Even a static page requires an explicit response-versus-rendered comparison before treating response HTML as sufficient. A hand-built JSON snapshot is manual evidence, **not** a completed `/seo-drift` baseline; retain the setup action for the next cycle.

### Missing browser or PageSpeed quota: continue with explicit limits

Playwright is one browser option, not a global audit gate. Test whichever browser capability the agent actually has; if none can access authenticated tools, request GSC/GA4 CSV exports through F-FILE and continue public crawl, source, sitemap, and supplied-file analysis. Record browser-only/rendered checks as unavailable until evidence arrives. Do not infer a rendering pass from raw HTML. Tool unavailability is a limitation of this audit environment, not evidence that the client's website is broken.

For PageSpeed HTTP 429, record the response and URL/strategy, check for an already configured `PAGESPEED_API_KEY` or `GOOGLE_API_KEY` without displaying either value. Prefer the dedicated PageSpeed key; if absent or unusable, try the existing Google key once. Pass the selected value as the API key and verify the response: its environment-variable name does not guarantee that PageSpeed is enabled, permitted by key restrictions, or within quota. Redact keys from commands, URLs, logs, and saved evidence. Do not repeatedly call the same anonymous endpoint. A new key is optional and does not guarantee quota. Try a human-supplied PageSpeed report or local Lighthouse when Chrome and the runtime are available; neither requires Playwright. Keep Lighthouse lab measurements separate from field Core Web Vitals. If no route is available, record Performance as **not measured** and continue the audit. Ask once for the missing evidence; do not wait indefinitely or create cloud accounts during the audit.

A report may be delivered with these explicitly documented evidence gaps once the applicable analysis and claim-check QA are complete. Mark affected collection rows unavailable with their reason and collection action; do not mark them passed. With missing performance or other category evidence, show measured categories but **withhold the overall 0–100 Health Score** until its inputs exist. Do not substitute zero, invent a score, or silently redistribute weights. This evidence-gap rule takes precedence over instructions elsewhere to display a total score or wait for every collection row.

Sources: [PageSpeed API setup](https://developers.google.com/speed/docs/insights/v5/get-started) and [Lighthouse execution options](https://developer.chrome.com/docs/lighthouse/overview).

## Prime Directive (every invocation)
1. Run the release and complete-package checks above at every session start; record their evidence in the Ledger. Then read runbook §0 (how to operate) and §2 (Progress Ledger — your only memory across sessions).
2. Read §2.3 Blockers — action anything the human has just unblocked, first.
3. **Your one and only deliverable is `<client-slug>-seo-audit-YYYY-MM-DD.md`.** Never fix code, change the site, "set things
   up", or create other files during the audit — every fix and every missing setup becomes a
   *written recommendation*. (Runbook Prime Directive #1.)
4. **Update the Ledger after every item, before the next one.** Echo "Ledger: item N → ✅" in chat.

## Subcommands

### (no argument)
Read the Ledger. Fresh audit (header unset, all ⬜) → run `begin`. Otherwise report status and ask
whether to continue from here or jump to a phase.

### begin
Kickoff & Preflight (§1.4–§1.5):
- Confirm `squirrel audit --help`. Test any available browser tool; if absent, use manual exports for authenticated data and continue independent collection. Browser absence and PageSpeed 429 are evidence gaps, not global audit gates.
- Ask all **8 kickoff items** in one message: URL, site stage, **competitors (never guess)**, GA4
  property, data folder (only when the default cannot be used), **target persona**, major site changes,
  and **"Have you used AI to write any of your pages?"** **Hard gate** — don't begin collection until
  competitors and persona are answered; do not begin Phase 2 until the AI-writing answer is resolved.
- Record answers in the Ledger header. Run **Squirrel Scan immediately** (mandatory before any skills).

### collect
Phase 1 (§3) in Ledger order — Playwright for GSC/GA4, CLI for Squirrel Scan, public API for PSI.
After each item: save data → tick the Ledger → echo it.
- **A missing measurement is a finding, not a skip.** If GA4, conversion tracking, GSC, or a
  keyword-volume source isn't set up, record a **Tier 1 "set it up" action** with beginner steps
  (§3.3) — never set it up live, never silently skip it.

### skills
Phase 2 (§4) — invoke the **five** analysis skills in order, feed each the relevant data, save to
`audit-data/<client>/skills/<skill>.md`, and tick §2.2. Before each: "Running [skill]. Data: […]."
1. `/programmatic-seo` — first; later skills reference its clusters
2. `/ai-seo-better-than-corey-haines`; save to `skills/ai-seo.md`
3. `/site-architecture` — uses the clusters from skill 1
4. `/schema-markup-better-than-corey-haines`; save to `skills/schema-markup.md` — uses Squirrel Scan data
5. `/competitors`; save to `skills/competitor-alternatives.md` — needs confirmed competitors (hold 🙋 if not)

If the kickoff answer says AI was used, invoke the installed `/remove-ai-slop-without-removing-ctas-and-good-marketing-copy` skill
from `BigChrisCooke/seo-playbook-skills` before the SaaS-gap checklist.
Follow its complete workflow on audit copies of every identified page (or the documented representative
sample), preserve and verify CTAs/links/offers/positioning/proof/capability claims, and save evidence under
`audit-data/<client>/skills/remove-ai-slop-without-removing-ctas-and-good-marketing-copy/` with a synthesis summary at
`skills/remove-ai-slop-without-removing-ctas-and-good-marketing-copy.md`. Never edit the live site, CMS, or repository source. If the answer
is no, mark the Ledger row skipped with that reason; if unresolved, hold it 🙋 and never infer authorship
with an AI detector.

Then **you run the SaaS-specific gap checklist yourself** (the role of the old `seo-audit` analysis
skill, folded in here): missing SaaS content types (comparison / alternative / glossary / feature-depth
pages), INP risk from blocking scripts, crawl-budget fragmentation, and AI-writing quality risks —
cross-referencing all five skill outputs. See methodology **Phase 2 (`/seo-audit`)** for the full checklist.

### score
Withhold the overall score if a required category is unmeasured, per the evidence-gap rule above. Otherwise compute the 0–100 **SEO Health Score per runbook §5.6** — seven weighted categories (Content 22% /
Technical 20% / On-Page 18% / Performance 12% / Schema 10% / AI Visibility 10% / Programmatic 8%),
the severity tiers, and the honest **calibration caveats** (it's a consultant's assessment, *not* a
Google ranking factor; not comparable across sites; don't chase the number). Produce the per-category
table and name the two highest-impact levers. §5.6 is the source of truth — don't re-derive weights here.

### synthesize
Phase 3 (§5.1): collect all skill outputs → **deduplicate** (multiple skills surface the same finding —
keep the most detailed, strip the rest) → cross-reference every recommendation against real data
(drop generic ones) → assign tier / impact (1–5) / effort (t-shirt size). **No "owner" field** — this
tool doesn't know the client's team, so don't invent one. Write the 90-day plan first.

### report
Assemble `<client-slug>-seo-audit-YYYY-MM-DD.md` per §5.2, then pass the **§5.4 QA gate** before marking complete. Write it in
**plain, beginner-friendly English** (explain jargon) and **open with the "if you get stuck, just ask
your AI assistant" line**. Structure:
1. Title + scope + data sources
2. **SEO Health Score** + per-category table (§5.6)
3. Leadership Summary
4. Executive Summary — reframing finding first (§5.3)
5. 90-Day Execution Plan — actions not findings; mandatory Deprioritized group; end **This Quarter**
   with *trial a keyword tool (Ahrefs / Surfer SEO / Mangools)*
6. Top Revenue Opportunities (≤5)
7. Key Findings (+ SXO block if run)
8. Additional Findings from Skills
9. Security & Platform Risk — only genuinely exploitable issues; don't raise alarm over static-site headers
10. What NOT to Do
11. Prioritized Recommendations — each once: `#N. Title / Impact / Effort / Issue / Actions / Verification`
12. Programmatic SEO — launch-order table only
13. Verification & Tracking — **SEO is iterative: re-run every ~2 weeks** (work verified at 2 weeks;
    ranking gains at 4–8) + the Health-Score re-run tracker
14. Appendices — noise, not overflow

### drift
Phase 4 (methodology) — retainer / migration only; skip for one-off audits. `/seo drift baseline`
after Tier 1 ships; `/seo drift compare` monthly.

### status
Read the Ledger and report done ✅ / in-progress ⏳ / blocked 🙋 / skipped ⏭️, the Blockers queue (§2.3),
and the session log (§2.5). No action — status only.

## Standing rules (never violate)
1. **Finish the report; don't perform the work.** No edits, no new files beyond the dated report + `audit-data/`.
   The audit ends when the dated report passes the QA gate; only implement fixes if the human explicitly asks *after* reading it.
2. **Keep the Ledger live** — update after every item.
3. **Never guess competitor names or the target persona.** Ask and wait; mark 🙋.
4. **Research, don't assert; verify before you claim.** Demand data behind every content recommendation
   (or label it a hypothesis); don't present derived numbers as platform totals; don't turn tiny counts
   into scary percentages; verify "missing / broken / fixed" against the live page. (§5.1 claims discipline.)
5. **Squirrel Scan is mandatory before any skills.**
6. **Right-size to the data** — thin data → short report; no padding.

## Reference files
- `seo-audit-runbook.md` — executable workflow (HOW) + Ledger + Prime Directive.
- `seo-audit-methodology.md` — reference manual (WHY): scoring (§5.6), report design, calibration, and the SaaS-gap checklist.
