The skill was the question
A site dropped out of Google. Each pass at Claude Code fixed one layer and missed the next. The fix was invoking the audit skill explicitly — same model, same codebase, a different shape of question.
Google forgets you on a Tuesday. You find out on a Thursday.
Short version, for anyone who arrived here from a search and needs the answer fast.
When you ask Claude Code to “fix the SEO” of a site that’s been deindexed, it will find one cause, fix it, and report success. The next pass finds the next cause. The pattern continues until you stop asking the model to notice things and start invoking the audit as a skill.
The skill is a written checklist the model is forced to walk: soft-404 status, canonical reciprocity, hreflang script subtags, sitemap protocol compliance, robots syntax, JS cloaking risk, structured data, cache headers, content quality per locale. One pass produces the full punch list.
Same model. Different question.
The rest of this post is how that lesson found me.
The deindex
site:arroxy.orionus.dev returned nothing. Ten days of absence before I noticed. No penalty in Search Console, no manual action, no email. The quiet kind of disappearance where the index decides you stopped existing and forgets to mention it.
I opened Claude Code and asked it to find out why.
The first cause
First pass came back fast.
GET /this-page-does-not-exist → 200 OK
Same bytes as /. Same bytes as every ghost URL Google had ever guessed at. No 404.astro in src/pages/. Cloudflare Pages’ SPA fallback was serving index.html for everything that didn’t resolve. Soft-404 across the entire surface. Google read it as mass duplicate content and dropped the property wholesale.
Added a real 404. Verified the status code:
curl -sI https://arroxy.orionus.dev/no-such-page | head -1
# HTTP/2 404
Felt done.
The next cause
It wasn’t done.
The hreflang cluster on /blog/ was declaring all 21 locales as alternates, and pointing every one of them at the corresponding locale homepage. Telling Google that the German equivalent of /blog/arroxy-vs-stacher/ was /de/. Wrong content mapping. Broken reciprocity. Google quietly drops clusters that lie.
Localized blog routes existed at /de/blog/, /ar/blog/, all responding 200, all serving English bodies with translated chrome, all stamped noindex,follow. All linked from the footer of every page. The crawl budget was bleeding into routes that had already admitted they shouldn’t be indexed.
Fixed the cluster. Pruned the dead routes. Pushed.
Felt done.
Circles
It wasn’t done.
The sitemap was hand-rolled and included /llms.txt and /pricing.md. Non-HTML resources the protocol doesn’t accept. Migrated to @astrojs/sitemap. The plugin shared its links array across each hreflang group and re-pushed x-default twenty-two times per serialize call. Patched the dedup.
Google Search Console rejected the robots.txt with a syntax error it refused to explain. The file looked clean. The validator pointed at nothing. It took longer than it should have to find:
User-agent: *
Content-Signal: search=yes, ai-input=yes, ai-train=yes
Allow: /
Content-Signal: is Cloudflare’s 2025 proposal. RFC 9309 doesn’t know it. Google and Bing flag the unknown directive without naming the line. Commented it out.
<link rel="alternate" hreflang="zh" ... /> was ambiguous. The page is Simplified Chinese. The tag could have been read as Traditional. Changed to zh-Hans. Same problem on sr. Changed to sr-Cyrl.
The JavaScript redirect at / was reading navigator.language and calling location.replace() to bounce users into their locale. Googlebot wasn’t tripping it today. Bingbot might. Yandexbot might. Crawlers don’t owe you stable behaviour. Ripped the redirect out. Replaced it with a dismissable banner.
Each pass surfaced a layer the last pass hadn’t seen. Each fix felt like the last fix.
It wasn’t.
The skill
What I had been doing wrong is the part worth writing down.
I had been asking the model to “fix the SEO.” A goal that vague returns whatever is on top of the model’s stack. The model is competent. It is not a checklist. It surfaces what it surfaces, repairs that, reports success, and moves on. The next layer is invisible until you ask again. The layer after that is invisible until you ask a third time. The session walks in circles around a property that is still broken, fixing one true thing per loop.
The fix was invoking /seo-audit as a skill, explicitly, by name. Installed from skills.sh a week earlier and forgotten about until this session.
A skill is a written checklist the model is forced to read before answering. Not because the model is smarter inside the skill. The model is the same model. The skill walks every dimension at once: soft-404 status, canonical reciprocity, hreflang script subtags, sitemap protocol compliance, robots syntax, JavaScript cloaking risk, structured data coverage, cache header parity, locale content quality. Each one a check it would have done if asked individually. None of them obvious from “fix the SEO.”
Same model. Same codebase. A different shape of question.
One pass produced the full punch list. The next pass cleared it. Sixteen Playwright cases verified the locale banner across RTL, LTR, dismiss, persistence, and click-through. The build came back green.
What the model was asking
Vague prompts get vague triage. The model isn’t lazy. It’s literal. When the goal is “fix the SEO,” the model fixes the part of the SEO it can see from where it’s standing. Standing somewhere else requires a different prompt, or someone else’s checklist held to the screen.
The general shape of the rule: if a task has a known-good audit procedure — security review, accessibility, performance, SEO, anything with a published rubric — invoke the rubric as a skill. Don’t ask the model to remember the dimensions. Ask the skill to walk them. Skills exist because models forget the boring parts. Boring parts are where deindex bugs live.
The index doesn’t come back overnight. The recovery curve is two weeks of waiting. But the property is correct now: every locale self-canonicalizes, every hreflang reciprocates, every 404 returns 404, every sitemap entry resolves to an indexable HTML page.
The thing I learned wasn’t about SEO.
The model knows everything. The model notices what you point at. The skill is the pointing.