Skip to content

record:highlights field icon is normalized by the renderer and then drawn by nothing at the pin — a possible #8691-class dead key #10054

Description

@os-zhuang

Filed unassigned by the #9972 dev seat (session session_01URCaKuNTuK3BKJvwqM74QU) as an out-of-scope finding hit while enumerating the remaining icon slots in packages/spec/src/ui/component.zod.ts. Unlabeled for PM triage: unlike its sibling finding, this one is a candidate defect, not a prose gap — but the measurement below is deliberately partial, so the premise needs confirming before anything is done about it.

Observation

RecordHighlightsField.icon (packages/spec/src/ui/component.zod.ts, inside the object arm of the union) is declared describe('Icon name (lucide icon key)'), and the union's own describe advertises it: Highlight field: bare name, or {name,label?,icon?,type?,readonly?}.

At .objectui-sha = 82a94170c (read via git show 82a94170c:, not at the checkout's HEAD):

  • packages/plugin-detail/src/renderers/record-highlights.tsx:68 normalizes the authored shape and carries icon through: icon: f?.icon.
  • The normalized fields go to HeaderHighlight (imported at :17) and to useRegisterHighlightFields. Grepping packages/plugin-detail/src at that pin for a per-field icon read finds none: HeaderHighlight.tsx's only icon occurrence is size="icon" on a button. The chip has no icon slot.

That is the exact shape #8691 recorded for the reference-rail entry icon, which was refused on the strength of it: "the renderer declares it in its TS interface and the page synthesizer emits it, but no render path reads it — the card has no icon slot, so a declared icon draws nothing."

What was NOT measured — read this before acting

This seat's card was the page:tabs describe; the enumeration was in scope, a full liveness verdict was not. Specifically unverified:

  • whether any consumer of useRegisterHighlightFields (registered through packages/react/src/context/RecordContext.tsx) draws the icon outside plugin-detail — app-shell was not swept;
  • whether the Studio block designer publishes the key as an authorable input, which would make it an author-facing promise regardless of the render path;
  • whether an authored icon is visible anywhere in the running showcase.

So the premise here is "no read path found in the obvious package", not "measured dead". A first-touch grading that closes this premise-overtaken with the missing read point named would be a good outcome.

If it holds

ADR-0049 enforce-or-remove, the same route the rail's icon took: either the key is retired via ADR-0087 (with the union's own describe corrected, since it advertises the key to authors), or a read path exists and the key gets the read-point describe #9881/#9972 landed for the container icons. The intermediate state — declared, normalized, drawn by nothing, described as if live — is the one that costs an author silently.

Dedup checked: searched open and closed issues for record:highlights icon, for highlight-field liveness, and for the #8691 dead-key phrasing — nothing matches this key.

Backlink: #9972. Sibling finding on the same enumeration: #10053.

Activity

  1. os-zhuang commented on Aug 20, 2026

    @os-zhuang
    ContributorAuthor

    Triage (half-state heal — the card had domain:spec but no pm state): pm:queue, type Task. Measurement-first framing per the card's own honesty: the premise is "no read path found in plugin-detail at the pin", NOT "measured dead" — the dispatch's first job is closing the unswept surfaces (app-shell consumers of useRegisterHighlightFields, Studio block designer authorability, showcase visibility). Then exactly one of: (a) a read point exists ⇒ land the read-point describe à la #9881/#9972 and close; (b) measured dead ⇒ ADR-0049 enforce-or-remove via the ADR-0087 retirement flow, which touches the union's own describe that advertises the key — that arm narrows the authorable surface, Clause-②: yes, contract-review tier. premise_still_valid: false with the read point named is a good deliverable.


    Generated by Claude Code

  2. added theissue type on Aug 20, 2026
  3. os-zhuang commented on Aug 21, 2026

    @os-zhuang
    ContributorAuthor

    Maintainer ruling (2026-08-21, live PM chat — recorded by the triage seat)

    Verbatim (untranslated): 「其他接受」 — accepting the triage recommendation for this card: option A. The freshness gate confirms the premise is already closed: the 2026-08-20 measurement run closed all three previously-unmeasured surfaces and found RecordHighlightsField.icon measured dead at the current pin (zero read points — structurally unable to travel useRegisterHighlightFields; not designer-publishable — field-list input typed string[]; zero in-tree producers), while advertised in six author-facing surfaces. So the ruling executes directly as the retirement.

    State: needs-user-decision → pm:queue (domain:spec), dispatchable.

    Dispatch notes: ADR-0087 retirement under the spec-property-retirement playbook. Clause-②: yes (narrows the authorable surface; an authored icon becomes a named unrecognized_keys refusal at publish) — dispatch at the contract-review tier per the census ACCEPT's own note (claude-fable-5). Scope per the census: drop icon from the object arm + correct the six advertisements (union describe component.zod.ts:1013, RecordHighlightsProps.fields describe :1021, objectui plugin-detail/src/index.tsx input description, packages/lint/src/zod-issue-format.ts:25, regen content/docs/references/ui/component.mdx:554/:589). The objectui-side advertisement edit follows the cross-repo rule (consuming-repo follow-up card if not deliverable in the same change). Recorded confidence gap stands: out-of-tree customer apps cannot be enumerated — the retirement's loud refusal is itself the mitigation.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions