Thanks Steve for sharing this. I am sorry to hear about your condition. I am sure as you survived Big C, you will survive the small C as well. Take care and thanks.
By "Make decisions easy to change later", do you mean,
1. Getting the Module structure of the system correct with well defined contracts between them so that they can be changed, updated independently of each other.
To move the project forward, at some point you have to make decisions based on incomplete information. Some of these decisions will be good, some will be ok, and some will be completely wrong. The problem is: You only know this after the fact, when parts of it or all of it is already implemented.
Because of this you should design for change and build a flexible architecture. My goto technique for this is to encapsulate everything regarding this decision into a module and put an interface around it. The interface stays the same, the implementation can adapt. How this interface looks like is not that important. You can build a library, it could be a REST API or some gRPC thing, whatever. So yes, the main idea is to create well defined contracts or interfaces (call them whatever you like), which will be be flexible enough to adapt to different implementations.
Do you want to share any further insights about what factors you use to narrow down the choices about the correct ways? Similarly how do you go about managing the Constraints & Trade-offs - Do you change the scope? Do you negotiate to relax the constraints etc.
I agree this is an awesome post and a really great example of how every Root Cause Analysis needs to be done. I am also impressed by their incident response.