{
  "version": "0.2.0",
  "rubricVersion": "0.9",
  "target": "https://developer.mozilla.org",
  "host": "developer.mozilla.org",
  "https": true,
  "measured": {
    "origin": "https://developer.mozilla.org",
    "host": "developer.mozilla.org",
    "https": true,
    "url": "https://developer.mozilla.org/en-US/"
  },
  "redirect": {
    "from": "https://developer.mozilla.org/",
    "to": "https://developer.mozilla.org/en-US/",
    "status": 302,
    "hops": 1,
    "chain": [
      {
        "url": "https://developer.mozilla.org/",
        "status": 302
      }
    ],
    "sameSite": true
  },
  "scannedAt": "2026-10-20T17:06:18.061Z",
  "durationMs": 3030,
  "requests": 29,
  "score": 61.8,
  "parts": {
    "standards": {
      "score": 88.3,
      "share": 0.7,
      "points": {
        "earned": 56.5,
        "available": 64
      },
      "counts": {
        "pass": 12,
        "warn": 2,
        "fail": 0,
        "na": 14,
        "total": 28
      }
    },
    "conventions": {
      "score": 0,
      "share": 0.3,
      "points": {
        "earned": 0,
        "available": 5
      },
      "counts": {
        "pass": 0,
        "warn": 0,
        "fail": 5,
        "na": 3,
        "total": 8
      }
    }
  },
  "previous": null,
  "level": 3,
  "levelName": "Machine-readable",
  "levelBlurb": "Text, title, headings and structured data are in the HTML, with no JavaScript run.",
  "levelCeiling": 3,
  "verdict": "Machine-readable",
  "confidence": 100,
  "confidenceLabel": "high",
  "fingerprint": "1f91c6124a6d8ed47c606a19ee06f9b048a90700b079980ad4350e44b5ceea30",
  "modules": {
    "commerce": {
      "inScope": false,
      "signals": []
    },
    "agentApi": {
      "inScope": false,
      "kinds": [],
      "signals": []
    }
  },
  "isCommerce": false,
  "commerceSignals": [],
  "blocked": null,
  "blockedNote": null,
  "deadline": {
    "ms": 60000,
    "reached": false
  },
  "profile": {
    "id": "api",
    "identified": true,
    "declared": false,
    "ambiguous": [],
    "evidence": [
      "API / developer platform (score 4), matched: A documentation path responds; API reference copy."
    ],
    "scores": [
      {
        "id": "api",
        "score": 4,
        "signals": [
          "A documentation path responds",
          "API reference copy"
        ]
      },
      {
        "id": "saas",
        "score": 2,
        "signals": [
          "A documentation path responds"
        ]
      },
      {
        "id": "institution",
        "score": 1,
        "signals": [
          "An organisation domain"
        ]
      }
    ]
  },
  "categories": [
    {
      "id": "discoverability",
      "label": "Discoverability",
      "score": 100,
      "counted": true,
      "pass": 6,
      "warn": 0,
      "fail": 0,
      "na": 0,
      "total": 6,
      "unscored": {
        "present": 0,
        "defective": 0,
        "absent": 0
      }
    },
    {
      "id": "content",
      "label": "Content",
      "score": 77.3,
      "counted": true,
      "pass": 5,
      "warn": 2,
      "fail": 0,
      "na": 3,
      "total": 10,
      "unscored": {
        "present": 0,
        "defective": 1,
        "absent": 0
      }
    },
    {
      "id": "botaccess",
      "label": "Crawler access",
      "score": 100,
      "counted": true,
      "pass": 1,
      "warn": 0,
      "fail": 0,
      "na": 0,
      "total": 1,
      "unscored": {
        "present": 0,
        "defective": 0,
        "absent": 2
      }
    },
    {
      "id": "protocol",
      "label": "API and agent",
      "score": null,
      "counted": false,
      "pass": 0,
      "warn": 0,
      "fail": 0,
      "na": 6,
      "total": 6,
      "unscored": {
        "present": 0,
        "defective": 0,
        "absent": 0
      }
    },
    {
      "id": "commerce",
      "label": "Commerce",
      "score": null,
      "counted": false,
      "pass": 0,
      "warn": 0,
      "fail": 0,
      "na": 5,
      "total": 5,
      "unscored": {
        "present": 0,
        "defective": 0,
        "absent": 0
      }
    }
  ],
  "checks": [
    {
      "id": "reachable",
      "category": "discoverability",
      "module": "core",
      "tier": "essential",
      "weight": 3,
      "conditional": false,
      "label": "Readable homepage",
      "why": "The homepage is the first URL every agent requests. An error or an empty page gives it nothing to read.",
      "skill": "agent-access",
      "standards": [],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "Measured at https://developer.mozilla.org/en-US/, where https://developer.mozilla.org/ redirects (HTTP 302). HTTP 200 text/html, 119 KB, 899 words of visible text. A temporary redirect is a weaker canonical signal than 301 or 308.",
      "evidence": "HTTP 200 · text/html · 119 KB · final https://developer.mozilla.org/en-US/",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "robots-txt",
      "category": "botaccess",
      "module": "core",
      "tier": "essential",
      "weight": 2,
      "conditional": false,
      "label": "robots.txt crawl policy",
      "why": "Crawlers read robots.txt before they fetch a page (RFC 9309). Its Sitemap line tells them where the URL list is.",
      "skill": "robots-txt",
      "standards": [
        "RFC 9309"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "/robots.txt has 1 group and 3 rules across all groups, and 1 Sitemap line.",
      "evidence": "HTTP 200 · text/plain · 119 bytes · User-agent: * Sitemap: https://developer.mozilla.org/sitemap.xml Disallow: /api/ Disallow: /*/files/ Disallow: /media",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "sitemap-xml",
      "category": "discoverability",
      "module": "core",
      "tier": "essential",
      "weight": 2,
      "conditional": false,
      "label": "XML sitemap",
      "why": "A sitemap lists the URLs a site wants crawled. Google says a small, well-linked site may not need one.",
      "skill": "sitemap",
      "standards": [],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "Sitemap index https://developer.mozilla.org/sitemap.xml parses and lists 10 child sitemaps. This scan does not read the child sitemaps.",
      "evidence": "HTTP 200 · application/xml · 1.3 KB · root <sitemapindex>",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "llms-txt",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "/llms.txt published and well-structured",
      "why": "A 2024 proposal for a markdown index of a site. Google Search does not use it.",
      "skill": "llms-txt",
      "standards": [
        "llmstxt.org"
      ],
      "status": "fail",
      "points": 0,
      "counted": true,
      "excluded": null,
      "detail": "Not served: /llms.txt answered HTTP 404.",
      "evidence": "HTTP 404 · text/html · first 16 KB read",
      "fix": "# MDN Web Docs\n\n> The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.\n\n## Pages\n\n- [MDN Web Docs](https://developer.mozilla.org/)\n- [<choose: name of the page at /docs>](https://developer.mozilla.org/docs)\n",
      "part": "conventions"
    },
    {
      "id": "link-headers",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Discovery via Link response headers",
      "why": "A Link header (RFC 8288) points a client at a resource before it parses the HTML.",
      "skill": "link-headers",
      "standards": [
        "RFC 8288"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: there is nothing for a Link header to name. No llms.txt or markdown variant is in use, and the site serves no OpenAPI document or API catalog.",
      "evidence": null,
      "fix": null,
      "part": "conventions"
    },
    {
      "id": "canonical",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 2,
      "conditional": false,
      "label": "Canonical URL",
      "why": "A canonical link names the one URL a page is known by. Google treats it and redirects as canonical signals.",
      "skill": "canonical",
      "standards": [
        "RFC 6596"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "Measured at https://developer.mozilla.org/en-US/, where https://developer.mozilla.org/ redirects (HTTP 302). Canonical https://developer.mozilla.org/en-US/ matches the page reached.",
      "evidence": "<link rel=\"canonical\" href=\"https://developer.mozilla.org/en-US/\">",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "http-caching",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "HTTP caching of the homepage",
      "why": "Cache-Control says how long the homepage may be reused. A validator lets a crawler ask whether it changed, and a 304 answer skips the body.",
      "skill": "http-caching",
      "standards": [
        "RFC 9111",
        "RFC 9110"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "The homepage sends Cache-Control \"public, max-age=3600\" and ETag and Last-Modified, and a request with If-None-Match and If-Modified-Since was answered HTTP 304 Not Modified.",
      "evidence": "Cache-Control: public, max-age=3600 · ETag: W/\"b76b498cae7043ee81e25fd04fe755e6\" · Last-Modified: Tue, 20 Oct 2026 01:09:12 GMT · conditional GET with If-None-Match and If-Modified-Since: HTTP 304",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "indexing-directives",
      "category": "discoverability",
      "module": "core",
      "tier": "essential",
      "weight": 2,
      "conditional": false,
      "label": "Homepage indexable: no noindex directive",
      "why": "A noindex in a meta tag or in a response header keeps the page out of search results. Bing keeps it out of Copilot too.",
      "skill": "indexing-directives",
      "standards": [],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "No noindex: the homepage has no robots meta tag for robots, bingbot or googlebot, and no X-Robots-Tag header.",
      "evidence": "no robots meta tag for robots, bingbot or googlebot, no X-Robots-Tag header",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "not-found-status",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "A real 404 for a missing page",
      "why": "A URL that does not exist answers 404 or 410 (RFC 9110). A 200 there makes every mistyped link look like a page.",
      "skill": "not-found-status",
      "standards": [
        "RFC 9110"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "/aws-probe-40adf5a0570b, a path that does not exist, answered HTTP 404.",
      "evidence": "HTTP 404 · text/html · first 16 KB read",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "structured-errors",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Structured errors for JSON requests",
      "why": "An agent that asks for JSON and gets an HTML error page has to read a page meant for people. RFC 9457 defines a JSON error format.",
      "skill": "problem-details",
      "standards": [
        "RFC 9457"
      ],
      "status": "fail",
      "points": 0,
      "counted": true,
      "excluded": null,
      "detail": "Not used: /aws-probe-40adf5a0570b, asked for JSON, answered HTTP 404 with an HTML page, not a JSON error.",
      "evidence": "HTTP 404 · text/html · first 16 KB read",
      "fix": "{\n  \"type\": \"about:blank\",\n  \"title\": \"Not Found\",\n  \"status\": 404,\n  \"detail\": \"Nothing is published at this address.\"\n}\n",
      "fixNote": "Send this with Content-Type: application/problem+json and the status 404 when a request for a missing path asks for JSON. Browsers can keep the HTML page (RFC 9457).",
      "part": "conventions"
    },
    {
      "id": "llms-full",
      "category": "discoverability",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "/llms-full.txt expanded context",
      "why": "A convention that puts a site's text in one file. The llms.txt proposal does not define it.",
      "skill": "llms-full-txt",
      "standards": [],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: /llms.txt is not served (HTTP 404), so /llms-full.txt is not asked for.",
      "evidence": null,
      "fix": null,
      "part": "conventions"
    },
    {
      "id": "markdown-negotiation",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Markdown content negotiation",
      "why": "Some coding agents ask for text/markdown. Google Search does not use markdown.",
      "skill": "markdown-negotiation",
      "standards": [
        "RFC 9110"
      ],
      "status": "fail",
      "points": 0,
      "counted": true,
      "excluded": null,
      "detail": "The homepage answered `Accept: text/markdown, text/html;q=0.5` with HTML, which is a valid response.",
      "evidence": "HTTP 200 · text/html · Vary: Accept-Encoding · markdown body: no",
      "fix": "Answer a request whose Accept header prefers text/markdown with a markdown version of the same page, at the same URL.\n- On a CDN that converts HTML to markdown, turn that conversion on for the site.\n- On a CMS or a static build, publish one .md file per page, and serve it when Accept prefers text/markdown.\nSend Content-Type: text/markdown; charset=utf-8 with the markdown.\nSend Vary: Accept with both the markdown and the HTML, so a shared cache keeps them apart.",
      "part": "conventions"
    },
    {
      "id": "headings",
      "category": "content",
      "module": "core",
      "tier": "essential",
      "weight": 2,
      "conditional": false,
      "label": "Semantic heading structure",
      "why": "Headings outline the page for screen readers and for any client that splits text by section.",
      "skill": "semantic-headings",
      "standards": [
        "WCAG 2.2"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "1 H1, 4 H2s, and 8 H3s in an outline of 13 headings, with no skipped level.",
      "evidence": "outline: H1 H2 H3 H3 H3 H3 H2 H3 H3 H3 H3 H2 H2",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "meta",
      "category": "content",
      "module": "core",
      "tier": "essential",
      "weight": 2,
      "conditional": false,
      "label": "Title and description",
      "why": "The title and the description say what a page is about. Google uses them for the title link and the snippet.",
      "skill": "page-metadata",
      "standards": [],
      "status": "warn",
      "points": 0.5,
      "counted": true,
      "excluded": null,
      "detail": "Title \"MDN Web Docs\" (12 characters) and a description of 145 characters. The first H1 \"Resources for Developers, by Developers\" shares 0 of 2 words with the title, brand names aside. Microsoft's guide to AI search answers (October 2025) asks for an H1 that matches the title or closely reflects it.",
      "evidence": "title (12 characters): MDN Web Docs · description (145 characters): The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps. · first H1: Resources for Developers, by Developers",
      "fix": null,
      "fixNote": "Give the first H1 and the title the same subject. Either can change, and brand names do not count.",
      "part": "standards"
    },
    {
      "id": "jsonld",
      "category": "content",
      "module": "core",
      "tier": "essential",
      "weight": 3,
      "conditional": false,
      "label": "JSON-LD structured data",
      "why": "Structured data names the entity a page describes. Google reads JSON-LD, Microdata and RDFa alike.",
      "skill": "structured-data",
      "standards": [
        "schema.org"
      ],
      "status": "warn",
      "points": 0.5,
      "counted": true,
      "excluded": null,
      "detail": "1 RDFa item on the homepage, and no top-level node names the page entity: BreadcrumbList is a structural type.",
      "evidence": "JSON-LD: 0 blocks, 0 parsed · schema.org @context: no · Microdata: 0 items · RDFa: 1 items · top-level types: BreadcrumbList",
      "fix": "<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Organization\",\n  \"name\": \"MDN Web Docs\",\n  \"url\": \"https://developer.mozilla.org/\"\n}\n</script>",
      "part": "standards"
    },
    {
      "id": "lang",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Language declaration and multilingual access",
      "why": "The lang attribute names the language of the text. WCAG 3.1.1 requires it at level A. Google reads hreflang, not lang.",
      "skill": "language-declaration",
      "standards": [
        "WCAG 2.2",
        "BCP 47"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "html lang=\"en-US\" is a well-formed BCP 47 tag, with no hreflang alternates.",
      "evidence": "html lang=\"en-US\" · alternates: none · content-language: (none)",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "no-js-fallback",
      "category": "content",
      "module": "core",
      "tier": "essential",
      "weight": 3,
      "conditional": false,
      "label": "Content that needs no JavaScript",
      "why": "Several AI crawlers do not run JavaScript. Text that appears only after scripts run is invisible to them.",
      "skill": "server-rendering",
      "standards": [],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "6265 characters of text are in the HTML before any script runs.",
      "evidence": "static text: 6265 characters · inside <noscript>: 0 characters · markup: 121595 characters",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "spa-fallback",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Per-page content separation (no SPA fallback)",
      "why": "A route that answers every URL with the same page makes every URL look alike to a crawler.",
      "skill": "server-rendering",
      "standards": [
        "RFC 9110"
      ],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "The homepage and /en-US/docs/Web/HTML have different titles (\"MDN Web Docs\" and \"HTML: HyperText Markup Language | MDN\") and different main text (14% word overlap).",
      "evidence": "compared / with /en-US/docs/Web/HTML · titles \"MDN Web Docs\" / \"HTML: HyperText Markup Language | MDN\" · skeleton 82% · main-text word overlap 14% · main text 6995 characters",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "viewport",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Responsive markup",
      "why": "Google indexes the smartphone rendering of a page. A viewport that blocks zoom fails WCAG 1.4.4.",
      "skill": "responsive-markup",
      "standards": [],
      "status": "pass",
      "points": 1,
      "counted": true,
      "excluded": null,
      "detail": "viewport content \"width=device-width, initial-scale=1.0\" sets width=device-width and leaves zoom on.",
      "evidence": "viewport meta: width=device-width, initial-scale=1.0",
      "fix": null,
      "part": "standards"
    },
    {
      "id": "ai-rules",
      "category": "botaccess",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "AI crawler policy in robots.txt",
      "why": "A crawler follows the robots.txt group that names it, otherwise the * group. A named group states the site's rules for that crawler.",
      "skill": "ai-rules",
      "standards": [
        "RFC 9309"
      ],
      "status": "fail",
      "points": 0,
      "counted": true,
      "excluded": null,
      "detail": "All 18 AI crawler tokens follow the * group (3 rules); none has its own group.",
      "evidence": "* group: 3 rules, partly disallowed, followed by 18 AI crawler tokens · robots.txt: 1 group, 3 rules",
      "fix": null,
      "part": "conventions"
    },
    {
      "id": "content-signal",
      "category": "botaccess",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Content-Signal preferences",
      "why": "Content-Signal states search, ai-input and ai-train preferences in robots.txt. No crawler documents honouring it.",
      "skill": "content-signals",
      "standards": [
        "contentsignals.org"
      ],
      "status": "fail",
      "points": 0,
      "counted": true,
      "excluded": null,
      "detail": "No Content-Signal line in robots.txt or the homepage headers. Under the policy, no signal states no preference.",
      "evidence": "HTTP 200 · text/plain · 119 bytes",
      "fix": "Content-Signal: search=<choose: yes or no>, ai-input=<choose: yes or no>, ai-train=<choose: yes or no>\n",
      "fixNote": "Add this line to the site's own User-agent: * group in /robots.txt, below its User-agent lines. Each value is the site owner's choice.",
      "part": "conventions"
    },
    {
      "id": "mcp-server",
      "category": "protocol",
      "module": "agent-api",
      "tier": "essential",
      "weight": 3,
      "conditional": true,
      "label": "MCP server answers and lists its tools",
      "why": "An agent given the address of an MCP server can call its tools. The scan opens one session to see that the server answers and what it offers.",
      "skill": "mcp-server",
      "standards": [
        "MCP 2025-11-25"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "openapi",
      "category": "protocol",
      "module": "agent-api",
      "tier": "essential",
      "weight": 3,
      "conditional": true,
      "label": "OpenAPI definition",
      "why": "An OpenAPI document describes an HTTP API so a client can call it without guessing.",
      "skill": "openapi",
      "standards": [
        "OpenAPI 3.x"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "oauth-discovery",
      "category": "protocol",
      "module": "agent-api",
      "tier": "essential",
      "weight": 2,
      "conditional": true,
      "label": "OAuth discovery documents",
      "why": "OAuth metadata tells a client where and how to authorise against the API.",
      "skill": "oauth-discovery",
      "standards": [
        "RFC 8414",
        "RFC 9728"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "api-catalog",
      "category": "protocol",
      "module": "agent-api",
      "tier": "recommended",
      "weight": 2,
      "conditional": true,
      "label": "API catalog",
      "why": "An API catalog lists a publisher's APIs in one document at a fixed address (RFC 9727).",
      "skill": "api-catalog",
      "standards": [
        "RFC 9727"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "webmcp",
      "category": "protocol",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "WebMCP browser tool declaration",
      "why": "WebMCP lets a page register tools for an in-browser agent. It is a W3C Community Group draft.",
      "skill": "webmcp",
      "standards": [
        "W3C WebMCP"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage has no form and calls no registerTool, so it offers no task to declare.",
      "evidence": null,
      "fix": null,
      "part": "conventions"
    },
    {
      "id": "docs",
      "category": "protocol",
      "module": "agent-api",
      "tier": "recommended",
      "weight": 2,
      "conditional": true,
      "label": "Documentation reachable",
      "why": "Documentation linked as service-doc (RFC 8631), or from the homepage, is how a client learns the API.",
      "skill": "documentation",
      "standards": [
        "RFC 8631"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "pricing-structured",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 2,
      "conditional": false,
      "label": "Structured pricing information",
      "why": "A price in markup is read without parsing prose. An Offer with a price and no currency is ambiguous.",
      "skill": "pricing-schema",
      "standards": [
        "schema.org/Offer"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: no Offer or PriceSpecification in the homepage markup states a price, and no pricing page states a complete one.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "service-schema",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Service/product scope machine-readable",
      "why": "Service markup states what is offered, by whom and where. An incomplete node leaves a client to guess.",
      "skill": "service-schema",
      "standards": [
        "schema.org/Service"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage markup declares no Service-type node.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "contact",
      "category": "content",
      "module": "core",
      "tier": "recommended",
      "weight": 1,
      "conditional": false,
      "label": "Structured contact information",
      "why": "A ContactPoint in the Organization markup makes the contact route machine-readable.",
      "skill": "contact-schema",
      "standards": [
        "schema.org/Organization"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage markup declares no Organization-type node.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "status-page",
      "category": "protocol",
      "module": "agent-api",
      "tier": "recommended",
      "weight": 1,
      "conditional": true,
      "label": "Service status and changelog feed",
      "why": "A status page and a changelog feed say whether the service is up and what changed.",
      "skill": "status-changelog",
      "standards": [
        "RFC 9727",
        "RFC 4287"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "product-schema",
      "category": "commerce",
      "module": "commerce",
      "tier": "essential",
      "weight": 3,
      "conditional": true,
      "label": "Product/catalog schema",
      "why": "Product and Offer markup on product pages feeds merchant listings.",
      "skill": "product-schema",
      "standards": [
        "schema.org/Product"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "returns",
      "category": "commerce",
      "module": "commerce",
      "tier": "recommended",
      "weight": 1,
      "conditional": true,
      "label": "Return policy machine-readable",
      "why": "A MerchantReturnPolicy states return terms in markup, also under the Organization.",
      "skill": "return-policy-schema",
      "standards": [
        "schema.org/MerchantReturnPolicy"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "inventory-freshness",
      "category": "commerce",
      "module": "commerce",
      "tier": "recommended",
      "weight": 2,
      "conditional": true,
      "label": "Inventory and price freshness",
      "why": "availability says whether an item is in stock. A past priceValidUntil can hide a product snippet.",
      "skill": "inventory-freshness",
      "standards": [
        "schema.org/Offer"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "seller-identity",
      "category": "commerce",
      "module": "commerce",
      "tier": "recommended",
      "weight": 1,
      "conditional": true,
      "label": "Seller identity declared",
      "why": "On a marketplace, the seller named on an offer is who the buyer contracts with.",
      "skill": "seller-identity",
      "standards": [
        "schema.org/Organization"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    },
    {
      "id": "shipping-costs",
      "category": "commerce",
      "module": "commerce",
      "tier": "recommended",
      "weight": 2,
      "conditional": true,
      "label": "Shipping cost and delivery declared",
      "why": "shippingDetails lets a client compute the delivered price.",
      "skill": "shipping-costs",
      "standards": [
        "schema.org/OfferShippingDetails"
      ],
      "status": "na",
      "points": 0,
      "counted": false,
      "excluded": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "part": "standards"
    }
  ],
  "unscored": [
    {
      "id": "dns-aid",
      "category": "discoverability",
      "module": "agent-api",
      "label": "DNS-AID discovery record",
      "group": "convention",
      "maturity": "experimental",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "faq-schema",
      "category": "content",
      "module": "core",
      "label": "FAQ markup for visible questions",
      "group": "choice",
      "maturity": "adopted",
      "state": "out-of-scope",
      "detail": "Not scored: no heading on the homepage names a FAQ section, and the homepage carries no FAQPage markup.",
      "evidence": "visible questions under a FAQ heading: 0",
      "fix": null,
      "fixNote": null
    },
    {
      "id": "breadcrumb",
      "category": "content",
      "module": "core",
      "label": "Breadcrumb markup on an inner page",
      "group": "choice",
      "maturity": "adopted",
      "state": "defective",
      "detail": "The inner page /en-US/docs/Web/HTML states a BreadcrumbList of 2 ListItems: 2 without a resolvable item URL (\"Web\", \"HTML\").",
      "evidence": "https://developer.mozilla.org/en-US/docs/Web/HTML · HTTP 200 · text/html · RDFa trail: Web > HTML · ListItem: 2 · item URLs: 0",
      "fix": "<script type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"MDN Web Docs\",\n      \"item\": \"https://developer.mozilla.org/en-US/\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"<choose: name of this section>\",\n      \"item\": \"<choose: URL of the /en-US/docs page, if the site has one>\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"<choose: name of this section>\",\n      \"item\": \"https://developer.mozilla.org/en-US/docs/Web\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"HTML: HyperText Markup Language\",\n      \"item\": \"https://developer.mozilla.org/en-US/docs/Web/HTML\"\n    }\n  ]\n}\n</script>",
      "fixNote": "Replace each <choose: …> with the name or the URL the site uses for that section, and drop a level that has no page. Show the same trail as links on the page."
    },
    {
      "id": "webbotauth",
      "category": "botaccess",
      "module": "agent-api",
      "label": "Web Bot Auth key directory",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "ai-policy",
      "category": "botaccess",
      "module": "core",
      "label": "AI usage policy page",
      "group": "choice",
      "maturity": "experimental",
      "state": "out-of-scope",
      "detail": "Not scored: robots.txt and Content-Signal state no AI restriction, so there is none for a policy page to explain.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "security-txt",
      "category": "botaccess",
      "module": "core",
      "label": "security.txt (RFC 9116)",
      "group": "choice",
      "maturity": "adopted",
      "state": "absent",
      "detail": "Not published: /.well-known/security.txt and /security.txt answered HTTP 404.",
      "evidence": "/.well-known/security.txt: HTTP 404 · text/html · first 20 KB read; /security.txt: HTTP 404 · text/html · first 19 KB read",
      "fix": "Contact: <choose: mailto: or https: address for security reports>\nExpires: 2027-04-18T17:06:15.000Z\nPreferred-Languages: en-US\nCanonical: https://developer.mozilla.org/.well-known/security.txt\n",
      "fixNote": "Serve this as text/plain at /.well-known/security.txt. Contact is your own decision, and RFC 9116 recommends an Expires less than a year ahead."
    },
    {
      "id": "ai-grounding-directives",
      "category": "botaccess",
      "module": "core",
      "label": "Snippet and AI grounding directives",
      "group": "choice",
      "maturity": "adopted",
      "state": "absent",
      "detail": "Not used: the homepage has no noarchive, nocache, nosnippet or max-snippet:0 directive, and no data-nosnippet attribute, so Bing applies none of the limits they set on snippets and Copilot answers.",
      "evidence": "no robots meta tag for robots, bingbot or googlebot, no X-Robots-Tag header · data-nosnippet: 0 elements",
      "fix": null,
      "fixNote": null
    },
    {
      "id": "mcp-card",
      "category": "protocol",
      "module": "agent-api",
      "label": "MCP server card",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "agent-skills",
      "category": "protocol",
      "module": "agent-api",
      "label": "Agent Skills declaration",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "a2a-card",
      "category": "protocol",
      "module": "agent-api",
      "label": "A2A agent card",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "a2a-signed",
      "category": "protocol",
      "module": "agent-api",
      "label": "Cryptographically signed agent card",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "auth-md",
      "category": "protocol",
      "module": "agent-api",
      "label": "/auth.md agent authentication guide",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "ard-manifest",
      "category": "protocol",
      "module": "agent-api",
      "label": "ARD resource discovery manifest",
      "group": "convention",
      "maturity": "experimental",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "mpp-discovery",
      "category": "protocol",
      "module": "agent-api",
      "label": "MPP discovery in OpenAPI (x-payment-info)",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "payment-protocols",
      "category": "commerce",
      "module": "commerce",
      "label": "Agent payment protocol (UCP profile or x402)",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "agent-purchase",
      "category": "commerce",
      "module": "commerce",
      "label": "Agent purchase policy",
      "group": "choice",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "ucp-manifest",
      "category": "commerce",
      "module": "commerce",
      "label": "UCP manifest (/.well-known/ucp)",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "acp-discovery",
      "category": "commerce",
      "module": "commerce",
      "label": "ACP discovery (/.well-known/acp.json)",
      "group": "convention",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: the homepage shows no commercial signal, so commerce checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "sandbox-environment",
      "category": "protocol",
      "module": "agent-api",
      "label": "Sandbox or test environment documented",
      "group": "choice",
      "maturity": "experimental",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "rate-limits-declared",
      "category": "protocol",
      "module": "agent-api",
      "label": "Rate limits and quotas documented",
      "group": "choice",
      "maturity": "experimental",
      "state": "out-of-scope",
      "detail": "Not scored: the scan found no API or agent surface, so API and agent checks are not asked of this site.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "licensing-terms",
      "category": "content",
      "module": "core",
      "label": "Reuse and licensing terms declared",
      "group": "choice",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: this check applies to publisher or institution sites; this site was measured as API platform.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "provenance-declared",
      "category": "content",
      "module": "core",
      "label": "Content provenance declared",
      "group": "choice",
      "maturity": "adopted",
      "state": "out-of-scope",
      "detail": "Not scored: this check applies to publisher or institution sites; this site was measured as API platform.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "booking-action",
      "category": "commerce",
      "module": "core",
      "label": "Machine-readable booking action",
      "group": "choice",
      "maturity": "draft",
      "state": "out-of-scope",
      "detail": "Not scored: this check applies to services sites; this site was measured as API platform.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    },
    {
      "id": "document-formats",
      "category": "content",
      "module": "core",
      "label": "Documents in machine-readable formats",
      "group": "choice",
      "maturity": "adopted",
      "state": "out-of-scope",
      "detail": "Not scored: this check applies to institution sites; this site was measured as API platform.",
      "evidence": null,
      "fix": null,
      "fixNote": null
    }
  ],
  "counts": {
    "pass": 12,
    "warn": 2,
    "fail": 0,
    "na": 14,
    "total": 28
  },
  "unscoredCounts": {
    "present": 0,
    "defective": 1,
    "absent": 2,
    "out-of-scope": 21,
    "not-measured": 0,
    "total": 24
  },
  "blockedBy": null,
  "nextLevelGaps": [],
  "ratio": {
    "passed": 12,
    "applicable": 14,
    "label": "12/14"
  },
  "meta": {
    "title": "MDN Web Docs",
    "description": "The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.",
    "lang": "en-US",
    "words": 899,
    "tokensEst": 1214,
    "bytes": 121702,
    "status": 200
  },
  "requests_log": [
    {
      "path": "/",
      "status": 200,
      "bytes": 121702,
      "ms": 221,
      "contentType": "text/html",
      "hops": 1
    },
    {
      "path": "/robots.txt",
      "status": 200,
      "bytes": 119,
      "ms": 56,
      "contentType": "text/plain",
      "hops": 0
    },
    {
      "path": "/sitemap.xml",
      "status": 200,
      "bytes": 1282,
      "ms": 80,
      "contentType": "application/xml",
      "hops": 0
    },
    {
      "path": "/llms.txt",
      "status": 404,
      "bytes": 19471,
      "ms": 592,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/security.txt",
      "status": 404,
      "bytes": 20480,
      "ms": 486,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/security.txt",
      "status": 404,
      "bytes": 19621,
      "ms": 493,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/about",
      "status": 404,
      "bytes": 20480,
      "ms": 463,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/contact",
      "status": 404,
      "bytes": 19621,
      "ms": 473,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/pricing",
      "status": 404,
      "bytes": 19464,
      "ms": 410,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/docs",
      "status": 200,
      "bytes": 149816,
      "ms": 267,
      "contentType": "text/html",
      "hops": 2
    },
    {
      "path": "/developers",
      "status": 404,
      "bytes": 20480,
      "ms": 448,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/api-catalog",
      "status": 404,
      "bytes": 19645,
      "ms": 401,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/openapi.json",
      "status": 404,
      "bytes": 20480,
      "ms": 417,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/openapi.json",
      "status": 404,
      "bytes": 20480,
      "ms": 467,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/mcp/server-card.json",
      "status": 404,
      "bytes": 20480,
      "ms": 437,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/ai-catalog.json",
      "status": 404,
      "bytes": 19466,
      "ms": 708,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/agent-card.json",
      "status": 404,
      "bytes": 19472,
      "ms": 489,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/oauth-protected-resource",
      "status": 404,
      "bytes": 19472,
      "ms": 461,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/oauth-authorization-server",
      "status": 404,
      "bytes": 19471,
      "ms": 502,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/.well-known/openid-configuration",
      "status": 404,
      "bytes": 19621,
      "ms": 527,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/en-US/docs/Web/HTML",
      "status": 200,
      "bytes": 186518,
      "ms": 23,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/",
      "status": 200,
      "bytes": 121702,
      "ms": 128,
      "contentType": "text/html",
      "hops": 1
    },
    {
      "path": "/",
      "status": 304,
      "bytes": 0,
      "ms": 26,
      "contentType": "",
      "hops": 0
    },
    {
      "path": "/aws-probe-40adf5a0570b",
      "status": 404,
      "bytes": 20480,
      "ms": 890,
      "contentType": "text/html",
      "hops": 0
    },
    {
      "path": "/aws-probe-40adf5a0570b",
      "status": 404,
      "bytes": 20480,
      "ms": 486,
      "contentType": "text/html",
      "hops": 0
    }
  ],
  "usable": {
    "kind": "none"
  }
}