I think there's a difference between going ahead and implementing piracy risk immediately, vs determining all the requirements of piracy risk and using them when designing your fundamental architecture, with hooks left in place for extensibility that simply aren't actually implemented yet. Maybe the Gondor navy will destroy the pirates, but then you have to worry about Corruption risk because you now may need to bribe the navy or risk having your cargo impounded (so you have to balance the risk of impounding vs the cost of bribing). Sure it's not the same thing as piracy risk, but it's similar, and because you designed your architecture from the get-go to enable piracy risk and other such extensions, you can now implement navy bribes pretty easily.
Meanwhile, if you'd said YAGNI to piracy risk and just implemented support for storm risk, you may find that you can't easily implement navy bribes without re-doing much of the work you already did for storm risk.
As saganus said[1], this is more of a craft than a science. You need to plan ahead with your architectural decisions, and they need to be made using the actual requirements you expect to encounter (as opposed to theoretical requirements, which aren't really much of a use to anyone), but that doesn't mean you need to actually implement everything immediately. Just enough to be satisfied that your architecture will suffice.
And this is why a lot of software written by the agile teams in the companies I've worked for looks like a messy accumulation of ad hoc solutions, with too little shared code and too much duplication.
Even if you are not implementing a feature right now, you still need to have as much information as possible about what might be needed in the future and how it will fit in in your solution.
No. You need to have information about what you're implementing right now, and the willingness to write it well.
What you generally see is that if you have a complex code base with lots of plan-for-the-future abstractions in it, refactoring it in any non-trivial way is really hard[1], so people don't, and you end up with hacks.
Whereas if the system is as simple as possible, you can make bigger changes more easily, and the code can stay cleaner.
That's no guarantee that it will -- code quality still requires discipline and sound engineering -- but it's a lot more likely with YAGNI than without.
[1] "Hey, we need to make our pricing system handle multiple currencies."
"Oh geez, that's going to wreak havoc with our risk plugin system, that change will take at least three weeks."
"Oh yeah, and we'll definitely need that risk plugin system when we get to the piracy risk feature later this year... what if we just kind of hack currency systems up by [doing something awful]?"
"Sure, we can do that in a week. I don't like it, but it's the only choice given our deadline right now."
The software I'm working on now is a messy accumulation of ad-hoc solutions but not because of YAGNI - it's because the real world of selling a system to multiple customers who get to demand things like "but we want our adverts to be blue on the second Tuesday of every third month" tends to makes software a mess.
Meanwhile, if you'd said YAGNI to piracy risk and just implemented support for storm risk, you may find that you can't easily implement navy bribes without re-doing much of the work you already did for storm risk.
As saganus said[1], this is more of a craft than a science. You need to plan ahead with your architectural decisions, and they need to be made using the actual requirements you expect to encounter (as opposed to theoretical requirements, which aren't really much of a use to anyone), but that doesn't mean you need to actually implement everything immediately. Just enough to be satisfied that your architecture will suffice.
[1] https://news.ycombinator.com/item?id=9607881