the story names · vibe coding · responsibility

How Jenni
came to be.

A note on names, the kind of vibe coding I want to defend, and why the human stays responsible when the AI types faster than them.

Forrest had a reason. So do my downloads.

In Forrest Gump, Jenny is the reason Forrest runs. Not the route, not the trainer, not the medal — the reason. He runs because she taught him to.

My Jenni is the same idea, just for my software. She's why every release of every project I ship lands somewhere reliable, gets verified, and is reachable from a single URL by tomorrow morning's update check.

The name is silly. I know. It also stuck the moment I typed it — and yes, with an i, deliberate. Forrest's Jenny had a y; mine doesn't. The spelling is the only thing I can keep straight at 2 a.m.

I was already doing this. Badly.

Long before Jenni had a name, I was already self-hosting downloads. Old habit, predates this stack: zip the binary, drop it in a download folder on the server, link the URL from wherever it had to be linked. It worked. It was also messy.

GitHub had a different role for me — it's where I show code to people. Pull requests, READMEs, the public face. Not where my apps go to fetch their next version. That always felt mismatched: the place where strangers read your code is not the same place where production should download from.

When WordPress plugins joined the pile of things I ship, the versioning side stopped being optional. Two plugins becomes ten becomes twenty, and every one of them needs a stable update endpoint, a verifiable hash, a virus scan that someone in legal can point to. The zip-in-a-folder pattern doesn't scale, and nobody needs another half-finished script to glue it together.

Jenni is the formal version of what I was already doing — plus the things I should have been doing all along. She also offers download widgets you can embed on external sites: upload a new version on jenni.download, the widget on someone else's page delivers the latest version with the ClamAV scan attached. Why include the scan? Why not.

The kind of vibe coding I want to defend.

I asked Claude to build me a download server. That sentence makes some developers wince. They picture a junior dev pasting unreviewed AI output into production and calling it shipped. That is not what vibe coding looks like — at least not the version I'd defend.

Most people think vibe coding means typing a sentence into ChatGPT and watching files appear. That misses where the actual work is. ChatGPT, in my workflow, is for discussion — sounding out an idea, arguing about scope, talking through trade-offs before any code touches disk. The development happens elsewhere: Claude Code with a stack of Skills, plus Get Shit Done for the disciplined slow parts — milestones, plans, atomic commits, code review as its own pass.

Even there, the prompt is not "hey Claude, write me XYZ." It's a conversation. I bring the what and the why. I argue with Get Shit Done about which milestone holds which scope, and what's allowed to bleed into the next one. I tell the AI how I, as a human, picture the thing — the texture, the constraints, the parts I won't compromise on. The AI is the developer in that pairing. It can also test the finished product live.

What stays with the human is control. Reading the diff. Catching the silent failures. Knowing when to say "no, that abstraction is wrong, throw it away." Making sure no API key ends up in a public repo, no migration drops a column without a backup, no --force push lands on main at midnight. The AI types faster than me. It does not assume responsibility.

Vibe coding is cool. It also comes with responsibility — especially when the thing you build will run on someone else's stack, ship to third parties, hold their files. Jenni was an exercise in exactly that: I read every line of the upload pipeline, hardened the bits that mattered (Argon2id, zip-slip, zip-bomb caps, ClamAV, signed cookies, CSP headers, rate-limited login, non-root container), ran her against my own production for months before this site went up. The code is fast. The trust is slow.

That's the vibe coding I want to defend.

Already shipping. Quietly.

Jenni runs at jenni.noschmarrn.dev, my own staging-but- actually-production instance. She ships every BreznFlow release, every Schneespur update, plus a handful of smaller things. About thirty release uploads since the start of the year. Zero incidents.

She's the most-used and least-talked-about thing in my stack — which is the highest compliment I have for a piece of indie infrastructure. The day I notice she's there is the day she failed at her job.

Before she goes public.

A few things to finish first: better release-notes rendering, an ed25519 signature option in the API response, an honest CHANGELOG of every security choice I made so others can audit them, and a docker compose file that makes the install a single command.

Then it's a public repo, an MIT license, and — if the indie corner of the internet does what it usually does — a pile of homelab forks running her by the end of the day she lands.

06 · still cooking

If you got this far, you probably get it. If you've got a project that wants this kind of update endpoint — or you just want to swap notes on vibe coding done well — I'd genuinely like to hear from you.

info@noschmarrn.dev