Hacker News new | ask | show | jobs
by powersurge360 1363 days ago
I am becoming increasingly skeptical that good internal documentation is even possible. I've been working in software development for around 12 years and have _never_ seen it done well and asking around the best I've heard offered up is the equivalent of an internal stack overflow.

For a while, I thought that maybe an exception would be having a technical writer on staff but after reading this post I'm significantly disheartened on that front too. I'd be interested to hear if anyone on hacker news has experienced good internal documentation and even more interested if any of you folks have experienced anything truly _great_.

For my contribution, I've found that documentation fails for a couple of reasons. The first is the burden of correctness. The people who most would like documentation are also the people who most need the documentation and they usually are also the people most likely to be reluctant to contribute to the documentation because they don't feel they can accurately represent the information. Imagine someone ramping into a feature and spending a few days reverse engineering how it works, collecting info, etc. Sometimes they'll put it up somewhere but a lot of the time contributing partial information feels 'wrong'.

And the second bit I find to be a big reason why documentation efforts fail is just the sheer friction of putting it into the documentation store to begin with. In confluence, for example, if you have a bit of information it can be tough to work out how to categorize it, where in the hierarchy it should go, etc, etc. Or if it's a GitHub wiki you want to put it somewhere that it is discoverable but also be careful that it's 'correct' because you don't want to break backlinks if it gets recategorized.

I've mostly given up on it at this point. Instead, I take detailed personal notes and make them publicly available. It doesn't have to be correct because being advertised as personal notes means that it's my opinion on the truth rather than objective fact. It isn't far away from my codebase, I can just tap a short keybinding in my editor to type my notes or search them and I can link directly from the notes to lines of code in files to jump back and forth. The particular system I use means that if I write a short snippet of code to solve a one off issue (like calling a path helper to derive a URL that I can't find in the interface) I can even drop it in a code block and execute it right from my note-taking tool. It isn't ideal for sure but I've gotten way farther in having a shareable knowledge base this way than I have in literal years of trying to get a shared, useful documentation store spun up.

6 comments

The issue is that people seem to equate "good documentation" with complete.

It's just not possible to do this. I think it would be better to talk about "effective documentation".

My opinion on the matter:

Three levels of documentation

1. high level documentation that describes the problems and the goals from the business perspective

2. mid-level documentation that describes the architecture that gets us there

3. low-level documentation, aka code.

high level gives you direction (where), mid-level gives you context (what), low-level gives you implementation (how)

You need the what to understand the how, and you need the where to understand the what.

The other piece is an acceptance that you can't document away the need for tacit knowledge.

To draw an analogy.

No amount of documentation is ever going to allow a kid to hop on a bike and ride it perfectly the first time. That is not what it means to teach a child to ride a bike. Instead the goal is to have enough documentation to minimize the amount of time it takes that child to gain the tacit knowledge necessary to ride a bike acceptably.

Once you accept the above and lower your bar, "effective documentation" becomes much more achievable.

yes. and the hard part is keeping the three levels in sync.
One of the reasons this is hard is because it's not that easy to really separate the three levels of abstraction. It's very difficult to state the business requirements neutrally, without coloring in any technical sort of solution (especially since the technical solution is usually what the customer asks for), and it's equally hard for many people to write a high-level technical design without filling in (or assuming) various implementation details.

In my team, I have started spelling out more concretely what I expect from the documentation at various levels. Keeping with the three levels specified by the GP, we always document:

1 - business rationale: what are we building, and who are we building it for (enumerate the stakeholders and their processes)

2 - component diagram: a graphical sketch of what different building blocks are involved (datastores, api endpoints, webservers, etc), and showing the direct connections between them

2 - data flow diagram(s): showing entry, exit and storage points for each class of data moving through the system

3 - starter documentation: what does a developer need to know/do before working on this project? This includes tooling, pointers to outside documentation, and a reading guide pointing to the rest of the project's documentation.

The rest of the low-level documentation is the responsibility of the team itself.

By insisting on documenting the second layer mostly graphically, there is less potential for overlap between the different layers. Of course, no documentation system is perfect, but I find the above has suited us quite well for what we do (we write business integration software, no huge client applications or software suites. YMMV, obviously).

I love this separation of aspects and the graphical representation to nudge out overlap.

How do you keep the layers consistent? How do you keep track what update to some layer is not covered in some other layer yet? Is that visible right in your layers? or some outside backlog?

The simple answer is that we try to keep most of the documentation (layers 2 and 3) in the same repository as the code itself, though that in itself is no guarantee that the documentation is up-to-date. Layer 1 documentation mentions explicitly which changes are part of which project, so the project timeline (which is external to the development team) should show if a mentioned project is supposed to have been completed already.

There are no airtight rules other than being mindful of your own processes. Our workflow generally looks like this:

Changes to level 1 documentation are done by the product or project manager in preparation for the work, so it's pretty easy to make that part of the documentation lead, rather than lag, the implementation. It's stored in the project wiki, rather than with the code. But that wiki is still git-based, which means we have an easily auditable changelog to check when a particular piece of information was last updated.

Layer 2 changes are usually done by (senior members of) the development team, but it's done in the week before the implementation starts. Since we use those diagrams to communicate with the rest of the development team about the changes required, the documentation updates happen rather organically.

I find that layer 3 documentation updates tend to be the hardest to capture in a process, because the code itself is much more in flux than the higher layers. What helps us here is that our developers know that the codebase they're working might not be worked on again until months in the future, so it's in their own interest too to keep the documentation correct. That said, we do have an explicit check for documentation updates in our project delivery checklist.

The most challenging situation is when we discover during development that an architecture redesign is required, but most of the time an architecture adjustment also means we need to re-evaluate the workload and possibly the delivery date, which basically means our process resets and we re-involve the product or project manager. Funnily, this then usually results in more documentation rather than less...

We sometimes also have a 2-person development team for small changes (never 1 person though), in which case all three layers are handled by the same people. But because they're updated in different stages of the project, and because they're already used to the same workflow in larger teams, the small team size doesn't affect the documentation quality as much as I initially feared.

I'm convinced that the only good documentation is generated from code or config, and has a source which is necessary for the system to run.

A tool that tells you who commits most frequently to a service or file is better than an outdated yaml file with an owner. A firewall that won't let your service make outgoing requests unless you list its dependencies is better than a manual list of dependencies. An API doc compiled from the type definition of your API or from a schema which requests are validated against is better than a manual API definition.

I've never seen it done properly either, but I think it's more a matter of incentives than structure or tools. The places where it was worst were places where people's reaction to wrong documentation tended to be a shrug.

Sometimes there were people who didn't document coz they kind of liked being the font of all knowledge.

Confluence also sucks - even harder than jira, if that's possible.

Well the real problem is: What's good documentation?

I'll settle for examples.

Documentation is a multi-headed hydra where you have different levels of technical competency and foreknowledge and familiarity with the programming environment patterns in use the organizations, particular technical stack organization, the people inside of it, what the product does, etc etc etc

This is why IMO in any nontrivial organization you need a dedicated technical writer - if only someone that sorts out the wiki and keeps it clean.
In my future perfect world, every artifact, every service, every everything will have a TTL. Expired stuff gets culled, in stages.
I like this approach. What is this note-taking tool? I want to use it. Also linking to code from the docs sounds really nice.
I don't know about the GP, but I wrote a simple script that will make a mdBook site out of Joplin notes:

https://gitlab.com/stavros/notes/

It's org mode in emacs with the org-roam plugin. If I wasn't using emacs I would probably have a folder full of markdown files instead and leverage a project-based grep to search it. The real power in the system is that it's close to your editor and personal so you can iteratively build up your knowledge.

In particular, every GitHub wiki belonging to an organization or a public project itself is a git repo of markdown files that you can clone and commit to. I probably would use that for per project documentation w/ a separate folder for managing broader notes. I think it's important to separate the markdown from a project's code because otherwise you can have important markdown updates trapped in a branch that hasn't been merged yet and because git works by line rather than by word you can get into complicated merge conflicts by features that touch similar business concepts.

Org mode happens to add some niceties on top in that you can have an example code block (roughly comparable to a triple back-tick code block in markdown) that also can be executed. The example code block can take some arguments like what interpreter to use and will paste the output into another code block underneath the source code block.

Because org mode is also used for organizing tasks it is easy to use it as a scratch pad as you grind through tasks and if something turns out to be useful you can promote it to a top level note (or org-roam node). And even if it's not obvious that it's a note candidate, just thinking through problems 'out loud' in org means you can search and find it later when the same or an adjacent problem comes up.

Another favorite feature I like in org mode is that in any code at any time I can tap out 'SPC n l' and it will capture a reference to the file and the line in the file and allow me to link to it in my notes. It doesn't capture by line number but by copying the literal line, which means that as feature updates push the line number up and down, it still will be able to find exactly the right file in exactly the right line as long as the line's content hasn't changed. It also serves as a rather nice canary because if the docs link to a line that no longer exists, then the documentation has probably gone stale.

The last major win with org mode vs markdown is with org-roam, which borrows the ideas from the standalone program Roam Research (which also is very similar to notion). Every 'node' you make initially is a file and you can fill it in as a wiki type structure. Everything is flat on the filesystem and has a unique id prepended to it so you can't overwrite it with another node of the same name. There's also a UUID associated with each node so if you move from one place to another, none of the links need to be updated. Contrast that with a regular wiki or markdown where when you move a file to a new folder you either have to leave a redirect behind or go through and update all of the back links.

You can also start a node as a subheading and later on promote it to a full file with all the backlinks still working correctly.

I started using org mode years ago with spacemacs, got frustrated with spacemacs, and gave up until earlier this year when I found doom emacs and gave it another spin. I wish I had a better recommendation for an alternative but after looking for 4-5 years for something as good as org mode, I could never find anything. Notion seems like a popular alternative but there's also a lot of shiny bells and whistles in it that can cause 'productivity procrastination' where you spend time configuring and turning knobs instead of actually using the system. Ironically, the second best tool I found was plain pen and paper using a minimal bullet journal technique and taking special care to do indexing. Of course, you can't share plain pen and paper in that way, but the name of the game for personal use is low friction and ready access. The better a system scores on those two in term of note-taking the more useful it will be.