Seems reasonable. Short-term, adding new things now does mean that the code gets split between <file>_enums_gen.h and specenum_gen.h, but long-term, we'll want to phase out the latter anyway.
I'm not sure about the name, given that codegen-side, I called them "generic"; so I'd probably make it bool is_<enum>_generic(enum <enum>). Then again, we are only using them for user flags, so it could instead be reasonable to use that language codegen-side.
Depending on the use cases, we might want to have a bunch more general #defines; e.g. for the last generic value (like EF_LAST_USER_FLAG or TER_USER_LAST) or the total number of generic values (like MAX_NUM_USER_EXTRA/TER_FLAGS).
Made it so the name for the function is chosen on a per-enum basis (just like the names for the generic enum members are). So it can be is_foo_user_flag or is_user_foo_flag or is_foo_flag_user_flag or whatever would be appropriately in line with other code involving that specific enum.
Follow-up idea to #48790 : when specenum has user flags defined, specenum generator could output inline function "bool is_<enum>_user_flag(enum <enum>)"
This would also at least reduce the need for defining likes of TER_USER_LAST.