Why I wrote the SEO Dev Spec, and what it actually decides

I wrote the SEO Dev Spec because the same question kept producing different answers depending on who was answering it. Framework defaults, old tutorials, role prompts and half-remembered blog posts disagreed about FID versus INP, about whether a content site may be a single-page app, and about whether a bare-domain redirect needed to be an explicit 301. A checklist does not settle that. A numbered rule that can be cited, tested and revised does.
This page explains why the SEO Dev Spec exists, how it was built, what it actually checks, and who should read it. It is a first-person account of one package in a public repository, not a general SEO guide. The repository is at github.com/rockyandtom/seo-dev-spec. Everything described here was checked on 2026-11-11.
01 /Why did I write a numbered rulebook?
Because a rule without an identifier gets re-litigated on every project. When two documents disagree, the person holding the keyboard decides, and the decision is invisible in the output. I wanted the decision to be visible: a rule number, a written judgement, and where possible a command that produces the evidence. That is the whole design premise of the SEO Dev Spec.
The disagreements were concrete rather than theoretical. One source said to watch FID, while the metric had already been retired in favour of INP. One said a content site could ship as a client-rendered app, while another required server-rendered HTML. One said every image should be lazy, including the first-screen image that determines LCP. One said keyword density was a vanity metric that should not be measured at all. Each of these is a decision that changes the shipped HTML, so each needed one authoritative answer rather than a preference.
I also wrote it because acceptance kept being confused with tooling. A checker that exits successfully is satisfying and nearly meaningless on its own. On 2026-10-29 I stopped using a script's exit code as the acceptance verdict after a 278-word page passed a 300-word threshold purely because navigation and footer text were counted. The SEO Dev Spec therefore separates mechanical evidence from the human reading of that evidence. The script collects. A person decides.
02 /How was the SEO Dev Spec developed?
It grew out of site work, then was made into a Skill, then cleaned for public release. Those are three distinct stages and the page keeps them separate.
The first stage was writing the rules themselves. Every rule received an identifier: three baselines prefixed Z, then nine families labelled R for rendering and crawlability, U for URLs and routing, I for internal links, T for titles and page metadata, K for the keyword map, P for programmatic-SEO gating, C for performance, D for deployment and M for 301 migration. Conflicts are resolved in an appendix table rather than by whoever argues last. Anything mechanically checkable received a command.
| Stage | What changed | Why it mattered |
|---|---|---|
| Rules first | Identifiers Z plus nine families R–M | A decision can be cited by number in a review |
| Conflict appendix | Explicit rulings for recurring disagreements | Framework defaults no longer outrank the spec silently |
| Checker | scripts/seo_check.py, standard library only | Six veto items can produce evidence without installing anything |
| Two dated revisions | v1.3 and v1.4, both 2026-11-09 | Corrections are visible instead of being folded into the text |
| Public release | Cleaned paths, English README, pushed to GitHub | The package can be read without my machine |
The second stage was revision, and both revisions are dated 2026-11-09 in the rule source. Version 1.3 moved keyword density from "vanity metric, no threshold" to a house-required check: each page declares a density_target in frontmatter, and three separate measurements are recorded rather than one convenient number. Version 1.4 added two-way anchor-text rules after an 18-page audit of a site found pages whose inbound links contained the complete target phrase zero times. That is a specific failure, and the rule names it.
| Revision | Dated | What changed | Trigger |
|---|---|---|---|
| v1.3 | 2026-11-09 | Density became a measured, per-page required check | One convenient number hid coverage gaps |
| v1.4 | 2026-11-09 | Anchor-text keyword alignment and mixed-ratio checks | 18-page audit found zero exact-phrase inbound links |
| v1.4 scope | 2026-11-09 | References, checklist and sources index updated together | A rule change that leaves its references stale is not a change |
The third stage was turning a personal Skill into a public package. I keep 19 user-level Skills on the machine behind this site, along with 87 archived WorkBuddy session directories and 256 JSONL session files. I selected 5 of those 19 for release and excluded 14: packages containing credentials, service-account dependencies, private buckets, or large build artifacts did not qualify. For the selected copies, two machine-specific absolute paths became portable $HOME forms, two hard-coded interpreter paths became python3, and eight install-path references became relative scripts/ paths. Backup and build-artifact filters ran across all copies and removed nothing, because the selected packages were already clean. A credential scan found nothing to redact. Nine files were published.
03 /What does the SEO Dev Spec actually do?
Four things, in a fixed order: it states what must not be done, gives a judgement for each item, provides an acceptance procedure, and records why each rule exists.
Three baselines sit above everything else. Main content and internal links must be present in the returned HTML rather than injected by JavaScript. One target keyword belongs to one page, recorded in a single keyword-map file. A new site does not ship bulk-generated pages. On top of those sit the nine rule families, ten launch veto items each with a copyable judgement command, and an indexing-troubleshooting decision tree covering four distinct failure modes.
The shipped checker covers six of the ten veto items. It fetches with a Googlebot user agent by default, and its subcommands are render, routes, sitemap, robots, links and audit. Exit codes are 0 for all pass, 1 for a hard failure and 2 for an argument or network error.
python3 scripts/seo_check.py audit https://your-domain.com
python3 scripts/seo_check.py render https://your-domain.com/page-a/ https://your-domain.com/page-b/
python3 scripts/seo_check.py routes https://your-domain.com --paths /about/,/blog/The repository also carries five reference notes: the ten veto items with commands, an internal-link audit procedure including template-block stripping and a 301 mapping workflow, the indexing decision tree, on-page copywriting notes with an explicit warning that single-page samples are not norms, and a per-rule source index that records rejected sources and the reasons. There is an assets/keyword-map.csv template, because the one-page-one-keyword rule is useless without a file to enforce it.
04 /Who should use the SEO Dev Spec?
Read it before building or changing any website, page template, URL or redirect, and run the checker at the acceptance gate. Cite rule numbers when another document, an expert prompt or an older tutorial disagrees. It is written for people who ship pages and have to justify what shipped, including the person who reviews a release rather than the person who wrote it.
It is deliberately narrow. It does not define the order of a launch, platform-specific deployment pitfalls, or keyword and data collection; separate Skills own those. It does not replace front-end engineering quality or a complete accessibility checklist covering keyboard behaviour, contrast, form labels and ARIA. If your question is "is this page accessible", this is not the document.
| Use it for | Do not use it for |
|---|---|
| Deciding whether content may be client-rendered | Choosing a framework for an interactive dashboard |
| Settling a 301 versus 308 argument with a citation | Planning the sequence of a launch |
| Checking that internal links exist in raw HTML | Selecting keywords or pulling volume data |
| Recording per-page density measurements | Replacing a full accessibility audit |
| Accepting or blocking a release | Judging front-end code quality |
If you install Skills at all, the trust boundary matters more than the rule text; the workbuddy skills page covers permissions, and the three installation paths explain what a package can reach. The GEO AI Traffic probing workflow picks up one specific case from this spec: what happens after a site is technically sound but still never appears in an assistant's answer. My field notes record the corrections that produced these rules, and the about page states who verifies them.
05 /What are the limits of this package?
The rule source SKILL.md and its reference notes are in Chinese. The repository README is an English guide to the package, not a translation. That is a real limitation for an English-only reader, and I would rather state it than imply otherwise. The spec also names other Skills that are separate packages and are not bundled here.
The checker is a data-collection tool. A passing exit code does not replace reading the HTML and counting words, keyword occurrences, H1 and H2 structure, and internal links on real pages. This is written into the rule source itself because the failure already happened once. Rule revisions are dated; treat the version and dates in SKILL.md as the record of what changed. Everything on this page reflects the state checked on 2026-11-11.
06 /Frequently asked questions
Is the SEO Dev Spec a Google ranking factor list?
No. It is a development and acceptance specification. Some rules restate platform behaviour that is externally observable, such as redirects and returned HTML, and some are house standards with no official standing, such as the 1000-word content floor. The rule source says which are which. Nothing here claims a ranking factor that an engine has not published.
Do I need the checker to follow the rules?
No. The checker automates six of ten veto items with Python 3's standard library and no credentials. The other four need a person: duplicate target keywords across pages, whether a staging environment is publicly reachable, whether retired URLs have correct one-to-one redirects, and whether a new site's first batch was too large. The script cannot see any of those.
Why is keyword density a required check here?
Because version 1.3 changed it on 2026-11-09. Each page declares its own density_target in frontmatter, and three measurements are recorded: phrase-weighted density, frequency density, and occurrences per thousand words. The rule is about measuring and leaving a number behind, not about chasing a universal percentage. Engines have published no official threshold, and the spec does not pretend otherwise.
Can I use it on a site that is not built with WorkBuddy?
Yes. The package is a Markdown rule source, five reference notes, a CSV template and a standalone Python script. It has no dependency on any agent platform, no credentials and no private service. It was packaged as a Skill because that is how I invoke it, but the files work on their own.
07 /Where should you go next?
The four Skills released alongside this one are documented individually on this site. The paid-demand presale validation framework answers a different question entirely: whether an idea deserves to be built. The game site development record shows what happens when a fact rule is applied too broadly. Game site selection and GEO AI Traffic cover the operating phase and assistant discovery, and all five public repositories published on 2026-11-11 are listed on the about page.