# The Agent-Readiness score

The score is a single number from 0 to 100. It is computed by arithmetic, not by a
language model, and the same inputs always produce the same output.

## The formula

The score is **penalty-based**. Every brand starts at 100 and loses points for
specific, named failures.

```
total = clamp(100 − (invisible_queries × 15) − (missing_signals × 10), 0, 100)
```

That is the whole formula. There are exactly two penalty terms.

| Penalty | Points | Triggered by |
|---|---|---|
| Invisible query | **15** each | A shopper question that engines answered, without naming the brand |
| Missing signal | **10** each | A structured-data signal the brand's archetype expects, verified absent |

!!!danger The total is not an average of the sub-scores
Visibility, recommendation rate, and technical readiness are **independent diagnostics**.
None of them feeds `total`. There is no weighted rubric and no four-dimension model —
documentation or tooling that implies one is describing something this system does not do.
!!!

## What counts as invisible

A query is penalized when engines answered it and a **majority did not name the brand**.
Concretely: of the mention rows for that query text, `invisible / total >= 0.5`.

A query with **zero** observations is `unobserved`. It is unverified, not failed, and
carries no penalty — though it still sits in the visibility denominator.

## The three sub-scores

Each is reported alongside the total as a diagnostic. Each is a percentage.

### Visibility

```
round(visible_queries / queries_attempted × 100)
```

The denominator is queries **attempted**, including ones no engine answered. An
unobserved query therefore lands in the denominator and in neither numerator — it
drags visibility down without costing the total any points. This is deliberate: it
signals thin evidence without punishing the brand for it.

### Recommendation rate

```
round(recommended_mentions / all_mentions × 100)
```

The share of all mention rows where the brand was actively recommended rather than
merely named. Reported under a "diagnostic" heading in the report because it is a
percentage of a variable-size denominator, not a 0–100 subscore.

### Technical readiness

```
round(present_signals / verifiable_checks × 100)
```

The denominator is the **verifiable** subset of the **archetype-applicable** checks.
Signals that could not be verified are excluded from both halves.

## The signal checks

Four checks per archetype, each worth 10 points when verified absent.

+++ ecommerce
| Check | Looks for |
|---|---|
| `product_schema` | `Product` / `ProductGroup` JSON-LD |
| `price_availability` | Price and availability in structured data |
| `review_markup` | Review / aggregate-rating markup |
| `llms_txt` | An **authored** `llms.txt` |
+++ service
| Check | Looks for |
|---|---|
| `organization_schema` | `Organization` JSON-LD |
| `service_schema` | `Service` JSON-LD |
| `faq_schema` | `FAQPage` JSON-LD |
| `llms_txt` | An **authored** `llms.txt` |
+++ saas
| Check | Looks for |
|---|---|
| `organization_schema` | `Organization` JSON-LD |
| `software_schema` | `SoftwareApplication` / `WebApplication` JSON-LD |
| `faq_schema` | `FAQPage` JSON-LD |
| `llms_txt` | An **authored** `llms.txt` |
+++ unknown
Scored on the **ecommerce** check set. This is deliberate — it is the pre-archetype
default, so an unclassifiable site is measured exactly as the system measured every
site before archetypes existed.
+++

!!!info `llms_txt` means authored, not served
A platform-generated `llms.txt` — the file some hosts emit by default — does not count.
The check classifies the file and returns `authored: false` for a generated one.
!!!

`review_markup` is dropped from the applicable set unless the crawl found strong
storefront evidence, so a brand with no cart is not penalized for missing review markup
on products it does not sell.

## Evidence gates

Before a score is issued at all, two coverage gates must pass.

| Gate | Threshold | Meaning |
|---|---|---|
| `coverage` | ≥ **0.60** | Share of attempted engine calls that returned a usable, judgeable response |
| `site_coverage` | ≥ **0.50** | Share of archetype checks that could actually be verified |

Failing either sets `evidence_ok: false` and populates `blockers` with plain-language
reasons. **Consumers must refuse to display the score when `evidence_ok` is false.**
The MCP tools enforce this themselves: withheld runs are split out of `get_score_history`
and excluded from `compare_brands` rankings.

## Versioning and comparability

`score_version` is stamped onto every score. Two runs are only comparable when the
scoring method and the question set both match — see
[Measurement reliability](reliability.md) for the guards and the noise floor.
