YTHO.md
Capturing why we did what we did.
Some background
README files have been around since the olden days of computing, and have become a critical component in pretty much any programming project. Any self-respecting project or module template will generate a boilerplate README.md file for you, usually at the root of your project. The major version control systems display the README on the home page of each repository because they're just that important.
By convention, open source projects (and the templates they are often built from) typically include additional files at the root of the project: LICENSE.md, CONTRIBUTING.md, and sometimes even CHANGELOG.md and CODE_OF_CONDUCT.md. They each have their own (somewhat) self-explanatory purpose, they are each optional, and sometimes their content is included in the README file instead of in those separate files.
Decision documents, on the other hand, have their own long history, but have generally been relegated to the world of waterfally, heavyweight, overly-prescriptive specification processes on large projects with way too many requirements and managers. They have not caught on in the open source world, and have had widely varying adoption rates on enterprise and commercial projects.
But let's not let history get in the way.
The problem(s)
Decisions are made throughout a project's history, but the context and reasons for them often fade from memory, especially when team members move to other teams. Discussions get lost in Slack threads, meetings, and email chains, which erodes shared understanding and often leads to revisiting the same debates. Here are the problems we are trying to solve:
The solution
The solution recommended here is to add a file to your repository to capture the reasons for significant decisions you and your team have made regarding your project. Call the file YTHO.md and store it at the project root, right next to README.md.
Most repositories already have a README.md that answers what the project is and how to use it. But few repos capture why the project is designed the way it is. That’s where this new companion file comes in: YTHO.md — short for “Why though?” And yes: It's a direct reference to the Y THO meme.
Think of YTHO.md as your project’s decision journal. It accumulates short, clear records of the architectural and design decisions you’ve made along the way. It is either a single Markdown file where short-form decisions accumulate over time or an index to longer-form decision documents.
Which decisions?
It would be absurd to capture the reason for every single decision made on a project. That's a rabbit hole that goes very deep. To avoid that rabbit hole we can start with a simple guideline: If recording a decision will solve at least one of our problems (memory loss, decision churn, onboarding pain, or team mis-alignment), then that's a decision worth recording in your YTHO. If you want a more formal and concise heuristic, you could try on the two-part harmony that the ADR GitHub Organization uses for defining Architecture Decisions and Architecturally Significant Requirements. Or you could use Michael Nygard's definition of "architecturally significant" decisions. Choose the one that resonates with your team.
Relationship to traditional decision documents
Decision documents are nothing new, and YTHO is not a replacement for them. Instead, it is a push for their adoption, especially when those decision documents explain to team members why decisions were made. That's a key function of most (if not all) decision document formats. It's entirely possible that the only unique idea here is to name your decision register/journal/index with the super-cool name YTHO.md.
The format you choose for your YTHO is completely dependent on the type of project you are using it in. It's not as important to choose the right format as it is to choose a format and get started. You can and should improve on your YTHO over time, and that can certainly include adopting a format that is a better fit for your team's needs.
The benefits
Memory resilience
Whatever your approach to documentation is, it really helps to write important things down. It improves your chance of remembering things. Writing them down consistently in the same place makes them easier to find. So if you make a decision that you think might be important, or that might change later, put it in a file in your repo. Then if you remember making that decision, you know you had a reason, and you think maybe you captured that reason, you'll know where to find it (or at least where to start looking).
This is especially important for teams with multiple decision makers. Decision records that are in the project repo are not just available for others to review at check-in, but also become a part of the collective long-term memory of the team. They provide historical insight that can later prove useful for research, audits, and (perhaps most importantly) explaining and extending architectural evolution.
Decision stability
Decisions are going to change – even the good ones. That fact is not just inevitable, but it's a critical component of continuous improvement. So we embrace change.
And we fight it vehemently. We have to be able to differentiate between changes that make things better and changes that make things worse. Embrace the better, fight the worse. This is not a guide for making those differentiations.
Instead, YTHO helps keep track of decisions made and why they were made so we don't go back and forth on those decisions. Critical decisions are often made after lengthy discussion and debate, and keeping track of the salient points made, alternatives considered, and justification for decisions can keep those (sometimes difficult) discussions from resurfacing every few months (or weeks, or days). Keeping a visible record of the rationale for a decision gives the team a sense of which facts on the ground might have to change (business situation, technology available, etc.) before the decision is ready to be reconsidered. And because teams with multiple perspectives will often disagree, debate, resolve, and then commit, it keeps conflicts over disagreements from resurfacing.
Because experimentation is an important part of embracing change and continuously improving, tracking the results of experiments is critical. YTHO can provide a historical record of experimentation results and the decisions that were inputs to or outputs of those experiments. By recording what we've tried and the outcomes we can understand previous attempts at solving problems that had varying results (which we hopefully don't need to revisit).
Smooth onboarding
Joining an existing team comes with a lot of homework. New team members must understand the product, the project, the codebase, the architecture, the people, the processes, and good lord the list is way too long to capture here. YTHO eases that burden a little bit by providing context and rationale for key technology choices and trade-offs. It even eases the burden on other team members, who don't have to answer quite so many of the same questions over and over. And it can reduce the frequency of uninformed "Why don't we just use X?" debates introduced by new voices on the team.
On the other side of that coin YTHO can reduce the context and knowledge lost when a team member leaves a team. Anything captured in YTHO can survive team member churn and provide a consistent base for ongoing improvement in the team's work.
Shared understanding
Establishing shared understanding is super easy when there's only one person on the team. For larger teams we have requirements, specs, issues, tasks, personas, scenarios, user stories, risk registers, product vision docs, and all sorts of other stuff. Each has its purpose, and each team will have to choose which of them will help get team members on the same page about what to do and how to do it. Many of these documents can – and should – answer the question "Why are we doing this thing this way?" YTHO fills in the gaps when other documents leave out the why.
Given that YTHO exists alongside other documentation, a YTHO need not repeat what is in other docs. It's way better to link to source documents. If the reason for a decision is written in a specification somewhere, or called out in an assumption, or mandated in a policy, then YTHO should link to the source. YTHO can then fit nicely into a team's specific choices for ways to share their understanding.
Similarly, YTHO is intended to fit nicely into a team's processes. By adding it to source control, team members can propose and review new decisions using the same tools they use for changing code, documents, and other project artifacts. For teams that don't use Markdown and Git, it's easy to adjust YTHO to work in other file formats and document stores. Wherever and however a team's understanding is shared, YTHO can fit right in.
How to YTHO
Getting started with YTHO is simple: Just add a blank Markdown file to the root of your repository and name it YTHO.md. Think of one of the foundational decisions you and your team have already made – ideally one that might be questioned later – and write that decision and the reason you made it in your new YTHO file. You're winning!
Getting better at YTHO is pretty simple too. Add one or two more major decisions you've already made. Add new entries as new decisions arise, even retroactively when someone remembers a decision already made. Capture them during sprint retrospectives or planning. Brainstorm them at the water cooler or the white board. Remember them in the shower. Then dry off and add them to your YTHO.
Then start accepting contributions via pull requests. Make it clear that anyone on the team can add them, and anyone can request them when they want to know why a decision was made. Use your existing pull request review process, just like you would with code.
As soon as your team realizes you would all benefit from some consistency, choose a format. Depending on your project needs, team preferences, corporate policies, and regulatory environment this may need to happen at the beginning, before you add any decisions to your YTHO.
Pay attention to when your YTHO helps your team, and when it doesn't help and just feels like yet another documentation make-work. Evolve over time to keep on adding value and only using YTHO when it solves – or will likely solve – a problem. As your project grows be open to improving the format you've chosen to make your YTHO easier to add to, easier to read, more informative, and better aligned with the needs of your team.
Finally, keep your decisions alive. Past decisions are often just as helpful for understanding a project as new ones, so deleting old decisions from your YTHO might be a mistake. Instead, mark them with a status such as Proposed, Accepted, Superseded, or Deprecated as things change, and add links to their predecessors to show the history of those changes.
Some format options
Here are some decision record formats you might consider for your YTHO. Of course you can create your own format, and you might get some good ideas for what to put in it from some of these options.
Decision Story
A Decision Story is a record of a decision in a concise, lightweight format. It is not a strictly-defined format like the formats below. Instead, a Decision Story is any narrative-style explanation of a design choice. It should capture what decision was made, why that decision was made, and the implications of that decision. It is usually one or two sentences, added to YTHO.md as a single paragraph or as an item in a categorized list. Decision Stories are similar to User Stories in agile requirements gathering.
Decision Stories are an excellent starting point for any team considering using YTHO. They are a flexible format, allowing your team to iterate on and improve your template quickly. Capture only what you need, and enjoy the fact that you don't have to capture all those elements required by other formats that just feel like a lot of work.
A Decision Story example:
_We chose to_ **use Decision Stories** for our YTHO format because they
are super-flexible, and we don't feel the need to write strictly formatted
reasons for our decisions. _We will consider Y-Statements or MADRs_ if we
realize we need more rigor and/or detail.
Y-Statement
A Y-Statement is a decision record written as one very long sentence with six parts, covering functional context, concern being faced, choice made, alternatives considered, benefits achieved, and accepted drawbacks. Because they are just one sentence – and apparently intended to fit on one slide – Y-Statements should fit nicely into your YTHO.md file. Each of the six parts of a Y-Statement should go on its own line, as shown below.
Y-Statements are the perfect solution for a team that wants to write decision records concisely and consistently without giving up the critical elements expected in pretty much any decision-making context (the six parts of the Y-Statement are those critical elements). Following the Y-Statement format will remind team members to consider each of those critical elements before making important decisions. And isn't that all we really need?
Here's a Y-Statement example. Note that each line starts with a few words that introduce the critical element on that line; those first few words on each line should be used every time you create a Y-Statement:
In the context of documenting our architecture in a world chock-full of
viable documentation standards,
facing the need to choose a format with which to document our decisions
and their rationales,
we decided for **Y-Statements**
and neglected Decision Stories, Nygard ADRs, and MADRs
to achieve compact, detailed, and consistently detailed decision records,
accepting that some of the alternative formats have room for more detailed
explanations and nuanced arguments for and against various alternatives.
ADR, Nygard ADR, and MADR
An Architectural Decision Record (ADR) is, technically speaking, any record that captures an architecturally significant decision and its rationale – in any format. So all of the format options here are technically ADRs. Technically.
But the term ADR didn't get cool until Michael Nygard gave us the Nygard ADR, a one- or two-page format for capturing a decision. It includes sections for title, context, decision, status, and consequences. The documents are written in Markdown or Textile, numbered sequentially, and stored in the project repository.
A Markdown ADR (MADR) is an evolution of the Nygard ADR that uses Markdown, provides a handful of format templates with varying amounts of detail required, and offers a set of tools for managing MADR files and indexes. This is starting to sound familiar. And cool.
The Nygard ADR and the various MADR formats are well suited for larger teams and organizations in which knowledge sharing is a critical challenge. They are also great for regulated environments in which documentation must meet specific formatting requirements and include a consistent set of data points.
Because ADRs are individual files, they are commonly indexed in a separate document, and that index has significant benefits of its own: It makes it easier for team members to find decision records, especially on projects with lots and lots of decisions to record. It also allows for nuanced and detailed descriptions without crowding the space of what might otherwise be one long document full of every decision recorded. So they provide scalability and organization, leading directly to shared understanding, even across larger organizations.
And what better name for that index file than YTHO.md?
Here's a MADR example that uses a short template from the ADR GitHub Organization:
# Use Markdown ADR (MADR)
## Context and Problem Statement
How to write clear and concise decision records? How to write nuanced and
detailed decision records?
## Considered Options
- Y-Statements
- Markdown ADRs
- Word documents (from a template)
## Decision Outcome
_Chosen option_: **Markdown ADRs**, because
- they can be written from within our software IDE of choice;
- they work well in Git, GitHub, and our branching and pull request
practices;
- they use Markdown – which is simple to learn, very easy to use, and
keeps our writers from focusing on formatting instead of content;
- and because there are a handful of useful MADR templates that balance
our preferences for consistency, nuance, brevity, and detail.
PEP, KEP, and RFC
In large communities of practice decision documents are often written in a custom format that keeps the contents of the document aligned with the specific needs of that community. Python Enhancement Proposals (PEPs) and Kubernetes Enhancement Proposals (KEPs) are examples of formats specific to communities formed around open source projects (Python and Kubernetes, respectively). In some other communities those proposals (and/or decision documents) are written as Requests for Change (RFCs), sometimes called Change Requests. These documents are often detailed, thorough, and peer-reviewed. So yeah: They're long.
When your team makes a decision based on a recommendation or decision made by a separate community (inside or outside your organization), and when that decision is published to the public, there is no need to re-write that decision in your YTHO. Instead, link to the PEP, KEP, RFC, or other decision record from your YTHO.
Here's an example:
- For Python styling, follow
[PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/).
YTHO vs. Decision Logs
Decision Logs and Decision Registers are formalized ways of capturing significant decisions for a project, team, or organization. They include a set of metadata about each decision, and are usually captured in a spreadsheet, a database, or a project management application.
Capturing decisions in a spreadsheet is a terrible idea, in pretty much any situation. Spreadsheets are great at capturing tabular data and doing calculations on that data, especially when you need to generate a report from those calculations. While decisions have important metadata (title, date, etc.), they are intended to be written in clear and concise language, read by others, and collaborated on by folks who don't spend much time running numbers. Spreadsheets are not good for writing, reading, or collaborating (despite what some folks might say). For software teams, opening a spreadsheet means switching to an out-of-band tool and saving content in a binary format (not talking about CSV here – that's a data table, not a spreadsheet), which means diffs and reviews and commenting are all handled differently than almost everything else those team members do.
If you're considering storing decision records in a spreadsheet, don't do it. Use YTHO and you'll get collaboration, a familiar writing interface (e.g. your coding IDE), simple and non-intrusive formatting, and version control that works exactly like your code repository because it is your code repository. You won't lose any of the metadata because it will be included in your template. And your team will pay attention to your decisions because they will see them in their regular workflow.
If you've already got a spreadsheet that your team captures decisions in, you are one of the lucky few. You get to kill a spreadsheet! Save your Decision Log to a text format (hi again, CSV), convert the data to match your favorite YTHO format (or create a new template that captures the columns in your spreadsheet), and check it in for the win. Don't look back.
If, however, you are storing decision records in a database or project management application, you have a more nuanced situation. First off, YTHO solves a bunch of problems you might not have. If your database or application has a user interface that makes it easy to write, read, and collaborate on decisions, you're probably OK. If those decisions are easy to get to within the tools you use every day, even better. And if it encourages continuous improvement and facilitates communication of decisions that are being proposed, under review, or accepted, then you are golden. Don't change a thing.
Of course if some or all of those things are failing in your database or application, you might want to consider switching to YTHO. Maybe you can even save some money on database or application licenses.
Choosing a format
Having said enough already about how choosing your YTHO format might depend on your team size, compliance needs, decision criticality, or even how nuanced (a.k.a. long-winded) your rationales tend to be, here's another way to think about it: Imagine your design process as a boxer, and consider which weight class it might be in. Larger teams, higher regulatory constraints, detailed processes, and long-winded writers all contribute to a heavier-weight design process. Turn over your napkin and do some quick math, then consider this guidance:
Whichever format you choose, remember that the goal is capturing decisions in a sustainable, useful way, not adding bureaucratic overhead.
Go make your YTHO.md
As you prepare to touch YTHO.md in your project directory, here are some last-minute tips:
OK, enough reading. Open your code repo and get started on your YTHO in three easy steps:
Good work! You're on your way to creating a cultural habit in your team: Every critical decision gets captured, in every project, where everyone can see it. Over time you’ll build a living narrative of each project’s evolution. Your future self (and your contributors) will thank you.
Let me know how it goes.