Goal
Implement role-based access control across all ctrl surfaces and display the permission matrix.
Requirements
- apps/ctrl/src/routes/_ctrl/settings/roles.tsx: roles tab showing permission matrix table
- Permission matrix: rows = surfaces (Dashboard, Content, Email, Listen, Team, Analytics, Settings/*), columns = roles (admin, member, viewer), cells = access level (full, read/write, read, none)
- apps/ctrl/src/lib/permissions.ts: typed permission constant defining the matrix. Used by both UI and route guards
- Surface route guards: each _ctrl surface route's beforeLoad checks capabilities.role against permissions. Unauthorized: redirect to /ctrl with toast "You don't have access to [surface]"
- API route guards: extend requireOrgRole usage across all ctrl API routes per the matrix:
- admin: all access
- member: content r/w, email r/w, team r/w, listen r, analytics r
- viewer: dashboard r, team r, listen r
Out of Scope
- Custom role creation
- Per-resource permissions (e.g., per-mailbox access)
Complete when: Permission matrix displays in settings, all surface routes enforce role-based access, API routes enforce role middleware.
Dev Workflow
Each step is mandatory. No exceptions. No skipping steps. No committing to main. No solo merges.
- Branch -- Create
feat/<issue#>-<description> from main. Use git worktrees for parallel work.
- Implement -- Write the feature. Write tests alongside code. Run
pnpm test, pnpm check (oxlint + oxc-format). All must pass.
- Commit -- Commit to the feature branch. Descriptive message focused on the "why."
- Simplify -- Run
/simplify on all changed files. Accept structural improvements, flatten unnecessary abstractions, remove dead code. Commit the result.
- PR -- Create the PR. Reference this issue number.
- PR Review -- Run
/review-pr which launches parallel review agents (code review, silent failure hunter, type design analysis). Fix every issue found. Re-run tests after fixes.
- Team Review -- Post PR to the legion bullpen. Get consensus from the team before merging.
- Request Merge -- Only after consensus. Never merge your own PR without review.
Platform Rules
- No
any -- use unknown and narrow
- No emoji in code, comments, or commits
- UUIDv7 for all identifiers
- Zod is source of truth for schemas
- Wrangler owns all D1 migrations (never drizzle-kit)
- pnpm only (never npm/yarn)
- Tests in
tests/ mirroring source tree, never colocated
Done When
Goal
Implement role-based access control across all ctrl surfaces and display the permission matrix.
Requirements
Out of Scope
Complete when: Permission matrix displays in settings, all surface routes enforce role-based access, API routes enforce role middleware.
Dev Workflow
Each step is mandatory. No exceptions. No skipping steps. No committing to main. No solo merges.
feat/<issue#>-<description>from main. Use git worktrees for parallel work.pnpm test,pnpm check(oxlint + oxc-format). All must pass./simplifyon all changed files. Accept structural improvements, flatten unnecessary abstractions, remove dead code. Commit the result./review-prwhich launches parallel review agents (code review, silent failure hunter, type design analysis). Fix every issue found. Re-run tests after fixes.Platform Rules
any-- useunknownand narrowtests/mirroring source tree, never colocatedDone When