“Lazy YAGNI”
You Aren’t Gonna Need It can lead to some silly situations if you interpret it too pessimistically. The pessimistic (and wrong) interpretation is that you should pretend that the user story you’re implementing is the only one you know about. This equates to doing zero up-front design, because you’re only concerned with whether the design satisfies the user story you’re currently implementing. The price of making this mistake is design churn: each new requirement may incur a large rewrite of existing code. This is obviously not a recipe for productivity.
Since you have a Release Plan which contains a list of User Stories that you’re going to need, you can tell that You Are Gonna Need It. YAGNI defends against programmer-initiated imaginary user requirements that divert attention away from actual documented user requirements.
If you’re coming up with a design for a user story and see that another story coming up soon could influence your design decision, you are in the most informed position compared to whoever estimated the stories when they were being prioritized. You may be able to avoid a lot of wasted effort by adopting a design now that will support both requirements. This is why XP Does Design before writing the tests and implementation.
However, user stories that are far in the future (> 6 months away) are likely to change, and their existence at all is probably a sign of premature planning. Looking even 3 months ahead is probably excessive. Your customer will learn a lot between now and then about what they really need, and may reprioritize or rewrite that future story. They’ve already prioritized it as being less important than the next 3 months of user stories, so you’re taking a risk when you decide to accommodate it in advance.
Note that I’m not talking about reprioritizing user stories. That is not something that engineers are allowed to do outside of the current iteration (only the customer may do that). I’m talking about extracting an Engineering Task from the future story and pulling it into the present iteration, so that the tests you write in the current iteration force you to use a particular design that will better accommodate the future story when you eventually write it.