We agree that placeholder code shouldn't commit you to too much, but there are patterns that help you with that.
In the parent, the original decoupling turned out to be less performant (I take it) but wouldn't hinder completing the first draft or get in the way of a rewrite with closer coupling.
This is what I started doing in the last year or two. Now my abstracted code tends to be directly motivated through refactoring the copy-paste stuff, with only a little bit of intentional architecture generated after learning that the abstraction addresses a common concern. It's a very cultivated way of developing the code - picking fruit as it turns ripe.
Even so, some decisions turn out to be extraordinarily hard to undo. One of my great blunders was a poor choice of data structure (too greedy with RAM it turned out.) The more experience you have, the more likely you are to sidestep those fatal early choices, of course.
This sounds off to me; if you assume you'll need to change the architecture later on, aren't you better off starting with a decoupled system that can more easily be changed? Or are you essentially arguing for YAGNI, in the sense that decoupling upfront is potentially useless?
I think the problem is that you don't know where the boundaries of your abstractions should be until you have a better understand of what it takes to solve the problem.
A far more dangerous mindset is to think that when starting the problem you are capable of planning the perfect architecture up-front. Often you don't even know what the problem is. Far better to keep things coupled and simple till you know in retrospect that you need to split them out. Same goes for global state.
This is a hard lesson to learn. Abstraction is seductive.