Unless you're being paid by the hour or don't care when the product ships, it's always a good idea to just to the simplest implementation that works. Premature prevention of technical debt is the root of all evil.
"The simplest implementation that works" is not the antithesis of "Code without technical debt." For example, code that has not been thoroughly tested can not be said to "work." Likewise, one form of technical debt is code that is not the simplest possible implementation. For example, Dick and Jane each implement their own versions of the same functionality, producing code that is not DRY. This has local simplicity,…
Suppose Dick and Jane both implement their simple feature which is fairly similar. I'd estimate that much of the time it's costless to have two slightly different approaches in the codebase. In those cases it's also nearly costless to retroactively standardize.
In the remaining cases where it isn't costless to retroactively standardize, a better optimized abstraction would have been useful. But, depending on the product's life cycle, building that abstraction may or may not count as premature optimization. Suppose Dick's feature takes off but Jane's ends up being phased out, now the extra month building the abstraction was totally wasted.
Is that technical debt a big leveraged call option that could cripple the team/org? Maybe, but maybe not. Maybe it's just a hassle that needs to be borne only if the feature succeeded, and thus would have been premature optimization if the feature didn't succeed. In other words exploration vs exploitation and the risk of cementing possibly unneeded conceptual overhead. I guess my intuition is that premature optimization comes from attempting in advance to pave the way for a low technical debt future on an unknown feature horizon.
It takes real skill to avoid this if one is too attuned to technical debt elimination as a design goal.