You need to start writing Architecture Decision Records
If you write software, you need to start maintaining Architecture Decision Records (ADRs). ADRs roughly fall into the category of Developer Documentation. They aren't aimed at the Users of the software. Instead, they are aimed at the developers and maintainers of the software. They usually contain information about the layout of the package and what the code does. ADRs, in this context, are an absolute necessity. By definition, ADRs are simply a Record of a Decision that has an impact of the Architecture of the application. In fact, Any meaningful technical decision made in a software project, irrespective of whether it has an impact on the architecture of the application, needs to be documented.
I first came across ADRs in Chapter 17 of Fundamentals of Software Architecture book. A few of us (at Enthought) read this book earlier in the year and ADRs are one of the things that we took away from the book. You can find more information on ADRs here and here.
Here's what the format of an ADR looks like, adapted from Ch. 17 of the FoSA book I linked earlier.
Title: Short description stating the architecture decision
Status: Proposed, Accepted, Superseded
Context: What is forcing me to make this decision?
Decision: The decision and corresponding justification
Consequences: What is the impact of this decision?
Compliance: How will I ensure compliance with this decision?
Notes: Metadata for this decision (author, etc.)
That's just a recommendation and we don't strictly enforce the use of the above format. In some ADRs, a "Compliance" section doesn't make sense as there isn't really anything that the project needs to continually comply with. In other cases, the only "Consequence" of a decision was the need to enforce future "Compliance" so we ignored the "Consequence" section.
For example, an ADR contained the decision to adopt mypy into a project. We documented why we were adopting it, how we planned to ensure that the team complied with this decision and added additional notes like the fact that we needed to rely on third-party stub packages for third-party Python packages.
Another ADR contained information on our approach to paths in the application. We documented the decision to only work with pathlib.Path objects internally and convert string paths to and from pathlib.Path objects at the periphery of the application i.e. in the I/O and/or UI layer of the application. This might sound familiar to you if you've used the Unicode sandwich approach before.
In another ADR, we documented why we chose to go with Python Library A over Python Library B and documented the consequences of this decision e.g. Library A is feature complete but less maintained when compared to Library B so we would have to keep an eye on code rot in Library A.
In some cases, we've chosen to drop the A from ADRs i.e. write Decision Records for any meaningful decision in a software application, even if it doesn't impact the overall "architecture" of the application.
Like I mentioned in the beginning, more often than not, developer documentation talks about what the code does but not why the code does what it does. The "Why" ends up getting buried in Git commit messages, PR descriptions and review comments. You might not need to know the "Why" but when the time comes, knowing the "Why" is how you ensure that you're making the right decision.
Have you used ADRs? Do you find them useful? If not, why?