Skip to content

web: derive auth state from the engine instead of a tab-local store #914

Description

@FSM1

Goal

Derive "am I signed in" from the engine, not from a tab-local store.

Problem

apps/web/src/stores/auth.store.ts is an independent, optimistic, per-tab writer, and #911 made it the thing the login redirect keys on. blueprint/web-client.md "UI state law" says the opposite: rendered state is the engine's word, with no independent writers, and unauthenticated pages redirect on facade auth state.

The engine event stream carries nothing auth-shaped — packages/client/src/worker/protocol.ts has snapshotUpdated, stalenessChanged, withheldUpdateEscalation, deadLetter, attributableAbuse, renewalFailed, opProgress — so there is nothing to derive from yet.

Consequences today:

  • facade.logout is origin-wide: it zeroizes the shared leader engine. authStore is per-tab memory, so logging out in tab A leaves tab B rendering /files as authenticated over a dead engine.
  • A token refusal, or a failover whose SecretSource re-export fails, leaves the UI signed in over an engine that is not.
  • This is the v1 two-store desync class re-forming one layer up.

Work

  • Add a session/auth event to the engine facade event stream and thread it through crates/wasm and packages/client.
  • Project it through the existing useSyncExternalStore snapshot adapter.
  • Reduce authStore to chrome only: the login method and the email to display.
  • Add the RequireAuth route guard for /files on top of the derived state, which App.tsx still lacks.

Gate

web unit + the web-e2e login spec. Both halves can run: tests/web-e2e/ exists (#809, #1078).

Dependencies

None outstanding. #804 (the auth store and login redirect), #805 (the useSyncExternalStore snapshot adapter), #809 (the web-e2e harness), and #910 (the threading surface this shares) have all landed — so there is no longer a land-one-rebase-the-other conflict with #910 to sequence around.

Blocks


Corrected 2026-08-06 against main @ 3d087d673. Stale before this edit: the ## Depends on section named #804, #805, #809 and #910, all now closed, so the issue read as blocked; the "land one, rebase the other" note against #910 is likewise discharged.

Part of #642

Metadata

Metadata

Assignees

No one assigned

    Labels

    comp:webpackages/client + apps/web — WASM host, browser seams, React UIv2-buildv2 rewrite build slice

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions