Your vibe-coded app got serious faster than expected

The dangerous part was not that AI wrote code quickly. It was how easy it became to forget which shortcuts were only safe while the app was still a toy.

Editorial illustration of a developer celebrating a working app while a second monitor shows unresolved launch warnings.

I did the thing everyone says they are doing now. I vibe-coded.

Not in the fake LinkedIn way where someone says they built a SaaS in eleven minutes and then quietly spends three days fixing the login page. I mean the normal version. I had an idea. I opened an AI coding tool. I described what I wanted. It started building. I kept nudging it along. A button here. A route there. A little database change. A "just make this work for now" moment that felt harmless at the time.

And then the app worked. Which was both wonderful and slightly terrifying. Because there is a specific moment in AI-assisted development where your brain shifts from "wow, this is amazing" to "wait, this thing might actually be real software now." That is the moment this post is about.

i.The magic phase is real

At first, vibe coding feels like cheating in the best possible way. You describe the idea, the agent builds the scaffolding, you ask for polish, it adds the polish, you ask for the bug fix, it confidently creates three new bugs while fixing the first one. Very normal. Very artisanal.

But the speed is intoxicating. The distance between "I have an idea" and "I can click around a working version" gets compressed so much that your judgment can lag behind the output.

That was the first thing I noticed. The AI did not just help me write code faster. It helped me postpone asking boring adult questions.

The agent didn't need a bigger prompt. It needed a better memory of what hurt last time.

That last question was the one that stuck. Because the app had memory-shaped problems. Not database memory. Not auth memory. Human memory. Project memory. The kind of memory that knows we only did it this way because we were trying to get a demo working. The kind that says this needs a security pass before anyone else touches it. The kind that remembers do not regenerate this component from scratch because the first version looked right but broke the edge case.

The most dangerous part of vibe coding is not always the code the AI writes. Sometimes it is the context the human forgets.

ii.What happens when it works

This is not just a personal problem. A year ago the interesting question was "can AI build the thing?" Now the more useful question is "what happens when the thing works?"

Because working is not the same as safe. Working is not the same as maintainable. Working is not the same as production-ready. And working is definitely not the same as "I understand every decision that led to this."

That drift is the scary part. A local tool becomes a hosted app. A demo gets shared with a few people. A few people become users. A harmless table starts holding data you care about. The project goes from "look what I made" to "oh no, I am responsible for this now."

The internet is noticing

“A lot of security is contextual.”

Jack Cable

Security researcher

The internet is noticing

“Speed without control is a liability, not an advantage.”

Manav Khurana

GitLab

There's also a clean line you cross without noticing: the moment your app touches someone else's personal data. Before that, a bug is your problem. After that, a bug is their problem. It becomes a fundamentally different kind of responsibility even if the code did not change at all.

GitLab AI accountability report

AI code is moving faster than control.

June 23, 2026
Governance challenges
92%
Review bottleneck
85%
Post-generation governance pain
84%
New technical debt risk
82%
AI adopted before policy
80%

Generation got faster. Accountability did not automatically come along for the ride.

Source: GitLab research. Manav Khurana put the problem cleanly: speed without control is "a liability, not an advantage."

iii.The surprise was not insecure code

That would be too easy. There are already plenty of posts saying AI-generated code can be insecure. And yes, that matters. But my more interesting realization was different: I had trouble reconstructing the story of the app.

Not the code. The story.

That stuff matters because software is not just code. Software is code plus decisions. Code plus tradeoffs. Code plus scars. Code plus "please do not touch this unless you enjoy sadness." And with AI coding, a lot of those decisions happen inside chat sessions that are easy to lose, hard to search, and weirdly detached from the actual project.

iii.The maturity curve has a dark sense of humor

Every vibe-coded app seems to go through the same emotional arc.

The Vibe-Coded App Maturity Curve

Fun -> consequences
Low consequence
High consequence
01 It works

The demo loads.

02 It has users

Shortcuts affect other people.

03 It has data

Fake data becomes real stakes.

04 It has risks

Review and auth suddenly matter.

05 It has lore

Fragile fixes become tribal knowledge.

06 It needs memory

Warnings need somewhere durable to live.

You do not graduate the curve by writing more code. You graduate it by remembering the shortcuts and warnings that came with the last round.

iv.The actual problem was forgotten risk

I started noticing a pattern. The app did not need me to remember everything. It needed me to remember the things that would hurt later. That is a much smaller and more useful category.

Things like this feature was built quickly for a demo. This endpoint should not be exposed publicly yet. This data model works for one user but probably not for teams. This auth path needs another review. This dependency was accepted quickly and should be checked later. This whole area needs a human review before launch.

That is not documentation exactly. It is not a ticket exactly. It is not a code comment exactly. It is more like a project conscience. A small voice that says: hey, before you ship this, you should remember what happened here.

Vibe coding creates software faster than it creates shared understanding.

v.Where memory clicked

This is where Empirical started to make more sense to me in a new way. I was not trying to create some grand AI memory architecture. I was just tired of losing the important little warnings. So I started saving them.

Not entire transcripts. Not every thought. Not a giant context dump. Just the stuff I knew future-me or future-agent would need.

Before

The agent asks what next

I spend ten minutes re-explaining what the app is, what we already tried, what broke, what I am nervous about, and what should not be touched.

After

The session starts with risk

Known project risks, launch blockers, previous failed approaches, important UI decisions, security-sensitive areas, and unresolved technical debt are already there.

I started saving these warnings in Empirical because I did not want them buried in a chat transcript.

Project memory launch-sensitive notes
AuthBefore deploying this, review auth and public routes again.
SchemaThis data model works for one user. It probably does not work for teams.
UIDo not regenerate the dashboard layout without checking the saved decisions first.
DebtThis feature was built around a demo assumption, not a production assumption.
LaunchThis area needs a human review before anything public touches it.

Empirical was not useful because it remembered everything. It was useful because it gave the project a place to remember what was easy to forget. That does not make the agent perfect. It just makes the conversation less amnesiac. Which, frankly, is a low bar. But a surprisingly useful one.

ThingWhere it belongs
How to run the appREADME
Current taskPrompt
Permanent repo rulesAGENTS.md / project instructions
Product decisionsDocs or issues
Repeated agent mistakesMemory
“Don't forget this before launch” warningsMemory
Security concerns tied to past decisionsMemory
Temporary implementation shortcutsMemory or issue tracker
Human-facing explanationsDocs
“I was tired and said yes to this”Therapy, then memory

vi.Security is contextual

The security lesson here is not that AI-generated code is automatically bad. That is too easy, and not very useful.

The better lesson is that AI makes it extremely easy to create working software before you have created the habits that normally surround working software: review, threat modeling, access control, traceability, test coverage, deployment hygiene, ownership, and remembering why something was built the way it was.

Working code answers can this run? It does not answer should this ship?

That is why Cable's framing matters. The same code can be fine for a local prototype and reckless for a public app. The same shortcut can be harmless with fake data and dangerous with user data. The same route can be tolerable behind admin auth and terrifying on the open internet wearing a little hello-world hat.

The question is not just "is this code secure?" The better question is "secure for what use, with what data, under what assumptions?" Those assumptions need somewhere to live.

Project fossils the mini-story nobody wants
TODO: replace this later
temporary fix
quick workaround
demo only
probably needs auth
revisit before launch

There is a very specific flavor of shame that comes from finding your own TODO comment in code the AI wrote after you asked it to clean things up. It is like getting haunted by a ghost you personally hired. Nothing humbles a person like realizing the warning label was written by past-you, ignored by current-you, and about to be rediscovered by future-you during a production incident.

Sticky note checklist that says: Before launch, check auth, remove demo assumptions, review public routes, stop trusting tired past-me.
The launch checklist I apparently need when past-me starts making executive decisions after midnight.

This is why memory started to feel less like a feature and more like a seatbelt. Not exciting. Not flashy. But you notice when it is missing.

A transcript remembers what was said. A scar remembers what it cost.

LayerQuestion it answers
Current promptWhat am I doing right now?
Project memoryWhat should not be forgotten?
Docs / repo / issuesWhat is the durable source of truth?

Save the scar, not the transcript. Save the assumption, not the entire discussion. Save the launch warning. Save the repeated correction. Save the boundary. If you have told the AI the same thing twice, it probably belongs in memory.

vii.The boring practical conclusion

I am still bullish on vibe coding. I love how fast it turns an idea into something you can click. But I am less casual about it now, because the more useful the app becomes, the more expensive forgotten context gets.

When an AI-generated app is just a sketch, forgetting is annoying. When it has users, forgetting is risk. When it has data, forgetting is liability. When it has a future, forgetting becomes debt.

Vibe coding did not just make me faster. It made memory more important. Not memory as in save every chat. Memory as in what did we learn that we will regret losing?

That is where Empirical clicked for me: not as a magic fix, not as a replacement for security review, not as an excuse to ship sloppy code, just as a place for the project to remember the warnings, decisions, scars, and assumptions that usually disappear between sessions.

Vibe coding gave me speed. Memory gave me a little bit of judgment back.

For the app that grew up

Give the project a place to remember.

Empirical holds the contextual decisions, launch-day warnings, and the "this is load-bearing, don't touch it" notes so the next session sees the scar before it reopens the wound.

All Empirical blog posts