# How ARD Check validates ARD endpoints

Validated against the ARD spec, version **pre-release (v0.91, 49eb4df)**.

We don't stop at the manifest – we request the links your entries publish and check that each one resolves and, for JSON types, that its body parses as JSON.

1. **Discovery** — We try, in order: the URL you pasted, if it is the manifest itself; /.well-known/ard.json; a link rel="ard" on the page you pasted, only when that page is HTML; and last the predecessor /.well-known/ai-catalog.json, which passes with a warning to move to ard.json. A web page that answers at ard.json with HTML, such as a catch-all page, is not taken as the manifest.
2. **Schema validation** — We validate the manifest against the current ARD schema (ArdManifest), including the uri and date-time formats. That is stricter than the upstream project's own tool, which does not assert them.
3. **Entries** — Each entry must have a urn:air identifier with a fully qualified publisher domain, and identifiers must be unique. We expect two to five representative queries per entry, run the media-type diagnostics ported from the upstream conformance tool, and require a trust manifest to carry an identity. When an identity is present we check the publisher binding the spec describes in §4.5.1; identity forms we cannot parse are reported as not checked, never failed. Registry entries must use a base URL, and when @context is present it should include the ARD context (reported as information).
4. **Live links** — We send GET requests only, with no credentials, and probe up to 10 entries; the rest are reported as not probed. Registry entries are declared-only and are not fetched. For each link we check that it resolves and, for JSON types, that its body parses as JSON. A nested ai-catalog is followed one level only. For text attestations we compare the declared digest with the document, up to 10 per run. A problem with a link is a warning at most, because the spec does not require links to resolve.
5. **Hygiene** — We check that the manifest is served over HTTPS with a JSON content type, whether CORS lets browser-based clients read it, whether it sets Cache-Control, and whether it still carries legacy top-level members such as specVersion, host, or collections.

## How ARD validation works

We check a live manifest against the current ARD specification. But the phase most validators skip is the one that matters most in practice.

We validate the manifest, then request the resources it lists. A manifest can claim anything; a live response confirms the link resolves and, for JSON types, that the body parses as JSON. An agent that follows an entry to an MCP server card should get JSON back, not a login page.

Severity follows the spec's wording: MUST misses are errors, SHOULD misses are warnings, and where the spec is silent we only report what we saw. ARD is still a proposal, so we pin the check to one version of the spec and this page says which. When the spec moves, the check follows.

### What we intentionally don't check

This is a conformance and reachability check, not a test of the services your entries point to. We do not call a registry's search API (POST /search); we only check that a registry entry is declared correctly. We do not read other discovery routes the spec describes: in-page JSON-LD, the robots.txt Agentmap directive, or DNS SVCB records. We do not verify trust manifest signatures, and attestations are checked only as far as their digest. We also don't validate the MCP server cards or A2A agent cards themselves, only that the link resolves and its body parses as JSON; use the MCP and A2A checks for those. And we assert uri and date-time formats that the upstream tool leaves unchecked, so a manifest can pass that tool and still be flagged here.
