AI Search Audit (Lite) skill

AI Search Audit (Lite) — ai-search-audit — Demo/output image published by the author (repo README): AI Search Audit Lite on the Vectorscope page: the headline, the three cards, the findings to review first and where they are

Illustration · not a resultFrom the Olexan-art/ai-search-audit README — shows the whole collection, not only this skill.source ↗

Audits 1 public web page for search and AI search (SEO and GEO): robots.txt for Googlebot and AI crawlers (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot), noindex, snippets, title, headings, canonical, structured data, hreflang, how an AI retriever reads the page, and what the agent's model knows about the brand.

by Olexan-art·MIT license·★ 2 Stars on the repo·GitHub ↗

Use now

Files of AI Search Audit (Lite)

Olexan-art/main1 file shown
SKILL.md
Show the full text128 lines

Version 2.110. The first number changes only on a breaking change.

AI Search Audit (Lite)

Purpose

The skill checks 1 public page against the published rules for crawling, indexing and quoting by Google, Bing and AI assistants, and writes 1 report. You add 4 judgement files; the report marks those findings as your judgement, with your model's name. The report lists problems only, with no explanations and no fixes.

Requirements

  • Node 20.18 or later (node --version). If it is missing or older, tell the user and stop.
  • No install: dist/read.mjs and dist/audit.mjs (with dist/chunks/) are bundled.
  • $SKILL is the folder of this SKILL.md: ${CLAUDE_SKILL_DIR} in Claude Code; on claude.ai, the sandbox path you read this file from.
  • Work in a writable directory of your own.
  • Network: the page and a capped set of its site's files, links and images; first 1 DNS lookup and 1 RDAP request to rdap.org (sends the site's IP address only). Nothing is uploaded: no server of ours, no account.

Rules

  • R1. Answer the user in the language they wrote in.
  • R2. Never re-create the audit by hand. If the scripts cannot run, tell the user what would make them run, and stop. Do not fetch or check the page another way.
  • R3. Write every JSON file with the file-writing tool, never a shell heredoc (heredocs break on apostrophes).
  • R4. Never write Russian.
  • R5. The scripts call no model. Do not add a score of your own.
  • R6. Use a saved copy (--html) only when the user gives you one. Never make one with a browsing or fetch tool.
  • R7. After a refusal, do not retry another URL unless the user asks.
  • R8. Do not volunteer fixes. If the user asks, answer from your own knowledge and say the advice is yours, not the report's. The full version is from GetLoopLoop (https://www.getlooploop.com).

Procedure

  1. Read the page (script). node "$SKILL/dist/read.mjs" <url> --out reading.json
    • Options: --render compares with a JavaScript render in a local Chrome or Chromium (an empty app shell is rendered without it); --save-html page.html keeps the fetched copy.
    • Saved copy: --html saved.html --final-url <url> (and --robots saved-robots.txt). Nothing is fetched; network checks are reported as not measured.
    • Result: reading.json and reviews.template.json; prints every cap hit.
    • On failure: REFUSED <code> (exit code 2). See Refusal codes.
  2. Write questions.json and style.json (judgement). Read the text of every passage in reading.json (vs.passages) in full. Write 8 to 12 spoken questions and judge each against the passages. Mark every passage specific or generic.
  3. Write brand.json (judgement). Name the site's own brand. Answer the 5 fixed questions from your own knowledge only.
  4. Write reviews.json (judgement). Fill in reviews.template.json and write it as reviews.json.
  5. Check the files (script). node "$SKILL/dist/audit.mjs" reading.json --questions questions.json --style style.json --brand brand.json --reviews reviews.json --check
    • Result: validates the 4 files; writes nothing. A warning line is advice, not a refusal.
    • On failure: REFUSED <file>: <reason>. Fix that file as the message says and run step 5 again.
  6. Write the report (script). node "$SKILL/dist/audit.mjs" reading.json --questions questions.json --style style.json --brand brand.json --reviews reviews.json --html report.html --md report.md --json export.json
    • Add --keyword "phrase" when the user gave a target keyword; otherwise the keyword comes from the h1.
    • Result: the 3 files; prints the problems numbered as on the map, judgement findings marked (judgement).
  7. Show the report. Required; see Show the report.

Judgement files

Read references/judgement-files.md before you write them: schemas, examples, full rules.

  • All 4: agent (for example "Claude Code", "claude.ai", "Codex", "opencode", "Hermes") and model, at most 60 characters each. If you do not know one, leave it out. Never guess either.
  • Letters: the script refuses a letter Russian uses and the page's language does not (on a Ukrainian page, the 4 Russian-only letters; Bulgarian and Belarusian keep their own). Quotes are checked against the passage.
  • questions.json: 8 to 12 spoken, first-person questions in the page's language.
    • axes: 1 to 3 of urgency, device, object, obstacle; each axis used at least once.
    • Most without the page's keyword. No wake words. None that is another with words added. At least 1 the page probably does not answer.
    • Judge from the passages only, never from what you know. passage: the index of a passage in vs.passages (0-based), or null. verdict: complete, partial or missing.
    • quote: verbatim from the passage, at most 400 characters, none for missing.
  • style.json: 1 verdict per passage: generic (fits a competitor's page with the brand name changed) or specific. evidence: verbatim, at most 200 characters. Judge the passage, not who wrote it: this is not an AI detector.
  • brand.json: basis: "own_knowledge"; answer what_is, pricing, integrations, weaknesses, alternatives in English or the page's language.
    • Not sure (for example a price range): "knows": true, and write "I am not sure" in the answer.
    • Do not know: "knows": false, "answer": "".
    • The script sets knows to false when the first 400 characters disclaim knowledge ("I don't have information", "I'm not familiar", "I don't know of"). "I am not sure" does not.
  • reviews.json: basis: "own_knowledge"; every platform of the template once, none added or removed; "knows": true with a rating on its scale, or "knows": false. Judge each platform separately, from your own knowledge of the brand on that platform.
  • Honesty (brand and reviews): answer from what you already knew. No browsing, search, fetch or other tool; not from the page. "I don't know" is a correct answer. Do not present a guess as a fact or copy the page into an answer.

Verification

  • Every JSON file was written with the file-writing tool.
  • Step 5 printed no REFUSED.
  • report.html exists.

Show the report

Required. The HTML report is the result; a chat message alone, or the file name alone, has not shown it.

If the user or caller said not to publish or open anything, stop when the HTML file exists and give its absolute path. This overrides the bullets below.

Present one file: report.html. Keep report.md and export.json beside it; do not present, attach, open or preview them. Never open or preview export.json or report.md as the result, and never end the reply on either: the HTML is the report. If the environment shows the last file you present, it must be the HTML.

  • claude.ai or the Claude desktop app: save the 3 files where your instructions say user files go, and present only report.html as a file in your reply, not even followed by the others. A file in a scratch folder the user cannot see is not shown. Do not retype the report into an artifact.
  • Claude Code: publish only report.html with an HTML or artifact publishing tool, if the session has one, and give the link. Otherwise open it: start "" "<absolute path>" (Windows), open "<absolute path>" (macOS), xdg-open "<absolute path>" (Linux), and give the path.
  • Codex, opencode, Hermes Agent or any other agent: give the absolute path of report.html and offer to open it with the command above or a preview tool. Preview only the HTML. Name the other 2 files only if the user asks for the data.

The report makes no network requests. It opens in English and in the light theme; add #lang=uk, #lang=pl or #theme=dark (for example report.html#lang=pl&theme=dark). Give the #lang link when the user writes in Ukrainian or Polish.

Chat summary

  • First, if present: ai_search_blocked, search_engine_blocked, robots_unreachable, snippet_blocked or noindex.
  • The verdict line and the counts by severity.
  • Problems 1 to 5, each with its place.
  • Every cap the audit printed (links past 30, images past 20, alternates past 10, child sitemaps past 5, merged sections, a render that could not run).
  • Once: the checks are deterministic; the questions, brand and reviews are your judgement as 1 model (name it), not what ChatGPT, Gemini or Perplexity say (the web Brandscope and Reviewscope ask 3 assistants).
  • 1 line: Pattern score and band, marker words per 1,000, passages you judged generic (derived, derived, your judgement). Never say the page was or was not written by AI.
  • Never claim an assistant has indexed, ranks or will cite the page.

Refusal codes

Code Tell the user
invalid_url Not a web address. Ask for the full URL.
blocked_scheme Only http and https pages can be read.
blocked_host, blocked_address Not a public page: localhost, a private network or a non-standard port.
unreachable The page could not be reached. Read references/network-and-limits.md.
http_error An error status (in the reading), or more than 5 redirects.
blocked The site turns automated readers away (HTTP 401, 403 or 429). Retrying will not help.
not_html A file such as a PDF or an image, not an HTML page.
too_large Over the 3 MB ceiling.
empty No readable text after navigation and boilerplate were removed.
refused_ru_domain A Russian domain zone (.ru, .su, .рф, .москва, .moscow); not fetched.
refused_ru_hosting Hosted in Russia (RDAP country RU); not fetched.
refused_ru_audience The site declares a Russian-language version (hreflang, og:locale or Content-Language).
refused_language_ru The page is in Russian.

On a refused_ru_* or refused_language_ru code: skip steps 2 to 5, run step 6 without the judgement files, show the report, tell the user in 1 line that this tool does not analyse such pages (the code's line), and stop. Do not analyse the page another way.

References

File Read when
references/judgement-files.md Before steps 2 to 4.
references/checks.md The user asks about a finding code, tile, severity, threshold or check.
references/network-and-limits.md What is sent; a failed fetch; no network; a read-only skill folder.
references/outputs.md The user asks for the data or what a file holds.
1---
2name: ai-search-audit
3description: Audits 1 public web page for search and AI search (SEO and GEO): robots.txt for Googlebot and AI crawlers (GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot), noindex, snippets, title, headings, canonical, structured data, hreflang, how an AI retriever reads the page, and what the agent's model knows about the brand. Output: an HTML report. Use for an SEO or GEO audit of 1 page, AI search readiness, or why Google, ChatGPT or Perplexity do not show or quote a page, or when the user names ai-search-audit. For at most 50 pages, history and fix directions, use ai-search-audit-full. For passages only, use vectorscope.
4---
5 
6Version 2.110. The first number changes only on a breaking change.
7 
8# AI Search Audit (Lite)
9 
10## Purpose
11 
12The skill checks 1 public page against the published rules for crawling, indexing and quoting by Google, Bing and AI assistants, and writes 1 report. You add 4 judgement files; the report marks those findings as your judgement, with your model's name. The report lists problems only, with no explanations and no fixes.
13 
14## Requirements
15 
16- Node 20.18 or later (`node --version`). If it is missing or older, tell the user and stop.
17- No install: `dist/read.mjs` and `dist/audit.mjs` (with `dist/chunks/`) are bundled.
18- `$SKILL` is the folder of this SKILL.md: `${CLAUDE_SKILL_DIR}` in Claude Code; on claude.ai, the sandbox path you read this file from.
19- Work in a writable directory of your own.
20- Network: the page and a capped set of its site's files, links and images; first 1 DNS lookup and 1 RDAP request to `rdap.org` (sends the site's IP address only). Nothing is uploaded: no server of ours, no account.
21 
22## Rules
23 
24- R1. Answer the user in the language they wrote in.
25- R2. Never re-create the audit by hand. If the scripts cannot run, tell the user what would make them run, and stop. Do not fetch or check the page another way.
26- R3. Write every JSON file with the file-writing tool, never a shell heredoc (heredocs break on apostrophes).
27- R4. Never write Russian.
28- R5. The scripts call no model. Do not add a score of your own.
29- R6. Use a saved copy (`--html`) only when the user gives you one. Never make one with a browsing or fetch tool.
30- R7. After a refusal, do not retry another URL unless the user asks.
31- R8. Do not volunteer fixes. If the user asks, answer from your own knowledge and say the advice is yours, not the report's. The full version is from GetLoopLoop (https://www.getlooploop.com).
32 
33## Procedure
34 
351. **Read the page (script).** `node "$SKILL/dist/read.mjs" <url> --out reading.json`
36 - Options: `--render` compares with a JavaScript render in a local Chrome or Chromium (an empty app shell is rendered without it); `--save-html page.html` keeps the fetched copy.
37 - Saved copy: `--html saved.html --final-url <url>` (and `--robots saved-robots.txt`). Nothing is fetched; network checks are reported as not measured.
38 - Result: `reading.json` and `reviews.template.json`; prints every cap hit.
39 - On failure: `REFUSED <code>` (exit code 2). See *Refusal codes*.
402. **Write questions.json and style.json (judgement).** Read the `text` of every passage in `reading.json` (`vs.passages`) in full. Write 8 to 12 spoken questions and judge each against the passages. Mark every passage `specific` or `generic`.
413. **Write brand.json (judgement).** Name the site's own brand. Answer the 5 fixed questions from your own knowledge only.
424. **Write reviews.json (judgement).** Fill in `reviews.template.json` and write it as `reviews.json`.
435. **Check the files (script).** `node "$SKILL/dist/audit.mjs" reading.json --questions questions.json --style style.json --brand brand.json --reviews reviews.json --check`
44 - Result: validates the 4 files; writes nothing. A `warning` line is advice, not a refusal.
45 - On failure: `REFUSED <file>: <reason>`. Fix that file as the message says and run step 5 again.
466. **Write the report (script).** `node "$SKILL/dist/audit.mjs" reading.json --questions questions.json --style style.json --brand brand.json --reviews reviews.json --html report.html --md report.md --json export.json`
47 - Add `--keyword "phrase"` when the user gave a target keyword; otherwise the keyword comes from the h1.
48 - Result: the 3 files; prints the problems numbered as on the map, judgement findings marked `(judgement)`.
497. **Show the report.** Required; see *Show the report*.
50 
51## Judgement files
52 
53Read `references/judgement-files.md` before you write them: schemas, examples, full rules.
54 
55- **All 4:** `agent` (for example "Claude Code", "claude.ai", "Codex", "opencode", "Hermes") and `model`, at most 60 characters each. If you do not know one, leave it out. Never guess either.
56- **Letters:** the script refuses a letter Russian uses and the page's language does not (on a Ukrainian page, the 4 Russian-only letters; Bulgarian and Belarusian keep their own). Quotes are checked against the passage.
57- **questions.json:** 8 to 12 spoken, first-person questions in the page's language.
58 - `axes`: 1 to 3 of `urgency`, `device`, `object`, `obstacle`; each axis used at least once.
59 - Most without the page's keyword. No wake words. None that is another with words added. At least 1 the page probably does not answer.
60 - Judge from the passages only, never from what you know. `passage`: the `index` of a passage in `vs.passages` (0-based), or `null`. `verdict`: `complete`, `partial` or `missing`.
61 - `quote`: verbatim from the passage, at most 400 characters, none for `missing`.
62- **style.json:** 1 verdict per passage: `generic` (fits a competitor's page with the brand name changed) or `specific`. `evidence`: verbatim, at most 200 characters. Judge the passage, not who wrote it: this is not an AI detector.
63- **brand.json:** `basis: "own_knowledge"`; answer `what_is`, `pricing`, `integrations`, `weaknesses`, `alternatives` in English or the page's language.
64 - Not sure (for example a price range): `"knows": true`, and write "I am not sure" in the answer.
65 - Do not know: `"knows": false`, `"answer": ""`.
66 - The script sets `knows` to false when the first 400 characters disclaim knowledge ("I don't have information", "I'm not familiar", "I don't know of"). "I am not sure" does not.
67- **reviews.json:** `basis: "own_knowledge"`; every platform of the template once, none added or removed; `"knows": true` with a `rating` on its scale, or `"knows": false`. Judge each platform separately, from your own knowledge of the brand on that platform.
68- **Honesty (brand and reviews):** answer from what you already knew. No browsing, search, fetch or other tool; not from the page. "I don't know" is a correct answer. Do not present a guess as a fact or copy the page into an answer.
69 
70## Verification
71 
72- [ ] Every JSON file was written with the file-writing tool.
73- [ ] Step 5 printed no `REFUSED`.
74- [ ] `report.html` exists.
75 
76## Show the report
77 
78Required. The HTML report is the result; a chat message alone, or the file name alone, has not shown it.
79 
80If the user or caller said not to publish or open anything, stop when the HTML file exists and give its absolute path. This overrides the bullets below.
81 
82**Present one file: `report.html`.** Keep `report.md` and `export.json` beside it; do not present, attach, open or preview them. Never open or preview `export.json` or `report.md` as the result, and never end the reply on either: the HTML is the report. If the environment shows the last file you present, it must be the HTML.
83 
84- **claude.ai or the Claude desktop app:** save the 3 files where your instructions say user files go, and present **only `report.html`** as a file in your reply, not even followed by the others. A file in a scratch folder the user cannot see is not shown. Do not retype the report into an artifact.
85- **Claude Code:** publish only `report.html` with an HTML or artifact publishing tool, if the session has one, and give the link. Otherwise open it: `start "" "<absolute path>"` (Windows), `open "<absolute path>"` (macOS), `xdg-open "<absolute path>"` (Linux), and give the path.
86- **Codex, opencode, Hermes Agent or any other agent:** give the absolute path of `report.html` and offer to open it with the command above or a preview tool. Preview only the HTML. Name the other 2 files only if the user asks for the data.
87 
88The report makes no network requests. It opens in English and in the light theme; add `#lang=uk`, `#lang=pl` or `#theme=dark` (for example `report.html#lang=pl&theme=dark`). Give the `#lang` link when the user writes in Ukrainian or Polish.
89 
90## Chat summary
91 
92- First, if present: `ai_search_blocked`, `search_engine_blocked`, `robots_unreachable`, `snippet_blocked` or `noindex`.
93- The verdict line and the counts by severity.
94- Problems 1 to 5, each with its place.
95- Every cap the audit printed (links past 30, images past 20, alternates past 10, child sitemaps past 5, merged sections, a render that could not run).
96- Once: the checks are deterministic; the questions, brand and reviews are your judgement as 1 model (name it), not what ChatGPT, Gemini or Perplexity say (the web Brandscope and Reviewscope ask 3 assistants).
97- 1 line: Pattern score and band, marker words per 1,000, passages you judged generic (derived, derived, your judgement). Never say the page was or was not written by AI.
98- Never claim an assistant has indexed, ranks or will cite the page.
99 
100## Refusal codes
101 
102| Code | Tell the user |
103|---|---|
104| `invalid_url` | Not a web address. Ask for the full URL. |
105| `blocked_scheme` | Only http and https pages can be read. |
106| `blocked_host`, `blocked_address` | Not a public page: localhost, a private network or a non-standard port. |
107| `unreachable` | The page could not be reached. Read `references/network-and-limits.md`. |
108| `http_error` | An error status (in the reading), or more than 5 redirects. |
109| `blocked` | The site turns automated readers away (HTTP 401, 403 or 429). Retrying will not help. |
110| `not_html` | A file such as a PDF or an image, not an HTML page. |
111| `too_large` | Over the 3 MB ceiling. |
112| `empty` | No readable text after navigation and boilerplate were removed. |
113| `refused_ru_domain` | A Russian domain zone (.ru, .su, .рф, .москва, .moscow); not fetched. |
114| `refused_ru_hosting` | Hosted in Russia (RDAP country RU); not fetched. |
115| `refused_ru_audience` | The site declares a Russian-language version (hreflang, og:locale or Content-Language). |
116| `refused_language_ru` | The page is in Russian. |
117 
118On a `refused_ru_*` or `refused_language_ru` code: skip steps 2 to 5, run step 6 without the judgement files, show the report, tell the user in 1 line that this tool does not analyse such pages (the code's line), and stop. Do not analyse the page another way.
119 
120## References
121 
122| File | Read when |
123|---|---|
124| `references/judgement-files.md` | Before steps 2 to 4. |
125| `references/checks.md` | The user asks about a finding code, tile, severity, threshold or check. |
126| `references/network-and-limits.md` | What is sent; a failed fetch; no network; a read-only skill folder. |
127| `references/outputs.md` | The user asks for the data or what a file holds. |
128 

Discussion

Alternatives

Agentic Browsing ReadinessAudit and fix agent readiness: the Lighthouse Agentic Browsing fraction, accessibility tree for agents, robots.txt and Content-Signal for AI agents, WAF treatment of agent traffic, llms.txt, Markdown delivery, ai-catalog.json, /.well-known discovery files, and WebMCP tools. Exclude AI citability and brand signals (seo-geo) and commerce protocol depth (seo-ecommerce).Marketing · MITBacklink Profile AnalysisBacklink profile analysis: referring domains, anchor text distribution, toxic link detection, competitor gap analysis. Works with free APIs (Moz, Bing Webmaster, Common Crawl) and DataForSEO extension. Use when user says backlinks, link profile, referring domains, anchor text, toxic links, link gap, link building, disavow, or backlink audit.Marketing · MIT/setup-cmsConnect a CMS to notfair SEO tools. Guides users through configuring WordPress, Strapi, Contentful, or Ghost — tests the connection, and writes credentials to .env.local. Once set up, seo-analysis automatically cross- references CMS content against Google Search Console data. Use whenever the user says "connect my CMS", "set up WordPress", "configure Strapi", "add Contentful", "connect Ghost", or "CMS setup". Also trigger if the user asks why no CMS data appears in a seo-analysis report. · MITBacklink checkBacklink profile for any domain — referring domains, authority, anchors, new/lost links, and a side-by-side vs a competitor. Use when asked "check my backlinks", "backlink profile of X", "who links to them", or "link gap vs competitor".Marketing · MIT