Bugfix: Why were legacy role strings (manager, editor, viewer, syste...

Documentation for Sessions

🐛 Bugfix: Why were legacy role strings (manager, editor, viewer, syste...

Date: 2026-03-31
Time: 18:42:06 UTC
Session: gspace1-293.4
Agent: angular
Confidence: 97%
Status: ✅ Documented


📋 Decision Context

Question:

Why were legacy role strings (manager, editor, viewer, system) causing silent capability denials?

Task: S293: Fix legacy role normalization in CapabilityGuard


🎯 Decision Made

Chosen:

Added normalizeToPlatformRole() mapping in both backend CapabilityGuard and frontend RoleAccessService. Maps: system→executive, manager→builder, editor→user, viewer→user. Unknown roles default to guest.

Options Considered:

  1. Normalize in the guard/service (chosen)
  2. Normalize at JWT creation time in backend-auth.service
  3. Add legacy roles to the capability matrix allowedRoles

💭 Reasoning

Root cause: JWT tokens contain legacy UserRole values (system, manager, editor, viewer) from the pre-S220 era. The capability matrix uses PlatformRole (executive, developer, admin, builder, user, guest). When CapabilityGuard called hasCapability('manager', VIEW_MEMORY), it returned false because 'manager' is not in the matrix — even though managers SHOULD have builder-level access. The fix normalizes at the consumption point (guard/service) rather than at JWT creation because: (1) existing tokens in the wild already have legacy values, (2) backend-auth.service already outputs platformRole on new tokens but old tokens lack it, (3) normalizing at consumption handles both old and new tokens. This was caught by the e2e test suite which verified all 6 PlatformRoles × key capabilities, exposing that legacy role users were silently denied everything.


📁 Files Involved


🔗 Related


Auto-generated by MCP Smart Consolidation