When it comes to software, documentation all too often seems to come along as a bit of an afterthought. Most systems either seem to have not enough, or too much. By thinking of documentation as being of differing types and serving different needs I've found it easier to write better documentation, which for me all started with the use of decision logs.
Different people have differing needs when accessing technical documentation so it's crucial to keep in mind who you are writing documentation for, and what their needs might be. For example, some people will want to understand how to get started working on an application or what standards they should follow, whereas someone else might want to understand why certain choices were made prior to making changes.
I was recently working on a large migration project moving a website from one platform to another. Throughout this process we had very little prior documentation to help us and ended up having to spend a significant amount of time reverse-engineering the existing platform just to understand exactly what all of the functionality did.
The more we dug, the more questions came up as to why certain choices were made. It would've been great to go back in time and understand the thought processes behind decisions. Was a choice made because of personal preference by the developer or team working on that feature? Was it a carefully researched and evaluated decision? Were there any technical or business constraints that impacted the choices? Were they aware of any limitations in their choice?
"One of the hardest things to track during the life of a project is the motivation behind certain decisions. A new person coming on to a project may be perplexed, baffled, delighted, or infuriated by some past decision. Without understanding the rationale or consequences, this person has only two choices: blindly accept the decision or blindly change it"
Michael Nygard (Documenting Architecture Decisions)
If we'd known the rationale behind these decisions it would've helped us to know if there were certain area we should change going forwards, or areas to be particularly careful about changing.
This process got me thinking about how to avoid passing on the same problems either my future self or other developers and settled on the decision log format as being the tool that could help make that possible.
What is a decision log? At it's simplist, it is a document that makes a record of a decision. In my usage, it takes on a particular format heavily inspired Michael Nygard's Documenting Architecture Decisions.
This format gives us three things:
- Clear purpose, documenting a snapshot in time on a single decision
- Increased visibility and democratisation
- Repeatable, consistent structure
Living documentation versus snapshots in time
Possibly the most important aspect of decision logs is that they only reflect a specific moment in time. If you make a decision, and then 6 months later decide to pivot and change your approach then what you've really done is make two decisions. Rather than editing the original decision log you make a new one to reflect the new decision. This means that decision logs come with very little ongoing maintenance cost. You might mark a decision log as "superseded", but aside from this you otherwise aim to leave them as-is.
Living documentation however should be considered always up-to-date and evergreen. This could be your get-started guide, or documentation on your current standards and processes. For anything like these it is crucial the documentation is maintained and kept up to date. If someone is trying to get started on a project then having incorrect or outdated instructions can be just as frustrating as having no documentation at all (or even more so).
Where you don't make a distinction between living documentation and snapshots documentation these can easily blur into one. Instead of a concise, easy to maintain get-started guide you can end up with a more verbose document that attempts to explain both how to get started, but also why certain choices were made. This increases the amount someone needs to read just to get started, but also increases how much documentation you need to maintain going forwards too.
By splitting off the why into a series of decision logs can then simplify the living documentation, linking off to the relevant decision logs where appropriate. This allows you to increase the overall amount of documentation whilst making the living documentation more succinct and maintainable.
Increasing visibility of decisions
Decisions can happen all of the time, and are often the result of a group discussion or meeting. Crucial decisions which impact the product you are building or ways you're working end up lost within meeting notes or within the heads of the individuals within the original discussion.
For everyone impacted by the decision it can then be impossible to work out what has actually been decided, and why. This is where dangerous mistakes start to be made. People may not be aware of a decision, and make their own choices which conflict with decisions made elsewhere. They might be aware of the decision, but not the thought process behind it, making an assumption that a certain limitation has already been considered and planned for whereas it may not be something the decision maker(s) were aware of at all.
By following a more rigorous process with documenting important decisions you help make these decisions, and the decision making process, more transparent to others within your team.
Decision logs should be seen as a crucial form of documentation that lives alongside all of your other documentation. The decisions can then be referenced by other pages or tickets.
Repeatable, consistent structure
When writing any kind of new document, I often find the first few words tend to be the hardest. You're starting from a blank slate, with just that little cursor blinking away patiently waiting for you to get started. To get started you need to think about how you're going to structure the document, as well as actually get your point across. It may seem subtle, but I believe it all creates that little bit of friction which can be the difference between having an important decision documented or not.
Rather than starting with a blank document I use a pre-configured template for my decision logs. This means I avoid that dreaded empty document and instead start with a page with various headings in place which form the structure of the document. Each section has a purpose, so instead of spending time thinking about the structure I now get straight into the actual writing. If I'm at an early stage in making a decision I can quite comfortably fill in the sections that I already know and leave the rest blank until I've reached that point in the decision. This flips the process from documenting something after the decision has been made to instead being a useful tool for actually making the decision.
Having a consistent structure is equally advantageous for the reader too as it becomes a repeatable pattern that helps make the documents easier to read. If someone reads a decision log already with some awareness of the background they can easily skip to a later section of the document whilst someone new to the problem can read the entire page.
Structure of a decision log
This is where I outline the problem I am trying to solve. Provide any useful background on the decision, requirements that need to be considered or constraints that need to be worked with. From the context other people should be able to gain a high-level understanding of why this is an important decision to be making.
I try and keep the context section fairly succinct – try and avoid information overload here.
This is a useful section for expanding upon the context and options considered either with more in-depth documentation or with research. It allows someone who wants to really understand the intricacies of the problem to dive in deeper.
I'll often use this section to reference other pages. This could be other first-party or third-party documentation (even previous decision logs). It could include useful books or blog posts, or the results of any analysis I have completed.
Treat this section as optional for the reader – if someone is in a hurry they should be able to skip this section and still have a decent understanding of the decision.
Here's where I start going into the different viable options. I present this as a table with each column representing a different option. For each option I include a short description, a bullet point list of pros and cons and a cost value.
This gives a nice summary of the different options and allows them to be quickly compared against each other.
|Option 1||Option 2||Option 3|
The "cost" row is something I adapt depending on the decision at hand. Where there is a financial cost then it works well as it is. Time can also be a cost, but equally so can risk.
From the options considered I then document the decision that has been made. This section tends to actually be the shortest as all the options have been explained earlier in the document.
I use this section to explain why a specific option was choosen, especially if there a few options that would've been suitable.
It's also entirely possible for you to get this far and decide to go with none of the options and keep things as they are, for example if the options all introduce a set of new problems worth than the original problem you were trying to resolve. At this point, decising to do nothing is still a decision and should be noted.
If the context section outlines the situation that led to the decision being required then the consequences section outlines the situation after the decision has been made.
This should be a summary of how things will look once the decided option has been implemented noting both the positives and negatives.
Most architectural decisions will introduce some negative consequences. This might be some new constraints that it introduces on the system, changes in maintanance or new training required to get the team ready to use a new technology choice. It might be that one decision then opens up a new set of decisions that need to be made. For example, you might decide to use a new framework and then need to start deciding on testing tools or deployment processes which could all be in subsequent decision logs.
Writing down these consequences is an important step in making it clear which consequences were foreseen versus those which were discovered at a later date, and making it clear if any specific actions need to be taken to address these.
The last section in a decision log is a list of action items. This is typically a set of tasks related to implementing the decision that has now been made, but could also include reminders to review this decision in a few months time or tasks to create new decision logs for subsequent decisions that need to be made.
I've been using decision logs for the last couple of years and have found them an invaluable way of both thinking about decisions and documenting them.
They have gone from being an artifact I created after making a decision to a key part of how I will explain problems and come to an agreement on the right decision to make. Decisions now feel more visibile within the department, and more democratic with anyone able to access existing decision logs or raise their own for any architectural changes they would like to propose.
Cover photo by Kyle Glenn, Skateboarding photo by Brandon Morgan – both on Unsplash.