Problem
The web UI has no proactive auth guard. The only auth gate is a reactive axios interceptor that redirects to /login after an API call returns 401. Consequences:
- An unauthenticated visitor to
/, /tasks, etc. renders the full sidebar + loading skeletons, then flickers to /login only after the first 401.
/login has no "already authenticated → redirect to /" check.
- Token expiry mid-session on SSE/WebSocket streams (which auth via
?token=) silently fails into the hook's error state ("Connection failed") with no path back to re-auth — the reactive interceptor only fires on axios calls, not on EventSource/WebSocket.
Evidence
web-ui/src/lib/api.ts:147-152 — sole auth gate (reactive 401 → clear token → redirect)
web-ui/src/app/login/page.tsx — no already-authenticated redirect
useStressTestStream, useAgentChat, useTerminalSocket — ?token= auth, no re-auth on expiry
Fix
- Add a lightweight route guard (in
AppLayout or middleware) that redirects unauthenticated users to /login before rendering the shell.
- Redirect authenticated users away from
/login.
- On SSE/WS auth failure (401/handshake reject), clear the token and redirect to
/login.
Acceptance criteria
Source: release-readiness audit 2026-06-13 (frontend agent).
Problem
The web UI has no proactive auth guard. The only auth gate is a reactive axios interceptor that redirects to
/loginafter an API call returns 401. Consequences:/,/tasks, etc. renders the full sidebar + loading skeletons, then flickers to/loginonly after the first 401./loginhas no "already authenticated → redirect to/" check.?token=) silently fails into the hook's error state ("Connection failed") with no path back to re-auth — the reactive interceptor only fires on axios calls, not on EventSource/WebSocket.Evidence
web-ui/src/lib/api.ts:147-152— sole auth gate (reactive 401 → clear token → redirect)web-ui/src/app/login/page.tsx— no already-authenticated redirectuseStressTestStream,useAgentChat,useTerminalSocket—?token=auth, no re-auth on expiryFix
AppLayoutor middleware) that redirects unauthenticated users to/loginbefore rendering the shell./login./login.Acceptance criteria
/loginwithout shell flicker./loginis redirected to/.Source: release-readiness audit 2026-06-13 (frontend agent).