You can fix insecure code with a diff. You cannot fix an insecure design with a diff. This is the category where the checkout flow works, the API returns 200, the tests pass — and someone discovers they can order a thousand dollars of product for zero dollars forever, because nothing in the flow was wrong, only the flow itself.
Insecure design is the category for bugs you cannot grep for. The code is fine on its own — every function does what it says. The problem is that the flow they add up to has a hole in it. A payment that settles optimistically, a reset token that never expires, a quota that resets on every request. The fix is a rethink, not a patch.
What your AI actually built
You asked for a checkout that takes a Stripe payment, writes the order to the database, and sends a confirmation email. The model gave you exactly that. The frontend calls /api/checkout, the route creates the order, the user sees the success page.
What the model did not ship was the state machine. The order is marked paid as soon as the row is written. The webhook that actually confirms the charge runs later, updates the same row, and nobody notices that for the first fifteen seconds the order was already treated as fulfilled. A race condition nobody wrote on purpose — because nobody designed the flow to have one state at all.
The same class of bug hides in password resets that do not expire, in coupon codes that stack, in rate limits that count failures but not successes, in multi-step forms where step three trusts the hidden field from step two. The code is fine. The plan is broken.