I think we had a successful approach to specifications in one of my previous jobs as we delivered the project on time and with only a couple of issues found in production.
The purpose of writing specs was twofold:
- we used them to make time estimates
- they were an exploratory tool to help us understand the scope of the project.
We wrote specs upfront for the whole product but without going into too much detail, and with an emphasis on the UI. This was a means for us to get a feel for what had to be done and for the scope of the project. After that we went through the specs and listed all the tasks that had to be carried out at the level of "create the options dialog layout", "implement getting and setting of options" and so on. This unearthed a lot of things that would otherwise have turned into surprises and potential delays during implementation.
The next step was to assign time to each task. There was two of us performing estimates, which is important because when we disagreed it often highlighted things we'd forgotten about and allowed us to improve estimates, or otherwise we just took the average of our numbers for a better guess. We used a granularity of 0.5 days for our estimates, and kept the "multiply your estimate by 2" rule firmly in mind.
We found that this works out to be fairly accurate. Although the averaged times for particular tasks can still end up being wrong, you finish some of them later and some earlier because of 0.5 day granularity.
When we started implementing things, we had to work everything out in a lot more detail and inevitably had to do some things differently from the spec. To that end, we got together and worked out the best approach to implementing each feature, sometimes with prototypes. We didn't update the original spec but we did make notes after the meetings as it's very easy to forget the details afterwards.
Depending on the project, it may also be a good idea to keep the original spec up to date as the application evolves, but we didn't need to do it this time.
In spite of the Agile bent of the project, we found that writing a complete spec in the beginning was a great investment of our time, even though we fully expected it to get outdated quickly.