It looks like {NS,UI}TextVIew's implementation of auto-correct does indeed copy custom attributes, so I've implemented option (a) above - a complete check of the incoming text against the Yata backing store. This is the only way forward I can see. I've coded it up and it works.
One wrinkle is that I have to start the check one character before WillProcessEditing's editingRange because that previous character's attributes (and YataID) might have been copied when inserting the first character.
A further wrinkle is that when changes happen to NSTextStorage, the textview sometimes moves the cursor. But it does this well after {Will,Did}ProcessEditing. Discussion and various solutions are available here, however one that works for me is to do processing in WillProcessEditing (I must do that because I might need to change the TextStorage), remember the cursor position I want, and then apply the cursor position in the TextDidChange delegate function which appears to execute very late in the various text change delegates.