fix(auth): the hydration ceiling did not reach isAuthenticated - #813
Merged
Conversation
The timeline was not slow. It was waiting on a gate that could no longer open. useRequireAuth exposes isLoading and hydrated as EFFECTIVE values: a 4s ceiling resolves them so a page stops waiting on an auth store that is never going to answer. isAuthenticated was computed from the RAW store, so it opted itself out of the ceiling that every other field honours. /timeline renders `isLoading ? spinner : !isAuthenticated ? spinner : content`. The ceiling cleared the first gate after 4s; the second stayed shut forever. It never redirected either, because the redirect only fires when there is no user — and there was one, which is why the header rendered notifications the whole time. Measured live before the fix, on a fully signed-in session: domInteractive 903ms all support API calls done by 2.1s feed request NEVER MADE long tasks none articles after 122s 0 Zero network and zero long tasks is what distinguishes this from a performance problem. Nothing was slow; nothing was running at all. The same page had rendered in ~10s on other loads, which is what made it look like variable slowness rather than a stuck gate. `!!user` is unchanged and still does the real work: a timed-out ceiling can only report authenticated for someone who already has a user object, and the "no user" case is asserted so the ceiling can never invent a session. The hook had no tests at all despite gating every authenticated page. Proven by mutation: restoring the raw flags fails the "lets a signed-in user through" case and only that one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012dpTLxh5GJWeWTF1UEvcD5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The timeline was not slow. It was waiting on a gate that could no longer open.
useRequireAuthexposesisLoadingandhydratedas effective values: a 4s ceiling resolves them so a page stops waiting on an auth store that is never going to answer.isAuthenticatedwas computed from the raw store, so it opted itself out of the ceiling every other field honours./timelinerendersisLoading ? spinner : !isAuthenticated ? spinner : content. The ceiling cleared the first gate after 4s; the second stayed shut forever. It never redirected either — the redirect only fires when there is nouser, and there was one, which is why the header kept rendering notifications the whole time.Measured live, on a fully signed-in session
Zero network and zero long tasks is what separates this from a performance problem. Nothing was slow — nothing was running. The same page rendered in ~10s on other loads, which is exactly what made it look like variable slowness rather than a stuck gate, and why my earlier timings ranged from 10s to 48s.
Safety
!!useris unchanged and still does the real work: a timed-out ceiling can only report authenticated for someone who already has a user object. The "no user" case is asserted, so the ceiling can never invent a session.The hook had no tests at all, despite gating every authenticated page. Proven by mutation: restoring the raw flags fails the "lets a signed-in user through" case and only that one.
🤖 Generated with Claude Code
https://claude.ai/code/session_012dpTLxh5GJWeWTF1UEvcD5