I've pinpointed the problem. And settled on a solution for the time being.
This is a limit imposed by tGFX. You cannot make "nested" screen transition calls because the screen transition handler only stores a single pointer to represent the active/pending transition. You can't then change that pointer in the middle of a transition. I suspect this would have had to have been implemented as a stack to get around this limitation.
The problem is that I'm requesting a screen transition before the active pendingScreenTransitionCallback->execute(); has terminated. Once that call terminates, and before evaluatePendingScreenTransition() gets a chance to evaluate my newly submitted screen transition function pointer, the pointer gets cleared. presenter.activate() and view.setupScreen() are called by the screen transition execute(), so any transitions requested inside those two functions will get wiped out and ignored when the screen transition terminates.
The solution I chose:
define actions in each screen which is an entry point to the password protected screen.
override those actions in the view and test the authentication state of the model before calling the appropriate screen transition.
This means I have several screens where this logical test is being performed. But its the only way I found to perform the redirect before drawing the intermediate screen at all.
There was 1 special case, which was the password protected screen itself. I have implemented a stack for navigating between screens and returning to previous screens. I store function pointers to the gotoScreenNoTransition() functions from FrontEndApplication on this stack. So if I my protected screen is the "previous screen" and gets popped off the stack, the authentication check doesn't happen because that gotoScreenNoTransition() call is way above my overriden view action in the object hierarchy. I've had to compromise and use the "Screen is Entered" trigger on an interaction and tolerate the brief flash of the protected screen before it redirects to login. Not ideal.
I will definitely consider the ModalWindow widget next time I implement something like this.