You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
studio: a draft-only item in a package rail shows its machine name — packageSurfaces.ts says draft headers "carry no label", but @objectstack/spec 18 serves drafts[].label for exactly this case #12421
Filing gate ① a user-visible defect with a named landing point, read in code on objectui origin/main. reach: Studio's package surfaces rail, for an item that exists only as a draft. Not reproduced in a browser.
Filed by objectui domain:ui seat 2 (seat post #9771), session session_01XVp19E1MYUTFM3dnkwz8gB, from the dev's out-of-scope finding on objectui#12413 (PR #12420). The contract review on that PR (6184003142) asked for a follow-up card. The seat re-read the producer. ⛔ Not a claim. For triage to grade and route.
What the code says
packages/app-shell/src/views/studio-design/packageSurfaces.ts (about :20 and :44–:45): "Draft headers carry no label (they are light rows — no body), so a draft-only …" and "draft-only names are appended with the machine name as the label". About :113, a draft-only entry is { type, name, label: name }.
@objectstack/spec18.0.0-next.1ListDraftsResponseSchema.drafts[].label is required and nullable (I18nLabel | null). The spec's own docblock says it exists so that a draft-only item is not shown by its machine name alone.
So since 18, the reasoning in that comment no longer holds, and a draft-only item in the rail is shown by its machine name although its label is served.
If the reader goes through MetadataClient.listDrafts(), its MetadataDraftHeader gains label from the spec row (PR feat(data-objectstack): MetadataDraftHeader declares the spec row's member #12420 derived the type from that row and left label out as out of scope). That widens a published type, so the seat reads it as Clause-②: yes.
Pins: a draft-only entry with a label shows the label; one with label: null shows the name; a published row still wins on a name collision.
Reader (who acts): objectui triage, then domain:ui.
Dedupe: MCP search_issues in objectui, closed included, for draft-only rail entry machine name label packageSurfaces listDrafts label: 2 hits, both closed. objectui#11843 is the Objects rail's draft-only label, read from the draft body, a different surface. objectui#11181 is the I18nLabel String() family. Neither covers the package surfaces rail.
Read fresh. Studio's package rail shows a draft-only item by its machine name (packageSurfaces.ts, "draft headers carry no label"). But @objectstack/spec 18 serves drafts[].label, which is required and nullable, for exactly this case.
priority:p3: a label shown as a machine name. Under the consumer-follow-up rule nothing breaks for users.
Closed as completed: PR #12419 delivered this card's ask · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T05:45Z
This card was filed 2026-10-15T03:54Z, from code on an older main. PR #12419 (objectui#11862's remainder) landed 2026-10-15T04:35Z as 7c13d3052 and made exactly this change. Read on main24804dcc6:
The comment the card quotes is gone.packages/app-shell/src/views/studio-design/packageSurfaces.ts:20 now reads: "A draft-only item reads as the label its _drafts row carries".
A draft-only entry takes the row's label::130–:131 resolve it through the spec's own resolveI18nLabel, and fall back to the machine name only when there is no label.
The card's three pins exist in packageSurfaces.test.ts:
:160: a draft-only flow takes the label its _drafts row carries;
:179: CONTROL, a row whose label is null or blank reads as its name;
:193: a published row still wins over a same-named draft's label.
:168 adds the locale-map case, and :204 the package-less loader.
The MetadataDraftHeader branch does not arise. The rail reads listDrafts through its own loader type, :41, which already carries label?: I18nLabel | null. So no published type widens, and no Clause-②: yes is owed.
Its row on objectui#12334's pre-release list closes with it. pm:queue is removed in the same act. Reopen it if a surface still shows a draft-only item by its machine name.
Activity
objectstack-fleet commentedon Oct 15, 2026
Triage: first grade ·
bug·priority:p3·domain:ui·target:v18·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-15T04:57ZRead fresh. Studio's package rail shows a draft-only item by its machine name (
packageSurfaces.ts, "draft headers carry no label"). But@objectstack/spec18 servesdrafts[].label, which is required and nullable, for exactly this case.priority:p3: a label shown as a machine name. Under the consumer-follow-up rule nothing breaks for users.target:v18: it is a follow-up of the 18 drafts row, so it is listed on release(v18): objectui's first 18.x release — the syncmajor, Changesets pre mode onnext, and the two gate edits (the maintainer's ruling on #12030), after #12030 lands #12334 as a p3 row.domain:ui. If the reader goes throughlistDrafts(),MetadataDraftHeadergainslabelfrom the spec row, derived as PR feat(data-objectstack): MetadataDraftHeader declares the spec row's member #12420 did formember. That isClause-②: yes, as the seat reads it.objectstack-fleet commentedon Oct 15, 2026
Closed as completed: PR #12419 delivered this card's ask ·
domain:uiseat 1 ·session_01JZnppgHRp4sREcouhkQYDB· 2026-10-15T05:45ZThis card was filed 2026-10-15T03:54Z, from code on an older
main. PR #12419 (objectui#11862's remainder) landed 2026-10-15T04:35Z as7c13d3052and made exactly this change. Read onmain24804dcc6:The comment the card quotes is gone.
packages/app-shell/src/views/studio-design/packageSurfaces.ts:20now reads: "A draft-only item reads as the label its_draftsrow carries".A draft-only entry takes the row's label:
:130–:131resolve it through the spec's ownresolveI18nLabel, and fall back to the machine name only when there is no label.The card's three pins exist in
packageSurfaces.test.ts::160: a draft-only flow takes the label its_draftsrow carries;:179: CONTROL, a row whose label isnullor blank reads as its name;:193: a published row still wins over a same-named draft's label.:168adds the locale-map case, and:204the package-less loader.The
MetadataDraftHeaderbranch does not arise. The rail readslistDraftsthrough its own loader type,:41, which already carrieslabel?: I18nLabel | null. So no published type widens, and noClause-②: yesis owed.Its row on objectui#12334's pre-release list closes with it.
pm:queueis removed in the same act. Reopen it if a surface still shows a draft-only item by its machine name.Generated by Claude Code