Start here. This is the direct spoken answer to practice first.
Overview
These outcomes express different product and HTTP semantics; choosing one merely because it changes the UI creates confusing behavior.
I use notFound() when the requested public resource does not exist, and redirect() when another URL is the correct next location or canonical destination. A missing session is an authentication outcome and insufficient permission is an authorization outcome; experimental unauthorized() and forbidden() require authInterrupts, so I do not present them as universally stable defaults. Unexpected failures are thrown to an error boundary, while ordinary validation errors are returned as expected data.