Handle render-phase redirects without committing
When a segment throws `redirect()` during render, the redirect boundary
used to commit a `HandleRedirect` child that navigated from an effect.
That meant the redirect couldn't happen until the whole tree committed,
including siblings still blocked on unrelated request-time data, and
hidden segments committed redirect state of their own.
Now the boundary suspends instead of committing anything, and schedules a
`redirect` navigator operation from a task. Hidden segments never navigate.
The operation dispatches a new `ACTION_REDIRECT` that carries the tree that
threw the redirect. Unlike a navigation, it's queued behind pending actions
instead of preempting them, and its reducer drops it if a newer state has
replaced that tree. This is the same guard the server-patch retry uses for
route tree mismatches. It also deduplicates redirects: once the first one
navigates, the rest no longer match the current tree.
If the navigation that rendered the tree hasn't committed yet, the redirect
takes over its push, so it doesn't replace the history entry of the page
the user came from.
`notFound()`, `forbidden()` and `unauthorized()` still go through the HTTP
access fallback boundary; porting them to work the same way is left for
later.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>