I Built a Blog That Yells at Me If Two Robots Write the Same Diary Entry

· 4 min read · by Michael Kaminski

Behind the Build, Vol. 2: today's work was a new Websites tab showcasing live production sites, plus a small guardrail that stops this very writing series from ever double-booking a day.

Yesterday this series was born. Today it nearly had an identity crisis. This portfolio's "Behind the Build" posts get generated by an automated routine — sometimes me at the keyboard, sometimes a scheduled run while I'm asleep — and it occurred to someone (me, at 11pm, mildly panicked) that nothing was stopping two of those runs from writing about the same day twice. So today's actual build work was equal parts "add a nice new page" and "stop my own robots from tripping over each other."

The fun part: a Websites tab

The portfolio got a new /websites route — a proper showcase of the live production sites I've shipped, each with its own screenshot, a one-line pitch, the domain, and a few tech tags. Twelve cards, twelve little proofs that the code actually runs somewhere other than my laptop. Capturing the screenshots was the tedious part; wiring up lazy-loading, JSON-LD, and a sitemap entry so search engines know the page exists was the "eat your vegetables" part. Nobody claps for sitemap.xml. I clap for sitemap.xml.

The less fun part: my diary can duplicate itself

Here's the problem in plain English: this article series is data — an array of objects in articles.ts — and more than one process can write to it. A manual commit here, a scheduled run there, both reasonably assuming they're the only one adding today's entry. Left alone, that's a recipe for two "July 24th" articles arguing with each other about what actually happened on July 24th, which is a genuinely strange failure mode for a personal blog to have.

What actually shipped

  • A load-time guard: the module now walks every article and throws immediately if two of them share a date. Not a lint rule, not a code review comment — a hard crash the instant the site tries to boot with a collision.
  • A written-down routine: CLAUDE.md now spells out the rules in plain language — check production first, never duplicate a date, add exactly one article per run, merge instead of overwrite when things have diverged. Documentation as a seatbelt for future-me and future-robots alike.
  • A merge, not a coin flip: when two branches of work landed the same morning, the fix wasn't to pick a winner — it was to keep both and let the date-collision check prove they coexist safely.

The lesson

The scariest bugs aren't the ones that crash loudly — they're the ones that quietly produce two plausible, slightly different versions of the truth and let you find out later, in front of someone else. A one-line invariant check at module load is cheap insurance against a very expensive kind of confusion. Also: if you're going to let robots keep your diary, teach them to compare notes first.

Next time in Behind the Build: whatever the robots get up to next.

All writing · Projects · Michael Kaminski


Book a Call · Download Resume · MKaminski1337@gmail.com · (404) 838-8613 · LinkedIn · GitHub · DEV