# Tristan Denyer — Full Site Content > Engineering Manager, team builder & coach, and former UX designer based in San Francisco. Writes about AI tooling, Next.js security, engineering management, and product design. - Site: https://www.tristandenyer.com - Canonical posts index: https://www.tristandenyer.com/llms.txt - RSS: https://www.tristandenyer.com/feed.xml - Generated: 2026-08-28T17:27:04.035Z This file contains every post on the site, concatenated as Markdown. AI assistants can ingest this single file to gain full context on the site's content without crawling each page. ## Contents - [Which AI Crawlers to Block in robots.txt, and Which to Allow (2026 Guide)](#robots-txt-for-ai-agents): How to block AI bots like Bytespider in robots.txt without losing GPTBot, ClaudeBot, and OAI-SearchBot citation traffic: the four bot classes, a fully annotated production example, and a copy-paste super-prompt that writes an RFC 9309-correct file for your site. - [OpenAPI Isn't Enough for AI Agents. Your API Needs a Field Guide.](#api-field-guide-for-ai-agents): Announcing api-agent.yaml v0.3: a proposed field guide APIs publish at /.well-known/ so AI agents learn the operational knowledge OpenAPI never captures, like idempotency, side effects, rate-limit behavior, and what to do when calls fail. - [Should You Trust Your AI's First Pass on Your Code? Why the Second Pass Is the One That Matters](#ai-second-pass-code-review-prompt): A copy-paste prompt for developers and engineers who need their AI-generated code to hold up in production and stand up to code review. - [Should You Trust Your AI's First Answer? Why the Second Pass Is the One That Matters](#ai-second-pass-review-prompt): A copy-paste prompt for lawyers, researchers, marketers, and executives: anyone in professional services who needs their AI output to actually hold up under scrutiny. - [Why Your Site Isn't Showing Up in ChatGPT, Claude, or Perplexity (Even With llms.txt)](#why-ai-tools-cant-see-your-site): Good news: if AI tools can't read your site, it's likely a fixable infrastructure problem, not a content one. Here's how to diagnose and fix the four issues (CDN rules, WAF challenges, slow TTFB, and JavaScript shells) that keep ChatGPT, Claude, and Perplexity from citing you. - [The Complete List of AI Files Your Website Needs in 2026 (llms.txt, ai.txt, AGENTS.md) with AI Prompts](#ai-files-for-websites-2026): Every week brings another file the AI web supposedly needs. This post sorts what's adopted from what's noise, organized by what each file actually does, with prompts to generate every one of them. - [How We Got Our AI Agent to Remember Everything and Stop Clobbering Each Other's Work](#ai-agent-persistent-memory-knowledge-system): A practical guide (with prompts) to persistent memory and shared context for dev teams using AI coding agents. - [Your Next.js App Might Be Leaking Secrets and Here's How to Find Out](#nextjs-leaking-secrets-snytch): Learn how secrets leak into Next.js client bundles through shared imports, NEXT_PUBLIC_ misuse, and prop serialization, and how @snytch/nextjs detects them before they ship. - [Data Architecture Documentation](#data-architecture): Big data architecture poster I designed while at RealGravity helped explain this complex system to the team. - [UI Development Study: How Do People Hold and Interact with Their Phone?](#user-research-people-hold-interact-phone): Results from a survey I wrote and conducted to discover how people held and interacted with their phone. ## Tools - [AI Readiness Check](https://www.tristandenyer.com/ai-readiness-check): A free tool that scans any URL for 16 AI readiness signals — llms.txt, robots.txt AI rules, schema.org, content negotiation, and more — and returns a graded scorecard. - [MCP Server](https://www.tristandenyer.com/mcp): A free public MCP (Model Context Protocol) server that runs the AI Readiness Check on any URL you give it. Add it to Claude Desktop, Claude Code, or Cursor and ask your agent to scan a site. - MCP endpoint: https://www.tristandenyer.com/api/mcp/v1 (Streamable HTTP, stateless, no auth) --- # Which AI Crawlers to Block in robots.txt, and Which to Allow (2026 Guide) *Source: https://www.tristandenyer.com/work/robots-txt-for-ai-agents* *Published: 2026-08-18* How to block AI bots like Bytespider in robots.txt without losing GPTBot, ClaudeBot, and OAI-SearchBot citation traffic: the four bot classes, a fully annotated production example, and a copy-paste super-prompt that writes an RFC 9309-correct file for your site. Your robots.txt is probably the oldest file on your site. It may also have quietly become the most consequential one again, because it is the first file every well-behaved AI crawler requests, and of all the files in the AI-readiness stack, it is the one with the longest-standing formal internet standard behind it (RFC 9309). This post is the practical companion to [the robots.txt section of my AI files guide](/work/ai-files-for-websites-2026#1-robotstxt-updated-for-the-ai-era): one file, treated properly. What changed, what a robust file looks like now, a fully annotated real-world example running in production, and a super-prompt at the bottom that generates all of this for your own site. ## robots.txt is the file every well-behaved AI crawler reads first Some context worth having before touching the file: - **It's a real standard now.** After 28 years as a gentleman's agreement, the Robots Exclusion Protocol became [RFC 9309](https://www.rfc-editor.org/rfc/rfc9309) in September 2022. Parsing rules, grouping rules, and precedence are formally defined. The examples below lean on that. - **Virtually everyone has one; almost no one has updated it.** [Cloudflare's Radar analysis of 200,000 top domains](https://blog.cloudflare.com/agent-readiness/) (April 2026) found robots.txt adoption at about 78%, but only about 16% of sites carry any AI-specific rules, and only about 4% declare structured AI-usage preferences. The overwhelming majority of robots.txt files on the internet were written for a web where the only serious reader was Googlebot. - **It's advisory.** Compliance is voluntary. The major labs honor it and say so publicly; bulk scrapers often don't. Declared rules protect you from cooperative bots' defaults. Server-side enforcement protects you from everyone else. You need both, and this post covers the first. ## Which AI crawlers to allow and which to block: the four bot classes The single biggest upgrade you can make to your robots.txt is to stop thinking "AI bots" and start thinking in classes, because the right answer differs per class. **1. Answer engines and retrieval fetchers.** OAI-SearchBot, ChatGPT-User, Claude-SearchBot, Claude-User, PerplexityBot, DuckAssistBot, and friends. These fetch your pages to answer a live question or keep an answer index fresh. They cite you and link back, which makes them the closest thing the AI era has to referral traffic. Blocking these is how you end up [invisible in ChatGPT, Claude, and Perplexity](/work/why-ai-tools-cant-see-your-site). **2. Model-training crawlers.** GPTBot, ClaudeBot, CCBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent. These collect content to train future models. Allowing them means models learn your product by default; blocking them costs you nothing in day-to-day AI visibility. This is the one genuinely philosophical decision in the file, and either answer is defensible. What is not defensible is not knowing which answer your file currently gives. **3. Coding agents and agentic browsers.** Claude Code, Cursor, Devin, Operator, and the growing pile of agentic fetchers. Low-volume, user-initiated, and increasingly how developers actually consume documentation. If developers matter to your business, this group decides whether their tools can read your docs on their behalf. **4. Bulk harvesters.** Bytespider, img2dataset, LAION downloaders, Scrapy runs, SEO-tool crawlers you don't use. High volume, no citation, no traffic back. The easy block. ## A complete AI-aware robots.txt example, annotated I recently rewrote [postman.com/robots.txt](https://www.postman.com/robots.txt) along exactly these lines. Here is the structure, with the reasoning: ```text # robots.txt — https://www.postman.com/ # Spec: RFC 9309 · Site summary for AI agents: https://www.postman.com/llms.txt # # Two groups: everything is allowed, except the bulk harvesters at the bottom. # Every allowed crawler — named or not — shares the one rule block below, so the # five crawl-trap Disallow rules are written once and apply to all of them. User-agent: * # AI answer engines. They cite and link back, so they send real traffic. # OAI-SearchBot powers ChatGPT search and does not train models. User-agent: OAI-SearchBot User-agent: ChatGPT-User User-agent: Claude-SearchBot User-agent: Claude-User User-agent: PerplexityBot User-agent: Perplexity-User User-agent: DuckAssistBot # …and a dozen more in this class # Model-training crawlers, so models learn Postman by default. # Google-Extended and Applebot-Extended gate AI training only, not search. # TO OPT OUT OF TRAINING: move these lines to the blocked group at the bottom. User-agent: GPTBot User-agent: ClaudeBot User-agent: Google-Extended User-agent: CCBot # … # Coding agents and agentic browsers. This is what decides whether a # developer's agent can read Postman docs on their behalf. User-agent: Claude-Code User-agent: Cursor User-agent: Devin # … Allow: / Disallow: /search?* # client-side search: nothing to index, infinite params Disallow: /*/run/create/?* # action endpoint, not a document Disallow: /*?ctx=* # context param, duplicates every page # Bulk harvesters — blocked. High volume, no citation, no traffic back. User-agent: Bytespider User-agent: img2dataset User-agent: Scrapy # … Disallow: / # Sitemap index only — it already fans out to all 26 child sitemaps. Sitemap: https://www.postman.com/sitemap.xml ``` Five deliberate choices in there, each of which I see missed constantly: **Stacked user-agents over one shared rule block.** Under RFC 9309, a crawler obeys *only* the most specific group that matches it. The moment you give ClaudeBot its own group, it stops reading your wildcard rules entirely, including the crawl-trap Disallows you wrote three years ago. Stacking every allowed agent above a single rule block means the five Disallow lines are written once and bind all of them. This is the fix for the most common structural bug in AI-era robots.txt files. **Comments as documentation.** The file states its own policy, cites the spec, and tells a future maintainer exactly how to flip the training decision ("move these lines to the blocked group"). Your robots.txt is read by more machines than any other file you own, but it is *maintained* by humans; write for both. **Crawl traps closed for everyone.** Faceted search, action endpoints, and duplicate-content query params (`?ctx=`) waste crawl budget for Google and burn tokens for AI fetchers alike. The agentic era did not repeal the old SEO hygiene; it raised the price of ignoring it. **Training allowed, deliberately.** Postman wants models to know its product deeply. Your call may be the opposite, and the file is one cut-and-paste from flipping. The point is that the file now *encodes a decision* instead of a default. **The sitemap line points at the index.** One line, fans out to 26 child sitemaps, never needs editing when a sitemap is added or renamed.
Where does your site stand? Run the AI Readiness Check. It reads your robots.txt with the taxonomy above, checks 18 more AI-readiness signals, and returns a graded scorecard in seconds. No email or shenanigans.
## Going further: Content Signals Classic robots.txt can only express *whether* a bot may crawl. It says nothing about *how* fetched content may be used, which is the question site owners actually care about now. [Content Signals](https://contentsignals.org/) close that gap with one directive: ```text Content-Signal: search=yes, ai-input=yes, ai-train=no ``` That line says: index me for search, use me in AI answers, do not train on me — independent of any crawl rules. Adoption is early (roughly 4% of top domains), and the [IETF AIPREF working group](https://datatracker.ietf.org/wg/aipref/about/) is standardizing this class of preference expression right now, with Content Signals aligned to its direction. Adding one line today is a cheap bet on where this is heading. The super-prompt below includes it as an option. ## What robots.txt cannot do Three honest limits, so this file does not become a false sense of security: 1. **It cannot enforce.** A user-agent string is a courtesy, not a credential. Rate limits, WAF rules, and auth are what stop a determined scraper. 2. **It cannot keep itself current.** New AI bots ship monthly. Any list, including the one above, decays. Organize by group, comment your intent, and revisit quarterly; the structure makes each revisit a two-minute edit. 3. **It cannot fix what it never sees.** If your CDN or bot-protection layer challenges AI fetchers before they reach your origin, your robots.txt is irrelevant to them. That failure mode, and how to diagnose it, is [its own post](/work/why-ai-tools-cant-see-your-site). ## The super-prompt: copy and paste this Paste this into ChatGPT, Claude, or your coding agent. Answer its questions, and it produces a complete, commented, RFC 9309-correct robots.txt organized exactly like the example above. Models with web search enabled will produce the freshest bot lists. ```text You are helping me write a robust, AI-agent-aware robots.txt file. Follow RFC 9309 exactly, including group-merging rules: a crawler obeys only the most specific matching user-agent group, so every allowed crawler must be stacked above ONE shared rule block to inherit the same Disallow rules. First, ask me for: 1. My site URL and what the site is (docs, SaaS, ecommerce, blog, media). 2. My audience: do developers use my site or docs? (Decides coding agents.) 3. My AI training stance: allow model-training crawlers (models learn my product/content by default) or block them (my content stays out of training sets). Explain the trade-off in two sentences before I choose, and note that blocking training does NOT affect AI answer visibility. 4. My AI answer visibility stance: nearly every site should allow answer engines and retrieval fetchers since they cite and link back. Confirm. 5. Crawl traps to close: ask me for my search URL pattern, faceted/filter params, action endpoints, session or tracking params that duplicate pages, and any infinite URL spaces (calendars, pagination bombs). 6. My sitemap situation: sitemap index URL if I have one, else the sitemap URL, else recommend generating one. 7. Whether I want a Content-Signal line (contentsignals.org syntax: search=..., ai-input=..., ai-train=...) matching my answers above. Then, using web search if available, build the CURRENT list of user-agents in four groups. My knowledge of bot names may be stale; verify against the ai-robots-txt community list on GitHub (github.com/ai-robots-txt/ai.robots.txt, 165+ tracked user-agents as of August 2026) and each vendor's published crawler docs: A. Answer engines & retrieval fetchers (e.g. OAI-SearchBot, ChatGPT-User, Claude-SearchBot, Claude-User, PerplexityBot, Perplexity-User, DuckAssistBot, Applebot, Gemini-Deep-Research, Google-NotebookLM, MistralAI-User, DeepSeekBot, Kimi-User, YouBot, ExaBot, TavilyBot and current peers) B. Model-training crawlers (e.g. GPTBot, ClaudeBot, CCBot, Google-Extended, Applebot-Extended, Meta-ExternalAgent, Amazonbot, bedrockbot, cohere-training-data-crawler, AI2Bot, PetalBot and current peers) C. Coding agents & agentic browsers (e.g. Claude-Code, Cursor, Devin, Operator, opencode, NovaAct, Trae, Manus-User and current peers) D. Bulk harvesters & scrapers with no citation value (e.g. Bytespider, TikTokSpider, img2dataset, LAIONDownloader, ImagesiftBot, Scrapy, aggressive SEO-tool bots) Required output: 1. The complete robots.txt, structured as: - Header comment: site URL, RFC 9309 reference, link to my /llms.txt if I have one, and a one-line statement of the file's policy. - `User-agent: *` plus groups A–C (per my answers) stacked over ONE shared rule block: `Allow: /` followed by my crawl-trap Disallows, each with a trailing comment saying why it exists. - Group D stacked over `Disallow: /`. - My Content-Signal line if I opted in, with a comment. - The Sitemap line (index preferred). - A comment telling a future maintainer exactly which lines to move to flip the training decision. 2. A short "what this file says" summary in plain English, one line per group, so I can sanity-check the policy against my intent. 3. Verification steps: the curl commands to confirm the file is live and the specific user-agent + path combinations I should test with a robots.txt checker to confirm the group inheritance works as intended. 4. Flag anything I chose that contradicts itself (e.g. blocking retrieval bots while saying I want AI answer visibility) instead of silently complying. Do not invent user-agent names. If you cannot verify a bot's current token, say so and link to the vendor's crawler documentation instead. ``` ## Verify it worked Three checks after you deploy: ```bash # 1. The file is live and plain text curl -s https://yoursite.com/robots.txt | head -20 # 2. A named crawler actually inherits your shared rules (RFC 9309 grouping) # Use Google's robots.txt tester or an RFC 9309 parser with user-agent # "ClaudeBot" against one of your Disallowed paths. # 3. The bots you allowed can actually reach you end to end curl -s -A "Mozilla/5.0 (compatible; ClaudeBot/1.0)" -o /dev/null -w "%{http_code}\n" https://yoursite.com/ ``` That third check matters more than people expect: a perfect robots.txt behind a bot-challenge wall is a policy nobody ever reads. If it returns anything but 200, start with [the reachability post](/work/why-ai-tools-cant-see-your-site). And if you want the whole picture in one shot, the [AI Readiness Check](/ai-readiness-check) grades your robots.txt alongside 18 other signals, including whether your Content Signals, llms.txt, and markdown routes agree with what your robots.txt promises. --- # OpenAPI Isn't Enough for AI Agents. Your API Needs a Field Guide. *Source: https://www.tristandenyer.com/work/api-field-guide-for-ai-agents* *Published: 2026-07-22* Announcing api-agent.yaml v0.3: a proposed field guide APIs publish at /.well-known/ so AI agents learn the operational knowledge OpenAPI never captures, like idempotency, side effects, rate-limit behavior, and what to do when calls fail. Watching an AI agent work an unfamiliar API can be frustrating. It may read the OpenAPI spec just fine and form perfectly valid requests, and then wander into the same traps an impatient engineer might. Maybe it creates a resource, checks the list milliseconds later, doesn't see it, and creates it again. Maybe it hits a 429 and decides the answer is to call harder. It has no real way of knowing that `/orders/place` is a proposal, not a charge. To be fair, none of that knowledge lives in the spec, and it was never supposed to. OpenAPI describes what an API is. How it behaves in production has almost no structured home there, only whatever prose someone tucked into a description field. That behavioral knowledge tends to live where it has always lived: in runbooks, in incident retros, in a Slack or Teams thread, and in the heads of the engineers who learned it the hard way. Humans pick that knowledge up over days or weeks of onboarding. Agents mostly don't get it at all, so they end up re-deriving it the expensive way by making the mistakes themselves, at machine speed, against production endpoints. ## What is api-agent.yaml? A field guide for AI agents using your API **[api-agent.yaml](https://github.com/tristandenyer/api-field-guide-spec)**, which I am calling The API Field Guide, is my proposal for where that knowledge should live. This is a YAML file the API owner publishes at `/.well-known/api-agent.yaml`, next to the OpenAPI spec. Think of it as the [Ocean's Eleven briefing](https://youtu.be/te-wYw0ymB8?si=h-3CaRDU53QgCPu5&t=59) for your agent. Before anyone touched the vault, they knew the layout, the guards, the alarms, and the way out. The file answers four questions, in four layers: - **What to know.** The conceptual model, the insights no schema captures ("an order is not live until confirmed"), the scope gotchas a flat OAuth scope list doesn't explain, how long writes take to become visible in reads, how to paginate safely. - **What to do.** Per-endpoint preconditions, idempotency requirements, side effects, reversibility and the exact call that compensates, latency expectations, and human-approval gates such as "orders above $50 stop and wait for a person." - **What changed.** Structured deprecations, migration notes for breaking changes, and, when an API dies, a pointer to its successor's contract, published at a git-committed address that outlives the endpoint itself. - **What to say.** A feedback channel, modeled on security.txt, where agents report undocumented errors and contract mismatches back to the owner. The file usurps nothing. It points at OpenAPI, Arazzo, AsyncAPI, and auth.md through a `refs` block and adds only the layer none of them cover.
See it in action: The interactive one-pager lets you click through a real example, field by field.
## The feedback loop that makes AI agents better at using APIs Each field is useful on its own, but the thing I keep coming back to is the closed loop they form. An agent runs into behavior the contract didn't predict. It re-fetches the field guide and compares the version against the one in memory from the last visit. If the version changed, something about the API shifted, and the agent migrates using the breaking-change notes, or, if the API has reached end of life, the successor contract. If the version didn't change, the contract itself is wrong, and the agent files a structured `stale_contract` report. The owner folds those reports back into the file and republishes. Every agent that arrives afterward gets the corrected contract. **One agent's failure becomes every agent's knowledge.** Agents stop being passive consumers of stale or outdated documentation and become the sensing layer that keeps the contract true. ## Won't another file just burn more of the agent's context window? Users of agents are trying to trim what they feed into context, not add to it, so a fair pushback here is: why ask agents to read one more file? And I think the math works out in a couple ways. The file is small. A typical field guide should run you about 300 to 1,500 tokens, and every section is optional. I am going to estimate most people generate a YAML file about 25-50% filled out. Agents are told to read selectively and load only the sections a task requires, so this should be token efficient. Meanwhile, a single failed API call-and-retry cycle, plus whatever it takes to reason through the failure, tends to cost an agent more tokens than reading the whole file up front. And the real comparison isn't field guide versus nothing. It's field guide versus what agents do today: scraping docs pages, guessing at retry policy, and learning by experiment. Against that baseline, this is the more efficient path. ## Built skeptical: prompt injection and the trust model A file that autonomous agents read and act on is an instruction channel, and instruction channels are attack surfaces. So the spec ships a trust model alongside the fields. The file is advisory, API-authored, and untrusted by default. Descriptive fields, such as error meanings and parameter gotchas, are safe to reason over because an agent can check them against observed behavior. Imperative fields, such as a test command to run or a successor contract to adopt, require human approval or out-of-band verification. Free text is treated as a prompt-injection surface, and field-guide text never outranks the human operating the agent. This does NOT absolve engineers from safeguards on their APIs. Every limit that matters must be enforced server-side or at a gateway, as well. Declared limits protect cooperative agents from mistakes. Servers protect the API from everyone else. ## Where it fits alongside MCP, Arazzo, agents.json, and AP2 This is deliberately one layer in a larger stack. MCP connects agents to tools, and a field guide is the enrichment source that makes a generated MCP server actually good. Arazzo and agents.json describe how to run a sequence of calls, while the field guide describes when to hold off and what to do when a call fails. AP2 proves that a human authorized a payment, and the field guide declares which operations need that proof. Your AI agent connected to Postman, or your in-house tooling can generate most of the file from the code, docs, collections, test runs, and monitors you already maintain. ## The api-agent.yaml spec is a draft, and I want the argument v0.3 is open for public comment. Read the [full spec](https://github.com/tristandenyer/api-field-guide-spec/blob/main/SPEC.md), a JSON Schema, three worked examples, and twelve open questions where I honestly don't know the right answer yet. A validator, a generator, and a reference implementation an agent can be pointed at are next on my list to build alongside this. If you own an API, I'd love to know what you think of this! If you build and use agents and or AI tooling, tell me what's missing or needs adjustment. Issues and pull requests are welcome: [github.com/tristandenyer/api-field-guide-spec](https://github.com/tristandenyer/api-field-guide-spec). --- # Should You Trust Your AI's First Pass on Your Code? Why the Second Pass Is the One That Matters *Source: https://www.tristandenyer.com/work/ai-second-pass-code-review-prompt* *Published: 2026-07-20* A copy-paste prompt for developers and engineers who need their AI-generated code to hold up in production and stand up to code review. > **Two ways to use this prompt:** > Run it on your own code changes before you open a PR. Or paste it in before reviewing a teammate's diff, letting the AI do a first read before you do. Either way, you show up knowing exactly where to dig in. _This is the developer-focused companion to [my second-pass prompt for professional work](/work/ai-second-pass-review-prompt), rebuilt from the ground up for code: diffs, PRs, security surfaces, and everything that breaks after you ship._ For those of you already using AI in your development workflow (generating code, debugging, writing tests, cleaning up docs), let's not stop there. Here is where things can go further, and where many developers stop short. This is the step that separates code that looks right from code that actually holds up in production, under load, and under review. **Challenging the output.** ## Why you may not be able to trust your AI's first pass AI coding tools are fast. Fluent. They produce clean-looking, syntactically correct code that clears a linter and passes a basic test. They're built to get it semantically correct, not necessarily functionally right. The challenge is not that AI writes bad code. It is that AI writes code that looks correct at the surface while carrying subtle logic errors, security gaps, and architectural decisions that made sense to no one in particular. The model does not understand your system. It will often pattern-match to what it has seen before. One thing worth knowing: unless specifically instructed, AI coding tools do not reason across your codebase. They work from a fixed snapshot of the world that stops at a specific point in time, with no awareness of what has changed in your dependencies, your infrastructure, or the security advisory landscape since then. They carry context from your session, which is not the same as understanding your architecture. They generate code that fits the pattern of the prompt, not necessarily the intent behind it. The first output is a starting point. A fast, often impressively capable starting point. But still a starting point, a first draft. ## How significant is the AI code quality problem? More significant than the productivity headlines suggest, and the data is starting to catch up with the hype. [CodeRabbit's analysis of 470 open-source repositories](https://www.coderabbit.ai/blog/2025-was-the-year-of-ai-speed-2026-will-be-the-year-of-ai-quality) found that AI-generated code carries 1.7 times as many defects as code written by humans. That is not a small delta. [Sonar's 2026 State of Code survey](https://www.sonarsource.com/state-of-code-developer-survey-report.pdf) found that 96% of professional developers do not fully trust AI-generated code, and only 48% say they always check it before committing (which may account for the defect rate above). AI already accounts for 42% of committed code industry-wide. That can be millions of lines of 'first-draft' code in production. It is not just correctness either. > **"AI included bugs like improper password handling and insecure object references at a 1.5-2x greater rate than human coders. … If 2025 was the year of AI coding speed, 2026 is going to be the year of AI coding quality."** > _— [Stack Overflow Blog / CodeRabbit, January 2026](https://stackoverflow.blog/2026/01/28/are-bugs-and-incidents-inevitable-with-ai-coding-agents/)_ [Stack Overflow's 2025 Developer Survey](https://survey.stackoverflow.co/2025/ai/) found that developer trust in AI tool accuracy has fallen to 33%, down from 43% the year before, while overall favorability toward AI tools has slid from 77% in 2023 to 60%. That is not developers becoming more skeptical for no reason. That is developers accumulating experience with what AI-generated code does after it ships. The problem is not awareness. It is the gap between how much AI-generated code is going out and how rigorously it is being reviewed before it does. **This prompt is designed to close that gap.** ## What a deeper, second-pass prompt can do for your code One way to think about it: the first prompt is like a fast junior engineer who knows a lot of patterns and can move quickly. Solid output, good intentions, and genuinely useful in the right context. But most experienced engineers would not promote a PR from a junior engineer without a senior taking a careful, independent look at it first. This second-pass prompt works the same way. It resets context, strips out prior assumptions, and instructs the AI to approach the code as a skeptical senior engineer seeing it for the first time. Not a collaborator who helped write it, but more like a reviewer who has to defend it in a postmortem. A well-structured second-pass prompt can: - **Catch what the first pass missed:** logic errors, edge cases, off-by-one bugs, unhandled nulls - **Challenge the security posture:** not just whether auth exists, but whether it is enforced in the right place, with the right model, against the right threat surface - **Find the DRY violations and reusability gaps:** repeated logic, hardcoded values, inline behavior that should be extracted into shared utilities or components - **Verify library and API behavior:** rather than assuming it knows how a dependency works, retrieve current documentation and advisories at review time - **Surface what a senior engineer would raise in review:** an existing utility or dependency that already does what the new code reinvents, architectural inconsistencies, patterns superseded by better approaches, things that will cause pain in six months This is not about slowing down. It is about catching the things that slow you down later, in production, at 2am, in a postmortem. ## The AI echo chamber problem in code review There is a subtler issue that does not get discussed much. When AI is used to generate code and then asked to review that same code, the result is often a feedback loop that mostly validates itself. The model generated the code with a particular approach in mind. Asking it to review that code, without explicit instruction to break out of that frame, tends to produce agreement rather than challenge. It will check for the things it already checked for. It will miss what it missed the first time. This is one way AI-assisted code that passes an AI review can still carry security vulnerabilities, architectural problems, and logic errors that only surface in production. The prompt below is built to break that loop. It instructs the AI to treat every assumption as unverified, retrieve current library behavior and security advisories rather than rely on training-time knowledge, and approach the review the way a senior engineer who did not write the code would. Less pair programmer. More code reviewer with something to prove. ## Why not just start with this prompt and skip the first pass? The short answer is that this prompt works best when the code is far enough along to be meaningfully challenged. Think of it like submitting a PR for review. It should be ready, not still forming. Running a half-finished implementation through a structured adversarial audit produces a report on the wrong version of the code. The prompt works better when there is something settled to push against. There is also a practical consideration. This prompt is thorough. It checks security, traces code paths, retrieves current dependency information, and produces a structured report. On throwaway scripts or early-stage prototypes, that level of depth is probably overkill and can burn tokens where you shouldn't. Save it for code that is heading toward review, production, or a security boundary. One more thing: the two questions the AI asks before it starts require real answers. What is this change doing, and does it touch anything sensitive? If you cannot answer that clearly, the code may not be in the right shape for this yet. ## Who this is for This prompt tends to be most useful for developers and engineers whose output has real-world consequences: - **Frontend engineers:** components, state management, accessibility, client-side security, browser API usage, third-party pixels - **Backend engineers:** APIs, services, business logic, database queries, background jobs, third-party integrations, auth flows - **Full-stack developers:** API contracts, data fetching layers, session handling, shared types, anything owned end-to-end - **DevOps and platform engineers:** IaC, CI/CD pipelines, deployment configuration, secrets handling, IAM - **Engineering leads and senior engineers:** reviewing PRs before merge, setting technical standards, owning the decisions that show up in postmortems If the code is heading toward production, a security boundary, or a code review where someone is going to push back, this prompt is worth running first. ## How to use it 1. Get the code to a point where you would open a PR or send it for review 2. Open a fresh session with your AI agent, or clearly signal a context reset 3. Paste the prompt below, followed by the diff, link to PR, or relevant code sections 4. Answer the two questions the AI asks before it starts 5. Work through the findings: Critical first, then Significant, then Minor 6. For anything flagged as assumed or requiring a live environment to confirm, verify independently before shipping Those two questions matter. The more specific the answers, the sharper the audit. ## The prompt: copy and paste this (Edit it to fit your stack, your threat model, or your team's conventions. This should fit your needs.) ``` Role: Senior engineer running an independent second-pass audit of a diff / PR / change. Ignore prior session context; treat the work as new and unverified. Review as a skeptic, not a collaborator who already endorsed the approach. Objective: Find defects, gaps, security exposures, and risks the first pass missed. Categories below are focus areas, not a closed checklist. Measure the code against its stated intent but judge it by what it actually does: a divergence from intent is itself a finding, and good intent does not excuse a broken implementation. Scope (default): Audit only the changed code plus what it directly touches, depends on, or affects. Do not audit the whole codebase, refactor untouched code, or flag pre-existing issues unless the change introduces, worsens, or relies on them (note those briefly as out-of-scope context). Widen only if the author asks. Ask before starting: 1. Why is this change being made (ticket / bug / requirement / goal), what does it touch, and is any part internet-facing, handling auth, processing untrusted input, or touching sensitive data (PII, credentials, payments, health)? 2. Any narrower focus (e.g. "security only," "just the auth changes"), or a request to widen beyond the diff into surrounding files or a full-codebase audit? Verification: Do not trust memory or training-time assumptions for API signatures, library or framework behavior, version support, deprecations, browser compatibility, or security advisories / CVEs — retrieve current sources at review time. Trace each finding through the actual code path. Mark findings that need running code, a repro, or a test to confirm; flag anything unverifiable as assumed, pending human confirmation. Audit — core (all code): - Fitness for purpose: does it solve the stated problem? Is the approach proportionate (not over- or under-engineered), complete, and free of scope creep? Simpler alternatives? - Correctness and logic: edge/boundary/off-by-one, null/empty/zero, type coercion, inverted conditionals, wrong algorithm or data structure, arithmetic, ordering/uniqueness assumptions. - Error handling and resilience: unhandled exceptions/rejections, swallowed or over-broad catches, missing validation, timeouts/retries/backoff, resource leaks, partial-failure and rollback, graceful degradation. - Security (priority — audit thoroughly): Injection: SQL/NoSQL, command, path traversal, SSRF, XXE, deserialization, template/log — is untrusted input validated, encoded, or parameterized at every boundary? AuthN/AuthZ: broken/missing access control, IDOR, privilege escalation, session/token/JWT misuse, checks enforced only client-side. Secrets and config: hardcoded creds/keys/tokens, secrets in source/logs/errors, insecure defaults. Secret lifecycle trace (mandatory whenever the change touches any secret, API key, token, credential, or connection string): enumerate each one, then trace it end-to-end and confirm it cannot reach (1) client-delivered code or markup — bundles, hydration/serialized props, public env prefixes like NEXT_PUBLIC_ or VITE_, source maps, HTML comments; (2) the display layer — UI state, DOM attributes, error screens, admin panels, autocomplete/form echoes; (3) transit it does not need — query strings and URLs, Referer headers, redirects, third-party API calls, analytics/telemetry events, webhook payloads, email; (4) persistence it does not need — application logs, error trackers and crash reports, CI/CD logs, caches, localStorage/sessionStorage, temp or config files, VCS history. Sampling is not tracing: follow every read of the secret to every sink. Record the result per secret; an unverified path is itself a finding, not a pass. Web/browser: XSS (stored/reflected/DOM; innerHTML, dangerouslySetInnerHTML, v-html), CSRF, CORS, CSP, clickjacking, cookie flags (HttpOnly/Secure/SameSite), open redirects, postMessage, mixed content. Crypto: weak algorithms, poor randomness, improper TLS/cert validation, unsalted or fast password hashing, homegrown crypto. Data exposure: PII handling, over-permissive responses, stack traces to clients, sensitive data in logs. Dependencies/supply chain: known-vulnerable or abandoned packages (check current advisories), unpinned versions, lockfile integrity, risky transitives, typosquats. Cite OWASP/CWE where it sharpens a finding. - Code quality: readability, naming, complexity, duplication, dead code, unused imports/vars, right level of abstraction, adherence to the project's style/linter/conventions. - DRY and reusability: repeated logic or duplicated code blocks that should be consolidated; hardcoded values that should be constants or config; inline logic that should be extracted into named functions, shared utilities, or reusable components (UI, presentational, container, form, layout, or otherwise). - Performance: algorithmic complexity, N+1 queries, redundant work, blocking I/O on hot paths, unbounded memory, caching; for frontend, bundle size and re-render cost. - Concurrency and state: races, deadlocks, unsafe shared state, missing atomicity/locking, idempotency, cross-async ordering. - Testing: coverage of new/changed paths, untested edge cases, brittle or non-asserting tests, testability. - Observability: log quality/levels, actionable errors, metrics/tracing on new critical paths, production diagnosability. - Interfaces and compatibility: contracts, breaking changes, versioning, backward compatibility for callers, stored data, serialized formats. - Data and persistence: migration safety/ordering/reversibility, transaction boundaries, integrity constraints, rollout compatibility. Audit — context-specific (only where relevant): - Frontend/browser: accessibility, state correctness, cross-browser/responsive, listener cleanup (leaks), SSR/hydration, loading/error states. - Backend/service: request validation, rate limiting, auth middleware placement, statelessness, connection pooling, pagination/payload limits. - Deployment/infra: env and feature-flag handling, rollback/zero-downtime, migration-vs-deploy ordering, IaC correctness, least-privilege IAM, resource limits/health checks, pipeline secrets, CI/CD gates. Cross-cutting: - Consistency: internal contradictions, terminology/version drift, divergence from surrounding architecture and conventions. - Compliance and exposure: dependency license conflicts, regulatory obligations (PII/GDPR, accessibility), legal/operational liability (flag only). - Prior art: reinvented functionality that already exists as an internal utility, a language standard-library feature, or an established third-party library; duplicated or conflicting patterns; approaches superseded by a known standard/RFC or better practice; what a panel of senior engineers would raise. Output: Findings by severity — Critical / Significant / Minor. For each: location (file, line/range, function), description, impact, resolution. Name the vulnerability class (+ CWE/OWASP) for security findings. - Critical: exploitable vulnerability, data loss/corruption, correctness bug on a core path, likely outage. - Significant: weakens robustness/security/performance/maintainability, or needs mitigation before merge. - Minor: style, naming, low-risk nits. State explicitly if a severity level has no findings. End the report with a "Secrets sweep" line: either "no secrets touched by this change," or the list of secrets traced with a per-secret verdict (clean / finding raised / could-not-verify and why). A report without this line is incomplete. Constraint: When a fix needs a judgment call or depends on intent, threat model, or unstated requirements, stop and ask — do not assume. Do not rewrite beyond what demonstrates a fix unless asked. Stay in scope; if the change depends on a larger problem outside the diff, flag it and ask before expanding. ``` ## What to expect back The AI returns a structured report by severity level, with findings tied to specific files, line ranges, and functions. **Critical:** exploitable vulnerabilities, data loss or corruption risk, correctness bugs on core paths, things likely to cause an outage. **Significant:** findings that weaken robustness, security, performance, or maintainability, or that need addressing before the code merges. **Minor:** naming, style, low-risk nits, things worth knowing but not blocking. The report closes with a **secrets sweep**. If the change touches any keys, tokens, or credentials, the AI has to trace each one through the client bundle, the display layer, network calls, logs, and storage, then give you a verdict on every single one. Anything it could not verify gets written up as a finding. I added this requirement after asking an agent whether it had confirmed no secrets were exposed anywhere in a change we had just reviewed. It admitted it had only spot-checked. I feel you should never have to ask that question after the fact, and that the answer belongs in the report. Each finding includes the location, the problem, the impact, and a suggested resolution. Security findings are named with their vulnerability class and CWE or OWASP reference where applicable. Where anything requires a judgment call or depends on intent or threat model, the AI is instructed to stop and ask rather than assume. Push back on findings that do not fit your context. Ask for elaboration on anything unclear. Most engineers are surprised by what surfaces on code they thought was ready. Run it once and you will understand why this step exists. ## What if it comes back with nothing critical? That is a valid and useful result. A thorough second pass that confirms the code is solid before it goes to review is genuinely useful information. The goal is to feel more confident about the code changes, their blast radius, and even discover non-obvious impacts on the codebase. ## Frequently asked questions **Should I trust AI-generated code without reviewing it?** Most experienced engineers would say no, and the data backs that up. Sonar's 2026 survey found that 96% of professional developers do not fully trust AI-generated code, and only 48% say they always check it before committing. AI code introduces 1.7 times as many defects as human-written code on average. Review is not optional. It is the step that determines whether the speed gain was real. **What kinds of bugs does AI-generated code typically miss?** The most common failure patterns are subtle logic errors and catches that pass basic tests but break on edge cases, security vulnerabilities introduced at input boundaries and auth checks, silent error handling that swallows failures rather than surfacing them, and DRY violations where the same logic gets copied rather than extracted. These are exactly the things a structured second-pass audit is designed to surface. **Why does AI write insecure code even when it looks correct?** AI models generate code that fits the pattern of the prompt, not necessarily the threat model of the system. They do not know what is internet-facing, what data is sensitive, or what your auth architecture assumes. Security requires understanding context that the model does not have unless you provide it explicitly, which is exactly what the two pre-audit questions are designed to capture. **Is this the same as running an automated security scanner or linter?** Not at all. Linters catch style and syntax. Static analysis catches known patterns. This prompt instructs the AI to reason about the code's behavior across real scenarios, trace logic through actual code paths, check current security advisories at review time, and surface architectural and design-level issues that an automated tool would miss. Think of it as a senior engineer review, not a scan. **Why not just start with this prompt instead of generating code first?** This prompt is a review tool, not a generation tool. It works best when there is something settled to push against. Running it on a half-formed implementation produces a report on the wrong version of the code. Get the first pass to a point where you would open a PR, then run this. **Can I use this to review code I wrote myself without AI?** Yes. The prompt does not care how the code was produced. It only evaluates whether it holds up under scrutiny. Some engineers run it on legacy code before touching it, to understand what they are working with before making changes. **Does this work with ChatGPT, Claude, Gemini, and other AI tools?** Generally yes. The prompt is written in plain instruction language and works across capable frontier models. Results vary slightly by model, particularly on security depth, but the structure and intent carry across most of them. For security-sensitive code, models with web search enabled will produce better results on dependency and CVE checks. **What does "flag as assumed, pending human confirmation" mean?** When the AI cannot verify a finding by tracing through the actual code or retrieving current documentation, it is instructed to flag it rather than assert it confidently. That is your cue to verify it yourself or run the code to confirm before shipping. It is the prompt's built-in honesty mechanism, and one of the most useful things it does. --- _The first pass is where your AI shows you what it can generate. The second pass is where you find out if it should ship._ --- # Should You Trust Your AI's First Answer? Why the Second Pass Is the One That Matters *Source: https://www.tristandenyer.com/work/ai-second-pass-review-prompt* *Published: 2026-07-12* A copy-paste prompt for lawyers, researchers, marketers, and executives: anyone in professional services who needs their AI output to actually hold up under scrutiny. > **Two ways to use this prompt:** > Use it on your own AI-assisted work before it goes out. Or paste it in before reviewing a colleague's work, and let the AI do a first read before you do. Either way, you show up knowing exactly where to focus. _Developer or engineer? There is a [companion version of this prompt built specifically for code review](/work/ai-second-pass-code-review-prompt): diffs, PRs, security surfaces, and everything that breaks in production._ For those of you already using AI for your writing and research, crafting prompts, getting output back, cleaning it up, and moving on, that puts you ahead of most. But here is where things can go further, and where most professionals stop short. It is the step that separates output that sounds good from output that is actually defensible and on solid ground. **Challenging it.** ## Why you may not be able to trust your AI's first output AI agents want to always have an answer, and appease you. They tend to sound authoritative right up until the moment they are wrong. For those working in professional contexts (a lawyer filing a brief, a researcher publishing findings, an executive putting out a board memo, a marketer publishing a whitepaper), the stakes are different. Those words carry weight, citations get checked, claims get quoted, and the reasoning gets pulled apart. Or, in some case, they are taken at authoritative face-value and _never_ challenged. One thing worth knowing: AI agents do not fact-check themselves in real time. They draw on a fixed snapshot of information with a hard cutoff date, with no awareness of what has changed since then. They carry assumptions baked in from your session. They tend to pattern-match to what sounds right rather than verify what is right. They can cite a source that loosely supports a claim while completely missing a newer study that changes the picture. The first output is a draft, which at times can be a very good one, but should still be considered a draft. ## How significant is the AI hallucination problem? More significant than most professionals currently expect, and it may not be improving as fast as the headlines suggest. [Stanford testing](https://hai.stanford.edu/news/ai-trial-legal-models-hallucinate-1-out-6-or-more-benchmarking-queries) found that leading legal AI research tools produced incorrect information between 17 and 34 percent of the time on challenging legal queries. As of mid-2026, one researcher tracking AI errors in legal filings has catalogued over 1,450 documented cases of AI hallucinations in court documents, with new incidents being logged at four to five per day. Lawyers have been sanctioned and fined tens of thousands of dollars for submitting briefs built on AI-generated citations that do not exist. It is not limited to legal work either. > **"68% of IT professionals have personally witnessed AI produce hallucinations with potential operational impact. Of those, 16% report the errors reached production environments before anyone caught them."** > _— [Ivanti 2026 AI Maturity Report](https://www.ivanti.com/resources/research-reports/scaling-ai-it-operations)_ [McKinsey's 2026 AI Trust Maturity Survey](https://www.mckinsey.com/capabilities/tech-and-ai/our-insights/tech-forward/state-of-ai-trust-in-2026-shifting-to-the-agentic-era) found that inaccuracy is the single most cited AI risk among senior decision-makers with direct responsibility for AI governance. For many, the problem is not awareness. It is the ability to catch errors before they go out. **This prompt is specifically built to close that gap.** It explicitly instructs the AI to go out and verify rather than assume, challenge rather than confirm, and flag anything it cannot empirically support before it ends up in something that matters. ## What a deeper, more robust second-pass prompt can do One way to think about it: the first prompt is like bringing in a sharp junior associate to do the initial work. Solid effort, good intentions, and a genuine desire to impress. But most experienced professionals would not let that work walk out the door without a senior person taking a fresh, independent pass at it first. This 'second-pass' prompt works similarly. It resets the AI's context, removes prior assumptions, and instructs it to approach the work as a senior, independent, skeptical expert reviewer. Not a collaborator who already agreed with your direction. A well-built second-pass prompt can: - **Catch what the first pass missed:** factual errors, unsupported claims, gaps in logic - **Challenge the sources:** not just whether they exist, but whether they are current, authoritative, and actually support the specific claim they are attached to - **Surface what you may not have known to look for:** adjacent research, expert consensus that cuts against the argument, newer findings that change the picture - **Check the work** against the outside world, not just internally for consistency - **Grade tone against actual intent,** because drift is common and inconsistent register can quietly undermine credibility This is not about doubting the work. It is about putting it through the same kind of pressure test a peer reviewer, opposing counsel, or a room full of domain experts might apply. ## The AI echo chamber problem worth knowing about There is a subtler issue that I don't see getting discussed much. When AI is used to research, draft, and then review the same work, the result can be a feedback loop that mostly validates itself. The model was trained on certain, limited sources. The prompt was framed with a particular angle. The output reflects both. Asking that same AI to review what it just produced, without explicit instruction to break out of that loop and into the wider world of knowledge, tends to produce validation rather than challenge. This is one way AI-generated work that reads as internally coherent can still be externally wrong when it gets published, filed, or cited. The prompt below is designed to address this directly. It instructs the AI to retrieve current, external information rather than pull from memory, to surface non-obvious connections to work outside the immediate focus, and to approach the review the way a panel of outside experts might. **Less collaborator; more skeptic.** ## Why not just start with this prompt and skip the first pass? The short answer is that this prompt tends to work best when the work is far enough along to be meaningfully challenged. Think of it like handing your Master's thesis in to the board for review. It should be done and ready, not still forming. Running a half-formed draft through a structured adversarial audit produces a report on a moving target. The prompt works better when there is something settled to push against. There is also a practical cost consideration. This prompt is thorough. It retrieves sources, checks consensus, audits tone, and produces a structured report. On early drafts or lower-stakes work, that level of depth may not be necessary. It is worth saving for work that matters. One more thing worth noting: the three questions the AI asks before it starts require real answers. Who is this for? What tone was intended? What should the reader walk away thinking or feeling? If those answers are not clear yet, the work may not be ready for this step. ## Who this is for This prompt tends to be most useful for professionals whose output carries real-world consequences: - **Lawyers:** briefs, contracts, memos, opinions - **Researchers and academics:** papers, literature reviews, grant proposals - **Marketing professionals:** campaigns, whitepapers, thought leadership, e-books and sales materials - **C-suite and senior executives:** board communications, strategic documents, public statements - **Policy professionals:** white papers, regulatory filings, public commentary If the work gets cited, acted on, scrutinized, or published, this kind of review is worth running. ## How to use it 1. Get your work to a point where you feel like it is ready to share with peers 2. Open a fresh session with your AI agent, or clearly signal a context reset in the chat you are working in 3. Paste the prompt below (if you are in a new chat, follow it up with the full document you want reviewed) 4. Answer the three questions the AI asks before it starts 5. Work through the findings: Critical first, then Significant, then Minor 6. Anything flagged as unverified, confirm independently before it goes out Those three questions are worth answering carefully. The quality of the review tends to reflect how well they are answered. ## The super-prompt: copy and paste this (And yes, of course you may edit this prompt to suit your needs! Add a line about removing em dashes and common AI phrasing, if you prefer. It's YOUR prompt.) ``` Role: Senior peer reviewer conducting an independent second-pass audit. Prior context from this session does not apply. Treat this work as new. Objective: Identify all errors, gaps, inconsistencies, and risks not caught in the initial review. The categories below are primary areas of focus, not an exhaustive checklist; flag anything warranting attention regardless of category. Before beginning the audit, ask the author: 1. Who is the intended audience for this work? 2. What tone and register were you aiming for? (e.g., formal, conversational, authoritative, clinical, persuasive) 3. What do you want the reader to think, do, or feel after engaging with this work? Verification standard: Do not rely on memory, prior session context, or training-time assumptions for any factual claim, source, citation, domain standard, or professional guideline. Each item must be treated as unverified until confirmed. Where current, authoritative information is needed to validate a finding, retrieve it at time of review. Flag any finding that cannot be empirically verified as assumed and mark it for human confirmation. Audit scope: - Accuracy: factual errors, unsupported claims, outdated sources, misapplied citations, conclusions unsupported by evidence - Completeness: missing steps or elements, unstated assumptions, unaddressed counterarguments or alternative interpretations - Consistency: internal contradictions, terminology drift across sections, reasoning that breaks down end-to-end - Clarity: ambiguous language, passages open to multiple readings, terminology mismatched to the intended audience - Risk and exposure: claims or language that could be challenged, misread, or create professional, legal, or ethical liability (flag only; do not revise without instruction) - Structure and form: argument flow, adherence to applicable formatting or citation standards, anything a peer reviewer would flag - Tone and register consistency: using the author's stated intentions as the benchmark, provide a subjective overall grade (On-Target / Mostly Consistent / Drifting / Inconsistent) and flag specific passages where the tone or register departs from the intended direction, noting what changed and how to bring it back in line - Source quality: evaluate each source against authority (is this a recognized, credible voice in this domain?), recency (is it current enough for the claim it supports?), specificity (does it actually support the specific claim being made, or only loosely?), primary vs. secondary (is this the original source or a citation of a citation?), and consensus alignment (does this represent mainstream expert opinion, a minority view, or a contested position, and is that accurately reflected?); flag each source with qualitative descriptors and prioritize as Critical / Significant / Minor - Non-obvious relationships and field positioning: identify adjacent, contradicting, corroborating, or superseding work, findings, standards, or arguments the author may be unaware of or has not engaged with; flag where the work unknowingly replicates, conflicts with, or is materially strengthened by external sources; surface what a panel of domain experts would raise that the author, working inside their own focus, would not Output format: Report findings prioritized as Critical / Significant / Minor. For each: location, description, impact, and recommended resolution. Constraint: Where a correction requires a judgment call or depends on authorial intent, halt and ask before proceeding. Do not assume intent. ``` ## What to expect back The AI returns a structured report by severity level. **Critical**: findings that, if left unaddressed, could undermine the credibility, accuracy, or defensibility of the work. **Significant**: issues that weaken the work or create exposure, but do not invalidate it outright. **Minor**: polish items, tone drift, small citation gaps, stylistic inconsistencies. Each finding includes the location, the problem, why it matters, and a suggested path to resolution. Where anything requires a judgment call, the AI is instructed to stop and ask rather than assume. At this point, challenge specific findings, ask for more clarity, push back where something does not feel right. Get curious. Most people are surprised by what it surfaces. Run it once and you will understand why this step exists. ## What if the AI comes back and finds nothing wrong? That is a valid result. A thorough second pass that confirms the work is solid is genuinely useful information. The goal is not to find something wrong. It is to know that if something were wrong, it would have been found. ## Frequently asked questions **Should I trust my AI's first answer?** For most professional work where accuracy matters, probably not without some form of verification. AI agents can produce confident, fluent output that contains factual errors, outdated information, fabricated citations, and logical gaps without any visible indication that something is off. The first output is a starting point. This prompt is one way to find out if it holds up. **What is an AI hallucination?** An AI hallucination is when a model confidently produces information that is false, fabricated, or unsupported, and presents it as fact. This includes invented citations, misquoted sources, outdated statistics presented as current, and conclusions that go beyond what the evidence actually supports. The challenge is that hallucinated content often reads as polished and credible, which is exactly what makes it risky in professional work. **How often do AI hallucinations happen in professional work?** More often than most professionals expect. Stanford testing found leading legal AI tools produced incorrect information between 17 and 34 percent of the time on challenging queries. A Neil Patel study found that nearly half of marketers encounter AI inaccuracies multiple times a week, and more than a third say hallucinated content has already made it to the public. Ivanti's 2026 AI Maturity Report found 68 percent of IT professionals have personally witnessed AI hallucinations with operational impact. **Who is responsible if AI output contains errors?** The professional who published or submitted it. The Thomson Reuters Future of Professionals Report found that nearly half of surveyed professionals say final responsibility for AI-assisted errors lies with the individual, not the tool. That makes independent verification before anything goes out more than a best practice. For lawyers especially, courts have sanctioned attorneys for submitting AI-generated briefs with fabricated citations, regardless of whether they knew the errors were there. **Can AI citations be wrong or made up?** Yes, and it happens regularly. AI models can generate citations that look legitimate but reference papers, cases, or sources that do not exist. As of mid-2026, one researcher tracking AI errors in legal filings has catalogued over 1,450 documented cases involving fabricated or hallucinated citations in court documents. The same risk applies to research papers, marketing whitepapers, and any professional content that relies on sourced claims. **How do I verify AI output for accuracy?** One of the more reliable approaches is a structured second-pass audit using a prompt built to challenge the original output rather than validate it. The prompt in this post instructs the AI to treat every claim as unverified, retrieve current information at time of review, and flag anything it cannot empirically confirm. Anything flagged as unverified is worth confirming independently before the work goes out. **Why does AI get facts wrong even when it sounds confident?** AI models are trained to predict what sounds plausible, not to verify what is true. They work from a fixed snapshot of the world that stops at a specific point in time, with no awareness of what has changed since. They cannot access real-time information unless connected to search tools, and they tend to pattern-match to familiar structures rather than confirm accuracy. The result can be output that reads as authoritative while containing errors that only a more targeted review would surface. **What is the difference between AI proofreading and an AI second-pass audit?** Proofreading typically catches grammar, spelling, and surface-level errors. A second-pass audit is a structured adversarial review covering source quality, expert consensus, professional and legal exposure, field positioning, and tone consistency. The difference is roughly the same as the difference between a spellcheck and a peer review. This prompt does the latter. **Should I review AI output before publishing or submitting it?** For work that gets cited, scrutinized, or acted upon, reviewing it before it goes out is worth doing. This prompt works best when the first draft is already in reasonably solid shape. Running it too early, on a half-formed draft, tends to produce a report on the wrong version of the work. **Can I use this on work I wrote myself without AI?** Yes. The prompt does not care how the first draft was produced. It only evaluates whether the output holds up under scrutiny. **Does this work with ChatGPT, Claude, Gemini, and other AI tools?** Generally yes. This prompt is written in plain instruction language and tends to work across capable frontier models. Results can vary slightly by model but the structure and intent carry across most of them. --- _The first output is where your AI shows you what it can do. The second pass is where you find out if it was right._ --- # Why Your Site Isn't Showing Up in ChatGPT, Claude, or Perplexity (Even With llms.txt) *Source: https://www.tristandenyer.com/work/why-ai-tools-cant-see-your-site* *Published: 2026-05-02* Good news: if AI tools can't read your site, it's likely a fixable infrastructure problem, not a content one. Here's how to diagnose and fix the four issues (CDN rules, WAF challenges, slow TTFB, and JavaScript shells) that keep ChatGPT, Claude, and Perplexity from citing you. So, your site has `llms.txt`. It has schema.org JSON-LD. It has clean `.md` routes and an `AGENTS.md`. And ChatGPT, Claude, and Perplexity still can't see it. The reason might not be your AI files. It's the heaps of technology in front of and powering your site, like a CDN, WAF, or slow origin server, causing the AI crawler to never reach your content. **TL;DR:** Four things block your AI visibility, in this order: 1. A CDN or WAF rule that blocks AI crawler user-agents (GPTBot, ClaudeBot, PerplexityBot) 2. CAPTCHAs or bot challenges on public content pages that AI crawlers can't pass 3. A slow origin server (TTFB over 1 second) that times out before AI crawlers give up 4. JavaScript-only rendering that returns an empty HTML shell to non-browser fetchers You can [run the AI Readiness Check](https://www.tristandenyer.com/ai-readiness-check) to see whether your site is reachable, fast enough, and serving real HTML to crawlers. For the full diagnosis (including the CDN and WAF audit it can't do for you), read on. Last week I shipped that tool and started running it against real sites. Sites I expected to score well, did not. Sites that had clearly invested in AI visibility, surprised me by returning a score of **F**. And I mean a LOT of sites. Not because they hadn't done the work. The problem was getting access to the AI files: the tool was getting 400s, 500s, JavaScript challenges, and request timeouts before it could see any of the work. ChatGPT, Claude, and Perplexity get similar treatment to what my scanner sees, since they share the same kind of HTTP fetch, no JavaScript execution, and no human-shaped fingerprint. The scanner won't catch every UA-specific block (those need direct testing, covered later in this post), but for performance issues and blanket challenges, what blocks one blocks them all. You can put the most beautifully crafted [`llms.txt`](https://www.tristandenyer.com/work/ai-files-for-websites-2026#llms-txt) on the internet behind a security rule that blocks AI crawlers, and to ChatGPT it doesn't exist. You can have a perfect schema.org graph with a complete set of `.md` routes, and if your origin server takes 4 seconds to send the first byte, GPTBot already gave up and moved on. This post is the companion to ["The Complete List of AI Files Your Website Needs in 2026"](https://www.tristandenyer.com/work/ai-files-for-websites-2026). That one was "what files to add." This one is "what's in front of those files preventing them from being read."
**A quick note on browsing agents.** A growing class of AI tools (ChatGPT Agent, Claude's Computer Use, Perplexity Comet, Gemini browsing) drive a real browser instead of making raw HTTP requests, so they can pass JavaScript challenges and some CAPTCHAs. But they're not what cites you in AI answers. The indexing and retrieval bots that do that are still HTTP fetchers. The rule of thumb holds: a CAPTCHA in front of public content blocks the traffic you most want for AEO (answer engine optimization).
## The 8 layers between an AI crawler and your content When an AI crawler makes a request to your site, the request can travel through up to eight independent layers before it ever touches your actual page content. Any one of them can slow it down, challenge it, or reject it outright: 1. **DNS resolution** (your registrar / DNS provider). 2. **The CDN edge** (Cloudflare, Fastly, Akamai, AWS CloudFront, Bunny, Vercel Edge, etc.). 3. **A WAF or bot management layer** (Cloudflare Bot Management, AWS WAF, Akamai Bot Manager, Imperva, DataDome, HUMAN/PerimeterX, Sucuri, etc.). 4. **A rate limiter** (often in the same stack). 5. **A challenge or CAPTCHA service** (Turnstile, reCAPTCHA, hCaptcha, vendor-specific JS challenges). 6. **Your origin's reverse proxy** (Nginx, Caddy, your hosting provider's edge). 7. **Application-level security** (Wordfence, Sucuri Security plugin, Cloudways/Kinsta firewall rules, custom middleware). 8. **The actual origin server** (what most consider their "website") with its own response time, render path, and database. Most site owners only know two or three of those eight layers well. The other five are usually defaults set by a hosting provider, a one-click WordPress installer, a "secure your site!" walkthrough from 2022, or a DevOps engineer who left the company. This is not an attack on any particular vendor or setup. The vendors are doing what their customers asked for: stop bots. They don't always know that _many AI crawlers are good bots_, and customers often don't know what defaults are running on their behalf. ## Does blocking AI bots hurt your Google rankings? **AI-specific bot rules generally should not hurt traditional SEO.** The dominant managed rules from major CDN/WAF vendors target AI user-agents (GPTBot, ClaudeBot, CCBot, Bytespider, etc.) and explicitly exclude verified search engines like Googlebot and Bingbot. Flipping those rules on doesn't directly tank your Google rankings. That part of the conventional wisdom is wrong, and worth correcting. What absolutely _does_ hurt SEO are the broader protections that often live in the same stack. "Under Attack" or interstitial JS challenge modes issue a multi-second JavaScript check to every visitor, and neither Googlebot nor AI crawlers can pass that kind of challenge. Aggressive WAF security presets like "High," "I'm Under Attack," or "Strict" have been reported to flag a meaningful share of legitimate Googlebot traffic as malicious, and browser integrity checks can block mobile Googlebot specifically since it doesn't always execute the same JS check the desktop crawler does. Rate limits configured by IP range can catch Googlebot too, since Google's crawl infrastructure operates from a relatively concentrated range of US IPs. Geo-IP blocking that excludes North America frequently catches Googlebot and almost every AI crawler in the same blast radius. And application-level firewalls (Wordfence, Sucuri, ModSecurity rule sets) often ship with rules that treat _any_ unusual user agent as suspicious. Then there's performance, which hits both SEO and AEO. Page speed and Core Web Vitals are confirmed Google ranking signals, so slow LCP and slow TTFB hurt your rankings even if every bot can technically reach you. AI crawlers are also far less patient than Googlebot. SEO and performance vendors consistently report timeouts in the 1 to 5 second range, with the page being abandoned if complete HTML hasn't been delivered in that window. The AI companies themselves don't publish exact thresholds, but the directional claim is well established: much shorter than Googlebot, and they don't retry. So, bot protection misconfigurations hurt SEO. Performance hurts both SEO and AEO. The AI-specific block hurts only AEO. Three different problems, three different fixes. ## Why your site isn't showing up in ChatGPT, Claude, or Perplexity answers In my experience running scans, four issues turn an A-grade site chock full of AI files into an empty box for ChatGPT, Claude, and Perplexity. In rough order of how often I see them, and how badly they hit: ### 1. Default-on AI bot blocking at your CDN or WAF **What it does:** A number of CDN/security platforms have rolled out one-click "block AI bots" rules over the past two years. [Cloudflare's managed rule](https://blog.cloudflare.com/declaring-your-aindependence-block-ai-bots-scrapers-and-crawlers-with-a-single-click) is the most visible example, but Fastly, Akamai, and others ship similar toggles. The mechanics vary, but the effect is the same: requests with user-agents like [`GPTBot`](https://platform.openai.com/docs/bots), `ClaudeBot`, `CCBot`, `Meta-ExternalAgent`, `Bytespider`, `Amazonbot`, and a long list of others get rejected at the edge, before robots.txt, before your origin, before anything else. Sometimes the rule is enabled by default for new accounts. Sometimes it gets enabled when an admin checks "yes, secure my site" during onboarding. **Why it's the biggest problem in 2026:** The economics are real and ugly. AI crawlers visit publisher sites constantly to gather content. The AI tools they feed answer users directly, so very few of those users ever click through to the publisher. Cloudflare and several large publishers have reported crawl-to-referral ratios in the thousands or tens of thousands to one. The vendors didn't add these toggles to be hostile; they added them because publishers were being crawled aggressively without seeing any of the traffic that would normally justify it. The blanket-block toggle is a reasonable response to that math _for the average publisher_. It's a terrible response if your business model depends on showing up in AI answers. **How to find it:** This is the layer most worth auditing first. The check is the same regardless of vendor: log into whatever sits in front of your origin and look for an "AI bots," "AI crawlers," or "AI scrapers" rule. This could be CDN/edge (Cloudflare, Fastly, Akamai, AWS CloudFront, Bunny, Vercel), dedicated bot management (DataDome, HUMAN, Imperva, Radware), and host-integrated security (WP Engine, Kinsta, Cloudways, Pantheon). If it exists, look at the per-bot table (most modern dashboards have one). Anything showing "Block" is invisible to that AI service. **The fix:** Don't blanket-allow or blanket-block. Split by purpose. The pattern most publishers should run is: | User-agent | Purpose | Recommended action | | ---------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------- | | `OAI-SearchBot`, `ChatGPT-User` | ChatGPT search index, real-time fetch | **Allow** | | `PerplexityBot`, `Perplexity-User` | Perplexity search and live answers | **Allow** | | `ClaudeBot`, `Claude-SearchBot`, `Claude-User` | Claude indexing and live fetch | **Allow** | | `Googlebot`, `Bingbot` | Traditional search (also feeds AI Overviews and ChatGPT/Bing) | **Allow** | | `GPTBot` | OpenAI training | Allow if you want max visibility, block if you want to opt out of training | | `CCBot` | Common Crawl, used to bootstrap many models | Block if you've already opted out of training | | `Google-Extended`, `Applebot-Extended` | AI training only, separate from search | Block if opted out of training (does not affect search) | | `Bytespider` | TikTok/ByteDance | Most publishers block; minimal upside | The point: there's no single right answer, but there is a wrong one. Flipping a master toggle to "block everything" without realizing the search and retrieval bots are in the same list as the training ones. ### 2. CAPTCHAs and bot challenges blocking AI crawlers on public pages **What they do:** Three classes of mechanism, all sharing the same failure mode for AI tools. They assume a real browser, real JavaScript execution, and a human-shaped fingerprint. AI crawlers have none of those. The first is heuristic bot-detection modes. Many WAFs and bot managers ship "fight mode" presets that challenge anything looking automated. Useful for credential stuffing. Catastrophic for legitimate AI crawlers, which by definition look automated. The second is "Under Attack" interstitials, designed for active DDoS situations. They issue a multi-second JS check to every visitor before letting them through. AI crawlers can't pass it. Googlebot can't pass it. Real users complain. If you ever turned this on for a bad night and forgot to turn it off, your AI visibility is currently zero. The third is CAPTCHA and challenge widgets in front of public content pages. Cloudflare Turnstile, Google reCAPTCHA, hCaptcha, DataDome. These are all solid products doing what they're built to do: detect non-browsers and non-humans. Putting them on a login form, a comment box, or a checkout page is exactly correct. Putting them in front of the body of a blog post, a product page, a docs page, or a `.md` route makes that content invisible to every AI tool, full stop. **Where bot challenges are fine:** in front of action endpoints, like POST handlers, sign-ups, comments, login. **Where they're not fine:** in front of GET requests for public content (such as requesting your web page, or a sitemap.xml file.) **The fix:** 1. Use bot challenges only on action endpoints, never on public GET routes. 2. If you must protect public pages, configure a "skip" or "allow" rule for verified bots that fires before any challenge. 3. Keep interstitial and "under attack" modes available for active incidents, but make sure they're off during normal operation. They're emergency tools, not steady-state defaults. 4. If you use a bot-fight or heuristic mode, scope it: exclude paths under `/blog/`, `/docs/`, `/articles/`, and so on. Verifying any of this is one curl command away, covered in the diagnosis section below. ### 3. Slow TTFB and server response times This is the blocker with the most surface area, because every site has a performance budget and many sites have spent it. **The numbers AI crawlers actually expect:** A caveat before the numbers is that AI companies themselves don't publish exact crawler thresholds. The figures here are the working consensus across SEO consultancies and crawler-monitoring vendors, who have converged on roughly the same numbers without much in the way of a primary source. Treat them as directionally right rather than authoritative, and tighten further if your traffic suggests it. The timeout window is most commonly cited at 1 to 5 seconds, with some sources putting the ceiling at 10. AI crawlers don't retry the way Googlebot does, so whatever you serve in that window is the only shot they take. For TTFB, reported recommendations range from 200ms (aggressive) to 800ms (the absolute ceiling); anything above 1 second is risky. HTML payload should stay under 1MB, since bigger pages risk truncation or being skipped entirely. And on Core Web Vitals, aim for LCP under 2.5s, CLS under 0.1, and a healthy INP. Those are confirmed Google ranking signals, so this isn't an AI-only concern. **What slows you down in practice:** Most often it's an origin on a cheap shared host with no edge caching, since a huge portion of the internet is set up that way to keep hosting costs down. Hosting in a region far from where AI crawlers make their requests (most operate out of US East) adds latency on top of that. Then there's the application layer: database-backed page generation with no caching layer, render-blocking JavaScript in the head, 4MB hero images served uncompressed, and "headless CMS" architectures with three serverless function hops between request and HTML. Any one of those will push you past the AI crawler timeout window. Stack two or three together and you're invisible. **The fix:** 1. Put a CDN in front of your origin. Plenty of free or inexpensive options solve the geographic problem alone. And this one change can make your human visitor's experience far better, as well! 2. Cache aggressively. AI crawler traffic is not personalized; everyone gets the same response. Cache it. 3. Compress everything (Brotli for HTML, AVIF/WebP for images, gzip for JSON). 4. Run `curl -w "%{time_starttransfer}\n" -o /dev/null -s https://yoursite.com/your-best-page`. If it returns more than 0.8 seconds, you have work to do. ### 4. JavaScript-only rendering (SPAs and CSR) **What it does:** If your site uses client-side rendering (React, Vue, or Angular SPA without SSR), Next.js app router with mostly client components and no caching, or Next.js pages router without `getServerSideProps`, the initial HTML response is a near-empty shell with a `
` and a script tag. The actual content materializes later, after the browser executes your bundle. Googlebot can deal with this, mainly, sometimes. Most AI crawlers cannot deal with it at all. The majority of AI crawlers do not render JavaScript and only see the raw HTML of a page, which means any critical content or navigation that depends on JS to load remains unseen. **How to spot the problem:** View source on one of your pages (Ctrl+U on Windows/Linux and Option+Command+U on macOS). If you see your article text in the raw HTML, you're fine. If you only see `
` and a bunch of script tags, that's what an AI crawler sees too. **The fix:** Server-side render or pre-render your public pages. - Next.js: use the `app/` router with server components, or `getServerSideProps` / `getStaticProps` in pages router. - Nuxt: SSR mode (the default). - React without a framework: introduce a pre-rendering layer (Prerender.io, react-snap) or migrate to Remix / Next.js. - Angular: Angular Universal. If migrating is too big a lift, a pre-rendering proxy like Prerender.io can sit in front of your origin and serve fully-rendered HTML to bots while leaving real users on the SPA. Not elegant, and certainly not my go-to, but it works. ### A note on robots.txt A common assumption is that `robots.txt` is where you control AI crawlers. It's not, or at least not the only place. Reputable AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Applebot-Extended, CCBot) do honor `robots.txt` directives, so it's a perfectly valid layer for opting out of training. But it's the polite layer. It's enforcement-by-trust. The CDN, WAF, and bot-management layers above your origin are the actual enforcement. If your `robots.txt` says "allow GPTBot" but Cloudflare's managed AI bot rule is on, GPTBot is still blocked. Always audit both layers, and treat the infrastructure layer as authoritative. ## How to test if AI crawlers can reach your site Here's the diagnostic flow I run when an AI Readiness Check comes back with a low score that doesn't match the work the owner clearly put in. ### Step 1: Curl as the actual AI bots What your origin sees is not what the edge sees. The fastest way to find out what GPTBot or ClaudeBot is getting is to pretend to be them. (Heads up: AI crawler user-agent strings drift over time as vendors release new versions. Check the [official bot docs](https://platform.openai.com/docs/bots) for the current version of each before relying on a long-running test.) ```bash # As GPTBot curl -A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.0; +https://openai.com/gptbot)" \ -I https://yoursite.com/your-best-page # As ClaudeBot curl -A "Mozilla/5.0 (compatible; ClaudeBot/1.0; +claudebot@anthropic.com)" \ -I https://yoursite.com/your-best-page # As PerplexityBot curl -A "Mozilla/5.0 (compatible; PerplexityBot/1.0; +https://docs.perplexity.ai/guides/bots)" \ -I https://yoursite.com/your-best-page ``` What you want to see: `HTTP/2 200`. What's bad: - `HTTP/2 403` → blocked outright. Likely a WAF or bot rule somewhere in the stack. - `HTTP/2 401` → some kind of auth wall in front of public content. - `HTTP/2 429` → rate limit. Whitelist verified bots. - `HTTP/2 503` with a challenge header → JS challenge or CAPTCHA. - A 200 response with the body containing "Just a moment..." or "Checking your browser" → JavaScript challenge that no AI crawler will pass. ### Step 1 alternative: Just ask the AI directly If you don't want to drop into a terminal, you can ask the AI tools themselves. Open ChatGPT, Claude, or Perplexity and try: ``` Fetch the URL [your-page] right now. Don't use cached content. Tell me whether the fetch succeeded, the page title, the first sentence of the main body, and whether you hit any challenge, redirect, or blocking page. ``` When this works, you'll get back a clean answer with content that matches your live page. When it fails, the AI will tell you, usually with a specific error like "I couldn't access that page" or "I received a blocking response." That failure is exactly what real users see when they try to ask the AI about your content. Two caveats: the tool may answer from cache (use a cache-busting query string like `?nocache=12345` to force a fresh fetch), and don't run this test in "agent" or "browse" mode since those drive a real browser and can pass challenges that the standard retrieval bots can't. ### Step 2: Time the response ```bash curl -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\nSize: %{size_download} bytes\n" \ -o /dev/null -s https://yoursite.com/your-best-page ``` Run this from a US server (e.g. a small DigitalOcean droplet in NYC) for the most realistic AI-crawler-shaped reading. If TTFB is over 800ms, AI crawlers are throwing your page back. ### Step 3: Check what's in the raw HTML ```bash curl -s https://yoursite.com/your-best-page | grep -c "your-actual-content-keyword" ``` Replace `your-actual-content-keyword` with a phrase that appears in your article body. If the count is zero, your content is JS-rendered and AI crawlers aren't seeing it. ### Step 4: Look at server logs by user agent Pull your last 30 days of access logs and grep for the AI user agents. If you see lots of GPTBot, ClaudeBot, and PerplexityBot hits with 200s, you're fine. If you see 403s, 503s, or nothing at all, you have a problem. Most CDN and bot-management dashboards will do this for you with a per-bot view if you go looking. Names vary, but the data is usually there. ### Step 5: Run the AI Readiness Check Once you've worked through the manual checks, run the [AI Readiness Check](https://www.tristandenyer.com/ai-readiness-check) to confirm what you found and catch anything you missed. It surfaces most of the above automatically: failed fetches, slow responses, JS-rendered shells, and blocked status codes, and it shows you which checks couldn't run because the site never returned content. If a check that should have passed is failing, the most common reason in 2026 is one of the four reasons above, not missing files. ## Should you allow or block AI crawlers? A decision framework Past the technical fixes, there's a deliberate decision to make. The blunt-force "block everything" defaults exist because the math is genuinely ugly for many publishers. You give crawlers your bandwidth and content for years, and they send back a click maybe once in a thousand requests. So what's the right strategy? It depends on what your site does. ### Should a personal blog or small business block AI crawlers? No. Your goal is visibility, not protection. The traffic an AI tool sends you is small but valuable, and (no offense) your content was never going to anchor anyone's training run. Allow search and retrieval bots. Decide on training bots based on principle. ### Should a publisher (news, magazine, recipe site) block AI crawlers? This is the hard case. Allowing search and retrieval keeps you in AI answers. Allowing training contributes to a system that may eventually replace clicks to your site entirely. My take (but you need to think about this): allow search and retrieval, block training, watch the data, and revisit quarterly. A growing middle path is to return `402 Payment Required` instead of `403 Forbidden` for training crawlers. That signals "here's how to license this" rather than just "no," and multiple infrastructure vendors are now building toward that pattern. ### Should an ecommerce or SaaS site block ChatGPT, Perplexity, or Claude? No. Do not block `ChatGPT-User`, `PerplexityBot`, or `Claude-User`. These are the bots that fetch your page when a user is _actively asking AI for a recommendation_. Blocking them is the digital equivalent of locking the front door during business hours. ### Should a docs site block AI crawlers? No, and arguably less so than anyone else. Be maximally open. Coding agents (Cursor, Claude Code, Codex) make many of their fetches as authenticated users via direct tool use, and being unreachable means being unused. This is the one category where I'd argue against any AI block at all. ## AI readiness fix checklist, ranked by impact | Priority | Fix | Where to look | Impact | | ------------ | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------- | | 🟢 Day 1 | Audit your edge / WAF / bot manager. Allow search and retrieval bots. | Whatever sits in front of your origin | Massive | | 🟢 Day 1 | Confirm "under attack" or full-site interstitial mode is only on during an active incident, not as a steady-state default | Top-level CDN/security dashboard | Massive | | 🟢 Day 1 | Curl your site as GPTBot, ClaudeBot, PerplexityBot. Confirm 200s. | Terminal | Diagnostic | | 🟡 Week 1 | Move CAPTCHAs and bot challenges off public GET routes; keep on POST/auth only | WAF / app-level rules | High | | 🟡 Week 1 | Verify Googlebot can pass your security stack | Google Search Console URL Inspection | High (SEO) | | 🟡 Week 1 | Get TTFB under 800ms (ideally 200ms) | Hosting + CDN + caching | High (SEO + AEO) | | 🟠 Month 1 | Server-side render any JS-only public pages | Framework migration | High | | 🟠 Month 1 | Compress HTML, defer non-critical JS, optimize images | Build pipeline | Medium | | 🔵 Quarterly | Review AI crawler traffic in server logs by user agent | Logs / vendor dashboard | Strategic | | 🔵 Ongoing | Re-run [AI Readiness Check](https://www.tristandenyer.com/ai-readiness-check) | tristandenyer.com | Strategic | --- # The Complete List of AI Files Your Website Needs in 2026 (llms.txt, ai.txt, AGENTS.md) with AI Prompts *Source: https://www.tristandenyer.com/work/ai-files-for-websites-2026* *Published: 2026-04-27* Every week brings another file the AI web supposedly needs. This post sorts what's adopted from what's noise, organized by what each file actually does, with prompts to generate every one of them. Every few years it seemed like a new file was needed to be added to a website for better SEO and better crawling. I remember it starting with `robots.txt`, then `sitemap.xml`, and `security.txt`. Now it seems like every week we have new files designed for AI crawlers, language models, and autonomous agents. It's getting hard to keep up, let alone know what's adopted, what's proposed, and what's actually useful. This post is the complete list (as of this week), organized by what each file actually _does_, with a copy-paste prompt at the end of each section so you can generate it for your website in minutes. **Who this is for:** ## A reality check before we start Most of the AI-specific files below are **emerging conventions, not proven standards**. Server log audits have found that major crawlers (GPTBot, ClaudeBot, PerplexityBot) don't fetch `llms.txt` or `.md` files unprompted. Google's John Mueller has said no AI system he's aware of currently uses `llms.txt`. So why bother? Three reasons: 1. **Humans like to paste URLs into AI tools as references, or for the AI to condense or explain them.** When someone drops your page into ChatGPT or Claude, these files make your content dramatically easier for the AI to work with. 2. **Coding agents like Cursor and Claude Code already fetch them.** If you have developer docs, this is a real distribution channel today. 3. **Cost is near zero. Upside is real.** Most of these take a few minutes to under an hour to implement. The web has a long history of early adoption paying off. For permission files (the "don't train on me" category), the story is different. Those carry legal weight in the EU under the Copyright in the Digital Single Market (CDSM) Directive, even if enforcement is spotty. I'll label each file's real-world status honestly so you can decide what's worth your time. ## Quick-start: if you only do three things 1. **Update your `robots.txt`** to handle AI crawlers explicitly. Jump to section ↓ 2. **Add an `llms.txt`.** It's a five-minute markdown file. Jump to section ↓ 3. **Make sure your key pages have `schema.org` JSON-LD structured data.** Jump to section ↓ If you're a developer, add a fourth: **`AGENTS.md`** in every repo you work on. Jump to section ↓
Not sure where you stand? Run the AI Readiness Check. It scans any URL for 19 signals, and returns a graded scorecard in a few seconds. No email or shenanigans.
## AI files vs. traditional web files: a quick comparison A lot of these files sound similar but do completely different things. Here's how the most-confused ones actually compare: | File | Category | What it controls | Honored today? | Where it lives | | ----------------- | ----------------------- | ----------------------------------------- | ------------------------------- | ------------------------------- | | `robots.txt` | Permission (crawling) | Whether bots can fetch your pages | ✅ Yes, all major AI crawlers | `yoursite.com/robots.txt` | | `sitemap.xml` | Discovery (traditional) | Which pages exist, for search indexing | ✅ Yes, search engines | `yoursite.com/sitemap.xml` | | `ai.txt` | Permission (training) | Whether your content can train AI models | ⚠️ Spawning network only | `yoursite.com/ai.txt` | | `tdmrep.json` | Permission (training) | TDM opt-out with EU legal weight | ✅ Legal standing in EU | `/.well-known/tdmrep.json` | | `llms.txt` | Visibility | Curated index of your best content for AI | ⚠️ When humans paste URLs | `yoursite.com/llms.txt` | | `llms-full.txt` | Visibility | Your entire site as one markdown blob | ⚠️ ChatGPT, coding agents | `yoursite.com/llms-full.txt` | | `schema.org` | Visibility (structured) | Machine-readable description of each page | ✅ Search and Copilot | `