Repository navigation
Confidence 6/10 · 1 issue to address
🟡 Confidence 6/10 · needs attention. Held at 6 because a correctness warning is open.
1 warning −1 · tests covered · risk high −1
Adds observer below member, makes an unknown role string read as observer instead of member, and rewords the member denial. The policy ladder itself is sound; the Members page's existing role reader reports an observer as a member.
observerjoinsRoleandRANKbelowmemberunder keyorg:observerroleOfanswersobserverfor any role string it does not knowhighestRolekeeps the member floor only for an empty role setholdersPhrasefor a member permission names admins, engineers and members
Before merge
- Manual · Create the
org:observerrole in the Clerk development and production instances, orroleOfwill never see the key
Findings
🟠 Warning · F1 · An observer member renders as Member in the Members page and cannot be promoted to member
correctness · packages/domain/src/policy/roles.ts:46-54
roleOf("org:observer") now answers observer, but observerRole stays out of assignableRoles, so entryOf (apps/web/src/page/settings/kit/org-membership.ts:13) finds no entry and falls back to the member one: the row reads "Member" with org:member preselected for someone who holds no grants. Picking Member then equals toOrgRole(member.role), so members/update.ts:585 drops it as a no-op.
Let `org-membership` resolve the observer entry (label "Observer") while keeping it out of `ROLE_ENTRIES`, so the row is not reported as a member and a Member pick still saves.
What was checked
- No production caller passes bare role names to
Policy.can; sessions, keys and device credentials carry Clerk keys (packages/auth/src/index.ts:780) holdersPhraseis only feddenial.requiredfrompermissions.ts, never a session's own role, so the reworded message is correct- The empty-set member floor is tested (
policy.test.ts:29) and the diff adds no untraced production work
bdcd2bc · Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Annotations
Check warning on line 54 in packages/domain/src/policy/roles.ts
maple-review-bot / Maple / review
correctness: An `observer` member renders as Member in the Members page and cannot be promoted to member
`roleOf("org:observer")` now answers `observer`, but `observerRole` stays out of `assignableRoles`, so `entryOf` (`apps/web/src/page/settings/kit/org-membership.ts:13`) finds no entry and falls back to the member one: the row reads "Member" with `org:member` preselected for someone who holds no grants. Picking Member then equals `toOrgRole(member.role)`, so `members/update.ts:585` drops it as a no-op.