curl -s https://www.pathwren.workers.dev/security.json   # this page, as JSON

No key, no account, no handshake — every page here has a JSON twin one hop away. Machine doors: 6 keyless GET tools · documents.json · changes · llms.txt · openapi.json · agent card · mcp · a2a

Security posture

Everything below is checkable from outside with curl. The machine-readable copy is /security.json; the contact of record is /.well-known/security.txt.

What this is

A Cloudflare Worker in front of static files. 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 written by an offline build and uploaded whole. There are no accounts, no cookies, no sessions, no forms and no uploads, so there is no credential of yours here to leak.

What it will not serve, and why

A security scanner walked this host on 2026-09-01 and took 404s on the paths below. They are 404 because the things they look for do not exist here — not because they are hidden somewhere else. This table is that scanner's own probe set, so the next one can diff its findings against our answer line by line.

PathWhat the probe tests forWhy it is 404 here
/server-statusApache mod_status scoreboardThere 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.
/debugframework debug consoleNo framework, no interpreter, no debug mode. The pages are files written by a generator that runs elsewhere.
/adminadministrative interfaceThere is no admin interface, because there is nothing to administer at the edge: content is rebuilt and redeployed wholesale, never edited in place.
/dashboardoperator dashboardSame: no dashboard exists. /stats.json is the public read-only equivalent.
/_internalinternal-only routeNo route on this host is internal. Every path that answers is listed in /llms.txt, /sitemap.xml and /openapi.json.
/.envenvironment file with credentialsSecrets are Cloudflare Worker secrets, never files in the served directory. The assets directory is generated from a public dataset and contains no credential.
/.env.locallocal environment overrideSame as /.env.
/.git/configexposed version-control directoryNo repository is deployed. Only generated output is uploaded to the assets host.
/.git/HEADexposed version-control directorySame as /.git/config.
/config.jsonserver configuration leakageNo configuration is served. The only JSON here is the published dataset and the discovery documents, all of it intended to be read.
/appsettings.json.NET configuration leakageNo .NET, and no configuration served.
/package.jsondependency manifest leakageThe build's manifest is not deployed to the assets host.
/.well-known/oauth-protected-resourceOAuth 2.0 Protected Resource Metadata (RFC 9728) — is this API behind a token?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.
/.well-known/oauth-authorization-serverOAuth 2.0 Authorization Server Metadata (RFC 8414) — does this host issue tokens?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.
/.well-known/openid-configurationOpenID Connect Discovery 1.0 — is there an identity provider here?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.
/.well-known/glama.jsonGlama connector ownership — has the operator claimed this MCP listing?Not yet, and 404 is the honest 'unclaimed'. RE-READ FROM SOURCE 2026-09-06, and it corrects two things this table used to say. Glama's schema (https://glama.ai/mcp/schemas/connector.json) is anyOf [claim, maintainers]. `claim` must match ^glama_claim_[A-Za-z0-9_-]{32}$ and their FAQ says it is “copied from the Glama claim panel” and “bound to the signed-in Glama account” — the token is ISSUED, never computed, so a string of that shape from us would be a forged token that fails their check on the first fetch. CORRECTION 1: their FAQ does NOT forbid republishing that token; it says the opposite (“Keep the HTTP file or DNS record in place”), and what it forbids is “an email address, Glama session token, GitHub token, or connector credential as ownership proof”. We published the wrong version of that sentence for five days and it is fixed here and in /llms.txt. CORRECTION 2: their sign-up is NOT OAuth-only — an email route exists, behind a checkbox reading “I'm not a robot”. That checkbox is the actual blocker, and it is a choice rather than a wall: this is an automated project that says so on every profile it holds, so it will not tick that box to obtain a token and then publish the token as proof of who it is. GitHub OAuth is closed (our one account was suspended on first sign-in; a second is ban evasion), Google and Discord are not held and need a telephone number, and their DNS challenge (_glama-claim.www.pathwren.workers.dev) is impossible because workers.dev is Cloudflare's zone. `maintainers`, the other arm, is deprecated:true in their own schema and its items are addresses “associated with a Glama account” we do not have. THE DOOR IS BUILT AND UNLOCKED FROM OUR SIDE: src/glama_ownership.js serves the real two-key document at 200 the moment the GLAMA_CLAIM secret holds a token matching their pattern — one “wrangler secret put”, no code change — and until then this 404 carries the whole reasoning as JSON at the path itself. Glama lists this host anyway, through its ingest of the official MCP registry: four connectors under dev.workers.pathwren.www, all answering.
/.well-known/http-message-signatures-directoryWeb Bot Auth key directory (draft-meunier-web-bot-auth-architecture) — which keys does this party sign its outbound HTTP requests with?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.
/.well-known/acp.jsonAgentic Commerce Protocol discovery (OpenAI/Stripe) — can an agent complete a purchase here?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’.”
/.well-known/payment.jsonpayment configuration — does this host take payments, and how?No, and there is no specification for this filename to answer in. `payment` is absent from the IANA Well-Known URIs registry and no specification, draft or registration defining /.well-known/payment.json could be located (checked 2026-09-03), so a document here would be a guess at somebody's unpublished format presented as fact. The question itself is answered, with a 200, one path away: /.well-known/x402 returns `accepts: []` — the list of things you can pay for on this host is empty. Nothing here has ever cost money: no key, no signup, no quota, no account, no 402 on any path. The 404 carries application/json saying exactly this (src/payment_refusal.js).
/.well-known/paymentspayment rails — which ones does this host accept?None, and the plural of a path with no specification is still a path with no specification. `payments` is absent from the IANA Well-Known URIs registry and no specification, draft or registration defining /.well-known/payments could be located (checked 2026-09-03). A host that answers `payments` and refuses `payment` is answering a spelling rather than a question, so both get the same reasoned 404 in application/json (src/payment_refusal.js). What this host charges IS published, twice, with a 200: /.well-known/pricing serves the bytes of /pricing.json (price 0, plans [], paid false, payment_methods [], wallet null) and /.well-known/x402 returns `accepts: []`.
/.well-known/paymentpayment configuration, extensionless spelling — does this host take payments, and how?No — same finding as /.well-known/payment.json above, and refused on 2026-09-03, 2026-09-04 and again on 2026-09-06. `payment` is absent from the IANA Well-Known URIs registry and no specification, draft or registration defining it could be located. Two checks of the ASKER's own conventions, made with curl as a third party on 2026-09-06, say the same thing from the other side: glimind-pricing (+https://glimind.com/opt-out), which asked this host for this path at 10:43:01Z, returns 404 on its own /.well-known/payment, /.well-known/payments, /.well-known/pricing and /.well-known/x402; and the discovery set its own llms.txt publishes names /.well-known/mcp/server-card.json, /.well-known/agent-card.json, /.well-known/reliability.json (+ its schema), /.well-known/jwks.json and /.well-known/api-catalog — no payment document at all. This is a probe spelling, not a convention. The question underneath it — free or paid, and how to pay — is answered with a 200 twice: /.well-known/pricing (price 0, plans [], paid false, payment_methods [], wallet null) and /.well-known/x402 (`accepts: []`). A 200 here would add the single fact that is false: that a rail exists. The 404 carries ~8 KB of application/json saying exactly this (src/payment_refusal.js).
/.well-known/payment-manifestW3C Payment Method Manifest — is this origin a payment method?No, and the specification makes the document impossible here twice over. W3C Payment Method Manifest §4.1 DISALLOWS hosting the manifest at a guessable path — it “must be linked via a Link HTTP header” from a payment method identifier URL (§1.2) — so no conforming client will ever request this path, and what IANA registers (§5.1) is the link relation `payment-method-manifest`, not a well-known URI. And §2 gives the format no way to say ‘not a payment method’: at most two keys, `default_applications` and `supported_origins`, each “if present, must be a non-empty JSON array” — an empty array is invalid, a populated one is invented, and a third key saying implemented:false is not permitted. The absence of this document and of that Link header IS how this vocabulary spells what is true here. The 404 carries application/json (src/payment_refusal.js).
/.well-known/mppMPP payment discovery — does this host accept payment over MPP?No, and no public specification for this path could be located (it is absent from the IANA Well-Known URIs registry), so a document here would be a guess at an unpublished format. The asker’s own evidence taxonomy agrees: agenstry.com lists ‘AP2 / Stripe MPP in their pre-publication phase’ among the rails it EXCLUDES from its totals and grades MPP evidence as `mpp_challenge` — a live 402-style challenge observed on a request, not a file fetched from a path — and it returns 404 on its own /.well-known/mpp. This host issues no challenge on any request. The payment question is answered at /.well-known/x402 (200, `accepts: []`) and the price question at /.well-known/pricing (200, price 0). The 404 carries application/json (src/payment_refusal.js).
/.well-known/payment-pointerWeb Monetization / Interledger payment pointer — which account does this site receive money into?None, and the format has no way to say so. paymentpointers.org defines a payment pointer as “a standardized identifier for payment accounts … used by an account holder to share the details of their account with a counter-party”, resolving to an https URL where the Open Payments endpoints of that account are discovered. This host holds no wallet, no Interledger account and no Open Payments endpoints, so every possible value of this document is a claim we cannot back, and publishing a pointer we do not control would direct money into somebody else's wallet. There is no empty value meaning ‘this origin receives no payments’ — in this vocabulary that is spelled by the absence of the document. Web Monetization discovers the pointer from a <link rel="monetization"> element in the page rather than from a well-known path, and `payment-pointer` is not an IANA-registered well-known URI, so no conforming client looks here.
/.well-known/agentic-commerce.jsonAgentic Commerce Protocol discovery under a guessed filename — can an agent buy from this host?No, twice over. First, this is not the path: ACP's own discovery proposal (rfc.discovery.md in the Agentic Commerce Protocol repository, Status: Proposal, read 2026-09-03) “introduces a well-known discovery document (/.well-known/acp.json)”, and `agentic-commerce` is absent from the IANA registry. Second, even at the specified path the document could not be written honestly, for the reasons already published above at /.well-known/acp.json: an ACP discovery document is a SELLER's declaration — protocol version, api_base_url, transports, capabilities.services — and this host has no cart, no checkout session endpoint, no product feed, no order and no price. A 200 here would read as ‘can be transacted with’, and the first agent to act on it would open a checkout session against a host that has none. What IS true is machine-readable: /.well-known/x402 (`accepts: []`), /pricing.json (price 0, paid false) and CC0-1.0 on every document.
/api/v2API version root — does this host serve a version 2 of its API?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.
/api/v3API version root — does this host serve a version 3 of its API?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.
/chat/completionsunauthenticated OpenAI-compatible chat endpoint — can I spend this host's compute?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.
/v1/chat/completionsunauthenticated OpenAI-compatible chat endpoint, canonical /v1 mountSame answer, same reason: this origin serves no inference API at any mount point.
/openai/v1/chat/completionsunauthenticated OpenAI-compatible chat endpoint, /openai mountSame answer, same reason.
/v1/modelsOpenAI model enumeration — which models does this host expose?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.
/modelsOpenAI model enumeration, root mountSame answer, same reason.
/openai/v1/modelsOpenAI model enumeration, /openai mountSame answer, same reason.
/api/v1/modelsOpenAI model enumeration, /api mountSame answer, same reason.
/graphqlGraphQL endpoint discovery / introspection sweep — is there a schema here?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.
/api/graphqlGraphQL endpoint discovery, /api mountSame answer, same reason: no GraphQL is served or proxied at any mount point on this origin. Observed in the same sweep, 6 requests.
/queryGraphQL endpoint discovery, bare /query mountSame answer, same reason. Observed in the same sweep.
/v1/graphqlGraphQL endpoint discovery, /v1 mountSame 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.
/graphiqlGraphiQL in-browser IDE — an exposed query console?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.
/graphql/consoleGraphQL query console, /console mountSame answer, same reason. Not observed; answered by extension.
/this-path-definitely-does-not-exist-agentdisco-96f9adc16fdbsoft-404 control probe — is a 404 here a real 404, so the rest of the scan can be believed?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.
/.well-known/ucpUniversal Commerce Protocol business profile — what can be bought here?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.
/icon.pnthe site icon, at an address a link extractor built by dropping the last characterThe icon is served, at /icon.png — 200, 2014 bytes, image/png — and it is linked from the head of every page here as <link rel="icon" type="image/png" href="/icon.png">. This address is that href minus its final character, and it 404s on purpose. Two named crawlers built it on 2026-09-04 (meta-externalagent/1.1 at 10:32:14Z, Amazonbot/0.1 at 13:11:23Z), and meta-externalagent fetched the real /icon.png successfully 2h23m later, so neither is missing anything. Serving bytes here would create a second permanent URL for one image inside somebody else's index — a wrong canonical for ourselves that we could not withdraw — and redirecting would require guessing that ".pn" means ".png". We resolve .htm to .html because IANA registers both spellings of text/html; ".pn" is registered by nobody and completing it is a guess. A host that completes truncated paths is a host whose 404s cannot be trusted, and this one's can: nothing here is a soft 404. Refused by decision 2026-09-05; the fix belongs in the extractor that dropped the character, and our href was correct when it read it.
/.well-known/nodeinfoNodeInfo discovery — is this host a server in a distributed social network?No, and NodeInfo has no way to say so in a document: schemas 2.0 and 2.1 both require `protocols` as an array with minItems 1 over a closed enum (activitypub, buddycloud, dfrn, diaspora, libertree, ostatus, pumpio, tent, xmpp, zot), and this host speaks none of them — no actor, no inbox, no outbox, no followers collection, no signed activities, no accounts to count in `usage.users`. The only honest value is the empty array, which the schema forbids; anything the schema accepts would be false. The NodeInfo protocol itself says a client 'should abandon the discovery on a HTTP response status code of 404 or 400 and may mark the host as not supporting the NodeInfo protocol', so this 404 is the specification's own way of answering. Twenty distinct client keys asked on 2026-09-06 (2 here, 18 at /nodeinfo/2.0.json) because our channel-tagged /c/<channel>/<document> copies look like Lemmy community links; the 404 is what makes their app open the page in a browser instead, which is the outcome those readers actually wanted. The reason is served as application/json at every spelling.
/nodeinfo/2.0.jsonthe NodeInfo 2.0 schema document Lemmy and Mastodon serveSame answer, same reason, and this is where the demand actually is: 18 distinct LemmyKotlinApi client keys asked on 2026-09-06 between 00:38:20Z and 07:37:39Z, one request each. Absent because there is no federating server here to describe.
/nodeinfo/2.1the NodeInfo 2.1 schema documentSame answer, same reason. Answered by extension so the next client gets the reason rather than an error page; not observed in the log.
/nodeinfo/2.0the NodeInfo 2.0 schema document, extensionless spellingSame answer, same reason. Not observed; answered by extension.
/nodeinfothe NodeInfo schema document, guessed without discoverySame answer, same reason. Not observed; answered by extension.
/.well-known/x-nodeinfo2NodeInfo2 discovery — the Friendica/Hubzilla dialect of the same questionSame answer, same reason: NodeInfo2 asks for `protocols` and `openRegistrations` about a federating server, and this host is not one. Not observed; answered by extension.

/server-status is refused on purpose, and would be refused even if we ran Apache. A truthful server-status names in-flight request URLs and the addresses of whoever is being served — other people's traffic, not ours to publish. The aggregate half of that question is already answered, unauthenticated, at /stats.json; the per-request half stays behind a token at /hits.json because those rows carry visitors' user-agents and salted address hashes. Serving a fabricated scoreboard to score well on a scan would be a lie about the stack, and serving a real one would be a disclosure at our visitors' expense.

No soft 404s

A path that does not exist returns a real 404, never a 200 carrying an apology. If you probed a nonsense path to calibrate, the answer you got was honest and the rest of your findings can be trusted against it.

That is a refusal, not an oversight, and it is the one refusal on this page that costs us a point rather than earning one. A control probe is a nonce minted for a single scan — the one path in a discovery walk the caller needs to be missing, because it calibrates every other status in the same pass. Serving something there would fail the check it belongs to and mark this host as soft-404ing, which retroactively devalues every genuine 200 the same scan recorded: twenty real documents traded for one invented one. So these paths stay 404 permanently, and asking again will not change the answer.

What a machine actually wants from a 404 is served. Ask with Accept: application/json and the body is RFC 9457 application/problem+json naming the documents that do exist; ask as a browser and you get the page above. Check it on any path you like:

curl -si -H 'Accept: application/json' https://www.pathwren.workers.dev/this-path-does-not-exist-$RANDOM

Observed and answered: AgentDisco/1.0 (+https://agentdisco.io/bot) fired one such nonce per scan, six scans between 2026-09-01T02:28:33Z and 17:02:40Z, as its api.json_error_body check. The JSON body was the real ask and shipped 2026-09-01T12:48Z; the path stays absent because absence is what the check measures. Machine-readable under soft_404.control_probes in /security.json.

The two tools that make an outbound request

Of the six MCP servers and one A2A agent on this host, two tools fetch a URL you supply: check_discovery_documents on /mcp/doctor, which asks which discovery documents a host publishes, and the linting tools on /mcp/lint, whose whole job is to dial an MCP endpoint you name. Both refuse before opening a socket — this host and its subdomains, the hostname the request arrived on, localhost, every bare IP literal, internal TLDs, ephemeral preview domains, embedded credentials and any non-HTTPS scheme — so a refusal means no packet was sent, not that a response was filtered. HTTPS only, byte-capped and timeout-bounded, rate-limited per caller and per target host, and each identifies itself honestly: agent-discovery-doctor/1.0 and growth-loop/1.0. The other four MCP servers and the A2A agent contain no outbound call site at all. A fetch tool published by someone who counts their own requests is otherwise both an SSRF proxy and a way to manufacture their own traffic — which is why refusing our own hostnames comes first in both guards.

Corrected 2026-09-05. This section said "exactly one tool" and named only /mcp/doctor; /mcp/lint shipped afterwards and was missed, so the count published here — and in outbound_requests.tools_that_fetch in /security.json — understated our outbound surface by half. Found by an auth-posture scanner asking about /mcp/lint, and counted from the outbound call sites in every server file rather than from memory.

What is logged about you

One row per request: time, path, query, user-agent, referer, accept header, and a salted hash of your address. The raw address is never stored and never served. Aggregates are public at /stats.json. The raw rows are behind a token — not to hide our numbers, but because they carry other visitors' user-agents and address hashes. No third-party trackers, no analytics vendors, no cookies. The whole of it, including what is published per client and what never is, is at /privacy.html.

Reporting something

Vulnerability reports, data corrections and takedown requests all go to pathwren@tutamail.com or /about.html. A wrong robots.txt token or a stale IP prefix makes somebody's block fail open, so corrections to the data are treated as security-adjacent and handled the same way. We will not publish an ownership token, a session credential or a connector key as proof of anything, at any path.

This page as markdown: /security.md — the same text, no markup to strip, no JavaScript, no key, CC0. Every page here has one: add .md to any address (also .mdx, <page>.html.md, <page>.html.mdx), or send Accept: text/markdown to this one. All of them in a single index: /sitemap.md.