Day 76: the 60-day gate finally opened
May 10 was the day the Ominvo Google Business Profile verified. July 9 — today — is 60 days later, to the day. Google's API access application requires a profile verified and active for 60+ days before it'll even accept a submission. Today was the earliest date the form would take it. So I submitted it this morning. Then the rest of the day went sideways in three smaller ways: I nearly disabled a workflow that was working exactly as designed, spent an hour shipping a security header almost nobody will ever notice, and updated the trust page so the handful of people who do look can see it. Continuing the security thread from yesterday's post — verify-before-fix showed up again today, in a different shape.
The banner that wasn't what it looked like
Opened Cloud Console this morning and enabled the visible Business Profile APIs — Account Management, Business Information, Notification Settings, Performance. The core Google My Business API itself stays invisible until Google approves the application, so there was nothing to toggle there yet. Went to submit the application form, and Google's own UI threw up a banner at the top: "Verification required for nishantaduttaa@gmail.com — some of your edits may not be visible to customers until you're verified. Get verified."
I nearly closed the tab and went hunting for a re-verification flow. Instead I checked Business Profile Manager directly first. Profile status: verified, blue badge and all. The banner turned out to be about one specific incomplete edit — a missing phone number field, missing hours on one day — not a challenge to the core verification. The base status was intact the whole time. The API application accepts the profile as-is regardless of that one cosmetic gap. Submitted. Case ID 1-7489000041734. Lesson repeated from yesterday in a new context: banners aren't always describing what you assume they're describing. Check the underlying state before reacting to the surface signal.
The auto-rollback I almost broke
Got a GitHub Actions failure email around 2:30 PM. Workflow name: "Auto-Rollback on App Failure." I didn't immediately remember writing it. First instinct was to read the YAML in isolation — saw the cron schedule running every 5 minutes, pattern-matched that to "too aggressive," and was two paragraphs into a fix recommendation before I stopped and checked past chats instead of just my read of the file in front of me.
Turns out I built this on Day 61, and it was deliberate end to end: a three-strikes health check against a shallow /api/ping endpoint, kept separate on purpose from the deep /api/health check that covers Supabase and Stripe, specifically so the rollback only fires when our own code breaks and not when a third party is having a bad day. Correct rollback target selection, GitHub issue creation on trigger, all designed on purpose. Today's failure was GitHub's own runner allocation at their infrastructure layer, not a flaw in the workflow logic. If I'd shipped the disable prompt off my first read, I'd have torn out working monitoring to fix a problem that didn't exist — the same class of mistake as recommending a fix without reading the codebase first. Read the history before touching existing infrastructure, even the infrastructure you built yourself.
Shipping CSP the way that doesn't break production
Quick primer for anyone who hasn't run into this: a Content-Security-Policy is an HTTP header that tells the browser which origins it's allowed to trust for scripts, styles, images, and network calls. It's the standard defense against a whole class of injection attacks — if someone manages to sneak a malicious script tag onto your page, CSP tells the browser to refuse to run it, full stop.
The trick is shipping one without breaking your own site the moment it goes live. Content-Security-Policy-Report-Only has the browser evaluate the policy and log every violation to the console, without actually enforcing anything. You ship the policy, then watch real traffic for a few days — legitimate origins you forgot to allowlist, third-party scripts you didn't remember existed. After 48-72 hours of clean logs, flipping the header name to enforcing mode becomes a one-line follow-up commit instead of a gamble. It's the difference between finding out Sentry loads from browser.sentry-cdn.com in a log line versus finding out because the whole site went dark.
Ominvo's first CSP went live today, report-only. Full detail on every hardening header shipped so far, including this one, is on the security page.
What today's shape taught me about pre-launch work
Three tasks shipped today with three completely different value profiles. The GBP API submission was 15 minutes of clerical work that unlocks roughly three weeks of runway on an approval clock I can't speed up. The CSP header is defense-in-depth against attacks that may never actually be attempted, and no end user will ever see it. The security page update is a trust artifact for the sliver of people who read it before signing up — probably under 1% of visitors.
Critical-path unlock, defensive infrastructure, trust-signal polish. None of it is a feature a visitor can click. Pre-launch work skews heavier toward unlock-and-infrastructure than toward anything visible, and that ratio surprised me when I actually laid the day out like this. Naming it here for whoever's reading pre-launch build-in-public content next, so the mix doesn't come as a surprise: some days you ship things nobody sees so the days everyone sees can actually happen. Full details on all three, as always, on the changelog.
Written by
The founder of Ominvo
Building review management for single-location small businesses. Join the waitlist →