Nothing weird about it, you see people arguing right here whether a site should add a new history entry when a filter is set.
Interacting with the URL from JS within the page load cycle is inherently complex.
For what it's worth, I'd also argue that the right behavior here is to replace.
But that of course also means that now the URL on the history stack for this particular view will always have the filter in it (as opposed to an initial visit without having touched anything).
Of course the author's case is the good/special one where they already visited the site with a filter in the URL.
But when you might be interested in using the view/page with multiple queries/filters/paramerers, it might also be unexpected: for example, developers not having a dedicated search results page and instead updating the query parameters of the current URL.
Also, from the history APIs perspective, path and query parameters are interchangeable as long as the origin matches, but user expectations (and server behavior) might assign them different roles.
Still, we're commenting on a site where the main view parameter (item ID, including submission pages) is a query parameter. So this distinction is pretty arbitrary.
And the most extreme case of misusing pushState (instead if replace) are sites where each keystroke in some typeahead filter creates a new history entry.
All of this doesn't even touch the basic requirement that is most important and addressed in the article: being able to refresh the page without losing state and being able to bookmark things.
Manually implementing stuff like this on top of a basic routing functionality (which should use pushState) in an SPA is complex very quickly.