On the train this morning I was working on my DevTeach talk about doing design on an Agile project. I'm trying to explain the concepts of the Last Responsible Moment and delaying technical commitment in terms of Lean Programming. Part of the theme of my talk is simply to not do anything that you don't know that you need to do. "If we do task A now, feature B will be easier later" is an example of speculation, not knowledge. It might turn out to be a good decision, but do you really know for sure that you'll actually implement feature B? If feature B doesn't actually get built, you might have wasted effort building extra complexity in the form of hooks for a feature that never gets built.
You need to be very cognizant of the difference between "I think designing it this fancier way will help in release 2..." and "we could reduce some duplication if we abstracted the XYZ like this." The first statement is an idea that you keep in the back of your mind. The second statement is something to act on.
Don't ever let yourself believe that you know what the business wants or needs more than they do. My poor colleague just got hit by an example of this. He'd built some nontrivial functionality to interpret trade prices in a new screen to match a specification from our client's tech lead. You can probably guess what happened as soon as an actual business person saw the screen for the first time today. Needless to say, my colleague just started rewriting the implementation of the trade price interpretation (20 unit tests worth of code). It's good to know the business domain, but don't fool yourself into believing that you're the domain expert instead of the business.
I built a couple complex features this summer that have never, ever been used in production. Same story, same team lead. When I finally started talking to the end users (and knowing enough about the domain to actually understand what they were talking about) I found out quickly that these features were more or less useless to them. The business problem we were trying to address still exists, but the real solution was to make part of the screen behave more intelligently to speed up the entry of Trades. We blew it by assuming that we knew what the business needed.
If it isn't entirely obvious, I'm not in an Agile shop at all at the moment. We're doing the engineering practices, but the project management isn't there. I think one of the biggest advantages of Agile is turning the software development process into more of a "Pull" mechanism instead of the traditional "Push" model of linear waterfall. I don't try to guess out what the business might want or find useful. I'll make suggestions, but the final decision still has to be from the business. If the business is setting the priorities then you'll be building features according to an established business need. You can cut waste by only designing the software for the features the business has already requested (how you keep the doors open for later features is a much, much bigger discussion some other time).
Grrr.