Repository navigation
ACL.md §1a: role scope as the standard, not folklore - #373
Merged
Merged
Conversation
The role graph said what a role may DO. Nothing said how much of the install a role may do it TO — so that question has been answered ad hoc, per screen, by whoever was looking at the time. §1a now states it as the standard, with the tiers in one vocabulary (SELF / ORG / ORG TREE / APP-WIDE) and the cut line named: `user` is self-scoped, `manager` is their org, `supermanager` their org plus its children, and `admin`/`superadmin`/`developer` are APP-WIDE — administering orgs is the job. "Tenant admin" is not a role in this model; if you mean someone bounded to one org you mean manager or supermanager. Two things the section is careful about: - **The unit of scope is the ORG, and how many people live in an org is the APP DEVELOPER'S decision.** One user per org, a team in one org, a tree of orgs — all valid configurations of the same model, and the ACL behaves identically under each. The platform scopes by org; populating those orgs is an application concern and deliberately not specified here. - **It reconciles with §1 rather than contradicting it.** "The same person can be `admin` in one org and `viewer` in another" is about where a role is STORED — on the membership, so it can differ per org. It is not a claim about reach. "What conforming code looks like" is the part that makes this usable as a standard: scope is decided in the SERVICE from the caller's role and passed into the model finder (a finder that hard-codes `org_id = <caller's org>` has silently decided no app-wide role exists); a tenant role is scoped automatically while an app-wide role is not scoped at all; and a missing org filter is a defect ONLY if a tenant-scoped role can actually reach that surface — read the acl.ini grant first. `Tiger_Model_Media::search()` is cited as the reference gate, since it already decides from role and org together. Also: the role descriptions in core/configs/acl.ini now name their scope in that same vocabulary, so the cut line is visible by reading down the list instead of inferred. `admin` said "Administrator" and `superadmin` said "Platform administrator", which is where the ambiguity lived. Description strings only — no behaviour, and nothing asserts them. AGENTS.md's Authorization section points at §1a before you write a finder. Unit suite green (1200 tests, 18318 assertions). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013vdyTeoDrGE4hKxt53TsE8
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.
The role graph said what a role may do. Nothing said how much of the install a role may do it to — so that question has been answered ad hoc, per screen, by whoever was looking at the time.
ACL.md §1anow states it as the standard. Inserted as 1a rather than renumbering, so no existing§Ncross-reference breaks.The tiers
guestusermanagersupermanagerparent_org_id)adminsuperadmindeveloperThe cut line is between
supermanagerandadmin. "Tenant admin" is not a role in this model — if you mean someone bounded to one org, you meanmanagerorsupermanager.Two things the section is careful about
The unit of scope is the ORG, and how many people live in an org is the app developer's decision. One user per org, a team sharing one org, a tree of orgs — all valid configurations of the same model, and the ACL behaves identically under each. The platform's job is to scope by org correctly; populating those orgs is an application concern and is deliberately not specified here.
It reconciles with §1 instead of contradicting it. "The same person can be
adminin one org andviewerin another" is about where a role is stored — on the membership, so it can differ per org. It is not a claim about reach.What makes it usable as a standard
"What conforming code looks like" is the operative part:
org_id = <caller's org>has silently decided no app-wide role exists.acl.inigrant first.Tiger_Model_Media::search()is the reference gate: it decides from role and org together.Also
core/configs/acl.inirole descriptions now name their scope in that same vocabulary, so the cut line is visible by reading down the list rather than inferred —adminpreviously said just"Administrator"andsuperadmin"Platform administrator", which is where the ambiguity lived. Description strings only; no behaviour, and nothing asserts them.AGENTS.md's Authorization section points at §1a before you write a finder.Unit suite green: 1200 tests, 18318 assertions.
🤖 Generated with Claude Code
https://claude.ai/code/session_013vdyTeoDrGE4hKxt53TsE8