Wow, I just solved it... Apparently this had nothing to do with iOS versions, Google Calendars sync, etc. I just haven't realized that I need to pass a negative value to alarmWithRelativeOffset. This was completely non-intuitive. With a negative offset, it works perfectly. This also explains why zero offset was working before.
(I guess perhaps it might have a little bit to do with Google Calendars... I'm guessing that other calendars might support alarms after the event, and so that would have allowed me to debug the issue more easily, but it's not supported in Google Calendars so the invalid "alarm in the future" is just ignored).
There's still the minor issue where there's essentially no way to create an event without an alarm in CalendarA, but my guess is that nothing can be done here - even the native Calendar app has this issue.