Episode 38 — Use Comments Carefully to Improve Maintainability Without Misleading Anyone
In this episode, we’re going to talk about comments in a way that beginners rarely hear: comments are not automatically helpful, and in automation they can become dangerous if they lie, drift, or distract. A good comment can save time, reduce mistakes, and help a new contributor understand why code exists. A bad comment can do the opposite by creating false confidence, because people trust written explanations, especially under stress. Automation code is often maintained when something is failing, which means the reader’s attention is limited and the temptation to rely on comments is high. That is why comments must be treated as part of the system, not as decoration. The goal is not to comment everything or to avoid comments entirely. The goal is to use comments deliberately so they add durable understanding that the code alone cannot express, while avoiding commentary that will become misleading over time.
Start with a simple principle: code shows what happens, but it does not always show why it happens. The why is where comments can add the most value. For example, a piece of automation might include a retry delay that seems oddly long, or it might include a validation rule that seems strict. The code can show the delay and the rule, but the reason might be tied to an external constraint, like service rate limits, a known timing issue, or a safety requirement. Without the why, a future maintainer might “clean up” the code by shortening the delay or loosening the rule, and accidentally reintroduce the very problem the code was designed to prevent. A comment that explains the motivation can prevent that kind of accidental regression. In deployable automation, preventing regressions is a major part of maintainability because automation is meant to be stable and repeatable. Comments are therefore most useful when they protect important intent that is not obvious from the implementation.
Another principle that helps beginners is that comments should be stable or they should not exist, because unstable comments are the ones that turn into lies. Many people write comments that restate the code in plain language, such as increment counter or check if value is empty. Those comments are rarely stable because the code can change while the comment is forgotten, leaving behind an outdated explanation. Even when the comment stays correct, it often adds no real value because the reader can see the same information by reading the code. In automation, redundant comments create noise, and noise is costly under stress because it hides the signals you need. A better approach is to comment on constraints, intent, and assumptions rather than on obvious mechanics. When you choose comments that are about the why and the boundaries, those comments are more likely to remain useful even if the implementation details shift.
Comments can also serve as a bridge for beginners when code must be written in a slightly more complex way to be reliable. Automation often has to handle edge cases, error paths, and recovery logic that make the code less straightforward than a simple script. For example, a function might have a seemingly odd sequence of steps because it needs to ensure cleanup happens even when something fails. The code can express this, but the design reasoning might still be unclear without context. A short comment that explains the intended behavior of the sequence can reduce misunderstanding during future maintenance. The key is to keep the comment aligned with behavior rather than describing each line. The comment should tell the reader what the block is trying to ensure, such as ensuring cleanup occurs before returning, rather than narrating every operation. That kind of comment improves maintainability by making the purpose of the block clear, which helps future changes stay consistent with the original safety goals.
It’s also important to treat comments as part of the audit story, because in automation repositories, explanations can matter during incident analysis. When something breaks, people look for clues about what changed and what the system was supposed to do. Comments can provide useful clues, but only if they are accurate. If comments claim a safety check exists but the code no longer enforces it, an investigator might assume the system is protected when it is not. That can lead to incorrect conclusions and incorrect remediation. This is why misleading comments are worse than no comments, because they cause people to stop looking. In automation, stopping too early is a common failure mode during debugging: you find an explanation that sounds plausible and move on, only to miss the real cause. Careful comment use means you write comments you are willing to defend later and that you will keep updated when behavior changes.
Another common beginner misunderstanding is thinking that comments are a substitute for readable code. In practice, comments cannot rescue code that is chaotic or unclear, especially under stress. If the logic is hard to follow, the best fix is usually to improve structure and naming so the code becomes self-explanatory. Comments can then be used to clarify the intent and constraints, not to patch over confusion. This connects to formatting standards and linting, because readable code is a foundation, and comments should build on that foundation rather than compensating for its absence. If you rely on comments to explain messy logic, you create a fragile situation where the comments must remain perfectly synchronized to keep the code understandable. That is rarely realistic over time, especially in distributed teams. A maintainable automation codebase uses comments to add missing context, not to carry the entire understanding.
Comments also interact with change over time, which is where they often become misleading. Automation code frequently evolves because external services change, requirements change, and environments change. When code evolves, comments must evolve too. If you are not willing to maintain a comment, it is better not to write it. This sounds harsh, but it is a practical rule that prevents comment rot, which is when comments become outdated and untrustworthy. Beginners can adopt a simple habit: when you change code, read nearby comments and ask whether they are still true. This habit treats comments as part of the same maintenance surface as code. In automation work, where reliability depends on small details, treating comments as second-class citizens is a recipe for long-term confusion. A healthy codebase is one where comments are relatively rare, highly meaningful, and consistently accurate.
Another area where comments can help without misleading is documenting assumptions and invariants. An assumption is something the code expects to be true, such as the idea that a configuration value will always be present, or that a certain input will be normalized before reaching a function. An invariant is a condition that should remain true throughout execution, such as the idea that an object is always in a valid state after a certain step. These are powerful concepts because they guide safe changes. If a maintainer knows what assumptions the code relies on, they can avoid breaking those assumptions accidentally. In automation, assumptions often involve the environment, such as the existence of certain permissions or the behavior of external systems. A comment that states an assumption clearly can prevent subtle breakage when someone changes how configuration is loaded or how errors are handled. This kind of comment is durable because it expresses the contract the code relies on, and contracts tend to be stable until deliberately revised.
Comments can also be useful for explaining the relationship between a piece of code and an external policy or operational requirement. Automation often exists to enforce policy, such as limiting access or ensuring certain steps happen in a certain order. The code might implement the policy, but it may not be obvious which part of the policy it is fulfilling. A comment can tie the code to the operational reason it exists, such as a compliance requirement or a security principle like least privilege. This does not require long explanations; it just requires enough context to prevent accidental removal or weakening of the behavior. The danger here is adding comments that sound official or absolute when the policy changes. That is why the comment should describe intent and context, not claim permanent truth. In other words, explain why the code was written this way at the time, and be prepared to update it when requirements change.
There is also a subtle social benefit to careful comments, which is improving collaboration without creating debate. If a code block has an unusual approach and the comment explains the rationale, reviewers are less likely to request unnecessary rewrites. This reduces rework because the team can focus on meaningful improvements rather than relitigating the same decisions. For beginners, this can feel like protection: your intent is visible, and reviewers can evaluate the change fairly. At the same time, comments should not be used to argue with reviewers or to leave emotional notes. Comments are part of the permanent record, so they should be professional, clear, and focused on system behavior. In automation projects, professionalism matters because comments may be read during audits or incident reviews, and you want the repository to reflect a calm engineering culture. Calm engineering culture supports calm operational response, which is exactly what maintainability demands.
To bring this together, using comments carefully means writing them where they add durable value, primarily in explaining why a behavior exists, what constraints it addresses, and what assumptions it relies on. Avoid comments that restate the code, because they add noise and are likely to drift into being wrong. Treat comments as part of the maintenance surface, updating or removing them when code changes so they do not become misleading. Use comments to clarify non-obvious decisions, external constraints, and invariants that future maintainers must preserve to keep automation reliable. In a high-stress incident, the most dangerous comment is the one that gives false confidence, so your aim should be fewer comments with higher accuracy and higher usefulness. When you get this right, comments become a quiet form of resilience, helping the codebase remain understandable and trustworthy even as it evolves and even when someone is reading it at the worst possible time.