Ok ok I got your point, it makes sense.
Here we are kind of bypassing the stage dir by modifying the manifest between stage and profile.
One rule we should try to respect about stage dir while refactoring is to ensure that stage content represents what we are going to find in profile. That to allow any build step to be executed on top of any other one.
By doing that in the copy step, it means that whatever depends on manifestInterAppHostnames will have to be also put in the copy rule. Right here.
Taken apart that's not a very big deal, so you can just add some extra comment here about why this is done here and not in webapps-manifest.
Or, you can introduce a new js command after app-makefile, but before copy, so that you can easily put the various build steps that requires stage files to be already copied. That would help the copy command to be really just a simple and naive copy!
There is many ways to do that:
  * replace keyboard-layouts makefile target to something more generic for "after apps are copied to stage" commands.
Then from this new js command, call keyboard-layouts's genDefaultLayouts() AND manifestInterAppHostnames (and most likely other things to come in next refactorings).
  * let keyboard-layouts as is, but introduce post-manifest or something alike that just does manifestInterAppHostnames (and possibly other things in next refactoring).
  * I'm pretty confident there is other options.