I'm sorry if this conversation has gone around in circles--I've been traveling and haven't paid close enough attention.  To summarize, I think the entire series needs just 2 things:

- the unreg / reg bracketing any pg->set_role() calls in load_pgs(), add_newly_split_pg(), start_peering_interval(), etc.
- is_primary() checks in the reg/unreg methods so that we only unreg if primary and only reg if primary.  basically as you originally proposed, except keep the assert (which will now hold with the unreg and reg calls before/after role changes)

Does that make sense?  (If not let me know; I may still be missing something.)