True. Not everything will change. But you don't know which ones will and which ones won't. So be ready.
> I think the problem I have with your principle is that many of the techniques to accommodate change (the "IOC, interfaces, etc" you mention) can have a real and immediate cost when it comes to understanding a codebase, and that's the fundamental sin when it comes to maintainability.
Not true. The benefits of IOC and loose coupling are well established and I won't even bother relisting them here. I'll only say that those benefits usually outweigh the minor indirection you get as a result.
The question then becomes, do you loose couple from the beginning? or tightly couple everywhere and loosen as you go. I tend towards doing it from the start, for consistency sake (help those poor junior engineers out), and for all the other benefits (which again, i don't want to list, but i'll add the one biggie - unit and integration testing).
I'll also note that IOC/loose coupling is rarely the cause of the over abstraction you fear. I've seen it way more in domain models or APIs.
There are many fads, new fangled doo-dads, thingamajigs in our software world. New frameworks, seismic shifts in architecture, herd mentality etc. IOC/loose coupling isn't one of them. It's good, old engineering practice.