Hi Chadwin. Some of your other points will help with a spec that is not defined 100%, particularly designing a system that is flexible to change and communication. If the system is easy to change then finding out you need to make a change at a late stage isn't as much of a problem and by communicating with the client often you should spot such things a bit earlier.
Sometimes all you can do is know a particular client can be problematic and schedule extra time to deal with the inevitable changes.
Dave Murray
.NET developer with a passion for mobile and DevOps.
In my experience that is almost impossible to acheive. I think only one project I've worked on had defined goals and outcomes before the code was written that did not subsequently change and that was a very short contract making a small addition to an existing system.
"No plan survives contact with the enemy" is as true today as it was in 19th century Prussia.