# angeo/module-aeo-audit

> Magento 2 AEO (AI Engine Optimization) Audit. v3 covers 15 signals — robots.txt AI bots, llms.txt + llms.jsonl, Product / Organization / FAQ schema, merchant return + shipping policies, sitemap.xml, UCP profile, AI product feed, OG tags, canonical + hreflang, JSON-LD quality, well-known endpoint matrix, Core Web Vitals via CrUX. Score Trend dashboard, Admin UI, cron, dynamic fix commands, dependency-injected extension point for custom checkers.

`composer require angeo/module-aeo-audit`

Canonical URL: https://packagento.com/angeo/module-aeo-audit

## At a glance

- **Vendor**: angeo (https://packagento.com/angeo.md)
- **Latest version**: 3.1.0 — released 2026-06-14
- **Pricing**: Free
- **Package type**: Magento 2 module
- **Status**: active, accepting new buyers

## Installation

Packagento is licence-gated, so even free packages need a licence on a project before Composer can resolve them.

1. **Sign in or create an account** at https://packagento.com/customer/account/.

2. **Add the package to your account.** Open https://packagento.com/angeo/module-aeo-audit and complete the free checkout. A licence is minted automatically.

3. **Create or pick a project, then activate the licence on it.**
   - Projects represent the Magento installs you deploy to. Manage them at https://packagento.com/projects/.
   - Activate the new licence on the project you'll deploy this package to. Activation is what generates the Composer credentials scoped to that project.

4. **Add the project credentials to your Magento codebase.**

   Grab the project's public + private key from https://packagento.com/projects/ (open the project, then its Credentials tab), and add them to `auth.json`:

   ```json
   {
     "http-basic": {
       "packagento.com": {
         "username": "ppk_live_...",
         "password": "psk_live_..."
       }
     }
   }
   ```

   Add the Packagento Composer repository to `composer.json`:

   ```json
   {
     "repositories": [
       { "type": "composer", "url": "https://packagento.com" }
     ]
   }
   ```

5. **Install and apply.**

   ```bash
   composer require angeo/module-aeo-audit:*
   bin/magento setup:upgrade
   bin/magento setup:di:compile
   bin/magento cache:flush
   ```

## What it does

Magento 2 AEO (AI Engine Optimization) Audit. v3 covers 15 signals — robots.txt AI bots, llms.txt + llms.jsonl, Product / Organization / FAQ schema, merchant return + shipping policies, sitemap.xml, UCP profile, AI product feed, OG tags, canonical + hreflang, JSON-LD quality, well-known endpoint matrix, Core Web Vitals via CrUX. Score Trend dashboard, Admin UI, cron, dynamic fix commands, dependency-injected extension point for custom checkers.

## README

[![Packagist Version](https://img.shields.io/packagist/v/angeo/module-aeo-audit.svg)](https://packagist.org/packages/angeo/module-aeo-audit)
[![Packagist Downloads](https://img.shields.io/packagist/dt/angeo/module-aeo-audit.svg)](https://packagist.org/packages/angeo/module-aeo-audit)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![PHP](https://img.shields.io/badge/php-%3E%3D8.2-8892BF.svg)](https://php.net)
[![Magento](https://img.shields.io/badge/magento-2.4.6%20%7C%202.4.7%20%7C%202.4.8-EE672F.svg)](https://magento.com)

**One CLI command that tells you exactly why ChatGPT, Gemini, Claude, and Perplexity aren't recommending your store — and how to fix it.**

- 🏠 Project home: [angeo.dev](https://angeo.dev)
- 📦 Source: [github.com/angeo-dev/module-aeo-audit](https://github.com/angeo-dev/module-aeo-audit)
- 🐛 Issues: [github.com/angeo-dev/module-aeo-audit/issues](https://github.com/angeo-dev/module-aeo-audit/issues)
- 📖 Full guide: [Magento 2 AEO Guide 2026](https://angeo.dev/magento-2-aeo-guide/)

---

### Compatibility

| Component | Version |
|---|---|
| Magento Open Source | 2.4.6, 2.4.7, 2.4.8 |
| Adobe Commerce | 2.4.6, 2.4.7, 2.4.8 |
| Adobe Commerce Cloud | All current versions |
| PHP | 8.2, 8.3, 8.4 |
| Themes | Luma, Hyvä |

Tested with: Magento Open Source 2.4.7-p3 + PHP 8.3 + Hyvä 1.3.

---

### What's new in v3.0.0

> **Major release** — see [CHANGELOG.md](CHANGELOG.md) for the breaking-change
> migration guide if you have custom checkers.

**15 signals** (up from 9), reflecting the actual AEO landscape of 2026: AI
shopping integrations, merchant policies, agentic commerce, and structured-data
quality.

**6 new checkers:**

- `merchant_policies` — `MerchantReturnPolicy` + `OfferShippingDetails` —
  required by Google AI Mode and ChatGPT Shopping since Jan 2026
- `organization_schema` — brand entity in AI knowledge graphs
- `ucp_profile` — Universal Commerce Protocol (`/.well-known/ucp`), with
  built-in security check that detects leaked JWK private keys
- `jsonld_quality` — three-page schema breadth audit (homepage / category /
  product), `WebSite+SearchAction`, `BreadcrumbList`, `ItemList`
- `well_known` — discovery matrix for `/.well-known/{ucp,ai-plugin.json,security.txt,mcp}`
- `core_web_vitals` — LCP / INP / CLS via Google CrUX API (free, opt-in
  with API key)

**Refactored architecture** (this is the BC-break):

- Shared `Service\HttpCache` — eliminates duplicate fetches across checkers
  (hundreds of redundant HTTP requests on multi-store audits before, dozens
  now)
- `Service\StoreUrlSampler` — single source of truth for product / category /
  CMS URL sampling
- New `--category` and `--fail-on-severity` CLI flags for CI workflows
- Per-checker exception isolation — slow or failing checkers no longer halt
  the audit run

> **Note on access-log monitoring**: an `ai_bot_traffic` checker was
> prototyped during v3 development and excluded from the release after
> security review — it encouraged broad read access on `/var/log/nginx/`,
> didn't work on Cloud/containerised hosting, and was dominated by false
> positives behind edge caches. AI-bot traffic is better measured at the
> edge (Fastly/Cloudflare Analytics) or via APM (New Relic, Datadog) than
> inside a PHP module. See CHANGELOG.md "Considered and rejected" for the
> full rationale. The `live_signal` category remains in `CheckerInterface`
> for third-party modules with secure live-signal sources — notably
> `angeo/module-aeo-brand-visibility`.

---

### What it checks — 15 signals

| #  | Signal | Code | Weight | Category | What it validates |
|----|--------|------|--------|----------|-------------------|
| 1  | **robots.txt — AI bots** | `robots_txt` | 1.0 | technical | 12 AI bots, syntax errors, versioned UAs, conflicting rules |
| 2  | **llms.txt — content map** | `llms_txt` | 1.0 | technical | Spec compliance + store-locale + currency match + cross-host links |
| 3  | **llms.jsonl — catalog** | `llms_jsonl` | 0.75 | technical | JSON Lines validity, required fields, eCommerce fields |
| 4  | **sitemap.xml** | `sitemap` | 0.8 | technical | XML, lastmod, `.gz`, catalog disproportion |
| 5  | **Product schema** | `product_schema` | 1.0 | technical | JSON-LD on real product, offers, Hyvä detection |
| 6  | **Merchant policies** ★ NEW | `merchant_policies` | 0.9 | technical | `hasMerchantReturnPolicy`, `OfferShippingDetails`, `priceValidUntil`, `itemCondition` |
| 7  | **Organization schema** ★ NEW | `organization_schema` | 0.8 | technical | `Organization` / `OnlineStore` on homepage, `sameAs`, logo |
| 8  | **UCP profile** ★ NEW | `ucp_profile` | 0.9 | technical | `/.well-known/ucp`, signing keys, leaked-private-key detection |
| 9  | **AI product feed** | `ai_product_feed` | 1.0 | feed | Feed file, `/.well-known/ai-plugin.json`, REST endpoint |
| 10 | **JSON-LD quality** ★ NEW | `jsonld_quality` | 0.7 | technical | Breadcrumb, ItemList, WebSite+SearchAction, duplicate schemas |
| 11 | **Canonical + hreflang** | `canonical` | 0.7 | technical | Canonical agrees with og:url + JSON-LD url; hreflang on multi-store |
| 12 | **Open Graph** | `open_graph` | 0.7 | technical | All 5 OG tags, description length |
| 13 | **FAQ schema** | `faq_schema` | 0.5 | technical | FAQPage JSON-LD on homepage or sampled CMS page |
| 14 | **Well-known matrix** ★ NEW | `well_known` | 0.5 | technical | ucp / ai-plugin.json / security.txt / mcp inventory |
| 15 | **Core Web Vitals** ★ NEW | `core_web_vitals` | 0.5 | external_api | LCP / INP / CLS via Google CrUX (API key required) |

★ NEW = added in v3.0.0.

---

### Installation

```bash
composer require angeo/module-aeo-audit
bin/magento setup:upgrade
bin/magento cache:flush
```

For full coverage, install the companion modules:

_(README truncated for .md surface. Full README on https://packagento.com/angeo/module-aeo-audit.)_

## Changelog

All notable changes to `angeo/module-aeo-audit` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### [3.1.0] — 2026-06-10

> Minor release. Adds per-signal enable/disable configuration, configurable
> sitemap placeholder-slug handling, and fixes two false-signal bugs in the
> sitemap checker. Fully backward compatible — no interface or DB changes.

#### Added

- **Per-signal configuration.** Every one of the 15 signals can now be enabled
  or disabled individually under **Stores → Configuration → Angeo AEO → AEO
  Audit → Signals (Checks)**. All signals are **enabled by default**, so a
  fresh install behaves exactly as before. Disabled signals are skipped during
  the audit and excluded from the score entirely — they neither raise nor lower
  it (removed from both numerator and denominator). Settings are store-scoped.
- **Configurable sitemap placeholder-slug handling.** New group **Angeo AEO →
  AEO Audit → Sitemap Checker**:
    - `Placeholder slug handling` — *Affect score* (default) or *Ignore*
      (report-only, never changes status/score).
    - `Placeholder slug threshold` — how many placeholder slugs are tolerated
      before the score is affected (default 1).
- New `Angeo\AeoAudit\Model\Config` — a single typed reader for all module
  settings, so checkers no longer touch `ScopeConfig` directly.
- New `Angeo\AeoAudit\Model\Config\Source\SlugMode` option source.
- Unit tests: disabled-checker skipping in `AuditRunner`; sitemap foreign-element
  FAIL; placeholder-slug score/ignore modes; disproportion-false-positive
  regression.

#### Fixed

- **Sitemap: false "disproportion" warning.** The v3 check compared sitemap URL
  count against active **products only**, but a sitemap also lists the homepage,
  CMS pages and categories — so healthy stores were frequently warned. URL count
  is now compared against the full indexable surface (products + categories +
  CMS pages) and reported as **informational context only** (`coverage_ratio`);
  it never changes the result status.
- **Sitemap: false "stale" warning.** Staleness was computed from the **first**
  `<lastmod>` in the file, so a single old entry (often the homepage or a CMS
  page) flagged the whole sitemap as stale. A legitimately unchanged product
  *should* keep an old `<lastmod>` — that is honest metadata, not a defect. The
  check now inspects the **newest** `<lastmod>` across the file and only warns
  if nothing at all has changed in 180 days (a sign of a broken generation
  cron). Individual old entries are informational only.

#### Added — sitemap structural integrity

- **Sitemap: foreign-element detection.** Non-sitemap elements injected directly
  into `<urlset>` (e.g. a stray `<script>` from a theme or module) are now
  detected and reported as a FAIL. `libxml` parses such markup without error, so
  the previous XML-validity check missed it.
- **Sitemap: placeholder-slug detection.** Slugs that carry no meaning for an AI
  engine (`test2.html`, `product-name.html`, bare numbers, etc.) are surfaced so
  they can be renamed. Behaviour is controlled by the new configuration above.

### [3.0.0] — 2026-05-22

> Major release. Adds 6 new checkers, refactors the checker architecture, and
> requires changes in third-party modules that implement `CheckerInterface`.

#### ⚠️ Breaking changes

_(Changelog truncated for .md surface. Full history on https://packagento.com/angeo/module-aeo-audit.)_

## Recent Versions

| Version | Released |
|---|---|
| 3.1.0 | 2026-06-14 |
| 3.0.0 | 2026-05-28 |
| 2.1.2 | 2026-05-15 |
| 2.1.1 | 2026-04-24 |
| 2.1.0 | 2026-04-24 |
| 2.0.1 | 2026-04-19 |
| 2.0.0 | 2026-04-16 |
| 1.0.0 | 2026-04-02 |

## Dependencies

### Require

| Package | Constraint |
|---|---|
| magento/framework | ^103.0 |
| magento/module-backend | ^102.0 |
| magento/module-catalog | ^104.0 |
| magento/module-cms | ^104.0 |
| magento/module-config | ^101.2 |
| magento/module-store | ^101.1 |
| magento/module-ui | ^101.2 |
| php | ~8.2.0\|\|~8.3.0\|\|~8.4.0 |

### Require (dev)

| Package | Constraint |
|---|---|
| magento/magento-coding-standard | ^33.0 |
| phpstan/phpstan | ^1.10 |
| phpunit/phpunit | ^10.0 |

### Suggest

| Package | Constraint |
|---|---|
| angeo/module-aeo-brand-visibility | Live AI visibility check across ChatGPT, Claude, Perplexity, Gemini |
| angeo/module-llms-txt | Generate llms.txt and llms.jsonl |
| angeo/module-openai-product-feed | ACP product feed for ChatGPT Shopping |
| angeo/module-openai-product-feed-api | REST API endpoints for ACP feed |
| angeo/module-rich-data | Product, Organization, FAQ JSON-LD and merchant policies |
| angeo/module-robots-txt-aeo | Fix robots.txt AI bot access |
| angeo/module-ucp | Universal Commerce Protocol profile (/.well-known/ucp) for Google AI Mode / Gemini |

## Quality

Latest release (3.1.0) fails the Packagento QA pipeline. Verdicts below are per-cell (Magento line × PHP version) for the matrixed tools, and run-once for the static / security tiers.


### Compatibility

Each Magento line is installed on its supported PHP versions, then the module is built (DI compile + static-content deploy). Cells show passed / failed / untested; staircase gaps render as `–`.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | Pass | Pass | – | – |
| 2.4.8 | – | Pass | Pass | – |
| 2.4.9 | – | – | Pass | not tested |


### Code Quality

Advisory checks against the module's source. Never affect the Compatibility verdict — a phpcs finding can't make a module incompatible.

#### Static Analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Fail | 60 | 3 errors, 57 warnings (ruleset: Magento2) — 19 auto-fixable with phpcbf |
| PHPMD | Warning | 48 | 48 rule violations (CyclomaticComplexity:13, NPathComplexity:13, ExcessiveMethodLength:8, MissingImport:5, UnusedFormalParameter:4) |
| Cpd | Pass | 0 |  |
| Composer validate | Pass | 0 |  |

#### PHPStan

Type-checks the module against a real Magento install. Re-runs per Magento + PHP version because resolvable symbols differ between releases.

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | 16 | 16 | – | – |
| 2.4.8 | – | 16 | 16 | – |
| 2.4.9 | – | – | 16 | N/A |


### Tests

Unit and integration suites run per Magento + PHP cell. Test failures speak to the module's behaviour, not its compatibility with a line, so they're reported here separately.

#### Unit Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | 12 | 12 | – | – |
| 2.4.8 | – | 12 | not tested | – |
| 2.4.9 | – | – | 13 | not tested |

#### Integration Tests

| Magento | PHP 8.2 | PHP 8.3 | PHP 8.4 | PHP 8.5 |
|---|---|---|---|---|
| 2.4.7 | N/A | N/A | – | – |
| 2.4.8 | – | N/A | N/A | – |
| 2.4.9 | – | – | N/A | N/A |


### Security

Dependency-advisory audit (composer audit) plus a source malware scan. A malware detection fails the version outright.

| Tool | Status | Findings | Summary |
|---|---|---|---|
| Composer audit | Pass | 0 |  |
| Malware scan | Pass | 0 |  |

## Licence and pricing

Free. A licence is still minted on checkout and bound to your project for Composer access — no payment step.

Refundable within 14 days of first purchase via https://packagento.com/account/refunds/.

## Install via Claude Code or any MCP client

The Packagento MCP server can run the licence + project + Composer steps above in one tool call:

```
purchase_and_install_packages(
  composer_names=["angeo/module-aeo-audit"],
  project_id="proj_xxx"
)
```

This handles cart, checkout, licence minting, project activation, and writes auth.json credentials. Connect a client with `claude mcp add packagento https://mcp.packagento.com`. Full setup at https://packagento.com/docs/mcp-setup.

## Vendor

angeo is a Magento 2 vendor on Packagento. See https://packagento.com/angeo.md for their full catalogue.

