A very simple but effective thing I started doing is writing „cleanup“ comments. Duplication, ad-hoc coupling and such.
In the comments I sometimes decribe how one could go about it, so I remember later what the issue might be.
There are several benefits to this. For one, prioritizing what matters in the moment. Letting things unfold for real, so the right structure becomes more obvious later. Also it sometimes sparks little discussions that are useful and reveal a pragmatic way forward.
As c2 wiki has it[1]
> * The first time you do something, you just do it.
> * The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway.[...]
> * The third time you do something similar, you refactor.
E.g. I've seen a lot of Incidental Duplication being refactored out, leaving the code apparently cleaner, but in practice, really much worse.
1. You write some code.
2. You write a duplicate of #1.
3. You write another duplicate of #1, so you should refactor. But the PM doesn't understand why you're changing the code you made in #1 and #2 as part of ticket #3.
So the jaded devs are certain the duplication will occur, but believe their choice is either to pre-emptively fix the duplication at #1, or never to fix it at all.
If that is the case, the PM does not understand red-green-refactor, always-refactoring, or even just plain refactoring. I'd say the PM doesn't even understand the idea of technical debt, in that case.
The problem is certainly the PM's disconnect to how to keep a codebase (and their team) sane in the most common programming practices. And not the refactoring itself.
Mess in code is inevitable. Taking on technical debt is fine, knowingly leaving certain parts messy is fine too. Provided you do so knowingly, and manageable.
So, indeed: I very much prefer to see someone who has horrible code but can explain why it wasn't a problem there, or how they refactored out of it into a beauty, than someone who has one "initial commit" that is that beauty immediately.
Edit: I've worked in places where there was a mess-paralysis. An in-grained fear for breaking stuff (but not the prowess to solve that with better CI, tests etc). Where we could not react to market or customer demands, where all progress was halted by that fear to have to go into "The Mess" and break stuff, or introduce New Mess.