# seo-audit-skill's results table has one row and three empty cells

> A two-tier SEO audit agent skill where Python scripts make the deterministic calls and the model makes the judgement calls. The full tier stops without a PageSpeed key, four scripts ship with no dependency file, and the results table above the skill list was never filled in.

**JeffLi1993/seo-audit-skill** — SEO agent skill for OpenClaw,Claude Code, and AI agents. Generate beginner SEO audits and advanced technical SEO reports for any page.

- Repository: https://github.com/JeffLi1993/seo-audit-skill
- Website: https://nanoskill.ai/skills/seo-audit
- Stars: 762 · Forks: 98
- Language: Python
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/jeffli1993-seo-audit-skill

## The results table above the skill list was never filled in

Between the report output section and the skills section sits a table with four columns and one row. The columns are Website, Audit Summary, Site Checks, and Page Checks and insights. The single row names colaos.ai. All three remaining cells are empty.

The output example directly above it does have content, showing a run and its result:

```
audit this page: https://openclaw.ai
→ ✅ Report saved → reports/openclaw-ai-audit.html
```

So the table is a placeholder that was scaffolded and left as it is, and it sits in the most-read position of the document, between the description of what a report contains and the list of what you can run. Nothing in the rest of the file explains what belongs in those cells, whether they were meant to hold verdicts, scores, or links to reports, or who was meant to fill them in.

It is worth naming because it is the kind of gap that makes a reader distrust the numbers next to it. The check tables below are precise about what each row verifies, and this one is the only place in the document where a claim about output quality would have been made.

## The full tier stops outright without a PageSpeed key

The two tiers are not basic and better. They are different check sets, and the larger one has a hard dependency. The note attached to seo-audit-full says it requires a Google PageSpeed Insights API key for the PageSpeed checks, that the key is read from PAGESPEED_API_KEY or GOOGLE_PAGESPEED_API_KEY or passed with a --api-key argument, and that without a key the full audit stops and asks you to configure one.

That is a defensible design. Failing at the start beats emitting a report with a silent hole in it. It does mean the seven full-only checks are unreachable without an external account.

Counting the coverage tables, the site-level split puts seven checks in both tiers: robots.txt, sitemap.xml, 404 handling, URL canonicalization, i18n and hreflang, Schema, and the trust pages. Four are full only: the sitemap URL inventory, staging subdomain indexation, GSC crawl status, and PageSpeed with Lighthouse. On the page side, ten run in both tiers and three are full only: OG and social tags, content quality, and the robots meta directives.

## Four Python scripts, no dependency file and no tests

The root of the repository holds a LICENSE, two READMEs, an assets directory, and the two skill folders. There is no dependency manifest, no package metadata, no test directory and no continuous integration configuration among the top-level entries.

The payload is four scripts, described in the layout as:

```
seo-audit-skill/
├── seo-audit/
│   ├── SKILL.md                       # Skill definition + agent workflow
│   ├── references/REFERENCE.md        # Field definitions, edge cases
│   ├── assets/report-template.html    # HTML output template
│   └── scripts/
│       ├── check-site.py              # robots.txt + sitemap → JSON
│       ├── check-page.py              # TDK + H1 + canonical + slug → JSON
│       ├── check-schema.py            # JSON-LD extraction + validation → JSON
│       └── fetch-page.py              # Raw HTML fetcher, SSRF protection
└── seo-audit-full/
    ├── SKILL.md
```

So a user installing this gets scripts whose dependencies are undeclared, and the listing shows the full tier carrying only a SKILL.md where the basic tier carries four files. A second discrepancy sits next to it: the layout places the report template inside seo-audit/assets, while the repository root also has an assets directory of its own.

The one thing the layout does tell you is that fetch-page.py carries SSRF protection, which is the check that matters most for a tool whose whole job is to fetch a URL someone pasted.

## The alt text check names no selector

One row in the page coverage table has an empty code span in it. Image Alt Text is described as an alt attribute check on all of nothing, followed by JS-render detection. The selector that was meant to sit between the backticks is missing, so the check as specified does not say what it walks.

That is a small gap with a large blast radius, because the same row is marked as running in both tiers. A script cannot check every image in a page without knowing what counts as an image element, and the JS-render detection half suggests the answer involved client-side rendering, which is exactly where a missing selector would matter most.

The rest of the table is unusually concrete by comparison. Title Tag is checked for 50 to 60 characters, keyword position, and separate rules for a homepage against an inner page. Meta Description is checked for 120 to 160 characters, keyword match, and a concrete value proposition rather than generic filler. Word Count flags body text under 500 words. Keyword Placement looks at the first 100 body words. Heading Structure targets five to seven H2s and reports the H3 to H2 ratio. Those five thresholds are the part you can check against your own pages by hand.

## The two layers hand over a flag called llm_review_required

The architecture section draws the pipeline. A URL goes into a layer of Python scripts, which emit structured JSON, and the output leaves that layer labelled as JSON plus a flag named llm_review_required, pointing at the next layer.

The justification offered for the split is that scripts handle the 80% of checks that are deterministic, with two examples given: does robots.txt exist, and is the title 55 characters. The 80% figure is asserted without a count of checks behind it, so treat it as a description of intent rather than a measurement. What is verifiable is the shape of the division. The layer boundary sits exactly where string matching stops being enough: title length and status codes are script work, while keyword intent, content quality and page type inference are named as the model's job.

One thing about the drawing is worth flagging as a documentation fact. The box for the second layer is opened but never filled in: the diagram stops at the top edge of an empty rectangle, and the text beneath it starts the why before that layer is described anywhere. So the flag name is the only precise statement about the handover you get.

## The site checks are the interesting part, and staging detection is the sharpest

Of the eleven site-level checks, the one that stands out is staging subdomain indexation, which is full tier only. It looks for public hosts beginning with test., staging., dev., preview., beta. and uat., and flags them as mirroring production and potentially indexable. That is a real operational risk rather than a search ranking nuance, since a staging copy reachable from production navigation can take index on its own.

The 404 check is the other one worth reading. It distinguishes a true 404 from a soft 404 that returns 200, and from a page that returns 301 to the homepage, which is a failure mode that passes most naive checks.

Canonicalization covers the HTTP to HTTPS redirect, www consistency, trailing slash handling, and whether the canonical tag matches the final URL. The hreflang check asks about reciprocal symmetry, BCP 47 codes, the x-default entry, duplication of the default language URL, and alignment between canonical and hreflang, which is the combination that most often contradicts itself across locales.

The sitemap check follows the Sitemap directive path declared in robots.txt and samples child sitemaps when the top-level file has none.

## Conclusion

This suits someone who wants a repeatable checklist rather than an opinion about a page, because the deterministic half of the checks is written down and visible, and the model half is confined to judgement calls that a script cannot make. Read the tier boundaries before choosing, since seven of the site checks and three of the page checks exist only in the full tier, and the full tier refuses to start without a Google PageSpeed Insights key. Two things to plan for. Four Python scripts ship with no dependency manifest and no test suite at the root, so treat the environment as yours to build. And the report is an HTML file for a human to judge, not a machine-readable verdict, which is what the project asks for when it tells you to read it yourself and keep what matters for your goals.

## FAQ

### What does the seo-audit-skill produce?

A standalone HTML report from a single URL. A basic audit is saved as reports/<hostname>-audit.html and a full audit as reports/<hostname>-full-audit.html. Sections include an audit summary with critical, warning and passing counts, site checks, page checks, the top three ranked fixes, and a walkthrough giving evidence, impact and fix for each major finding.

### Do I need an API key for the full SEO audit?

Yes. The full tier requires a Google PageSpeed Insights API key, supplied through PAGESPEED_API_KEY, GOOGLE_PAGESPEED_API_KEY, or a --api-key argument. Without a key the full audit stops and asks you to configure one rather than producing a partial report.

### Which agents can run the seo-audit-skill?

Any agent runtime that supports SKILL.md, with Claude Code and Cursor named explicitly, and the repository description also lists OpenClaw. Installation uses the skills CLI: npx skills add JeffLi1993/seo-audit-skill, followed by a prompt such as audit this page: followed by the URL.

### What is the difference between the basic and the full SEO audit?

The basic skill is the default and gives a structured report of more than twenty checks. The full skill adds PageSpeed, sitemap inventory, social tags, content quality, Search Console data and competitor gap analysis. The coverage tables mark each check per tier: seven site checks and three page checks exist only in the full tier.

### What do the Python scripts in seo-audit-skill actually check?

Four of them. check-site.py handles robots.txt and sitemap work and is described as covering the sitemap inventory and staging detection. check-page.py covers title, meta, H1, canonical and slug. check-schema.py extracts and validates JSON-LD. fetch-page.py is the raw HTML fetcher and carries SSRF protection. Each emits structured JSON to the model layer.

## Sources

- [Issues](https://github.com/JeffLi1993/seo-audit-skill/issues)
- [JeffLi1993/seo-audit-skill on GitHub](https://github.com/JeffLi1993/seo-audit-skill)
- [License: MIT](https://github.com/JeffLi1993/seo-audit-skill/blob/main/LICENSE)
- [Project website](https://nanoskill.ai/skills/seo-audit)
- [README](https://github.com/JeffLi1993/seo-audit-skill/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jeffli1993-seo-audit-skill
