Para mí, me gusta el enfoque que presenta Kent Beck en XP (no estoy seguro si es "su" idea o la de otra persona, pero ahí es donde la escuché por primera vez):
Ya es bastante difícil resolver los problemas de hoy sin tratar de resolver cuáles son los problemas del mañana y resolverlos también.
Los desarrolladores pueden dedicar mucho tiempo a soluciones para requisitos que no existen, casos extremos que nunca ocurrirán o incluso problemas genuinos donde el impacto del problema es significativamente menor que el costo de prevenirlo.
Este es el momento que podría ponerse en cosas que los usuarios realmente querrán y usarán, cosas que les darán beneficios que superarán enormemente incluso los inconvenientes que se causarán en el improbable caso de que una de estas cosas realmente suceda.
Más allá incluso de este resultado no óptimo para el usuario, el impacto en el desarrollador de la sobre ingeniería de esta manera tiende a ser sobre un código complejo que es más difícil de soportar y más difícil de mejorar.
Entonces, para mí, si sabe, o puede estar bastante seguro, que algo es un requisito o que va a causar un problema, resuélvalo, si no, no lo haga.
Es posible que tenga que regresar y volver a trabajarlo cuando resulte que hubo un requisito más amplio que el que implementó originalmente, pero en general el esfuerzo total que realiza en el proyecto seguirá siendo menor porque en la mayoría de los casos eso no sucederá.