I have been working with a lot of vibe coders at work, and it got me thinking about maintenance. Software needs looking after once you ship it, packages go out of date and vulnerabilities get found, and when you are new to building with AI it is easy not to think about any of this.
Then I realized I should apply the same thinking to my own projects, so I went through their git history. I found plenty, although not the kind of thing I expected, and one of them was still open on the day I looked.
So this is no longer a post about what other people forget. It is about me.
One advisory, three apps
On October 14, Next.js published fixes for two critical vulnerabilities and a high-severity one. "Critical" here means remote code execution, i.e. under certain conditions, a stranger on the internet could run their own code on your server without logging in. The fix arrived in version 16.4.1.
I run three apps on Next.js, all built with AI coding tools and all with the same person responsible, which is me. This is what happened:
| App | When its code moved to a patched version | Time after the advisory | Live in production |
|---|---|---|---|
| chandlernguyen.com | October 18 | 4 days | October 18 |
| DIALØGUE | October 29 | 15 days | October 29 |
| Prova | November 3 | 20 days | November 3 |
When I looked on November 3, Prova was still locked to Next.js 16.2.6, the version it had been on since May, and production was running it. Running pnpm audit --prod listed 5 critical advisories, all of them in Next.js.
That number sounds worse than what I found, so I want to be fair about it. When I went through each one with my AI tools, most of the critical ones did not apply to Prova. It has no use cache functions, it doesn't run on Windows, and I found no attacker-controlled input reaching the next/og code. The image optimization ones probably don't apply on Vercel either, however that is an inference from how the platform behaves, as I couldn't find a statement from Vercel saying so. What clearly did apply was a high-severity denial of service issue in Server Actions, which means someone could have disrupted the app, and that stayed live until the patch.
I moved production to Next.js 16.4.5 the same day. The audit went from 5 critical to 0, and most of the high-severity ones cleared as well. What remains is outside Next.js and I still need to work through it, so this is better but not clean.
I can't call any of that good maintenance. The worst advisories mostly missed Prova because of how it happens to be built, not because anyone checked. That is luck, and I only know it because I finally looked.
I also can't take much credit for the first row. My site's October 18 commit was a general toolchain upgrade, from Next.js 16.1.6, and its message doesn't mention the advisory. It may simply have been good timing.
Why being busy did not help
The easy explanation would be that Prova had been neglected, and there is some truth to that. It had a 41-day gap between commits in August and September.
However, that explanation falls apart in October. Prova had 175 commits that month. I shipped fixes for iOS, billing, email and translations, and the Next.js version did not move. On October 30 I even wrote a dependency maintenance plan for it. Its status line reads "planned; no implementation started."
So activity is not maintenance, and I think this is the part that matters most for anyone building with AI. When you build a feature, you get feedback immediately. You can see the button, click it and watch it work. When a vulnerability is announced in a package you installed five months ago, you get nothing. The app keeps serving pages, the tests stay green and the build passes. Nothing is broken, and that is exactly why nobody looks.
It would be like a smoke alarm that only makes a sound if you go and ask it. AI tools make it much cheaper to build the house. They don't install the alarm.
This also happened to me before. DIALØGUE had no commits between October 6, 2025 and January 11, 2026. React2Shell, a critical Next.js and React vulnerability, became public in early December. My patch commit is dated January 11, more than five weeks later, and the oldest production deployment record I can still see is from January 18, so I can't tell you exactly what was running in December. What probably helped me most had nothing to do with me: Vercel says it rolled out firewall rules for all its customers, while also saying plainly not to rely on them instead of patching.
I want to be clear on one thing, because the phrase "vibe coder" can sound like an insult. I learned to code through structured courses, including a cybersecurity certificate, and these repos have tests and review gates, and this still happened. So I don't think it is a beginner problem. I think it is what happens by default when creating software gets cheap and nobody is assigned to watch it.
What the alarm looks like
The good news is that a very small check changes this a lot.
On October 27, I added pnpm audit --prod to my site's CI, which is just the automatic set of checks that runs when code is pushed. On October 28 it failed, because of an advisory in an email rendering library that my site pulled in but never used, and on October 29 I removed that library. It took two days and I didn't have to remember anything.
Nothing about that was clever. Somebody, or something, simply has to be told to look.
Updating packages would not have saved me
If this post stopped there, it would give you false comfort, because some of the more uncomfortable fixes I made in October had nothing to do with outdated packages. They were mistakes in my own product.
In DIALØGUE, for example:
- Privileged database functions could be called with only the public key, and a logged-in user could reach functions that were meant only for my backend.
- A refunded podcast could come back to life and finish without being charged again, and on a small number of podcasts it did.
In Prova, public database roles had inherited permissions no one had chosen, such as TRUNCATE, because they came from a platform default. No app path used them, but they were there.
No version upgrade fixes any of this. These apps had been running with these problems, and nothing failed there either. They only surfaced because a security review went looking for them, and I had done earlier security reviews on these products that did not catch them all.
Was any of this misused? I don't know, and I can't fully find out. My database logs only go back about 90 days, and some of these problems are older than that. In the period I can see, I found no outside calls to those functions. That covers a limited window and does not show that nothing happened. I also can't tell who or what restarted those refunded podcasts, although a retry in my own code is my best guess.
This is not a complete list either. I am still working through other issues, and I won't describe those while they are open.
The model question is not what I thought it was
I expected to write that old AI models cost you more money. I can't support that. I looked, and I don't have a before-and-after cost in any of these repos, so it would just be a guess.
What I found is stranger. My DIALØGUE script-draft and review models were set to gemini-3.5-flash until October 12. Google's documentation now says that endpoint is not shutting down and automatically routes requests to gemini-3.6-flash. I don't know when that routing started, so I can't tell you which model was answering for how long. A model name in your config doesn't freeze the model.
Prices move as well. Gemini 3.8 Flash, which I moved Prova and DIALØGUE to in October, is listed at $0.75 per million input tokens and $3.75 per million output tokens through December 31. From January 1, 2027 that doubles to $1.50 and $7.50. I only moved to it last month, and I still have to work out what that does to my costs.
Upgrading is not free of risk either, and I don't want to pretend it is:
- Shortly after I switched Ask Sydney to DeepSeek Flash, at least one question failed in production because the model wanted more search rounds than my code allowed.
- When I moved Prova's embeddings, the first runs failed after the knowledge base table had been cleared, so retrieval was degraded until I recovered it.
- That same migration turned up a production setting that would have sent a Claude model name to Google's API.
The thing that made the Prova migration trustworthy was boring. I had a recorded evaluation from before the change, 22 out of 24 sprint review decisions correct, and I got the same score afterwards. Without that I would only have been hoping.
Should you maintain it at all?
The hardest question is the one I almost left out. Every app you ship is a small subscription you have to keep paying with your attention, and AI has made it very easy to sign up for more of them.
With STRAŦUM I made the other choice. I retired it and published v1 as a reference implementation. The repository says it is not maintained as a production service, and its security file lists the advisories I know about, including build-time dependency issues with no fix available, which it assesses as low practical risk. I think that is a perfectly honest outcome. The dishonest version is an app that still takes signups while nobody is watching it.
What I would do on Monday
If you have shipped something with AI and people are using it, this is the list I would start with. None of it needs to be perfect.
- Run the audit once, today.
npm audit --omit=devorpnpm audit --prod, in every repo that is live. Then ask your AI tool which of the results apply to how your app is built, since not all of them will. - Make that check automatic. Add it to CI so it can fail without you remembering. For an app you touch rarely, use a scheduled run too, because a check that only runs on a push won't help during a quiet month.
- Read your permissions, not just your packages. Ask what someone can do with only your public key and no account. Then test it on a local copy instead of assuming.
- Search your history for secrets. If a real key was ever committed, revoke it. Deleting the line is not enough.
- Find out how far back your logs go before you need them. That decides whether you can ever answer the question of whether something was misused.
- Keep one small evaluation for each AI feature. Even 20 real examples with known good answers will tell you whether a model change made things worse.
- Check your AI provider's deprecation and pricing pages on a schedule. Put it on your calendar. If you use Gemini 3.8 Flash, January 1 is already a good date to start with.
- Decide keep or retire for each app. If you are not going to watch it, take it down or say so.
I am still working out how much of this can be handed to an agent on a schedule. I do know that writing the plan on October 30 did not patch anything.
If you are building with AI, when did you last check something you already shipped, and what did you find? I would really like to know, especially if you have a better alarm than mine.