From 0 to 71/71: Building a GEO Compliance Audit System

social card 898 from 0 to 71 71 building a geo compliance audit system
From 0 to 71/71: Building a GEO Compliance Audit System

What happens when you email a plugin’s support team, answer their follow-up question in full, and never hear back

TL;DR

RankMath had compatibility issues with custom PHP implementations — 10 failures in 9 days, none visible on the frontend. We emailed support, answered their follow-up with full technical detail, and heard nothing back. So we built a 6-module, 71-check audit system from scratch. It runs the full site in 1 minute 38 seconds and catches things no SEO plugin is designed to catch.

The distinction that makes it different: RankMath audits pages. This audits the site.

Score Manual Mar 3–4 60/60 Mar 10 65/69 Mar 11 AM 71/71 Mar 11 PM 100% Audit score progression — 8 days from first check to 71/71
Figure 1. Audit score progression from manual review to 71/71 automated pass in 8 days.

The Story

On 3 March we sent a professional email asking three technical questions about RankMath compatibility with custom PHP implementations:

  1. “Known conflicts with custom PHP implementations?”
  2. “Recommended hooks/filters to prevent interference?”
  3. “Whether specific modules within Rank Math should be disabled in cases involving custom scripts?”

Bhanu replied, asking for more specifics. So we sent them: two fully documented conflicts, exact filter names, the mu-plugin workaround we’d already built, and two precise questions — whether RankMath had a supported way to control JSON-LD entity ordering, and whether there was a filter to override the author @id URL without changing the WordPress username.

Then silence.

We had already answered their follow-up. We had already built the workaround. We just wanted to know if there was a supported path that wouldn’t break on the next RankMath update. That answer never came.

The full list of what was breaking — 10 RankMath issues across 9 days, none of them visible on the frontend — is documented in 10 RankMath Issues in 9 Days.

Why a Custom Audit System — WordPress Architecture

RankMath audits pages. What we needed was something that audits the site.

That distinction sounds small. It isn’t. A plugin that checks one page at a time cannot detect cross-page schema conflicts, entity naming drift, or consistency failures that only appear when you look at the full page set together. It also can’t verify that its own output is landing correctly — which, on custom PHP templates, it wasn’t.

By Mar 4 we’d already built two mu-plugins to patch around RankMath’s behavior: geolab-entity-fix.php to intercept and rewrite its schema output, and rankmath-rest-api.php to expose its meta fields to the REST API. We were verifying fixes manually, round by round, with no systematic way to confirm nothing had regressed elsewhere on the site.

audit.py was the systematic way.

Going deeper? The GEO Workbook is a 30-day action plan that turns the GEO Stack framework into daily tasks — one section per day, measurable progress each week.

The Build: 6 Modules, 71 Checks — GEO Stack

Built on Mar 10 — seven days after the email to Bhanu, still no reply. Six modules covering the full GEO compliance stack, each targeting a specific layer of what the manual optimization rounds had been checking by hand.

Module 1 — Theme Files

<0.1s

Theme structure, functions.php enqueue registration, FSE template and parts existence, hook and filter wiring. Fast infrastructure verification — confirms the theme layer is assembled correctly before the heavier modules run.

Module 2 — Schema

<0.1s

Every structured data declaration across all deployed pages. Catches duplicate schema types, missing required properties, malformed JSON-LD, and entity ordering — the check that flagged SCHEMA_FAQPAGE_DUPLICATE_001 before GSC did, and that verified the Round 6 entity regression was resolved.

Module 3 — SEO Config

<0.1s

RankMath integration checks, functions.php references, robots.txt and sitemap existence. Verifies configuration state — confirms RankMath’s hooks are wiring correctly after each mu-plugin patch.

Module 4 — Performance

<0.1s

Page load signals, asset loading, caching state. Infrastructure health checks that run fast because they’re testing known endpoints rather than parsing page content.

Module 5 — GEO Compliance (regex-based checks via Python)

109.6s — 85% of total runtime

Each of the 14 content pages fetched and checked against the full GEO Stack: TL;DR presence, Key Takeaways sections, H1 entity match, testimonial and review schema, retrievability signals, extractability markers, structural authority. Slow by design — 14 pages × N checks via wp post get for each criterion. This is the module that surfaced the four content compliance failures at 65/69, and the module that doesn’t exist anywhere in standard SEO tooling.

Module 6 — AI Visibility

18.3s

Cross-link integrity, internal reference scanning, and AI visibility signals checked across the full page set simultaneously. The module that no per-page SEO plugin runs — because per-page tooling has no concept of site-level consistency. A page can pass every individual check and still create conflicts when the full set is viewed together.

The Journey: 0 → 71/71

Date State What happened
Mar 3–4 8 manual rounds Entity schema conflicts, REST API gaps, and template issues resolved by hand. No audit system yet — just rounds of check, fix, recheck.
Mar 10 60/60 audit.py launched with 5 infrastructure modules. Passed immediately — the Round 1–8 work had already cleared the underlying issues. Score dropped when hard checks were added, not when the site got worse.
Mar 11 65/69 Expanded to 71 checks across 14 content pages. Four failures immediately: missing TL;DR blocks, wrong H1-to-meta ordering, missing version history sections across 7 pages. Content compliance gaps that manual review had missed.
Mar 11 71/71 All four gaps closed same day. Key Takeaways checks added during the same session, bringing the scale to 71. Still no reply from RankMath.

Hitting 71/71 felt like relief more than celebration. Not because it wasn’t satisfying — it was — but because it meant the system was finally telling the truth about the site. The manual rounds had been honest about what they could check. The audit system was honest about everything.

What It Catches That No Plugin Does

The entity schema regression in Round 6 is the clearest example. RankMath outputting “Artur Ferreira” as the primary entity name instead of “The GEO Lab” — title match false, H1 match false, conflicting entities flagged, entity score dropping across multiple pages simultaneously. No frontend symptom. No RankMath warning. No GSC notification. Invisible until something checked the full page set for entity consistency at once.

The audit system’s module architecture reflects the five-layer structure of the GEO Stack — each of the six modules maps to a specific layer, from Nginx crawl configuration and robots.txt (Layer 1) through entity schema and JSON-LD graph integrity (Layer 3).

That’s the category of failure a site-level audit catches and per-page tooling structurally cannot: not whether a page is valid, but whether the site is consistent.

The other category is regression detection. Once 71/71 is the baseline, any future change that breaks a check surfaces on the next audit run — not days later in GSC, not weeks later in a ranking drop, not never because nobody looked. The audit isn’t a one-time diagnostic. It’s the mechanism that keeps the baseline honest.

One category it doesn’t catch: failures on custom PHP templates that require manual inspection. WP_WPHEAD_MISSING_001 — three templates with no wp_head() call, no schema, no OG tags, no robots meta — was found manually during the Mar 10 session. Nothing in audit.py currently scans custom PHP templates for missing hook calls. It’s in the failure registry as a documented fix. It’s a gap worth naming.

Key GEO Takeaway

An audit system is only as useful as its ability to detect failures before deployment — not after. The gap between wp-cli audit and rendered-HTML audit exposed a class of mu-plugin injected content that the script couldn’t see. Building the audit to run against curl output rather than post_content was the architectural fix that made all nine pages pass.

Frequently Asked Questions

Why not use a standard SEO audit tool?

Standard SEO audit tools check rankings, backlinks, and technical health at the page level. They don’t check GEO compliance signals, cross-page schema consistency, entity naming drift, or REST API field registration. The gap isn’t a quality difference — it’s a scope difference. General SEO tooling isn’t built to audit a custom GEO implementation, and no amount of configuration changes that.

Can’t RankMath’s built-in schema validator catch these issues?

RankMath validates that its own JSON-LD output is syntactically correct. It doesn’t check for duplicate declarations caused by interactions with custom HTML components, cross-page entity inconsistencies, or whether its output is landing on pages built with custom PHP templates. Validating schema and auditing a site’s schema layer are different operations.

What does 71/71 mean in practice?

Every check across all six modules passes on all 14 deployed content pages simultaneously. Not each page in isolation — the full site, including cross-page consistency. It’s not a quality score; it’s a compliance baseline. A page can be well-written and structurally wrong for AI retrieval. 71/71 means the infrastructure underneath the content is working correctly and consistently.

How often does the audit run?

Manually, on demand — typically after any significant content change, schema update, or new page deployment. Full run: 1 minute 38 seconds. For a shareable audit report, the AI Visibility Diagnostics Console generates the PDF version.

What’s the relationship between the audit system and the GEO console?

The audit system is the technical compliance layer — it verifies the infrastructure is correct. The AI Visibility Diagnostics Console is the visibility layer — it measures how content performs against the GEO Stack and tracks citation outcomes. Both run on the same site. Neither replaces the other.

Version History

  • Version 1.0 — 12 March 2026: Initial publication. Documents the build of audit.py — 6 modules, 71 checks, 0 → 71/71 journey from Mar 10–11 2026.

What Practitioners Are Saying

“The module timing breakdown is the most honest part of this post. Module 5 taking 85% of runtime isn’t a design flaw — it’s what real compliance checking looks like at page scale. Most audit tools are fast because they don’t actually check what matters.”

— Daniel Cardoso, Head of Content Strategy, SaaSMetrics.io

“I built something similar for client sites. The failure that’s hardest to catch is always the one that passes the script but fails the rendered page. The mu-plugin gap described here is exactly that class of failure — and the curl-based verification is the right fix.”

— Marco Silva, Technical SEO Lead, VisibilityStack

About the author: Artur Ferreira is the founder of The GEO Lab with over 20 years (since 2004) of experience in SEO and organic growth strategy. He developed the GEO Stack framework and leads research into Generative Engine Optimisation methodologies. Connect on X/Twitter or LinkedIn.

Have questions? Contact The GEO Lab