Every test I had, the matcher passed. In production it skipped payments without a word, and only ones that had arrived before a certain stretch of the past.
This was a reconciliation job: incoming bank transfers tagged only by requisites, matched against user obligations. I had rewritten the normalization step. Locally every fixture matched. Staging matched. Then the unmatched queue started filling up with old transfers that had reconciled fine for years.
The environments were identical. The data was not.
That requisites column had been written by three generations of my own code. Different trimming, different handling of separators, different ideas about what counts as the same reference. Each generation was correct when it shipped. My fixtures all came out of the newest writer, so my tests only ever saw the current dialect. The older dialects existed nowhere except production.
The cost was a day of staring at a matcher that was, in isolation, right.
What I do differently now: before I touch any read path, I ask how many writers have ever touched that table. Then I pull a sample of the genuinely distinct value shapes, anonymize them, and keep one fixture per shape, including the ones no live code can produce anymore. Historical dialects are part of the schema whether you documented them or not.
Local parity gets you the same runtime. It does not get you the same sediment.
I write up more of these production-only failure modes on my blog: https://polycratia.com/c/a300efcf
When you change a normalizer, I'd like to know how you find out which formats are already sitting in the table.