Blameless environment: no one should write quality code

At RIT ++, Nikita Sobolevn ( sobolevn ) delivered, as he himself called it, a sermon on the quality of code and processes in the company. Particularly sensitive, please pour yourself chamomile tea, but we do not offer to move away from the screens. You can disagree with any of the theses, insist that talking about TV shows is the key to a healthy atmosphere in the team, and claim that you do not need a strict framework of linter and CI to write good code. But if you ever blamed others for failures at work, you should read or watch Nikita's story.



Have you ever worked in a bad job?



I worked for a long time. My company was terrible. Everything was very bad, for nothing, everything is out of the ordinary. We had disgusting processes, hated clients and inept developers. Nothing could be done about it. When everything is so bad, you just don’t know what to take, where to start. You feel like a miserable cog that cannot influence anything.







When I say everything is bad, I mean that we had:





Yes, it was outsourced development, but that didn’t make it bad. People made her like that.



“People are doing a bad job, it's people who are to blame for the fact that the processes are bad, the code is poor and the customers are bad” - this thought tormented me for many years. People are to blame for the fact that I do not enjoy my work.







I attributed all possible sins to people and thought that they were the main source of problems. I was hoping that someday they will change, or others will appear, and everything will be fine.



In all seriousness, I thought about the fact that other companies employ fundamentally different people who differ in their internal qualities and professionalism, and that these other people are from a different test.


But at some point I began to guess that maybe people are not to blame - maybe a mistake on a different level, somewhere something went wrong so much earlier. And then the path to correction appears. Only then can you save yourself as a developer.



I realized that we need a revolution, that everything needs to change: the way I work, how I feel, that going to work does not become a test for me. I wanted to work in a good place.



There was only one problem - it was my company .







I am the person who started this revolution.



I realized that you need to change everything in order to again enjoy your favorite job. I love programming, I am ready to do it 12 hours a day and call it my rest and my work.



Therefore, I perceived all the failures very painfully. Not only were they connected with my favorite business, they were connected with my finances, with my sense of self and relations with other people and were strongly reflected in my whole life. When something did not work out for me, I could not rest, I could not think of anything else.



I decided that the most important thing I can do now in order to improve my life is to do my job well. For this, I needed to rethink all the chaos that we had and bring order to it.







But when you look into chaos, you don’t see patterns — nothing that would indicate how it should be.



Creating order out of chaos is an act of creation that is difficult.


You need to start from the very beginning to understand when everything flew into chaos. You need to determine a new order and explain to yourself what to do. These are beautiful words: “Let's do everything well!”. But you come to work and you don’t really understand what to undertake in order to change everything, there are no ideas.



The education you received and the books you read do not help, because everything you did before that you learned from these books and from this education.



Formulation of the problem



Then I thought - what is the biggest problem? Where is the most painful point that does not allow to live and work? I realized that this is a statement of the problem . For me, setting a task has always been quite optional.



I think many of you have seen the task from one heading "Fix the bug on the prod." We had a lot of these, I wrote them in one line, and then people did something wrong and tried to fix it wrong. I thought: “Why don't they think with their own heads? What are you doing at all? You need to fix a simple bug, and not do all this nonsense. "



Then I did not realize that I was really setting goals poorly. But at some point I still realized that I needed to do this in a completely different way, and I developed several principles.







Tasks should be short . Not in terms of describing how to “fix a bug on the prod,” but short in nature. Short, small tasks are convenient to do. They are understandable to anyone: a beginner, an average, experienced developer. Everyone can understand such a task and do it, for example, in half a working day. You can start with this.



Tasks should be ordered . When they set tasks, they often don’t think in what order they should be done. But tasks can block each other, parallelize, or add additional complexity to other tasks if completed ahead, etc.



Very little is said about the ordering of tasks: they are brought in to Jira or Trello, and then they are taken from there. But few think, and in what order, why and why the order is just this.



All tasks must be individual . What does it mean? Tasks are entities that exist within a project and always belong to someone. Sometimes right in the description of the problem you can find: “Sergey, Masha, please correct this. You know how to do it. ” You can’t do this, you need to give the whole context so that this task becomes individual within itself, so that any person who reads it can fulfill it. So that there are no scattered knowledge scattered about the project, and there are no hidden meanings in the framework of this task.



When the tasks became individual, short and orderly, people began to do them the way I want.


Just changing the way of communication, I made sure that the very people who had done this nonsense began to do what I want - is it not magic? Is this not proof that a lot is easy to change. And I began to delve further into this issue.



We often failed the customer, did not do what would benefit him. I thought that if developers began to understand our tasks and do them as they should, can they understand what the customer really wants and do as the customer wants?



I tried to combine this into a kind of two-faced figure, who on the one hand thinks like a developer, on the other hand - like a client.







This is not a new task. In general, this approach is called Domain-Driven Design and has been successfully used for many years. I decided to take the best - a way of communication, tools, technologies, and try to make the developers understand what needs to be done to satisfy the client's desires.



The task was very difficult, and I am still working on its solution. But I developed a simple formula for myself.



Requirements . It all starts with them, the customer expresses his will to us, the developers, in the form of requirements. The client conditionally says: "I demand that the login page works." Their awareness begins, scribbling in the form of tables, lists, graphs, etc. Requirements remain with you as the most important part of your project. This is what you do at the highest level.



But these requirements are not operable for the developer, they are too high-level and raw. To get started, the programmer needs documentation.



Documentation and requirements are twin brothers, this is dual unity. Requirements - this is what you need to do, and the documentation - how to do it.



When I realized that, in principle, documentation can be generated from requirements, this became an important part of our business process. We learned how to write down requirements in a special format and generate documentation.



Tests . The next logical step is to verify that it works. We began to test our requirements to make sure that we are really doing what is needed.



The most interesting thing is that I did not invent anything - I did not write a single line of code in order for this to work. I just took the existing technologies and received: requirements, they are documentation, they are tests.


The next logical step was to pull code on this whole thing, because code is what we are directly involved in.



Code - for the sake of which everything is actually started. In order for the customer and the developer to connect, it would seem that you need to get into one of them in the head and make them understand each other. But to get into the head, you can take the same tools and connect them so that the developer begins to understand what is happening. Here you can read how I do it in practice.



As soon as we combined (the Code is one!) Developers and the customer with the help of such ingenious interweaving of different entities, we achieved very important: our developers finally began to do what the business needed . They stopped introducing something just like that, because they saw the requirements and understood them, understood what needed to be done.



To make sure that we execute, we have tests that are written in the form of requirements, and these requirements are clear enough to be implemented in an understandable language in the code, and write good code according to these requirements.



Communication



I have already mentioned “communication” many times. I love chatting with my friends and family, but not at work. At work, I have to communicate with people - I did not choose them on this basis. Very often, communication at work does not help .



We all communicate with colleagues on non-working topics (discussing TV shows, etc.), because we are people. Fortunately, this flaw is fixable. In order to understand how really disastrous communication is for us, you can look at various examples.



First of all, people distract each other and tear from a state of flow. The man just came up and said something - what should I do with this now? Why did he tell me that he wanted to convey this?



Or rallies. I hate them, I always feel like an idiot when I sit at meetings. Everyone seems to understand something, they have smart faces, and I miss one and think when it will be over. I want to leave because everything that we discuss can be discussed much faster.



Rallies steal a huge amount of time and do no good.


There are several other important problems, for example, people begin to swear at these meetings. Imagine that you were placed in a small room full of people whom you don’t really want to see. You want to leave there, and these people make you make some serious decisions. Quite naturally, abuse starts - first passive aggression, then obvious insults. Unfortunately, nothing can be done with this, because people are conflicting beings. No matter how you try to moderate the situation, no matter how you pick up good people who don’t swear - people will swear, and this is normal .



There is another problem in our business - people disappear . Your front-end or devoop can easily stop responding one day. Especially people who work remotely can simply turn off the phone and end the conversation unilaterally.



These and some other problems seem insoluble. You can not teach all people to be good, non-conflict, responsible - it is simply impossible.



But you can live with it. Being a realist, you can understand that life is like this: people will disappear, curse, not want to communicate with you - this is normal. I solved this problem as follows - structured communication.







To structure communication, it is enough to take two steps:





When you are in a position that you can dictate your will to other people, you teach them to communicate. You show that communication should be structured and useful for all participants .



We chose communication through GitLab. If you have a question, ask it in GitLab. If you want to ask some strange question, ask it there. If you understand that there is no place where you can ask such a question, perhaps it does not need to be asked.



We only communicate on working topics . If someone wants to discuss the Game of Thrones - sorry, we are working, and discuss the Game of Thrones with your friends. If you want to discuss a new technology, create a ticket, let's discuss it: perhaps it will benefit the project. But "Game of Thrones" certainly will not bring benefits to the project.



Structured communication makes different people the same. GitLab even has avatars all about the same - one letter K, the other C, and I don’t know who these people are. I don’t care what they are, the main thing is that they communicate within the structure.



After we structured the communication, established work with the customer, learned how to write understandable tickets, it's time to get down to the code.



Code



And here a new problem lies in wait - people do not know how to write code, and this is normal . I used to think that others write bad code, and I'm good. But then I realized that I myself was writing bad code. And after a while it dawned on me that all people write bad code , and that's fine.



People are not made to write code. Programming is an aggressive environment to which a person is not predisposed. The code has a lot of complexities: architecture and a huge amount of information. In distributed systems, it’s terrible in general. It is difficult for a person to cope with the flow of information. And this is normal.



But if so, you can do something with this and learn how to work in these conditions.







In order to work with this, you need rigor - CI and tests that will be as strict as possible on what you are doing. It should be the Last Judgment - a tool that answers the question, good code or bad. Only by looking at it, the all-seeing eye of CI will say whether your work will fall into master or will remain somewhere on stage.



Such a CI, of course, should be inevitable. As soon as someone gets the exclusive right to commit to master, all attempts to build processes fall apart, because this someone starts to do all kinds of nonsense.



The inevitable and rigorous CI provides some more cool features. This is an opportunity to develop, because now there is a base bar from which you can build on: each next piece of code is better than the previous one. Each subsequent piece of code adds value to the project and improves CI. Each subsequent piece of code is a step towards development.



Once the foundation is ready, you can move on.



But people will still make mistakes, because no CI, even configured in the most rigorous way, can catch all the errors . And they will appear in places about which no one else will even think.



What can be done about this? You can return to the usual tactics and say: “You made a mistake, correct it. You wrote bad code - go learn to write code. " This is a bad path that does not lead to development.



In order to really write correctly and develop your product, you need a new approach and a new mentality.


Blameless environment



I called this approach Blameless environment - this means that I never blame people for anything . If a bug got into your project, this is a project problem. This bug should be fixed so that it never happens again. If this is a bug in the code, you need to write a regression test. If this is a bug in the project infrastructure, you need to write a tool that will prevent this bug.







When you start not just fixing bugs and hoping that everything will not fall apart on production, but correcting them at the system level, you start creating and creating - creating new tools, developing new approaches and architectural patterns. You start to think with your head and make sure that bugs do not recur.



Constant work on errors takes the developer to a fundamentally different level. You begin to invent tools for developers, implement them, promote, etc.


The creation that I am talking about is massive. When you try to use this approach, you will come across the fact that everything that exists now, especially for some programming languages, is not strict enough.



Once I wondered if I could write a linter that would make everyone write the same code. I was very strict and included all the possible rules that I could come up with. But people still write different code . It is very similar, but I can always understand that this code was written by different people. So, my linter is still not strict enough - wait for new releases.



The approach remains, we are waiting for the machine to respond, the program is well done or not. And it works, because such tools help in the work.



But we must not forget that people are necessary participants in the process . No matter what excellent technical settings you make, if the person’s experienced look did not go through your code, there can still be something that makes your hair stand on end, although CI passed.



On the one hand, we have dealt with our problem and we have rejected very bad code. But, nevertheless, we are not completely isolated from him. A code review process is required . If the code did not pass the code review, then everything you have done before is pointless.



Each next step makes sense only when there is a foundation for the previous one.


If you don’t understand what you are doing, or if you set the task incorrectly, no code review and CI will help. Everything I'm talking about makes sense only in the system. The code review step is only necessary for one thing - to check the person after the machine.







Let's talk about gifts - what gifts are in development.



The most important gift is our bugs . Each product has bugs. Many people clutch their heads: “We have bugs on the project, can you imagine ?!” But still they live with them, there are just critical bugs, but there are not so many.



Some people start two trackers: one for the customer, the second internal. In the one that is for the customer, beautiful features and descriptions, and inside - tin: solid bugs. It turns into a mess very quickly, I don’t even want to talk about it.



But for some reason, in our reality, a bug is bad. The person who reported the bug, if he is not a tester, hears: “What are you doing? You are breaking deadlines. We have to do features, but you find some bugs. ” To present a bug means to say that something is not working, something is bad. But in fact, the opposite is true.



A hidden bug is bad, a bug found is good.


Bugs are gifts that can be used for the glory of the project. This is what allows you to take more and more confident steps towards development.



Naturally, then you need to encourage people for reporting bugs. They must be heroes within the project and must be revered. But to achieve this is difficult. To do this, you need to look even deeper and start not with tasks, but with payment.



I don’t want to go deeper into payment, because they usually disagree with me on this issue, and so much that they stop hearing rational arguments and only hear emotions. I do not want you to listen to emotions, I want you to think with your head.



Further, it all depends on the specific implementation of how we solved all these problems, what tools we chose for our stack, what technologies we invented and wrote, what approaches we use to distinguish who is good and who is bad in their field.



The main thesis of my story is not the people to blame. The system that causes people to do wrong is to blame - the system that encourages people to take our total time at meetings, write bad code, and do everything that we fight against.


This system can be fixed and easy to do. You can take all the tools that we use, put them yourself and work. They are all open source , so you can easily start doing the same.



Implementation



Without implementation it would be uninteresting. I told you what we are doing in general, and now I’ll give you a few more points to rekindle your interest further - how exactly do we achieve certain goals.



Complete freedom . We understand that developers may disappear, not want to work and not work, they may have a bad mood, they need complete freedom. This is normal, so if you want, you work, you don’t want to, you don’t work. You have complete freedom of action, you do not depend on anything at all.



No communication. We have no one to say that you are not going to work today or are going to work. In fact, we don’t care: you are going to work - well, you are not going to - also okay. There is not even a reporting system about this.



No team. When people are united by complete freedom, they can do whatever they want - which team? These are just people who do not communicate, have not seen each other in life, they do not care about common values ​​and requirements. They came here to work and earn money.



Bots control people. But in order for all this to function, there should not be a main person - one who would lead everyone. If there is someone most important, then it will turn out not freedom, but nonsense. Therefore, we need a bot to rule everyone. It is also laid out in open source.



All code. When you work with developers, you write requirements as code, documentation as code, everything as code, you understand that everything is code. So you can do a lot, because you can code, test, track its changes over time, etc. The code is one!



Payment for the result. This is the most holistic part: we do not pay salaries. Someone joked that we do not pay developers in principle. Indeed, there are people who have worked with us and have not earned anything because they have not done anything. We pay only for the result. Since the tasks are small, understandable, we can determine the price for each task. A person performs a task and receives money for it.



Payment for tickets and for review. If someone completed the task that you created, then we will pay you for opening a useful task. If you made a good review code, then we will pay you for it.



Everything is checked. Naturally, any action in the project is checked. Created a ticket or conducted a code review - we checked how well you did it. Everything is checked so that people give a quality result.



And now I would like you to think about another way of working. It exists and is liked by some people much more than the usual way. If it gives the best result and people like it, then the future lies with it.



With Agile, many teams realized that not only testers were responsible for quality. To consider all aspects of the development of quality products, we launched QualityConf , this year as part of RIT ++, and next year we will take it to a separate event. Watch videos of past speeches here , and in order not to miss conference information, subscribe to the newsletter .



All Articles