Your suppression list belongs in the mailer, not the call site
Every "we accidentally emailed someone who unsubscribed" incident has the same root cause: the check lived in the code that sends, and one send path forgot it.
17 Aug 2026
Field notes
Practical notes on building, securing, and operating software when the details actually matter.
Every "we accidentally emailed someone who unsubscribed" incident has the same root cause: the check lived in the code that sends, and one send path forgot it.
17 Aug 2026
Validation fails, Laravel returns a 302, and the visitor sees "Service temporarily unavailable" instead of "email is required". Here is why, and what to do.
10 Aug 2026
If your privacy page says data is deleted after two years, something in your codebase has to actually delete it. Usually nothing does.
3 Aug 2026
Two CSP headers do not override each other. The browser enforces both, your new allowed origin never takes effect, and nothing in the response looks wrong.
27 Jul 2026
The command that rebuilds the database from nothing is the one command every new machine runs first, and it is the one nobody runs again after the first month.
20 Jul 2026
An element that animates from invisible, told only to stop animating, stays invisible. The page does not lose its motion - it loses its content, for the people who asked for less motion.
13 Jul 2026
We moved the analytics gate out of PHP so the HTML would stop varying by cookie. For a while the entire gate could have been deleted with every server-side test still green.
6 Jul 2026
The nightly job is green. The bucket has files in it. Nobody has ever taken one of those files and rebuilt a working database from it, so nobody knows whether they can.
29 Jun 2026