Yes, you're supposed to avoid moving later commits across a rebase... but the reason you're supposed to avoid that is because git is so bad at it.
Where I agree with your take partially is that the UX for all of this in git is not great, and that ends up meaning that most people don't actually use git in this way. If the process of manually structuring the commits to clean up history on a feature branch were more intuitive, then I'd predict the issues of history-destroying rebases to essentially be moot; everyone would just present the commits for review exactly as we'd want them before review, and then we'd fast-forward merge into the main development branch without any issue. The problem is that doing this sort of restructuring after the fact isn't actually easy to learn how to do because of the poor ergonomics of the git CLI, so it's both tedious and error-prone for almost everyone. My perspective is that most of the concern around messing with history in git comes from being burnt by changes that were not intended by the one making them, and that workflows that avoid it (like merge commits) are essentially a compromise to avoid that risk by accepting a certain amount of cruft in the history of the main development branch. I don't blame anyone for using them, since the problems that make the rebase workflow harder are very real, but I don't think that the fact that rebase changes history is the real issue as much as it provides a mechanism for the actual underlying issues to manifest.
Git is a decentralized version control system. It is effectively a blockchain like Bitcoin but without the consensus mechanism, and just like transactions are final on the Bitcoin network, pushed commits are final in git. You can agree to use one branch over another, but if you are using git as designed (i.e. as a decentralized system), it can be confusing. Merge commits are how you can resolve that confusion.
It is a fundamental flaw. Either git needs to work better at using the history in all of its warty and real glory (for example offering a separate mutable presentation-layer commit-log in front of the immutable data-layer commit-log), or needs to provide better automation and mapping concepts that allow you handle incoming code that has a different history from the current branch.
Like if I have branch X and branch Y, and X is 1 commit ahead of Y, but I alter the comment of a commit in Y, now X is one or more commits behind Y and will not recognize identical code-changes as identical.
It gets worse if you squash a commit, where you start getting conflicts during merges and rebases even though the code-changes are the same.
I understand why these problems happen, and the ways to prevent it (don't rebase anything pushed), but it still underscores the fact that git doesn't properly accommodate its own love of rewriting history.
If git had a proper synced graph of history-rewriting actions (commit A was rewritten into commit B) then it would be able to provide better responses when doing a merge or reflist across rewritten branches.
That's a huge usability problem with git. Even as simple as a "rebase on merge" or "squash on merge" automation makes it impractical to push your topic-branch and keep working locally on that same branch while your topic-branch is being reviewed and tested, because git doesn't retain any concept of the fact that "this block of commits has been transformed into that block of commits and so you can consider them one-and-the-same".
I'm the git sme at my office and I deeply resent the amount of time I have to spent training juniors and students around git's jagged edges.
Ideally git should have a proper in-repo objects that reify a relationship between rebased/squashed/amended/etc commits and their predecessors and exposes that when you ask things like "hey is commit X in ref Y?" it could say "no, but there is a modified version of that commit".
There’s also a fun loophole where you can edit other people’s commits when doing a merge and attribute bugs to someone else. I caught someone doing this once (they were terrible at git) on account of I was the one who reviewed the code that got changed, and I specifically looked for that class of bug before approving it. Git blame and the commit history no longer agreed and I was able to show what happened.
Commits are actually snapshots of the entire repository, not just diffs, so even if the diff is the same, if the base is different, it is not the same commit. And when you rebase, all the old commits will stay there until you run the garbage collector, and only if they don't have a head.