Nice, you discovered a good case that my regex can’t find: which is a tag immediately followed by a disallowed character in tag like ,)`: #action,#keyword(#today) or any inline codeblock, which explains for your 4 bullet points.
$ marks an end of a word, which is an encounter with whitespace or end of the file.
What I’m puzzled about is your Obsidian not finding #action in non-inline codeblock. Mine finds it:
I’m not sure what the difference is. Maybe can you show mark-down text?