added a comment - - edited
Okay, I believe I have determined the problem. Let's first consider a working scenario with two files, bar.cljs and foo.cljs. These are compiled in that order. The order of compilation is important to the bug, which I believe explains why incremental compiliation can sometimes fix it.
1. bar.cljs gets compiled. When its ns form is emitted, compiler/emit :ns adds "bar" to the ns-first-segments atom.
2. foo.cljs gets compiled. When compiler/munge finds the bar variable in the function call, it calls compiler/shadow-depth to figure out whether it is shadowing something. Since bar.cljs already got compiled, shadow-depth sees its ns in the ns-first-segments atom. This causes compiler/shadow-depth to return 1, and then compiler/munge correctly outputs bar__$1 for the variable name.
In the purposefully broken example which reproduces the shadowing error, bar.cljs no longer exists. Even though the bar namespace is required in foo's ns declaration, it never makes it into the ns-first-segments atom. This causes the compiler/shadow-depth call to return 0, so compiler/munge sees no reason to append to the variable name and simply outputs "bar" which shadows the bar ns.
I believe the fix here is to patch compiler/emit :ns to conjoin the namespaces of its requires and requires-macros into the ns-first-segments atom. I am working on that now.