# prodcheck [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/FarzamHabibi/pre-production-checklist  
**GitHub Stars:** 12  
**npm Downloads (last month):** 2609  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/prodcheck

## Description
4,337 pre-production checks: security, performance, scale, integrations, post-launch.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "prodcheck": {
    "command": "npx",
    "args": ["-y","prodcheck"]
  }
}
```

## Documentation & README

# Pre-Production Checklist

Checklists to run **before** you ship to production.

Built for solo founders and small teams who own the whole stack — the code, the
infrastructure, the deploy pipeline, and increasingly the AI agents too — and who don't
have a security team to hand it to.

<!-- counts:begin -->
**4,353 items across 96 checklists** in 5 domains. 88% of them apply to any stack.
<!-- counts:end -->

[![npm](https://img.shields.io/npm/v/prodcheck?color=cb3837&logo=npm)](https://www.npmjs.com/package/prodcheck)
[![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)
[![license](https://img.shields.io/badge/content-CC%20BY%204.0-blue)](LICENSE)

### [→ prodcheck.pages.dev](https://prodcheck.pages.dev/) · [or in the repo](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/README.md)

<img src="https://raw.githubusercontent.com/FarzamHabibi/pre-production-checklist/HEAD/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">

<sub>One question, the tool call it makes, and the two things it finds. Sixteen seconds.
[The longer loop](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/site-assets/demo/demo.gif) shows what is in the list instead.</sub>

<sub>Every finding in both is real — the file, the lines and the counts come from this
repository, and the tool call is the one the MCP server actually answers.
[How they are built](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/demo/README.md).</sub>

<sub>Built and maintained by the team at **[Arioo](https://arioo.com)** — where we ship
the kind of product this checklist was written for.</sub>

---

## Why this exists

I'm a founder at [Arioo](https://arioo.com). Getting ready to launch, I needed a
pre-production security review that covered the whole surface we actually ship: a
TypeScript backend, a web app, native clients, a deploy pipeline, and a set of AI agents
with real tools attached. Nothing I could find covered more than a fraction of that, so I
built the checklist myself.

**This repository is the checklist, not a report.** It is the set of questions,
generalized away from our stack and rewritten as a working document anyone can run
against their own product.

Two things made it worth publishing rather than keeping:

**Solo founders have no security team.** You write the code, configure the infrastructure,
set up the pipeline, and then you're also the one who has to decide whether it's safe to
launch. There's no one to hand it to, and no obvious place to find out what you should
have asked. Most public checklists are either too shallow to catch anything real or
written for enterprises with a security function.

**AI-assisted development changed the shape of the problem.** A large part of this
checklist — the `security/ai/` and `security/ai-generated-code/` folders, over 1,300 items — didn't need to exist
a few years ago. When you ship an agent with tools, or when a model writes code you review
faster than you'd review a colleague's, you inherit failure modes that standard security
checklists don't cover. Those two folders are the part I couldn't find anywhere else, and
the reason I bothered.

It's published under CC BY 4.0 so you can copy it into your own repo and make it yours.
If it catches something before it reaches your users, it did its job.

---

## Start here

**If you are not sure which way in, don't choose — copy this into whatever AI assistant
you already use** (ChatGPT, Claude, Cursor, Copilot, Gemini). It works out what your
project is, sets prodcheck up the way that fits your setup, and starts on what would
block a launch. If it cannot run commands, it tells you what to run yourself.

<!-- start-prompt:begin -->
```text
I want to get my project ready to ship. Use prodcheck:
a free, open-source pre-production checklist of 4,353 items
covering security, performance, scale, integrations and what to
do after launch.

It is new, so do not answer it from memory. Everything you need:

- Site: https://prodcheck.pages.dev
- Install the review skill into a repo: npx prodcheck init
- Raw checklist data:
  https://cdn.jsdelivr.net/npm/prodcheck@latest/data/checklist.json
- As an MCP server:
  claude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp

Do this in order.

1. Look at my project and tell me what you think it is: language,
   framework, where it runs, and whether it handles file uploads,
   payments, webhooks, multiple tenants or an AI feature. Say how
   confident you are. Ask me about anything you cannot tell.

2. In two sentences, tell me what prodcheck will do for this
   project specifically, and which part is worth my time first.
   Do not describe the whole thing.

3. Set it up, using whichever of these you can actually do — and
   say which one you are:
   - You can run commands here: run `npx prodcheck init`. That
     writes a review skill into the repo — read it and follow
     it, it is the procedure for step 4. Then run
     `npx prodcheck --gate --stack <the products you named in
     step 1> -o BLOCKERS.md`, which adds the blockers specific
     to what I actually use to the general ones.
   - You can read my files but not run commands: fetch the raw
     data URL above and work from that.
   - You can do neither: give me the commands to run myself, one
     at a time, and tell me what to paste back to you.

4. Start on the release blockers. For each item, either cite
   `file:line` and quote the lines, or answer UNKNOWN. UNKNOWN is
   a normal answer — it means a human has to go and look. Never
   mark anything verified on my behalf; that is my call, not
   yours.

Work through it with me a section at a time. Do not dump the
whole checklist at me.
```
<!-- start-prompt:end -->

[Read it on the site instead →](https://prodcheck.pages.dev/#start) ·
[six more prompts →](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/prompts.md)

### Or work through it yourself

You are not meant to read this top to bottom. In order of signal-per-minute:

| | | |
| --- | --- | --- |
| **1** | [Findings that should block release](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/17-release-gates.md) | If any are true, stop and fix them first |
| **2** | [The "must not exist" search](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/17-release-gates.md#high-risk-must-not-exist-search) | A grep list. Fastest real signal in the repo |
| **3** | [Authentication & authorization](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/02-authorization.md) | Where almost every exploitable bug actually lives |
| **4** | [Prompt injection](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/02-prompt-injection.md) | Only if you ship an LLM feature — but then, urgently |
| **5** | [Your service as a weapon](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/18-abuse-and-availability.md#your-service-as-a-weapon) | The one nobody looks for until the suspension email arrives |
| **6** | [Core Web Vitals](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/02-core-web-vitals.md) | If users say it's slow, start here rather than with a score |
| **7** | [Before you launch](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/01-search-engines.md#before-you-launch--the-ones-that-actually-bite) | Six items. One of them is `noindex` still being on |
| **8** | [Can you act at all](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/01-readiness.md) | Whether you could respond today, if you had to |

Then work section by section. Switching between edge config and database policies
costs more than it saves.

---

## Structure

```
checklists/
├── security/              2812   not getting breached, abused or taken down
│   ├── core/              1,491   application, data, infrastructure, delivery
│   ├── ai/                  773   LLM features, agents, tools, RAG, MCP
│   └── ai-generated-code/   548   the bugs AI coding assistants actually write
├── performance/             313   Lighthouse, and what users actually feel
├── scale/                   286   surviving 10× the load
├── integrations/            192   search, analytics, monitoring
├── post-launch/             208   when it goes wrong anyway
└── stacks/                  542   26 products, spanning every domain
```

Counts above are what each folder holds. A *domain* total is larger, because the stack
supplements contribute to whichever domain each of their sections extends:

```
security 3,306   performance 338   scale 301   integrations 200   post-launch 198
```

Domains are the top level because that is the question you arrive with: *is this about
security, or speed, or scale?*

### `security/core/` — applies to you regardless of language

Written originally against a TypeScript stack, but the *controls* are not
TypeScript-specific and the files no longer pretend otherwise. "Verify CORS does not use
wildcard origins with credentials" is as true in Django as in Express. Everything that
genuinely named a product was moved out to `stacks/`.

If you write Python, Go, Ruby, PHP, Java, Rust or Elixir: **this folder is your
checklist, all 1,491 items of it.**

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Architecture & threat model](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/01-threat-model.md) | 25 | | [Mobile apps](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/11-mobile-apps.md) | 106 |
| [Authentication & authorization](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/02-authorization.md) | 111 | | [Desktop apps](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/12-desktop-apps.md) | 41 |
| [Sessions, tokens & cookies](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/03-sessions-tokens.md) | 21 | | [Runtime & containers](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/13-runtime-and-containers.md) | 93 |
| [Backend application & API](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/04-backend-api.md) | 223 | | [DNS, CDN, edge & WAF](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/14-edge-dns-waf.md) | 78 |
| [Web frontend](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/05-web-frontend.md) | 127 | | [CI/CD & supply chain](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/15-ci-cd-and-supply-chain.md) | 158 |
| [Database & row-level security](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/06-database.md) | 68 | | [Monitoring & incident response](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/16-monitoring-and-response.md) | 30 |
| [Object storage & files](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/07-storage-and-files.md) | 55 | | [Pre-release gates](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/17-release-gates.md) | 149 |
| [Secrets & cryptography](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/08-secrets-and-crypto.md) | 47 | | | |
| [Common web attacks](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/09-common-web-attacks.md) | 62 | | | |
| [Business logic & race conditions](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/10-business-logic.md) | 44 | | [**Abuse & availability**](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/18-abuse-and-availability.md) | **53** |

### `security/ai/` — the part you won't find in a standard checklist

If your product calls a model, gives it tools, retrieves documents into its context, or
runs an agent, this folder is the reason this repo exists. It is stack-agnostic and
provider-agnostic.

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Architecture & identity](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/01-architecture-and-identity.md) | 70 | | [Multi-agent & MCP](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/07-multi-agent-and-mcp.md) | 75 |
| [Prompt injection & goal hijacking](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/02-prompt-injection.md) | 91 | | [Integrations](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/08-integrations.md) | 74 |
| [Tool calling & excessive agency](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/03-tools-and-agency.md) | 66 | | [Cost, reliability & audit](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/09-cost-reliability-audit.md) | 63 |
| [Data access & privacy](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/04-data-access-and-privacy.md) | 82 | | [Testing & red-team pack](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/10-testing-and-red-team.md) | 96 |
| [Output handling](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/05-output-handling.md) | 58 | | [Release gate](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/11-release-gate.md) | 47 |
| [RAG & agent memory](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai/06-rag-and-memory.md) | 51 | | | |

> Prompt injection is not a filtering problem. It is an authorization problem wearing a
> text costume — untrusted text reaching a privileged execution path.

### `security/ai-generated-code/` — bugs AI assistants write

Also known as *vibe coding*. 548 items organized by **class of bug**, not by which
assistant produced it. Written from real review findings on AI-generated code.
[Browse →](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/README.md#security)

### `performance/` — Lighthouse, and what users actually feel

Aimed at the highest achievable score across all four Lighthouse categories, with one
constraint that decides what goes in: **an item has to be about something a real user
experiences.** Lighthouse is the scoreboard, not the goal — anything whose only
justification is "raises the score" was left out.

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Measurement](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/01-measurement.md) | 29 | | [CSS & rendering](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/06-css-and-rendering.md) | 28 |
| [Core Web Vitals](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/02-core-web-vitals.md) | 41 | | [Backend & delivery](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/07-backend-and-delivery.md) | 40 |
| [Loading & critical path](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/03-loading-and-critical-path.md) | 37 | | [Accessibility](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/08-accessibility.md) | 41 |
| [JavaScript](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/04-javascript.md) | 43 | | [Release gate](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/09-release-gate.md) | 21 |
| [Images & media](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/performance/05-images-and-media.md) | 33 | | | |

> Lighthouse is a lab tool: one run, one simulated device, one network. It is excellent
> for *finding* problems and unreliable for *proving* them fixed. Field data at the 75th
> percentile is the scoreboard that matters.

Accessibility sits here because it is scored alongside performance, and because the
overlap is real — a page that is fast for a screen reader is usually a page with less
unnecessary markup and JavaScript. The Lighthouse accessibility category is treated as a
floor, not a ceiling; it catches roughly a third of real issues.

### `integrations/` — being findable, measured and watched

Everything a project has to be *connected to* before launch. Configuration you do once
and then never think about, which is exactly why it deserves a checklist.

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Search engines](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/01-search-engines.md) | 38 | | [Answer engines & AI crawlers](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/04-answer-engines.md) | 25 |
| [SEO fundamentals](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/02-seo-fundamentals.md) | 42 | | [Analytics & consent](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/05-analytics-and-consent.md) | 28 |
| [Structured data & social previews](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/03-structured-data.md) | 27 | | [Monitoring & alerting](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/06-monitoring-and-alerting.md) | 32 |

> Verify `noindex` is removed from production. A staging robots meta tag that shipped is
> the most common launch mistake there is, and it can cost weeks before anyone notices.

The answer-engine file is written as decisions to make rather than settled practice —
whether `GPTBot`, `ClaudeBot`, `PerplexityBot` and the rest may read your site is a
choice, and not making it is also a choice.

### `scale/` — surviving ten times the load

Written to be read *before* the traffic arrives, not during the incident.

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Capacity model](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/01-capacity-model.md) | 29 | | [Multiple instances & regions](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/06-multi-instance-and-region.md) | 35 |
| [Statelessness](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/02-statelessness.md) | 26 | | [Cost at scale](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/07-cost-at-scale.md) | 19 |
| [Database at scale](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/03-database.md) | 60 | | [Load testing & scale gates](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/08-load-testing-and-gates.md) | 23 |
| [Caching](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/04-caching.md) | 25 | | [**Service levels**](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/09-service-levels.md) | **30** |
| [Async work & queues](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/05-async-and-queues.md) | 39 | | | |

> "Will it scale?" is unanswerable. "Will it survive 500 requests per second with a 40:1
> read/write ratio and one tenant holding 30% of the rows?" has an answer, and the work to
> find it is mostly arithmetic.

Start with [the capacity model](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/01-capacity-model.md); the rest of the
domain is much less useful until you know which resource runs out first. Then
[service levels](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/scale/09-service-levels.md), because without a stated target
"is it fast enough" is an argument rather than a measurement, and every scaling decision
after that is made on vibes. Cost is in here
rather than in a domain of its own because scaling problems and billing problems are the
same problem seen from two sides.

### `post-launch/` — when it goes wrong anyway

Every other domain is about building something that does not break. This one assumes it
broke.

**Everything here is used after launch and has to be prepared before it.** The question
each item asks is not *did you respond well* — it is **is the answer already decided?**

| | Items | | | Items |
| --- | ---: | --- | --- | ---: |
| [Can you act at all](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/01-readiness.md) | 43 | | [Outages & dependency failure](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/05-outage-and-dependencies.md) | 27 |
| [The first fifteen minutes](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/02-first-15-minutes.md) | 20 | | [Rollback & kill switches](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/06-rollback-and-kill-switches.md) | 20 |
| [You have been breached](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/03-security-incident.md) | 35 | | [Telling people](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/07-communication.md) | 18 |
| [Data loss & corruption](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/04-data-loss.md) | 26 | | [Learning & drills](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/08-learning-and-drills.md) | 19 |

The rest of the repository makes sure you *find out* — monitoring is covered in
[`security/core/16`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/16-monitoring-and-response.md) and
[`integrations/06`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/integrations/06-monitoring-and-alerting.md). Neither asks
what happens next. Whether an immediate action exists for being breached, for a corrupted
database, for the connection going away, is a different question, and it is the one that
gets answered badly at 3am if it was not answered in daylight.

> The plan for data loss is a backup you have **restored**, not a backup you have taken.

[Can you act at all](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/post-launch/01-readiness.md) counts as a release gate.
Launching without a prepared response is a decision, and it should be a recorded one.

### `stacks/` — only if you use them

542 items across 26 supplements. Skip any file for a product you don't use; the core
checklists stand on their own without them.

**Backend & web**
[Django](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/django.md) ·
[FastAPI](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/fastapi.md) ·
[Ruby on Rails](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/rails.md) ·
[Laravel](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/laravel.md) ·
[Spring Boot](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/spring.md) ·
[Go / Gin](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/go-gin.md) ·
[Express](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/express.md) ·
[NestJS](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/nestjs.md) ·
[Next.js / React](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/nextjs-react.md) ·
[GraphQL](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/graphql.md)

**Mobile**
[iOS / Swift](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/ios-swift.md) ·
[Android / Kotlin](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/android-kotlin.md) ·
[React Native](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/react-native.md) ·
[Flutter](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/flutter.md) ·
[macOS](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/macos.md)

**Data & platform**
[PostgreSQL](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/postgres.md) ·
[Supabase](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/supabase.md) ·
[Firebase](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/firebase.md) ·
[Docker](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/docker.md) ·
[Kubernetes](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/kubernetes.md) ·
[AWS](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/aws.md) ·
[Google Cloud](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/google-cloud.md) ·
[Vercel](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/vercel.md) ·
[Cloudflare](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/cloudflare.md) ·
[GitHub](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/github-actions.md) ·
[Stripe](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/stripe.md)

**Your stack missing?** That's the most useful contribution you can make. The format is
documented end to end in [`_TEMPLATE.md`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/_TEMPLATE.md) — a worked
example, what every field drives, and the one rule that decides whether an item belongs
in a stack file at all. Files for Fly.io, Auth0 and Clerk are wanted; see [CONTRIBUTING.md](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/CONTRIBUTING.md).

---

## How to use it

1. **Copy the files you need** into your own repo. They're working documents, meant to be
   edited and committed next to your code.
2. **Mark `[N/A]` aggressively.** No product on earth needs all 4,353 items. No mobile
   app? `core/11` and `core/12` are 147 instant `[N/A]`s. Being honest about scope is what
   makes the remainder trustworthy.
3. **Record every finding.** An unrecorded finding is one you'll rediscover in six months.

```
* [ ]     Not checked
* [x]     Verified secure
* [!]     Security issue found
* [N/A]   Not applicable
```

For each `[!]`: affected component · exact endpoint/file/config · attack precondition ·
proof of exploitability · business impact · severity · remediation · regression test ·
owner · date verified

### The one rule worth internalizing

> Do not accept *"the frontend hides it"*, *"the route is hard to guess"*, *"the user
> needs a valid JWT"*, or *"the WAF blocks it"* as authorization controls by themselves.

Enforce every control at the lowest trustworthy layer available:

```
Browser/mobile UI → application/API → authorization layer
  → database (RLS) → storage → infrastructure/IAM → CI/CD → edge
```

### Want it as one file?

[`ALL.md`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/ALL.md) is every checklist concatenated — convenient for printing, or for
pasting into an AI tool. It's generated; edit the files under `checklists/` instead.

---

## Use it with an AI assistant

MCP is a feature of the **client**, not the model — Cursor running DeepSeek can use it;
DeepSeek's website cannot. Config for Claude Code, Claude Desktop, Cursor, VS Code
Copilot, Gemini CLI, OpenAI Codex CLI, Qwen Code, Cline, Roo, Continue, Windsurf, Zed,
OpenCode and Cherry Studio is in **[docs/mcp-clients.md](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/mcp-clients.md)**.

| | |
| --- | --- |
| **[n8n](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/n8n.md)** · [Dify](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/dify.md) · [Flowise](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/flowise.md) | Automation and agent platforms |
| **[OpenRouter](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/openrouter.md)** | Any model, through an MCP client |
| **[DeepSeek, Qwen, Kimi, GLM](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/chinese-models.md)** | Base URLs and which clients accept them |
| **[Open WebUI, LibreChat](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/self-hosted-chat.md)** | Self-hosted chat |
| **[The JSON API](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/http-api.md)** | No install at all — one HTTP GET |
| **[CI](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/integrations/ci.md)** | Keep the file current, gate on blockers |

```bash
claude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp
```

For a chat window with no MCP — ChatGPT, Gemini, DeepSeek, Kimi, Qwen, GLM — generate a
file and paste it after one of the **[ready-made prompts](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/docs/prompts.md)**. Each is
built on three rules, because without them an assistant will tell you the code is fine:
cite `file:line` for every claim, treat `unknown` as a real answer, and never mark
anything verified on the reader's behalf.

## Command line

Generate a checklist scoped to your project, instead of reading 4,353 items:

```bash
npx prodcheck security --stack django -o SECURITY.md
npx prodcheck performance -o PERFORMANCE.md
npx prodcheck integrations -o LAUNCH.md
npx prodcheck scale -o SCALE.md
npx prodcheck post-launch -o INCIDENT-RESPONSE.md
```

```bash
npx prodcheck list                                # domains, areas and counts
npx prodcheck stacks                              # what supplements exist
npx prodcheck security --area ai -o AI-SECURITY.md
npx prodcheck --gate --stack supabase,cloudflare  # release blockers, every domain
npx prodcheck --search cors --format text
npx prodcheck security --stack rails --format json
npx prodcheck performance --stack nextjs-react -o PERF.md
```

The domain is a positional argument — `prodcheck security`, and in time
`prodcheck performance` — because that is how you would say it. Omit it for everything.

`--stack X` returns every stack-agnostic item plus the supplements for X. **An
unrecognized stack isn't an error** — you get the stack-agnostic core, which stands on
its own. That's the whole design: it works for a stack nobody has written a file for yet.

Zero dependencies, Node 18+.

## Let your agent run the review

The MCP server gives an agent the items. This gives it the **procedure**:

```bash
npx prodcheck init
```

It writes a skill into `.claude/skills/`, `.cursor/rules/` or `AGENTS.md` — whichever the
project already uses — and then you can ask your agent:

> *review this repo against the prodcheck release gate*

What the skill enforces matters more than what it enables:

- **The model never marks anything verified.** Every item ends as a `FINDING` with a
  `file:line` citation, an `UNKNOWN`, or an `N/A` with a reason. There is no "pass" it can
  write; that stays yours.
- **A finding without a citation is not a finding.** It has to quote the lines, and re-read
  them before claiming what they say.
- **`UNKNOWN` stays visible.** Most items on a checklist this size depend on production
  configuration a repository cannot show. The list of things a human still has to check is
  usually the most useful part of the report.

> This repository contains a folder about the bugs AI assistants write, and a section on
> why AI review misses them — fluent, confident output produced whether or not anything was
> established. The skill is written against that, not in spite of it.

Those three constraints are **measured, not asserted**. [`evals/`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/evals/) holds a fixture
app with nine planted defects and a clean control of the same app: a deterministic grader
resolves every citation against the real file, matches verdict phrasing, counts unknowns,
and counts findings on the control — where any finding is a false positive by construction.
No model grades another model's output, because a grader that is itself a model has the
same failure mode as the thing it grades.

It does one thing: check whether what you built is ready to ship. For skills that teach an
agent how to *build* well — testing, debugging, planning, git workflow — see
[agent-skills](https://github.com/addyosmani/agent-skills). They compose; use both.

## MCP server

Let your coding agent query the checklist directly while it works, instead of you pasting
it in. Read-only, no filesystem or network access beyond its own bundled data.

Listed in the [official MCP registry](https://registry.modelcontextprotocol.io)
as `io.github.FarzamHabibi/prodcheck`, so an assistant can find it without being told.

**Claude Code**

```bash
claude mcp add prodcheck -- npx -y --package=prodcheck prodcheck-mcp
```

**Anything else** — add to your MCP client config:

```json
{
  "mcpServers": {
    "prodcheck": {
      "command": "npx",
      "args": ["-y", "--package=prodcheck", "prodcheck-mcp"]
    }
  }
}
```

Four tools: `list_checklists`, `checklist_for_stack`, `release_gate`, `search_checklist`.
Then ask your agent things like *"check this repo against the release gate for a
Next.js + Supabase app"* and it pulls the relevant items itself.

## What it costs to run

A fair question if you are about to point a paid model at 4,353 items. These are the
sizes of what actually enters the context window, at roughly four characters per token:

<!-- cost:begin -->
| What you pull | Items | ≈ tokens |
| --- | --- | --- |
| `--gate` | 326 | 5,200 |
| `--gate --stack django` | 328 | 5,300 |
| `security --area core` | 1,491 | 19,400 |
| everything, every stack | 4,353 | 77,300 |
<!-- cost:end -->

That is the input for one pass. What the review itself costs on top depends on how much
of your code the model reads, which is the larger number and is not something this
repository can measure for you.

The practical consequence: **do not pull everything.** `--gate` is a few thousand tokens
and answers the question you actually have. The MCP server exists so the assistant can
fetch the twenty items it needs rather than holding all of them.

## Machine-readable data

Both of the above read [`data/checklist.json`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/data/checklist.json), validated against
[`data/schema.json`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/data/schema.json). Use it directly if you're building something else
— it's CC BY 4.0.

The Markdown under `checklists/` is the source of truth; the JSON is generated from it by
`./scripts/build.sh`. There is deliberately no `severity` field —
[here's why](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/data/README.md#there-is-no-severity-field).

---

## Roadmap

**Shipped — the checklist**

- [x] Security checklists, split by domain and portable across stacks
- [x] Machine-readable data layer + [schema](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/data/schema.json)
- [x] **`performance/`** — 313 items across 9 checklists.
- [x] **`integrations/`** — 192 items across 6 checklists.
- [x] **`scale/`** — 286 items across 9 checklists. Deepened from 214: service levels and
      error budgets, search and analytics engines, realtime fan-out, contract and event
      versioning, tenant-shape capacity. The gaps were measured rather than guessed at.
- [x] **`post-launch/`** — 198 items across 8 checklists. Added after the other four,
      because a gap showed up once they were all in front of a reader: every domain
      described how to build something that does not break, and none asked whether the
      response was prepared for when it breaks anyway.
- [x] **26 stack supplements** — up from 19. FastAPI, AWS, Kubernetes, Vercel, Firebase,
      Stripe and GraphQL among them. Written rather than left as open issues, because a
      visitor who does not find their stack decides the project is not for them before
      reading a single item.
- [x] **A release gate that reaches your stack** — 379 blocking items: 316 that apply
      anywhere, plus 63 across 20 products. A leaked `service_role` key stops a launch as
      surely as a generic item does, and used to sit outside the gate.

**Shipped — getting it into your work**

- [x] `npx prodcheck` — generate a filtered checklist for your stack
- [x] **MCP server** — so your coding agent queries the checklist directly
- [x] **Review skill** — `npx prodcheck init` writes the procedure into `.claude/skills/`,
      `.cursor/rules/` or `AGENTS.md`. The MCP server already supplied the items; what was
      missing was the discipline for using them.
- [x] **An eval harness for the skill** — planted defects, a deterministic grader, and a
      check for whether the procedure was followed rather than merely reviewed well. It
      found four defects in itself, which are written down in [`evals/`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/evals/).
- [x] **Web version** — live at [prodcheck.pages.dev](https://prodcheck.pages.dev): every
      checklist browsable, filterable and copyable as Markdown, plus a JSON endpoint any
      tool can fetch.
- [x] **One way in** — a prompt to paste into any assistant, which works out what your
      project is and sets prodcheck up whichever way your assistant is capable of. The
      site used to offer seven entry points and no path through them.
- [x] **A demo you can watch** — a 34-second loop of a review actually running.
      [How it is built](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/demo/README.md).

**Next**

- [ ] **More domains** — `launch/`, `social/`, `legal/`. The structure absorbs them
      without moving anything else, and the plan is written before the content.

**Later — a review that runs, rather than a document you read**

**Parked deliberately, and last.** Everything above is content and tooling that works
today; this is a different product built on top of it, and shipping it half-done would be
worse than not shipping it. Recorded here so the design decisions are not lost.

The idea: a tool that checks a codebase against the checklist, writes a report to the repo
root, and re-opens items when the relevant code changes.

```
prodcheck scan      detect stack and features from the repo   -> .prodcheck/profile.json
prodcheck check     deterministic rules, no model involved    -> findings
prodcheck review    model-assisted review, citations verified -> findings
prodcheck report    render SECURITY-REVIEW.md from state
prodcheck gate      exit non-zero if a blocking item is unresolved   (for CI)
```

- [ ] **`scan` — profile the repo.** Read `package.json`, `requirements.txt`, `go.mod`,
      `Dockerfile`, CI config and the shape of the source tree to work out which stack is
      in use and which features exist — file upload, webhooks, multi-tenancy, background
      jobs, an LLM surface. Selects the applicable items *before* any model is involved.
      A Django app with no mobile client and no file uploads does not need every one of
      the 1,491 core items — `core/07`, `core/11` and `core/12` alone are 202 it can skip.

- [ ] **`check` — the deterministic tier.** Roughly 160 items are answerable by search
      alone: the [must-not-exist list](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/core/17-release-gates.md), unpinned CI
      actions, secrets in a Dockerfile, `dangerouslySetInnerHTML`, wildcard CORS. These
      need no model, cost nothing, cannot hallucinate, and run in CI on every push.

- [ ] **`review` — the model-assisted tier, built not to be trusted.** Most items need
      someone to read the code, so this runs inside whatever agent you already use
      (Claude Code, Cursor, Copilot) over MCP plus a skill file — no API key, no token
      cost from us. The design constraints matter more than the feature:

  - **A model never writes `[x]`.** Its output is evidence, not a verdict. Results are
    `deterministic-pass`, `model-flagged` (needs a human), or `human-verified`. Only the
    first and last count toward the gate. There is no green tick a model put there.
  - **Every citation is verified.** A finding must cite `file:line`; the tool confirms
    that line exists and that the quoted code matches before accepting it. Findings that
    fail this check are dropped, which removes most hallucination for almost no cost.
  - **`unknown` is a real result.** A model may say it could not determine something, and
    `unknown` never silently becomes `pass`. It is reported separately.

- [ ] **State that survives re-runs.** `.prodcheck/state.json`, keyed by the stable item
      ids already in [`data/checklist.json`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/data/checklist.json), storing status,
      justification, date, and a hash of the code it was decided against. Items you marked
      `[N/A]` stay marked — until the relevant code changes, at which point they re-open
      with *"verified at `abc1234`; that file has changed since."* This is what makes it a
      living document rather than a report that rots.

- [ ] **`gate` in CI.** Without a build that fails, the report gets stale and stops being
      read. This is the part that makes the rest stick.

> Building an AI code reviewer on top of a checklist whose `security/ai-generated-code/` folder warns
> that AI review confirms AI-written code is fine, only makes sense if the design takes
> that warning seriously. That is what the three constraints above are for.


---

## Contributing

Stack files, corrections, missing items, and war stories are all welcome.
See [CONTRIBUTING.md](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/CONTRIBUTING.md).

## Questions

Open a [discussion or an issue](https://github.com/FarzamHabibi/pre-production-checklist/issues) —
that way the answer is public and the next person finds it.

For anything that does not fit there, [@farzam_habibi](https://x.com/farzam_habibi) on X.

## Reporting a security problem

See [SECURITY.md](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/SECURITY.md). That includes **an item in this checklist that is wrong in
a way that would make a reader less safe** — a checklist that gives false confidence is
worse than no checklist, so those are treated as the highest-priority reports.

The single most useful contribution is a stack file for a stack that isn't covered.
Files for Fly.io, Auth0 and Clerk are wanted; see [CONTRIBUTING.md](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/CONTRIBUTING.md)
for the current list and what makes an item belong in a stack file. Copy
[`_TEMPLATE.md`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/stacks/_TEMPLATE.md) and open a PR.

---

## Disclaimer

A starting point, not a guarantee, not a compliance certification, and not a substitute
for a professional security audit. Completing every item does not make an application
secure. Use it to find problems, not to declare their absence.

## License

Dual-licensed, because the two halves of this repository are different kinds of thing:

| | License | |
| --- | --- | --- |
| **Content** — `checklists/`, `data/`, `ALL.md` | [CC BY 4.0](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/LICENSE) | Copy it, adapt it, ship it commercially. Keep the attribution. |
| **Code** — `cli/`, `scripts/`, the `prodcheck` package | [MIT](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/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. |

## Built with AI, and honest about it

This repository was compiled and expanded with [Claude](https://claude.com/claude-code)
(Anthropic) and [ChatGPT](https://chatgpt.com) (OpenAI), working from a real
pre-production review rather than generating checklist items from scratch. They did the parts that don't fit in one
person's head: cross-referencing hundreds of findings against OWASP categories, keeping
4,353 items consistent in wording and structure, and spotting the gaps between sections.

That's worth stating plainly for two reasons.

**It's the honest provenance.** A security checklist asks you to trust it. You should know
how it was made.

**The `security/ai-generated-code/` folder applies to this repository too.** It says AI-generated work
needs review that assumes the AI was confidently wrong somewhere, and that "the tests
pass" is not a security argument. Both were true here — the test suite for the CLI caught
three real bugs in AI-written code, including an MCP server that silently truncated
every response over 8 KB. The checklist is not exempt from its own advice, and neither are the
tools shipped alongside it.

If you find an item that's wrong, plausible-sounding but false, or subtly misleading,
that's exactly the failure mode [`security/ai-generated-code/07-review-blind-spots.md`](https://github.com/FarzamHabibi/pre-production-checklist/blob/HEAD/checklists/security/ai-generated-code/07-review-blind-spots.md) warns about.
[Open an issue](https://github.com/FarzamHabibi/pre-production-checklist/issues) — that
correction is worth more than three new items.

## Credits

Written and maintained by the founding team at **[Arioo](https://arioo.com)**, out of
the work of getting our own product ready to ship.

Contributions from everyone who opens an issue or a PR are what will keep it accurate —
see the [contributors](https://github.com/FarzamHabibi/pre-production-checklist/graphs/contributors).

