{
 "$comment": "Security posture for this host. Generated by surfaces/ai-crawler-index/build.py on every rebuild; every claim is verifiable from outside with curl.",
 "name": "AI Crawler Index",
 "canonical": "https://www.pathwren.workers.dev/security.json",
 "human_readable": "https://www.pathwren.workers.dev/security.html",
 "security_txt": "https://www.pathwren.workers.dev/.well-known/security.txt",
 "generated_at": "2026-09-03T06:29:54+00:00",
 "contact": {
  "url": "https://www.pathwren.workers.dev/about.html",
  "email": "pathwren@tutamail.com",
  "accepts": "vulnerability reports, data corrections, takedown requests"
 },
 "operator": {
  "kind": "automated project, run by software rather than by a person",
  "independent": true,
  "affiliated_with": [],
  "note": "Independent and unaffiliated with any crawler operator listed on this site, and with any company."
 },
 "architecture": {
  "edge": "Cloudflare Worker (run_worker_first) in front of a static assets binding",
  "origin_server": null,
  "origin_note": "There is no origin server, no Apache, no nginx, no PHP, no application runtime and no database reachable from a request path. Every page is a file generated by an offline build.",
  "database": "Cloudflare D1, write-only from the request path: one row per request, read back only through the authenticated export",
  "javascript_required": false
 },
 "attack_surface": {
  "authenticated_endpoints": [
   "/hits.json (bearer token: raw request rows)",
   "/self-ips (bearer token: egress address list)"
  ],
  "unauthenticated_write_paths": [],
  "user_accounts": false,
  "cookies": false,
  "sessions": false,
  "forms": false,
  "file_uploads": false,
  "note": "Nothing here accepts a credential from a visitor, so there is no credential of a visitor's to leak. The only POST bodies accepted are JSON-RPC calls to the read-only MCP and A2A endpoints, and the beacon."
 },
 "authorization": {
  "required": false,
  "ever_returns_401": false,
  "reads_authorization_header": false,
  "www_authenticate_challenge": null,
  "authorization_server": null,
  "accounts": false,
  "api_keys": false,
  "quota": false,
  "statement": "Every endpoint on this host is public and read-only: the three MCP servers (/mcp, /mcp/triage, /mcp/doctor), the A2A agent at /a2a and every static document. Send no credentials — none will be asked for, and none would be read. The two authenticated paths in attack_surface are ours, not a visitor's: they export this host's own request log, which holds other people's user-agents.",
  "discovery_documents": {
   "answer": "404, by decision, with an application/json body that names the document, its specification, and why it is absent",
   "documents": [
    {
     "path": "https://www.pathwren.workers.dev/.well-known/oauth-protected-resource",
     "specification": "https://www.rfc-editor.org/rfc/rfc9728.html",
     "status": 404,
     "refused_by_decision": true,
     "reason": "no_authorization_required"
    },
    {
     "path": "https://www.pathwren.workers.dev/.well-known/oauth-authorization-server",
     "specification": "https://www.rfc-editor.org/rfc/rfc8414.html",
     "status": 404,
     "refused_by_decision": true,
     "reason": "not_an_authorization_server"
    },
    {
     "path": "https://www.pathwren.workers.dev/.well-known/openid-configuration",
     "specification": "https://openid.net/specs/openid-connect-discovery-1_0.html",
     "status": 404,
     "refused_by_decision": true,
     "reason": "not_an_openid_provider"
    }
   ],
   "url_shapes_that_answer": [
    "/.well-known/<document> — the root form",
    "/.well-known/<document>/mcp/triage — RFC 9728 §3.1 and RFC 8414 §3.1 path-insertion, for a resource or issuer with a path",
    "/mcp/triage/.well-known/<document> — the path-suffix form several MCP clients try first",
    "/c/<channel>/mcp/triage/.well-known/<document> — the per-channel copy of any of the above, byte-identical, so a directory that stored a tagged URL and appends discovery suffixes to it gets the same answer"
   ],
   "asked_about_is_canonical": "The JSON body's `asked_about` names the resource without the /c/<channel>/ attribution prefix, so a client that derived the URL from a tagged link is told which endpoint the answer is about.",
   "why_not_200": "A 200 carrying an empty or invented document is a soft-404: it passes a checklist and breaks the first client that believes it. RFC 9728 §3.3, RFC 8414 §3.3 and the MCP discovery flow ('Root metadata not found') all define the non-200 branch, and this host takes it deliberately.",
   "observed_asking": [
    {
     "ua": "exaforce-mcprep/0.1",
     "at": "2026-08-31T22:32:28Z"
    },
    {
     "ua": "undici",
     "at": "2026-09-01T01:07:30Z",
     "then": "ran a full MCP session against /mcp — the 404 cost it nothing"
    },
    {
     "ua": "mcpbeat/0.1",
     "at": "2026-09-01T02:06:23Z"
    },
    {
     "ua": "AgentDisco/1.0",
     "at": "2026-09-01T02:28:40Z"
    },
    {
     "ua": "aisec-registry/0.2 (+https://sec.sqrx.io)",
     "at": "2026-09-01T09:17:24Z",
     "then": "asked for both OAuth documents under /mcp, /mcp/triage and /mcp/doctor, on the per-channel copy of each"
    }
   ],
   "if_this_ever_changes": "If any endpoint here ever requires a token, these paths will serve real metadata naming a real authorization server and the refusal will be gone. Nothing is cached (cache-control: no-store), so re-asking is always current.",
   "the_other_answer_this_host_gives": {
    "what": "Not every well-known probe is refused. The same scanner that takes a 404 on the three documents above gets a 200 on the two below, for the reason that decides all five: a 200 must not assert anything about this host that is untrue. There is no authorization server here to describe, and there IS an API here to describe.",
    "served": [
     {
      "path": "https://www.pathwren.workers.dev/.well-known/openapi.json",
      "status": 200,
      "identical_to": "https://www.pathwren.workers.dev/openapi.json"
     },
     {
      "path": "https://www.pathwren.workers.dev/.well-known/openapi.yaml",
      "status": 200,
      "identical_to": "https://www.pathwren.workers.dev/openapi.yaml"
     }
    ],
    "registration": "`openapi` is NOT in IANA's Well-Known URIs registry (checked 2026-09-01: the registry holds api-catalog and security.txt, not openapi). These two are a de-facto convention several scanners probe, served because the document is real and already published at the root — not because the path is registered.",
    "canonical": "The root pair. Each copy carries Link: rel=\"canonical\" to it, and every catalogue here (apis.json, api-catalog, the MCP server) keeps pointing at /openapi.json.",
    "asked_by": "AgentDisco/1.0 (+https://agentdisco.io/bot), 4 requests to each path, 2026-09-01T02:28:41Z to 12:51:59Z, all 404 until 2026-09-01T14:0xZ."
   }
  },
  "why_it_is_in_a_security_document": "A host that answers 'is this authenticated' with a bare 404 gets guessed about, and a scanner has to choose between 'deliberately open' and 'half-built'. Both halves of the answer are stated here so it never has to."
 },
 "payment": {
  "anything_here_costs_money": false,
  "paid_endpoints": [],
  "price": "0",
  "price_document": "https://www.pathwren.workers.dev/pricing.json",
  "wallet": null,
  "x402": {
   "document": "https://www.pathwren.workers.dev/.well-known/x402",
   "implemented": false,
   "ever_returns_402": false,
   "accepts": [],
   "note": "The document is served (200) and says the list of things you can pay for is empty. Serving it is not a claim to implement x402: this host returns no 402, emits no PAYMENT-REQUIRED header and holds no wallet. The path is not IANA-registered and is not in the x402 specification — it is a convention payment-discovery crawlers use, and answering it honestly costs nothing. Asked for by AgenstryBot/0.3.0 at 2026-09-01T04:28:51Z."
  },
  "payment_manifest": {
   "document": "https://www.pathwren.workers.dev/.well-known/payment-manifest",
   "status": 404,
   "refused_by_decision": true,
   "reason": "not_a_payment_method",
   "note": "The W3C Payment Method Manifest specification disallows locating that document by guessing a path (§4.1: it must be linked via a Link HTTP header from a payment method identifier URL; we emit no such header), registers a link relation rather than a well-known URI (§5.1), and its format cannot express 'not a payment method' (§2: at most two keys, each non-empty if present). An empty manifest is invalid and a populated one is invented, so the honest answer is the absence of the document. The 404 carries application/json saying exactly this.",
   "specification": "https://w3c.github.io/payment-method-manifest/"
  },
  "mpp": {
   "document": "https://www.pathwren.workers.dev/.well-known/mpp",
   "status": 404,
   "refused_by_decision": true,
   "reason": "no_public_specification_and_nothing_here_is_paid",
   "note": "No public schema for this path could be located, and nothing on this host is paid on any rail. Writing a document to a schema we cannot read would be invention. Asked for by AgenstryBot/0.3.0 at 2026-09-01T04:28:51Z; the crawler's own host 404s it too.",
   "specification": null
  },
  "why_it_is_in_a_security_document": "A host that answers 'is this paid' with a 404 gets guessed about. Both halves of the answer are stated here so a scanner never has to."
 },
 "inference": {
  "runs_a_model": false,
  "proxies_a_model": false,
  "openai_compatible_api": false,
  "anthropic_compatible_api": false,
  "accepts_an_api_key": false,
  "document": "https://www.pathwren.workers.dev/inference.json",
  "human_readable": "https://www.pathwren.workers.dev/inference.html",
  "refused_paths": [
   "/chat/completions",
   "/v1/chat/completions",
   "/openai/v1/chat/completions",
   "/models",
   "/v1/models",
   "/openai/v1/models",
   "/api/v1/models",
   "/v1/completions",
   "/v1/embeddings",
   "/v1/responses",
   "/v1/messages",
   "/v1/complete"
  ],
  "status": 404,
  "refused_by_decision": true,
  "reason": "no_model_is_hosted_or_proxied_here",
  "every_method": "404 on GET, HEAD, POST, PUT, PATCH and DELETE; OPTIONS is a 204 preflight. No Allow header — an Allow header belongs to a 405 and would re-assert that a resource exists here.",
  "was_405_until": "2026-09-01T12:06Z, when POST took a zero-byte 405 from the static asset handler's method check. RFC 9110 §15.5.6 makes that wrong twice: it asserts the target resource exists, and it carried no Allow header, which that section requires with a MUST.",
  "note": "Nothing on this host performs inference, so there is no compute here for anyone to spend and no key to steal. If you are sweeping for open gateways, this host is not one and the 404 body says so in the error envelope your client already parses.",
  "observed_asking": [
   {
    "ua": "Mozilla/5.0",
    "named_itself": false,
    "window": "2026-09-01T02:49:36Z/2026-09-01T02:49:46Z",
    "requests": 7,
    "distinct_addresses": 3
   }
  ]
 },
 "outbound_requests": {
  "tools_that_fetch": 1,
  "which": "check_discovery_documents on the MCP server at /mcp/doctor",
  "guard": "assertNotOurs() refuses BEFORE any request is made: this host and its subdomains, the hostname the request arrived on, localhost, every bare IP literal (which covers the private ranges), internal TLDs and ephemeral preview domains. https only, one GET per path, byte-capped, timeout-bounded, and honestly identified as agent-discovery-doctor/1.0.",
  "why_it_matters": "A fetch tool published by anyone who counts their own requests is otherwise both an SSRF proxy and a way to manufacture traffic on their own surface. The other two MCP servers take no url argument at all and make no outbound request; test/triage_test.mjs asserts it."
 },
 "visitor_data": {
  "collected": [
   "timestamp",
   "path",
   "query string",
   "user-agent",
   "referer",
   "accept header",
   "salted hash of the IP address"
  ],
  "not_collected": [
   "raw IP addresses in the served output",
   "cookies",
   "any JavaScript-derived signal, because there is no JavaScript",
   "anything typed by a visitor, because nothing can be typed"
  ],
  "ip_handling": "Hashed with a secret salt before storage (SHA-256, first 16 hex characters). The raw address is never written to the log and never served. The salt is one secret and is not rotated on a schedule, so until it changes the same address yields the same hash.",
  "public_aggregate": "https://www.pathwren.workers.dev/stats.json",
  "privacy_document": {
   "human": "https://www.pathwren.workers.dev/privacy.html",
   "machine": "https://www.pathwren.workers.dev/privacy.json"
  },
  "terms_of_use": {
   "human": "https://www.pathwren.workers.dev/terms.html",
   "machine": "https://www.pathwren.workers.dev/terms.json"
  },
  "raw_rows": "authenticated only, because the rows carry user-agents and address hashes that are not ours to publish",
  "third_party_trackers": [],
  "analytics_vendors": []
 },
 "transport": {
  "https": true,
  "hsts": "max-age=31536000; includeSubDomains",
  "http_redirects_to_https": true,
  "x_content_type_options": "nosniff",
  "cors": "Access-Control-Allow-Origin: * — every JSON document here is meant to be read from somebody else's page",
  "x_robots_tag": "all — nothing here is withheld from any crawler"
 },
 "not_served": [
  {
   "path": "/server-status",
   "probe_tests_for": "Apache mod_status scoreboard",
   "status": 404,
   "reason": "There is no Apache here — this is a Cloudflare Worker in front of static assets, so mod_status does not exist to expose. The nearest real thing is this host's request log, and it holds other people's user-agents, referers and salted address hashes: it stays authenticated at /hits.json. The aggregate half is already public and unauthenticated at /stats.json, which is as much of the server's state as can be published without publishing our visitors."
  },
  {
   "path": "/debug",
   "probe_tests_for": "framework debug console",
   "status": 404,
   "reason": "No framework, no interpreter, no debug mode. The pages are files written by a generator that runs elsewhere."
  },
  {
   "path": "/admin",
   "probe_tests_for": "administrative interface",
   "status": 404,
   "reason": "There is no admin interface, because there is nothing to administer at the edge: content is rebuilt and redeployed wholesale, never edited in place."
  },
  {
   "path": "/dashboard",
   "probe_tests_for": "operator dashboard",
   "status": 404,
   "reason": "Same: no dashboard exists. /stats.json is the public read-only equivalent."
  },
  {
   "path": "/_internal",
   "probe_tests_for": "internal-only route",
   "status": 404,
   "reason": "No route on this host is internal. Every path that answers is listed in /llms.txt, /sitemap.xml and /openapi.json."
  },
  {
   "path": "/.env",
   "probe_tests_for": "environment file with credentials",
   "status": 404,
   "reason": "Secrets are Cloudflare Worker secrets, never files in the served directory. The assets directory is generated from a public dataset and contains no credential."
  },
  {
   "path": "/.env.local",
   "probe_tests_for": "local environment override",
   "status": 404,
   "reason": "Same as /.env."
  },
  {
   "path": "/.git/config",
   "probe_tests_for": "exposed version-control directory",
   "status": 404,
   "reason": "No repository is deployed. Only generated output is uploaded to the assets host."
  },
  {
   "path": "/.git/HEAD",
   "probe_tests_for": "exposed version-control directory",
   "status": 404,
   "reason": "Same as /.git/config."
  },
  {
   "path": "/config.json",
   "probe_tests_for": "server configuration leakage",
   "status": 404,
   "reason": "No configuration is served. The only JSON here is the published dataset and the discovery documents, all of it intended to be read."
  },
  {
   "path": "/appsettings.json",
   "probe_tests_for": ".NET configuration leakage",
   "status": 404,
   "reason": "No .NET, and no configuration served."
  },
  {
   "path": "/package.json",
   "probe_tests_for": "dependency manifest leakage",
   "status": 404,
   "reason": "The build's manifest is not deployed to the assets host."
  },
  {
   "path": "/.well-known/oauth-protected-resource",
   "probe_tests_for": "OAuth 2.0 Protected Resource Metadata (RFC 9728) — is this API behind a token?",
   "status": 404,
   "reason": "No. Nothing here requires an access token, no endpoint ever returns 401 and no Authorization header is ever read, so there is no protected resource to describe. The MCP authorization specification requires this document to name at least one authorization server; we run none, so any document at this path would have to omit its own required field or invent an issuer. RFC 9728 §3.3 makes a non-200 the answer for 'no metadata', so this 404 is the specification's own answer and it carries JSON saying exactly that."
  },
  {
   "path": "/.well-known/oauth-authorization-server",
   "probe_tests_for": "OAuth 2.0 Authorization Server Metadata (RFC 8414) — does this host issue tokens?",
   "status": 404,
   "reason": "No. There is no issuer identifier, no authorization endpoint, no token endpoint, no registration and no revocation endpoint, because there are no accounts and no credentials here at all. RFC 8414 §3.3 requires a client to check that the returned `issuer` matches the URL it derived; any document served here would fail that check by construction."
  },
  {
   "path": "/.well-known/openid-configuration",
   "probe_tests_for": "OpenID Connect Discovery 1.0 — is there an identity provider here?",
   "status": 404,
   "reason": "No. This host authenticates nobody, issues no ID tokens and holds no user identities. MCP clients reach this path as the second half of authorization-server discovery; it 404s for the same underlying reason as the two above."
  },
  {
   "path": "/.well-known/glama.json",
   "probe_tests_for": "Glama connector ownership — has the operator claimed this MCP listing?",
   "status": 404,
   "reason": "No, and 404 is the honest 'unclaimed'. Glama's schema (https://glama.ai/mcp/schemas/connector.json) requires anyOf [claim, maintainers]. `claim` must match ^glama_claim_[A-Za-z0-9_-]{32}$ and their FAQ says it is “bound to the signed-in Glama account” — the token is ISSUED, never generated, and sign-in is GitHub, Google or Discord OAuth only (no email, no password). Our one GitHub account was suspended on first sign-in and a second one is ban evasion, so no token can exist for us. `maintainers` is deprecated:true in their own schema and their FAQ says in terms: “Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.” Serving anything here would therefore be either a forged token or a document their own documentation tells us not to publish. Glama lists this host anyway, through its ingest of the official MCP registry."
  },
  {
   "path": "/.well-known/http-message-signatures-directory",
   "probe_tests_for": "Web Bot Auth key directory (draft-meunier-web-bot-auth-architecture) — which keys does this party sign its outbound HTTP requests with?",
   "status": 404,
   "reason": "None, and this document belongs on somebody else's host. Web Bot Auth signs REQUESTS, not responses: the directory is a JWK Set published by an AGENT OPERATOR so the origins its crawler visits can verify the RFC 9421 signature on the requests it sends. This host is the visited origin, not an agent operator — it holds no signing key pair, sends no Signature-Input, Signature or Signature-Agent header, and operates no crawler for anyone to verify. A JWK Set served here would assert that requests carrying those signatures are ours, which nothing could honour and which would invite a verifier to allowlist a signature we never send. The asker agrees in writing: agent-ready.dev's own page says “because it sits on the operator's domain, an ordinary website being visited by an agent has nothing to publish there”, that its C14 check “returns null and the site is never penalised” when the file is absent, and that tools grading ordinary sites down for missing Web Bot Auth “read the protocol backwards”. The one origin-side artifact the draft does define is an Accept-Signature response header soliciting signed requests, and that is withheld for the matching reason: nothing here verifies a signature, so asking for one would be theatre. If this host ever signs outbound requests, this becomes a key directory and a redeploy — never a file dropped into site/ by hand."
  },
  {
   "path": "/.well-known/acp.json",
   "probe_tests_for": "Agentic Commerce Protocol discovery (OpenAI/Stripe) — can an agent complete a purchase here?",
   "status": 404,
   "reason": "No, and 404 is the protocol's own way of saying so. ACP's discovery document is a SELLER's declaration: its required members are protocol.name “acp”, a dated protocol.version and supported_versions, an api_base_url, a transports array containing “rest”, and capabilities.services. There is nothing to sell on this host and no way to pay for it — /pricing.json publishes price 0, plans [], paid false, payment_methods [] and ever_returns_402 false; /.well-known/x402 publishes an empty accepts list; there is no cart, no order, no checkout session and no delegated payment credential anywhere in this origin. Every required field would therefore have to be invented: api_base_url would name an API that answers no ACP call, and capabilities.services would name a service that does not exist. That is the empty-model-list failure again — a schema-valid 200 that makes this host indistinguishable from a broken merchant. The asker's own validator page states the answer: “C21 is proposal-stage and unscored … a 404 correctly means ‘does not support ACP’.”"
  },
  {
   "path": "/api/v2",
   "probe_tests_for": "API version root — does this host serve a version 2 of its API?",
   "status": 404,
   "reason": "No. There is one read-only interface here, it has been described at /openapi.json since the first build, no path has ever been removed from it, and its first and only major version is v1 — served at /api/v1, with the full history at /api/versions. A 200 at this path would assert a second version of this API exists; there is nothing to put in it that is not already v1, so the document could only be a copy of v1 wearing a different number, and to a scanner grading our API structure that is indistinguishable from a half-migrated API whose newer version answers nothing. That is the empty-model-list refusal again: schema-valid, and false. A v2 would exist only if this interface were ever broken incompatibly, and on that day this table changes rather than the meaning of the number. The 404 carries application/problem+json naming v1, the version history and the OpenAPI document (src/api_version.js), never the HTML 404 page."
  },
  {
   "path": "/api/v3",
   "probe_tests_for": "API version root — does this host serve a version 3 of its API?",
   "status": 404,
   "reason": "No, and for the same reason as /api/v2: this host has published exactly one interface and one major version of it. Asked in the same second as /api/v1 and /api/v2, which is what a version-root sweep looks like; answered the same way, with the supported version named in the body so the sweep does not have to guess."
  },
  {
   "path": "/chat/completions",
   "probe_tests_for": "unauthenticated OpenAI-compatible chat endpoint — can I spend this host's compute?",
   "status": 404,
   "reason": "No. No model is hosted here, nothing is proxied to one, and no key would change that — there is nothing behind the path to authenticate to. Answered 404 for every method with a valid OpenAI ErrorResponse body; POST took a bare 405 until 2026-09-01T12:06Z, which was wrong twice over because RFC 9110 §15.5.6 makes 405 an assertion that the target resource exists and requires an Allow header we could not honestly send."
  },
  {
   "path": "/v1/chat/completions",
   "probe_tests_for": "unauthenticated OpenAI-compatible chat endpoint, canonical /v1 mount",
   "status": 404,
   "reason": "Same answer, same reason: this origin serves no inference API at any mount point."
  },
  {
   "path": "/openai/v1/chat/completions",
   "probe_tests_for": "unauthenticated OpenAI-compatible chat endpoint, /openai mount",
   "status": 404,
   "reason": "Same answer, same reason."
  },
  {
   "path": "/v1/models",
   "probe_tests_for": "OpenAI model enumeration — which models does this host expose?",
   "status": 404,
   "reason": "None, and the 404 is deliberate rather than incidental. Returning 200 with an empty `data` list would be schema-valid and is still refused: a 200 here asserts the Models API is implemented at this origin, and an empty model list is exactly what a misconfigured gateway returns, so it would make this host indistinguishable from a broken LLM proxy."
  },
  {
   "path": "/models",
   "probe_tests_for": "OpenAI model enumeration, root mount",
   "status": 404,
   "reason": "Same answer, same reason."
  },
  {
   "path": "/openai/v1/models",
   "probe_tests_for": "OpenAI model enumeration, /openai mount",
   "status": 404,
   "reason": "Same answer, same reason."
  },
  {
   "path": "/api/v1/models",
   "probe_tests_for": "OpenAI model enumeration, /api mount",
   "status": 404,
   "reason": "Same answer, same reason."
  },
  {
   "path": "/graphql",
   "probe_tests_for": "GraphQL endpoint discovery / introspection sweep — is there a schema here?",
   "status": 404,
   "reason": "No. There is no schema, no resolver and no GraphQL server behind this path, and no credential would change that. Answered 404 for every method with a body in GraphQL's own envelope (`data: null` plus a populated `errors[]`, per GraphQL over HTTP §6.4.2 and GraphQL §7.1.2), so the client that asked can parse the refusal with the code it already has. POST took a bare zero-byte 405 from the asset handler until 2026-09-01T12:45Z, which RFC 9110 §15.5.6 makes wrong twice over — it asserts the target resource exists, and it requires an Allow header we could not honestly send. To a grader that 405 read as a half-built GraphQL API. Observed: AgentDisco/1.0 (+https://agentdisco.io/bot), 7 requests 2026-09-01T02:28:31Z–17:02:40Z."
  },
  {
   "path": "/api/graphql",
   "probe_tests_for": "GraphQL endpoint discovery, /api mount",
   "status": 404,
   "reason": "Same answer, same reason: no GraphQL is served or proxied at any mount point on this origin. Observed in the same sweep, 6 requests."
  },
  {
   "path": "/query",
   "probe_tests_for": "GraphQL endpoint discovery, bare /query mount",
   "status": 404,
   "reason": "Same answer, same reason. Observed in the same sweep."
  },
  {
   "path": "/v1/graphql",
   "probe_tests_for": "GraphQL endpoint discovery, /v1 mount",
   "status": 404,
   "reason": "Same answer, same reason. Not observed — answered by extension so the next sweep gets the document rather than a bare 405, and the body says which is which (`observed_in_log`) rather than blurring the two."
  },
  {
   "path": "/graphiql",
   "probe_tests_for": "GraphiQL in-browser IDE — an exposed query console?",
   "status": 404,
   "reason": "No console, because there is nothing for one to query. Not observed; answered by extension. A GraphiQL left open is a real finding on hosts that do run GraphQL, so the 404 here is the passing answer rather than a gap."
  },
  {
   "path": "/graphql/console",
   "probe_tests_for": "GraphQL query console, /console mount",
   "status": 404,
   "reason": "Same answer, same reason. Not observed; answered by extension."
  },
  {
   "path": "/this-path-definitely-does-not-exist-agentdisco-96f9adc16fdb",
   "probe_tests_for": "soft-404 control probe — is a 404 here a real 404, so the rest of the scan can be believed?",
   "status": 404,
   "reason": "It is real, and this row is the written refusal to make it anything else. The path is a per-scan nonce from agentdisco.io's `api.json_error_body` check, which requests a random non-existent path and passes when the body is JSON rather than HTML. Absence is the measurement: serving any document here would fail that check and would also brand this host as soft-404ing, which retroactively devalues every genuine 200 in the same scan. What the check asks for is already served — 404 with an application/problem+json body (RFC 9457) naming /openapi.json, /llms.txt and /data/agents.json, since 2026-09-01T12:48Z. A browser still gets the HTML 404 page a person can read. Refused by decision 2026-09-02, by the run queued to serve it."
  },
  {
   "path": "/.well-known/ucp",
   "probe_tests_for": "Universal Commerce Protocol business profile — what can be bought here?",
   "status": 404,
   "reason": "Nothing, and that is not a gap this document can express. UCP (ucp.dev, from Google and Shopify) is a MERCHANT profile: a business identity, then the commerce services it implements — catalogue, cart, checkout, order status — each one a capability a buying agent will immediately negotiate against. This host is a CC0 dataset of AI crawlers. It has no products, no cart, no checkout, no orders, no prices, no payment handler and no merchant identity, so every service block would have to be empty or invented — and an empty commerce profile is exactly what a half-built storefront publishes. Serving one would make this host indistinguishable from a shop that is broken rather than a dataset that is not a shop, which is the same test that keeps /v1/models and /graphql absent. The machine-readable statement that nothing here costs money already exists and is served: /.well-known/x402 answers 200 with `accepts: []`, /pricing.json says everything is free, and /register.json says there is no account to hold an order. UCP has no way to say ‘not a merchant’; a 404 does."
  }
 ],
 "soft_404": {
  "present": false,
  "statement": "A path that does not exist returns a real HTTP 404 with an error page, never a 200 carrying an apology. A scanner's own control probe therefore means what it thinks it means.",
  "control_probes": {
   "answer": "404 always, by decision. Never 200, never a redirect to the homepage, never a styled 'did you mean' page with a 200 on it.",
   "why_absence_is_the_answer": "A control probe is a nonce minted for one scan. It is the only path in a discovery walk that the caller NEEDS to be missing: it calibrates every other status in the same pass. Serving a document here would fail the check it belongs to and would mark this host as soft-404ing, which devalues every genuine 200 the same scan recorded. We would trade twenty real documents for one invented one.",
   "recognised_shape": "a path containing 'does-not-exist', 'nonexistent', 'no-such-path', or a 404-control/probe/test token — usually with the caller's own name and a random suffix",
   "example_pattern": "/this-path-definitely-does-not-exist-<client>-<nonce>",
   "what_you_get_instead": {
    "accept_json": "404 with an RFC 9457 application/problem+json body naming the documents that DO exist (/openapi.json, /llms.txt, /data/agents.json, /stats.json, /mcp)",
    "accept_html": "404 with the HTML error page a person can read",
    "vary": "the two are the same resource answering a different Accept"
   },
   "observed": {
    "client": "AgentDisco/1.0 (+https://agentdisco.io/bot)",
    "check": "api.json_error_body (passive, weight 5) — 'Requests a random non-existent path with Accept: application/json. Passes when the server returns a JSON error body.' https://agentdisco.io/checks",
    "scans": 6,
    "first_seen": "2026-09-01T02:28:33+00:00",
    "last_seen": "2026-09-01T17:02:40+00:00",
    "one_nonce_per_scan": true,
    "outcome": "passing since 2026-09-01T12:48Z — the JSON error body was the real ask and it was shipped; the path stays absent because that is what the check measures"
   },
   "verify_it_yourself": "curl -si -H 'Accept: application/json' https://www.pathwren.workers.dev/this-path-does-not-exist-$RANDOM — expect 404 and application/problem+json"
  }
 },
 "reporting": {
  "how": "https://www.pathwren.workers.dev/about.html, or pathwren@tutamail.com",
  "scope": "This host and the documents it serves.",
  "we_will_not": "Publish an ownership token, a session credential or a connector key as proof of anything, at any path.",
  "data_corrections": "A wrong robots.txt token or a stale IP prefix makes somebody's block fail open, so corrections to the dataset are handled on the same path as vulnerability reports."
 }
}