For future events, you need to store at minimum the local time; of course, that's not super useful to use, so you may also want to store the UTC as determined by the best current information when it was saved.
Whenever you get new rules, you need to look at at least all future events and see if their UTC offset changed and then decide what to do about it. Often the right thing to do is just adjust the UTC offset based on the new rules; but sometimes you might want to ask the user, or maybe just notify the user: hey, we got new DST rules, please confirm these modified events: [list]. Users don't always input times accurately[1], so a heads up lets them review the modified dates and update the events that were modified in a way that doesn't reflect their actual intent.
You might also want to look at past events and maybe also notify users that the rules changed, and you're sorry about any inconvenience because you didn't get the rules or didn't process them until after the event.
[1] If I'm planning to watch a sporting event on TV, I'm most likely to input it into my calendar in my local time, but the event is most likely scheduled in local time at the event. But not necessarily. IMHO, the closer to the time change the event is, the more important it is to get user feedback.
IMO the way to avoid insanity is explicit modeling, the pain comes from where different code was written with different beliefs about what the value "really means."
For example, if there's a lunchtime event in Bizarro São Paulo you record "Noon in Bizarro Brazil Time" or even ("Noon in whatever timezone that office building will exist in") because it really does depend on the rhythm of the city. In contrast, if it's an international video-conference, you might record it as a time in UTC or the timezone/city of the most-critical participants.
In both cases, users of the system should be able to see the "contract" along with the predicted moment in a probably-useful local representation. (I might not be in Bizarro São Paulo while I'm looking at the event, but I might know I'll be flying there later...)
If you're afraid a Bizarro-govt is going to do something weird at the last second and cause all sorts of customer complaints for missed events, you might code a system that keeps track of when predicted-times (in something safer like UTC or TAI) suddenly change for events in a way that might catch users by surprise, and then send out notices.
But also "whatever timezone that office building will exist in" may not actually be the same as the timezone that is actually used by the occupants of that office building. There are numerous communities which unofficially observe a different timezone to the one officially assigned to their locality.
You record a context sensitive date/condition based on the user intent (i.e. birthday travels with the user, in person meeting based on meeting location, international call based on local time or UTC, explicit timezone keeps the timezone, etc.). How you map user intent to recorded date is problem specific.
When the event happens you record the TAI. You may also wish to record the context sensitive date for auditing purposes, but it is not strictly necessary. You can rederive the occurred date if the event occurred in the past.