Do AI engines cite your writing, and does optimizing for them cost you human readers?
The GEO ABCD Testbed is a self-contained split-testing rig that serves four rewrites of the same article from one canonical URL, then measures whether AI engines start citing the page more, and whether humans stop reading it.
What is GEO, in plain English?
A regular search engine hands you a list of blue links to click. The newer answer engines just write the answer for you. GEO is the craft of making sure that when an AI writes that answer, it uses, and credits, your words.
The catch: the same tweaks that make a page easy for a robot to quote can make it duller for a person to read. This project runs both audiences side by side and measures who wins, so optimization never quietly costs you human readers.
Being quoted is the new front page
When an AI answers a question, it may quote a handful of sources and the reader never clicks through. A citation in that answer is now prime real estate.
Four versions compete at once
This is an ABCD test: the same article, rewritten four ways, quietly served from one address. An automated reader (a crawler) or a person each get one version.
Robots and readers, measured together
The framework watches whether AI engines start quoting the page more and whether real people keep reading. Hover any highlighted term for a plain definition.
Generative engines answer instead of link. Writing for them shouldn't break the page for people.
Generative Engine Optimization (GEO) reshapes content so retrieval systems quote it. But heavier formatting can flatten the reading experience. This framework holds both truths on screen at once: citation lift and human engagement, per variant, concurrently.
Get retrieved & cited
Structure, phrasing, and machine-readable renditions that AI crawlers ingest and quote.
Keep humans reading
Session length and scroll depth tracked per variant, so degradation shows up immediately.
Prove which one won
Attribution watermarks tie a specific AI citation back to the exact variant it came from.
Two audiences, two assignment rules
Crawlers and humans answer different questions, so they're split differently. One middleware at the edge routes both from a single URL.
Pinned by calendar window
Each 14-day window maps deterministically to one variant. Every crawler that visits during a window sees the same stable version, so each engine's index holds exactly one variant at a time.
- Deterministic & reproducible per window
- Later AI referral clicks attribute back to the indexed variant
- Pre-epoch requests clamp to window 0 → v1
Split randomly, held stickily
First visit assigns a random variant via a geo_v cookie scoped to /writing/. Every return visit serves the same one, so engagement is measured cleanly per person.
- Sticky assignment across return visits
- Pageviews, session length & max scroll depth reported
- ~1 KB client beacon that fails silently
One article, four doses of optimization
A control and three escalating levels of GEO compete head to head. All four state the same facts, only the formatting and phrasing change.
Control
The original article, untouched. The baseline every other variant is measured against.
Light GEO
Gentle structural nudges: clearer headings and lead sentences that read the same to a person.
Balanced GEO
Moderate restructuring for retrievability while protecting narrative flow.
Heavy GEO
Aggressive machine-first formatting, the ceiling of the dose-response curve.
Everything the framework does
A complete measurement pipeline (assignment, serving, telemetry, attribution, and analysis) all at the edge with no runtime dependencies.
Deterministic bot pinning
Calendar-window assignment keeps each engine's index on one stable variant, so citations map cleanly to a version.
Sticky human split & telemetry
A first-party geo_v cookie plus a ~1 KB beacon reports pageviews, session length and max scroll depth per variant.
Attribution watermarks
Each variant states one true fact in unique phrasing at the same position. Grep an AI answer for the string to identify the ingested variant.
Pre-compiled Markdown renditions
A static Markdown file (.md) ships beside each variant and serves on Accept: text/markdown. Deterministic, diffable, drift-free.
Edge CSS inlining
Local stylesheets are inlined at the edge via HTMLRewriter, and the content type on /.well-known/api-catalog is fixed on the fly.
Fail-silent safety valve
Every fallback logs before it degrades. If the rig throws, the reader still gets the page; missing variants fall back to v1, never a 404.
Blocker-neutral ingestion
Neutrally named beacon and endpoint dodge tracker filter lists; a server-side serve_log exposes blocker interference as a delivery gap.
Self-explaining dashboard
A hardened analytics console at /admin/geo with per-section help, glossaries, delivery colour legends, and CSV export.
CSP-hardened & self-hosted
No third-party runtime scripts. A pinned, self-compiled stylesheet and per-request nonce'd CSP lock the admin surface down.
Single source of truth
Slug, epoch, windows, bot list and watermarks all live in one config.js that the router and dashboard both import.
Referrers prove an engine sent traffic. Watermarks prove which variant earned the citation.
Because bot pinning rotates variants, every engine's index eventually holds all four, so a referral timestamp can't say which version was quoted. Instead, each variant phrases the same true fact uniquely. When an AI answer reproduces one of those strings, it names the source. npm run build refuses to ship if any output is missing its own watermark or carries another's.
$ grep -f watermarks.txt ai-answer.txt
v1 "24,303 passages…"
v2 "…an index of 24,303 passages"
v3 "the corpus spans 24,303 passages" ✓ match
v4 "24,303 indexed passages…"
$ echo "cited variant → v3 (Balanced GEO)"
cited variant → v3 (Balanced GEO)
Read the whole experiment on one page
The /admin/geo dashboard turns raw D1 rows into three answers, with plain-English help, click-to-explain tooltips, and a colour-coded delivery legend built in. Here is the current build, reading seeded test data:
Are humans still reading?
Pageviews, average session length and max scroll depth per variant, with "low n" flags on small samples so early numbers aren't over-read.
Did the beacon get through?
Delivery % (pageviews ÷ server-side serves) per traffic source detects ad-blocker interference, colour-coded green / amber / red.
Which variant is indexed now?
Per-window bot hits with the current window highlighted and the live variant badge ringed in gold, plus the four watermark strings inline.
Built to run on the edge, forever, for pennies
Cloudflare Pages Functions on V8 workers, D1 for analytics, vanilla JavaScript on the client, and zero third-party runtime dependencies.
See the framework in the wild
Open the live test post (the edge will hand you one of four variants) or dive into the analytics console to watch citation lift and human engagement race each other in real time.