M1 — Single SessionProvider via nested router.
The previous router had two route entries with `path: '/'`
(Navigate, AppShell) plus a separate `/login` entry, each wrapped in
its own RootLayout. That instantiated SessionProvider three times,
forking state the moment session writes diverged across siblings.
Replaced by one Root route with SessionProvider + <Outlet />, and
index/login/AppShell-children nested underneath. RootLayout (the
per-tree wrapper) is now obsolete and deleted; the new Root component
lives in src/routing/Root.tsx (addresses NIT N4 as a side effect).
M2 — Typo: "pollign" → "polling" in LiveCockpitPage masthead.
M3 — Replace asymmetric `?? 'rt_operator'` / `?? 'soc_analyst'`
fallbacks in LiveCockpitPage with an explicit `if (!user) return null;`
guard placed after all hooks (rules-of-hooks). AppShell already
redirects unauthenticated visitors to /login, so the guard documents
the invariant rather than introducing one.
NITs N1-N3, N5-N7 recorded in tasks/todo.md as sprint 1+ follow-ups.