Custom objects are pretty fragile. Simple tasks like moving control points on a curve has the potential to call Replace on the document with non-custom curve geometry resulting in a custom object turning into a non-custom object. UserData in this case does properly get duplicated and attached to the new object.
User data does have callbacks for Read, Write, Duplicate and Transform. Are there other events that you need to watch?
We probably need to add functionality to RhinoCommon to be of any serious help with this project. Is this a possibility or are you constrained to a version of Rhino we aren’t going to be adding SDK enhancements to (pre-Rhino 7)?