You neglect something I think is very important: You do not normally know up front what code will live and not.
If you carefully (over-)engineer everything you will perhaps not get time to write all those short-lived failures that preceded that long-lasting success.
Of course I wish that piece of code that I hacked 3 years ago and never got around to refactor was better done the first time! But that kind of thinking ignores the fact that if my mentality had been "perfect up front" then what I would have spent all my time perfecting was the previous piece of code, the one I have long since deleted. I never would have gotten around to writing the hacky code I kept.