But I do think it falls apart when applied at a more macro level.
The kind of duplication you want to avoid is knowledge duplication. If two pieces of code literally do the same thing but for different reasons/purposes, it may not be a good idea to deduplicate them.
The result made it hard to understand the code, and hard to graft in new functionality. So over time I refactored it to duplicate the code, but each string of code is a lot easier to understand.
I know that eventually I can move all the identical code out of there to its own service, and replace the 8 services with just 8 simple configuration lists, and that's definitely where we're going at some point in the future, but for now, the 8 times duplication is actually fine. People know these services and what they do, and I know they're conceptually all instances of the same thing, it's just not quite represented that way in the code yet. We'll get there.
It's possible a few still have some exceptions, so that needs to be figured out first, but due to the way the code is put together, there's no rush; people are only changing the parts they're meant to change anyway.
We were looking at a pull I'd created and he asked 'are these things really the same or is it just a coincidence because the features aren't mature enough yet?'. And yes I'd conflated two things with entirely different intents by over-abstracting.