---
name: om-geo-audit
description: >-
  Audit the agentic/AI-search visibility of a website — AI bot allowlist in
  robots.txt, llms.txt presence and format, an Agentic Resource Discovery (ARD)
  manifest, canonical/pagination correctness, Article/NewsArticle structured
  data, og:image minimum size, sitemap orphans, and content reachable without
  JavaScript. Use this when asked to check, grade, or report on how discoverable
  and citable a site is to AI crawlers and answer engines (GPTBot, ClaudeBot,
  PerplexityBot, OAI-SearchBot, etc.) — not classic keyword SEO.
---

# om-geo-audit

Published by [OMKomUnity](https://omkomunity.ai) — distilled from the build
gates that guard omkomunity.ai itself (`check-orphans`, `check-prerender-content`,
`qa-mobile`, OnCrawl crawl diffing). This skill is **detection only**: it tells
you what's broken and why it matters to an AI agent, not how to fix it — fixes
are OMKomUnity's consulting work.

## Why this differs from a classic SEO audit

A search crawler and an AI agent don't read a page the same way. An agent may
fetch once, with no JS execution, no retry on a redirect loop, and it decides
*whether to cite you* based on what it got in that one fetch — not on rank.
The controls below target that failure mode specifically.

## Controls

For each control: what to fetch, what a pass looks like, what a failure means.

### 1. AI bot allowlist in `robots.txt`
Fetch `/robots.txt`. For each of these user-agents, require an explicit
`Allow: /` (or no blocking `Disallow`): `GPTBot`, `ClaudeBot`, `Google-Extended`,
`Applebot-Extended` (foundation-model training, all respect robots.txt),
`OAI-SearchBot`, `ChatGPT-User`, `Claude-SearchBot`, `Claude-User`,
`PerplexityBot`, `Perplexity-User` (real-time fetch/citation — the actual GEO
traffic). A wildcard `Disallow: /` with no per-bot override silently opts a
site out of being cited, with zero error anywhere a human would see it.

### 2. `llms.txt`
Fetch `/llms.txt`. Pass = present, one H1, one blockquote summary, H2 sections
of markdown links (format: llmstxt.org). A missing file is not a failure by
itself — the spec is optional — but if present it must be well-formed.
Working assumption, not a vendor-documented behavior: treat a malformed file
as worse than none, since a strict parser can abandon the whole file on the
first error rather than reading the valid part.

### 3. Agentic Resource Discovery manifest
Fetch `/.well-known/ard.json` (and, for Lighthouse 13.5-era tooling, the
predecessor path `/.well-known/ai-catalog.json`). Pass = valid JSON,
`Content-Type` that isn't `text/html` (a redirect to an SPA shell returning
200 + HTML is the single most common failure here — the manifest URL "exists"
but every validator reads a malformed-JSON error), and every declared
`entries[].identifier` resolves. An **empty** `entries` array is honest and
valid if the site genuinely exposes no MCP server, A2A agent, registry, or
`application/ai-skill+md` resource yet — don't flag it as a failure, flag only
a manifest that's unreachable or lies about what it exposes.

### 4. Canonical and pagination
For a sample of paginated/filtered URLs (`?page=N`, `?category=`, etc.):
compare the `<link rel="canonical">` the page declares against the URL the
server actually serves after following redirects. A mismatch
(canonical says A, server 301s or serves content at B) means an agent that
trusts the canonical tag ends up citing a URL that doesn't exist. Page 1 of a
paginated set should self-canonicalize; pages ≥2 should either self-canonicalize
(if independently valuable) or canonicalize to page 1 (if not) — never both.

### 5. Structured data (Article / NewsArticle)
For content pages (blog posts, news, dated editorial), fetch the raw HTML
(no JS) and check for `Article` or `NewsArticle` JSON-LD with at minimum
`headline`, `datePublished`, and `author`. Missing structured data doesn't
block citation, but it's the cheapest signal an agent has for "this is dated,
attributable content" vs. unstructured marketing copy.

### 6. `og:image` minimum size
Check `<meta property="og:image">` resolves to an image ≥ 1200px on its
longest edge — this repo's own threshold, aligned with Meta's generic
sharing-preview guidance (1200×630px) rather than any generative-engine
spec; no vendor publishes a citation-card image requirement. Treat it as a
quality signal, not a hard block.

### 7. Sitemap orphans
Cross-reference every URL listed in `sitemap*.xml` against inbound
`<a href>` links found in the **rendered, no-JS HTML** of every other page on
the site. A URL that's only reachable via the sitemap has no path through
normal navigation — crawlers that don't prioritize sitemap-only URLs (OnCrawl
behavior, observed) never fetch it, and an agent following links the way a
user would never finds it either.

### 8. Content present without JavaScript
Fetch a content page with JS disabled (or diff the raw HTML against the
rendered DOM). Pass = the full body text is present in the initial HTML
response, not injected by a client-side chunk after hydration. An agent that
does a single unauthenticated GET and never executes JS — the common case —
sees exactly what's in that first response. If the body loads after
hydration, the agent sees a heading and nothing else.

## Output

Report pass/fail per control, with the fetched evidence (status code,
header, or matched/missing string) — never a verdict without the raw check
that produced it. Group failures by whether they block citation entirely
(1, 3, 8) or degrade citation quality (2, 4, 5, 6, 7).

## Scope

This skill stops at diagnosis. It names what's broken and why an agent would
be affected — it does not prescribe the fix, rewrite the robots.txt, or patch
the code. Remediation is OMKomUnity's consulting engagement.
