We do something very similiar, but we match run modes, module and templates - run modes rm_XXX is handled by the MyApp::XXX::run(), which pulls in the HTML::Template XXX.tmpl.
I guess if you wanted to handle inheritance, you could write some kind of BEGIN block in the derived modules that builds some kind of register at compile time, that is then used by setup() to build the CGI::App instance from. Then you just need to remember to do that for each derived module...hmmm maybe that just makes a different 'I always forget to ...' problem.
...it is better to be approximately right than precisely wrong. - Warren Buffet