# Aeo SEO Site Audit

> Analyze webpages for content quality, schema markup completeness, and AEO (Answer Engine Optimization). Designed to complement Ahrefs Site Audit findings.

- Skill: `yoyothesheep/aeo-seo-site-audit` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add yoyothesheep/aeo-seo-site-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yoyothesheep/aeo-seo-site-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: yoyothesheep (https://skillmd.com/u/yoyothesheep)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/yoyothesheep/aeo-seo-site-audit

---


# AEO & Content Analysis Skill (Ahrefs Complement)

This skill analyzes content quality, JSON-LD schema validation, and AEO (Answer Engine Optimization) for pages you specify. It complements Ahrefs Site Audit (which handles technical SEO) by focusing on aspects that require content analysis and AI-readiness assessment.

**Use this skill when Ahrefs Site Audit cannot:**
- Validate JSON-LD schema completeness and correctness
- Assess content quality and depth
- Evaluate how well pages answer user questions directly
- Identify authority/expertise signals
- Recommend AI-friendly content restructuring
- Assess natural language optimization
- Flag citability gaps

## When to Use This Skill

Trigger this skill when the user:
- Has run an Ahrefs Site Audit and wants to go deeper on content
- Asks "why isn't my content ranking for [query]?"
- Wants to "optimize for AI search" or "ChatGPT search"
- Asks "how do I get cited by AI" or "appear in AI overviews"
- Wants to "improve schema markup for content types"
- Asks "how can I make my content more AI-friendly?"
- Wants "content quality analysis" beyond technical SEO

## Core Workflow

Steps 1-2. **[Coordinator]** Gather Input — get URLs, Ahrefs project ID (optional), business context
Steps 3–8. **[Haiku Agents]** Fetch Ahrefs data (if provided) + extract entity/structure signals + crawl pages + content gap analysis
Steps 9–16. **[Sonnet Agent]** Validate schema, assess entity/cluster authority, analyze content quality, prioritize gaps, generate report

## Agent Architecture

### Coordinator (main Claude)
Handles Steps 1–2: gathers user input and orchestrates the two agents. Passes URLs + Ahrefs project ID to the Haiku agent(s), then passes all Haiku output payloads to the Sonnet agent.

### Haiku Research Agents
- One agent per URL, launched in parallel
- One additional agent for the Ahrefs API call (if project ID provided)
- Job: mechanical data extraction only — no analysis or judgment
- Output: structured JSON payload per URL (see Haiku Output Contract section below)

### Sonnet Synthesis Agent
- Single agent, runs after all Haiku agents complete
- Receives all Haiku JSON payloads + Ahrefs data
- Job: schema validation, content analysis, gap prioritization, report writing
- Output: final report
---

## Environment Detection

Before starting the audit, check which tools are available and adjust accordingly:

| Environment | Tools Available | Schema Inspection | JSON-LD Extraction Method |
|---|---|---|---|
| **Claude Code** (CLI) | `Bash`, `WebFetch`, file I/O | ✅ Full | Use `curl + grep` or Python to extract from raw HTML |
| **Claude Web** | `WebFetch` only | ⚠️ Partial (stripped) | Use `strings` from curl or ask user for Rich Results Test output |

**Note:** JSON-LD extraction is NOT optional. Audits claiming "no schema found" without explicit JSON-LD extraction attempts are incomplete and inaccurate. Always verify schema presence before reporting it as missing.

## Critical: Distinguish "Crawlable" from "Indexable"

⚠️ **Modern Googlebot executes JavaScript.** A site with empty static HTML (SPA, client-side rendering) may still be indexed by Google. The presence of a `<div id="root"></div>` does NOT mean the site is "not indexed."

**Crawlable** = Static HTML contains content (good for all crawlers, fastest for Googlebot)
**Indexable** = Google can find and index the content (true even if JS-rendered; Googlebot waits for JS execution)
**Optimal for AI crawlers** = Static HTML with schema markup (most AI answer engines have limited JS execution)

**Do not conclude a site is "not indexed" based solely on static HTML analysis.** Always verify actual indexing status first (see Step 1 below).

---

## COORDINATOR

## Step 1: Gather Input & Verify Indexing Status

Ask the user for:

**Required:**
- **Target URLs or Local Files**: The pages or codebase files to analyze.
  - If user provides live URLs: Proceed with the multi-agent web crawling in Steps 2-8.
  - If user asks you to audit a local codebase (e.g., within Claude Code): **Skip Steps 2 through 8**. Use your file reading tools to inspect the source files directly, extract schema/structure, and begin your evaluation directly at **Step 9**.

**⚠️ Before proceeding, verify actual Google indexing status:**

If user reports the site is "not indexed":
1. Ask: "Have you checked Google Search Console coverage report?" or "Have you tried `site:yourdomain.com` in Google search?"
2. If uncertain, recommend they verify using:
   - Google Search Console (Coverage > Indexed pages)
   - `site:yourdomain.com` search operator
   - Google's URL Inspection tool (one specific URL)
3. **Do not assume** a site is unindexed based on static HTML analysis alone. Modern Googlebot executes JavaScript and can index SPAs.
4. If the site is actually indexed, note this in the report's findings — the audit focus shifts to crawlability, AI-friendliness, and schema optimization (not indexing recovery).

**Optional:**
- **Ahrefs Project ID** (recommended): If you have Ahrefs Site Audit set up, provide the project ID
  - Skill will automatically fetch technical audit findings (titles, H1s, broken links, crawl issues, etc.)
  - Report combines Ahrefs technical findings + this skill's content/AEO analysis
  - No need to manually export/attach CSV—we pull directly from Ahrefs API
- **Business context**: What does the site do? What keywords/topics matter most?
- **Content goals**: Are you targeting AI search engines (ChatGPT, Perplexity, AI Overviews)?
- **Current pain points**: "Content not ranking well" / "Low AI citations" / "Thin content" etc.

**Note:** This skill complements Ahrefs Site Audit (which checks titles, meta descriptions, H1 tags, broken links, etc.). Focus here is content depth, schema, and AEO.

## Step 2: Orchestrate Agents

After gathering input, launch Haiku agents in parallel using the Task tool — one per URL, plus one for the Ahrefs API call if a project ID was provided, plus one site-level agent for entity signals (Step 4), site structure (Step 5), and content gap analysis (Step 6). Do not wait for one to finish before launching the next.

```
For each URL in target_urls:
  Task(
    subagent_type: "general-purpose",
    model: "haiku",
    prompt: <full HAIKU AGENT — Per-URL instructions, Steps 6 + 7 + 8> + "\n\nURL to process: {url}"
  )

# Site-level agent (runs once, not per URL)
Task(
  subagent_type: "general-purpose",
  model: "haiku",
  prompt: <HAIKU AGENT — Site-Level instructions, Steps 4 + 5> + "\n\nBrand name: {brand_name}\nHomepage: {homepage_url}"
)

If ahrefs_project_id provided:
  Task(
    subagent_type: "general-purpose",
    model: "haiku",
    prompt: <HAIKU AGENT — Ahrefs instructions, Step 3> + "\n\nProject ID: {ahrefs_project_id}"
  )
```

Collect all Task results. Once every Haiku agent has returned its JSON payload, proceed to the SONNET AGENT section.

---

## HAIKU AGENT — Ahrefs (optional, one agent per audit)

## Step 3: Fetch Ahrefs Audit Issues (Optional)

If user provided an Ahrefs project ID, pull technical audit findings:

```python
# Use Ahrefs MCP to fetch Site Audit issues
ahrefs_issues = site_audit_issues(
    project_id=user_project_id,
    date=None  # Get latest crawl
)

# Parse issues by type:
# - Title/meta description issues
# - H1/heading hierarchy issues
# - Broken links
# - Mobile optimization issues
# - Crawlability issues
# Store for reference in final report
```

**If user doesn't have Ahrefs project ID:**
- Skip this step
- Continue with content-only analysis

---

## HAIKU AGENT — Site-Level (one agent per audit)

## Step 4: Entity Signal Extraction

Run once per audit (not per URL). Extract signals that establish whether the brand is recognized as a trusted entity by AI systems.

**Checks:**

```bash
# 1. Google Knowledge Panel — fetch SERP for brand name
curl -s -A "Mozilla/5.0" "https://www.google.com/search?q=[Brand+Name]" | python3 -c "
import sys; html = sys.stdin.read()
print('knowledge_panel_detected:', 'kp-wholepage' in html or 'knowledge-panel' in html)
"

# 2. Wikipedia presence
curl -s -o /dev/null -w "%{http_code}" "https://en.wikipedia.org/wiki/[Brand_Name]"
# 200 = exists, 404 = not found

# 3. sameAs in Organization schema (from homepage JSON-LD already extracted)
# Check if any sameAs value contains: linkedin.com/company, wikidata.org, wikipedia.org
```

**Output — add to Haiku payload (site-level, run once):**
```json
"entity_signals": {
  "knowledge_panel_detected": false,
  "wikipedia_exists": false,
  "wikipedia_url": null,
  "linkedin_sameas_present": false,
  "wikidata_sameas_present": false,
  "organization_schema_present": false,
  "nap_fields_found": ["name", "url"],
  "nap_consistent_across_pages": null
}
```

**NAP consistency:** Extract `name`, `url`, `address`, `telephone` from Organization schema on each page. Flag if values differ across pages.

**Cross-platform consensus proxy:** If Ahrefs data available, count referring domains that are news/media/industry sites (not directories). Store count as `authoritative_referring_domains`.

---

## Step 5: Site Structure Sampling

Run once per audit. Goal: map content cluster architecture to assess topical authority.

**Steps:**
1. Fetch `/sitemap.xml` (or check `robots.txt` for sitemap URL). Parse all URLs.
2. Group by path segment (e.g., `/blog/`, `/guides/`, `/learn/`).
3. For each section: identify if a pillar/index page exists (path depth 1) vs sub-pages (depth 2+).
4. Fetch homepage HTML → extract top-level `<nav>` links.
5. For each pillar page found: count internal links to sub-pages and from sub-pages back to pillar.

**Output — add to Haiku payload (site-level):**
```json
"site_structure": {
  "sitemap_found": true,
  "total_urls_in_sitemap": 87,
  "content_sections": [
    {
      "section": "/blog/",
      "pillar_page_exists": false,
      "sub_page_count": 34,
      "internal_links_to_pillar": 0
    }
  ],
  "nav_links": ["About", "Blog", "Pricing"],
  "orphaned_pages_detected": true
}
```

If sitemap not found, attempt to discover sections from homepage navigation links only. Note the limitation.

---

## HAIKU AGENT — Per-URL (one agent per URL)

## Step 6: Content Gap Analysis (SERP Fallback — skip if Ahrefs available)

**If Ahrefs project ID provided:** Use Ahrefs Content Gap tool instead. Pass competitor keyword gaps as `content_gap.gap_subtopics` in the payload.

**If no Ahrefs access:** For each target URL, run SERP-based gap analysis:

```bash
# 1. Infer primary keyword from page H1/title (already extracted in Step 4)
# 2. Fetch Google SERP for that keyword
curl -s -A "Mozilla/5.0" "https://www.google.com/search?q=[primary+keyword]" | python3 << 'EOF'
import sys, re
html = sys.stdin.read()
# Extract People Also Ask questions
paa = re.findall(r'data-q="([^"]+)"', html)
# Extract top organic result URLs (first 3)
urls = re.findall(r'href="/url\?q=(https://[^&"]+)', html)[:3]
print("PAA:", paa[:8])
print("Competitor URLs:", urls)
EOF

# 3. For each competitor URL, fetch and extract H2/H3 headings
curl -s "[competitor_url]" | python3 -c "
import sys, re
html = sys.stdin.read()
headings = re.findall(r'<h[23][^>]*>([^<]+)</h[23]>', html)
print(headings)
"
```

**Output — add to per-URL Haiku payload:**
```json
"content_gap": {
  "primary_keyword_inferred": "best project management tools",
  "method": "serp_fallback",
  "paa_questions": ["What is the best PM tool for small teams?"],
  "competitor_subtopics": ["Integrations", "Pricing comparison", "Free tier breakdown"],
  "subtopics_covered_on_page": ["Features", "Pricing"],
  "gap_subtopics": ["Integrations", "Free tier breakdown"]
}
```

Diff logic: `gap_subtopics = competitor_subtopics − subtopics_covered_on_page` (fuzzy match on keywords, not exact string).

---

## Step 7: Crawl Target Pages, Extract JSON-LD & Content Signals

**⚠️ CRITICAL: JSON-LD extraction is mandatory on every page. Do ONE fetch per URL (not two) to ensure efficiency.**

**⚠️ CRITICAL: When analyzing static HTML, distinguish between:**
- **"Empty static HTML" (JS-rendered SPA)**: Does NOT mean "not indexable by Google." Modern Googlebot executes JavaScript. However, it DOES mean poor crawlability for other crawlers (Bingbot, AI answer engines, feed readers).
- **"No content in static HTML"**: Valid finding for crawlability audit. Report it as a crawlability gap, not an indexing problem.

For each target URL, extract all raw signals in a single pass. This step combines fetching, JSON-LD extraction, and content signal extraction.

### Environment Detection & Fetch Strategy

Before fetching, detect which tools are available:

- **Claude Code (Bash available):** Use `curl` to fetch raw HTML, extract JSON-LD and content signals immediately
- **Claude Web (WebFetch only):** Use `web_fetch`, JSON-LD will be stripped during conversion

### Fetch & Extract Implementation

**If `Bash` is available (Claude Code):**
```bash
curl -s "https://example.com" 2>&1 | python3 << 'EOF'
import sys, re, json
html = sys.stdin.read()
# Find all JSON-LD blocks
blocks = re.findall(r'<script[^>]*type=["']application/ld\+json["'][^>]*>(.*?)</script>', html, re.DOTALL)
extracted_jsonld = []
if blocks:
  for i, block in enumerate(blocks):
    try:
      data = json.loads(block.strip())
      extracted_jsonld.append(data)
      print(f"=== JSON-LD Block {i+1} ===")
      print(json.dumps(data, indent=2))
    except json.JSONDecodeError as e:
      print(f"Error parsing JSON-LD block {i+1}: {e}")
else:
  print("No JSON-LD found")
EOF
```

**If only `WebFetch` is available (Claude Web):**
```python
result = web_fetch(url, text_content_token_limit=50000)
# Note: JSON-LD is stripped during conversion. Store HTML as-is.
# Extracted schema will be empty; will note limitation in report.
```

### Content Elements to Extract (from stored HTML)

```python
# Parse from stored HTML:
- Total word count of main content
- Paragraph structure and sentence complexity
- Lists (<ul>, <ol>) and tables
- Presence of FAQ sections, direct answers to questions
- Formatting: bold, code blocks, callouts
- Links: internal links, citation links, source attribution
- Images: presence of descriptive captions
```

### Authority & Freshness Signals to Extract (from stored HTML)

```python
# Look for in stored HTML:
- Author information (name, title, credentials)
- Publication date (<meta name="article:published_time"> or datePublished in schema)
- Last updated date (dateModified or "Updated:" text)
- Organization/author credentials or bio
- External citations and source links
```

### Extract Internal Links from Stored HTML

```python
# From stored HTML, extract <a href="..."> where:
- href starts with "/" or contains the same domain
- Not pointing to: #anchors, mailto:, tel:, javascript:, files (.pdf, .jpg, etc.)
- Not duplicate URLs
# Store for optional content sampling (Step 5)
```

---

## Step 8: Required Representative Sampling

To ensure consistent, reproducible findings, crawl at least **2 representative pages per page type** present on the site. This sampling is **required** — not optional. Skipping dynamic or category pages is the most common cause of missed critical findings (CSR rendering gaps, listing schema gaps).

**Page types to identify and sample:**

| Type | Description | Examples |
|------|-------------|---------|
| Static content page | Server-rendered marketing or informational page | Homepage, About, Data Sources, FAQ |
| Dynamic/app route | Page that may require JavaScript to render content | Career detail, product page, quiz/tool |
| Category/listing page | Index of items or content | Blog index, career listings, provider directory |
| Utility/supporting page | Non-primary page with supporting content | Pricing, Contact, Sitemap |

**Sampling rules:**
- Review the user-specified URLs and identify which types are already covered
- For each type **not yet covered**, find and add 1–2 pages of that type (crawl the homepage, check nav links, or follow `href` patterns like `/discover/`, `/blog/`, `/products/`)
- For dynamic pages: fetch with `curl` regardless; if content is missing from raw HTML, that is a finding (CSR gap), not a reason to skip
- Maximum 10 additional pages beyond user-specified URLs
- If fetch fails, include the URL with `"error": "..."` — do not omit it

**For each sampled page:** Use Step 7 methodology (environment-aware fetch + JSON-LD extraction + content signal extraction, store HTML for parsing).

---

## Haiku Output Contract

Each Haiku agent outputs one JSON payload per URL. This is the only data the Sonnet agent receives — it never accesses raw HTML.

```json
{
  "url": "https://example.com/page",
  "status_code": 200,
  "fetch_method": "curl",
  "json_ld_blocks": [
    { "@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [...] }
  ],
  "json_ld_extraction_attempted": true,
  "word_count": 847,
  "headings": [
    { "level": "h1", "text": "..." },
    { "level": "h2", "text": "..." }
  ],
  "has_lists": true,
  "has_tables": false,
  "has_code_blocks": false,
  "faq_sections_detected": 2,
  "author_markup_found": true,
  "author_text": "Jane Smith, Senior Editor",
  "date_fields_found": ["datePublished"],
  "date_modified_found": false,
  "external_citation_links": 3,
  "internal_links": ["https://example.com/related-page"],
  "image_count": 4,
  "images_with_captions": 2,
  "content_gap": {
    "primary_keyword_inferred": "...",
    "method": "serp_fallback",
    "paa_questions": [],
    "competitor_subtopics": [],
    "subtopics_covered_on_page": [],
    "gap_subtopics": []
  },
  "ahrefs_issues": [],
  "entity_signals": {
    "knowledge_panel_detected": false,
    "wikipedia_exists": false,
    "wikipedia_url": null,
    "linkedin_sameas_present": false,
    "wikidata_sameas_present": false,
    "organization_schema_present": false,
    "nap_fields_found": [],
    "nap_consistent_across_pages": null
  },
  "site_structure": {
    "sitemap_found": false,
    "total_urls_in_sitemap": 0,
    "content_sections": [],
    "nav_links": [],
    "orphaned_pages_detected": false
  },
  "token_usage": {
    "model": "claude-haiku-4-5-20251001",
    "input_tokens": 0,
    "output_tokens": 0
  }
}
```

**Notes:**
- `json_ld_extraction_attempted` must always be `true` — never report "no schema found" without attempting extraction
- If fetch failed, include `"status_code": null` and `"error": "..."` — do not omit the URL from results
- `ahrefs_issues` is populated only on the Ahrefs agent payload, not per-URL
- `token_usage` must be populated by every Haiku agent. Use the actual token counts from the API response metadata if available; otherwise estimate based on prompt + output length.

---

## SONNET AGENT

The Sonnet agent receives all Haiku JSON payloads and the Ahrefs issues data. It never fetches URLs. All analysis, judgment, and report writing happens here.

**Token tracking:** At the end of your output, include your own token usage:
```json
{
  "sonnet_token_usage": {
    "model": "claude-sonnet-4-6",
    "input_tokens": 0,
    "output_tokens": 0
  }
}
```
Use actual API response metadata if available; otherwise estimate from input/output length.

## Step 9: Schema Validation

**Using JSON-LD blocks from Haiku payloads:**

- Check if schema type matches content type (FAQPage for FAQs, Article for blog posts, etc.)
- Identify missing required fields (author, datePublished, answer properties, etc.)
- Flag schema that doesn't match visible content signals (e.g., FAQPage present but `faq_sections_detected: 0` in payload)

**Do not validate "no schema found" without confirming `json_ld_extraction_attempted: true` in the Haiku payload.**

---

## Step 10: Entity Layer Assessment

Using `entity_signals` from the Haiku payload. This is the foundation — if the brand isn't recognized as an entity, schema and content improvements have limited AEO impact.

| Signal | Finding | Priority |
|--------|---------|----------|
| `organization_schema_present: false` | ❌ No machine-readable brand identity | 🔴 Critical |
| `knowledge_panel_detected: false` | ❌ Brand not recognized as Google entity | 🔴 Critical if org schema also absent |
| `wikipedia_exists: false` | ❌ No encyclopedic reference — low Knowledge Graph authority | 🟡 Important |
| `linkedin_sameas_present: false` | ❌ AI can't cross-reference brand on LinkedIn | 🟡 Important |
| `wikidata_sameas_present: false` | ❌ Missing Wikidata entity link | 🟢 Enhancement |
| `nap_consistent_across_pages: false` | ❌ Conflicting entity signals across pages | 🟡 Important |

**Fix guidance:**
- Add Organization schema with `sameAs` array pointing to LinkedIn, Wikipedia (if exists), Wikidata, and Crunchbase
- To earn a Knowledge Panel: ensure Wikipedia article exists or claim Google Business Profile; build consistent brand mentions on authoritative external sites
- NAP inconsistency: standardize `name`, `url`, `address` across all page-level Organization schema

---

## Step 11: Content Cluster Assessment

Using `site_structure` from the Haiku payload. Topical depth through clustering is how AI systems assess subject matter authority — individual pages aren't enough.

**Checks:**
- ❌ Content section has 5+ sub-pages but no pillar/index page (sub-articles floating without a hub)
- ❌ Pillar page exists but `internal_links_to_pillar: 0` (cluster is broken — sub-pages don't reinforce the hub)
- ❌ `orphaned_pages_detected: true` — pages in sitemap not reachable from navigation
- ❌ Sitemap not found — AI crawlers can't discover full content scope
- ✅ Each content section has a pillar page + 3+ supporting sub-articles with bidirectional internal linking

**Priority:** 🔴 Critical if a key topical section has 5+ pages with no pillar. 🟡 Important for linking gaps and orphaned content.

---

## Step 12: Schema Markup & Structure Validation

Analyze all crawled pages for JSON-LD completeness and AEO readiness:

### Schema Validation (HIGH PRIORITY)

**Missing Schema for Content Type:**
- ❌ FAQ/Q&A content with no `FAQPage` schema
- ❌ Articles with no `Article` or `BlogPosting` schema
- ❌ How-to content with no `HowTo` schema
- ❌ Product pages with no `Product` schema
- ❌ Organization pages with no `Organization` schema
- ❌ Reviews with no `Review` or `AggregateRating` schema
- ✅ Good: Schema matches content type with all required properties

**Incomplete Schema:**
- ❌ `FAQPage` present but missing author, datePublished, or mainEntity
- ❌ `Article` missing datePublished or author information
- ❌ Schema properties incomplete or marked with placeholder values
- ✅ Good: Schema has all required fields + recommended fields (author, date, description)

**Schema Quality:**
- ❌ Schema doesn't match visible content (e.g., FAQPage claims 10 Q&As but page shows 3)
- ❌ Nested schema incorrectly structured (e.g., Answer not properly nested in Question)
- ✅ Good: Schema structure is valid and matches content accurately

### Content Structure for AI (MEDIUM PRIORITY)

**Direct Answer Formats:**
- ❌ Content doesn't answer main question in first paragraph
- ❌ Answers buried in prose; no clear Q&A or summary
- ✅ Good: First sentence answers the question; FAQ/TL;DR at top

**Scannable Formatting:**
- ❌ Content is all prose; no lists, tables, or visual breaks
- ❌ No numbered steps for how-to content
- ✅ Good: Bulleted lists, comparison tables, numbered steps, short paragraphs

**Topic Coherence:**
- ❌ Content jumps between unrelated subtopics
- ❌ Sections don't connect logically
- ✅ Good: Clear section topics; content flows logically; related pages linked

---

## Step 13: Content Quality and Structure (SEO and AEO)

Evaluate all content for SEO quality and AEO (Answer Engine Optimization)—how well it serves both traditional search engines and AI systems like ChatGPT, Perplexity, and Google AI Overviews.

### Topic Coverage & Clarity

**User Intent & Comprehensiveness**
- ❌ Content doesn't clearly address the stated topic (from title/H1)
- ❌ Content is too shallow for user intent
- ✅ Good: Comprehensive coverage matching search intent
- ✅ Good: First paragraph directly answers the main question

**Content Gap Analysis (from `content_gap` payload field)**
- ❌ PAA questions unaddressed — list each specific unanswered question (e.g., "Page doesn't answer: 'What is the best PM tool for small teams?'")
- ❌ Competitor subtopics missing — list specific H2/H3 gaps vs top 3 ranking pages
- ✅ Good: Page covers all identified PAA questions and matches competitor subtopic depth
- Note the method used: `serp_fallback` (less precise, no volume data) vs `ahrefs_content_gap` (with keyword volume)

**Direct Answer Formats (AEO Priority)**
- ❌ Content doesn't answer specific questions directly; answers buried in prose
- ❌ No summary or abstract at the beginning
- ✅ Good: Clear questions as H2/H3 headings with immediate answers
- ✅ Good: Executive summary or TL;DR at top; definitions early in content
- ✅ Good: FAQ sections with explicit Q&A format

### Keyword & Semantic Usage

**Keyword Placement**
- ❌ Target keywords missing or poorly placed
- ✅ Good: Keywords naturally used in title, H1, H2s, and first paragraph
- ✅ Good: Related/semantic keywords present throughout

**Content Originality & Specificity**
- ❌ Generic, thin content; only rehashed information
- ✅ Good: Original research, specific examples, data, or expert analysis
- ✅ Good: Matches user intent (informational vs. commercial vs. transactional)

### Content Structure & Scannability

**Heading Hierarchy & Descriptiveness**
- ❌ Flat structure, generic headings, skipped heading levels
- ✅ Good: Descriptive headings that can stand alone; logical H2 → H3 progression
- ✅ Good: Each section addresses one clear subtopic

**List-Based & Semantic Structure (AEO Priority)**
- ❌ Information only in prose; no lists, comparisons, or checklists
- ❌ Content jumps between unrelated topics
- ✅ Good: Key points in numbered/bulleted lists; comparison tables; checklists
- ✅ Good: Content stays focused; related subtopics logically connected
- ✅ Good: Short paragraphs with varied formatting for scannability

**Schema Markup for AI Extraction (CRITICAL)**
**These are the #1 issues AI systems care about. Verify schema extraction before marking as missing.**

- ❌ **No FAQ schema** on Q&A content (major AEO issue)
- ❌ **No HowTo schema** for step-by-step guides
- ❌ **Missing Article/BlogPosting schema** with author, date, and structure
- ❌ **Missing Organization schema** on homepage
- ❌ **No BreadcrumbList schema** for navigation
- ✅ Good: `FAQPage` schema with complete Q&A pairs
- ✅ Good: `HowTo` schema with `HowToStep` items
- ✅ Good: `Article`/`BlogPosting` with author info and publication dates
- ✅ Good: `Organization`, `BreadcrumbList`, or other relevant schema types

### Authority & Citability (AEO Priority)

**Expertise & Author Signals**
- ❌ No author information, credentials, or expertise signals
- ✅ Good: Author bio with relevant credentials; "Written by [Name], [Title]"
- ✅ Good: Author schema markup

**Source Attribution & Evidence**
- ❌ Claims without sources or supporting links
- ✅ Good: Direct links to original sources and citations
- ✅ Good: "According to [Source], ..." format; statistics and data attributed

**Freshness Indicators**
- ❌ No date information; outdated without update signals
- ✅ Good: Clear publish date and "Last updated: [date]" for freshness
- ✅ Good: datePublished and dateModified in schema; references recent information

### Experience Proof (AEO Priority)

AI systems deprioritize content they could have generated themselves. Score on three dimensions using content signals from the Haiku payload:

| Dimension | Pass | Fail |
|-----------|------|------|
| **Original data** | Specific statistics, percentages, study sizes, or dates from a named primary source | All claims hedged ("many experts say", "studies show") or link only to other aggregators |
| **Firsthand evidence** | Named case study, specific customer result, before/after outcome, or explicit "in our experience" with context | Generic how-to advice with no specific organizational context |
| **Replication barrier** | Contains proprietary methodology, internal benchmark, unique dataset, or direct interview quote | Could have been written by summarizing 3 Wikipedia articles |

- ❌ Zero firsthand evidence — AI deprioritizes content it could generate itself
- ❌ All statistics link to aggregators (Forbes, HubSpot roundups) not primary sources — indirect citations reduce citability
- ✅ Named examples + quantitative outcomes present (e.g., "Acme reduced churn by 23% using X")

### Natural Language Optimization (AEO Priority)

**Conversational & Accessible Language**
- ❌ Overly technical jargon, corporate speak, or fragmented sentences
- ✅ Good: Explains concepts in plain language; answers like a human would
- ✅ Good: Complete sentences with necessary context; can extract any paragraph and it makes sense
- ✅ Good: Uses "you" to address the reader; includes clear definitions

**Topic Coherence**
- ❌ Content jumps between unrelated topics; no clear focus
- ✅ Good: Each section connects logically to others
- ✅ Good: Internal links to related topics on separate pages

### Content Patterns for AI (AEO Priority)

Identify and optimize for AI-friendly formats:

- **How-To Content**: "How to [task]" format, numbered steps, time estimates, prerequisites
- **Comparison Content**: "[X] vs [Y]" titles, side-by-side tables, pros/cons, clear recommendation
- **Definitive Guides**: "Complete Guide" or "Everything You Need to Know" format, table of contents, multi-section coverage
- **Best/Top Lists**: "Best [X] for [Use Case]" format, clear ranking criteria, descriptions with reasoning

### Priority Summary

| Priority | Issue | Impact |
|----------|-------|--------|
| 🔴 Critical | Missing FAQ/HowTo schema on relevant content | Prevents AI extraction; major ranking loss for AEO |
| 🔴 Critical | No author info/expertise signals | Reduces citability; AI systems deprioritize unsourced content |
| 🔴 Critical | Content doesn't directly answer questions | Users and AI skip the page |
| 🔴 Critical | Missing publish/update dates | AI views content as stale |
| 🟡 Important | Only prose (no lists/tables/structure) | Harder for AI to extract; poor scannability |
| 🟡 Important | Generic/non-descriptive headings | AI can't understand section topics |
| 🟡 Important | Missing source citations | Reduces authority; AI won't cite |
| 🟡 Important | Complex language without explanations | Users bounce; AI struggles to extract meaning |
| 🟢 Enhancement | Add comparison/HowTo schema | Improves featured snippets and AI citations |
| 🟢 Enhancement | Improve conversational tone | Increases engagement and AI relevance |
| 🟢 Enhancement | Add specific examples and data | Supports claim substantiation for AI search |

---

## Step 14: Authority & Citability Assessment

Evaluate how well pages establish expertise and enable AI systems to cite the content.

### Author Credibility Signals

**Observable signals:**
- ❌ No author information on any page
- ❌ Author listed but no credentials, title, or bio
- ❌ No author schema markup (Author property in schema)
- ✅ Good: Author name + title/credentials visible; Author schema present

**Impact on AEO:** AI systems check author credibility before citing. Missing author signals = low citability.

### Source Attribution & Citations

**Observable signals:**
- ❌ Claims made without sources or supporting links
- ❌ Statistics cited without attribution ("trusted data" but no link to source)
- ❌ No distinction between original data and curated information
- ✅ Good: Direct links to sources; "According to [Source]" format; statistics attributed
- ✅ Good: Original research/data clearly marked; methodology explained

**Impact on AEO:** AI systems prioritize citing well-sourced content. Direct links increase citability.

### Freshness Indicators

**Observable signals:**
- ❌ No publication or update date visible
- ❌ Outdated information without update signals
- ❌ No datePublished or dateModified in schema
- ✅ Good: Clear "Published [date]" and "Updated [date]" visible
- ✅ Good: datePublished and dateModified in schema; content references recent data

**Impact on AEO:** AI systems deprioritize stale content. Dates signal ongoing relevance.

### Expertise Depth

**Observable signals:**
- ❌ Shallow coverage; content could be written by anyone
- ❌ No evidence of specialized knowledge or experience
- ⚠️ Good domain knowledge but not explicitly stated
- ✅ Good: Domain expertise evident (specific examples, methodology, credentials)
- ✅ Good: Depth of coverage exceeds surface-level information

---

## Step 15: Prioritize Content & AEO Gaps

Group all identified issues into three priority tiers:

### 🔴 High Priority (Critical for AEO)

Issues that significantly impact AI citability and content quality:
- **No Organization schema** (AI has no machine-readable brand identity — entity layer foundation missing)
- **No Knowledge Panel + no Organization schema** (brand not recognized as a trusted entity by AI)
- **Content section with 5+ sub-pages but no pillar page** (no topical authority hub; AI can't assess depth)
- **Missing schema for content type** (e.g., no FAQPage on FAQ content, no Article on blog posts)
- **No author/expertise signals** (missing author name, credentials, or author schema)
- **Content doesn't directly answer main question** (answer buried in prose)
- **Missing publication date** (no datePublished in schema or visible date)
- **Incomplete schema** (FAQPage present but missing required fields like author, question, answer)

### 🟡 Medium Priority (Improves AEO)

Issues that enhance content quality and extractability:
- **Missing Wikipedia page or `sameAs` schema links** (LinkedIn, Wikidata not cross-referenced — entity recognition incomplete)
- **NAP inconsistency across pages** (conflicting Organization schema signals reduce AI confidence)
- **Pillar page exists but sub-pages don't link back** (broken cluster; topical authority signal diluted)
- **Orphaned pages** (in sitemap but unreachable from navigation)
- **Content gaps vs competitors** (PAA questions unaddressed; competitor subtopics missing)
- **Zero firsthand evidence or original data** (content is replicable by AI; low citability)
- **Thin content** (<300 words for informational pages; missing depth vs competitors)
- **No source citations** (claims made without supporting links or attribution)
- **Only prose formatting** (no lists, tables, or scannable structure for how-to/comparison content)
- **Missing dateModified** (no update signal for content refresh)
- **Poor topic structure** (content jumps between topics; sections not logically connected)
- **Complex language** (jargon-heavy without explanations; not conversational)

### 🟢 Low Priority (Enhancements)

Nice-to-have improvements:
- **Add comparison/HowTo schema** (improves featured snippets and AI citations)
- **Improve conversational tone** (makes content more readable and extractable)
- **Add specific examples and data** (supports claim substantiation for AI search)
- **Internal linking to related topics** (improves content coherence and crawlability)

For each issue, include:
- **What's wrong**: Clear description (e.g., "FAQ schema incomplete—missing 'answer' field in Q&A pairs")
- **Why it matters**: Specific AEO impact (e.g., "AI systems can't extract answers without complete schema")
- **How to fix**: Specific steps (e.g., "Add 'answer' property to each Q&A item in FAQPage schema")
- **Affected pages**: URLs with this issue
- **Estimated effort**: Quick (<30 min), Moderate (1-3 hours), Major (4+ hours)

---

## Step 16: Generate Content & AEO Report

Create a well-structured document (markdown or docx) with:

### Executive Summary
- **Tone:** Analytical and data-driven (see [TONE-GUIDE.md](../TONE-GUIDE.md))
- Total pages analyzed
- **Google indexing status (if reported as problem):** Clearly state whether actual indexing was verified via GSC/site: operator or if this is based on crawler simulation analysis. Important distinction: "Static HTML shows no crawlable content (gap for non-Google crawlers)" vs. "Not indexed by Google (requires GSC verification)."
- Summary of Ahrefs findings (if available): "Ahrefs identified X technical issues across Y pages"
- Overall AEO readiness score (based on schema, content, authority signals)
- Top 3-5 critical gaps (prioritized by AEO impact and effort)
- Estimated improvement: "With these changes, content will be 40-50% more extractable by AI systems"
- **Total research cost: $—** (one line; full breakdown in Token Usage appendix at end of report)

### Prioritized Recommendations

**Writing style for recommendations:** See [TONE-GUIDE.md](../TONE-GUIDE.md) for detailed style guidelines. Key principles:
- Use neutral language without dramatic framing
- Quantify impact with specific data
- Avoid vague benefits (no "better SEO" without specifics)
- Explain mechanisms and provide realistic effort estimates

**What to include:**
- **All** 🔴 Critical issues and 🟡 Important issues — no cap, no omissions
- **Top 3** 🟢 Enhancement items, selected by highest impact
- If more than 3 enhancements were identified, append: `> _N additional enhancements not listed — see Priority Summary for full list._`

**Priority tiers:**

| Tier | Label | Include |
|---|---|---|
| 🔴 Critical | Blocks ranking or AI citability; fix immediately | All |
| 🟡 Important | Meaningfully reduces performance; fix soon | All |
| 🟢 Enhancement | Incremental improvement; schedule when bandwidth allows | Top 3 |

Order within each tier by impact × effort. Begin with a summary table — one row per recommendation — then list full details for each item below the table.

**Summary table (one row per recommendation):**

| # | Priority | Recommendation | Category | Effort | Pages Affected |
|---|----------|---------------|----------|--------|----------------|
| 1 | 🔴 Critical | … | … | Quick / Moderate / Major | X of Y |
| 2 | 🟡 Important | … | … | … | … |
| … | … | … | … | … | … |

**Detailed recommendations (one section per item, matching table order):**

For each item:

- **What to do**: Specific, actionable instruction with affected page count or URLs
- **Why it matters**: Data-backed impact (e.g., "Affects 8 of 11 pages" / "Missing schema blocks AI extraction")
- **Category**: Technical SEO / Content / AEO / Information Architecture / Content Presentation
- **Effort**: Quick (<30 min) / Moderate (1–3 hrs) / Major (4+ hrs)

### Detailed Findings

**Writing style guidelines:** See [TONE-GUIDE.md](../TONE-GUIDE.md). Key principles:
- State issues factually without editorializing
- Explain specific mechanism of impact
- Use metrics: "3 of 11 pages" not "some pages"
- Distinguish between content quality and schema completeness

#### Entity & Brand Authority
- Knowledge Panel status (detected vs not)
- Wikipedia and Wikidata presence
- `sameAs` cross-platform links in Organization schema
- NAP consistency across pages
- Authoritative referring domain count (if Ahrefs data available)

#### Site Structure & Content Clusters
- Sections with pillar pages vs floating sub-articles
- Internal linking gaps (pillar → sub and sub → pillar)
- Orphaned pages (sitemap vs navigation reachability)
- Sitemap presence and coverage

#### Schema Markup Gaps
For each page/content type:
- Missing or incomplete schema (e.g., "FAQPage present but 3 of 10 Q&As missing 'answer' field")
- Affected pages (X of Y total)
- Impact on AEO (e.g., "AI systems can't cite answers without complete schema")
- Specific fix (e.g., "Add 'answer' property to all Question items")

#### Content Quality Issues
- Thin content vs competitors (word count, depth analysis)
- Content gap analysis: PAA questions unaddressed, competitor subtopics missing (list specific gaps per URL)
- Experience proof gaps: zero firsthand evidence, statistics only from aggregator sources, no replication barrier
- Dire

…(truncated)
