Типичный подход — сразу начинать заниматься разработкой и по ходу работы натыкаться на открытые вопросы и разбираться с ними. Результат понятен. Помните, как в конце сложного проекта все говорят, если бы мы с самого начала все знали, то построили работу бы совсем по другому, сэкономили бы массу времени и уложились в бюджет. Т.е. в конце проекта неопределенности нет. Но к этому времени давать оценку уже поздно.
Другой способ выяснить вопросы и тем самым устранить неопределенность – это выполнить проектирование. Когда я говорю про проектирование, я имею ввиду не только интерфейсное проектирование, но техническое. Это способ заранее выполнить весь проект, но только не по настоящему, руками программистов, а умозрительно, в голове проектировщиков.
Соответственно, проект разбивается на две части. Устранение неопределенности, т.е. проектирование, и непосредственно реализация, уже в состоянии минимального риска. С точки зрения договора это должно быть два отдельных этапа работ. Сколько они стоят, как об этом договориться с клиентом, как организовать эту работу.