# Check criteria reference — scanner v1.50.0

- scanner_version: 1.50.0
- Provenance: regenerated and diff-verified against the code in this commit by the contract test; see this file's git history.

Generated by `scripts/generate-check-reference.ts` from the check registry (`src/scanner/checks`). Do not edit by hand; regenerate after any rungs change. Graded structure (declared rungs, weights, categories, totals) is immutable per scanner version and requires a SCANNER_VERSION bump (A1 invariant); criteria sentences may be completed or corrected in place at the same version (delete the file and regenerate), because the CI drift test guarantees the committed document matches the code either way.

## State points

A check contributes `STATE_POINTS[state] / 100 × maxPoints` (`src/scanner/types.ts`):

| State | Points (of 100) |
|---|---|
| unknown | 0 |
| not_detected | 0 |
| detected | 10 |
| parseable | 35 |
| useful | 70 |
| high_confidence | 100 |

## Global negative-rung semantics (applies to every check)

A check's positive rungs (`detected` and above) are earned by its own grading
code, summarized per check below. When no clean positive signal is found, the
shared classifier (`src/scanner/classify-state.ts`) resolves the state from
the most informative HTTP outcome across the paths the check probed:

| Winning outcome | Resolved state |
|---|---|
| 2xx without the check's signal | `not_detected` |
| 401 / 403 (gated) | `detected` for existence-kind checks (the gate proves something is there); `unknown` for content-kind checks (the content cannot be assessed) |
| 404 / 410 | `not_detected` |
| 429 / 5xx / other reached status | `unknown` |
| status 0 (timeout / network / SSRF) | `unknown` |
| nothing probed / reachable | `unknown` |

**Honest-exhaustion rule**: a `not_detected` conclusion requires complete
evidence. When the scan's fetch/render budget latched before the check
resolved, a would-be `not_detected` resolves `unknown` instead (out of the
score denominator, lowers confidence). Positive evidence always stands.

**Orchestration overlays** (`src/scanner/scoring.ts`) can additionally force
two states onto ANY check after it returns, beyond its declared rungs:

- `not_detected` — a robots.txt `'*'`-baseline block on a surface the check
  needed forces a conclusive `not_detected` (`stampRobots`); a compliant
  generic agent is locked out, so the surface is a real gap.
- `unknown` — the runtime-budget truncation demotion, the no-work-item
  fallback, and the fail-open error catch all resolve `unknown`.

These two states form the globally assignable envelope
(`GLOBALLY_ASSIGNABLE_STATES` in `classify-state.ts`).

## Checks by dimension

"Reachable states" are the check's declared `rungs` keys — every state its own grading code can resolve to (the global envelope above can additionally force `not_detected`/`unknown`). "Cap" is the highest declared state; "effective max" is `maxPoints × STATE_POINTS[cap] / 100`, the most the check can actually contribute.

### discoverability

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| api-existence | 5 | yes | unknown, not_detected, detected, parseable | parseable | 1.75 | Checks whether the domain exposes an API endpoint. |
| api-versioning | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether the API uses versioned endpoints. |
| api-catalog | 3 | yes | unknown, not_detected, detected | detected | 0.3 | Checks whether the domain publishes an RFC 9727 API Catalog at /.well-known/api-catalog. |
| robots-txt | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the site publishes a valid robots.txt that declares a sitemap. |
| sitemap-xml | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the site publishes a valid, machine-readable XML sitemap. |
| canonical-domain | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether the site resolves to one canonical origin (root/www convergence, canonical tag). |
| subdomain-sweep | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether agent-relevant surfaces live at conventional subdomains (api.*, docs.*). |

Dimension totals (scored checks): maxPoints 24, effective max 18.05.

Rung criteria:

- **api-existence**
  - `unknown`: The locations where an API would show itself could not be read during the scan (no response or only temporary errors), so API presence could not be judged.
  - `not_detected`: The conventional API paths and spec locations checked returned only regular web pages, missing-page responses, or errors, with no sign of an API.
  - `detected`: Something API-shaped is present: an API path returned an authentication challenge or a non-HTML response, or a spec-like document exists that does not declare both servers and paths.
  - `parseable`: A published spec declares its servers and paths, or a conventional API path serves structured JSON rather than a web page, including a JSON 400 or 401 from a live API host.
- **api-versioning**
  - `unknown`: The spec, API responses, and documentation pages where version information would appear could not be read during the scan, or a response could not be compared against its control address, so versioning could not be judged.
  - `not_detected`: No version information was found in the API spec, in response headers, in URL paths, or on the documentation pages checked — or what was served there is indistinguishable from what the site returns for a deliberately nonexistent address.
  - `detected`: A version appears only in an API URL path (such as /v1), or versioning is mentioned, but not on a dedicated documentation page whose title or heading names the topic.
  - `parseable`: The API declares its version in its spec (info.version) or returns it in a version header, or a dedicated versioning page exists that does not yet describe the versioning scheme.
  - `useful`: A documentation page dedicated to versioning describes how the API is versioned.
  - `high_confidence`: The versioning documentation also describes what happens to old versions (deprecation, sunset, or retirement).
- **api-catalog**
  - `unknown`: The /.well-known/api-catalog path could not be read during the scan (no response, a temporary error, or an access restriction), so the catalog could not be checked.
  - `not_detected`: No API catalog was found at /.well-known/api-catalog or at a location announced in a Link header.
  - `detected`: The site serves an API catalog as JSON at /.well-known/api-catalog (RFC 9727) or at a location announced in a Link header.
- **robots-txt**
  - `unknown`: The /robots.txt file could not be read during the scan (no response, a temporary error, or an access restriction), so its presence could not be judged.
  - `not_detected`: Requesting /robots.txt returned no robots file (a missing-page response, an error, or an HTML page in its place).
  - `detected`: A non-HTML file is served at /robots.txt, but it contains no recognized robots directives.
  - `parseable`: The site serves a robots.txt that parses as a valid robots file (at least one User-agent group), but it does not declare a sitemap.
  - `useful`: The robots.txt declares at least one Sitemap URL.
  - `high_confidence`: A Sitemap URL declared in robots.txt also loads and parses as valid sitemap XML.
- **sitemap-xml**
  - `unknown`: The standard sitemap locations could not be read during the scan (no response, a temporary error, or an access restriction), so no conclusion was recorded.
  - `not_detected`: No valid XML sitemap was found at the standard locations or at any address declared in robots.txt.
  - `detected`: A sitemap location returned XML, but it does not parse as a valid urlset or sitemap index with page locations.
  - `parseable`: The site serves a valid XML sitemap, though its entries carry no last-modified dates or list only the homepage.
  - `useful`: The sitemap lists pages beyond the homepage and includes last-modified dates for them.
  - `high_confidence`: The dated sitemap also lists documentation, pricing, API, or developer pages among its URLs.
- **canonical-domain**
  - `unknown`: The root address could not be reached during the scan, so the site's canonical host could not be observed.
  - `not_detected`: Neither the root address nor the www address resolved to a usable homepage (both returned missing-page or error responses).
  - `detected`: The root address responds, but the root and www addresses do not settle on a single host (or the www side could not be assessed).
  - `parseable`: The root and www addresses resolve to the same single host.
  - `useful`: The root and www addresses resolve to the same host, and the homepage includes a canonical link tag.
  - `high_confidence`: The canonical link tag on the homepage names the same host that the root and www addresses resolve to.
- **subdomain-sweep**
  - `unknown`: The conventional subdomains could not be probed conclusively during the scan (lookups failed or only temporary errors came back), so their presence could not be judged.
  - `not_detected`: None of the conventional subdomains checked (api.*, docs.*, developer.*, dev.*) is live.
  - `detected`: At least one conventional subdomain (api.* or a docs-family host) is live, or one answered with an access challenge.
  - `parseable`: A live conventional subdomain serves the kind of content its name indicates (an api host serving non-HTML data, or a docs host serving pages).
  - `useful`: Both an api-family subdomain and a docs-family subdomain are live.
  - `high_confidence`: Both an api-family and a docs-family subdomain are live, and each serves the kind of content its name indicates.

### content_accessibility

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| llms-txt | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether the domain publishes an llms.txt file for LLM consumption. |
| llms-full-txt | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the domain publishes an llms-full.txt file with comprehensive inline LLM-readable content. |
| markdown-twin | 3 | yes | unknown, not_detected, detected, parseable | parseable | 1.05 | Checks whether a markdown twin (.md) is published alongside docs HTML pages (V1 detection only). |
| agent-ua-markdown | 0 | no (informational) | unknown, not_detected, detected, parseable | parseable | 0 | Checks whether the site serves Markdown to a transparently identified agent-compatibility user-agent without requiring an Accept header. |
| markdown-frontmatter | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether served Markdown begins with valid YAML metadata that helps agents identify and cite the page. |
| markdown-link-alternate | 0 | no (informational) | unknown, not_detected, parseable, useful | useful | 0 | Checks whether HTML pages advertise a Markdown representation with link rel="alternate" type="text/markdown". |
| markdown-negotiation-vary | 0 | no (informational) | unknown, not_detected, detected, parseable | parseable | 0 | Checks whether HTML-to-Markdown content negotiation declares Vary: Accept so caches keep representations separate. |
| markdown-url-fallback | 0 | no (informational) | unknown, not_detected, detected, parseable | parseable | 0 | Checks whether documentation pages expose a direct .md or /index.md representation without request headers. |
| code-fence-validity | 0 | no (informational) | unknown, not_detected, detected, useful | useful | 0 | Checks whether fenced code blocks in served Markdown have explicit, compatible closing fences. |
| agent-discovery-file | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether the site publishes a useful Agent Skills discovery index. |
| agent-instruction | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks for explicit, actionable when-to-use guidance in agent-facing Markdown. |
| agent-skills-index-v2 | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks Agent Skills discovery v0.2.0 schema, typed entries, and one published artifact digest. |
| modular-llms-txt | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks for scoped llms.txt indexes under major product or documentation areas. |
| llms-txt-links-resolve | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether a bounded sample of links declared by llms.txt resolves to real content. |
| agent-friendly-404 | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether a nonexistent path returns a real 404/410 with agent-followable recovery guidance. |
| content-crawl-depth | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether static same-site links lead from the homepage to substantive content two crawl hops away. |
| ai-txt | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether the domain publishes an ai.txt file declaring AI crawler policy. |
| raw-content-extractability | 8 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 8 | Checks whether meaningful content is extractable from raw HTML without JavaScript (not behind a JS shell, with usable main content). |
| freshness-signals | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the site publishes freshness signals (Last-Modified, ETag, sitemap lastmod) for content. |
| crawl-cost-estimate | 2 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Estimates crawl cost legibility from sitemap URL count and robots.txt Crawl-delay directives (informational — discoverability checks own sitemap/Crawl-delay scoring). |

Dimension totals (scored checks): maxPoints 24, effective max 22.05.

Rung criteria:

- **llms-txt**
  - `unknown`: The llms.txt locations could not be read during the scan (no response, a temporary error, or an access restriction), so the file's presence could not be judged.
  - `not_detected`: No llms.txt file was found at /llms.txt or /.well-known/llms.txt (an HTML page served at those paths does not count).
  - `detected`: A non-HTML file is served at an llms.txt path, but it lacks the H1 title line that begins a structured llms.txt.
  - `parseable`: The llms.txt begins with a valid title line but lists few or no links organized under section headings.
  - `useful`: The llms.txt lists at least three links under one or more section headings (a fuller index published on a non-primary subdomain also lands here).
  - `high_confidence`: An llms.txt on the main domain lists ten or more links organized across two or more section headings.
- **llms-full-txt**
  - `unknown`: The llms-full.txt locations could not be read during the scan (no response, a temporary error, or an access restriction), so the file's presence could not be judged.
  - `not_detected`: No llms-full.txt file was found at /llms-full.txt or /.well-known/llms-full.txt (an HTML page served at those paths does not count).
  - `detected`: A non-HTML file is served at an llms-full.txt path, but it lacks the H1 title line that begins a structured llms-full.txt.
  - `parseable`: The llms-full.txt begins with a valid title line, but its inline content beneath the headings runs under 5,000 characters.
  - `useful`: The llms-full.txt includes at least 5,000 characters of inline content beneath its headings.
  - `high_confidence`: The llms-full.txt includes at least 20,000 characters of inline content organized across three or more section headings.
- **markdown-twin**
  - `unknown`: The docs pages and their .md twin addresses could not be read during the scan (no response, a temporary error, or an access restriction), so twin availability could not be judged.
  - `not_detected`: No markdown (.md) version was found alongside the docs HTML pages checked on the discovered documentation host or at /docs and /documentation on the submitted domain.
  - `detected`: A non-HTML file is served at a .md address next to a docs page, but its body does not read as markdown.
  - `parseable`: A markdown version of a docs page is served at its .md address alongside the HTML page, including on a discovered docs host.
- **agent-ua-markdown**
  - `unknown`: The ordinary and agent-compatibility responses could not both be read, so user-agent variation could not be checked.
  - `not_detected`: No candidate page was observed switching from HTML to Markdown for the transparent agent-compatibility user-agent.
  - `detected`: A candidate page switched from HTML to text/markdown for the transparent agent-compatibility user-agent, but its body was not clearly Markdown-structured.
  - `parseable`: A candidate page switched from HTML to Markdown-structured text/markdown for the transparent agent-compatibility user-agent without an Accept header.
- **markdown-frontmatter**
  - `unknown`: No candidate Markdown representation could be read, so frontmatter could not be checked.
  - `not_detected`: Readable Markdown representations did not begin with a YAML frontmatter block.
  - `detected`: A head-anchored frontmatter block is present, but its YAML does not parse as a metadata object.
  - `parseable`: A head-anchored frontmatter block parses as a YAML metadata object.
  - `useful`: The parsed frontmatter includes a title plus description, canonical, freshness, or Markdown-URL metadata.
- **markdown-link-alternate**
  - `unknown`: The candidate HTML pages could not be read, so alternate-format declarations could not be checked.
  - `not_detected`: No candidate HTML page declared a text/markdown alternate representation.
  - `parseable`: A candidate HTML page declares an HTTP(S) text/markdown alternate URL.
  - `useful`: The declared on-domain alternate URL resolves to a Markdown representation.
- **markdown-negotiation-vary**
  - `unknown`: The candidate pages or their negotiated variants could not be read, so cache variation could not be checked.
  - `not_detected`: No candidate page was observed switching from HTML to Markdown in response to Accept: text/markdown.
  - `detected`: A candidate page negotiated from HTML to Markdown, but its response did not declare Vary: Accept.
  - `parseable`: A candidate page negotiated from HTML to Markdown and declared Vary: Accept.
- **markdown-url-fallback**
  - `unknown`: The candidate HTML pages or their direct Markdown addresses could not be read.
  - `not_detected`: No .md or /index.md representation was found for the reachable candidate pages.
  - `detected`: A direct Markdown address returned a non-HTML body, but the body was not clearly Markdown-structured.
  - `parseable`: A direct .md or /index.md address returned a Markdown-structured body.
- **code-fence-validity**
  - `unknown`: No candidate Markdown document could be read, so fenced blocks could not be audited.
  - `not_detected`: Readable Markdown documents contained no CommonMark fenced code blocks.
  - `detected`: At least one Markdown document has a fenced code block without a compatible explicit close.
  - `useful`: Every fenced code block found across the readable Markdown documents has a compatible explicit close.
- **agent-discovery-file**
  - `unknown`: The discovery index paths could not be read.
  - `not_detected`: No Agent Skills discovery index was found.
  - `detected`: A discovery file exists but is not a JSON object with a skills array.
  - `parseable`: The skills array parses, but contains no described, addressable skill.
  - `useful`: The index contains at least one skill with a name, description, and a URL or published file list.
- **agent-instruction**
  - `unknown`: Agent-facing instruction paths could not be read.
  - `not_detected`: No agent-facing instruction file or guidance was found.
  - `detected`: Agent guidance exists but lacks Markdown structure.
  - `parseable`: Structured guidance exists but lacks specific use-case or invocation guidance.
  - `useful`: The guidance says when to use the product and gives an actionable invocation or next step.
- **agent-skills-index-v2**
  - `unknown`: The v0.2.0 index or its selected on-domain artifact could not be read.
  - `not_detected`: No Agent Skills discovery index was found.
  - `detected`: An index exists but does not conform to the v0.2.0 entry schema.
  - `parseable`: Every entry has a valid type, URL, and SHA-256 digest.
  - `useful`: One on-domain SKILL.md artifact was fetched and its declared SHA-256 digest matched.
- **modular-llms-txt**
  - `unknown`: Scoped llms.txt paths could not be read.
  - `not_detected`: No scoped llms.txt was found under docs, API, or developer areas.
  - `detected`: A scoped text file exists but lacks an llms.txt H1.
  - `parseable`: A scoped llms.txt parses but has no link that remains inside its scope.
  - `useful`: A scoped llms.txt links to at least one resource inside the same product-area path.
- **llms-txt-links-resolve**
  - `unknown`: The llms.txt file or its sampled links could not be read.
  - `not_detected`: No llms.txt with agent-followable links was found.
  - `detected`: An llms.txt declares links, but none of the sampled links resolved to real content.
  - `parseable`: At least one sampled llms.txt link resolved to real content.
  - `useful`: Every sampled on-domain llms.txt link resolved to real, non-shell content.
- **agent-friendly-404**
  - `unknown`: The missing-page probe could not be read.
  - `not_detected`: The missing path did not return HTTP 404 or 410.
  - `detected`: The missing path returns 404/410 without a useful explanation.
  - `parseable`: The missing path returns 404/410 with a readable explanation.
  - `useful`: The 404/410 response points agents to docs, help, llms.txt, or a sitemap.
- **content-crawl-depth**
  - `unknown`: The raw homepage was unreachable or a JavaScript shell, so static crawl depth was inconclusive.
  - `not_detected`: The raw homepage exposed no static same-site content links.
  - `detected`: The homepage exposed static same-site links, but sampled children were not substantive.
  - `parseable`: A substantive first-hop page was reachable and exposed another static content link.
  - `useful`: A substantive second-hop page was reachable through static same-site links.
- **ai-txt**
  - `unknown`: The ai.txt locations could not be read during the scan (no response, a temporary error, or an access restriction), so the file's presence could not be judged.
  - `not_detected`: No ai.txt file was found at /ai.txt or /.well-known/ai.txt (an HTML page served at those paths does not count).
  - `detected`: A non-HTML file is served at an ai.txt path, but it is nearly empty or contains neither policy directives nor section headings.
  - `parseable`: The ai.txt has section headings but no recognizable policy directive lines (such as Allow, Disallow, Policy, Contact, Usage, Training, or Indexing).
  - `useful`: The ai.txt declares at least one policy directive line (such as Allow, Disallow, Policy, Contact, Usage, Training, or Indexing).
  - `high_confidence`: The ai.txt declares policy directive lines and organizes them under section headings.
- **raw-content-extractability**
  - `unknown`: The probed pages could not be assessed (they did not respond, returned errors or access restrictions, or served non-HTML responses), so readability without JavaScript could not be judged.
  - `not_detected`: Every probed page is a JavaScript shell whose initial HTML carries no meaningful readable content.
  - `detected`: Only minimal readable text is present in the raw HTML of the probed pages before any JavaScript runs.
  - `parseable`: Some readable text is present in the raw HTML, but much of it is navigation and page furniture, or some probed pages are JavaScript shells.
  - `useful`: The raw HTML of a probed page carries readable text without running JavaScript (at least 1,000 visible characters, or close to half of the visible text sitting in the main content area).
  - `high_confidence`: Two or more probed pages serve readable content in their raw HTML without running JavaScript.
- **freshness-signals**
  - `unknown`: The homepage and sitemap could not be read during the scan (no response, a temporary error, or an access restriction), so freshness signals could not be observed.
  - `not_detected`: Neither the homepage headers (Last-Modified, ETag) nor the sitemap (lastmod dates) carries any freshness signal.
  - `detected`: The only freshness signal is lastmod dates in the sitemap, and none of them falls within 90 days of the scan date.
  - `parseable`: Exactly one freshness signal is present: a Last-Modified header, an ETag header, or sitemap lastmod dates updated within 90 days of the scan date.
  - `useful`: At least two of the three freshness signals are present (Last-Modified header, ETag header, sitemap lastmod dates).
  - `high_confidence`: All three freshness signals are present, and the newest sitemap lastmod date falls within 90 days of the scan date.
- **crawl-cost-estimate**
  - `unknown`: The robots.txt and sitemap could not be read during the scan (no response, a temporary error, or an access restriction), so crawl cost legibility could not be assessed.
  - `not_detected`: Neither a sitemap nor a robots.txt Crawl-delay directive was found, leaving no crawl cost information to read.
  - `detected`: The sitemap signals a large crawl (an index declaring 20 or more child sitemaps, or more than 10,000 page URLs) with no further cost guidance.
  - `parseable`: Partial crawl cost information is published: a sitemap index without page counts, a sitemap of up to 10,000 page URLs, or a Crawl-delay directive without any sitemap.
  - `useful`: The sitemap lists up to 2,000 page URLs, or a sitemap index is published together with a robots.txt Crawl-delay directive.
  - `high_confidence`: The sitemap lists 500 or fewer page URLs and robots.txt publishes a Crawl-delay directive.

### bot_access_control

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| ai-bot-rules | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether robots.txt declares access rules specifically for AI bots (a declared AI-crawler preference). |
| content-signals | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether robots.txt declares Cloudflare Content Signals (search/ai-input/ai-train preferences). |
| tdmrep | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether the domain declares a TDM Reservation Protocol policy at /.well-known/tdmrep.json (a declared text-and-data-mining preference). |
| rsl | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether robots.txt declares an RSL (Really Simple Licensing) License directive and, if so, how completely the linked license states its terms. |
| agent-crawler-reachability | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether the homepage is reachable to five transparently identified major agent crawler user-agents. |
| bot-detection | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether agent crawler responses avoid explicit challenges and material content degradation. |

Dimension totals (scored checks): maxPoints 12, effective max 12.

Rung criteria:

- **ai-bot-rules**
  - `unknown`: The robots.txt file could not be read during the scan (no response, a temporary error, or an access restriction), so AI bot rules could not be checked.
  - `not_detected`: Either no plain-text robots.txt is served, or the one served names no AI-specific crawler.
  - `detected`: robots.txt names at least one AI-specific crawler (such as GPTBot or ClaudeBot) but declares no rule lines for it.
  - `parseable`: robots.txt declares an explicit rule (such as Allow or Disallow) for one AI-specific crawler.
  - `useful`: robots.txt declares explicit rules for two distinct AI-specific crawlers.
  - `high_confidence`: robots.txt declares explicit rules for three or more distinct AI-specific crawlers.
- **content-signals**
  - `unknown`: The robots.txt file could not be read during the scan (no response, a temporary error, or an access restriction), so Content Signals could not be checked.
  - `not_detected`: Either no plain-text robots.txt is served, or the one served contains no Content-Signal line.
  - `detected`: robots.txt contains a Content-Signal line, but no recognized signal (search, ai-input, ai-train) carries an unambiguous yes or no value.
  - `parseable`: One recognized Content Signal (search, ai-input, or ai-train) is declared with an unambiguous yes or no value for at least one crawler.
  - `useful`: Two of the three recognized Content Signals are declared with unambiguous yes or no values.
  - `high_confidence`: All three recognized Content Signals (search, ai-input, ai-train) are declared with unambiguous yes or no values.
- **tdmrep**
  - `unknown`: The /.well-known/tdmrep.json path could not be read during the scan (no response, a temporary error, or an access restriction), so the TDM policy could not be checked.
  - `not_detected`: No JSON tdmrep file was found at /.well-known/tdmrep.json.
  - `detected`: A tdmrep.json is served, but it is not valid JSON, is not a rules structure, or declares no rule with a valid tdm-reservation value (0 or 1).
  - `parseable`: The tdmrep.json declares at least one rule with a valid tdm-reservation value, but only for specific paths, not the domain root.
  - `useful`: The tdmrep.json declares a rule with a valid tdm-reservation value covering the domain root.
  - `high_confidence`: The domain-root rule also links a tdm-policy URL (an http or https address).
- **rsl**
  - `unknown`: The robots.txt file could not be read during the scan (no response, a temporary error, or an access restriction), so no RSL License directive could be looked for.
  - `not_detected`: Either no plain-text robots.txt is served, or it contains no License directive pointing to an RSL license file.
  - `detected`: robots.txt declares an RSL License directive, but no linked file could be read as an RSL document carrying the RSL namespace and a license entry.
  - `parseable`: The linked RSL document parses with a license entry, but the license states no usage or payment terms.
  - `useful`: The linked RSL license states machine-readable terms: at least one permitted or prohibited usage, or a payment model.
  - `high_confidence`: The RSL license states an explicit AI usage term (ai-train, ai-input, ai-index, or ai-all) together with a payment model.
- **agent-crawler-reachability**
  - `unknown`: Agent crawler homepage probes could not be completed.
  - `not_detected`: None of the sampled agent crawler user-agents reached the homepage.
  - `detected`: One or two sampled agent crawler user-agents reached the homepage.
  - `parseable`: At least three sampled agent crawler user-agents reached the homepage.
  - `useful`: All five sampled agent crawler user-agents reached the homepage.
- **bot-detection**
  - `unknown`: The ordinary homepage or agent probes could not be read.
  - `not_detected`: No sampled agent crawler received an unchallenged, substantive homepage.
  - `detected`: One or two sampled agent crawlers received an unchallenged, substantive homepage.
  - `parseable`: At least three sampled agent crawlers received unchallenged, substantive homepages.
  - `useful`: All five sampled agent crawlers received unchallenged homepages without material degradation.

### protocol_and_capability_discovery

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| link-headers | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether the API advertises related resources via RFC 8288 Link headers. |
| well-known-index | 2 | yes | unknown, not_detected, detected, parseable | parseable | 0.7 | Checks whether the site publishes machine-readable /.well-known/ descriptors. |
| openapi-spec | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether an OpenAPI/Swagger specification is published. |
| function-calling-compat | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether OpenAPI operations translate into uniquely named, typed, described function tools. |
| sdk-availability | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether official SDKs or client libraries are available. |
| mcp-descriptor | 5 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether the domain publishes a machine-readable MCP server descriptor. |
| mcp-support | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether the company documents or operates an MCP server that clients can connect to. |
| mcp-server-card | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the domain publishes an MCP Server Card for pre-connection discovery. |
| a2a-agent-card | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the domain publishes an A2A Agent Card for agent-to-agent discovery. |
| webmcp | 3 | no (informational) | unknown | unknown | 0 | Checks whether the site exposes WebMCP tools via navigator.modelContext at page load. |
| graphql-surface | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the domain advertises a GraphQL transport surface (static GET only — no introspection POST). |
| dns-aid | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the domain publishes a DNS-AID agent index at _index._agents.{domain}. |
| rate-limit-docs | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether rate limiting is documented. |
| auth-discovery | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether the site publishes a standardized, machine-readable authentication-discovery surface (OAuth 2.0 AS metadata / OpenID Connect Discovery / RFC 9728 Protected Resource Metadata) an agent can use to authenticate. |
| mcp-tool-listing | 0 | no (informational) | unknown, not_detected, parseable, useful, high_confidence | high_confidence | 0 | Checks whether a live MCP server returns a valid tool list. |
| mcp-tool-naming | 0 | no (informational) | unknown, not_detected, detected, parseable, high_confidence | high_confidence | 0 | Checks whether live MCP tools have unique, machine-safe names. |
| mcp-tool-descriptions | 0 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 0 | Checks description coverage across live MCP tools. |
| mcp-tool-annotations | 0 | no (informational) | unknown, not_detected, useful, high_confidence | high_confidence | 0 | Checks whether live MCP tools declare behavior annotations. |
| mcp-param-schemas | 0 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 0 | Checks whether live MCP tools publish usable input schemas. |
| mcp-resource-listing | 0 | no (informational) | unknown, not_detected, parseable, useful, high_confidence | high_confidence | 0 | Checks whether a live MCP server returns a valid resource list. |
| mcp-resource-quality | 0 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 0 | Checks whether live MCP resources are addressable and described. |
| mcp-error-handling | 0 | no (informational) | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 0 | Checks structured protocol errors using one unknown no-op method. |
| mcp-transport-modern | 0 | no (informational) | unknown, not_detected, useful, high_confidence | high_confidence | 0 | Checks which MCP Streamable HTTP protocol era the server negotiates. |
| mcp-server-identity | 0 | no (informational) | unknown, not_detected, detected, parseable, high_confidence | high_confidence | 0 | Checks the identity returned by the live MCP server. |
| mcp-auth-mechanism | 0 | no (informational) | unknown, not_detected, parseable, high_confidence | high_confidence | 0 | Checks the authentication challenge exposed by the MCP endpoint. |
| mcp-oauth-metadata | 0 | no (informational) | unknown, not_detected, detected, useful, high_confidence | high_confidence | 0 | Checks OAuth protected-resource and authorization-server metadata. |
| mcp-pkce-s256 | 0 | no (informational) | unknown, not_detected, detected, high_confidence | high_confidence | 0 | Checks whether MCP authorization metadata advertises PKCE S256. |
| mcp-multi-surface-coverage | 0 | no (informational) | unknown, not_detected, parseable, useful, high_confidence | high_confidence | 0 | Checks explicitly declared MCP endpoints as one bounded site-level set. |
| a2ui-support | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects A2UI declarations in MCP tool and resource metadata without invoking the UI. |
| mcp-app-registry | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects MCP tools linked to registered UI resources using the MCP Apps extension metadata. |
| mcp-apps-ui-quality | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects complete descriptive metadata for an app-linked tool and its matching UI resource. |
| mcp-view-csp | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects content-security-policy metadata on listed MCP App resources. |
| mcp-view-domain | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects a valid HTTPS rendering origin declared for an MCP App resource. |
| acp-support | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects a published Agentic Commerce Protocol checkout surface; permanently informational because payment capability is not a readiness quality. |
| acp-delegate-payment | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects the ACP delegated-payment API in a published specification; permanently informational because payment capability is not a readiness quality. |
| ap2-support | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects Agent Payments Protocol support in a UCP profile or published API specification; permanently informational because payment capability is not a readiness quality. |
| ucp-support | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects the Universal Commerce Protocol discovery profile; permanently informational because payment capability is not a readiness quality. |
| nlweb-ask | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects an NLWeb /ask operation in a published OpenAPI document without submitting a query. |
| nlweb-schema-feeds | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects the normative SchemaMap feed-discovery directive in robots.txt. |
| nlweb-streaming | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects NLWeb streaming support through published SSE or streaming-preference metadata. |

Dimension totals (scored checks): maxPoints 41, effective max 39.7.

Rung criteria:

- **link-headers**
  - `unknown`: The probed API and homepage responses could not be read during the scan (no response, a temporary error, or an access restriction), so Link headers could not be checked.
  - `not_detected`: No Link header appears on any probed response.
  - `detected`: A Link header is present on a probed response, but no entry in it parses with a rel type.
  - `parseable`: A Link header parses with at least one rel type.
  - `useful`: A Link header includes an agent-relevant rel type (api-catalog, service-desc, service-doc, or describedby) pointing at a target address.
  - `high_confidence`: The agent-relevant Link target also loads (a successful response at the linked address).
- **well-known-index**
  - `unknown`: The covered /.well-known/ paths could not be read during the scan (no response, a temporary error, or an access restriction), or a change-password response could not be compared against its control address, so no conclusion was recorded.
  - `not_detected`: Neither covered descriptor was found: no gpc.json, and no change-password response distinguishable from the site's handling of a deliberately nonexistent address.
  - `detected`: A covered /.well-known/ file is served but does not parse in its expected format (a gpc.json that is not valid JSON).
  - `parseable`: A covered descriptor is served and parses: a valid gpc.json, or a change-password address treated differently from a deliberately nonexistent control address.
- **openapi-spec**
  - `unknown`: The spec locations and API paths could not be read during the scan (no response, a temporary error, or an access restriction), so no spec search could complete.
  - `not_detected`: No OpenAPI or Swagger specification was found at the conventional locations or at addresses the site declares.
  - `detected`: A spec-like document exists, but it is too large to parse, does not parse as JSON or YAML, or lacks the required openapi/swagger version, info, or paths fields.
  - `parseable`: A valid OpenAPI or Swagger document is published, but it declares no operations or no schemas.
  - `useful`: The spec declares operations and schemas but misses at least one of: an info.version, a servers or host declaration, three or more operations, or responses defined on at least 80 percent of operations.
  - `high_confidence`: The spec declares its version, its servers or host, three or more operations, and responses on at least 80 percent of operations.
- **function-calling-compat**
  - `unknown`: No valid spec could be read.
  - `not_detected`: No operationId values are declared.
  - `detected`: Operation IDs are incomplete, duplicated, or function-unsafe.
  - `parseable`: Every operation has a unique function-safe ID, but typed-input or description coverage is thin.
  - `useful`: Every operation has a unique function-safe ID and at least 60% have typed inputs and descriptions.
- **sdk-availability**
  - `unknown`: The SDK and getting-started pages could not be read during the scan (no response, a temporary error, or an access restriction), or a page could not be compared against its control address, so SDK availability could not be judged.
  - `not_detected`: No SDK mention was found on the SDK or getting-started pages checked, or those addresses returned the same page the site returns for a deliberately nonexistent address.
  - `detected`: An SDK is mentioned on a general page (such as getting-started) rather than a page for SDKs or client libraries, with no concrete pointer to one.
  - `parseable`: A dedicated SDK or client-libraries page exists, but it includes no concrete pointer (an install command, a package-registry link, or a GitHub repository).
  - `useful`: The pages include one concrete SDK pointer: an install command, a package-registry link, or a GitHub repository.
  - `high_confidence`: The pages include two or more concrete SDK pointers (install commands, package-registry links, or GitHub repositories).
- **mcp-descriptor**
  - `unknown`: The MCP descriptor locations (/.well-known/mcp.json and related paths) could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No MCP server description was found at the descriptor locations checked.
  - `detected`: A file is served at an MCP descriptor location, but it does not contain the fields that describe an MCP server.
  - `parseable`: An MCP server is described, but the description includes no web address where the server can be reached.
  - `useful`: The MCP description includes a web address for the server.
  - `high_confidence`: The MCP description lists two or more tools, with descriptions and input formats on at least 80 percent of them.
- **mcp-support**
  - `unknown`: The official MCP documentation and likely endpoint locations could not be checked conclusively because they were unreachable, temporarily failing, or access-restricted.
  - `not_detected`: No first-party MCP support documentation or MCP-specific endpoint response was found.
  - `detected`: MCP is mentioned by the company, but not on a dedicated first-party support page and no live protocol response was found.
  - `parseable`: A dedicated first-party MCP page exists without a concrete endpoint, or an MCP-shaped endpoint returned structured MCP-related data.
  - `useful`: First-party documentation identifies a concrete MCP endpoint, or a live endpoint returned the expected authentication or method contract.
  - `high_confidence`: First-party documentation identifies the endpoint plus capabilities and connection details, explicitly establishes a company-operated service with those details, or the endpoint returned an MCP-specific protocol or OAuth discovery response.
- **mcp-server-card**
  - `unknown`: The Server Card locations (/.well-known/mcp/server-card.json and related paths) could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No MCP Server Card was found at the locations checked.
  - `detected`: A file is served at a Server Card location, but it does not contain the fields that describe an MCP Server Card.
  - `parseable`: A Server Card is described, but it lacks a remote endpoint entry (a type and web address) or the identity fields name, description, and version.
  - `useful`: The Server Card declares its identity and at least one remote endpoint (a type and web address).
  - `high_confidence`: A remote endpoint in the Server Card also lists its supported MCP protocol versions.
- **a2a-agent-card**
  - `unknown`: The Agent Card locations (/.well-known/agent-card.json and related paths) could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No A2A Agent Card was found at the locations checked.
  - `detected`: A file is served at an Agent Card location, but it does not contain the fields that describe an A2A Agent Card.
  - `parseable`: An Agent Card is described, but it is missing required fields (name, description, version, supported interfaces, or described skills).
  - `useful`: The Agent Card declares described skills and a supported interface with a web address.
  - `high_confidence`: The Agent Card also declares its capabilities, default input and output modes, and tags on every skill.
- **webmcp**
  - `unknown`: WebMCP tools can only be observed by loading the page in a browser, which this scanner release does not yet do, so the check always records no conclusion.
- **graphql-surface**
  - `unknown`: The conventional GraphQL paths (/graphql and variants) could not be read during the scan (no response, a temporary error, or an access restriction), or a response could not be compared against its control address.
  - `not_detected`: Nothing GraphQL-shaped was found at the conventional GraphQL paths, or what was served there is indistinguishable from what the site returns for a deliberately nonexistent address.
  - `detected`: A response exists at a GraphQL path, but it carries no recognizable GraphQL markers.
  - `parseable`: A GraphQL path answers with a GraphQL-shaped body (including the 400 or 405 error JSON real endpoints return to a plain GET), or a page carries static GraphQL documentation markers.
  - `useful`: A GraphQL path serves GraphiQL, GraphQL Playground, or Apollo markers.
  - `high_confidence`: A GraphQL path serves an interactive GraphQL IDE (GraphiQL or Playground) together with Apollo or schema markers.
- **dns-aid**
  - `unknown`: The DNS queries for _index._agents.<domain> failed or timed out, so the index could not be checked.
  - `not_detected`: Nothing is published at _index._agents.<domain> (the DNS-AID index location): DNS reports no such name, or answers with an empty record set — as wildcard and catch-all zones do — or the only records there are unrelated to agent discovery, such as an SPF policy.
  - `detected`: A record at the index name names agent discovery (agent, mcp, or a2a) but publishes no usable value.
  - `parseable`: The index publishes a parseable record: an SVCB record, or a TXT record naming agent, mcp, or a2a metadata.
  - `useful`: The index's SVCB record includes transport or capability metadata (an alpn, port, or capability document parameter).
  - `high_confidence`: The index's SVCB record publishes both a transport protocol list (alpn) and a capability document parameter (cap).
- **rate-limit-docs**
  - `unknown`: The rate-limit documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No rate limit mention was found at the documentation locations checked.
  - `detected`: Rate limiting is mentioned, but not on a dedicated documentation page whose title or heading names the topic.
  - `parseable`: A dedicated rate-limit page exists, but it does not state a concrete numeric limit together with limit-handling information.
  - `useful`: The rate-limit page states a concrete numeric limit and how limits surface (rate-limit response headers, a documented 429, Retry-After, or backoff guidance).
  - `high_confidence`: The page also documents the 429 status, the Retry-After header, and how limits differ by tier or plan.
- **auth-discovery**
  - `unknown`: The standard authentication-discovery locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No OAuth authorization-server metadata, OpenID Connect discovery document, or protected-resource metadata was found at the standard /.well-known/ locations.
  - `detected`: An authentication-discovery file is served at a standard location, but it does not parse as valid metadata.
  - `parseable`: A valid protected-resource metadata document (RFC 9728) is published, but it names no authorization servers.
  - `useful`: The site publishes a valid OAuth authorization-server or OpenID Connect discovery document, or protected-resource metadata naming its authorization servers.
  - `high_confidence`: Valid protected-resource metadata and a valid authorization-server document are both published, or the metadata is announced in a WWW-Authenticate challenge on a protected endpoint.
- **mcp-tool-listing**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-tool-naming**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-tool-descriptions**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-tool-annotations**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-param-schemas**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-resource-listing**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-resource-quality**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-error-handling**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-transport-modern**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-server-identity**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `parseable`: The live server returned a structurally readable signal.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-auth-mechanism**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `parseable`: The live server returned a structurally readable signal.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-oauth-metadata**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-pkce-s256**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `detected`: The live server exposed the signal, but it was incomplete or malformed.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **mcp-multi-surface-coverage**
  - `unknown`: A declared endpoint required authentication, was unreachable, or could not be inspected conclusively.
  - `not_detected`: No qualifying live signal was returned by the declared first-party MCP endpoints.
  - `parseable`: The live server returned a structurally readable signal.
  - `useful`: The live server returned a signal an agent can use directly.
  - `high_confidence`: Every relevant item on every conclusively inspected server met this check’s quality contract.
- **a2ui-support**
  - `unknown`: MCP endpoint list metadata could not be read conclusively.
  - `not_detected`: No matching declaration was found in readable MCP list metadata.
  - `detected`: A matching declaration was found in readable MCP list metadata.
- **mcp-app-registry**
  - `unknown`: MCP endpoint list metadata could not be read conclusively.
  - `not_detected`: No matching declaration was found in readable MCP list metadata.
  - `detected`: A matching declaration was found in readable MCP list metadata.
- **mcp-apps-ui-quality**
  - `unknown`: MCP endpoint list metadata could not be read conclusively.
  - `not_detected`: No matching declaration was found in readable MCP list metadata.
  - `detected`: A matching declaration was found in readable MCP list metadata.
- **mcp-view-csp**
  - `unknown`: MCP endpoint list metadata could not be read conclusively.
  - `not_detected`: No matching declaration was found in readable MCP list metadata.
  - `detected`: A matching declaration was found in readable MCP list metadata.
- **mcp-view-domain**
  - `unknown`: MCP endpoint list metadata could not be read conclusively.
  - `not_detected`: No matching declaration was found in readable MCP list metadata.
  - `detected`: A matching declaration was found in readable MCP list metadata.
- **acp-support**
  - `unknown`: The published API specification surfaces could not be checked.
  - `not_detected`: No ACP checkout declaration was observed in the bounded published API specifications checked.
  - `detected`: A first-party published API specification declares the ACP checkout surface.
- **acp-delegate-payment**
  - `unknown`: The published API specification surfaces could not be checked.
  - `not_detected`: No ACP delegated-payment operation was observed in the bounded published API specifications checked.
  - `detected`: A first-party published API specification declares the ACP delegated-payment operation.
- **ap2-support**
  - `unknown`: The UCP profile and published API specification surfaces could not be checked conclusively.
  - `not_detected`: No AP2 capability or mandate declaration was observed in the bounded UCP and published API surfaces checked.
  - `detected`: AP2 is declared by the UCP capability profile or a first-party published API specification.
- **ucp-support**
  - `unknown`: The UCP discovery location could not be checked conclusively.
  - `not_detected`: No UCP profile was observed at the normative root /.well-known/ucp location.
  - `detected`: A UCP profile with schema-valid service and payment-handler registry entries is published at /.well-known/ucp and survives a same-family catch-all control.
- **nlweb-ask**
  - `unknown`: Published OpenAPI locations or their controls could not be checked.
  - `not_detected`: No NLWeb-shaped /ask operation was found.
  - `detected`: A published OpenAPI document declares an NLWeb-shaped /ask operation.
- **nlweb-schema-feeds**
  - `unknown`: robots.txt or its catch-all control could not be checked.
  - `not_detected`: No valid HTTPS SchemaMap declaration was found.
  - `detected`: robots.txt declares at least one valid HTTPS SchemaMap location.
- **nlweb-streaming**
  - `unknown`: Published OpenAPI locations or their controls could not be checked.
  - `not_detected`: No NLWeb streaming declaration was found.
  - `detected`: A published NLWeb /ask operation declares streaming support.

### authentication_and_credentials

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| auth-documentation | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether authentication documentation exists. |
| programmatic-auth-flow | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether a programmatic (non-interactive) authentication flow is documented. |
| credential-management | 4 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 4 | Checks whether credential management (rotation, revocation, scoping) is documented. |
| sandbox-environment | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether a sandbox or test environment is available. |
| auth-md-exists | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects a non-empty, non-HTML Markdown authentication file at the root /auth.md path. |
| auth-md-structure | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects auth.md sections for service context, registration, permissions, workflow, and OAuth metadata. |
| auth-md-walkthrough-simulation | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Statically simulates whether auth.md documents an ordered discover-register-token-use-recovery walkthrough. |
| agent-auth-discovery-metadata | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects a conforming Agent Auth discovery document at its well-known location. |
| agent-auth-endpoints-reachable | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Checks whether the first-party register, capabilities, and execute routes declared by Agent Auth are reachable. |
| agent-auth-www-authenticate | 0 | no (informational) | unknown, not_detected, detected | detected | 0 | Detects an observed WWW-Authenticate AgentAuth challenge with a first-party discovery URL. |

Dimension totals (scored checks): maxPoints 19, effective max 19.

Rung criteria:

- **auth-documentation**
  - `unknown`: The authentication documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No authentication-related terms were found at the documentation locations checked.
  - `detected`: Authentication is mentioned, but not on a dedicated documentation page whose title or heading names the topic.
  - `parseable`: A dedicated docs page graded for authentication exists, but it does not document a complete method (the credential and how a request carries it). The page may be an auth guide or a REST API page that discusses credentials.
  - `useful`: The graded page documents at least one complete method: the credential (API key, bearer token, or OAuth) and how a request carries it.
  - `high_confidence`: The page documents two or more complete methods, or it references an OpenAPI or Swagger security scheme.
- **programmatic-auth-flow**
  - `unknown`: The authentication documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No mention of non-interactive authentication (service accounts, client credentials, API tokens, or header-based keys) was found at the documentation locations checked.
  - `detected`: Programmatic authentication is mentioned, but not on a dedicated documentation page whose title or heading names authentication.
  - `parseable`: A dedicated authentication page exists, but it documents neither a non-interactive grant with a token endpoint nor a header-based key method.
  - `useful`: The page documents a machine-usable flow: a non-interactive grant (such as client credentials) with a token endpoint, or a header-based API key or bearer token method.
  - `high_confidence`: The page also documents scopes and token expiry or refresh.
- **credential-management**
  - `unknown`: The keys and security documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No mention of credential rotation, revocation, or key management was found at the documentation locations checked.
  - `detected`: Credential management is mentioned, but not on a dedicated documentation page whose title or heading names keys, credentials, or security.
  - `parseable`: A dedicated keys or security page exists, but it does not document how to rotate or revoke credentials.
  - `useful`: The page documents rotating or revoking keys, tokens, or other credentials.
  - `high_confidence`: The page documents rotation and revocation together with credential scoping or expiry.
- **sandbox-environment**
  - `unknown`: The sandbox and testing documentation locations could not be read during the scan (no response, a temporary error, or an access restriction), or a page could not be compared against its control address.
  - `not_detected`: No mention of a sandbox or test environment was found at the documentation locations checked — the addresses either returned nothing, returned the same page the site returns for a deliberately nonexistent address, or resolved to a profile page rather than documentation.
  - `detected`: A test environment is mentioned, but not on a dedicated documentation page whose title or heading names the topic.
  - `parseable`: A dedicated sandbox or testing page exists, but it shows neither test credentials nor a test base URL.
  - `useful`: The page shows test credentials or a test base URL.
  - `high_confidence`: The page documents separate test and live credentials together with a concrete test workflow (test data or simulations).
- **auth-md-exists**
  - `unknown`: The root auth.md location or its catch-all control could not be checked.
  - `not_detected`: The auth.md document did not satisfy the exists criteria.
  - `detected`: The auth.md document satisfied the exists criteria.
- **auth-md-structure**
  - `unknown`: The root auth.md location or its catch-all control could not be checked.
  - `not_detected`: The auth.md document did not satisfy the structured criteria.
  - `detected`: The auth.md document satisfied the structured criteria.
- **auth-md-walkthrough-simulation**
  - `unknown`: The root auth.md location or its catch-all control could not be checked.
  - `not_detected`: The auth.md document did not satisfy the walkthrough criteria.
  - `detected`: The auth.md document satisfied the walkthrough criteria.
- **agent-auth-discovery-metadata**
  - `unknown`: The discovery location or its catch-all control could not be checked.
  - `not_detected`: No conforming Agent Auth discovery document was found.
  - `detected`: A conforming Agent Auth discovery document was found.
- **agent-auth-endpoints-reachable**
  - `unknown`: Discovery or safe first-party endpoint probing was inconclusive.
  - `not_detected`: At least one required declared endpoint was absent.
  - `detected`: All three required declared endpoints returned route-level responses.
- **agent-auth-www-authenticate**
  - `unknown`: No conclusive set of API response headers could be observed.
  - `not_detected`: Observed API responses did not advertise an AgentAuth challenge.
  - `detected`: An observed API response advertised AgentAuth and a first-party HTTPS discovery URL.

### documentation_quality

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| api-reference-depth | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether API reference documentation has meaningful depth. |
| changelog-presence | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether a changelog or release notes page exists. |

Dimension totals (scored checks): maxPoints 10, effective max 10.

Rung criteria:

- **api-reference-depth**
  - `unknown`: The API reference locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No API reference content (parameters, examples, status codes, or similar indicators) was found at the documentation locations checked.
  - `detected`: Reference content is mentioned, but not on a dedicated reference page whose title or heading names the reference.
  - `parseable`: A dedicated API reference page exists, but it does not show parameters together with example requests or responses.
  - `useful`: The reference page documents parameters together with example requests or responses (a curl example counts).
  - `high_confidence`: The reference page documents request and response bodies, examples, authentication, pagination, and error or status codes.
- **changelog-presence**
  - `unknown`: The changelog locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No changelog or release notes terms were found at the locations checked.
  - `detected`: A changelog is mentioned, but not on a dedicated page whose title or heading names release history.
  - `parseable`: A dedicated changelog page exists, but it lacks dated or versioned entries paired with change descriptions (added, fixed, removed, and similar).
  - `useful`: The changelog lists at least one dated or versioned entry alongside change descriptions.
  - `high_confidence`: The changelog also lists three or more distinct dated or versioned entries.

### structured_data_io

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| pagination-shape | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks OpenAPI operations for a typed, agent-followable pagination round trip. |
| async-job-pattern | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks OpenAPI operations for 202 Accepted plus a machine-followable job polling signal. |
| batch-endpoints | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks OpenAPI operations for an explicit batch/bulk endpoint with an array request body. |
| structured-data-io | 8 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 8 | Checks whether the API publishes a typed, consistent structured-data contract (OpenAPI response schemas). |
| data-export-api | 4 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 4 | Checks whether the API supports data export or bulk retrieval. |
| machine-readable-pricing | 1 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 1 | Checks whether pricing information is available via a machine-readable endpoint (JSON API). |
| json-ld | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether public pages expose parseable, agent-usable JSON-LD structured data. |
| json-ld-entity-linking | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks whether JSON-LD entities use resolvable identifiers and real graph or identity links. |
| schema-type-breadth | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks how many distinct, meaningfully populated Schema.org entity types public pages expose. |

Dimension totals (scored checks): maxPoints 13, effective max 13.

Rung criteria:

- **pagination-shape**
  - `unknown`: No valid spec could be read.
  - `not_detected`: No pagination shape is declared.
  - `detected`: Pagination vocabulary exists without a typed shape.
  - `parseable`: A typed pagination input or continuation output is declared.
  - `useful`: One operation declares both a typed cursor/token input and a continuation output.
- **async-job-pattern**
  - `unknown`: No valid spec could be read.
  - `not_detected`: No asynchronous job pattern is declared.
  - `detected`: Async/job vocabulary exists without a 202 response.
  - `parseable`: An operation declares 202 Accepted without a poll location or job-tracking shape.
  - `useful`: A 202 response declares Location or sufficient job-tracking fields.
- **batch-endpoints**
  - `unknown`: No valid spec could be read.
  - `not_detected`: No batch/bulk operation or array request body is declared.
  - `detected`: A batch/bulk operation is named without an array request body.
  - `parseable`: An operation accepts an array request body but is not explicitly batch/bulk.
  - `useful`: An explicit batch/bulk operation accepts an array request body.
- **structured-data-io**
  - `unknown`: The spec locations could not be read during the scan (no response, a temporary error, or an access restriction), so the response contract could not be assessed.
  - `not_detected`: No API spec declaring response shapes was found at the locations checked.
  - `detected`: A spec-like document exists, but it is too large to parse, does not parse, or declares no response schemas.
  - `parseable`: The spec declares response schemas, but typed responses cover fewer than 60 percent of its operations.
  - `useful`: The spec declares typed response schemas on at least 60 percent of operations, but misses a pagination pattern, a structured error response, or both.
  - `high_confidence`: The spec declares typed response schemas on at least 60 percent of operations, plus a pagination pattern and an error response with a declared schema.
- **data-export-api**
  - `unknown`: The export documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No mention of bulk export or data export was found at the documentation locations checked.
  - `detected`: Data export is mentioned, but not on a dedicated documentation page whose title or heading names export.
  - `parseable`: A dedicated export page exists, but it documents neither a bulk or export endpoint nor an export format.
  - `useful`: The page documents a bulk or export endpoint, or names an export format (CSV, NDJSON, JSONL, Parquet, or similar).
  - `high_confidence`: The page documents a bulk or export endpoint, an export format, and async-job or pagination handling for large exports.
- **machine-readable-pricing**
  - `unknown`: The machine-readable pricing paths (/pricing.json and API pricing paths) could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No JSON pricing data was found at the paths checked (/pricing.json, /api/pricing, /api/plans, and variants).
  - `detected`: A JSON-like response is served at a pricing path, but it does not parse as a JSON object or array.
  - `parseable`: Valid JSON is served at a pricing path, but no entry in it carries a price field.
  - `useful`: The JSON lists at least one plan entry with a price field.
  - `high_confidence`: The JSON lists two or more plans, each with a price, a currency, and a billing interval.
- **json-ld**
  - `unknown`: No candidate page could be read completely enough to assess JSON-LD.
  - `not_detected`: No complete candidate page contains an application/ld+json script.
  - `detected`: A JSON-LD script exists, but it is invalid or lacks a typed JSON-LD context.
  - `parseable`: A JSON-LD document parses and contains at least one typed node under a context.
  - `useful`: A typed JSON-LD node also carries at least three properties and an agent-usable name, description, headline, or URL.
- **json-ld-entity-linking**
  - `unknown`: No candidate page could be read completely enough to assess entity links.
  - `not_detected`: No JSON-LD node exposes an @id.
  - `detected`: An @id is present but cannot be resolved as an HTTP(S) identifier.
  - `parseable`: At least one JSON-LD @id resolves as an HTTP(S) identifier.
  - `useful`: A resolvable @id is actually linked by a node reference to a defined entity, or a typed identified entity carries a resolvable sameAs identity link.
- **schema-type-breadth**
  - `unknown`: No candidate page could be read completely enough to assess Schema.org types.
  - `not_detected`: No typed Schema.org node was found.
  - `detected`: Exactly one distinct Schema.org type was found.
  - `parseable`: At least two distinct Schema.org types were found.
  - `useful`: At least three distinct Schema.org types are each meaningfully populated with multiple properties and an agent-usable text or URL field.

### observable_state_and_reliability

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| status-and-health | 2 | yes | unknown, not_detected, detected | detected | 0.2 | Checks whether the API exposes health or status endpoints. |
| webhook-documentation | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether webhook or event notification documentation exists. |
| error-documentation | 5 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 5 | Checks whether error codes and error handling are documented. |
| retry-and-idempotency | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether retry behavior and idempotency are documented. |
| x402-or-mpp-support | 1 | no (informational) | unknown, detected, parseable, useful | useful | 0.7 | Checks whether the API advertises machine-payable access (x402 / MPP): an HTTP 402 response, a payment-required response header, or a published /.well-known/x402.json manifest. |
| rate-limit-headers | 0 | no (informational) | unknown, not_detected, detected, parseable, useful | useful | 0 | Checks live API responses for machine-readable quota, remaining-capacity, reset, policy, and Retry-After guidance. |

Dimension totals (scored checks): maxPoints 15, effective max 13.2.

Rung criteria:

- **status-and-health**
  - `unknown`: The health and status paths could not be read during the scan (no response or only temporary errors), so no conclusion was recorded.
  - `not_detected`: No health or status endpoint was found at the conventional paths (/status, /health, /healthz, and variants), and no linked off-host status page was reachable.
  - `detected`: A conventional health or status path answers with a non-HTML response, or a linked off-host status page is reachable (machine-readable JSON when robots allow it, otherwise the status page itself), or the path answers with an access challenge.
- **webhook-documentation**
  - `unknown`: The webhook documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No mention of webhooks or event notifications was found at the documentation locations checked.
  - `detected`: Webhooks are mentioned, but not on a dedicated documentation page whose title or heading names webhooks or events.
  - `parseable`: A dedicated webhook page exists, but it does not list at least two named event types together with a payload shape.
  - `useful`: The webhook page lists two or more named event types (such as charge.refunded) together with a payload shape.
  - `high_confidence`: The page also documents signature verification and delivery retry behavior.
- **error-documentation**
  - `unknown`: The error documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No error documentation terms were found at the documentation locations checked.
  - `detected`: Error handling is mentioned, but not on a dedicated documentation page whose title or heading names errors.
  - `parseable`: A dedicated error page exists, but it neither enumerates at least two distinct error status codes nor documents an error response shape.
  - `useful`: The error page enumerates two or more distinct error status codes, or documents an error response shape (such as a code and message object).
  - `high_confidence`: The page also names a machine-readable error format (problem details) alongside retry guidance, or mentions OpenAPI or Swagger.
- **retry-and-idempotency**
  - `unknown`: The retry and idempotency documentation locations could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No retry or idempotency terms were found at the documentation locations checked.
  - `detected`: Retries or idempotency are mentioned, but not on a dedicated documentation page whose title or heading names the topic.
  - `parseable`: A dedicated retry or idempotency page exists, but it documents neither an idempotency-key mechanism nor a concrete retry strategy.
  - `useful`: The page documents an idempotency-key mechanism or a concrete retry strategy (backoff, 429 handling, or Retry-After).
  - `high_confidence`: The page documents both an idempotency-key mechanism and a retry strategy.
- **x402-or-mpp-support**
  - `unknown`: No machine-payment signal was observed (no HTTP 402 response, no payment-required header, and no /.well-known/x402.json manifest); because payment support can be invisible to an unauthenticated probe, a miss records no conclusion rather than an absence.
  - `detected`: A payment signal was observed: an HTTP 402 response, a payment-required response header, an x402 payment envelope in a 402 body, or a /.well-known/x402.json file carrying x402 fields without further structure.
  - `parseable`: The /.well-known/x402.json manifest is structured: it declares an x402 version or lists resource entries, though none carries a price amount.
  - `useful`: The x402 manifest lists at least one resource entry carrying a concrete price amount.
- **rate-limit-headers**
  - `unknown`: No confirmed live API response was available for header inspection.
  - `not_detected`: A live API response was found without rate-limit headers.
  - `detected`: A live API response exposes one rate-limit signal.
  - `parseable`: A live API response exposes multiple usable rate-limit signals.
  - `useful`: A live API response exposes quota, remaining-capacity, and reset/policy guidance.

### agent_safety_and_trust

| Check | Max pts | Scored | Reachable states | Cap | Effective max | Description |
|---|---|---|---|---|---|---|
| security-txt | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the site publishes a valid security.txt for vulnerability disclosure. |
| legal-pages | 2 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 2 | Checks whether terms of service, privacy, and data-use policies are discoverable. |
| org-identity | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether the site exposes org identity signals (legal name, address, support email, socials). |
| metadata-consistency | 3 | yes | unknown, not_detected, detected, parseable, useful, high_confidence | high_confidence | 3 | Checks whether homepage metadata is internally consistent (canonical, Open Graph, schema, pricing). |

Dimension totals (scored checks): maxPoints 11, effective max 11.

Rung criteria:

- **security-txt**
  - `unknown`: The security.txt locations (/.well-known/security.txt and /security.txt) could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No security.txt file was found at /.well-known/security.txt or /security.txt (an HTML page or empty file there does not count).
  - `detected`: A non-HTML file is served at a security.txt location, but it contains no recognized RFC 9116 field.
  - `parseable`: The security.txt uses RFC 9116 field names but has no Contact line.
  - `useful`: The security.txt publishes a Contact address, but either its Expires date had already passed on the date the scan ran (or is missing or duplicated), or it lacks an Encryption or Policy line.
  - `high_confidence`: The security.txt publishes a Contact address, exactly one Expires date still in the future on the date the scan ran, and an Encryption or Policy line.
- **legal-pages**
  - `unknown`: The conventional policy paths could not be read during the scan (no response, a temporary error, or an access restriction).
  - `not_detected`: No terms of service, privacy, or data-use policy page was found at the conventional paths.
  - `detected`: A policy page was found, but not both a privacy policy and terms of service.
  - `parseable`: Both a privacy policy and terms of service were found, but at least one carries under 400 characters of readable policy text.
  - `useful`: Both the privacy policy and the terms of service carry at least 400 characters of readable policy text.
  - `high_confidence`: In addition to substantive privacy and terms pages, a data-use policy of the same substance is published.
- **org-identity**
  - `unknown`: The homepage could not be read during the scan (no response, a temporary error, or an access restriction), so identity signals could not be observed.
  - `not_detected`: The homepage shows none of the four identity signals: an organization name in structured data, a postal address, a support-style email address, or a social profile link.
  - `detected`: The homepage shows one of the four identity signals.
  - `parseable`: The homepage shows two of the four identity signals.
  - `useful`: The homepage shows three of the four identity signals.
  - `high_confidence`: The homepage shows all four identity signals: an organization name in structured data, a postal address, a support-style email address, and a social profile link.
- **metadata-consistency**
  - `unknown`: The homepage could not be read during the scan — no response, a temporary error, an access restriction, or a page that exceeded the scanner response-size limit before enough of the document was read to compare metadata.
  - `not_detected`: The homepage carries no assessable metadata: no canonical link, no Open Graph url or title tag, and no structured data block.
  - `detected`: The homepage metadata raises three or more consistency warnings (host mismatches between canonical, Open Graph, and page address; an Open Graph updated time more than two years before the scan date; unparseable structured data; or a meta-tag price that contradicts the structured-data price).
  - `parseable`: The homepage metadata raises exactly two of the consistency warnings.
  - `useful`: The homepage metadata raises exactly one of the consistency warnings; or the homepage was too large to read in full and the portion read, which included a complete document head, raised none.
  - `high_confidence`: The homepage metadata is present and raises none of the consistency warnings, including no update timestamp older than two years as of the scan date.

## Grand totals (scored checks)

- maxPoints: 169
- effective max contribution: 158 — checks whose declared cap sits below `high_confidence` cannot earn their full maxPoints, so a site that maxes every check scores 93/100, not 100.
