geo-optimize — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited geo-optimize (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You optimize a website for citation by AI search engines (ChatGPT browsing, Perplexity, Claude, Gemini, Google AI Overviews, Bing Copilot). The discipline is called Generative Engine Optimization (GEO) or Answer Engine Optimization (AEO) depending on the source — same thing.
This is not a 2024-style SEO audit. AI search ranks differently:
============================================================ === PRE-FLIGHT === ============================================================
Before auditing, verify:
curl for user-agent tests, playwright or puppeteer for render diffs, jq for JSON-LD parsing.Recovery:
============================================================ === PHASE 1: AI CRAWLER PARITY TEST === ============================================================
The single most predictive test: can AI crawlers actually see your content?
Generate geo/parity_test.sh:
#!/usr/bin/env bash
# Fetch pages as each AI bot and verify content parity vs human browser
URL="$1"
USER_AGENTS=(
"GPTBot/1.0 (+https://openai.com/gptbot)"
"OAI-SearchBot/1.0 (+https://platform.openai.com/docs/bots)"
"ChatGPT-User/1.0 (+https://openai.com/bot)"
"PerplexityBot/1.0 (+https://perplexity.ai/perplexitybot)"
"Perplexity-User/1.0 (+https://perplexity.ai/perplexity-user)"
"ClaudeBot/1.0 (+https://anthropic.com/claudebot)"
"Claude-Web/1.0 (+https://anthropic.com)"
"Google-Extended/1.0"
"GoogleOther/1.0"
"Bingbot/2.0 (compatible; MSNBot/2.0; +http://search.msn.com/msnbot.htm)"
"Applebot-Extended/1.0"
)
for ua in "${USER_AGENTS[@]}"; do
echo "=== $ua ==="
curl -sSL -A "$ua" "$URL" | grep -oE "(<title>.*</title>|<h1[^>]*>.*</h1>)" | head -3
echo
doneThen run a JS-rendered fetch via Playwright and diff key content elements (title, H1, body length, structured data, target keywords). If non-trivial drift, flag as a P0 issue.
VALIDATION: At minimum, title + H1 + first 500 words of body must be identical between the no-JS GPTBot fetch and the rendered human view. Schema.org JSON-LD must be in the static HTML (not injected client-side).
FALLBACK: If the site fails parity, do NOT continue downstream phases. Generate a remediation plan first: move to SSR (Next.js, Astro, Nuxt SSR mode, Remix, SvelteKit SSR) or pre-render critical pages.
============================================================ === PHASE 2: LLMS.TXT GENERATION === ============================================================
llms.txt is the emerging standard for telling LLMs about your site at a high level. It's the AI-era cousin of robots.txt + sitemap.xml collapsed into a curated human-readable index.
Generate two files at the site root:
/llms.txt (curated, terse)# {Site Name}
> {One-sentence value proposition that an LLM should learn about you}
## Core Pages
- [About](https://example.com/about): One-sentence summary
- [Products](https://example.com/products): What you sell, who it's for
- [Pricing](https://example.com/pricing): Tiers and starting prices
## Documentation
- [Getting Started](https://example.com/docs/start)
- [API Reference](https://example.com/docs/api)
## Trust & Authority
- [Customer Stories](https://example.com/customers)
- [Press & Recognition](https://example.com/press)
## Contact
- Support: [email protected]
- Sales: [email protected]/llms-full.txt (full corpus, for LLMs that want depth)Concatenate the markdown content of the 20-50 most important pages, with H1 headings and source URLs as anchors. Cap at ~200KB so it fits in typical context windows.
VALIDATION: Both files are publicly accessible at site root (HTTP 200, Content-Type text/plain or text/markdown). llms.txt is under 8KB. llms-full.txt is under 250KB. No JS required to view.
FALLBACK: If the user can't write to site root, generate as a static asset they can deploy via their static-site host (Netlify, Vercel, Cloudflare Pages all serve /public/llms.txt).
============================================================ === PHASE 3: SCHEMA.ORG COVERAGE AUDIT & FILL === ============================================================
Scan every important page for JSON-LD and report coverage. The schema types that move the needle for AI citations:
| Page Type | Required Schema |
|---|---|
| Homepage | Organization (with sameAs to social/Wikidata/Crunchbase) |
| About / Team | Person (each author/founder with sameAs, jobTitle, worksFor) |
| Article / Blog Post | Article + author (Person) + publisher (Organization) |
| Product | Product + Offer + AggregateRating (if reviews exist) |
| Docs / Guides | HowTo OR TechArticle, with step array |
| FAQ | FAQPage with mainEntity array |
| Listing / Category | ItemList + BreadcrumbList |
| Local Business | LocalBusiness with geo, openingHoursSpecification |
| Reviews | Review with author, itemReviewed, reviewRating |
| Events | Event with startDate, location, offers |
| Job Posting | JobPosting |
| Video | VideoObject with transcript (massive AI citation boost) |
For EACH missing schema, generate valid JSON-LD with required + recommended properties filled. Use the user's actual data, not placeholders.
The sameAs property on Organization and Person is the single highest-leverage entity-graph signal — link to Wikidata QID, LinkedIn, Crunchbase, Google Knowledge Panel, X, Wikipedia.
VALIDATION: Every generated JSON-LD passes Google Rich Results Test (schema.org validator) with zero errors. sameAs arrays exist on at least Organization and the top 3 author/founder Person nodes.
============================================================ === PHASE 4: ENTITY DENSITY AUDIT === ============================================================
For each pillar page (high-traffic, high-conversion, or strategic content), count "recognized entities" — proper nouns that map to a Knowledge Graph node (companies, products, people, places, technologies, standards).
Target: ≥ 15 recognized entities per pillar page (the 4.8× selection threshold from 2026 ranking factor research).
Process per page:
Google-Extended searches).Output geo/entity_audit.md with per-page recommendations.
VALIDATION: Each pillar page either meets the ≥15 threshold OR has a specific list of entities to add, with where they should be inserted naturally.
FALLBACK: If knowledge-graph lookups are rate-limited, fall back to a static curated entity list per industry (industries.yaml) — coverage is partial but report explicitly notes the gap.
============================================================ === PHASE 5: E-E-A-T & AUTHOR ENTITY === ============================================================
E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness) is a binary citation gate for AI search in 2026, not a ranking nudge.
Check:
/author/{slug} page.sameAs links.worksFor, knowsAbout, alumniOf, social sameAs.founder, foundingDate, numberOfEmployees, address, sameAs.Output geo/eeat_report.md per author and per content section.
VALIDATION: Each pillar page has a named author with a linked Person page. Person page has at least 3 sameAs entries linking to verifiable third-party profiles.
============================================================ === PHASE 6: AI BOT ALLOW RULES & RATE LIMITS === ============================================================
Update robots.txt to explicitly allow AI bots you want to index you. Default policy:
User-agent: *
Allow: /
User-agent: GPTBot
Allow: /
User-agent: OAI-SearchBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Perplexity-User
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: Claude-Web
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: Applebot-Extended
Allow: /
User-agent: anthropic-ai
Allow: /
Sitemap: https://example.com/sitemap.xmlIf the site is behind Cloudflare's AI bot blocker (now default-on for many tenants), surface that and recommend disabling for the bots above.
VALIDATION: curl -A "GPTBot" https://yourdomain.com/robots.txt returns the file. curl -A "GPTBot" https://yourdomain.com/some-pillar-page returns 200 with full content.
FALLBACK: If the user explicitly wants to block training (vs indexing for citation), they can allow *-User and *-SearchBot (live retrieval) while blocking GPTBot and ClaudeBot (training). Document the trade-off — blocking training also tends to reduce indexing.
============================================================ === PHASE 7: CITATION TRACKING SETUP === ============================================================
GEO success requires measuring what was cited and where.
Generate geo/track_citations.py — a recurring polling job that:
query, engine, date, cited_urls[], our_brand_mentioned (bool), our_url_cited (bool), competitors_cited[].Set up via cron or as a scheduled skill (/schedule weekly).
VALIDATION: First run produces a baseline. Second run a week later produces a delta report. Both runs persist to geo/citations.db.
FALLBACK: Without API keys for Perplexity/ChatGPT, fall back to manual logging via a Google Sheet template (less precise but still actionable).
============================================================ === PHASE 8: PRIORITIZED PUNCH LIST === ============================================================
Output geo/punch_list.md with findings ranked by impact:
| Priority | Issue | Impact | Effort |
|---|---|---|---|
| P0 | Site uses CSR, AI bots see empty HTML | Blocks ALL citations | High |
| P0 | Missing Organization schema on homepage | No entity grounding | Low |
| P1 | 8 of 12 pillar pages have < 15 entities | -4.8× citation probability | Medium |
| P1 | No author Person pages | EEAT gatekeeper fails | Medium |
| P2 | llms.txt missing | Lost soft signal | Low |
| P3 | Schema FAQPage missing on 4 pages with FAQs | Lost rich result | Low |
Each item links to the specific phase output explaining the fix.
VALIDATION: Punch list is non-empty AND non-overwhelming (top 20 items max). P0 items are unambiguous, not stylistic preferences.
============================================================ === SELF-REVIEW === ============================================================
Score 1–5:
============================================================ === LEARNINGS CAPTURE === ============================================================
Append to ~/.claude/skills/geo-optimize/LEARNINGS.md:
============================================================ === STRICT RULES === ============================================================
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.