(I’m in a foul and dour mood tonight, so take the following in that context. This is going to be more cynical than I think I’ve been in quite some time. This article is a perfectly reasonable writeup for the position it espouses, and the author articulated it well. I just don’t agree at all.)
I’m increasingly of the opinion that decision records process just doesn’t matter for like 95% of orgs. These artifacts are busywork to make us feel better about stringing together the same ingredients everybody else is using and pretending we’re “real engineers”. At the companies I’ve worked with, near nobody has ever read these things. Doesn’t matter if somebody has put minutes into it, hours, or days–it’s all just paperwork.
At one company, we had a wiki where these were kept in order. Designs were proposed along with business constraints and alternatives, people approved it, and then maybe one in a blue moon we’d refer back to them if something was truly baffling. Most of the engineers didn’t refer to these, and over time the wiki got overgrown and the business people stopped paying attention to them to in favor of their own web of Google docs. The one time I found these useful was explaining to the C-level how a project had gone totally off the rails…and these documents were only a small piece of that puzzle.
At another company, there was an abortive attempt to do these. Unfortunately, we were moving with such speed–and tearing up so much of what had been laid down–that this documentation frequently just became out of date and redundant. We also had a long-enough leash, and enough greenfield work, that the history just didn’t matter. Anything that was not self-evident and documented in comments, commit messages, and Jira tickets tended to get rewritten anyway and reliably and simply enough that we could generally decipher what was going on.
It was the third of these companies that put the stake in the heart of my dreams for these documents. We had ADRs and even a dedicated (unorganized) repository for them. The CTO was a big fan of process and documentation (though they’d of course claim the opposite) and agile and matrix management, and a manifestation of these proclivities was that any team working on a thing was supposed to have an ADR explaining what they’d picked and why, and ideally exploring a couple extra options.
The problems with this were numerous.
First, these things could take weeks or even months to review. What would frequently happen is that there’d be a proposal, then the immediate engineers on the project would weigh in, and then senior ICs that might have good engineering sense (or might not!) would weigh in, and then some number of directors from different teams would weigh in, and then somebody would say “oh ho ho we need to see how this impacts product”. This, incidentally, was the happy path–god forbid there was any actual disagreement about the proposed plan or weighing-in. Then, you’d see people going back and forth in the comments. Eventually the team responsible would just implement something and leave the ADR to languish in review and because we didn’t really care about clearing these things out (at least for a while) they just took up room.
Second, most of the ADRs weren’t actually documenting decisions, they were recording whimsy. Totally unable to be discussed in any meaningful way. Legacy code is legacy code, and if an ADR was written to document some dumbfuckery, it didn’t make it any less stupid–you just shrug and move on and deal with it when the time comes. Of course, people would dress up this “decision” process with things like the alternatives they considered, which almost always seemed to just be padding to center the Overton window neatly on their solution…one option would be some permutation of “punt and don’t do anything” and the other would usually be some outlandish rewrite.
Continuing to pick on that a bit more, one of the things about these “decisions” is that they really weren’t. In an organization committed to, say, k8s, the deployment “decision” won’t actually include a fair assessment of a dedicated host. Similarly, if the organization has a devops team in transition and the k8s story is weird, the decision will never actually include k8s and instead will do something else. If key people are uncomfortable with technology X (quite aside from whether or not it is correct for the task at hand), then by gosh and by golly the ADR is probably going to miraculously choose some technology other than X. It’s all so tiresome.
Third, ADRs were often just plain ignored. I witnessed on multiple occasions ADRs that I wrote or that other teams wrote, and which had even been through the wringer of review, just be straight-up ignored by implementors or overruled by management. CTOs get to be the decider, but when they explicitly bandy about ADRs and their gravitas and then don’t let their teams actually use them, it’s fucking rage inducing.
Fourth, ADRs were often just badly written. Frequently, an ADR would be missing critical business context, or implementation details, or just be so vague that it didn’t actually have any meat to engage with. I’m sure that with better guidelines or engineering leadership this could’ve been addressed a bit, but honestly given the other shortcomings listed I can’t really blame the writers for making low-effort ADRs. A lot of folks also just didn’t really have practice writing them or doing technical writing period, and there was also articulated the feeling that asking juniors to do this stuff (with senior supervision and assistance) was somehow above their paygrade–this of course makes one wonder where exactly institutional expertise in ADRs is supposed to be cultivated.
Fifth, ADRs that actually contained sufficient detail would also be frequently pilloried for being “too detailed”. If, for example, in an appendix (imagine that, and ADR with a bloody appendix to provide technical context for a legacy system!) there was a listing of database structures and routines that had to be excised or replaced, there would be reviewers that straight up ignored it or would actively complain about the presence of that information.
~
I’m sure ADRs have been useful somehwere, to somebody, at some time. But, honestly, the most damning thing I can observe about ADRs is the existence of Raymond Chen’s Old New Thing blog; if that sort of context and detail is considered an entertaining historical read, why the hell do we think that there is any special care that should be taken about why we’re using CurrentYearJSFramework instead of LastYearJSFramework?
The time would be better spent actually implementing the damned thing in a simple way, and then making sure the process is documented in Jira–though I’m unsure people read tickets either.
Almost at the ‘user story’ level, but with extra detail that needs to be considered from a ‘product’ perspective but may not be in the original user story.
As a customer
I want to see my balance on every page
So that I keep track as I make transactions
Given I have a balance of 0
When I browse to any page
Then I should see a balance of '0.00'
And my balance should appear positive
Given I have a balance of -1
When I browse to any page
Then I should see a balance of '-1.00'
And my balance should appear negative
Given I have a balance of 1
When I browse to any page
Then I should see a balance of '1.00'
And my balance should appear positive
Specific coverage, more edge cases - but more for asserting we haven’t made a mistake than altering the requirements.
Given I have a balance of <balance>
When I browse to <page>
Then there should be an element with id 'balance'
And the 'balance' element should have text '<text>'
And the 'balance' element should have class '<appearance>'
Examples:
| balance | page | text | appearance |
| 0 | / | 0.00 | positive |
| -1 | / | -1.00 | negative |
| 1 | / | 1.00 | positive |
| -0.01 | / | -0.01 | negative |
| 0.01 | / | 0.01 | positive |
| -999999999.99 | / | -999,999.999.99 | negative |
| 999999999.99 | / | 999,999,999.99 | positive |
| 0 | /transactions | 0.00 | positive |
| 0 | /user | 0.00 | positive |
This is a great explanation how ADRs can fail. They look easy to introduce but as with any process there are plenty of subtle things that can go wrong. You probably did not catch all of them in this long comment.
One of the things I’ve found to be most important is using neutral language in describing the context, options, and consequences. We tend to gravitate toward writing in “pros” and “cons” for every option. That can lead to intellectual dishonesty. We fool ourselves by looking hard for “cons” in the options we don’t like and much less hard at the options we like. Reverse that for the “pros”.
The result is usually a problem statement about how everything is awful, a few options where one looks amazing and the others are clearly awful, then a conclusion that says everything will be awesome. The truth is always messier.
I think this stems from early experience writing “pitches” for approval, funding, etc. It trains everyone to be a salesman.
This is why I don’t even separate my “consequences” section into pros and cons. A consequence should be a fact about the situation that will result. Objective. If stated plainly, all parties should agree “yes that is a consequence that will follow” whether they agree with the decision or not.
Whether a consequence is classified as a “pro” or a “con” is entirely about the relationship one has to the consequence.
Example:
System A will need to sustain 1,000 TPS for at least 5 minutes.
Not really exciting, right? Several parties could agree that 1,000 TPS will be required. (If not, then the disagreement stems from different understanding of the system or different assumptions about behavior. Good information to uncover!)
Is 1,000 TPS good or bad? That depends entirely on whether you like that number or not. If you like it, then you might regard that consequence as a “pro”. Someone else could rationally consider it a “con” based on their relationship to it.
And previously previously. I’m surprised I haven’t run across this recommendation before. I can think of a couple teams I’ve worked with in the past that could have really benefitted from this style of documentation. I’m going to see if I can introduce it to my current team.
This is a good practice, but one that’s only really necessary because of flaws in organizational practices.
Generally speaking, if I as a developer make any kind of important technical decision, I’m doing it in conversation with other developers (either the other people who are working on the project or, more often, the technical manager who has assigned the task). If I’m working totally on my own, then I will generally make notes about the reasoning behind particular decisions so that I can cover my own ass later (since getting chewed out over making necessary decisions unexpected by somebody up the chain whose own preferences are based on a misunderstanding of the behavior of other parts of the system is really common). Boiling this stuff down into a single document requires changing the format from a conversation to an explanation, and this change is often lossy since you’re liable to end up focusing on whatever sections were most interesting or caused the most trouble rather than really enumerating the choices made at the very beginning of the project (which may have had the greatest affect on the project’s trajectory). Meanwhile, the conversation you’ve already had has all the relevant information! So, the best way to handle this is to permanently store conversations (preferably by having all of them through the same text-based medium and making that searchable).
Where I work, most technical conversations are at partially done this way. However, every few years we have some kind of internal turnover in preferred messaging tech, which causes two problems:
all technical conversations from the previous generation are lost or made difficult to find. (We switched from Slack to Teams last year, and everybody found some third party slack backup system to try to back up what they could, but it’s borderline impossible now to find information about what was said two or three years ago now. Before that we used XMPP, and all that stuff is long gone.)
Folks who have been with the company for longer than ten years have largely decided to opt out of the churn and not bother with it. So, if you want to reach them, you send and email and they will telephone you or actually drive into the office to talk.
On top of this, these shiny new messaging platforms support voice or video chat. Sometimes ‘official’ video meetings get recorded (although nobody watches the recordings – they aren’t searchable, they’re filed away automatically somewhere on a series of near-identical-yet-incompatible CMSes with an autogenerated title, and you end up spending three hours negotiating what could be a two sentence email). When the voice chat feature stops working (which it often does), we end up just using our personal telephones! So not only does the technical decision-making conversation take substantially longer, but the evidence that such a conversation ever took place is lost, and most of the content of the conversation is forgotten and lost permanently before it’s even over.
Keep a single, text-based, permanently-stored, searchable system for real-time communication that can have conversations tagged as part of particular projects and decision records become a “nice to have” along the same lines as executive summaries and tutorial documents.
(I’m in a foul and dour mood tonight, so take the following in that context. This is going to be more cynical than I think I’ve been in quite some time. This article is a perfectly reasonable writeup for the position it espouses, and the author articulated it well. I just don’t agree at all.)
I’m increasingly of the opinion that decision records process just doesn’t matter for like 95% of orgs. These artifacts are busywork to make us feel better about stringing together the same ingredients everybody else is using and pretending we’re “real engineers”. At the companies I’ve worked with, near nobody has ever read these things. Doesn’t matter if somebody has put minutes into it, hours, or days–it’s all just paperwork.
At one company, we had a wiki where these were kept in order. Designs were proposed along with business constraints and alternatives, people approved it, and then maybe one in a blue moon we’d refer back to them if something was truly baffling. Most of the engineers didn’t refer to these, and over time the wiki got overgrown and the business people stopped paying attention to them to in favor of their own web of Google docs. The one time I found these useful was explaining to the C-level how a project had gone totally off the rails…and these documents were only a small piece of that puzzle.
At another company, there was an abortive attempt to do these. Unfortunately, we were moving with such speed–and tearing up so much of what had been laid down–that this documentation frequently just became out of date and redundant. We also had a long-enough leash, and enough greenfield work, that the history just didn’t matter. Anything that was not self-evident and documented in comments, commit messages, and Jira tickets tended to get rewritten anyway and reliably and simply enough that we could generally decipher what was going on.
It was the third of these companies that put the stake in the heart of my dreams for these documents. We had ADRs and even a dedicated (unorganized) repository for them. The CTO was a big fan of process and documentation (though they’d of course claim the opposite) and agile and matrix management, and a manifestation of these proclivities was that any team working on a thing was supposed to have an ADR explaining what they’d picked and why, and ideally exploring a couple extra options.
The problems with this were numerous.
First, these things could take weeks or even months to review. What would frequently happen is that there’d be a proposal, then the immediate engineers on the project would weigh in, and then senior ICs that might have good engineering sense (or might not!) would weigh in, and then some number of directors from different teams would weigh in, and then somebody would say “oh ho ho we need to see how this impacts product”. This, incidentally, was the happy path–god forbid there was any actual disagreement about the proposed plan or weighing-in. Then, you’d see people going back and forth in the comments. Eventually the team responsible would just implement something and leave the ADR to languish in review and because we didn’t really care about clearing these things out (at least for a while) they just took up room.
Second, most of the ADRs weren’t actually documenting decisions, they were recording whimsy. Totally unable to be discussed in any meaningful way. Legacy code is legacy code, and if an ADR was written to document some dumbfuckery, it didn’t make it any less stupid–you just shrug and move on and deal with it when the time comes. Of course, people would dress up this “decision” process with things like the alternatives they considered, which almost always seemed to just be padding to center the Overton window neatly on their solution…one option would be some permutation of “punt and don’t do anything” and the other would usually be some outlandish rewrite.
Continuing to pick on that a bit more, one of the things about these “decisions” is that they really weren’t. In an organization committed to, say, k8s, the deployment “decision” won’t actually include a fair assessment of a dedicated host. Similarly, if the organization has a devops team in transition and the k8s story is weird, the decision will never actually include k8s and instead will do something else. If key people are uncomfortable with technology X (quite aside from whether or not it is correct for the task at hand), then by gosh and by golly the ADR is probably going to miraculously choose some technology other than X. It’s all so tiresome.
Third, ADRs were often just plain ignored. I witnessed on multiple occasions ADRs that I wrote or that other teams wrote, and which had even been through the wringer of review, just be straight-up ignored by implementors or overruled by management. CTOs get to be the decider, but when they explicitly bandy about ADRs and their gravitas and then don’t let their teams actually use them, it’s fucking rage inducing.
Fourth, ADRs were often just badly written. Frequently, an ADR would be missing critical business context, or implementation details, or just be so vague that it didn’t actually have any meat to engage with. I’m sure that with better guidelines or engineering leadership this could’ve been addressed a bit, but honestly given the other shortcomings listed I can’t really blame the writers for making low-effort ADRs. A lot of folks also just didn’t really have practice writing them or doing technical writing period, and there was also articulated the feeling that asking juniors to do this stuff (with senior supervision and assistance) was somehow above their paygrade–this of course makes one wonder where exactly institutional expertise in ADRs is supposed to be cultivated.
Fifth, ADRs that actually contained sufficient detail would also be frequently pilloried for being “too detailed”. If, for example, in an appendix (imagine that, and ADR with a bloody appendix to provide technical context for a legacy system!) there was a listing of database structures and routines that had to be excised or replaced, there would be reviewers that straight up ignored it or would actively complain about the presence of that information.
~
I’m sure ADRs have been useful somehwere, to somebody, at some time. But, honestly, the most damning thing I can observe about ADRs is the existence of Raymond Chen’s Old New Thing blog; if that sort of context and detail is considered an entertaining historical read, why the hell do we think that there is any special care that should be taken about why we’re using CurrentYearJSFramework instead of LastYearJSFramework?
The time would be better spent actually implementing the damned thing in a simple way, and then making sure the process is documented in Jira–though I’m unsure people read tickets either.
I think if it isn’t with the code, it is useless when trying to understand it in the future.
Jira tickets: useless. Wikis: useless. Documentation repos: useless.
Commit messages: useful. ADRs with zero process next to the code they document: useful. Comments: useful. Code: useful.
There is one exception to prove the rule: talking with the author: useful. Shame we can’t box copies of our brains with every commit.
For me the real documentation is the specs/tests.
These are the levels I like:
I have been struggling to find tests useful on front end code.
This is a great explanation how ADRs can fail. They look easy to introduce but as with any process there are plenty of subtle things that can go wrong. You probably did not catch all of them in this long comment.
One of the things I’ve found to be most important is using neutral language in describing the context, options, and consequences. We tend to gravitate toward writing in “pros” and “cons” for every option. That can lead to intellectual dishonesty. We fool ourselves by looking hard for “cons” in the options we don’t like and much less hard at the options we like. Reverse that for the “pros”.
The result is usually a problem statement about how everything is awful, a few options where one looks amazing and the others are clearly awful, then a conclusion that says everything will be awesome. The truth is always messier.
I think this stems from early experience writing “pitches” for approval, funding, etc. It trains everyone to be a salesman.
This is why I don’t even separate my “consequences” section into pros and cons. A consequence should be a fact about the situation that will result. Objective. If stated plainly, all parties should agree “yes that is a consequence that will follow” whether they agree with the decision or not.
Whether a consequence is classified as a “pro” or a “con” is entirely about the relationship one has to the consequence.
Example:
System A will need to sustain 1,000 TPS for at least 5 minutes.
Not really exciting, right? Several parties could agree that 1,000 TPS will be required. (If not, then the disagreement stems from different understanding of the system or different assumptions about behavior. Good information to uncover!)
Is 1,000 TPS good or bad? That depends entirely on whether you like that number or not. If you like it, then you might regard that consequence as a “pro”. Someone else could rationally consider it a “con” based on their relationship to it.
Edit: I forgot to mention that I previously wrote about this same advice in my blog.
And previously previously. I’m surprised I haven’t run across this recommendation before. I can think of a couple teams I’ve worked with in the past that could have really benefitted from this style of documentation. I’m going to see if I can introduce it to my current team.
This is a good practice, but one that’s only really necessary because of flaws in organizational practices.
Generally speaking, if I as a developer make any kind of important technical decision, I’m doing it in conversation with other developers (either the other people who are working on the project or, more often, the technical manager who has assigned the task). If I’m working totally on my own, then I will generally make notes about the reasoning behind particular decisions so that I can cover my own ass later (since getting chewed out over making necessary decisions unexpected by somebody up the chain whose own preferences are based on a misunderstanding of the behavior of other parts of the system is really common). Boiling this stuff down into a single document requires changing the format from a conversation to an explanation, and this change is often lossy since you’re liable to end up focusing on whatever sections were most interesting or caused the most trouble rather than really enumerating the choices made at the very beginning of the project (which may have had the greatest affect on the project’s trajectory). Meanwhile, the conversation you’ve already had has all the relevant information! So, the best way to handle this is to permanently store conversations (preferably by having all of them through the same text-based medium and making that searchable).
Where I work, most technical conversations are at partially done this way. However, every few years we have some kind of internal turnover in preferred messaging tech, which causes two problems:
On top of this, these shiny new messaging platforms support voice or video chat. Sometimes ‘official’ video meetings get recorded (although nobody watches the recordings – they aren’t searchable, they’re filed away automatically somewhere on a series of near-identical-yet-incompatible CMSes with an autogenerated title, and you end up spending three hours negotiating what could be a two sentence email). When the voice chat feature stops working (which it often does), we end up just using our personal telephones! So not only does the technical decision-making conversation take substantially longer, but the evidence that such a conversation ever took place is lost, and most of the content of the conversation is forgotten and lost permanently before it’s even over.
Keep a single, text-based, permanently-stored, searchable system for real-time communication that can have conversations tagged as part of particular projects and decision records become a “nice to have” along the same lines as executive summaries and tutorial documents.
/u/dmonay, you might get a much out of this! @dmonay