{
 "name": "The AgentDrives Standard",
 "version": "0.10",
 "status": "draft",
 "date": "2026-10-25",
 "licence": "CC BY 4.0",
 "page": "https://agentdrives.com/standard",
 "markdown": "https://agentdrives.com/standard.md",
 "classes": [
  {
   "id": "core",
   "label": "Core",
   "meaning": "An agent can't do the work without it."
  },
  {
   "id": "recommended",
   "label": "Recommended",
   "meaning": "An agent works faster and makes fewer mistakes with it."
  },
  {
   "id": "advanced",
   "label": "Advanced",
   "meaning": "Newer standards an agent uses where they exist."
  }
 ],
 "statuses": [
  {
   "id": "measured",
   "label": "Measured in every drive"
  },
  {
   "id": "partly",
   "label": "Partly measured"
  },
  {
   "id": "not_measured",
   "label": "Not measured yet"
  }
 ],
 "sections": [
  {
   "id": "find",
   "title": "Find",
   "about": "An agent reads about your product before it uses it.",
   "criteria": [
    "FIND-01",
    "FIND-02",
    "FIND-03",
    "FIND-04",
    "FIND-05",
    "FIND-06"
   ]
  },
  {
   "id": "docs",
   "title": "Docs",
   "about": "What an agent reads to make its first call, then real work.",
   "criteria": [
    "DOCS-01",
    "DOCS-02",
    "DOCS-03",
    "DOCS-04",
    "DOCS-05",
    "DOCS-06",
    "DOCS-07",
    "DOCS-08",
    "DOCS-09",
    "DOCS-10",
    "DOCS-11"
   ]
  },
  {
   "id": "get-in",
   "title": "Get in",
   "about": "An account and a credential without a person.",
   "criteria": [
    "IN-01",
    "IN-02",
    "IN-03",
    "IN-04",
    "IN-05",
    "IN-06",
    "IN-07",
    "IN-08",
    "IN-09",
    "IN-10",
    "IN-11",
    "IN-12"
   ]
  },
  {
   "id": "api",
   "title": "API",
   "about": "Calls an agent can build from the spec and retry safely.",
   "criteria": [
    "API-01",
    "API-02",
    "API-03",
    "API-04",
    "API-05",
    "API-06",
    "API-07",
    "API-08",
    "API-09"
   ]
  },
  {
   "id": "mcp",
   "title": "MCP",
   "about": "A server an agent can connect to and pick the right tools from.",
   "criteria": [
    "MCP-01",
    "MCP-02",
    "MCP-03",
    "MCP-04",
    "MCP-05",
    "MCP-06",
    "MCP-07",
    "MCP-08",
    "MCP-09",
    "MCP-10",
    "MCP-11"
   ]
  },
  {
   "id": "cli",
   "title": "CLI and SDKs",
   "about": "Commands and libraries that run with nobody at the keyboard.",
   "criteria": [
    "CLI-01",
    "CLI-02",
    "CLI-03"
   ]
  },
  {
   "id": "errors",
   "title": "Errors",
   "about": "Errors an agent can read, fix and get past.",
   "criteria": [
    "ERR-01",
    "ERR-02",
    "ERR-03",
    "ERR-04",
    "ERR-05",
    "ERR-06",
    "ERR-07"
   ]
  },
  {
   "id": "limits",
   "title": "Limits",
   "about": "Rate and plan limits an agent can see and keep to.",
   "criteria": [
    "LIM-01",
    "LIM-02",
    "LIM-03",
    "LIM-04"
   ]
  },
  {
   "id": "pay",
   "title": "Pay",
   "about": "Paying without a card form or a person.",
   "criteria": [
    "PAY-01",
    "PAY-02",
    "PAY-03",
    "PAY-04",
    "PAY-05",
    "PAY-06"
   ]
  },
  {
   "id": "leave",
   "title": "Leave",
   "about": "Cancel, delete and export by API.",
   "criteria": [
    "LEAVE-01",
    "LEAVE-02",
    "LEAVE-03",
    "LEAVE-04"
   ]
  },
  {
   "id": "protocols",
   "title": "Agent protocols",
   "about": "Newer ways for agents to find and call you.",
   "criteria": [
    "PROTO-01",
    "PROTO-02",
    "PROTO-03",
    "PROTO-04"
   ]
  }
 ],
 "market": {
  "date": "2026-10-25",
  "products": 151,
  "min_count": 5,
  "about": "Of the listed products whose drives graded a criterion, how many pass, partly pass and fail it. A count under 5 is null."
 },
 "criteria": [
  {
   "id": "FIND-01",
   "section": "find",
   "title": "Agents may read docs, API and sign-up",
   "requirement": "robots.txt and bot rules let a declared agent read docs, the API reference and the sign-up page.",
   "why": "An agent that robots.txt or a bot rule turns away never reads a page about your product.",
   "fix": "Allow declared AI agents on your docs, API reference and sign-up page in robots.txt and your bot rules.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#find-01"
  },
  {
   "id": "FIND-02",
   "section": "find",
   "title": "llms.txt that works",
   "requirement": "Valid llms.txt (H1, summary, sections of links), links resolve, under 50k characters, linked from doc pages.",
   "why": "One short file tells an agent where everything is, without crawling the site.",
   "fix": "Publish /llms.txt with a title, a summary and sections of working links, under 50k characters.",
   "graded": "We fetch /llms.txt (or the one on your docs. site) and /llms-full.txt. llms.txt must be a text file that starts with a # title, has a > summary and ## sections of Markdown links, and stays under 50,000 characters. We open five of its links and each must answer. Whether doc pages link to it isn't checked yet.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#find-02"
  },
  {
   "id": "FIND-03",
   "section": "find",
   "title": "Markdown twins of doc pages",
   "requirement": "Each doc page has a Markdown version (.md URL or Accept: text/markdown with Vary: Accept) with the same content.",
   "why": "An agent reads Markdown best. The same page as HTML costs it many times the tokens.",
   "fix": "Serve each doc page as Markdown at a .md URL, or on Accept: text/markdown with Vary: Accept.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#find-03"
  },
  {
   "id": "FIND-04",
   "section": "find",
   "title": "OpenAPI an agent can find",
   "requirement": "An OpenAPI document at a stable public URL, linked from the docs, or listed in /.well-known/api-catalog (RFC 9727).",
   "why": "With the spec an agent knows every call without guessing from prose.",
   "fix": "Put your OpenAPI file at a stable URL, link it from the docs and list it in /.well-known/api-catalog.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#find-04"
  },
  {
   "id": "FIND-05",
   "section": "find",
   "title": "MCP server an agent can find",
   "requirement": "The MCP URL, transport and sign-in are on one docs page and in a server card or the MCP registry.",
   "why": "An agent can only connect to an MCP server when it knows the address and how to sign in.",
   "fix": "Put the MCP URL, transport and sign-in on one docs page, and publish a server card or a registry entry.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#find-05"
  },
  {
   "id": "FIND-06",
   "section": "find",
   "title": "Prices an agent can read",
   "requirement": "Plan names, prices, units, limits and overage are in page text (not images or script only), ideally also as JSON.",
   "why": "An agent choosing a product for someone compares prices. A price inside an image is no price to it.",
   "fix": "Write each plan's price, unit, limits and overage as page text, and offer the same as JSON.",
   "graded": "The pricing page's text without script: pass when it names prices, what each is per and a plan (or the resource, for usage pricing); partly when one is missing; fail when no price is in the text. JSON pricing is noted.",
   "market": {
    "n": 39,
    "pass": 32,
    "partly": null,
    "fail": null
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#find-06"
  },
  {
   "id": "DOCS-01",
   "section": "docs",
   "title": "A quickstart that gets to the first call",
   "requirement": "One page from zero to a first working call: credential, one complete request, the expected answer.",
   "why": "The first call is where agents give up most. One page that gets there saves the most attempts.",
   "fix": "Write one page from no account to a first working call, with the full request and the answer.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-01"
  },
  {
   "id": "DOCS-02",
   "section": "docs",
   "title": "Sign-in documented for software",
   "requirement": "How to get a credential without a browser, its scopes, its lifetime and how to revoke it.",
   "why": "Without it an agent tries a browser login it can't finish.",
   "fix": "Document how software gets a credential, its scopes, how long it lasts and how to revoke it.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-02"
  },
  {
   "id": "DOCS-03",
   "section": "docs",
   "title": "Error reference",
   "requirement": "Every error code listed with its meaning and the fix.",
   "why": "An agent fixes an error fast when it can look the code up.",
   "fix": "List every error code with what it means and how to fix it.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-03"
  },
  {
   "id": "DOCS-04",
   "section": "docs",
   "title": "A page for each core task",
   "requirement": "Each core capability has its own page or reference entry.",
   "why": "An agent looks for the task it was given, not for how your docs are organised.",
   "fix": "Give each core task its own page or reference entry.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#docs-04"
  },
  {
   "id": "DOCS-05",
   "section": "docs",
   "title": "Examples that run as written",
   "requirement": "Core pages carry complete examples (imports, auth, real field names) that run unchanged.",
   "why": "Agents copy examples. One wrong field name costs a round of errors.",
   "fix": "Make every example complete, with imports, auth and real field names, and test that it runs.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-05"
  },
  {
   "id": "DOCS-06",
   "section": "docs",
   "title": "Docs match what the product does",
   "requirement": "Documented calls behave as documented.",
   "why": "An agent trusts the docs. When a call does something else, it's stuck.",
   "fix": "Test the documented calls against the live product and fix whichever side is wrong.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-06"
  },
  {
   "id": "DOCS-07",
   "section": "docs",
   "title": "Docs cover the whole surface",
   "requirement": "Everything the product does over API, MCP or CLI is documented. Nothing works only undocumented.",
   "why": "An agent only uses what it can read about.",
   "fix": "Document every call your API, MCP server and CLI accept.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-07"
  },
  {
   "id": "DOCS-08",
   "section": "docs",
   "title": "Pages fit one fetch",
   "requirement": "Markdown under 50k characters. Content not hidden behind script, tabs or late in the page.",
   "why": "Agents read a page in one fetch. What sits behind a tab or a script, they never see.",
   "fix": "Keep each page's Markdown under 50k characters, with its content in the page itself.",
   "graded": "Each docs page we read is sized as text: over 50,000 characters is too big for one fetch. A page with under 30 words before script runs and 150 or more after it hides its content. Pass: no page flagged; fail: more than half.",
   "market": {
    "n": 62,
    "pass": 29,
    "partly": 33,
    "fail": 0
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-08"
  },
  {
   "id": "DOCS-09",
   "section": "docs",
   "title": "Dated changes",
   "requirement": "A dated changelog, the API version on each reference page, deprecations announced with dates.",
   "why": "An agent working from older docs needs to see what changed and when.",
   "fix": "Keep a dated changelog, show the API version on reference pages and date every deprecation.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-09"
  },
  {
   "id": "DOCS-10",
   "section": "docs",
   "title": "A path written for agents",
   "requirement": "A page or llms.txt section that tells an agent which way in, which surface, and which limits apply to it.",
   "why": "An agent starts faster when the docs say which way in is meant for it.",
   "fix": "Add a page or llms.txt section for agents: the way in, the surface to use and its limits.",
   "graded": "From the docs we read and llms.txt: the best page or section for agents (or an MCP page), by what its title and headings name. Pass: how an agent gets in, which surface to use and its limits; partly: one or two of them; fail: no such page.",
   "market": {
    "n": 62,
    "pass": 13,
    "partly": 35,
    "fail": 14
   },
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-10"
  },
  {
   "id": "DOCS-11",
   "section": "docs",
   "title": "Docs an agent can navigate",
   "requirement": "An llms.txt or sitemap that lists every docs page, one topic per page under clear headings, a code sample to copy on each API reference page, and a quickstart with a first request.",
   "why": "An agent finds its way by the index and the headings, and copies the code it sees. Docs without them cost it guesses.",
   "fix": "List every docs page in llms.txt, keep one topic per page under headings, put a code sample on each API page and a first request on the quickstart.",
   "graded": "From the docs we read: four parts, each scored from 0 to 1. The index (an llms.txt by how much of the docs it lists, else a sitemap), pages with headings and one topic, API reference pages with a code block, and a quickstart with a code block. Pass: an average of 0.85 or more with no part under 0.6; fail: under 0.5.",
   "market": {
    "n": 62,
    "pass": 20,
    "partly": 41,
    "fail": null
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#docs-11"
  },
  {
   "id": "IN-01",
   "section": "get-in",
   "title": "A way in with no person",
   "requirement": "At least one route gets an agent working without a person: key by API, pay per call, keyless, or a sign-up it can finish.",
   "why": "If every way in needs a person, an agent working alone stops at the door.",
   "fix": "Offer one way in an agent can finish on its own: a key by API, pay per call, no key, or a sign-up without a person.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#in-01"
  },
  {
   "id": "IN-02",
   "section": "get-in",
   "title": "The best route exists and works",
   "requirement": "The most agent-native route the product's model allows is offered: a key from one API call (limited until a person claims it) or a paid call. OAuth only where a person's data is at stake.",
   "why": "The shorter the way in, the more agents reach the first call.",
   "fix": "Offer a key from one API call, limited until a person claims it, or a paid call. Keep OAuth for a person's data.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-02"
  },
  {
   "id": "IN-03",
   "section": "get-in",
   "title": "Fast to the first call",
   "requirement": "First working call within minutes and a few calls.",
   "why": "Every extra step is a place where an agent can stop.",
   "fix": "Cut the path to a first call down to a few calls and a few minutes.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-03"
  },
  {
   "id": "IN-04",
   "section": "get-in",
   "title": "Signed agents get past the bot check",
   "requirement": "A verified or signed agent (Web Bot Auth) is not challenged on sign-up, login and API paths.",
   "why": "A signed agent has told you who it is. A challenge stops it anyway.",
   "fix": "Let verified and signed agents (Web Bot Auth) through on sign-up, login and API paths.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#in-04"
  },
  {
   "id": "IN-05",
   "section": "get-in",
   "title": "No phone, card or ID at step one",
   "requirement": "Sign-up asks only for what an agent has: an inbox, or nothing.",
   "why": "An agent has an inbox. It has no phone, card or passport.",
   "fix": "Ask only for an email address at sign-up, or nothing.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-05"
  },
  {
   "id": "IN-06",
   "section": "get-in",
   "title": "Keys an agent can manage",
   "requirement": "Keys can be made, scoped, listed and revoked by API. They expire or rotate, and a prefix shows what they are.",
   "why": "An agent that can't list or revoke its own keys leaves old ones behind.",
   "fix": "Let keys be made, scoped, listed and revoked by API, with an expiry and a prefix that says what they are.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-06"
  },
  {
   "id": "IN-07",
   "section": "get-in",
   "title": "MCP and OAuth sign-in set up to spec",
   "requirement": "401 with WWW-Authenticate resource_metadata. RFC 9728 and RFC 8414 metadata valid. CIMD or DCR. PKCE S256. Consent finishes without a lost browser step.",
   "why": "MCP clients sign in by the spec. A missing header or metadata file stops them.",
   "fix": "Answer 401 with WWW-Authenticate resource_metadata, publish valid RFC 9728 and RFC 8414 metadata, and support PKCE S256 with CIMD or DCR.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-07"
  },
  {
   "id": "IN-08",
   "section": "get-in",
   "title": "Sign-in for agents acting for a person",
   "requirement": "Where a person's data is at stake: device flow (RFC 8628) or a back-channel approval, so the agent never needs to drive a browser.",
   "why": "An agent acting for a person needs that person's yes without driving a browser.",
   "fix": "Support the device flow (RFC 8628) or a back-channel approval.",
   "graded": "From the ways in a drive finds: a device flow or an identity assertion beside an app sign-in (OAuth) passes, an app sign-in without either fails. Whether a person's data is at stake, and back-channel approval other than these, aren't tested yet.",
   "market": {
    "n": 57,
    "pass": 27,
    "partly": 0,
    "fail": 30
   },
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-08"
  },
  {
   "id": "IN-09",
   "section": "get-in",
   "title": "A person can claim what the agent made",
   "requirement": "An agent-made account comes with a claim link for its person and clear limits until then.",
   "why": "The person behind the agent must be able to take the account over.",
   "fix": "Give every agent-made account a claim link for its person, and state its limits until then.",
   "class": "recommended",
   "status": "not_measured",
   "status_label": "Not measured yet",
   "url": "https://agentdrives.com/standard#in-09"
  },
  {
   "id": "IN-10",
   "section": "get-in",
   "title": "Terms allow an agent's account",
   "requirement": "Terms don't ban accounts or sign-ups made by software.",
   "why": "Terms that ban software sign-ups make every agent's account a breach.",
   "fix": "Allow accounts made by software in your terms.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#in-10"
  },
  {
   "id": "IN-11",
   "section": "get-in",
   "title": "Every way in works for an agent",
   "requirement": "Each way in the product offers (an API key, OAuth client credentials, a device flow, an email link, a password, single sign-on) lets an agent in without a person, or the docs say which way is for agents.",
   "why": "An agent tries the ways it finds. Each one that stops it is time lost, and some agents never try another.",
   "fix": "Make every way in you offer work for an agent without a person, or say in the docs which one is for agents.",
   "graded": "A drive lists every way in it finds and whether the agent got in by it. It leaves out a person's own key, an admin's invite and a sign-in that needs an account first. Every way it tried let it in: pass. Some: partly. None: fail. Whether the docs name the way for agents isn't tested yet.",
   "market": {
    "n": 67,
    "pass": 13,
    "partly": 21,
    "fail": 33
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#in-11"
  },
  {
   "id": "IN-12",
   "section": "get-in",
   "title": "The best way in is built for agents",
   "requirement": "The best way in for an agent is one built for it (a key from one API call, no account, pay per call or its own agent identity), and an agent gets in by it on its own.",
   "why": "The way in an agent should use decides how far it gets alone.",
   "fix": "Offer a way in built for agents: a key from one API call, no account, or pay per call.",
   "graded": "Each drive names the best way in for an agent and why: the first, agent-native first, that the agent got in by on its own, else the first one offered. Built for agents and the agent got in: pass. In only by email or another account: partly. In by none on its own: fail.",
   "market": {
    "n": 68,
    "pass": 18,
    "partly": 14,
    "fail": 36
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#in-12"
  },
  {
   "id": "API-01",
   "section": "api",
   "title": "OpenAPI that lints clean",
   "requirement": "OpenAPI 3.1 (or 3.0) that validates. Every operation has a unique operationId, a description, success and error responses, and examples.",
   "why": "Tools and agents load a clean spec without errors.",
   "fix": "Validate the OpenAPI file and give every operation an operationId, a description, responses and examples.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-01"
  },
  {
   "id": "API-02",
   "section": "api",
   "title": "The spec matches the live API",
   "requirement": "Live calls match the spec: paths, fields, status codes.",
   "why": "An agent builds its calls from the spec. A wrong field fails the call.",
   "fix": "Test the live API against the spec and fix whichever side is wrong.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-02"
  },
  {
   "id": "API-03",
   "section": "api",
   "title": "One way to page through lists",
   "requirement": "Every list has a limit with a documented maximum and a cursor with an explicit next or has_more.",
   "why": "One paging style lets an agent read every list the same way.",
   "fix": "Give every list a limit with a documented maximum, a cursor and an explicit next or has_more.",
   "graded": "Each list endpoint in the API spec (a GET that returns a list) takes a cursor, page or limit parameter. Every one passes, under half fails, anything between is partly. Whether answers say next or has_more isn't checked yet.",
   "market": {
    "n": 60,
    "pass": 8,
    "partly": 27,
    "fail": 25
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-03"
  },
  {
   "id": "API-04",
   "section": "api",
   "title": "Answers sized for an agent",
   "requirement": "Core reads return what the task needs. Fields can be chosen or expanded. No unbounded lists.",
   "why": "Large answers fill an agent's context and push out the task.",
   "fix": "Let callers choose or expand fields, and bound every list.",
   "graded": "Each limit parameter on a list endpoint in the API spec has a maximum or a default. Every one passes, under half fails, anything between is partly. Field choice and real answer sizes aren't checked yet.",
   "market": {
    "n": 52,
    "pass": 37,
    "partly": 9,
    "fail": 6
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-04"
  },
  {
   "id": "API-05",
   "section": "api",
   "title": "Writes answer with the object",
   "requirement": "A create or update returns the stored object and its id, and it is readable at once.",
   "why": "An agent needs the id to carry on, without a second read.",
   "fix": "Return the stored object and its id from every create and update.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-05"
  },
  {
   "id": "API-06",
   "section": "api",
   "title": "Retries are safe",
   "requirement": "Creates accept an Idempotency-Key: a retry replays the first answer and a changed body is refused.",
   "why": "Agents retry after timeouts. Without a key, a retry makes a second order.",
   "fix": "Accept an Idempotency-Key on creates: replay the first answer and refuse a changed body.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#api-06"
  },
  {
   "id": "API-07",
   "section": "api",
   "title": "Versions an agent can pin",
   "requirement": "A version can be pinned (header or path). Deprecations come with Deprecation and Sunset headers.",
   "why": "A pinned version keeps an agent working while the API moves on.",
   "fix": "Let callers pin a version by header or path, and send Deprecation and Sunset headers.",
   "graded": "The API spec lets callers pin a version (in the path, the server URL or a header) and shows how changes are announced: deprecated marks, Deprecation or Sunset headers, or a changelog. Both pass, one is partly, neither fails. Headers on real answers aren't checked yet.",
   "market": {
    "n": 65,
    "pass": 32,
    "partly": 23,
    "fail": 10
   },
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-07"
  },
  {
   "id": "API-08",
   "section": "api",
   "title": "Long work has a status",
   "requirement": "Long jobs return a status URL or id. Webhooks or events report the end.",
   "why": "An agent can't hold a connection open for a long job.",
   "fix": "Return a status URL or id for long jobs, and report the end by webhook or event.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#api-08"
  },
  {
   "id": "API-09",
   "section": "api",
   "title": "A sandbox or test mode",
   "requirement": "The agent can try the core without real money or real messages.",
   "why": "An agent learns by trying. A sandbox lets it try without spending money or messaging people.",
   "fix": "Offer a test mode or sandbox that covers the core.",
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#api-09"
  },
  {
   "id": "MCP-01",
   "section": "mcp",
   "title": "Remote MCP on the current spec",
   "requirement": "A remote Streamable HTTP endpoint on the current protocol version, where initialize works.",
   "why": "Hosted agents connect over Streamable HTTP. A local-only or old server leaves them out.",
   "fix": "Run a remote MCP endpoint on Streamable HTTP and the current protocol version.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-01"
  },
  {
   "id": "MCP-02",
   "section": "mcp",
   "title": "The core is reachable over MCP",
   "requirement": "Each core capability has a tool.",
   "why": "An agent on MCP can only do what there is a tool for.",
   "fix": "Add a tool for each core capability.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-02"
  },
  {
   "id": "MCP-03",
   "section": "mcp",
   "title": "Tool names that sort themselves",
   "requirement": "Names valid (1 to 128 characters of A-Z, a-z, 0-9, _, - and .), unique, in one consistent pattern (verb_noun or service_resource_verb).",
   "why": "Clear names in one pattern help a model find the right tool in a long list.",
   "fix": "Use valid, unique names in one pattern, such as verb_noun.",
   "graded": "Each name is 1 to 128 of A-Z, a-z, 0-9, _, - and ., used once, and all names follow one pattern such as snake_case.",
   "market": {
    "n": 29,
    "pass": 26,
    "partly": null,
    "fail": 0
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#mcp-03"
  },
  {
   "id": "MCP-04",
   "section": "mcp",
   "title": "Descriptions that say when to use the tool",
   "requirement": "Each description states its purpose, when to use it and when not, key parameters and limits, at a sensible length.",
   "why": "The model picks a tool from its description alone.",
   "fix": "Say in each description what the tool does, when to use it and when not, its key parameters and its limits.",
   "graded": "Each description is scored on four things: 40 to 1,500 characters, says what the tool does, says when to use it, names a parameter or limit. A tool meets it with three of the four.",
   "market": {
    "n": 29,
    "pass": null,
    "partly": 15,
    "fail": 12
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#mcp-04"
  },
  {
   "id": "MCP-05",
   "section": "mcp",
   "title": "Agents pick the right tool",
   "requirement": "Different models choose the right tool for plain-language tasks.",
   "why": "A tool picked wrongly is a task done wrongly.",
   "fix": "Test plain-language tasks on several models and rewrite the descriptions they get wrong.",
   "graded": "From the tool list alone: each tool has a name of its own and a description to choose by, no two tools are so alike that an agent can't tell them apart, and at least half the descriptions say when to use the tool. Every tool clear passes, more than half unclear fails, anything between is partly. Choices by real models aren't tested yet.",
   "market": {
    "n": 29,
    "pass": 5,
    "partly": 24,
    "fail": 0
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-05"
  },
  {
   "id": "MCP-06",
   "section": "mcp",
   "title": "Typed, tight input schemas",
   "requirement": "Every parameter typed and described, required ones listed, enums where values are fixed, and no-argument tools reject extra fields.",
   "why": "Tight schemas stop bad calls before they run.",
   "fix": "Type and describe every parameter, list the required ones, use enums and reject extra fields.",
   "graded": "Every parameter has a type and a description, required ones are listed, fixed values are an enum, and a tool without arguments refuses extra fields.",
   "market": {
    "n": 29,
    "pass": 5,
    "partly": 20,
    "fail": null
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#mcp-06"
  },
  {
   "id": "MCP-07",
   "section": "mcp",
   "title": "Truthful annotations",
   "requirement": "readOnlyHint, destructiveHint and idempotentHint set. A tool marked read-only changes nothing.",
   "why": "Clients use these hints to decide what runs without asking.",
   "fix": "Set readOnlyHint, destructiveHint and idempotentHint on every tool, and keep them true.",
   "graded": "Every tool sets readOnlyHint, and a tool that changes data also sets destructiveHint and idempotentHint. Whether the hints are true isn't checked yet.",
   "market": {
    "n": 29,
    "pass": 15,
    "partly": 8,
    "fail": 6
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-07"
  },
  {
   "id": "MCP-08",
   "section": "mcp",
   "title": "Structured results",
   "requirement": "Data tools declare outputSchema and return structuredContent that matches it, with the same as text.",
   "why": "Structured results let an agent use the data without parsing text.",
   "fix": "Declare outputSchema on data tools and return matching structuredContent, with the same in text.",
   "graded": "Each result the drive got back is structured (structuredContent that fits the tool's outputSchema), JSON text or plain prose. Every tool structured passes, more than half prose fails, anything between is partly. Whether the text repeats the same data isn't checked yet.",
   "market": {
    "n": 8,
    "pass": 6,
    "partly": null,
    "fail": 0
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-08"
  },
  {
   "id": "MCP-09",
   "section": "mcp",
   "title": "Results sized for a context window",
   "requirement": "List and search tools take limit and cursor, and truncate with a hint on what to narrow. Tool results stay small.",
   "why": "One huge result can fill an agent's whole context.",
   "fix": "Give list and search tools a limit and a cursor, and truncate with a hint on how to narrow.",
   "graded": "Each tool's biggest result in tokens (characters divided by 4): under 5,000 passes, 5,000 to 25,000 is partly, over 25,000 fails. We note whether a big result pages or says it was cut, but don't grade it yet.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-09"
  },
  {
   "id": "MCP-10",
   "section": "mcp",
   "title": "Tool errors come back as results",
   "requirement": "Bad input and business errors return isError with what to fix. An unknown tool is a protocol error. One tool needing auth does not break the connection.",
   "why": "An agent reads an error result and tries again. A broken connection ends its session.",
   "fix": "Return bad input and business errors as isError results that say what to fix.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#mcp-10"
  },
  {
   "id": "MCP-11",
   "section": "mcp",
   "title": "A tool list that fits",
   "requirement": "Tool definitions cost few tokens. Large servers load toolsets on demand.",
   "why": "Every tool definition takes context before any work starts.",
   "fix": "Keep tool definitions short, and load large toolsets on demand.",
   "graded": "The whole tool list in tokens (characters divided by 4): under 10,000 passes, 10,000 to 30,000 is partly, over 30,000 fails.",
   "market": {
    "n": 29,
    "pass": 11,
    "partly": 9,
    "fail": 9
   },
   "class": "advanced",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#mcp-11"
  },
  {
   "id": "CLI-01",
   "section": "cli",
   "title": "A CLI that never waits for a person",
   "requirement": "Every command runs with flags or env, emits JSON on request and exits non-zero on failure.",
   "why": "An agent can't answer a prompt in a terminal.",
   "fix": "Make every command run from flags or env, print JSON on request and exit non-zero on failure.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#cli-01"
  },
  {
   "id": "CLI-02",
   "section": "cli",
   "title": "CLI sign-in without a browser",
   "requirement": "A token from env or a flag works. Browser login is optional.",
   "why": "An agent on a server has no browser to log in with.",
   "fix": "Accept a token from env or a flag, and keep browser login optional.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#cli-02"
  },
  {
   "id": "CLI-03",
   "section": "cli",
   "title": "Official SDKs that match the API",
   "requirement": "Typed SDKs in the main languages, current with the API version.",
   "why": "Agents write code with your SDK. An old one writes wrong calls.",
   "fix": "Publish typed SDKs in the main languages and release them with each API version.",
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#cli-03"
  },
  {
   "id": "ERR-01",
   "section": "errors",
   "title": "Real status codes",
   "requirement": "Errors use 4xx and 5xx codes, never a 200 with an error inside.",
   "why": "An agent checks the status code first. A 200 with an error inside looks like success.",
   "fix": "Answer every error with a 4xx or 5xx code.",
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#err-01"
  },
  {
   "id": "ERR-02",
   "section": "errors",
   "title": "Errors a program can read",
   "requirement": "A stable machine code plus a message in a documented shape (RFC 9457 or your own documented format).",
   "why": "A stable code lets an agent handle an error without reading prose.",
   "fix": "Return a stable error code and a message in one documented shape, such as RFC 9457.",
   "graded": "Every error answer from the API or MCP server the drive called carries a stable code: an RFC 9457 problem type, a code or type field, or a JSON-RPC error code with data. A number that only repeats the HTTP status doesn't count. Every error with one passes, none fails, some is partly. Whether the shape is documented isn't checked yet.",
   "market": {
    "n": 21,
    "pass": null,
    "partly": 10,
    "fail": 7
   },
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#err-02"
  },
  {
   "id": "ERR-03",
   "section": "errors",
   "title": "Errors say what to do next",
   "requirement": "The error names the field, the allowed values or the next step (a fix or a docs link).",
   "why": "An error that names the fix gets fixed on the next try.",
   "fix": "Name the field, the allowed values or the next step in each error, with a docs link.",
   "graded": "Every 4xx error the drive met names the field, the allowed values or the next step: a field pointer, a hint, a docs link or a message that says what to change. \"Not found\" alone doesn't count. Every error with one passes, none fails, some is partly. Whether the next try then works is ERR-05.",
   "market": {
    "n": 21,
    "pass": null,
    "partly": 15,
    "fail": 5
   },
   "class": "core",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#err-03"
  },
  {
   "id": "ERR-04",
   "section": "errors",
   "title": "All validation problems at once",
   "requirement": "A bad request lists every invalid field, not only the first.",
   "why": "One problem per answer turns one fix into many round trips.",
   "fix": "Return every invalid field in one answer.",
   "graded": "Each drive sends the API one read-only request with two invalid fields. The answer names both: pass. One: fail, or partly when another answer from the same API listed several. An API that accepts the request, or answers before it checks the fields, isn't measured. Older drives pass when an error they met listed two or more problems.",
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#err-04"
  },
  {
   "id": "ERR-05",
   "section": "errors",
   "title": "The agent recovers",
   "requirement": "After an error the corrected retry succeeds within a few attempts.",
   "why": "Every agent makes mistakes. What counts is that it gets back on track.",
   "fix": "Make errors precise enough that a corrected retry works within a few tries.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#err-05"
  },
  {
   "id": "ERR-06",
   "section": "errors",
   "title": "Auth errors that tell the cases apart",
   "requirement": "Missing, invalid, expired and under-scoped credentials answer differently (401 or 403, WWW-Authenticate, the scope named).",
   "why": "Each case has its own fix: a new key, a refresh or a wider scope.",
   "fix": "Answer missing, invalid, expired and under-scoped credentials differently, and name the scope needed.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#err-06"
  },
  {
   "id": "ERR-07",
   "section": "errors",
   "title": "A request id on every answer",
   "requirement": "Every response carries a request id the owner's support can trace.",
   "why": "With an id, the person behind the agent can trace a call with your support.",
   "fix": "Send a request id on every response.",
   "graded": "Every error answer from the API the drive called carries a request or trace id, in a header or the body. Cloudflare's cf-ray doesn't count. Every error with one passes, none fails, some is partly. Successful answers aren't checked yet.",
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#err-07"
  },
  {
   "id": "LIM-01",
   "section": "limits",
   "title": "Rate limits an agent can obey",
   "requirement": "A limit answers 429 with Retry-After (and RateLimit and RateLimit-Policy headers), never 200 or 500.",
   "why": "An agent that knows when to retry waits. One that doesn't keeps hitting you.",
   "fix": "Answer 429 with Retry-After, and RateLimit and RateLimit-Policy headers.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#lim-01"
  },
  {
   "id": "LIM-02",
   "section": "limits",
   "title": "Limits known before they hit",
   "requirement": "Limits per plan are published and current usage is readable (headers or a usage route).",
   "why": "An agent plans its work around limits it can see.",
   "fix": "Publish the limits per plan and make current usage readable by header or route.",
   "graded": "The API's answers to the drive's own calls carry rate-limit headers (RateLimit or X-RateLimit), and every 429 or 503 says when to retry. Headers on at least half the answers, with a retry time on every 429 or 503, passes. No header and no retry time fails. Anything between is partly. Published limits per plan and usage routes aren't checked yet.",
   "market": {
    "n": 13,
    "pass": 7,
    "partly": null,
    "fail": 5
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#lim-02"
  },
  {
   "id": "LIM-03",
   "section": "limits",
   "title": "Plan gates that explain themselves",
   "requirement": "A plan-gated call says which plan unlocks it and how to buy it by API.",
   "why": "An agent that hits a plan gate needs to know what unlocks it.",
   "fix": "Say in the error which plan unlocks the call and how to buy it by API.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#lim-03"
  },
  {
   "id": "LIM-04",
   "section": "limits",
   "title": "Holds up under repetition",
   "requirement": "Core tasks pass on every one of several runs.",
   "why": "A task that works in one run of three can't be left to an agent.",
   "fix": "Run the core tasks many times and fix what fails some of the time.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#lim-04"
  },
  {
   "id": "PAY-01",
   "section": "pay",
   "title": "Start without a card",
   "requirement": "A free plan or a trial without a card, with a key that works on it.",
   "why": "An agent has no card of its own to start a trial with.",
   "fix": "Offer a free plan or a trial without a card, with a key that works on it.",
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-01"
  },
  {
   "id": "PAY-02",
   "section": "pay",
   "title": "An agent payment rail on the core",
   "requirement": "x402 or MPP challenges that parse, name the right price and networks, settle, and cover the core work.",
   "why": "With x402 or MPP an agent pays per call, with no account and no card form.",
   "fix": "Answer core calls with x402 or MPP challenges that name the right price and networks, and settle them.",
   "class": "advanced",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-02"
  },
  {
   "id": "PAY-03",
   "section": "pay",
   "title": "A plan an agent can buy by API",
   "requirement": "The plan the product sells can be bought by API, Stripe Projects or a 402, without a card form in a browser.",
   "why": "An agent can't fill in a card form in a browser.",
   "fix": "Sell your plans by API, through Stripe Projects or with a 402 payment.",
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-03"
  },
  {
   "id": "PAY-04",
   "section": "pay",
   "title": "Payments safe to retry, with a receipt",
   "requirement": "A retried payment never charges twice, and every payment returns a receipt.",
   "why": "Agents retry. A payment that charges twice costs the person behind it.",
   "fix": "Make payments idempotent and return a receipt for each one.",
   "graded": "Graded from the payments our agent made, else the payment calls in your API spec, else a 402 on your own endpoint. Each payment call needs an idempotency key, on the call or documented for the whole API, and a receipt, invoice or transaction id in its answer. Pass when every call has both, partly when some do, fail when none does. A 402 that wasn't paid is partly: it is safe to retry, but no receipt was seen. Products with only free plans aren't graded.",
   "market": {
    "n": 17,
    "pass": 5,
    "partly": 8,
    "fail": null
   },
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-04"
  },
  {
   "id": "PAY-05",
   "section": "pay",
   "title": "Spend an agent can see and cap",
   "requirement": "Balance, usage and a spend cap readable and settable by API.",
   "why": "The person behind an agent wants a ceiling on what it spends.",
   "fix": "Make balance and usage readable by API, and let callers set a spend cap.",
   "graded": "Graded from your API spec, your MCP tools and the calls our agent made. Readable: a route or tool for usage, balance, spend or billing. A cap: a route or tool that sets a spend, usage or billing limit, or a budget. Billing alerts don't count as a cap. Pass with both, partly with one or with a cap described only in the docs, fail with neither. Products with only free plans aren't graded.",
   "market": {
    "n": 77,
    "pass": null,
    "partly": 18,
    "fail": 56
   },
   "class": "advanced",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-05"
  },
  {
   "id": "PAY-06",
   "section": "pay",
   "title": "No person in the buy path",
   "requirement": "No sales call, quote, captcha or phone check before paying.",
   "why": "A sales call, a quote or a captcha before paying stops every agent.",
   "fix": "Let a buyer pay without a call, a quote, a captcha or a phone check.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#pay-06"
  },
  {
   "id": "LEAVE-01",
   "section": "leave",
   "title": "Cancel by API",
   "requirement": "Cancel by API or CLI. The answer states when access ends and what is still owed.",
   "why": "An agent that started a plan must be able to stop it too.",
   "fix": "Offer cancel by API or CLI, and say in the answer when access ends and what is still owed.",
   "class": "core",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#leave-01"
  },
  {
   "id": "LEAVE-02",
   "section": "leave",
   "title": "Delete by API, checked",
   "requirement": "The account and its data can be deleted by API, and a later login or key call fails.",
   "why": "A deleted account has to stay deleted, with its data and its keys.",
   "fix": "Delete the account and its data by API, and make old logins and keys fail.",
   "class": "recommended",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#leave-02"
  },
  {
   "id": "LEAVE-03",
   "section": "leave",
   "title": "Export before leaving",
   "requirement": "All of the account's data can be exported by API in a documented format (JSON or CSV with ids and relations).",
   "why": "A person moving on needs their data, and an agent can do the export for them.",
   "fix": "Export all of an account's data by API as JSON or CSV, with ids and relations.",
   "graded": "From the docs and the API spec, never by trying: pass when they document a data export and a way to delete the account or cancel the plan by API or a self-serve page; partly when one is there, or the way out goes through support; fail when neither is.",
   "market": {
    "n": 67,
    "pass": 15,
    "partly": 24,
    "fail": 28
   },
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#leave-03"
  },
  {
   "id": "LEAVE-04",
   "section": "leave",
   "title": "Grants and keys end on request",
   "requirement": "Keys and OAuth grants can be revoked by API and stop working at once.",
   "why": "Revoking a key or a grant only helps when it takes effect at once.",
   "fix": "Revoke keys and OAuth grants by API, and stop them working at once.",
   "class": "recommended",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#leave-04"
  },
  {
   "id": "PROTO-01",
   "section": "protocols",
   "title": "A2A agent card that works",
   "requirement": "A valid A2A 1.0 card whose advertised interfaces answer, with skills, examples and auth stated.",
   "why": "Other agents find and call yours through its card.",
   "fix": "Publish a valid A2A 1.0 agent card whose interfaces answer, with skills, examples and auth.",
   "graded": "The card at /.well-known/agent-card.json (or the older /.well-known/agent.json) must parse and state a name, skills with ids, its interfaces and its auth. Whether the interfaces answer isn't checked yet.",
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#proto-01"
  },
  {
   "id": "PROTO-02",
   "section": "protocols",
   "title": "WebMCP tools on the web app",
   "requirement": "Pages register user-level tools (document.modelContext) with schemas and honest hints.",
   "why": "An agent in a browser can call your web app's tools instead of clicking through it.",
   "fix": "Register your web app's actions as WebMCP tools with schemas and honest hints.",
   "class": "advanced",
   "status": "not_measured",
   "status_label": "Not measured yet",
   "url": "https://agentdrives.com/standard#proto-02"
  },
  {
   "id": "PROTO-03",
   "section": "protocols",
   "title": "Web Bot Auth as a receiver",
   "requirement": "Signed requests are verified and allowed, and the policy for signed agents is stated.",
   "why": "A signed agent proves who it is. Your site can let it in on that.",
   "fix": "Verify Web Bot Auth signatures, let signed agents through and state your policy for them.",
   "class": "advanced",
   "status": "measured",
   "status_label": "Measured in every drive",
   "url": "https://agentdrives.com/standard#proto-03"
  },
  {
   "id": "PROTO-04",
   "section": "protocols",
   "title": "Agent Skills published",
   "requirement": "An Agent Skills index (/.well-known/agent-skills/index.json) with digests, and skills that match the product.",
   "why": "A skill teaches an agent how to use your product well.",
   "fix": "Publish an Agent Skills index at /.well-known/agent-skills/index.json with digests.",
   "graded": "The index at /.well-known/agent-skills/index.json must parse and list skills, each with a name, a url and a sha256 digest. Whether the skills match the product isn't checked yet.",
   "class": "advanced",
   "status": "partly",
   "status_label": "Partly measured",
   "url": "https://agentdrives.com/standard#proto-04"
  }
 ]
}