__root identify effect called posthog.reset() whenever `user` was falsy —
which includes the brief window while the session resolves on every page
load. After the signup hard-redirect this rotated the anonymous distinct_id,
orphaning the pre-signup anonymous person that carries `user_signed_up` and
first-touch `$initial_utm_*`. The later identify() then merged a fresh, empty
anon id, so signups never linked to trial/payment (only ~16% stitched) and
channel attribution read "(none)" for 100% of signups.
- __root.tsx: gate the effect on isLoading and only reset() on a real
identified -> anonymous transition (logout), tracked via a ref. Logout
still resets via dashboard handleSignOut.
- register.tsx: identify() within the still-active anonymous session before
firing user_signed_up, so the anon->identified merge carries $initial_utm_*
and attributes the signup (email flow; Google is handled on OAuth return).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>