I ran into this as well. If an Event has a name, you can instantly grep across a giant monolith (or a big folder of microservice repos) and find every file that is concerned with that event.

If you pull it out into a constant, you're back to opening up projects one-by-one to 'find usages'

grepability is underrated. This is one of the reasons I dislike passing functions into interfaces - it makes it harder to follow the call chain when the functions are constantly renamed.

Luckily there are often solutions that just come down to which arbitrary labels that you assign. e.g. compare these two blocks

    do_thing = do_thing_one_way if condition else do_thing_other_way
    process(data, do_thing=do_thing)
versus

    thing_processor = do_thing_one_way if condition else do_thing_other_way
    process(data, thing_processor=thing_processor)
The first is much more greppable - search for "\bdo_thing" all over the code base. The second requires realizing that the processor function renames the internal function to "thing_processor".