It is tackled at the very end of the article, but there is a very good and a totally valid use of the comments: answering "why?" questions (as opposed as describing the code).
This propagates to all other advice in this article.
Magic numbers? Comments can be good be useful if they answer "why"
PACKET_SIZE = 32 # Section 3.5.7 of RFC-99999
TODOs? Comments can be good if they answer "why" (as in, "why haven't this been done yet)
# TODO: once #1234 is fixed, rewrite as a binary search (right now it is not supported)
After-update notes? If the action is optional, make it a comment -- this will make upgrading to latest version easier.
# This function is present in libfoo-1.23, but our version is older, so we are re-implementing it here.
The author gets so close to the productive answer regarding TODOs, it's frustrating to see the conclusion be "...so never add TODO comments at all."
So what, after creating the issue for the future, the person implementing it has to start over navigating the code?
And the next person working on the code (who might not know about that issue) might stumble across the same obstacles as the original author who went on to file the issue?
I think in any multi-programmer project, the bidirectional link code<->issue needs to exist.
The only reason it's even controversial is code with "what?" comments, those just pollute the codebase (a little bit of high level what comments are sometimes Ok).
Comment everything. The worst thing that can happen is somebody concludes "nope, that's not true anymore." To avoid describing the system entirely is nothing but laziness. Rationalize it however you like, it's just laziness.
This propagates to all other advice in this article.
Magic numbers? Comments can be good be useful if they answer "why"
TODOs? Comments can be good if they answer "why" (as in, "why haven't this been done yet) After-update notes? If the action is optional, make it a comment -- this will make upgrading to latest version easier.