I think I may have discovered the cause, but not a good solution.
What I believe is happening is that when org.jboss.seam.faces.Redirect is used to handle the login-required="true" redirect to login, then redirect to the initial destination flow, it is killing the conversation.
When captureCurrentView is called, it creates a new Conversation (since there wasn't a long running conversation). Then, the login page joins that Conversation, since it has join=true. Then when the returnToCapturedView method is called, it executes Conversation.instance().end(); which ends the Conversation the login action had used.
Does this sound like the likely cause?
If so, any ideas on how to fix it?
Sorry to keep replying to myself, but there's no edit button.
What I'd meant to say was:
Any ideas on how to fix it, other than putting <begin-conversation join="true" /> on every single protected page's page.xml, which works, but is a total hack?