If I needed such guarantees I'd create a minimal public interface which maintained invariants and sent events, and not allow random code to mess with the private implementation details.Someone would add in new logic or just forget and not send the changed event.
In languages which support such mechanisms, clean hard internal interfaces are a good way to modularize code so that it is still maintainable when one returns to it years later.