Filed unassigned by the domain:ui execution seat while implementing objectui#5905 (the inputType tombstone). Measured, not fixed — see "Why this was not fixed in that PR" below.
The defect
skills/objectui/guides/plugin-development.md documents the ComponentInput shape (the fence marked os:check, around lines 95-110) and lists five members as ordinary writable optionals:
advanced?: boolean; // Hide by default in designer
inputType?: string; // Widget hint for the designer control
min?: number; max?: number; step?: number; // numeric bounds
placeholder?: string;
All five of inputType / min / max / step / placeholder are ADR-0049 RETIREMENT TOMBSTONES on the real ComponentInput: ?: never on the interface in packages/types/src/base.ts, plus a retirementTombstone() named refusal on the Zod mirror in packages/types/src/zod/base.zod.ts. min / max / step / placeholder were retired on 2026-08-31; inputType followed under the same card's ruling.
So the published guide teaches a write that is now a tsc error at the authoring site and a named parse refusal at runtime. This is the published skills tree — the guide an agent copies into a user's repository — so the blast radius is outside this repo, which is exactly where the tombstones' named refusal was bought to help.
Note the guide is stale for four of the five keys independently of the inputType change: that half has been wrong since 2026-08-31.
Why the gate did not catch it, which is the more interesting half
pnpm check:skill-examples is GREEN on this fence (measured on 0b24d7f8 plus the inputType branch: Semantic phase: 13 of 13 ts fence(s) judged, 0 failed). It is not skipping the fence — it judges it. The fence passes because the snippet declares its own local type ComponentInput = { ... } alias rather than importing the published one, so the gate compiles a private copy of the shape and cannot compare it against the real declaration. A structurally identical snippet can therefore drift arbitrarily far from the type it claims to document and stay green forever.
That is a different defect from objectui#5465 (the doc-snippet scanner not covering skills/ at all) — here the scanner does reach the file, and the local re-declaration is what defeats it.
Suggested disposition
Two parts, and the second is the one that stops recurrence:
- Correct the five members in the guide to record the tombstones, pointing at
description as the published remedy.
- Consider whether a snippet that re-declares a published type should be allowed to claim it. Importing
ComponentInput from @object-ui/types in the fence would make the drift a compile error instead of a silent lie, and the same shape probably exists in other guides.
Why this was not fixed in the inputType PR
Three reasons, all boundary rather than difficulty:
skills/** is a governed surface in this repository (agent drafts, human merges), so touching it changes that PR's landing route.
- The published skills tree carries a line-count ratchet, and the dispatch that produced the tombstone carried no net-increase budget for it.
- Four of the five keys were already stale before that change, so this is not collateral of it.
Generated by Claude Code, session session_01KbJQ1y1J12nZxYzFWhP8Q3, from the objectui#5905 implementation run.
Generated by Claude Code
Filed unassigned by the
domain:uiexecution seat while implementing objectui#5905 (theinputTypetombstone). Measured, not fixed — see "Why this was not fixed in that PR" below.The defect
skills/objectui/guides/plugin-development.mddocuments theComponentInputshape (the fence markedos:check, around lines 95-110) and lists five members as ordinary writable optionals:All five of
inputType/min/max/step/placeholderare ADR-0049 RETIREMENT TOMBSTONES on the realComponentInput:?: neveron the interface inpackages/types/src/base.ts, plus aretirementTombstone()named refusal on the Zod mirror inpackages/types/src/zod/base.zod.ts.min/max/step/placeholderwere retired on 2026-08-31;inputTypefollowed under the same card's ruling.So the published guide teaches a write that is now a
tscerror at the authoring site and a named parse refusal at runtime. This is the published skills tree — the guide an agent copies into a user's repository — so the blast radius is outside this repo, which is exactly where the tombstones' named refusal was bought to help.Note the guide is stale for four of the five keys independently of the
inputTypechange: that half has been wrong since 2026-08-31.Why the gate did not catch it, which is the more interesting half
pnpm check:skill-examplesis GREEN on this fence (measured on0b24d7f8plus theinputTypebranch:Semantic phase: 13 of 13 ts fence(s) judged, 0 failed). It is not skipping the fence — it judges it. The fence passes because the snippet declares its own localtype ComponentInput = { ... }alias rather than importing the published one, so the gate compiles a private copy of the shape and cannot compare it against the real declaration. A structurally identical snippet can therefore drift arbitrarily far from the type it claims to document and stay green forever.That is a different defect from objectui#5465 (the doc-snippet scanner not covering
skills/at all) — here the scanner does reach the file, and the local re-declaration is what defeats it.Suggested disposition
Two parts, and the second is the one that stops recurrence:
descriptionas the published remedy.ComponentInputfrom@object-ui/typesin the fence would make the drift a compile error instead of a silent lie, and the same shape probably exists in other guides.Why this was not fixed in the
inputTypePRThree reasons, all boundary rather than difficulty:
skills/**is a governed surface in this repository (agent drafts, human merges), so touching it changes that PR's landing route.Generated by Claude Code, session
session_01KbJQ1y1J12nZxYzFWhP8Q3, from the objectui#5905 implementation run.Generated by Claude Code