The issue is resolved.
I had made an mxml SparkSkin for the spark.component.RadioButton. The component responded correctly to mouse interaction, except on the BitmapImage (custom radio button icon) that I configured with a source for each state. My test users adapted by clicking the label, but of course they wanted to be able to click the actual radio button too.
After 2.5 days of painful redesigning the whole radiobutton logic and components from scratch: all behaved the exact same way when implemented. Then I tried putting my original skinned component in a new location in the same view, and it worked. When I switched to design view, I noticed a group sitting on top of my radiobutton icons at alpha=0. It was simply covering the button icon portion of the radiobutton component and blocking mouse interaction.
Lesson learned: If a component logically should work and does not, move it to a different place in the view, ideally the top layer (bottom of your mxml). Check design view for stuff that you created and forgot about. Don't doubt your logic which is probably correct, the problem is usually something very simple.