You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
RoleDefinition.permissions is required and read by nothing — every consumer uses only name/inherits #4288
Observation-class finding, surfaced while wiring @object-ui/permissions' tests into tsc for #4040 (tranche 1, PR #4287). Nothing a user meets today — filed rather than fixed because resolving it either way changes a public exported type.
permissions is the only required member besides name and label, and it is documented as the role's direct object-level grants.
Nothing in this repository reads it. A repo-wide search for role.permissions / roleDef.permissions / r.permissions over packages/** and apps/** (excluding dist and node_modules) returns nothing. The four places that take a RoleDefinition[] all use name and inherits only:
packages/permissions/src/evaluator.ts:18, and resolveRoles at :92 — walks inherits, matches on name
Every grant the evaluator actually applies comes from the separate ObjectPermissionConfig[], keyed by object with a roles map inside it. So there are two declared homes for "what a role may do", and only one of them is wired.
How it surfaced
Five of @object-ui/permissions' declared TEST_DEBT errors were TS2741 — fixtures annotated RoleDefinition that omit permissions:
src/__tests__/evaluator.test.ts(16,7): error TS2741: Property 'permissions' is missing in type '{ name: string; label: string; }' but required in type 'RoleDefinition'.
src/__tests__/store.test.ts(14,3): error TS2741: ...
PR #4287 gives each fixture permissions: [], which is accurate for those roles and leaves the type alone. That is the right fix for the test files, and it is also the thing that makes the dormancy visible: five fixtures independently omitted a required field, and every case still asserted exactly what its author meant, because no code path was ever going to look.
Why it is finding and not queued
No user-visible behaviour depends on it either way. It is one of two shapes, and telling them apart is a product question, not a code one:
The field is aspirational — role-attached grants were designed and never wired. Then it is ADR-0049 enforce-or-remove territory: either build the reader or retire the declaration.
The field is intended and merely optional in practice — every real role today gets its grants from ObjectPermissionConfig. Then it should be permissions?:, and the required-ness is what is wrong.
Either resolution edits packages/types' published surface, so it wants a ruling rather than a guess. Cheap to settle whenever the permissions surface next gets attention.
Findings triage (grade): hold — finding stays. RoleDefinition.permissions is a required member of a public exported type (packages/types/src/permissions.ts) that nothing in the repo reads — the evaluator family walks name/inherits only. Resolving it either way (optional-ize, remove, or wire a consumer) changes a public exported type, which is a contract call, not a lane fix; but with zero consumers and zero user impact there is no pull to force that call today. Held as the declared-but-unread record; escalate to a decision card when the @object-ui/types permission surface is next revised (the #4040 tranche work that surfaced this is the likely trigger).
Findings triage: promoted — finding → pm:queue as a member of sweep #4328 (dead-surface deletions batch 3). Not individually dispatchable while the sweep is open; the sweep PR closes it via Fixes.
Premise re-verified on origin/main @ b16be40: .permissions has zero production reads in packages/permissions/src — resolveRoles (evaluator.ts:92) walks only name/inherits, and the sole non-test hit is a test comment documenting exactly this state. The sweep row allows "remove" or an explicitly argued demotion-to-optional; the PR must state which and why.
Activity
claude commentedon Aug 11, 2026
Findings triage (grade): hold —
findingstays.RoleDefinition.permissionsis a required member of a public exported type (packages/types/src/permissions.ts) that nothing in the repo reads — the evaluator family walksname/inheritsonly. Resolving it either way (optional-ize, remove, or wire a consumer) changes a public exported type, which is a contract call, not a lane fix; but with zero consumers and zero user impact there is no pull to force that call today. Held as the declared-but-unread record; escalate to a decision card when the@object-ui/typespermission surface is next revised (the #4040 tranche work that surfaced this is the likely trigger).本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-zhuang commentedon Aug 11, 2026
Findings triage: promoted —
finding→pm:queueas a member of sweep #4328 (dead-surface deletions batch 3). Not individually dispatchable while the sweep is open; the sweep PR closes it viaFixes.Premise re-verified on
origin/main@b16be40:.permissionshas zero production reads inpackages/permissions/src—resolveRoles(evaluator.ts:92) walks onlyname/inherits, and the sole non-test hit is a test comment documenting exactly this state. The sweep row allows "remove" or an explicitly argued demotion-to-optional; the PR must state which and why.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
chore(sweep): retire four zero-consumer declared surfaces (objectstac…