The Art of the Handover
I recently read that in a lean value stream your immediate customer, the one you should take care to design for next, is not the end customer, but the next step down the value stream — your internal customer.
This reminded me of an interview where I got asked a blunt question, the exchange went a bit like this:
“How can we trust that you will stick around?”
“What do you mean by that?” I replied.
“Well, it looks like in your CV the longest you have been in a company has been one and a half years, and it seems you like travelling and changing around a lot - how can we trust you are going to stick with us and maintain our systems and not leave us dry a few months down the line?”
When he said that, I got a tad annoyed; my first thought was, “This guy really doesn’t understand what DevOps culture is all about if he is talking about me sitting around “maintaining” when in reality he should be talking about me continuously improving the infrastructure. But then I figured he didn’t mean ill, he just wanted to make sure he was hiring the right candidate and it was a fair question to ask if that was his concerned. So I replied something like this:
“If your systems need constant maintenance by the person who has set them up, then you hired the wrong person, even if that person stays with you for ten years. You ideally want someone who sets systems up that are fully automated, reliable and easy to understand by his successor, then you will not be reliant on this person forever. I understand your fear, and yes it’s true that when I get bored in a role I move on to another challenge where I can learn more, but I will never leave you dry, I will make sure that the next person has an easy time understanding what I have done and can easily take over from me. My aim is to create value for you while I create value for my career, and I don’t feel I am creating additional value for myself or you if I am a bottleneck in your company.”
He seemed somewhat satisfied with that answer but I didn’t get the job, and to be honest I didn’t want that job either, I knew that from ten minutes into the conversation as I didn’t feel our values were aligned, so we were both happy in the end.
I have worked in places where the previous sysadmins and developers were not the best and their work was very difficult to follow and understand, which made my job hell at the beginning, and I have worked with other sysadmins and developers who are good at their jobs but their work is very hard to follow and confusing to deal with.
Whether you are handing your work down to a successor or handing it down the value stream (I’ll refer to both of these as customers in this article), it is very important you do it right and take your time to avoid technical debt, confusion and wasted time.
This is why it is important you take these points into consideration when handing over your work to someone else in your team or down the value stream.
Folder and file structure
I’ve worked with many people that create the file structure of their repositories like my mother arranges her kitchen; so only she understands the logic and locations of all her utensils and ingredients.
It is normal to have a little chaos in your repositories when you are starting to work on something, but as your work matures, improve it so it makes logical sense. Try and arrange folders and files so that it is as intuitive as possible, and if you feel it needs some explaining, add an explanation on the README.md file.
Also, deal with your repository the way Marie Kondo deals with homes; dispose of things that don’t “spark joy”, and only leave that which is strictly necessary; the more redundant files and folders you leave in a repo, the more someone will have to struggle to understand the utility of them.
Aim for coding simplicity
Your code should be very easy to read and understand. I know that sometimes you may be very tempted to show off your awk and complex regex skills, but if there is a simpler command that can achieve the same thing without significant performance penalties and it’s easier to read, always aim for that option. There is beauty in code that’s simple to read and easy to understand, when code is well written, even a person who is not familiar with the language can pick the general idea of what you are trying to do and you will save the entire company a lot of time.
Of course, sometimes it is not possible to do something elegant, beautiful and simple, in that case make sure you add comments where you explain why this was done this way.
Especially make sure to comment “hacky” solutions; if there was no way to do it any other way, explain why, and aim to fix it in the future.
Have a decent understanding of what you are doing
I know this seems very obvious, but I worked in places where people are looking for a quick solution to a problem, they find some code in stackoverflow and paste it there without fully understanding it. Sometimes the code may be complicated, uncommented and no one knows what it does.
One egregious case of this can be found in nginx and apache config files. I’ve worked with some of these files that made absolutely no sense to anyone in the company and no one had the guts to remove or simplify them in case something broke.
So try to understand and add comments to your code or configuration, and wherever possible put a link to the source in the code so people can at least see where you got the idea from.
Document contextually, rather than comprehensively or exhaustively
Exhaustive documentation covers everything that your application does, every parameter and every function. Man pages are a good example of exhaustive documentation. Personally I think exhaustive documentation serves a better purpose in software exposed to the public, and when your application has reached a fair level of maturity.
Exhaustive documentation is good for a quick reference and it works best when you are already somewhat familiar with the application. The problem with exhaustive documentation is that it often contains too much information for someone to get started or do a particular job, and you can easily overwhelm whoever you are handing down your work to. Also it takes a lot of work to keep up to date and maintain if the software is changing at a very fast pace.
Additionally, too often exhaustive documentation does not contain any usage examples, which makes it difficult to know how to construct accurate usage cases from it, as an example of this I am currently looking at the man page for xmllint.
I would expect comprehensive documentation to encompass less than exhaustive documentation and have a narrower focus on the most common use cases. The Agile manifesto aims to create working software over comprehensive documentation. This aim is preferable to spending loads of time documenting ever changing code ad nauseam that could be otherwise spent working on improving it.
In an internal lean value stream aim to do comprehensive or exhaustive documentation if you are leaving the team or company, otherwise contextual documentation is a better option.
Contextual documentation aims to provide all the necessary information required for someone to understand, operate and diagnose the application down the value stream.
Context can vary depending on the situation and the needs of your immediate customers. It can encompass anything from description and usage, to testing procedure and dependencies. Try and think what types of questions your customer would have and don’t make assumptions as to what knowledge they have, if you are unsure what to include, proactively ask your colleagues for their opinion.
Keep contextual documentation close to your source.
There seems to be a trend going on in many companies about confluencing everything, this is by no means a bad practice in itself. However if that means separating documentation from the repository, I see two problems with this approach:
- You have to effectively maintain two sources of truth.
- You have to trust that your customer knows where this confluence page is, and that she has access to it and doesn’t forget to go look at it when working with your application.
Having everything in one place makes things simple for you and your customer. I would advice using confluence to reference the repository, add a description for what it does and a link to the REAME.md for further documentation.
Use a wiki to maintain general documentation that applies to multiple repos, or perhaps tutorials with images that are better shown there, but then provide links to the README.md file in your repo where more up to date information is provided. It will be easier for you to keep your README.md file up to date with details.
You can also use the wiki to create documents about engineering practices, coding styles, etc. That you can later link on your README.md files.
Write concise and easily understood tickets
When you write a ticket for your own team, or for another team or even for yourself try and provide concise and clear details. Every ticket should have context, action items and any additional information that you can think of.
Here are a couple examples of most common bad tickets:
- One liner, vague tickets that explain nothing and give no context. Something like “Create role for x” or “give root access for y” is not a good ticket. Instead provide context why this is required, what needs to be done and any additional information that will help whoever needs to work with it.
- Tickets that contain way too much information. Examples of this are just pasting a chain of emails so the person who needs to do the work has to go through the whole exchange and try to make sense of it. This is especially bad when the person is not even familiar with the topic.
Design with your customer in mind
Always design your work aiming to make the life of the team down the value stream as easy as it can possibly be.
For example, if you are an SRE tasked to create an automated deployment pipeline, make it as easy as possible for your developers to be able to easily deploy their applications and revert when something breaks. On the other hand if you are a developer working on a microservice that’s going to be handed over to an operations team, you may want to make sure you design it with the best design principles in mind.
Take your time
Make sure to take your time to do a good job, if a product owner or anyone else tries to push you to deliver quicker, try and find a compromise, explain that good things take time, and it creates a lot more value down the line for you to spend the time doing an excellent, well understood application than having to pick up the pieces later. Agile doesn’t mean breakneck development, it means fast, short iterations of good quality software following design principles that aim for quality. Finally, don’t do any work for others you do not understand!
Following the above will take you more time for sure. However it will probably take you less time than the amount of time wasted by everyone trying to figure out convoluted code and documentation and the more people use your code, the more time you are saving to the entire company.
This also naturally yields itself to much better engineering and reliability and it falls under lean principles of manufacturing.
If you feel compelled to kindly leave praise, remember you can hold down the clap button to lazily express enthusiasm 😉