Dave, I wanted to add a few comments here, in case it helps. The use of constraints may or may not work well, as Chris said for reasons of efficiency. The current RJ system adds/removes variables one-at-a-time, and therefore there could be many "proposed additions" which involve model likelihood calculations, but ultimately end up in a guaranteed rejection because they violate the constraint (of including too many marker variables). Furthermore, this would scale progressively worse, in the presence of even more possible marker variables.
An alternate approach that came to mind for me, thinking about your problem of "selecting 1 among 5 markers to include in the model" (and later, perhaps more) would be to reframe the RJ where it contains a single indicator variable, with a categorical prior, which determines which marker variable is included in the model. Then, the selection of "which single marker" is encompassed into a single RJ move, first updating the categorical indicator of "which marker to include", and then updating the value of the (single) marker which is currently in the model. I think this would be much more efficient, and hopefully would also scale well. The downside, here, is that it would involve re-working some of NIMBLE's RJ sampler functions, to operate instead on a categorical indicator (a modified version of the sampler_RJ_indicator function), and also a modified version of the sampler_RJ_toggled function, to only update the value of the "current" marker. You can find code for these, as they are used in the current RJ system, at:
Let us know if this sounds appealing, or you decide to go down this path. It sounds like an interesting problem you're working on.
Cheers,
Daniel