Most portfolios introduce themselves before they show anything. The best ones reverse the order. A short argument for putting the work first.

A public, unauthenticated form that writes to the database and sends email is a bot's favorite denial-of-service target. No single control is enough. The point is layering honeypot, Turnstile, rate limiting, and email verification so one layer failing doesn't sink the rest.

A JS-readable token in localStorage is one XSS away from account takeover. Moving it into an HttpOnly cookie is the well-known fix but ActionController::API has no cookies, no CSRF, and a few other surprises waiting on the first commit.

A nonce and 'unsafe-inline' in the same CSP directive: the browser silently drops 'unsafe-inline' by spec. Debugging a policy that quietly broke production.

Three vcr recording behaviors that never raise an error: the config beats the CLI flag, ambient traffic gets taped, and re-records append instead of replacing.

Every LLM provider goes down eventually, so the obvious move is to retry against another one. The naive rescue-and-retry works until your bill spikes and the logs can't tell you how often failover fired or what it cost. Here's the version that keeps the receipts.

A published portfolio — complete, polished, exactly what search engines want — quietly vanished from Google. The culprit wasn't the live page at all. It was a private draft nobody could see, plus a one-line assumption in our SEO gate that counted it as a duplicate. A short debugging story about canonical URLs, sensible defaults, and the danger of de-indexing both copies of a tie.
