Leave off all details that the programmer doesn't need to know.

I differ on this, what you need is a clear road map, not people left in the dark. A feature for 2.0 may require a portion of 1.0 to be designed in a certain way, if you omit the knowledge of that feature coming down the road, you may be looking at a costly rewrite to adapt the app to that feature. Whereas the developer having for knowledge of the feature may steer them in designing the system with the though it mind that it will be coming.

you're paying multiple times for this first milestone, but it's worth it to find a good one

This is not good advice. You would be much better off combining that money and hiring a proven senior level guy, as one senior level guy can outperform a group of junior level guys. Which is what you get many times when you solicit from those sites. To be honest those sites are a race to the bottom and no senior level guys are lurking there because they have plenty of work and don't need to compete in that race.

The best advice is to break your 1.0 requirements into micro-milestones with the respective developer, the trick is to get them down to 40hr increments, for example you ask the developer do you think you can get account create / update done in 40hrs and the developer says yes with the exception of roles and permissions, or just yes, I can get that all done.

You work the contract from that perspective, they have to produce something in 40hrs and if they start going over then it becomes apparent quickly and you are rarely ever at risk of loosing more than 40hrs. This allows you to measure your risk in small increments and allows you to cut loose at the point that they start failing, while still having and completed 40hr blocks as feature complete, that you can turn over to a new developer should they start failing.

For instance, say you have 3 features in 1.0: account, orders and inventory. say the developer does account in 40hrs, submits it to you and it is feature complete, you then move on to orders and the developer misses 40 and claims that he needs 20hrs more (it happens) so you give him the 20hrs and it comes back feature complete. Now you have 2/3 done, but at any given time you where only at risk for a 40hr loss and 60hr loss when you decided to take a greater risk. Finally, say they miss inventory and claim it will take them another 40hrs, you decide that you are willing to assume 80hrs risk and it still come back defective and it will be yet another 40hrs. At this point you feel that it is too much risk so you cancel the contract, you are still in possession of 2/3 of the development effort and you can solicit for that final 1/3. As well you can opt at that point to diversify because you are loosing faith in the original developer at which point you could agree to the addition 40hrs with the original developer while hiring another developer to build the final 1/3 in parallel, in case the original developer is not able to complete the task.

One other thing to note, is when the first 40hrs is complete hire an independent party to review the architecture and the code to ensure that it is not a ball of spaghetti that will become a maintenance nightmare.

This is a far more pragmatic approach to hiring a developer.