Getting it done is a bare necessity of a good programmer, but what separates the mediocre programmer from a good programmer is whether they get it done in a more maintainable fashion.
It is completely ridiculous to say as long as one can get a product launched, they are a good programmer, because you're likely praising a group, half of whom are good programmers, and half of whom are sinking the product more and more over time. This is a common happening I see with praise of engineers from a management perspective, and why so often companies sink without knowing where exactly they went wrong.
You can judge if a programmer is good, not by tearing apart and poking at the mistakes they made in a new project, but if they proceeded to code using strong abstractions and decoupled code. The easiest programmers to fire are the ones who don't ship, and the programmers that tend to be the costliest to a business are the ones who ship crap code.
Obviously no-one can see the future. The problem isn't when code can't be easily extended, the problem is when code is easily broken.
I'm not sure if there is much of a distinction there. I can extend your code with very little effort if I'm permitted to break it in the process.
Further, there are times when a good programmer must deliberately exclude forward thinking solutions because a non-functioning product precludes a successful business. Yes, it should still be a secure solution. Yes, a TODO label may be warranted, but a surefire way to get yourself labeled as a bad programmer is to spend weeks working out "future proof" solutions while the competition is shipping an application that can be successfully executed.