The rewrite passed every test I had. Three days later support was sitting on a queue of people asking why they'd been told twice that their payment went through.
I was pulling a notification service out of an inherited monolith: fan-out to WhatsApp, Telegram, web and mobile push. The old code was ugly. One function queried a log table, assembled the recipient list, and sent everything inline. The new one was a consumer per channel, independent and retryable. Strictly better on paper.
What I missed: the old query joined against that log table before sending. Nobody had written that down as deduplication. Not in a ticket, not in a comment. It was a side effect of how the list got built, and it had been quietly absorbing retries for years.
My clean version had no such accident. Every retry was a new message. And on payment notifications a duplicate doesn't read as a bug to the person getting it, it reads as being charged twice.
So when people ask what to check before a rewrite, I don't start with architecture or service boundaries. I start here: which behaviors of this system are load-bearing without being specified anywhere? Then: who notices if they change, and how fast do they notice?
What I do differently now is run old and new side by side on real traffic before cutover, then diff the outputs. Every difference becomes an explicit decision: keep the quirk, or remove it on purpose. Nothing inherited silently, nothing lost silently.
I wrote up the rest of the questions I ask before touching an inherited system here: https://polycratia.com/c/feff745e
If you've done a rewrite, I'd like to hear which accidental behavior turned out to be load-bearing...