The original /products gate test expected either a Products heading
(signed-in) or a Sign-in button (signed-out). In practice the page
renders NotAuthorized (403) for any session without the right
org_role, so the second branch never matched and the test failed.
The Sign-in surface is dashboard-only today. Once M10.1 wires a
shared sign-in redirect for protected routes, widen this test.
Refs: M5.3
playwright.config.ts + tests/e2e/{apex,tenant,health}.spec.ts. make e2e for local. CI e2e job opt-in via RUN_E2E repo variable. OIDC click-through deferred to when stage is up.
Refs: M5.3
10 route shells under /[slug]/, role-filtered Nav, backstage stub at /__backstage__, dashboard reads session.products to render tiles. src/lib/session.ts is the canonical role × surface matrix; canSee() is the only RBAC primitive in the portal (real enforcement remains at the API layer). 24 vitest tests; 100% src/lib coverage.
Refs: M5.2
Next.js 16 + Auth.js v5 skeleton: host→slug middleware, tenant-context layout, OIDC sign-in flow against breakpilot-dev realm. 100% coverage on src/lib. Bumps next to 16.2.6 to clear trivy CVEs in 15.0.3.