docs(auth): the org-role vocabulary is closed — correct the mirror's standing instruction (framework ADR-0108) - #2907
Merged
Conversation
…standing instruction (framework ADR-0108) `org-roles.ts` told the next maintainer "a role added server-side must be added HERE too". There are no server-side additions left to chase. The framework used to register every declared `position` / `permission` name as an organization role, so this list could always fall behind the server's. That channel was retired (framework ADR-0108, objectstack#3723): every value stored in `sys_member.role` is projected into `current_user.positions`, so a business role handed out that way was capability carrying none of the position system's controls. `sys_member.role` is now a closed, framework-owned list of owner / admin / delegated_admin / member; an app's business roles are positions, granted through `sys_user_position` or an invitation's placement (framework ADR-0105 D8). The mirror is therefore complete by construction rather than by vigilance. No behaviour change — the four names and labels are what they already were. Still a mirror rather than a derivation, but for a packaging reason now, not a design one: the names live in `@objectstack/spec` as `BUILTIN_MEMBERSHIP_ROLES`, which `@object-ui/auth` cannot import yet (this package takes no dependency on `@objectstack/spec`, and the constants are absent from the published 16.1.0 — they ship with the first ADR-0108 release). The doc records the exact swap for when it can. A new test pins the list to those four in display order so drift fails loudly instead of silently offering a value the server's enforced select rejects. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0186LhwkUBupmLJUUAMda5hU
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
July 28, 2026 07:20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to objectstack-ai/objectstack#3802 (ADR-0108), which closed the
sys_member.rolevocabulary server-side. Tracks the console half of objectstack-ai/objectstack#3723.Why
packages/auth/src/org-roles.tscarried a standing instruction that is now wrong:There are no server-side additions left to chase. The framework used to register every declared
position/permissionname as an organization role, so this list could always fall behind the server's. That channel was retired: every value stored insys_member.roleis projected intocurrent_user.positions, so a business role handed out that way was capability carrying none of the position system's controls — nogranted_by, no validity window, no scope check.sys_member.roleis now a closed, framework-owned list ofowner/admin/delegated_admin/member. An app's own business roles are positions, granted throughsys_user_positionor an invitation's placement (framework ADR-0105 D8).So this mirror is complete by construction rather than by vigilance — which is the opposite of the risk the old comment was warning about.
Why this is not yet the derivation
The obvious next step is to import the names instead of restating them. It cannot be done in this PR, for a packaging reason rather than a design one:
@objectstack/specasBUILTIN_MEMBERSHIP_ROLES/BUILTIN_MEMBERSHIP_ROLE_OPTIONS;@object-ui/authtakes no dependency on@objectstack/spec(its deps are@object-ui/typesandbetter-auth);@objectstack/spec@16.1.0from npm and grepped itsdist: zero occurrences. They ship with the first release carrying ADR-0108.The module doc now records the exact swap for when that lands: the four
export consts become a re-export andORG_ROLESbecomes[...BUILTIN_MEMBERSHIP_ROLES]. Labels and the grade ladder stay local — they are console concerns, and merging them into the name list would be the modeling error ADR-0108 D4 warns about.What changed
org-roles.ts— module doc rewritten: the vocabulary is closed, the stale "add it here too" instruction removed, and the blocked derivation documented with its precise unblock condition.index.ts— the one-line comment above the re-export, same correction.__tests__/org-roles.test.ts— a drift guard pinningORG_ROLESto exactly those four in display order, so divergence fails loudly instead of silently offering a value the server's enforcedselectwould reject with a 400.No behaviour change. The four names and their labels are what they already were; only the comments and one new assertion differ.
type-checkclean.🤖 Generated with Claude Code
https://claude.ai/code/session_0186LhwkUBupmLJUUAMda5hU
Generated by Claude Code