The only reason to use let is to indicate to the reader that you're going to be reassigning the variable to a new value at some point within the current scope.
If you aren't going to be doing that, using const lets the reader know the assignment won't change to refer to a new value.
Yes, I've heard this reason before, but how does that help? The only benefit of that particular arrangement as far as I can tell is that it's possible to enforce via linter. It doesn't signal intent, it merely states a fact that could be observed by reading the source code. What is the point of that? What problem does it solve? Are people running into hard to debug issues because a variable got reassigned? I don't remember that ever causing an issue before the advent of const. People go to great lengths to avoid writing `let` just because the linters have been telling them to use `const` so they consider `let` a code smell now. Is this really better?
It tells you up front what you would otherwise have to go line by line to find out.
There's a similar argument to be made for using forEach/ map / reduce / filter instead of a for loop. Each of those iterative methods has slightly different semantic intent. The only thing the for loop adds to the mix, and therefore the only reason to use them, is the availability of continue / break.
Hell, the same argument could be made for while loops vs for loops. What does a for loop really add that you couldn't get with a while loop?
As for your last point, I don't know of any linter that complains about the use of let when you reassign it. The ones I've used only complain if you use let when const would have worked identically in your code.
The fact that people write bad code is not down to let/const or linters. People always have and always will write crap and not understand why.
> it merely states a fact that could be observed by reading the source code
In 4 characters it clarifies something that could take 300 lines, 10 nested ifs, loops, etc; and, that trust disappears the moment someone, later down in the code *does* change the value.
Clarified intent, nearness-to-declaration, and linted protection are real benefits.
If you aren't going to be doing that, using const lets the reader know the assignment won't change to refer to a new value.
It's that simple.