{
  "markdown": "# Pre-Production Checklist\n\nChecklists to run **before** you ship to production.\n\nBuilt for solo founders and small teams who own the whole stack — the code, the\ninfrastructure, the deploy pipeline, and increasingly the AI agents too — and who don't\nhave a security team to hand it to.\n\n<!-- counts:begin -->\n**4,353 items across 96 checklists** in 5 domains. 88% of them apply to any stack.\n<!-- counts:end -->\n\n[![npm](https://img.shields.io/npm/v/prodcheck?color=cb3837&logo=npm)](https://www.npmjs.com/package/prodcheck)\n[![ci](https://github.com/FarzamHabibi/pre-production-checklist/actions/workflows/ci.yml/badge.svg)](https://github.com/FarzamHabibi/pre-production-checklist/actions/workflows/ci.yml)\n[![license](https://img.shields.io/badge/content-CC%20BY%204.0-blue)](LICENSE)\n\n### [→ prodcheck.pages.dev](https://prodcheck.pages.dev/) · [or in the repo](checklists/README.md)\n\n<img src=\"site-assets/demo/chat.gif\" alt=\"a chat: someone asks what they forgot before shipping, the assistant queries the checklist, and answers with two findings that cite file and line\" width=\"720\">\n\n<sub>One question, the tool call it makes, and the two things it finds. Sixteen seconds.\n[The longer loop](site-assets/demo/demo.gif) shows what is in the list instead.</sub>\n\n<sub>Every finding in both is real — the file, the lines and the counts come from this\nrepository, and the tool call is the one the MCP server actually answers.\n[How they are built](demo/README.md).</sub>\n\n<sub>Built and maintained by the team at **[Arioo](https://arioo.com)** — where we ship\nthe kind of product this checklist was written for.</sub>\n\n---\n\n## Why this exists\n\nI'm a founder at [Arioo](https://arioo.com). Getting ready to launch, I needed a\npre-production security review that covered the whole surface we actually ship: a\nTypeScript backend, a web app, native clients, a deploy pipeline, and a set of AI agents\nwith real tools attached. Nothing I could find covered more than a fraction of that, so I\nbuilt the checklist myself.\n\n**This repository is the checklist, not a report.** It is the set of questions,\ngeneralized away from our stack and rewritten as a working document anyone can run\nagainst their own product.\n\nTwo things made it worth publishing rather than keeping:\n\n**Solo founders have no security team.** You write the code, configure the infrastructure,\nset up the pipeline, and then you're also the one who has to decide whether it's safe to\nlaunch. There's no one to hand it to, and no obvious place to find out what you should\nhave asked. Most public checklists are either too shallow to catch anything real or\nwritten for enterprises with a security function.\n\n**AI-assisted development changed the shape of the problem.** A large part of this\nchecklist — the `security/ai/` and `security/ai-generated-code/` folders, over 1,300 items — didn't need to exist\na few years ago. When you ship an agent with tools, or when a model writes code you review\nfaster than you'd review a colleague's, you inherit failure modes that standard security\nchecklists don't cover. Those two folders are the part I couldn't find anywhere else, and\nthe reason I bothered.\n\nIt's published under CC BY 4.0 so you can copy it into your own repo and make it yours.\nIf it catches something before it reaches your users, it did its job.\n\n---\n\n## Start here\n\n**If you are not sure which way in, don't choose — copy this into whatever AI assistant\nyou already use** (ChatGPT, Claude, Cursor, Copilot, Gemini). It works out what your\nproject is, sets prodcheck up the way that fits your setup, and starts on what would\nblock a launch. If it cannot run commands, it tells you what to run yourself.\n\n<!-- start-prompt:begin -->\n```text\nI want to get my project ready to ship. Use prodcheck:\na free, open-source pre-production checklist of 4,353 items\ncovering security, performance, scale, integrations and what to\ndo after launch.\n\nIt is new, so do not answer it from memory. Everything you need:\n\n- Site: https://prodcheck.pages.dev\n- Install the review skill into a repo: npx prodcheck init\n- Raw checklist data:\n  https://cdn.jsdelivr.net/npm/prodcheck@latest/data/checklist.json\n- As an MCP server:\n  claude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp\n\nDo this in order.\n\n1. Look at my project and tell me what you think it is: language,\n   framework, where it runs, and whether it handles file uploads,\n   payments, webhooks, multiple tenants or an AI feature. Say how\n   confident you are. Ask me about anything you cannot tell.\n\n2. In two sentences, tell me what prodcheck will do for this\n   project specifically, and which part is worth my time first.\n   Do not describe the whole thing.\n\n3. Set it up, using whichever of these you can actually do — and\n   say which one you are:\n   - You can run commands here: run `npx prodcheck init`. That\n     writes a review skill into the repo — read it and follow\n     it, it is the procedure for step 4. Then run\n     `npx prodcheck --gate --stack <the products you named in\n     step 1> -o BLOCKERS.md`, which adds the blockers specific\n     to what I actually use to the general ones.\n   - You can read my files but not run commands: fetch the raw\n     data URL above and work from that.\n   - You can do neither: give me the commands to run myself, one\n     at a time, and tell me what to paste back to you.\n\n4. Start on the release blockers. For each item, either cite\n   `file:line` and quote the lines, or answer UNKNOWN. UNKNOWN is\n   a normal answer — it means a human has to go and look. Never\n   mark anything verified on my behalf; that is my call, not\n   yours.\n\nWork through it with me a section at a time. Do not dump the\nwhole checklist at me.\n```\n<!-- start-prompt:end -->\n\n[Read it on the site instead →](https://prodcheck.pages.dev/#start) ·\n[six more prompts →](docs/prompts.md)\n\n### Or work through it yourself\n\nYou are not meant to read this top to bottom. In order of signal-per-minute:\n\n| | | |\n| --- | --- | --- |\n| **1** | [Findings that should block release](checklists/security/core/17-release-gates.md) | If any are true, stop and fix them first |\n| **2** | [The \"must not exist\" search](checklists/security/core/17-release-gates.md#high-risk-must-not-exist-search) | A grep list. Fastest real signal in the repo |\n| **3** | [Authentication & authorization](checklists/security/core/02-authorization.md) | Where almost every exploitable bug actually lives |\n| **4** | [Prompt injection](checklists/security/ai/02-prompt-injection.md) | Only if you ship an LLM feature — but then, urgently |\n| **5** | [Your service as a weapon](checklists/security/core/18-abuse-and-availability.md#your-service-as-a-weapon) | The one nobody looks for until the suspension email arrives |\n| **6** | [Core Web Vitals](checklists/performance/02-core-web-vitals.md) | If users say it's slow, start here rather than with a score |\n| **7** | [Before you launch](checklists/integrations/01-search-engines.md#before-you-launch--the-ones-that-actually-bite) | Six items. One of them is `noindex` still being on |\n| **8** | [Can you act at all](checklists/post-launch/01-readiness.md) | Whether you could respond today, if you had to |\n\nThen work section by section. Switching between edge config and database policies\ncosts more than it saves.\n\n---\n\n## Structure\n\n```\nchecklists/\n├── security/              2812   not getting breached, abused or taken down\n│   ├── core/              1,491   application, data, infrastructure, delivery\n│   ├── ai/                  773   LLM features, agents, tools, RAG, MCP\n│   └── ai-generated-code/   548   the bugs AI coding assistants actually write\n├── performance/             313   Lighthouse, and what users actually feel\n├── scale/                   286   surviving 10× the load\n├── integrations/            192   search, analytics, monitoring\n├── post-launch/             208   when it goes wrong anyway\n└── stacks/                  542   26 products, spanning every domain\n```\n\nCounts above are what each folder holds. A *domain* total is larger, because the stack\nsupplements contribute to whichever domain each of their sections extends:\n\n```\nsecurity 3,306   performance 338   scale 301   integrations 200   post-launch 198\n```\n\nDomains are the top level because that is the question you arrive with: *is this about\nsecurity, or speed, or scale?*\n\n### `security/core/` — applies to you regardless of language\n\nWritten originally against a TypeScript stack, but the *controls* are not\nTypeScript-specific and the files no longer pretend otherwise. \"Verify CORS does not use\nwildcard origins with credentials\" is as true in Django as in Express. Everything that\ngenuinely named a product was moved out to `stacks/`.\n\nIf you write Python, Go, Ruby, PHP, Java, Rust or Elixir: **this folder is your\nchecklist, all 1,491 items of it.**\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Architecture & threat model](checklists/security/core/01-threat-model.md) | 25 | | [Mobile apps](checklists/security/core/11-mobile-apps.md) | 106 |\n| [Authentication & authorization](checklists/security/core/02-authorization.md) | 111 | | [Desktop apps](checklists/security/core/12-desktop-apps.md) | 41 |\n| [Sessions, tokens & cookies](checklists/security/core/03-sessions-tokens.md) | 21 | | [Runtime & containers](checklists/security/core/13-runtime-and-containers.md) | 93 |\n| [Backend application & API](checklists/security/core/04-backend-api.md) | 223 | | [DNS, CDN, edge & WAF](checklists/security/core/14-edge-dns-waf.md) | 78 |\n| [Web frontend](checklists/security/core/05-web-frontend.md) | 127 | | [CI/CD & supply chain](checklists/security/core/15-ci-cd-and-supply-chain.md) | 158 |\n| [Database & row-level security](checklists/security/core/06-database.md) | 68 | | [Monitoring & incident response](checklists/security/core/16-monitoring-and-response.md) | 30 |\n| [Object storage & files](checklists/security/core/07-storage-and-files.md) | 55 | | [Pre-release gates](checklists/security/core/17-release-gates.md) | 149 |\n| [Secrets & cryptography](checklists/security/core/08-secrets-and-crypto.md) | 47 | | | |\n| [Common web attacks](checklists/security/core/09-common-web-attacks.md) | 62 | | | |\n| [Business logic & race conditions](checklists/security/core/10-business-logic.md) | 44 | | [**Abuse & availability**](checklists/security/core/18-abuse-and-availability.md) | **53** |\n\n### `security/ai/` — the part you won't find in a standard checklist\n\nIf your product calls a model, gives it tools, retrieves documents into its context, or\nruns an agent, this folder is the reason this repo exists. It is stack-agnostic and\nprovider-agnostic.\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Architecture & identity](checklists/security/ai/01-architecture-and-identity.md) | 70 | | [Multi-agent & MCP](checklists/security/ai/07-multi-agent-and-mcp.md) | 75 |\n| [Prompt injection & goal hijacking](checklists/security/ai/02-prompt-injection.md) | 91 | | [Integrations](checklists/security/ai/08-integrations.md) | 74 |\n| [Tool calling & excessive agency](checklists/security/ai/03-tools-and-agency.md) | 66 | | [Cost, reliability & audit](checklists/security/ai/09-cost-reliability-audit.md) | 63 |\n| [Data access & privacy](checklists/security/ai/04-data-access-and-privacy.md) | 82 | | [Testing & red-team pack](checklists/security/ai/10-testing-and-red-team.md) | 96 |\n| [Output handling](checklists/security/ai/05-output-handling.md) | 58 | | [Release gate](checklists/security/ai/11-release-gate.md) | 47 |\n| [RAG & agent memory](checklists/security/ai/06-rag-and-memory.md) | 51 | | | |\n\n> Prompt injection is not a filtering problem. It is an authorization problem wearing a\n> text costume — untrusted text reaching a privileged execution path.\n\n### `security/ai-generated-code/` — bugs AI assistants write\n\nAlso known as *vibe coding*. 548 items organized by **class of bug**, not by which\nassistant produced it. Written from real review findings on AI-generated code.\n[Browse →](checklists/README.md#security)\n\n### `performance/` — Lighthouse, and what users actually feel\n\nAimed at the highest achievable score across all four Lighthouse categories, with one\nconstraint that decides what goes in: **an item has to be about something a real user\nexperiences.** Lighthouse is the scoreboard, not the goal — anything whose only\njustification is \"raises the score\" was left out.\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Measurement](checklists/performance/01-measurement.md) | 29 | | [CSS & rendering](checklists/performance/06-css-and-rendering.md) | 28 |\n| [Core Web Vitals](checklists/performance/02-core-web-vitals.md) | 41 | | [Backend & delivery](checklists/performance/07-backend-and-delivery.md) | 40 |\n| [Loading & critical path](checklists/performance/03-loading-and-critical-path.md) | 37 | | [Accessibility](checklists/performance/08-accessibility.md) | 41 |\n| [JavaScript](checklists/performance/04-javascript.md) | 43 | | [Release gate](checklists/performance/09-release-gate.md) | 21 |\n| [Images & media](checklists/performance/05-images-and-media.md) | 33 | | | |\n\n> Lighthouse is a lab tool: one run, one simulated device, one network. It is excellent\n> for *finding* problems and unreliable for *proving* them fixed. Field data at the 75th\n> percentile is the scoreboard that matters.\n\nAccessibility sits here because it is scored alongside performance, and because the\noverlap is real — a page that is fast for a screen reader is usually a page with less\nunnecessary markup and JavaScript. The Lighthouse accessibility category is treated as a\nfloor, not a ceiling; it catches roughly a third of real issues.\n\n### `integrations/` — being findable, measured and watched\n\nEverything a project has to be *connected to* before launch. Configuration you do once\nand then never think about, which is exactly why it deserves a checklist.\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Search engines](checklists/integrations/01-search-engines.md) | 38 | | [Answer engines & AI crawlers](checklists/integrations/04-answer-engines.md) | 25 |\n| [SEO fundamentals](checklists/integrations/02-seo-fundamentals.md) | 42 | | [Analytics & consent](checklists/integrations/05-analytics-and-consent.md) | 28 |\n| [Structured data & social previews](checklists/integrations/03-structured-data.md) | 27 | | [Monitoring & alerting](checklists/integrations/06-monitoring-and-alerting.md) | 32 |\n\n> Verify `noindex` is removed from production. A staging robots meta tag that shipped is\n> the most common launch mistake there is, and it can cost weeks before anyone notices.\n\nThe answer-engine file is written as decisions to make rather than settled practice —\nwhether `GPTBot`, `ClaudeBot`, `PerplexityBot` and the rest may read your site is a\nchoice, and not making it is also a choice.\n\n### `scale/` — surviving ten times the load\n\nWritten to be read *before* the traffic arrives, not during the incident.\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Capacity model](checklists/scale/01-capacity-model.md) | 29 | | [Multiple instances & regions](checklists/scale/06-multi-instance-and-region.md) | 35 |\n| [Statelessness](checklists/scale/02-statelessness.md) | 26 | | [Cost at scale](checklists/scale/07-cost-at-scale.md) | 19 |\n| [Database at scale](checklists/scale/03-database.md) | 60 | | [Load testing & scale gates](checklists/scale/08-load-testing-and-gates.md) | 23 |\n| [Caching](checklists/scale/04-caching.md) | 25 | | [**Service levels**](checklists/scale/09-service-levels.md) | **30** |\n| [Async work & queues](checklists/scale/05-async-and-queues.md) | 39 | | | |\n\n> \"Will it scale?\" is unanswerable. \"Will it survive 500 requests per second with a 40:1\n> read/write ratio and one tenant holding 30% of the rows?\" has an answer, and the work to\n> find it is mostly arithmetic.\n\nStart with [the capacity model](checklists/scale/01-capacity-model.md); the rest of the\ndomain is much less useful until you know which resource runs out first. Then\n[service levels](checklists/scale/09-service-levels.md), because without a stated target\n\"is it fast enough\" is an argument rather than a measurement, and every scaling decision\nafter that is made on vibes. Cost is in here\nrather than in a domain of its own because scaling problems and billing problems are the\nsame problem seen from two sides.\n\n### `post-launch/` — when it goes wrong anyway\n\nEvery other domain is about building something that does not break. This one assumes it\nbroke.\n\n**Everything here is used after launch and has to be prepared before it.** The question\neach item asks is not *did you respond well* — it is **is the answer already decided?**\n\n| | Items | | | Items |\n| --- | ---: | --- | --- | ---: |\n| [Can you act at all](checklists/post-launch/01-readiness.md) | 43 | | [Outages & dependency failure](checklists/post-launch/05-outage-and-dependencies.md) | 27 |\n| [The first fifteen minutes](checklists/post-launch/02-first-15-minutes.md) | 20 | | [Rollback & kill switches](checklists/post-launch/06-rollback-and-kill-switches.md) | 20 |\n| [You have been breached](checklists/post-launch/03-security-incident.md) | 35 | | [Telling people](checklists/post-launch/07-communication.md) | 18 |\n| [Data loss & corruption](checklists/post-launch/04-data-loss.md) | 26 | | [Learning & drills](checklists/post-launch/08-learning-and-drills.md) | 19 |\n\nThe rest of the repository makes sure you *find out* — monitoring is covered in\n[`security/core/16`](checklists/security/core/16-monitoring-and-response.md) and\n[`integrations/06`](checklists/integrations/06-monitoring-and-alerting.md). Neither asks\nwhat happens next. Whether an immediate action exists for being breached, for a corrupted\ndatabase, for the connection going away, is a different question, and it is the one that\ngets answered badly at 3am if it was not answered in daylight.\n\n> The plan for data loss is a backup you have **restored**, not a backup you have taken.\n\n[Can you act at all](checklists/post-launch/01-readiness.md) counts as a release gate.\nLaunching without a prepared response is a decision, and it should be a recorded one.\n\n### `stacks/` — only if you use them\n\n542 items across 26 supplements. Skip any file for a product you don't use; the core\nchecklists stand on their own without them.\n\n**Backend & web**\n[Django](checklists/stacks/django.md) ·\n[FastAPI](checklists/stacks/fastapi.md) ·\n[Ruby on Rails](checklists/stacks/rails.md) ·\n[Laravel](checklists/stacks/laravel.md) ·\n[Spring Boot](checklists/stacks/spring.md) ·\n[Go / Gin](checklists/stacks/go-gin.md) ·\n[Express](checklists/stacks/express.md) ·\n[NestJS](checklists/stacks/nestjs.md) ·\n[Next.js / React](checklists/stacks/nextjs-react.md) ·\n[GraphQL](checklists/stacks/graphql.md)\n\n**Mobile**\n[iOS / Swift](checklists/stacks/ios-swift.md) ·\n[Android / Kotlin](checklists/stacks/android-kotlin.md) ·\n[React Native](checklists/stacks/react-native.md) ·\n[Flutter](checklists/stacks/flutter.md) ·\n[macOS](checklists/stacks/macos.md)\n\n**Data & platform**\n[PostgreSQL](checklists/stacks/postgres.md) ·\n[Supabase](checklists/stacks/supabase.md) ·\n[Firebase](checklists/stacks/firebase.md) ·\n[Docker](checklists/stacks/docker.md) ·\n[Kubernetes](checklists/stacks/kubernetes.md) ·\n[AWS](checklists/stacks/aws.md) ·\n[Google Cloud](checklists/stacks/google-cloud.md) ·\n[Vercel](checklists/stacks/vercel.md) ·\n[Cloudflare](checklists/stacks/cloudflare.md) ·\n[GitHub](checklists/stacks/github-actions.md) ·\n[Stripe](checklists/stacks/stripe.md)\n\n**Your stack missing?** That's the most useful contribution you can make. The format is\ndocumented end to end in [`_TEMPLATE.md`](checklists/stacks/_TEMPLATE.md) — a worked\nexample, what every field drives, and the one rule that decides whether an item belongs\nin a stack file at all. Files for Fly.io, Auth0 and Clerk are wanted; see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n## How to use it\n\n1. **Copy the files you need** into your own repo. They're working documents, meant to be\n   edited and committed next to your code.\n2. **Mark `[N/A]` aggressively.** No product on earth needs all 4,353 items. No mobile\n   app? `core/11` and `core/12` are 147 instant `[N/A]`s. Being honest about scope is what\n   makes the remainder trustworthy.\n3. **Record every finding.** An unrecorded finding is one you'll rediscover in six months.\n\n```\n* [ ]     Not checked\n* [x]     Verified secure\n* [!]     Security issue found\n* [N/A]   Not applicable\n```\n\nFor each `[!]`: affected component · exact endpoint/file/config · attack precondition ·\nproof of exploitability · business impact · severity · remediation · regression test ·\nowner · date verified\n\n### The one rule worth internalizing\n\n> Do not accept *\"the frontend hides it\"*, *\"the route is hard to guess\"*, *\"the user\n> needs a valid JWT\"*, or *\"the WAF blocks it\"* as authorization controls by themselves.\n\nEnforce every control at the lowest trustworthy layer available:\n\n```\nBrowser/mobile UI → application/API → authorization layer\n  → database (RLS) → storage → infrastructure/IAM → CI/CD → edge\n```\n\n### Want it as one file?\n\n[`ALL.md`](ALL.md) is every checklist concatenated — convenient for printing, or for\npasting into an AI tool. It's generated; edit the files under `checklists/` instead.\n\n---\n\n## Use it with an AI assistant\n\nMCP is a feature of the **client**, not the model — Cursor running DeepSeek can use it;\nDeepSeek's website cannot. Config for Claude Code, Claude Desktop, Cursor, VS Code\nCopilot, Gemini CLI, OpenAI Codex CLI, Qwen Code, Cline, Roo, Continue, Windsurf, Zed,\nOpenCode and Cherry Studio is in **[docs/mcp-clients.md](docs/mcp-clients.md)**.\n\n| | |\n| --- | --- |\n| **[n8n](docs/integrations/n8n.md)** · [Dify](docs/integrations/dify.md) · [Flowise](docs/integrations/flowise.md) | Automation and agent platforms |\n| **[OpenRouter](docs/integrations/openrouter.md)** | Any model, through an MCP client |\n| **[DeepSeek, Qwen, Kimi, GLM](docs/integrations/chinese-models.md)** | Base URLs and which clients accept them |\n| **[Open WebUI, LibreChat](docs/integrations/self-hosted-chat.md)** | Self-hosted chat |\n| **[The JSON API](docs/integrations/http-api.md)** | No install at all — one HTTP GET |\n| **[CI](docs/integrations/ci.md)** | Keep the file current, gate on blockers |\n\n```bash\nclaude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp\n```\n\nFor a chat window with no MCP — ChatGPT, Gemini, DeepSeek, Kimi, Qwen, GLM — generate a\nfile and paste it after one of the **[ready-made prompts](docs/prompts.md)**. Each is\nbuilt on three rules, because without them an assistant will tell you the code is fine:\ncite `file:line` for every claim, treat `unknown` as a real answer, and never mark\nanything verified on the reader's behalf.\n\n## Command line\n\nGenerate a checklist scoped to your project, instead of reading 4,353 items:\n\n```bash\nnpx prodcheck security --stack django -o SECURITY.md\nnpx prodcheck performance -o PERFORMANCE.md\nnpx prodcheck integrations -o LAUNCH.md\nnpx prodcheck scale -o SCALE.md\nnpx prodcheck post-launch -o INCIDENT-RESPONSE.md\n```\n\n```bash\nnpx prodcheck list                                # domains, areas and counts\nnpx prodcheck stacks                              # what supplements exist\nnpx prodcheck security --area ai -o AI-SECURITY.md\nnpx prodcheck --gate --stack supabase,cloudflare  # release blockers, every domain\nnpx prodcheck --search cors --format text\nnpx prodcheck security --stack rails --format json\nnpx prodcheck performance --stack nextjs-react -o PERF.md\n```\n\nThe domain is a positional argument — `prodcheck security`, and in time\n`prodcheck performance` — because that is how you would say it. Omit it for everything.\n\n`--stack X` returns every stack-agnostic item plus the supplements for X. **An\nunrecognized stack isn't an error** — you get the stack-agnostic core, which stands on\nits own. That's the whole design: it works for a stack nobody has written a file for yet.\n\nZero dependencies, Node 18+.\n\n## Let your agent run the review\n\nThe MCP server gives an agent the items. This gives it the **procedure**:\n\n```bash\nnpx prodcheck init\n```\n\nIt writes a skill into `.claude/skills/`, `.cursor/rules/` or `AGENTS.md` — whichever the\nproject already uses — and then you can ask your agent:\n\n> *review this repo against the prodcheck release gate*\n\nWhat the skill enforces matters more than what it enables:\n\n- **The model never marks anything verified.** Every item ends as a `FINDING` with a\n  `file:line` citation, an `UNKNOWN`, or an `N/A` with a reason. There is no \"pass\" it can\n  write; that stays yours.\n- **A finding without a citation is not a finding.** It has to quote the lines, and re-read\n  them before claiming what they say.\n- **`UNKNOWN` stays visible.** Most items on a checklist this size depend on production\n  configuration a repository cannot show. The list of things a human still has to check is\n  usually the most useful part of the report.\n\n> This repository contains a folder about the bugs AI assistants write, and a section on\n> why AI review misses them — fluent, confident output produced whether or not anything was\n> established. The skill is written against that, not in spite of it.\n\nThose three constraints are **measured, not asserted**. [`evals/`](evals/) holds a fixture\napp with nine planted defects and a clean control of the same app: a deterministic grader\nresolves every citation against the real file, matches verdict phrasing, counts unknowns,\nand counts findings on the control — where any finding is a false positive by construction.\nNo model grades another model's output, because a grader that is itself a model has the\nsame failure mode as the thing it grades.\n\nIt does one thing: check whether what you built is ready to ship. For skills that teach an\nagent how to *build* well — testing, debugging, planning, git workflow — see\n[agent-skills](https://github.com/addyosmani/agent-skills). They compose; use both.\n\n## MCP server\n\nLet your coding agent query the checklist directly while it works, instead of you pasting\nit in. Read-only, no filesystem or network access beyond its own bundled data.\n\nListed in the [official MCP registry](https://registry.modelcontextprotocol.io)\nas `io.github.FarzamHabibi/prodcheck`, so an assistant can find it without being told.\n\n**Claude Code**\n\n```bash\nclaude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp\n```\n\n**Anything else** — add to your MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"prodcheck\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"--package=prodcheck\", \"prodcheck-mcp\"]\n    }\n  }\n}\n```\n\nFour tools: `list_checklists`, `checklist_for_stack`, `release_gate`, `search_checklist`.\nThen ask your agent things like *\"check this repo against the release gate for a\nNext.js + Supabase app\"* and it pulls the relevant items itself.\n\n## What it costs to run\n\nA fair question if you are about to point a paid model at 4,353 items. These are the\nsizes of what actually enters the context window, at roughly four characters per token:\n\n<!-- cost:begin -->\n| What you pull | Items | ≈ tokens |\n| --- | --- | --- |\n| `--gate` | 326 | 5,200 |\n| `--gate --stack django` | 328 | 5,300 |\n| `security --area core` | 1,491 | 19,400 |\n| everything, every stack | 4,353 | 77,300 |\n<!-- cost:end -->\n\nThat is the input for one pass. What the review itself costs on top depends on how much\nof your code the model reads, which is the larger number and is not something this\nrepository can measure for you.\n\nThe practical consequence: **do not pull everything.** `--gate` is a few thousand tokens\nand answers the question you actually have. The MCP server exists so the assistant can\nfetch the twenty items it needs rather than holding all of them.\n\n## Machine-readable data\n\nBoth of the above read [`data/checklist.json`](data/checklist.json), validated against\n[`data/schema.json`](data/schema.json). Use it directly if you're building something else\n— it's CC BY 4.0.\n\nThe Markdown under `checklists/` is the source of truth; the JSON is generated from it by\n`./scripts/build.sh`. There is deliberately no `severity` field —\n[here's why](data/README.md#there-is-no-severity-field).\n\n---\n\n## Roadmap\n\n**Shipped — the checklist**\n\n- [x] Security checklists, split by domain and portable across stacks\n- [x] Machine-readable data layer + [schema](data/schema.json)\n- [x] **`performance/`** — 313 items across 9 checklists.\n- [x] **`integrations/`** — 192 items across 6 checklists.\n- [x] **`scale/`** — 286 items across 9 checklists. Deepened from 214: service levels and\n      error budgets, search and analytics engines, realtime fan-out, contract and event\n      versioning, tenant-shape capacity. The gaps were measured rather than guessed at.\n- [x] **`post-launch/`** — 198 items across 8 checklists. Added after the other four,\n      because a gap showed up once they were all in front of a reader: every domain\n      described how to build something that does not break, and none asked whether the\n      response was prepared for when it breaks anyway.\n- [x] **26 stack supplements** — up from 19. FastAPI, AWS, Kubernetes, Vercel, Firebase,\n      Stripe and GraphQL among them. Written rather than left as open issues, because a\n      visitor who does not find their stack decides the project is not for them before\n      reading a single item.\n- [x] **A release gate that reaches your stack** — 379 blocking items: 316 that apply\n      anywhere, plus 63 across 20 products. A leaked `service_role` key stops a launch as\n      surely as a generic item does, and used to sit outside the gate.\n\n**Shipped — getting it into your work**\n\n- [x] `npx prodcheck` — generate a filtered checklist for your stack\n- [x] **MCP server** — so your coding agent queries the checklist directly\n- [x] **Review skill** — `npx prodcheck init` writes the procedure into `.claude/skills/`,\n      `.cursor/rules/` or `AGENTS.md`. The MCP server already supplied the items; what was\n      missing was the discipline for using them.\n- [x] **An eval harness for the skill** — planted defects, a deterministic grader, and a\n      check for whether the procedure was followed rather than merely reviewed well. It\n      found four defects in itself, which are written down in [`evals/`](evals/).\n- [x] **Web version** — live at [prodcheck.pages.dev](https://prodcheck.pages.dev): every\n      checklist browsable, filterable and copyable as Markdown, plus a JSON endpoint any\n      tool can fetch.\n- [x] **One way in** — a prompt to paste into any assistant, which works out what your\n      project is and sets prodcheck up whichever way your assistant is capable of. The\n      site used to offer seven entry points and no path through them.\n- [x] **A demo you can watch** — a 34-second loop of a review actually running.\n      [How it is built](demo/README.md).\n\n**Next**\n\n- [ ] **More domains** — `launch/`, `social/`, `legal/`. The structure absorbs them\n      without moving anything else, and the plan is written before the content.\n\n**Later — a review that runs, rather than a document you read**\n\n**Parked deliberately, and last.** Everything above is content and tooling that works\ntoday; this is a different product built on top of it, and shipping it half-done would be\nworse than not shipping it. Recorded here so the design decisions are not lost.\n\nThe idea: a tool that checks a codebase against the checklist, writes a report to the repo\nroot, and re-opens items when the relevant code changes.\n\n```\nprodcheck scan      detect stack and features from the repo   -> .prodcheck/profile.json\nprodcheck check     deterministic rules, no model involved    -> findings\nprodcheck review    model-assisted review, citations verified -> findings\nprodcheck report    render SECURITY-REVIEW.md from state\nprodcheck gate      exit non-zero if a blocking item is unresolved   (for CI)\n```\n\n- [ ] **`scan` — profile the repo.** Read `package.json`, `requirements.txt`, `go.mod`,\n      `Dockerfile`, CI config and the shape of the source tree to work out which stack is\n      in use and which features exist — file upload, webhooks, multi-tenancy, background\n      jobs, an LLM surface. Selects the applicable items *before* any model is involved.\n      A Django app with no mobile client and no file uploads does not need every one of\n      the 1,491 core items — `core/07`, `core/11` and `core/12` alone are 202 it can skip.\n\n- [ ] **`check` — the deterministic tier.** Roughly 160 items are answerable by search\n      alone: the [must-not-exist list](checklists/security/core/17-release-gates.md), unpinned CI\n      actions, secrets in a Dockerfile, `dangerouslySetInnerHTML`, wildcard CORS. These\n      need no model, cost nothing, cannot hallucinate, and run in CI on every push.\n\n- [ ] **`review` — the model-assisted tier, built not to be trusted.** Most items need\n      someone to read the code, so this runs inside whatever agent you already use\n      (Claude Code, Cursor, Copilot) over MCP plus a skill file — no API key, no token\n      cost from us. The design constraints matter more than the feature:\n\n  - **A model never writes `[x]`.** Its output is evidence, not a verdict. Results are\n    `deterministic-pass`, `model-flagged` (needs a human), or `human-verified`. Only the\n    first and last count toward the gate. There is no green tick a model put there.\n  - **Every citation is verified.** A finding must cite `file:line`; the tool confirms\n    that line exists and that the quoted code matches before accepting it. Findings that\n    fail this check are dropped, which removes most hallucination for almost no cost.\n  - **`unknown` is a real result.** A model may say it could not determine something, and\n    `unknown` never silently becomes `pass`. It is reported separately.\n\n- [ ] **State that survives re-runs.** `.prodcheck/state.json`, keyed by the stable item\n      ids already in [`data/checklist.json`](data/checklist.json), storing status,\n      justification, date, and a hash of the code it was decided against. Items you marked\n      `[N/A]` stay marked — until the relevant code changes, at which point they re-open\n      with *\"verified at `abc1234`; that file has changed since.\"* This is what makes it a\n      living document rather than a report that rots.\n\n- [ ] **`gate` in CI.** Without a build that fails, the report gets stale and stops being\n      read. This is the part that makes the rest stick.\n\n> Building an AI code reviewer on top of a checklist whose `security/ai-generated-code/` folder warns\n> that AI review confirms AI-written code is fine, only makes sense if the design takes\n> that warning seriously. That is what the three constraints above are for.\n\n\n---\n\n## Contributing\n\nStack files, corrections, missing items, and war stories are all welcome.\nSee [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Questions\n\nOpen a [discussion or an issue](https://github.com/FarzamHabibi/pre-production-checklist/issues) —\nthat way the answer is public and the next person finds it.\n\nFor anything that does not fit there, [@farzam_habibi](https://x.com/farzam_habibi) on X.\n\n## Reporting a security problem\n\nSee [SECURITY.md](SECURITY.md). That includes **an item in this checklist that is wrong in\na way that would make a reader less safe** — a checklist that gives false confidence is\nworse than no checklist, so those are treated as the highest-priority reports.\n\nThe single most useful contribution is a stack file for a stack that isn't covered.\nFiles for Fly.io, Auth0 and Clerk are wanted; see [CONTRIBUTING.md](CONTRIBUTING.md)\nfor the current list and what makes an item belong in a stack file. Copy\n[`_TEMPLATE.md`](checklists/stacks/_TEMPLATE.md) and open a PR.\n\n---\n\n## Disclaimer\n\nA starting point, not a guarantee, not a compliance certification, and not a substitute\nfor a professional security audit. Completing every item does not make an application\nsecure. Use it to find problems, not to declare their absence.\n\n## License\n\nDual-licensed, because the two halves of this repository are different kinds of thing:\n\n| | License | |\n| --- | --- | --- |\n| **Content** — `checklists/`, `data/`, `ALL.md` | [CC BY 4.0](LICENSE) | Copy it, adapt it, ship it commercially. Keep the attribution. |\n| **Code** — `cli/`, `scripts/`, the `prodcheck` package | [MIT](LICENSE-CODE) | Creative Commons licenses aren't designed for software, and a CC-licensed npm package gets rejected by corporate legal review. MIT removes that friction. |\n\n## Built with AI, and honest about it\n\nThis repository was compiled and expanded with [Claude](https://claude.com/claude-code)\n(Anthropic) and [ChatGPT](https://chatgpt.com) (OpenAI), working from a real\npre-production review rather than generating checklist items from scratch. They did the parts that don't fit in one\nperson's head: cross-referencing hundreds of findings against OWASP categories, keeping\n4,353 items consistent in wording and structure, and spotting the gaps between sections.\n\nThat's worth stating plainly for two reasons.\n\n**It's the honest provenance.** A security checklist asks you to trust it. You should know\nhow it was made.\n\n**The `security/ai-generated-code/` folder applies to this repository too.** It says AI-generated work\nneeds review that assumes the AI was confidently wrong somewhere, and that \"the tests\npass\" is not a security argument. Both were true here — the test suite for the CLI caught\nthree real bugs in AI-written code, including an MCP server that silently truncated\nevery response over 8 KB. The checklist is not exempt from its own advice, and neither are the\ntools shipped alongside it.\n\nIf you find an item that's wrong, plausible-sounding but false, or subtly misleading,\nthat's exactly the failure mode [`security/ai-generated-code/07-review-blind-spots.md`](checklists/security/ai-generated-code/07-review-blind-spots.md) warns about.\n[Open an issue](https://github.com/FarzamHabibi/pre-production-checklist/issues) — that\ncorrection is worth more than three new items.\n\n## Credits\n\nWritten and maintained by the founding team at **[Arioo](https://arioo.com)**, out of\nthe work of getting our own product ready to ship.\n\nContributions from everyone who opens an issue or a PR are what will keep it accurate —\nsee the [contributors](https://github.com/FarzamHabibi/pre-production-checklist/graphs/contributors).\n",
  "bytes": 38336,
  "sha": "549292e563b7be754c38f9b1e8bf1bbe38aee25a04ce2e72fcd3168872ec520b",
  "repo_slug": "farzamhabibi/pre-production-checklist",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_farzamhabibi_prodcheck_f3d271f6/readme"
}