Day 33: Five commits, one security call, and what the changelog page taught me
The day in numbers
Five commits. About four hours of focused work. Roughly 1,800 words of new content shipped across two blog posts. One security decision that took fifteen minutes of real thinking before I made it.
Day 33 wasn't a feature day. It was the kind of day where you tidy up around the foundation you've been pouring all week.
The security call: opening up /api/health
UptimeRobot needed to ping /api/health every five minutes. The endpoint was originally token-gated — anyone hitting it without the right header got a 401. That worked, but it added a fragile coupling: rotate the token, monitoring breaks, you don't notice until something else breaks first.
I removed the gate.
Before doing it I sat with the question for a while. The honest test for opening something up isn't "could a security person object?" — they always can. The test is: what specifically gets exposed, and how would an attacker monetize that exposure?
Here's what /api/health returns: four service names (Supabase, Stripe, Resend, Anthropic — already public knowledge, mentioned in our status page and our blog), four response times in milliseconds, four ok/degraded/down statuses. No counts, no IDs, no row data, no auth state, no user info.
What an attacker could learn: "Ominvo uses Supabase as their database, and right now Supabase is responding in 1,200ms." That's not operationally useful. They can't probe further from there. The endpoint accepts no inputs.
So I shipped it.
What I'd never make public: anything with row counts (leaks traffic estimates), anything authenticated (leaks user state), anything that takes user input (creates an attack surface). Health checks with zero inputs and zero row data are in a different category.
The changelog page
I shipped a /changelog before I had earned one. Six entries — Day 28 through Day 33 — none of which most users would care about.
The argument is changelog-as-PR. Stripe does this. Linear does this. Vercel does this. When you launch, the first thing journalists, prospects, and your own team checks is the changelog. If it's empty, you look like you're still warming up. If it's full, you look like a moving train.
So you start it before launch. You write entries that are real but minor — auth fix, footer cleanup, new endpoint — and by the time launch lands, the page has 30 entries and looks lived-in.
Honest acknowledgment: a changelog with six entries reads more aspirational than informational right now. That's fine. The infrastructure exists, the design language is set, and adding entries is a 60-second job per ship.
The social icons fix
This one barely deserves a paragraph except for the lesson: pre-launch sites accumulate ghost links. The footer had LinkedIn and YouTube icons wired to URLs that don't exist — placeholder code from an earlier scaffold. I caught it because I was clicking around looking for something unrelated.
Audit your footer before launch. Audit every "Coming soon" disclaimer. Audit the pages your nav links to and confirm they actually render. The bigger your site gets, the more ghost links accumulate, and the worse a clicked broken link looks to a first-time visitor.
Two blog posts in one day
Day 33 shipped two posts: Day 32's retrospective and a longer field-notes piece on what Ominvo actually does and why it exists.
These do different jobs. The retros are for the build-in-public audience and for me, six months from now, when I want to remember what Day 33 felt like. The field-notes piece is for someone who lands on the blog cold and wants to understand the product without reading the marketing copy. One is journal, the other is positioning.
I used to think you should pick one. You shouldn't. Different posts serve different readers, and "is this the right voice for the brand" is the wrong question — the right question is "who is this paragraph for."
What I shipped that nobody will see
Most of Day 33 is invisible from the outside. The security thinking. The endpoint changes. The footer cleanup. The blog scaffolding decisions that compound over the next year of posts.
Pre-launch posture is mostly this: 80% of the work doesn't show up on the homepage. It shows up as the absence of bugs, the smoothness of the auth flow, the speed of a page load, the fact that the changelog exists. Users don't notice any of it individually, but they feel the cumulative weight.
What broke today
Nothing. No incidents, no rollbacks, no security drills.
That's notable because Day 31 had a token leak that ate half the day. Pattern I'm starting to see: a leak-day or stress-day, followed by a cleanup-day or compounding-day. The bad days teach you what to add to PANIC.md. The good days are when you add it.
Tomorrow
Day 34 is the Health tab raw log table — the placeholder I left when I shipped the Health tab on Day 32. Plus one missing page. Stay tuned.
Tagged
Written by
The founder of Ominvo
Building review management for single-location small businesses. Join the waitlist →