Skip to content

[finding] bare element:filter / element:form nodes still validate clean, and retired component types are offered as typo suggestions — the node-level refusal #14159 built could close both #15110

Description

@claude

Filed by the os-dev developer subagent for #14159 (session session_0174WZTU6XcFcS7g2kykC53i, branch claude/issue-14159-user-profile-not-placeable) as an out-of-scope observation — not fixed there (the ruling's scope is the one member user:profile; every other member of both lists is untouched). Unassigned; triage's to grade.

Observation

#14159 (ruling B) adds RETIRED_PAGE_COMPONENT_TYPES (packages/spec/src/ui/page.zod.ts): a retired page-component TYPE is refused by NAME at the parse — the enum's error map, a check on PageComponentSchema.type, and the kept ComponentPropsMap row all carry one prescription. That closes, for user:profile, the gap the two earlier element-grain retirements recorded in their own docblocks as structural:

Two consequences remain measurable on origin/main (read at 29db3cd2; re-derived on the #14159 branch at 4c392c5d):

  1. A bare element:filter / element:form node still validates clean at every door. PageComponentSchema.safeParse({ type: 'element:filter' }) succeeds; os validate / os build / os lint accept it (the component-type-unknown rule treats a ComponentPropsMap row as known, and the SDUI 组件 props 没有解析闸门:PageComponent.properties 是开放 record,ComponentPropsMap 的 29 个站点从不被 parse(#4001 批 17 的 no gate 判定) #5068 props gate has nothing to judge on an empty bag). The user-visible consequence is the one Console renders nav:menu / global:search / global:notifications / app:launcher as "Component Placeholder" — four spec-declared PageComponentType members with no renderer #12183 and Ruling needed: does user:profile get a renderer, or become explicitly not author-placeable? — the one #12183 sibling that ruling never covered (gates objectui#7135) #14159 were filed about: the console draws the placeholder / unknown-type panel in front of an end user. The mechanism to refuse the node by name now exists; adding the two members to RETIRED_PAGE_COMPONENT_TYPES (with their own prescriptions — both already have a Delete the component story and a live replacement) is a contract decision (Clause ②: accept-set narrowing), so it is recorded here rather than done as a rider.

  2. Retired types are offered as "Did you mean" suggestions. KNOWN_COMPONENT_TYPE_CANDIDATES (component-type-vocabulary.ts) is derived from the enum + every ComponentPropsMap row, so element:filter, element:form — and, after Ruling needed: does user:profile get a renderer, or become explicitly not author-placeable? — the one #12183 sibling that ruling never covered (gates objectui#7135) #14159, user:profile — are candidates findClosestMatches can propose for a typo inside a reserved namespace (e.g. element:fitler gets Rename element:fitler → element:filter, a rename INTO a retired element). The vocabulary's docblock also describes the row-superset as "exactly" the measured string-arm registrations plus the two tombstoned elements; user:profile now joins that set, so the sentence is one member short.

What is NOT claimed

Suggested shape, if ruled

Add both names to RETIRED_PAGE_COMPONENT_TYPES with their existing prescriptions (the node-level check and the enum error map pick them up with no further wiring); have KNOWN_COMPONENT_TYPE_CANDIDATES exclude RETIRED_PAGE_COMPONENT_TYPES keys so a typo is never renamed into a retired type; flip the two docblocks' "not expressible here" sentences. Pins mirror component.test.ts's #14159 describe. PALETTE_EXCLUSIONS in objectui stays as is either way.

Refs: #14159 (the ruling and the mechanism) · #12183 (the four-sibling ruling) · #9220 / #9249 (the two element-grain retirements) · #12950 (the component-type-unknown rule and its vocabulary).

Generated by Claude Code


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

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions