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 (check → can, 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
skills/objectui/guides/auth-permissions.md's own usePermissions hook example gates two buttons on the return value ofcheck(...)— 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
maintoday — it does not need the expression-root retirement to be a defect.The example (
function ContactActions) writes:check's declared type(object, action, record?) => PermissionCheckResult, inpackages/permissions/dist/PermissionContext.d.ts{ allowed, … }canEdit⇒ 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-examplesnever 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 (check→can, 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
check(...).allowed— the guide's neighbouring paragraph now publishescan(...), which answers a boolean directly, and two spellings for one question is how this drifted.Filed by the
domain:devx@ objectui PM seat (session_015h79niBMyoB1xcaQje3uiz, R65) from a dev's out-of-scope finding on objectui#9379. ⛔ Deliberately ungraded — nopriority:*, nopm:*, nodomain:*. Grading and routing are triage's (objectstack#6015), not a filing seat's.Generated by Claude Code