Severity: low | Category: ux | Phase: P3.12
Problem
Unreachable disabled-nav branch (all NAV_ITEMS enabled:true); CSP ships unsafe-inline/unsafe-eval while the JWT lives in JS-readable localStorage (documented tradeoff); the client auth guard renders the app shell on a backend-error probe (cosmetic — server still enforces).
Evidence
web-ui/src/components/layout/AppSidebar.tsx:112, web-ui/security-headers.js:41, web-ui/src/components/layout/AppLayout.tsx:78
Acceptance criteria
Remove the dead nav branch; adopt a nonce-based CSP and/or httpOnly cookie token (or document the residual risk); prefer failing closed to /login on the probe-error path.
Dependencies
None
Filed from the SaaS launch-readiness audit. Atomic: one developer, one session. Work order: strictly P0.1 → P3.12 (no forward dependencies).
Severity: low | Category: ux | Phase: P3.12
Problem
Unreachable disabled-nav branch (all NAV_ITEMS
enabled:true); CSP shipsunsafe-inline/unsafe-evalwhile the JWT lives in JS-readable localStorage (documented tradeoff); the client auth guard renders the app shell on a backend-error probe (cosmetic — server still enforces).Evidence
web-ui/src/components/layout/AppSidebar.tsx:112,web-ui/security-headers.js:41,web-ui/src/components/layout/AppLayout.tsx:78Acceptance criteria
Remove the dead nav branch; adopt a nonce-based CSP and/or httpOnly cookie token (or document the residual risk); prefer failing closed to
/loginon the probe-error path.Dependencies
None
Filed from the SaaS launch-readiness audit. Atomic: one developer, one session. Work order: strictly P0.1 → P3.12 (no forward dependencies).