I've started breaking down new features (or work efforts, to be precise) into three separate areas:
- Fully understood problems
- Partially understood problems that can be worked in parallel
- Partially understood problems that are linear
Fully Understood Problems
These are the easiest and less risky. Going into this, you know everything that needs to be done to get it out the door. It's usually in an isolated or at least well-designed piece of code, test coverage is good, etc. Often these are problems that are iterating on a current feature or piece of functionality. These are well-understood because we have essentially done them before.
For these, you can do an estimate and be pretty confident that you'll make it. Your risk in these scenarios comes under non-product areas (developers getting sick, build system dying, etc), and those are risks that you can quantify based on your past development history.
Examples: adding a field to a form, creating the fifth skin for an application, adding a new type or class of data, etc.
Partially Understood Parallelizable Problems
These types of issues are more risky than fully understood problems. Going into this, you know that you don't have all the information you need, and lack of information increases your risk. However, these are problems that can be approached from multiple directions at once. This means you can increase your knowledge and decrease your risk to a certain extent by throwing resources at the problem.
For these, you need to add an additional padding to your estimate. You can go ahead and do an estimate based on your history of these types of problems, but be aware that optimistic estimates are not the best route here. On top of your usual risk profile, you have the "there be dragons and I have an army" factor.
Examples: a new hardware platform, a new feature written in house, etc.
Partially Understood Linear Problems
The last type of problem to address is a feature or work effort that you don't quite understand and that needs to be worked on linearly. These are the features that you can't attack from a lot of different angles - you fix a problem to uncover the next. Throwing resources at this problem is unlikely to help; it's the classic baby problem (one woman can have a baby in nine months, but nine women cannot have a baby in a month). The best mitigation strategy here is to reduce your cycle time as much as possible; the time between uncovering a problem, identifying it, and fixing it should be shrunk as much as possible, because you don't know how many of these cycles are between your team and their goal. These problems also respond well to a "war room" approach, in which you create a dedicated team to solve this problem with all needed resources - dev, test, IT, etc. - and (physically) isolate that team so this is all they work on.
These problems have potential to be farthest from your original estimates and the hardest to fully estimate. Again, you can look at your team's history based on these types of problems, but you need to assume that it will take longer than you think. On top of your usual risk profile, you have the "there be dragons and I am but one man" factor.
Examples: performance improvements, build failures, etc.
So when you're creating your schedule and assessing the risk, ask yourself what kinds of problems you're facing. If you can classify the kinds of problems you can solve, you can determine how solid your estimates are and therefore how risky your schedule is.