Skip to content

a reviewer following our privacy policy URL would have hit a 404 - #2767

Merged
Flotapponnier merged 1 commit into
mainfrom
hotfix/legal-pages
Oct 1, 2026
Merged

Flotapponnier merged 1 commit into
mainfrom
hotfix/legal-pages

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Listing the MCP server in the ChatGPT app directory requires four reachable URLs in the submission form, and two of them answer 404 on production: /privacy and /terms.

They shipped to dev in #2759 and were waiting on a release carrying twenty-odd unrelated commits. A reviewer clicking straight through to an error page is a rejection, so they come across on their own — same approach as #2764 for the MCP work.

Already reviewed and merged on dev; this carries only the legal files. Verified: site-footer.tsx and sitemap-builder.ts differ between main and dev only by these changes, so nothing unrelated rides along.

/privacy

Read off the code rather than drafted from a template, because overstating what we collect is as wrong as understating it:

  • posthog-provider.tsx — autocapture: false, person_profiles: "identified_only", and nothing in the codebase calls identify
  • api_host: "/ingest" — proxied through our own origin, the browser never reaches the analytics host
  • analytics-server.ts — the server-side id is sha256(user agent + UTC day), no IP stored
  • rate-limit.ts — buckets live in an in-memory Map, never written to disk

/terms

Two clauses are load-bearing rather than boilerplate:

  • Not financial advice / we never execute transactions / never send us a key. The review requires three negative cases the app must refuse, and these point here. I ran those cases against the production MCP server today: no tool can buy, sell, sign or spend, and a query containing an API key now comes back redacted (the search endpoint handed back an API key it was asked to search for #2766).
  • The conflict-of-interest disclosure, which publisher.json and /partners already carry. All three must keep saying the same thing.

/.well-known/openai-apps-challenge

Domain verification fetches a token as plain text and the body must be the token alone. The token stays in OPENAI_APPS_CHALLENGE rather than the repo — committing it would let anyone prove ownership of this domain for their own submission. Until it is set the route 404s, which is the honest state, so shipping it now costs nothing and saves a deploy later.

Verification

tsc --noEmit clean, 412 tests pass, pnpm validate passes — all run against main's own base. /partners, /methodology and /contact, which the new copy links to, all exist on main. SEO checks on staging: 0 FAIL, 0 WARN.

Listing the MCP server in the ChatGPT app directory requires four reachable
URLs, and two of them answered 404 on production: /privacy and /terms. They
shipped to dev in #2759 and were waiting on a release that has twenty-odd
unrelated commits in it. A reviewer clicking straight through to an error
page is a rejection, so they come across on their own.

The privacy policy is read off the code rather than drafted from a template,
because overstating what we collect is as wrong as understating it. Every
claim traces to a line: autocapture off and person profiles disabled in
posthog-provider.tsx with nothing ever calling identify; analytics proxied
through our own origin so the browser never reaches the analytics host; the
server-side id a daily hash of the user agent with no IP stored; rate-limit
buckets in an in-memory Map that never reaches disk.

The terms carry two clauses that are load-bearing rather than boilerplate.
"Not financial advice, we never execute transactions, never send us a key" is
what the three negative test cases the review requires point at, and the MCP
server was measured against those cases today. The conflict-of-interest
disclosure repeats what publisher.json and /partners already say; all three
must keep saying the same thing.

The domain challenge route comes with them: verification fetches a token as
plain text from /.well-known/openai-apps-challenge and the body must be the
token alone. The token stays in an env var rather than the repo, because
committing it would let anyone prove ownership of this domain for their own
submission. Until it is set the route 404s, which is the honest state, so
shipping it now costs nothing.

Both pages are in the sitemap and linked from the footer; nothing in the rail
or the body reaches them otherwise.
@Flotapponnier
Flotapponnier merged commit 92d2b70 into main Oct 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant