The Codebase Used to Ask the Questions
I've been collecting postmortems for about a year now. Apps that shipped, got breached, and got attributed to AI in the writeup.
The collection has a strange pattern. When I sort them by founder background, by tool, by funding, by category, the patterns blur. When I sort them by what architectural decision the founder skipped, the pattern is sharp enough to draw a line through.
It's the same line every time. Where do secrets live. Who can read what. What's on each side of the trust boundary.
I want to try to explain why that keeps happening, because I don't think it's the answer most people are reaching for. It's not because of bad builders or bad models. actually that's the act of writing code used to force you to answer those questions, and now it doesn't.
Building used to be the planning
Think about what you actually did, before agents, when you sat down to build a web app.
You opened a file. You imported your framework. You started writing the auth middleware, because the framework asked you to. Halfway through you stopped, because you realized you hadn't decided where the session lived. You went to look up cookie versus JWT. You read three Stack-Overflow threads. You made a call. You came back. You wrote the middleware.
Then you set up the database. Then you noticed your user table didn't have a column for the auth field you'd just decided on. Then you migrated. Then you wrote the signup form. Then you noticed the signup form was sending the password in the clear over local HTTP, and you stopped to add HTTPS to your dev environment, which took an hour.
By the time the app could log a user in, you had answered maybe forty small architectural questions. None of them were a meeting or design doc. They were forced on you by the act of trying to make the code run.
The codebase, in other words, was a planning tool that disguised itself as an implementation tool. Every line you wrote was also a decision you'd been forced to make. Implementation and planning were the same activity and go hand in hand. You didn't notice the planning happening because it was just called "coding."
This is the thing nobody talks about when they talk about how much faster AI coding agents have made software development. They've made implementation faster. But implementation was carrying planning on its back the whole time. When you make implementation cheap and fast, you don't just get cheap fast implementation. You get planning that never happens at all.
What the agent doesn't ask
Leonel Acevedo started Enrichlead with Cursor in March 2025. He'd never written production code before. He prompted the agent for what he wanted, the agent built it, he shipped.
The breach came two days later. Due to poor authentication, no rate limiting and input validation. API keys in the frontend bundle. He posted on Twitter that he was under attack and didn't know how to fix it because he wasn't technical. Cursor kept breaking adjacent features when he asked it to patch. He shut down within the week.
Here's the thing I want you to notice. The agent didn't fail Acevedo. The agent did exactly what he asked. He asked for a lead enrichment SaaS, and the agent built one that functionally enriched leads. The thing he didn't ask for was the thing that killed him.
He didn't ask "where should my API keys live" because he didn't know to ask. He didn't ask "who should be allowed to hit this endpoint" because he didn't know that endpoints had owners. He didn't ask "what happens if someone discovers this URL" because the concept of an unauthenticated attacker wasn't part of his mental model.
In the old world, none of that would have mattered. The codebase would have caught it. The first time he tried to add a payment integration, Stripe would have refused his client-side key and forced him to set up a server. The first time he deployed, his framework would have warned him about secrets in the bundle. The first time he hit production, the act of typing process.env.X instead of hardcoding would have made him think about environments. The friction would have been the curriculum.
as there was no friction and the agents wrote everything, the planning phase never happened.
This pattern repeats
I have five more of these. I'm going to describe them quickly because the pattern is the same and the conclusion is the same and the only reason to dwell on each one is to convince you that I'm not cherry-picking.
In May 2025, a security researcher named Matt Palmer crawled 1,645 apps built on Lovable, one of the bigger vibe coding platforms. He found 303 insecure endpoints across 170 of those apps. Some of them had access control inverted, where unauthenticated users had full read access and signed-in users were blocked. The vulnerability got assigned CVE-2025-48757 with a CVSS of 9.3. Alex Stamos, formerly Facebook's CSO, said about it: "You can do it correctly. The odds of doing it correctly are extremely low." 10.3% of all Lovable apps had broken access control.
In July 2025, Tea, a women-only dating safety app, sat at #1 on the US App Store. The verification flow required uploading a selfie next to a government photo ID. On July 25, a 4chan user dumped 59 gigabytes of user data. Around 72,000 images. 13,000 selfies and government IDs. The founder, Sean Cook, said publicly he doesn't know how to code. The app was built by two contractors. The 4chan leaker cited vibe coding as the cause. A women's safety app doxxed women's faces because nobody decided where the upload bucket lived.
A week later, Wiz Research disclosed an auth bypass on Base44, Wix's vibe coding platform. Two endpoints registration and OTP verification required no authentication at all. A single bug compromised every app on the platform. The blast radius was the whole product.
In December 2025, Orchids, a tool that generated small apps for users to run locally, shipped without isolating generated code from the host machine. A BBC journalist demonstrated zero-click remote code execution by sharing a malicious project. The sandbox architecture was really important implementation and yet nobody decided to plan it well.
Then Moltbook. January 2026. Matt Schlicht is the CEO of Octane AI. He's been in AI commerce since 2016. He's not a beginner. Before he launched Moltbook, "the social network for AI agents," he posted: "I didn't write a single line of code for @moltbook. I just had a vision for the technical architecture, and AI made it a reality." Wiz Research pulled 1.5 million API authentication tokens, 35,000 email addresses, and private direct messages out of the app within a few weeks. The Supabase service role key was sitting in the client-side JavaScript bundle.
If you've worked with Supabase you know the service role key is the god-mode key. It bypasses every row-level security policy you've ever written. and it is not supposed to leave the server. Ever. The CEO of an AI company put it in a frontend bundle and shipped.
As you can see the same pattern across these Six apps and same root cause every time. and it's definitely not caused by the bad models or incompetent developers. Schlicht is more technical than 99% of the people building things this year.
It's not a model problem
The first thing everyone reaches for, when they hear about one of these, is "they should have used a better model."
I don't think this works. I'll tell you why.
The Cursor agent that built Enrichlead in March 2025 was running on whatever Anthropic shipped that month. The Cursor agent today is running Claude Opus 4.6, which is genuinely several orders of magnitude better at code. If you handed Opus 4.6 the same prompt Acevedo gave Cursor in March 2025 "build me a lead enrichment SaaS" it would build a more elegant version of the same insecure app. Because Acevedo never told Opus 4.6 that the app would store API keys, accept payments, or have an admin panel. The model can't infer security requirements from "build me a SaaS." Nothing can.
The constraint here isn't the model capabilities. Its that the user has to know what to ask for, and most users don't. In the old world, the codebase asked the questions on their behalf. The IDE throws error and demands debugging. The framework refused to run. The deploy pipeline rejected the bundle. Now nothing complains. The output looks good. The user ships.
There's a study from Columbia, cited in a Towards Data Science piece I read last spring, that made the mechanism click for me. The researchers found that the most reliable way to get a user to accept a generated code suggestion was to make the error message go away. The constraint causing the error, often, was a safety guard. So the path of least resistance, for both the agent and the user, was to remove the guard, accept the diff, and ship.
That's not a bad agent. it exactly an agent doing exactly what its objective function tells it to do. The objective function is "make the user happy in the next thirty seconds." Security is a thirty-day concern, not a thirty-second one. So it loses every time.
The planning has to live somewhere
If the codebase used to do the planning and doesn't anymore, the planning has to live somewhere. There are exactly three places it can go.
It can go in your head. This works if you're an experienced engineer who has done this before. You sit down, you imagine the production version of the app, you list the architectural decisions, you encode them in your prompts. You catch the API-keys-in-frontend mistake because you've seen it twelve times. This is what the small number of competent people building with agents are doing right now, mostly without realizing it, and it's why their apps don't end up in essays like this one.
It can go in a teammate's head. This is what teams have always done. You sketch a thing on a whiteboard, your senior engineer says "where's the auth boundary," and the conversation goes from there. The teammate is the planning step. Anyone who's worked on a real engineering team has had this experience. It's also why solo vibe coders, and small teams of non-technical founders, are the ones who keep showing up in these postmortems. There's no senior engineer in the room to ask the question.
It can go in software. This is the new option and it's where things get interesting. If neither you nor your teammates can play the role of the senior engineer, you need something that does. A tool that sits between you and the agent and forces the architectural conversation to happen before the code does.
I spent five years at Coinbase building the platform that 700+ engineers shipped on top of. The thing you learn in that job is that planning artifacts have to scale with execution speed, and they almost never do. Teams ship faster. Specs stay the same. The gap between "what we agreed to build" and "what's actually running in production" widens quietly until someone notices, usually after an incident. Coding agents have taken that same dynamic and compressed it from quarters into days. The gap that used to take six months to open now opens in an afternoon.
That's the problem Devin and I started Scott AI to work on. The bet is that the planning step has to be its own piece of software, separate from the coding agent, because the agent that's about to write the code has a conflict of interest about whether the code should be written. Asking an execution agent if the plan is good is like asking a contractor if you need an architect. The honest answer is usually yes, but the incentives push the other way.
What we've built is something we call a planspace. You spec the app in the planspace before any execution agent runs. The planspace is grounded in your codebase and whatever knowledge sources you've connected, so it knows what already exists. It runs multiple agents in parallel during planning, Claude and Codex and others, on the theory that disagreement between models surfaces architectural questions that any one of them, alone, would have missed. The planspace gets reviewed and locked. Only then does the execution agent get the green light.
We're early. The product is in active development and the shape will keep changing. I'm not going to claim Scott AI would have saved every app in this essay. Tea was built by contractors who probably wouldn't have used any tool we shipped. Acevedo didn't think he needed planning. Schlicht's whole tweet was about not having a technical co-pilot.
What I will claim is this. If Matt Schlicht had been forced to fill in a planspace before generating Moltbook, the planspace would have asked him where the Supabase service role key lived. That question, surfaced once, would have saved 1.5 million tokens. The cost of the planspace is five minutes of friction at the start of the project. The cost of skipping it is a Wiz disclosure and a relaunch.
Whether we win this category or not, I don't know. Anthropic could ship a fuller plan mode tomorrow and absorb a lot of the value. Cursor already has one. The thing I'm more confident about is that some piece of software is going to occupy this slot, because the slot is too important to leave empty and too cognitively demanding to expect every founder to fill from memory.
What you can do this afternoon
You don't need Scott AI to start. The cost of the manual version is fifteen minutes and a text file. I want to walk you through what I'd do if I were shipping a vibe-coded app today, because the friction is small enough that nobody has a good excuse.
Before prompting the agent to build anything that touches real users, write down five things:
- What data the app stores, and which of it is sensitive
- Where the auth boundary is, and what's on each side of it
- What secrets the app needs, and where they live
- Who is allowed to read each piece of data, and how that gets enforced
- What the worst case looks like if someone finds a hole
Paste it into the agent's context as the first message. Ask the agent to refer back to it before generating any code that touches auth, secrets, or storage. That's the manual version of what a planspace does. It works.
Then add one more step. Ask a second model to review the plan. Not the same model you're about to build with. A different one. Have Claude read what Codex wrote, or Codex read what Claude wrote. They catch different things. Last week I ran a small internal project through this loop and Codex caught a row-level security gap that Claude had been blind to. Took me forty-five seconds to fix. Would have taken a month to debug in production, and probably a Wiz disclosure to find at all.
This loop is what we're trying to make automatic at Scott AI. You can run it by hand. The cost is fifteen minutes. The question is whether you will.
The bar moved
The floor on minimum viable software moved when agents arrived, and I don't think enough people have noticed.
It used to be "the app works on my machine." That floor was higher than it sounded, because to get the app to work on your machine, you had to make most of the architectural decisions that mattered. The floor came with a built-in curriculum.
The new floor is "the app looks like it works in the demo video." That floor is much lower than it sounds. You can clear it without making any architectural decisions at all. The curriculum is gone. The polish is up. The robustness is down.
This is the asymmetry that explains every breach in this essay. The apps look good on day one. They fall apart on day eight. Not because the agents are bad, but because the day-one polish was paid for, in the old world, by the day-eight robustness. You used to get them together. Now they're decoupled, and you only get the day-eight robustness if you go out of your way to ask for it.
Going out of your way to ask for it is the new senior-engineer skill. Whether you encode it in your head, in a teammate, or in a piece of software, you have to encode it somewhere. The apps that don't encode it anywhere are the ones we keep finding in our collection.
We're not going to stop building this way. The economics are too good. What's going to happen is the planning step will come back, in a different form, because the breach rate will force it back. The question is what form, and how soon, and how many more Moltbooks we collect before we get there.