@aboytsov is right that it's thread local (since it's a var). I think this issue doesn't actually matter, as long as we continue to treat drake.core/main as a singuler Drake process run. If we want to be more fancy than that, we'd need to revisit this and ask some design questions (e.g., what concurrency limitations do we want if a Drake process is handling multiple workflows?). But I don't want to foist these hypotheticals upon Myron, as that would be cruel and unusual scope creep at this point. Or, I might be missing something important, Artem please tell me if so.

@myronahn is right that techincally, the ^dynamic isn't needed, since we never redefine.

I think the crux if the matter is that we want a globalish variable to hold our semaphore, and we want to define it's value later (specifically, in core/main when we know the number of jobs). And the way we're accomplishing this now is not idiomatic. All things considered, I think I would just get rid of the set-jobs-semaphore function and do an inline def instead (in core/main). I wouldn't use ^dynamic, and I think I'd just call it JOBS-SEMAPHORE. Perhaps this is a bit raw, but there are only 2 places that make use of it, and they're both very clear and simple.

(BTW, I hereby claim credit for inventing the technical term "globalish". I cannot find any prior use within this... context. (See what I did there?))