# Content Gap + AEO Opportunity Playbook

> The synthesis playbook EntireCommerce AI runs to surface the exact 20 to 50 content opportunities where competitors are winning organic rankings and LLM citations, and the client is not. Reads SEO keyword footprint, AEO citation signals, and competitor content to produce a prioritised content-production roadmap with full briefs for the top 10.

---

## Purpose

Turn SEO + AEO + competitor data into a single ranked list of content the brand should produce next. Most content programmes run on intuition and editor-calendar inertia. This playbook replaces intuition with a scored opportunity list grounded in three inputs: keywords competitors rank for that the brand does not, questions LLMs answer with competitor citations while ignoring the brand, and intent-mapped SERP clusters where the category has room. The output is a production roadmap of 20 to 50 pieces ranked by opportunity score, plus full content briefs for the top 10.

Content-gap analysis has been an SEO primitive for a decade. What is new and underserved: the AEO layer. ChatGPT, Claude, Perplexity, and Google AI Overview increasingly intermediate the commercial journey. Every query the LLM answers by citing a competitor is a lost attention impression. This playbook treats AEO citation whitespace as a first-class input alongside keyword whitespace, then scores each opportunity on the combined axis.

## When to run it

- **Pre-production planning** for a 90-day content sprint.
- **Quarterly refresh** on an active content programme to rebalance the calendar toward what the data says will compound.
- **First-run strategic content audit** for a prospect evaluating whether to hire the agency for content production.
- **After a major Google or LLM algorithm shift** to re-test which topics still carry ranking and citation upside.

## Who this is for (ICP)

Premium DTC brands, AOV $500+ or 2x category median, founder-led, US or English-speaking market focus. Must have either (a) 6+ months of organic activity with at least 30 pages indexed and some ranking footprint, or (b) greenfield ambition, paired with a serious willingness to publish 1 to 2 pieces per week for two quarters. The playbook works for brands outside those shapes but the output is tuned for the shapes above.

---

## Two paths, four modes

The playbook flexes on two independent axes.

### Axis 1. Data maturity

- **Path A. Established content footprint.** Brand has existing content, at least 30 indexed pages, and a measurable ranking surface in GSC. Gap analysis runs from the current state outward.
- **Path B. Greenfield.** New brand, minimal indexed content, no meaningful GSC data. Gap analysis runs bottom-up from competitor footprint alone.

### Axis 2. Scope depth

- **Full.** 3 to 5 competitors, 50+ opportunities surfaced, top 10 briefed.
- **Quick.** 1 competitor, 10 opportunities surfaced, top 5 briefed.
- **AEO-only.** Skip the keyword-gap layer entirely. Mine LLM citation whitespace only. Top 15 questions briefed as AEO-extractable pages.
- **Cluster-deep.** Pick one topic cluster up front. Produce 20 briefs inside that cluster, at varying search-intent depths (informational pillar, commercial sub-pages, transactional landing pages).

### The four modes

| Mode | Path | Scope |
|---|---|---|
| Full-A | Established | Full |
| Full-B | Greenfield | Full |
| Quick | Either | Quick |
| AEO-only | Either | AEO-only |
| Cluster-deep | Either | Cluster-deep |

### Mode detection

1. Read `CLAUDE.md` for the brand's stage and existing content footprint.
2. If GSC is configured and the brand has more than 30 indexed pages with at least 100 ranking queries, default to Path A. Otherwise Path B.
3. Ask the user which scope depth they want. Default to Full if time and budget allow.
4. Record the mode in the report header.

---

## Tool-availability gate (strict, two layers)

The playbook runs on a mix of external public-data APIs and the client's own search-console data. External-only runs still produce a high-value report. GSC unlocks the own-site layer.

### External layer (always runs)

| Tool | Used for | `.env` variable |
|---|---|---|
| DataForSEO | Competitor ranked keywords, SERP enrichment, keyword volume and difficulty, SERP intent classification | `DATAFORSEO_LOGIN`, `DATAFORSEO_PASSWORD` |
| Ahrefs (optional) | Native content-gap tool, competitor top pages, content clusters | `AHREFS_API_KEY` |
| Serper | Live SERP snapshots, AI Overview presence, featured-snippet capture | `SERPER_API_KEY` |
| Keywords Everywhere | Volume lookups, related queries, long-tail discovery | `KEYWORDS_EVERYWHERE_API_KEY` |
| Screaming Frog CLI | Client-side content inventory, canonicals, internal link graph | installed locally |
| ChatGPT, Claude, Perplexity | AEO citation probes across 30 to 50 category questions | manual or API |
| Google AI Overview check via Serper | Google AI Overview presence per query | `SERPER_API_KEY` |

### Internal layer (logged-in tool access, unlocks Path A depth)

| Tool | Used for | Access required |
|---|---|---|
| Google Search Console | Own-site query footprint, impressions, CTR, position by query | Restricted access on GSC property for the operator's service account |
| Google Analytics 4 | Content-attributed conversion and engagement data per URL | Viewer access for the service account |

### Gate behaviour

1. External layer runs on every mode. The Ahrefs content-gap tool is the simplest single-tool shortcut when an Ahrefs seat is available. DataForSEO covers the same ground through two calls (competitor `labs_ranked_keywords` plus client `labs_ranked_keywords`, set-difference in Python). Do not use the DataForSEO `labs_keyword_intersection` call for gap analysis. It returns intersections (keywords both domains rank for) when the analysis needs the set difference.
2. Path A unlocks when GSC credentials exist. Without GSC, Path A degrades to a competitor-footprint-only analysis. Honest stubbing: state clearly that the own-site layer is unavailable, and file the access grant as a prerequisite.
3. Mark every missing tool in the credential inventory. Offer to walk the user through sign-up for any missing tool.

---

## Inputs the playbook accepts

Prompted at the start of the run. Default from `CLAUDE.md` where populated.

| Input | Required | Example |
|---|---|---|
| Brand name | Yes | `Incred Golf` |
| Brand URL | Yes | `https://incred.golf` |
| ICP one-liner | Yes | `Club golfers in the US aged 35 to 55 working on wedge consistency` |
| Competitor URLs | Yes | 3 to 5 URLs for Full mode, 1 for Quick |
| Target geography | Yes | `United States` |
| Current content inventory | Yes | `12 blog posts, all published in 2024, no structured clusters` |
| Monthly organic traffic band | Yes | `under 1,000`, `1k to 10k`, `10k to 50k`, `50k+` |
| AEO priorities | Yes | Which LLM the ICP uses most (`ChatGPT`, `Perplexity`, `Claude`, `Google AI Overview`) |
| Existing topic clusters | Optional | `technique, equipment, practice, tour-player deep-dives` |
| Mode | Auto | Detected and confirmed |

---

## Output: one consolidated report, two formats

```
{client_folder}/docs/content-gap/{YYYY-MM-DD}/content-gap-report.md
{client_folder}/docs/content-gap/{YYYY-MM-DD}/content-gap-report.docx
```

Supporting evidence:

```
{client_folder}/data/content-gap/{YYYY-MM-DD}/
  - own-site-inventory.csv
  - gsc-queries-top1000.csv
  - competitor-rankings-{slug}.csv (one per competitor)
  - keyword-gap-raw.csv
  - aeo-probe-log.csv
  - scored-opportunities.csv
  - clusters.md
```

Report length: 5,000 to 9,000 words. Briefs for top 10 live inside the report, cross-linked to their cluster.

### Report structure (fixed order)

```
# Content Gap + AEO Opportunity Report: {Brand} ({YYYY-MM-DD})

Mode: {Full-A / Full-B / Quick / AEO-only / Cluster-deep}
Access level: {External only / External + GSC}

## Executive summary
3 to 4 sentences. Leads with the single cluster the brand should launch first and why, plus the headline opportunity band (total monthly search volume surfaced, estimated captureable share).

## Cross-cutting themes
3 to 5 synthesis bullets. Each spans at least two of the eight sections.

## Key findings
5 to 7 one-sentence bullets, one per section.

## Top 10 briefed opportunities (quick-reference table)
Table: rank, target keyword, cluster, opportunity score, intent, monthly volume, KD, AEO-extractable yes/no.

## 1. Own-site content inventory
## 2. Competitor content footprint
## 3. Keyword gap
## 4. AEO citation audit
## 5. SERP intent map and topic clusters
## 6. Opportunity scoring
## 7. Content pillar + cluster plan
## 8. Top 10 full content briefs

## 30-60-90 publishing plan
30-day actions, 60-day actions, 90-day actions. Each row: what ships, who owns, what metric to watch.

## Access-grant checklist
(Only appears if GSC or GA4 is missing.)

## Conclusion
2 to 3 paragraphs. What to publish this week. Where to learn more about ongoing support if the founder wants this run for them. Book-a-call CTA.
```

### Synthesis pass (mandatory before writing to disk)

Assemble sections 1 through 8 as a single draft. Read end-to-end in one pass. Ask:

- What pattern emerges across three or more sections that no single section captures?
- Which clusters show up as gaps in both the keyword layer (Section 3) and the AEO layer (Section 4)? Those are the double-hit priorities.
- Which SERP intents (Section 5) are the brand's existing pages targeting, and which are they ignoring? Does the 30-60-90 plan rebalance toward the ignored intents?
- Is there a strategic narrative the Executive Summary placeholder misses?

Produce 3 to 5 cross-cutting insight bullets. Revise the Executive Summary. Re-rank Section 8 to promote multi-leverage briefs. Write the synthesis bullets into the Cross-cutting themes block. Generate the Key findings and Top 10 table from the re-ranked list.

---

## Section 1. Own-site content inventory

Runs on Path A only (or with a lightweight public crawl on Path B).

- Screaming Frog CLI crawl on the brand's domain. Export URL, title, meta description, canonical, word count, H1, internal-link count, indexable status.
- Cross-reference with GSC top 1,000 queries (if GSC configured). For each URL, tag: currently-ranking query (top keyword by impressions), current position, impressions over 90 days, CTR.
- Classify each page by content type: pillar, cluster sub-page, product page, category page, blog post, landing page, other.
- Flag orphan pages (zero internal links in), thin pages (under 300 words), outdated pages (last-modified over 18 months).

Deliverable: inventory CSV plus a 200-word narrative of the existing content footprint. Path B stub: "Greenfield brand. Own-site inventory covers product and category pages only. Full content inventory unlocks once the first editorial cluster ships."

## Section 2. Competitor content footprint

**Step 0 — competitor-set + benchmarking opt-in.** Run the competitor-set decision tree from `PLAYBOOK-TEMPLATE.md`. Use the `## Competitors` block in `{client}/CLAUDE.md` if populated, otherwise auto-propose from the head-term SERP data and ask the user to confirm/swap/skip.

**Conditional BT deliverables (when a competitor set exists):**
- `BT-CONTENT-publishing-cadence.md` — posts/month, total post count, content depth, internal-linking density.
- `BT-SEO-organic-visibility.md` (if not already produced by a parallel SEO audit run).

If skipped, note in the deliverable: "Benchmarking skipped — no competitor set provided."

Runs on the external layer. For each competitor URL:

- Pull top 100 organic keywords via Ahrefs or DataForSEO `labs_ranked_keywords`. Capture keyword, volume, difficulty, position, landing-page URL.
- Pull top 50 organic landing pages. Capture URL, page title, estimated monthly organic traffic, top ranking keyword, topic cluster.
- Cluster the top 50 pages into 4 to 8 topic buckets per competitor. Cluster labels should be plain English in the ICP's register (for example "wedge technique drills" over SEO-jargon like "short-game-content").
- Identify the competitor's strongest cluster (highest combined monthly traffic). Note its structure: is it a pillar-and-cluster architecture, a flat blog, a programmatic set of templated pages, a glossary?

Deliverable: per-competitor CSV and a 150-word narrative per competitor.

## Section 3. Keyword gap

Cross-competitor set-difference, then consolidation.

- Pull the client's ranking keywords (client ranked in top 100) via DataForSEO `labs_ranked_keywords` or GSC top-queries export.
- Pull each competitor's ranking keywords the same way.
- For each competitor, compute `competitor_keywords - client_keywords` in Python. Save per-competitor output as `keyword-gap-vs-{competitor}.csv`.
- **Union across all competitors into a single deduped master dataset.** For each keyword compute `num_competitors_ranking`, `aggregate_volume` (max observed), `max_difficulty`, `best_competitor_position`, `client_ranks` (boolean).
- Filter: keep keywords with difficulty under 40 and monthly volume above 30. Tighten or relax thresholds by brand authority (high-DR brands can pursue KD up to 60).
- Enrich each surviving keyword: SERP intent classification (informational, commercial, transactional, navigational) via DataForSEO SERP API or pattern-matching, CPC (commercial-intent proxy), SERP features present (featured snippet, AI Overview, PAA, video carousel, local pack).
- Score each keyword: `opportunity = aggregate_volume × num_competitors_ranking × max(1, 101 - max_difficulty) × (1 if not client_ranks else 0.3)`. The `(101 - max_difficulty)` factor keeps the score positive across DataForSEO's 0-100 KD scale. Rank descending.

Deliverables:
- `keyword-gap-consolidated.csv` — the unioned, enriched, scored master dataset. This is the primary artefact that feeds Sections 5 through 8.
- `keyword-gap-vs-{competitor}.csv` — per-competitor raw outputs retained as evidence.
- 200-word narrative on the 3 to 5 themes dominating the gap.

**Tool-note (critical):** do not use `seo_toolkit.py keyword-research` gap mode or DataForSEO `labs_keyword_intersection`. Both return intersections (keywords ranked by both domains) when the analysis needs the set difference. Compute the delta manually in Python.

**On-page-signal fallback.** When DataForSEO and Ahrefs are both unavailable: WebFetch each competitor's and the client's homepage, top 10 nav links, top 5 collection pages, top 5 PDPs, and blog index. Extract titles, meta descriptions, H1/H2 blocks, URL slug tokens, schema markup, anchor text. Produce `fallback-onpage-signals.csv` per domain. Run the consolidation on this reduced dataset and label deliverables "on-page signals only, no ranking or volume data". Sections 4 through 8 still run, honestly flagged.

### Section 3.5. SERP-feature mining

Pure ranked-keyword data answers "what competitors rank for". PAA, related searches, and autocomplete answer "what buyers type". The two frequently diverge. Mining both layers fills the long-tail and AEO-extractable layer the set-difference misses.

For the top 20 to 30 head-term queries from the consolidated universe (by opportunity score, skipping head terms the client already owns position 1):

- Serper `/search` on each head term. Parse `peopleAlsoAsk[]` (4 to 8 questions per query) and `relatedSearches[]` (8 to 12 suggestions).
- Serper `/autocomplete` on the head term plus pattern-completions: `{head_term}`, `best {head_term}`, `how to {head_term}`.
- Fallbacks: `WebSearch` returns related searches reliably. Autocomplete falls back to manual incognito-Chrome capture exported to CSV. Log the gap honestly when paid endpoints are missing.

Compile: `serp-features-mined.csv` with columns `head_term`, `feature_type` (paa / related / autocomplete), `text`, `implied_intent`, `semantic_cluster`.

Cluster the mined phrases against Section 3 clusters. Phrases that do not attach to any existing cluster typically signal a new long-tail cluster the ranked-keyword pull missed. Flag these explicitly.

Every mined phrase the client's existing content does not address becomes a candidate for: an FAQ block on an existing page, a new H3 section inside an existing pillar, or a dedicated page where volume justifies it. These candidates feed Sections 7 (pillar planning) and 4 (AEO remediation).

Deliverable: `serp-features-mined.csv` plus a 150-word narrative on the most surprising buyer-language patterns.

## Section 4. AEO citation audit

Runs on the external layer.

- Draft 30 to 50 category questions covering the full buyer journey: early-stage educational ("what is X"), mid-stage comparison ("X vs Y"), late-stage commercial ("best X for Y"), post-purchase support ("how to use X").
- Probe each question across four engines: ChatGPT (live browsing enabled), Claude (with web search), Perplexity, Google AI Overview (via Serper).
- For each probe record: is the client brand cited, which competitors are cited, does an AI Overview or LLM answer exist at all, what sources are cited (own-site articles, Reddit, Quora, competitor pages, third-party publishers).
- Classify each question into one of four buckets:
  - **Competitor-owned** (two or more competitors cited, client absent)
  - **Category-whitespace** (no strong citations from anyone; AI answers from low-authority sources or hedges)
  - **Client-present** (client cited alongside others)
  - **Unanswered** (engine declines to answer or gives a generic non-specific response)

Deliverable: AEO probe CSV (one row per question per engine), plus a 250-word narrative on which buckets the questions cluster into and which are the highest-opportunity AEO targets. Category-whitespace questions are the fastest AEO wins. Competitor-owned questions are the hardest but highest-prestige wins.

## Section 5. SERP intent map and topic clusters

Cluster every keyword from Section 3 and every question from Section 4 into 4 to 8 topic clusters. Clustering rules:

- Start from the competitor cluster labels produced in Section 2. Use them as the initial taxonomy.
- Keep cluster labels in the ICP's own register. Plain-English over SEO-jargon.
- Within each cluster, map every keyword and question to one of four SERP intents: informational, commercial, transactional, navigational.
- Identify the pillar opportunity per cluster (the highest-volume informational keyword that can anchor a long-form guide). Every cluster needs a pillar. Sub-pages link up to the pillar, the pillar links down to the sub-pages.
- Flag any cluster where the AEO layer (Section 4) and the keyword layer (Section 3) both show whitespace. These are the double-hit clusters and should sort to the top of Section 7.

Deliverable: `clusters.md` with the full taxonomy, pillar opportunity per cluster, and sub-page map.

## Section 6. Opportunity scoring

Every surviving keyword and AEO question gets scored. Composite score, 0 to 1,000.

| Factor | Weight | Definition | Scale |
|---|---|---|---|
| Volume | 25% | Monthly search volume for the keyword | Log-scaled 1 to 10 (10 = over 10,000/mo) |
| Ease of ranking | 20% | Inverse of keyword difficulty | 1 to 10 (10 = KD under 10) |
| AEO extractability | 20% | How extractable the likely page is by LLMs (crisp definition, comparison table, FAQ, schema candidate) | 1 to 10, manually assigned |
| Commercial intent | 20% | Based on CPC and SERP intent classification | 1 to 10 (10 = transactional with CPC over $10) |
| Client fit | 15% | Alignment with the brand's positioning and catalogue | 1 to 10, manually assigned |

**Score = Volume × Ease × AEO_extractability × Commercial_intent × Client_fit ÷ 100.** Rank descending. Top 20 to 50 enter the roadmap. Top 10 go to briefs.

Effort sits outside the composite score and acts as a tiebreaker. Within a score band, prefer lower-effort pieces first (under 1,500 words, no custom graphics, existing internal expertise).

Deliverable: scored-opportunities CSV sorted by composite score descending.

## Section 7. Content pillar + cluster plan

Group the top 20 to 50 ranked opportunities into their clusters (Section 5). For each cluster:

- **Pillar page.** Identify the single anchor page for the cluster. State its working title, target keyword, intended length (2,500 to 5,000 words), and sub-page fan-out.
- **Sub-pages.** 3 to 8 sub-pages per cluster, each targeting one scored opportunity. State working title, target keyword, intent, length target.
- **Internal-link map.** Every sub-page links up to the pillar. The pillar links down to every sub-page. Cross-cluster links where semantically justified.
- **Publishing sequence.** Order within the cluster: pillar first where cluster has no existing coverage, or sub-pages first where a pillar equivalent already exists and needs expansion.

Deliverable: the cluster plan, typically 4 to 8 clusters with 20 to 40 sub-pages total.

## Section 8. Top 10 full content briefs

For the top 10 scored opportunities, produce a full production-ready brief. Each brief contains:

- **Working title.** Optimised for SERP CTR. Writer and editor use it as the publish-ready headline.
- **Target keyword** and estimated monthly volume, difficulty, SERP intent.
- **Secondary keywords** (3 to 5 semantically related terms to weave in).
- **Search intent and audience.** Two sentences on who types this query and what they are trying to accomplish.
- **Competitor-beating angle.** What the top-ranking pages miss. This is the reason the brand's page will rank or get cited. Derived from a manual read of the top 3 SERP results for the keyword.
- **AEO-extraction structure.** H2s framed as questions where sensible. Direct-answer paragraph under each H2. FAQ block at the bottom with 5 to 8 questions. Schema recommendations (Article, FAQ, HowTo, Product as applicable).
- **Internal-link map.** 3 to 6 internal links to related pages (pillar, sub-pages, product or category pages).
- **Recommended external citations.** 3 to 5 authoritative sources to cite. Raises AEO extractability via the Princeton GEO cite-sources effect (+40% visibility).
- **Statistics to include.** 2 to 4 category statistics with named sources. Adds the Princeton GEO add-statistics effect (+37%).
- **Expert quotes or attribution.** 1 to 2 quotes from category experts (with name, title, source) if attainable.
- **Word count target.** 1,200 to 3,500 words based on SERP depth.
- **Production lift.** One line on what it takes to produce this (existing internal expertise, external interview, data pull, original research).

Deliverable: 10 briefs embedded in the report. Each brief 300 to 500 words.

---

## 30-60-90 publishing plan

After Section 8, map the top 10 briefs plus the next 10 to 20 opportunities into a production calendar.

| Horizon | Actions |
|---|---|
| 30 days | Publish top 3 briefs. Ship the pillar for the single highest-priority cluster. Instrument tracking (GSC, GA4 events per cluster). |
| 60 days | Publish briefs 4 through 8. Begin second cluster. Refresh two existing pages that scored high in the Section 3 gap. Re-probe AEO engines on the 30-day published pieces to confirm extraction. |
| 90 days | Publish briefs 9 and 10. Complete the pillar-and-cluster architecture for the top two clusters. Review opportunity scores against early performance data and reprioritise the roadmap. |

---

## Voice conventions (strict)

- No em-dashes. Period, comma, colon.
- No negative parallelisms. State the positive.
- Four-word sentence floor.
- "ecommerce" one word.
- No AI clichés.
- Every claim traces to data. No fabricated volumes. No invented competitor rankings. Where a tool call fails, state it and move on.

### Voice enforcement gate (mandatory before writing to disk)

Grep the full draft for each banned pattern:

| Banned | Grep for | Fix |
|---|---|---|
| Em-dash | `—` (U+2014), `--` used as em-dash | Replace with period, comma, or colon |
| Negative parallelism | `, not `, ` rather than `, ` instead of `, `opposite of `, `not only ` | State the positive claim alone |
| Banned spelling | `e-commerce`, `E-commerce`, `E-Commerce` | Replace with `ecommerce` |
| AI clichés | `Here's the`, `Here's what`, `Here's why`, `Most people`, `The uncomfortable truth`, `The brutal truth`, `The breakthrough` | Rewrite without the cliché frame |
| Sub-four-word sentence | Sentences of 1 to 3 words standing alone | Merge or expand |

Zero matches before write. Sub-agents drafting sections must run the same pass on returned output.

---


## Output formatting: bullets over paragraphs (mandatory for every report and summary)

When this playbook generates a report, executive summary, brief, or any deliverable with multiple findings or actions, the default output structure is bullet lists, not prose paragraphs.

- Any time the text enumerates three or more items (findings, fixes, gaps, recommendations, criteria, things-they-do-better) those items become separate bullets. Do not bury enumerated points inside a paragraph.
- Reserve paragraphs for genuinely connected reasoning where prose flow carries the argument. Cap those paragraphs at four sentences.
- Multi-clause sentences with semi-colons or commas separating discrete points are a signal to break into bullets.
- The canonical pattern is: heading + one lead-in sentence + bullet list. The lead-in frames the list; the bullets carry the load.
- Reports ship scannable. The reader skims on a phone between meetings.

Run a paragraph-density check before commit: any paragraph longer than four sentences, or containing three or more enumerated items inside prose, is a candidate for bullet conversion. Convert it.

Applies to: full reports, executive summaries, email overviews, weekly reviews, dashboards, action-item lists, and any narrative deliverable. Does not apply to: opening framing paragraphs (one paragraph allowed), conclusion paragraphs (one or two allowed), or quoted founder/buyer voice.

## Acceptance criteria

- Runs end-to-end from a single Claude Code prompt.
- Detects the correct mode and adapts the section depth.
- Produces the scored opportunity list (20 to 50 entries) with transparent per-factor scoring.
- Delivers 10 full content briefs inside the consolidated report, each with the 11-field brief structure.
- Cross-cutting themes surface at least one insight spanning Sections 3 (keyword gap), 4 (AEO citation), and 5 (cluster map).
- Honest stubs where GSC is missing. Access-grant checklist populated.
- Voice gate runs before write. Zero banned-pattern matches.
- Consolidated report at `{client_folder}/docs/content-gap/{YYYY-MM-DD}/content-gap-report.md`, Word doc alongside. Supporting CSVs in the data folder.

---

## Reference material

- `gtm-audit.md`: sister synthesis playbook covering keyword-gap analysis at Section 3.3.
- `scripts/seo/seo_toolkit.py`, `dataforseo_client.py`, `keywords_everywhere_client.py`, `serper_client.py`: wired clients.
- Princeton GEO paper (2024): visibility-boost coefficients used in Section 6's AEO-extractability scoring.
