Skip to content

PermissionGuardConfig is published authoring surface with zero consumers, and its fallback union contradicts the only shipped guard implementation #8024

Description

@baozhoutao

Found while compiling packages/permissions/README.md for objectui#5174 batch 20 (the UNGATED_DOCS burn-down). Filed unassigned and NOT fixed there — that batch is scoped to one README plus one ledger entry, and this is a contradiction between two SHIPPED surfaces, which the card's standing ruling sends to a maintainer rather than settling in a README.

What

@object-ui/types declares PermissionGuardConfig (packages/types/src/permissions.ts), and @object-ui/permissions re-exports it (packages/permissions/src/index.ts). It is described in its own docblock as "Permission guard configuration for UI components". The only shipped guard component, PermissionGuard in @object-ui/permissions, does not accept it and does not agree with it:

key PermissionGuardConfig (@object-ui/types) PermissionGuardProps (@object-ui/permissions)
the required permission permission: string | PermissionAction action: PermissionAction
the target object object?: string (optional) object: string (required)
denied behaviour fallback?: 'hide' | 'disable' | 'redirect' | 'custom' fallback?: 'hide' | 'disable' | 'custom'
the custom content fallbackComponent?: string fallbackContent?: ReactNode
redirect target redirectPath?: string (nothing)

So an author who takes the published type at its word can declare fallback: 'redirect' with a redirectPath, and nothing in this repository will ever honour either: 'redirect' is not a member of the union the component reads, and no code reads redirectPath at all.

Measured, on origin/main 4bb33d7a4

Grep over packages, apps, examples, scripts, content, docs, skills, e2e, excluding dist/:

  • PermissionGuardConfig — 3 hits, all of them declaration or re-export: packages/types/src/permissions.ts (the export interface), packages/types/src/index.ts (barrel), packages/permissions/src/index.ts (barrel). Nothing constructs one, accepts one, or reads one.
  • redirectPath — 1 hit, its own declaration line.
  • fallbackComponent — 1 hit, its own declaration line.

There is no consumer, no test, and no doc page that teaches the type: the permissions README documents the component props, never this config shape.

Why this is worth a decision rather than a quiet edit

This is the declared-but-unenforced shape: a published type that lets an author declare a capability the runtime does not deliver, which is exactly the class the enforce-or-remove doctrine covers. The two candidate routes are not equivalent and neither is obviously right from the tree alone:

  1. Retire the type. Nothing reads it, so nothing breaks in this repository; it leaves the public surface of two packages, which is why it wants a maintainer rather than a passing dev.
  2. Wire it. Give PermissionGuard a config-driven arm that really implements redirect, and reconcile permission / action and fallbackComponent / fallbackContent to one spelling.

Route 2 is an expansion of declared capability with no pull recorded anywhere in the tree; route 1 is the default the startup-focus rule points at. Recording both rather than picking, because the choice is a public-surface one.

⚠️ Only the two spellings that CONTRADICT are asserted above; whether @objectstack/spec has a say in PermissionGuardConfig's shape was not measured here and should not be assumed either way.

Reachability, honestly

Nothing a user hits at runtime today, precisely because no code path reads the type. Its cost is authoring-time: a type-safe-looking declaration that publishes clean and then does nothing, which is the failure mode the contract-first rule exists to prevent.

Related: objectui#5174 (the burn-down that surfaced it), objectui#8008 (batch 18's two-shipped-surface finding on the same card, filed the same way).

Filed by the os-dev seat for objectui#5174 batch 20, from session session_01FhBNJcLRZLe8M87VcUgpKr; left unassigned for PM triage.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpackage: typespm:queuepriority:p3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions