Skip to content

docs(spec): record the live read point of page:tabs items[].icon (#9972) - #10055

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-9972-tabs-icon-describe
Aug 19, 2026
Merged

docs(spec): record the live read point of page:tabs items[].icon (#9972)#10055
os-zhuang merged 1 commit into
mainfrom
claude/issue-9972-tabs-icon-describe

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#9972

Text face only, the exact sibling of the landed accordion record: page:tabsitems[].icon parsed, rendered, and said nothing about itself — the same absence a liveness sweep reads as declared-but-unenforced, and the same absence that once cost a full dispatch cycle re-deriving a cross-repo read point before the retirement candidate was closed premise-overtaken. Nothing about what parses changes.

The key is live — re-measured at the pin, not taken from the card

Read at .objectui-sha = 82a94170c (the value at this branch point on origin/main), via git show 82a94170c: against the objectui sibling's object store:

  • Readerpackages/components/src/renderers/layout/containers.tsx:662-665: PageTabsRenderer guards on item.icon and renders a LazyIcon whose name prop is item.icon, inside the TabsTrigger, left of the label span (mr-1.5 h-3.5 w-3.5 shrink-0 opacity-70, aria-hidden).
  • Registrationcontainers.tsx:721: the items input of ComponentRegistry.register('tabs', …) publishes the key to the Studio block designer, documented as [{ label, value?, icon?, count?, visibleWhen?, children }].

Vocabulary resolves through objectui's LazyIcon (lib/lazy-icon.tsx — kebab-case or PascalCase, normalised to kebab-case, with a fallback when the name is not a real Lucide icon).

What changed

  • packages/spec/src/ui/component.zod.ts — a .describe() on the tab item's icon naming the consumer behaviourally, plus the docblock above it carrying the file:line anchors and the measured pin, in the idiom the neighbouring split keys already use.
  • packages/spec/src/ui/component.test.ts — an accept-pin beside the existing page:tabs blocks asserting three things: the key parses and survives to the parsed output; an undeclared sibling on the same item is still refused (so the accept is not vacuous on a schema that stopped being strict); the .describe() still names the consumer.
  • .changeset/tabs-item-icon-liveness.md@objectstack/spec patch.

Reverse verification ran from the committed state with the direction predicted first: reverting only the schema file turned exactly one pin red (description is undefined) while the accept and the strictness pin stayed green — the two do not read the description, so this is the observed direction, not the presumed one.

The remaining icon slots in component.zod.ts, per the grading's in-scope extra

Re-derived at this branch point with two probes (every line starting icon:, plus a multi-line-declaration probe and a sweep for any *[Ii]con* key), because a multi-line declaration would evade a single-line grep:

There are no other bare icon slots — the tab item was the last one, so nothing else qualifies for same-PR coverage under the "same two-anchor live-reader class" rule. Full enumeration, all out of scope here:

SlotStateWhy not in this PR
page:header.iconretiredKey(…) (ADR-0087, removed in 17.0.0)not a live key at all
reference-rail entry iconrefused with a guidance prescriptionmeasured read by nothing (#8691)
record:alert.icondescribe that already names the read pointalready recorded
page:accordion items icondescribe + accept-pinlanded as #9881
record:highlights field icondescribe, vocabulary onlynot bare; and its liveness is itself in doubt — filed as #10054
element:button.icondescribe, vocabulary onlynot bare; live but the read point is unrecorded — filed as #10053
object-metric.icondescribe, vocabulary onlynot bare; live but the read point is unrecorded — filed as #10053

The three vocabulary-only describes are a weaker class than this card's trigger (they are declared with intent, not bare), so they are recorded as findings for triage (#10053, #10054) rather than folded in here.

Verification

pnpm --filter @objectstack/spec test — 414 files / 11039 tests pass. pnpm --filter @objectstack/spec typecheck green (tsc, scripts tsconfig, and the test-layer ledger, counts unchanged). Generated artifacts: check:generated and check:api-surface green after a real DTS build; the describe regenerates nothing (git status clean beyond the three files, and the landed accordion describe text likewise appears in no committed artifact). Gate families were re-derived against the actual changed paths with scripts/pm/dispatch-gates.mjs; the run and its result are in the report on the issue.


Generated by Claude Code

…9972)
A `.describe()` naming the objectui consumer plus an accept-pin, the exact
sibling of the landed accordion record — so a liveness sweep stops re-deriving a
false retirement candidate for a key that renders.
Re-verified at the pin this repo builds against (`.objectui-sha` = 82a94170c):
`containers.tsx:662-665` renders `{item.icon && <LazyIcon name={item.icon} …/>}`
inside the TabsTrigger, and `:721` publishes the key to the Studio block
designer in the `items` input.
Nothing about what parses changes — the key was already declared and optional.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01URCaKuNTuK3BKJvwqM74QU
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation tests tooling protocol:ui labels Aug 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 1 documentable anchor(s).

1 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v15.mdx(via PageTabsProps (symbol))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see

Coarse fallback — 115 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 20b9a9ce1b184e55468444905dc215f64d459249packageMentionDocs.

Which tree this was computed on

This run read content/docs from ce5b456ed4a40490f146a4294ae20557f3ff718f — the merge of head e521aba3f9423b08d776e047f50adb4badf631d7 into base 20b9a9ce1b184e55468444905dc215f64d459249, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ce5b456ed4a40490f146a4294ae20557f3ff718f && git checkout ce5b456ed4a40490f146a4294ae20557f3ff718f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 20b9a9ce1b184e55468444905dc215f64d459249 e521aba3f9423b08d776e047f50adb4badf631d7 && git checkout -B drift-repro 20b9a9ce1b184e55468444905dc215f64d459249 && git merge --no-ff e521aba3f9423b08d776e047f50adb4badf631d7
node scripts/docs-audit/affected-docs.mjs --json 20b9a9ce1b184e55468444905dc215f64d459249

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 20b9a9ce1b184e55468444905dc215f64d459249 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@os-zhuang
os-zhuang marked this pull request as ready for review August 19, 2026 20:13
@os-zhuang
os-zhuang added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit 60e0f90Aug 19, 2026
27 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-9972-tabs-icon-describe branch August 19, 2026 20:51
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] page:tabsitems[].icon is the exact sibling of #9881 — live objectui reader, no .describe(), no accept-pin

2 participants

@os-zhuang@claude