In some cases there are many options and great talent is readily working on the problem for the given organization. Its nice to have options, but this is an exceedingly rare scenario. For example there are tons of options available today, but from reading HN job posts it looks like a the answer is still a CRUD app that does some SAAS solution with React, AI, and Python. I could guess that and be right more than 60% of the time, which is extraordinary considering these business have thousands of technology combinations and unlimited ideas to pick from. Its all about the talent available, but when I say talent I just mean people because when you are that restricted it isn't very talented.
Edit: typo
- https://github.com/peter-evans/lightweight-architecture-deci...
- https://www.thoughtworks.com/radar/techniques/lightweight-ar...
Lightweight ADRs are a good recommendation. I've put similar practices into place with teams I've worked with. Though I prefer to use the term "Technical Memo", of which some contain Architectural Decisions. Retroactive documentation is a little misaligned with the term ADR, in that it isn't really making any sort of decision. I've found the term ADR sometimes makes some team members hesitant to record the information because of that kind of misalignment.
As for retroactively discovering why, code archeology skills in the form of git blame and log, and general search skills are very helpful.
1. Either literally as a comment in the code. Immediately findable
2. As a description in the commit (easy to find with git blame).
3. As a comment in the Code Review/Pull Request system. This works for very stable things but is more brittle than the other ones. Usually exposes the discussion among parties but the outcome of that discussion should probably be in 1. And 2.
Another benefit of keeping comments in the context of where they happen is that you'll actually remember to update them. Otherwise, they're duplication (code smell) and introduce a risk of divergence.
That's why WYSIWYG standalone word docs or similar for design or manually written wikis are so dangerous for code that lives and keeps changing. The thing that keeps teams tidy is often single sources of truth where you can generate/render other things easily.
---
Reading tests or talking to someone is possible but if you had to do that for everything you might waste a lot of time so while it can be extremely beneficial I don't consider it my thought process.
To actually answer your question, do a git blame, check the commit messages and anything linked in commit messages. Do some search in the company’s internal knowledge base, architecture documents, specs, whatever you have available. Even if you don’t find a direct answer, understanding some more context might eventually lead to one.
If you have no documentation at all anywhere, then you have to analyze the code yourself. It’s part of your job. When you’re done be sure to document your findings.
Git commit will generally explain why it was done. The task it references may or may not explain the decision process that lead to it. Usually not.
It's rarely related to code, more often a business decision due to some obscure reason/desire which may or may not provide any actual value.
Sometimes, not generally. A lot of people are bad at commit messages, and commits migrated from older tools may be unusably terse because those tools didn't support multi-line commit messages well.
I see this a lot with developers who come in and start to criticise before understanding.
There is always a reason for why something is as it is, and it’s unlikely that the people before you were just idiots.
TL;DR: You have to reimplement the application or features to understand the "why" regarding technical decisions.
Otherwise cross reference ticket.
Otherwise search docs.
Otherwise ask teammates.
Otherwise don't change it.
If you have to change it have a careful rollback / DR plan.
When it comes to code, run the unit tests.