Skip to content

finding(skills): auth-permissions.md's usePermissions example gates on check(...), which answers an OBJECT — every gated button renders for a denied user, and the fence is unmarked so no gate compiles it #9671

Description

@os-try-charles

skills/objectui/guides/auth-permissions.md's own usePermissions hook example gates two buttons on the return value of check(...) — which answers an object. An object is always truthy, so both buttons render for every user, denial included.

The reading

Found by the dev landing objectui#9379 while repairing a different paragraph of the same guide. ⭐ This one is independent of objectui#9308 and is wrong on main today — it does not need the expression-root retirement to be a defect.

The example (function ContactActions) writes:

const canEdit = check('contacts', 'update', contact)
…
{canEdit && …}
reading value
check's declared type (object, action, record?) => PermissionCheckResult, in packages/permissions/dist/PermissionContext.d.ts
what the guide's own pipeline section says it returns { allowed, … }
therefore canEdit an object ⇒ always truthy
what a reader copying this ships both gated buttons visible to every user, including one who was denied

⇒ the guide contradicts itself within one page: its pipeline section describes the object, and its hook example then treats the object as a boolean.

⭐ Why no gate caught it

The fence is unmarked, so check-skill-examples never compiled it. ⇒ this is not a gate that failed — it is a gate that was never asked. The marked-fence floor the gate enforces is a floor, not a census, and an unmarked example is outside its population entirely.

Why it was not fixed while the file was open

The dev repairing objectui#9379 had this exact file open and did not fold this in, which I endorse: different defect class from that card's, outside the section that PR repairs, and skills/** is a governed surface — every extra file or paragraph widens what a human has to approve. ⭐ The same mistake inside the paragraph it did repair was fixed in place (checkcan, which answers a boolean), because leaving it would have made the repaired example untrue on its own terms. That bounded repair is named in PR #9669's body.

What a fix has to decide

  • ⛔ Not simply check(...).allowed — the guide's neighbouring paragraph now publishes can(...), which answers a boolean directly, and two spellings for one question is how this drifted.
  • Whether the fence should be marked so the gate compiles it. That is the durable half: an unmarked example is invisible to the only instrument that could have caught this.

Filed by the domain:devx @ objectui PM seat (session_015h79niBMyoB1xcaQje3uiz, R65) from a dev's out-of-scope finding on objectui#9379. ⛔ Deliberately ungraded — no priority:*, no pm:*, no domain:*. Grading and routing are triage's (objectstack#6015), not a filing seat's.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions