{"version":"2026-07-04","name":"Visa Atlas technical SEO/GEO control matrix","description":"Audit-ready control matrix for rendering, indexability, schema, open-data discovery, AI retrieval, freshness, performance and private-evidence boundaries behind the Visa Atlas SEO/GEO plan.","license":"CC BY 4.0","attribution":"Visa Atlas","sourceDatasets":["/api/public/visibility-metrics","/api/public/traffic-forecast","/api/public/content-opportunities","/api/public/execution-readiness","/api/public/crawler-access","/api/public/indexable-pages","/api/public/search-index","/api/public/battlecard-search-experiments","/api/public/quarterly-market-share-summary"],"methodology":{"sourceOfTruth":"Controls consolidate existing source audits, rendered artifact checks, public dataset contracts and local evidence workflows. They are an audit matrix, not a separate traffic or ranking claim.","cadence":"Run source controls on every SEO/GEO change, rendered controls after production build, liveness controls before source-refresh sign-off, and private evidence controls before publishing any outcome claim.","versionInputs":{"visibilityMetricsVersion":"2026-07-03","trafficForecastVersion":"2026-07-03","contentOpportunityVersion":"2026-07-03","crawlerAccessVersion":"2026-07-03","indexablePageManifestVersion":"2026-07-03"},"privateEvidencePolicy":"Private analytics, Search Console exports, server logs, screenshots, transcripts, outreach records and reviewer notes stay local unless converted into separately reviewed aggregate evidence.","caveats":["Passing these controls does not guarantee rankings, traffic, AI citations, backlinks or market share.","A failed critical control blocks release or page expansion until corrected.","Controls prove implementation and governance; business outcomes still require reviewed GSC, AI citation, referral and authority evidence."]},"summary":{"controlCount":9,"criticalCount":6,"highCount":3,"publicSurfaceCount":37,"commandCount":27},"controls":[{"id":"release-gate-chain","label":"SEO/GEO release gate chain","category":"evidence-governance","severity":"critical","auditObjective":"Every growth-facing change must pass type checking, source audits, freshness controls, production build and rendered artifact checks before release.","requiredSurfaces":["/api/public/visibility-metrics","/visibility-metrics","scripts/seo-geo-release-gate.mjs"],"evidenceCommands":["npm run audit:seo-geo","npm run audit:release-gate","npm run audit:execution-readiness","npm run audit:postbuild"],"passCriteria":["TypeScript compiles with no emit.","Source/template SEO/GEO audits pass before build.","Production build completes with the canonical site URL.","Rendered artifact and build-performance budget audits pass against .next output."],"failureResponse":["Block release until the failing gate is fixed.","Do not publish traffic, ranking, citation or market-share claims from a failed gate."],"relatedForecastCohorts":["calculators-tools","data-reference","freshness-policy","longtail-navigation","research-authority"],"privateEvidenceBoundary":"The gate proves local controls passed; it does not publish private analytics, raw Search Console exports or server logs."},{"id":"static-rendering-canonical-control","label":"Static rendering, canonical and noindex control","category":"rendering","severity":"critical","auditObjective":"Crawlers and AI retrievers must receive complete server-rendered HTML with canonical URLs, legal scope text, citations and no accidental noindex on indexable targets.","requiredSurfaces":["/sitemap.xml","/api/public/indexable-pages","/api/public/search-index","/api/public/competitor-query-battlecards"],"evidenceCommands":["npm run audit:rendered-seo","npm run audit:indexable-page-manifest","npm run audit:noindex"],"passCriteria":["Representative built pages contain canonical URLs and expected schema/citation snippets.","Indexable page manifest mirrors sitemap intent.","No known thin or disallowed page class is included in the sitemap."],"failureResponse":["Remove affected URLs from sitemap or apply noindex until source-backed value is restored.","Fix the rendered artifact, not only the source template."],"relatedForecastCohorts":["longtail-navigation","core-route-reference","data-reference"],"privateEvidenceBoundary":"Rendered artifacts and manifests are public; crawl impressions and query rows remain local until reviewed aggregate reporting."},{"id":"schema-citation-contract","label":"Structured data and citation contract","category":"structured-data","severity":"critical","auditObjective":"Public pages and JSON endpoints must expose honest Article, Dataset, DataDownload, WebAPI, WebApplication, ItemList and citation metadata without misleading ClaimReview markup.","requiredSurfaces":["/data","/api/public","/api/openapi.json","/citation-packs","/answer-capsules"],"evidenceCommands":["npm run audit:data-citation","npm run audit:webapi-schema","npm run audit:calculator-provenance","npm run audit:rendered-seo"],"passCriteria":["Dataset/DataDownload JSON-LD points at canonical JSON endpoints.","Calculator and tool pages expose provenance and WebApplication context where applicable.","Rendered audit rejects misleading ClaimReview or unsupported guarantee language."],"failureResponse":["Remove unsupported schema before release.","Prefer visible source provenance over schema-only trust signals."],"relatedForecastCohorts":["calculators-tools","data-reference","research-authority"],"privateEvidenceBoundary":"Schema describes public source-backed content only; reviewedBy and sameAs fragments remain blocked unless local evidence workflows approve them."},{"id":"open-data-discovery-control","label":"Open-data and API discovery control","category":"open-data","severity":"critical","auditObjective":"Every public dataset must be discoverable through /data, /api/public, OpenAPI, API reference, Link headers, Dataset JSON-LD, llms.txt and AI-agent guidance.","requiredSurfaces":["/data","/api/public","/api","/api/openapi.json","/ai-agents","/use-our-data","/llms.txt","/llms-full.txt"],"evidenceCommands":["npm run audit:data-front-door","npm run audit:openapi","npm run audit:mcp","npm run audit:rendered-seo"],"passCriteria":["PUBLIC_DATASETS count matches the catalog and rendered DataCatalog JSON-LD.","OpenAPI includes each dataset route.","LLM discovery files include strategic research, API and data endpoints."],"failureResponse":["Do not add a public endpoint without a catalog record and API reference entry.","Do not rely on a hidden JSON feed as a citation surface."],"relatedForecastCohorts":["data-reference","research-authority"],"privateEvidenceBoundary":"Public endpoints expose reusable metadata and controls; raw outreach, analytics, evidence logs and rejected submissions stay local."},{"id":"ai-retrieval-access-control","label":"AI and search crawler access control","category":"ai-retrieval","severity":"high","auditObjective":"Search and AI crawlers must be intentionally allowed, discover the site through robots/sitemaps/LLM indexes, and be measured from server logs rather than GA4 inference.","requiredSurfaces":["/robots.txt","/research/crawler-ai-retrieval-access-audit-2026","/api/public/crawler-access","/mcp"],"evidenceCommands":["npm run audit:visibility-metrics","npm run seo:botlog -- logs.txt --json","npm run audit:mcp"],"passCriteria":["Robots policy is generated from shared crawler allow/deny constants.","Crawler-access JSON and report explain live proof limits.","MCP and AI-agent surfaces expose read-only provenance-out tooling."],"failureResponse":["Fix robots, middleware or discovery headers before interpreting AI citation or referral metrics.","Require server-log evidence for crawler-fetch claims."],"relatedForecastCohorts":["research-authority","data-reference"],"privateEvidenceBoundary":"Server logs are local evidence. Public surfaces can publish reviewed aggregate crawler findings only after redaction and scope review."},{"id":"freshness-liveness-control","label":"Freshness and source-liveness control","category":"freshness","severity":"critical","auditObjective":"The site must not scale content or traffic assumptions when dated sources are stale, invalid or unverified against source liveness requirements.","requiredSurfaces":["/freshness","/api/public/freshness","/policy-updates","/api/public/fact-changes"],"evidenceCommands":["npm run audit:stale","npm run audit:freshness","npm run audit:seo-geo -- --include-liveness"],"passCriteria":["Public freshness report has zero stale and zero invalid dated source records.","Major release sign-off can include source liveness checks.","Policy and figure-change surfaces keep old/new values, dates and source URLs."],"failureResponse":["Freeze new content expansion for affected cohorts until freshness is restored.","Rebase any forecast range that depends on stale high-risk facts."],"relatedForecastCohorts":["freshness-policy","data-reference","core-route-reference"],"privateEvidenceBoundary":"Freshness status is public; source-refresh working notes and failed live probes can remain local until triaged."},{"id":"programmatic-page-quality-control","label":"Programmatic page quality and pruning control","category":"indexability","severity":"critical","auditObjective":"Long-tail route, corridor, profession and comparison pages should enter the index only when they provide unique source-backed value and useful next actions.","requiredSurfaces":["/compare","/professions","/from/indian/to/uk","/api/public/indexable-pages"],"evidenceCommands":["npm run audit:thin","npm run audit:noindex","npm run audit:longtail-depth","npm run audit:longtail-provenance"],"passCriteria":["Thin fallback combinations are excluded from sitemap and guarded from indexing.","Surviving long-tail pages include source-basis blocks and at-a-glance data.","Internal links route users and crawlers to stronger data, route and calculator pages."],"failureResponse":["Noindex or remove sparse page classes before adding more programmatic URLs.","Prioritise thickening and source provenance over raw URL count."],"relatedForecastCohorts":["longtail-navigation"],"privateEvidenceBoundary":"Indexability intent is public through sitemap and manifest; GSC URL performance exports stay local."},{"id":"client-bundle-performance-control","label":"Client bundle and interactive-tool performance control","category":"performance","severity":"high","auditObjective":"Interactive tools should remain usable without importing full datasets into client bundles or shifting crawler-visible source content behind client-only rendering.","requiredSurfaces":["/triage","/calculators","/widgets",".next/app-build-manifest.json",".next/build-manifest.json",".next/server/app"],"evidenceCommands":["npm run audit:triage-performance","npm run audit:calculator-provenance","npm run audit:rendered-seo","npm run audit:build-performance"],"passCriteria":["Root app JS stays within the 380 kB raw / 115 kB gzip post-build budget.","Representative route JS stays within the 425 kB raw / 130 kB gzip post-build budget.","Named data-heavy HTML and public feed artifacts stay within explicit .next/server/app payload budgets.","Calculator pages expose server-rendered context, provenance and worked examples where available.","Widgets and tools keep required attribution and source links."],"failureResponse":["Move bulky data and source-backed explanatory content back to server-rendered surfaces.","Do not accept client interactivity that hides the answer layer from crawlers."],"relatedForecastCohorts":["calculators-tools"],"privateEvidenceBoundary":"Bundle sizes and rendered output are public build evidence; user-entered calculator profiles are never logged or published by these controls."},{"id":"experiment-evidence-boundary-control","label":"Experiment and private evidence boundary control","category":"evidence-governance","severity":"high","auditObjective":"GSC, GA4, bot-log, SERP snapshot, market-share and authority-distribution evidence must be collected with declared scope and kept private until converted into reviewed aggregate evidence.","requiredSurfaces":["/api/public/battlecard-search-experiments","/api/public/quarterly-market-share-summary","/api/public/visibility-metrics","/api/public/authority-distribution-plan"],"evidenceCommands":["npm run seo:gsc-cohorts -- gsc-pages.csv --json --period-start=YYYY-MM-DD --period-end=YYYY-MM-DD --property-label=gsc-domain-redacted --search-type=web","npm run seo:gsc-experiment-outcomes -- gsc-experiment-outcomes.jsonl --json","npm run seo:ai-referrals -- analytics-referrers.csv --json --period-start=YYYY-MM-DD --period-end=YYYY-MM-DD --property-label=ga4-redacted --bot-filtered","npm run seo:market-share-summary -- surface-summary.json --json"],"passCriteria":["Local evidence commands require period, property/search type or bot-filter context where relevant.","Public datasets publish protocols and approved aggregate fields, not raw private exports.","Outcome claims require reviewed scope-matched evidence rows."],"failureResponse":["Reject unscoped or unredacted evidence from public claims.","Treat anecdotal wins as local notes until the aggregate review contract passes."],"relatedForecastCohorts":["calculators-tools","data-reference","research-authority","longtail-navigation"],"privateEvidenceBoundary":"Raw GSC, GA4, bot-log, screenshots, transcripts and outreach records stay local unless separately reviewed, redacted and aggregated."}]}