DEV Community

MEROLINE LIZLENT
MEROLINE LIZLENT

Posted on

Why Documentation Is Architecture

Most of the engineers consider documentation as an after-thought; a README on a finished system written in the final 20 minutes before a PR gets merged. That's the wrong way to do this relationship. Documentation is not a description of architecture. It is part of the architecture, and marking it as separate is the cause of so many rotting systems, which still pass all tests.

The compiler doesn't care, your team does

It could be a consistent codebase and yet it be undocumented garbage from the point of view of anybody who didn't write it. Only one sort of correctness is enforced by the compiler (or interpreter): does this code perform the operation that the instructions say it performs. It doesn't weigh in on why a specific table contains a deleted_at column, versus a hard delete, or why a service tries 3 times with exponential back-off, versus 5 times with a fixed interval. Those decisions include constraints that are not apparent in the diff, regulatory, historical, or performance. If these are only in the mind of the programmer who wrote them, the actual architecture is partially undocumented, and these constraints will be breached as soon as someone else messes with the code when it is under a tight deadline.

Architecture is not only the shape of your services and schemas, it's the set of decisions and constraints that shape stayed within. Undocumented constraints are like walls that we don't see, or know about. They are walked through without anyone knowing they exist, and one of the assumed conditions is broken at a time.

Documentation as a design artifact, not a report

Good documentation should be done prior to and/or in the midst of implementation, not after. When writing a design doc that explicitly states the problem, the options you considered, the one you selected, and the tradeoffs you made, you are actually doing real design work, you are making mistakes in your thinking process that would only become apparent during production. There have been more times I've trapped myself in bad assumptions when I'm drafting a “why not X” section of a design doc than I have been in writing code reviews. Code review typically is done to see if the implementation is as per the design; it is not usually done to validate whether the design was correct, but by the time there's a PR, the investment and effort in the implementation make it hard for the reviewers to question the approach.

This implies that design docs should be considered to be an essential piece of any nontrivial change; rather than an optional feature. The doc should include the invariant being introduced or preserved (e.g., for a new Go service, or an idempotent contract change in the FastAPI endpoint) rather than just a description of the code. This endpoint is idempotent for retries since it is based on the key of request_id which the client must provide for each logical operation. The endpoint is not: This endpoint handles POST requests to /orders.

Decision records outlive the decision-makers

The reason that Architecture Decision Records (ADRs) work is that it documents the shape of the reasoning, not only the results. 18 months later the question was always asked, "why didn't we just do the obvious thing?" A short ADR, context, decision, consequences, maybe three paragraphs, answers that question. If it wasn't for that history, the logic that seems like god's own work is tried, something that nobody remembers was structurally important gets broken, and the change is reverted at 2am. It makes the next engineer read 3 paragraphs and either realize the constraint is no longer true and move on; or realize why the constraint is still true and not waste a sprint to discover it the hard way.

This is particularly apparent when it comes to smaller teams and solo projects, where no one is around to ask. When you're the only maintainer in a project and you're away for 6 months, you'll only have the ADRs as your teammates when you're back. I've just reopened my own repos relating to Bitcoin/lightning and discovered that the commit messages give me the information about what changed but not why a specific timelock value or fee-bumping approach was taken over the other alternatives, and that took real time that a 3 paragraph doc could have saved all together.

Where documentation actively prevents bad architecture

There is a more strong version of the above statement to be made, and that is that documentation does not only document architecture, it enhances it. One of the best methods to review a design if you don't have the context is to explain to an imaginary reader who doesn't. This is free and is one of the best design-review techniques available. When it's hard to explain why a service owns certain data, it's probably not ownership, it's a wrong boundary. It is hard to explain the API without resorting to three exceptions and a footnote and if you need to do that, then the contract of the API is probably not consistent, it is just under documented. Documentation debt and architectural debt are often the same debt in other clothes, and paying off one debt will often result in paying off the other debt.

Practical shape, not process theater

This doesn't involve any heavy weight process. For a small team or solo project, a good document practice is: a one-page ADR for any decision that would be expensive if it was reversed, a set of in-line comments which explain why it is not wrong on the first glance, and a living Architecture document that gets a five-minute update whenever the responsibility of any major component changes. It isn't that it isn't enough to document, it's that it's missing where it could be most important, a pretty formatting wiki that nobody ever updates after the schema changes twice is worse.

Consider documentation a first-class design tool, and the architecture benefits as a by-product. As if it were some paperwork and the architecture slowly disintegrates without anyone ever realizing that it was an unnecessary loss to begin with.

Top comments (0)