Everyone who receives data, and everyone who deliberately does not.
Established by reading the code that talks to each vendor, not by recalling what a product like this usually uses. Last checked against the code on 5 September 2026.
Two vendors receive data from every deployment.
Microsoft Corporation
| Services | Azure Container Apps, Azure Database for PostgreSQL, Azure Key Vault, Azure Blob Storage, Azure Table Storage, Azure Log Analytics, Azure Static Web Apps |
|---|---|
| Purpose | Runs the hosted control plane and this site, and stores everything the control plane holds. |
| Data received | Account name and email, GitHub identifiers, session records including IP address and browser user agent, organization and repository metadata, policy, run events, audit entries, and the name, work email, company and message somebody leaves on the contact form. |
| Where | United States, Azure Central US. The region is enforced by a validation rule in the infrastructure code, so a deployment to another region fails at plan time rather than moving data quietly. |
| Established from | infra/terraform/modules/control-plane, infra/terraform/stacks/control-plane |
GitHub, Inc.
| Services | GitHub OAuth, GitHub Apps, GitHub Container Registry |
|---|---|
| Purpose | Signs people in, reads the repository and membership metadata an organization grants, and stores the control plane's container image. |
| Data received | GitHub account identifier, login, email, display name, avatar URL, and the installation and repository identifiers for repositories an organization connects. No production data and no run contents. |
| Where | United States |
| Established from | web/apps/api/src/auth/github.ts, web/apps/api/src/github/app.ts |
Model providers receive nothing unless you give us a key.
Model-driven planning is optional. With no provider key stored, the engine plans deterministically and no request leaves for either vendor. When the engine calls a model directly from your own continuous integration with your own key, that is your relationship with the vendor rather than ours. These two are listed as our subprocessors for the case that matters to a review: a request that transits the hosted control plane.
Anthropic PBC
| Services | The Claude API |
|---|---|
| Purpose | Model-driven planning: deciding the next action an exploratory user takes, and synthesizing a response for a third-party API that is not reachable from the twin. |
| Data received | Whatever the request carries. In the paths this product ships, that is a workflow description, the page address and title, field and control names, and up to 4,000 characters of the twin's visible page text; or one outbound request line and up to 4,000 bytes of its body. Raw HTML, cookies, and local storage are excluded by construction. |
| Where | United States |
| Engaged when | Only when an organization stores an Anthropic key with the control plane and routes model calls through it. With no key the engine plans deterministically and sends nothing. |
| Established from | web/apps/api/src/providers/proxy.ts, runner/src/model.ts, engine/cmd/af-proxy/synth.go |
OpenAI
| Services | The OpenAI chat completions API |
|---|---|
| Purpose | The same model-driven planning, when an organization chooses OpenAI instead. |
| Data received | The same categories as the Anthropic entry above. |
| Where | United States |
| Engaged when | Only when an organization stores an OpenAI key with the control plane and routes model calls through it. |
| Established from | web/apps/api/src/providers/proxy.ts, runner/src/model.ts, engine/cmd/af-proxy/synth.go |
One vendor sees this website. It sees nothing a customer runs.
This site counts page views itself and always will, but a counter that sends no address, no element and no ordering cannot say where somebody gave up on it. PostHog answers that, with autocapture and session replay, for the pages you are reading right now. It is listed separately from the two sections above because it is engaged by a different thing: no account, organization, repository, policy, run, audit entry or piece of your production data reaches it, because nothing that handles any of those calls it. Its requests go through an endpoint we run rather than to a vendor address, and that is transport rather than a boundary: PostHog, Inc. receives what they carry, which is why it is on this page at all.
Every value typed into a form is replaced in the browser before anything is sent, so a recording of the careers form or the contact form holds fields filling up with asterisks and not what was written in them. There is no cookie, no identifier that outlives a tab, and no IP address: the endpoint in front of PostHog does not forward one. A reader whose browser sends Global Privacy Control or Do Not Track, or who has switched measurement off on the privacy page, never fetches PostHog’s code at all.
PostHog, Inc.
| Services | PostHog Cloud US: product analytics, autocapture and session replay |
|---|---|
| Purpose | Answers where somebody gave up on the marketing website. The first party counter beside it cannot: it sends no address, no element and no ordering, by design, so it can say how many people reached the pricing page and never why they left it. |
| Data received | The marketing website only. PostHog, Inc. receives the page address including its query string, the page title, the referrer, one page view per route, how far down each page you scrolled before leaving it, autocaptured clicks and form submissions carrying the element's tag, classes, ids and visible label text, the browser, operating system, device type, screen and viewport size, browser language and timezone, and a session recording of the pages visited. A recording holds the page structure and styling, cursor movement, clicks and scrolls. EVERY INPUT VALUE IS MASKED IN THE BROWSER BEFORE IT IS SENT, so a recording of the careers form or the enterprise contact form shows fields filling up with asterisks and never the name, work email, company, links or message typed into them. Advertising identifiers are stripped out of the address, and so is the raw user agent string, which posthog-js would otherwise attach to every event and which this project has published a promise about elsewhere; the browser and operating system derived from it are kept, the string itself is not. NOT YOUR IP ADDRESS: the endpoint in front of PostHog does not forward it, so PostHog never receives it and the geography on a PostHog dashboard describes our datacenter rather than any reader. No cookie is set, and the identifier lives in sessionStorage for one tab, so nothing here joins two visits. No account, organization, repository, policy, run, audit entry or production data reaches PostHog: this row is about the website and not about the product. |
| Where | United States, PostHog Cloud US. The browser sends to an endpoint this project runs on its own domain, at app.antifailure.dev, which forwards to PostHog. THAT IS TRANSPORT AND IT IS NOT A BOUNDARY, and the difference is the whole reason this row exists: it changes the destination your browser connects to, not who receives the data. PostHog receives it either way. What it buys is that a content blocker's vendor list does not match the request, so the measurement is not silently half missing, and that your address is dropped on the way through. It is the same site and not the same origin, because this site is a static export with no server of its own to forward anything. Where that endpoint is not reachable the requests fail and are dropped; nothing falls back to sending them to PostHog directly. |
| Engaged when | Only for a person browsing the marketing website, and only where that person is being measured. Global Privacy Control, Do Not Track, the switch on the privacy page and a browser that reports itself as automated each stop it, and each of them stops it BEFORE the library is fetched rather than after: a reader who has said no causes no request for PostHog's code at all, so there is no recorder to have read the page. Nothing in the hosted control plane, the engine, the runner or the command line calls PostHog. |
| Established from | www/lib/posthog.ts, www/components/ProductAnalytics.tsx, www/lib/beacon.ts |
The vendors a reviewer asks about next, and why each one is absent.
| Payment processors, and the condition on that | No card details reach any system here, and none can: checkout and the billing portal are pages Stripe hosts, so a card is entered on Stripe's own form and this product never sees one. That part is unconditional. What is conditional is the rest: the control plane contains a real Stripe client, and it is active when AF_STRIPE_SECRET_KEY and AF_STRIPE_WEBHOOK_SECRET are set. Where they are, Stripe processes an organization's plan, subscription and invoice records and is a subprocessor for that deployment. Where they are not, the billing routes refuse and name the missing variables, and nothing reaches Stripe at all. The control plane says which of the two it is on the first line it logs at startup. This entry used to say there was no billing and that the only Stripe code was an offline simulator, which was true when it was written and stopped being true when the billing work landed. |
|---|---|
| Email and messaging providers, and the condition on that | Two different things share this heading and only one of them is conditional. A customer application's own outbound message, to Resend, SendGrid, Postmark, Amazon SES, Twilio or Slack, is intercepted by the side-effect firewall, recorded locally and never delivered, and that is unconditional. Separately, the control plane itself can send one kind of mail, a sign-in link, through Resend, and that path is active when AF_RESEND_API_KEY, AF_MAIL_FROM and a public URL are all set. Where they are, Resend receives the address the link is sent to and is a subprocessor for that deployment; setting some of the three and not all of them stops the process at startup rather than half enabling it. This entry used to say nothing in the product could send a message, which described the firewall correctly and the control plane's own mail not at all. |
| Error tracking, and the rest of the analytics question | PostHog IS engaged now, for product analytics and session replay on the marketing website, and it has its own row on the list above rather than a softened sentence here. A third party does see something, and no sentence on this page is allowed to imply otherwise: the requests travel through an endpoint we run, and PostHog, Inc. receives what they carry. THIS ENTRY USED TO SAY THERE WAS NO POSTHOG. That was true when it was written and stopped being true the day the marketing site started sending, which is the same failure the payment and email entries above record about themselves. What is still true is everything the row above is careful to exclude: PostHog is a vendor for the WEBSITE, and no account, organization, repository, policy, run, audit entry or piece of production data reaches it. There is no Sentry, no Datadog, no Bugsnag, no Google Analytics, no Mixpanel, no Amplitude and no Plausible in anything this repository wrote, and there is no crash reporter in the engine, the runner, the command line or the control plane, none of which calls any analytics vendor at all. The first party counter described on the privacy page still runs beside PostHog and still sends what it always sent: a channel and a page shape from closed lists, and a random identifier that lives in sessionStorage for one browsing session. The control plane exposes metrics for an operator to scrape and exports nothing. TWO SCRIPTS ARE FETCHED AT RUNTIME, and this entry used to say the site loads none from another origin: PostHog's session replay recorder, which comes from the endpoint this project runs at app.antifailure.dev rather than from any vendor host, and the cal.com booking widget on the contact page, which loads app.cal.com/embed/embed.js and an iframe behind it when a reader scrolls near it. The first is our own infrastructure serving a third party's code, so it is not a third party request; the second is one, which is why this page cannot say the shorter thing either. Saying the site loads no script from a third party would be false while /contact embeds cal.com, so both are named instead of a claim being narrowed until it fits. That iframe reports its own errors to a Sentry host, which is cal.com's document doing cal.com's error tracking on cal.com's origin rather than anything here, and it is named because a reader's browser opens the connection either way. |
| Other model providers | Only Anthropic and OpenAI are accepted. Azure OpenAI, Google, Amazon Bedrock, and local model servers are refused by the provider validation rather than silently supported. |
| Other clouds | The hosted control plane runs only on Azure. There is no AWS, Google Cloud, Vercel, Cloudflare, or Fastly in its path. |
How you find out when this list changes.
| Today | This page and the log below. The list is a single file in a public repository, so every change to it is a public commit with a date and an author, and can be watched without asking us. |
|---|---|
| Under a signed agreement | Thirty days written notice to the address on the order form before a new subprocessor begins processing, and a right to object within that period. |
| Why the difference | Nothing in this product can send an email. That is a fact about the code rather than a policy, and promising a notification that nothing could deliver is the failure this page exists to avoid. |
The thirty day period is a drafted commitment rather than a negotiated one. It is the common term and it is written here so that a review has something concrete to accept or push back on.
Change log.
- 5 September 2026PostHog, Inc. added, for product analytics and session replay on the marketing website only. Named rather than quietly added: the entry below the list said in as many words that there was no PostHog, and a company that sells boundary discipline does not get to soften that by deleting the sentence. Every input value is masked before it leaves the browser, no cookie is set, and a reader who has asked not to be tracked never fetches the library at all.
- 30 August 2026First published. Microsoft and GitHub listed as engaged for every organization; Anthropic and OpenAI listed as engaged only for an organization that stores a model provider key.
Know what happens before you deploy.
Create a disposable production twin for every risky change. Catch migration failures before they reach customers.