At some point some manager will come up with a solution for people moving away from teams and leaving with knowledge of the system. We can document it well, so people can come and go without the team losing knowledge. We just need to be sure to document everything in our undocumented system.
This plan will fail. Documentation takes time to write. When you have smaller teams, documentation usually becomes a "nice to have" rather than a "must have", so it won't get done. Or more accurately, "we will do it as soon as this urgent feature gets shipped." There is always another urgent feature to ship.
If leadership wises up and decides that no feature can ship without documentation, if documentation because a gatekeeping mechanism, the most likely scenario is that garbage documentation will be written to get a feature pushed to production.
This is because when we have an undocumented system, documentation is the feature we are shipping. You can get features or documentation, but not both at the same time. Yes, people building features can always document the new feature by writing some descriptive paragraphs. Yet trying to sneak in documenting an undocumented system along with code is an act of kidding yourself.
If you want to document an undocumented system, create cards where the feature is the documentation.
Keep in mind that even if you create cards for documentation, the documentation cannot cover everything. It can't because it is not possible.
One explanation for this, almost a proof, comes from philosophy. Hubert Dreyfus was an American philosopher who was a Heidegger scholar. One of Heidegger's ideas about existence is we exists in a complex network of meaning. A coke bottle is meaningful to us because we understand that there is a cola drink that comes with it. Along with the drink, it carries a narrative of U.S. innovation, commercial imperialism, 20th century advertising about families, tradition, and Christmas. 40 centuries in the future, if another species find it, they will lack all of this context, and a coke bottle will be some strange bottle.
The complex meaning that comes with the coke bottle is not conscious when we see it. It is unconscious, latent, but unsaid unless it is deliberately brought up. The coke bottle has different meanings in the US, where it can be seen as Americana. Whereas a Mexican it can bring up Hollywood idyllic societies and eating Mexican soups like pozole or menudo which requires a Coca Cola.
Dreyfus calls this unconscious, complex web of meaning and context the background. As the coke bottle example shows, the combinations of connections of context and meanings that a single coke bottle has is staggering. As we find new connections, those connections explode. We don't have a way to encode all of these connections. We can't do it with modern computers. We definitely can't do it with writing.
In many ways, we can't share information about what we know with others. What we can do is share ideas with some context, sharing some of this context and meaning with others. The other person gets to discover it by themselves, connecting it to their own background.
This appears so abstract that it is a nice intellectual toy, a crossword puzzle for absent-minded people. It has many practical uses, though.
Let's apply the insight of the background to documentation. Total documentation is impossible, because it is impossible to write down all the meaning of a system into writing as it stands today. It is even more difficult to encode its total history or its future.
Let's illustrate this. You may have an internal ticketing system written in Django. You need to describe the application's purpose, code, its features. All the features, even the ones that no one uses, but maybe someone will. Who the users are. The version of Django that you are using. All the libraries that Django is using. All of the extra libraries that you installed. The version of python that it is running. The c code that runs python and many of the libraries. The version of make that is used in linux, which is the OS we use in production, but MacOS that is used for development. Describing MacOS.
Yes, that is a silly example of completeness, yet I have seen documentation that tries to approximate this. Let's say that you are only documenting your own application, leaving the documentation of the libraries to the library authors. Total documentation of your own system is still impossible. We still have an explosion of combinations of meanings.
Let's enumerate how difficult is total documentation of just our custom systems. You need to document architecture and its changes over time. Business requirements, and their changes overtime. Document who the users are. How are they using it. Which features have bugs, but which also which bugs you can't change because users depend on their incorrect behavior. Document the code. Document every variable used; every piece of data. The database schemas used. The reason why we encode a Decimal as Numeric when exporting to JSON. The APIs that we are connecting to. And so on and so on.
We can save ourselves time and effort by acknowledging that total knowledge is impossible due to the Background. Instead of attempting total documentation, we focus on writing documentation that makes our system discoverable. We give hints rather than exhaustive explanations. We point out tricky areas of the code, places that diverge from the conventions (and what are conventions but a technical Background?) explaining why we did so. We grow it as a garden. The next time you use the documentation and something is missing, add to it.
It is not as impressive as trying to capture everything in the system, yes. But do this over time, and you will have documentation that is useful.