In my opinion the specs should be in the same ns as the code.

My main consideration is my personal philosophy, and technically it works out well. My philosophy is that the spec of a function is an integral part of it. It isn't an extra thing. It's definitely not "two concerns" as put in the OP. Actually, it's what the function is, because in terms of correctness: who cares about the implementation? who cares what you wrote in your defn ? who cares about the identifier? who cares about anything but the spec?

I think it's weird because not only clojure.spec came later, also most languages will not let you have specs as an integral thing even if you wanted it to be, and anything close (tests in the code perhaps) is usually frowned upon, so of course it seems weird. But give it some thought, and you might reach a conclusion like I did (or you may not, this part is opinionated).

The only good reasons I can think of as to why you wouldn't want specs in the same ns are these two reasons:

It clutters your code. You want to support Clojure versions pre Clojure 1.9.0.

As for the first reason, well, again, I think it's an integral part of your functions. If you find that it really is too much, my advice would be the same as if your ns would be too cluttered up regardless of spec: see if you can split it up.

As for the second reason, if you truly care, you can check in code if the clojure.spec ns is available, if not then shadow the names with functions/macros that are NOP. Another option is to use clojure-future-spec but I haven't tried it myself so I don't know how well it works.

Another way this works out well technically is that sometimes there's a cyclic dependency that you cannot handle with different namespaces, e.g. when your specs depend on your code (for function specs) and your code depends on your specs for parsing (see this question).