Repository navigation
fix(types,components)!: retire grid's flat smColumns / mdColumns / lgColumns / xlColumns; the breakpoint object is the one spelling (objectui#11505) - #11510
Conversation
…mns/xlColumns; the breakpoint object is the one spelling (objectui#11505)
The grid registration offered four flat per-breakpoint column inputs and
seeded two of them; the renderer read them over the breakpoint object, and
no GridSchema face declared them. Triage ruling A: the four inputs and the
renderer's four reads are removed, the registration seeds
columns: { xs: 1, md: 2, lg: 4 }, and both zod faces refuse the four keys
by name (retirementTombstone, naming the breakpoint object member to
write); the TypeScript face carries them as `?: never` tombstones.
The enumeration pin's REGISTERED_NOT_DECLARED ledger empties, and the grid
DOM whitelist canary keeps the four keys as unread, unforwarded keys.
Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC
Co-authored-by: Claude <noreply@anthropic.com>
… unknown-prop (objectui#11505) Built from the live registry the way the containment pin builds it: each retired flat key draws `unknown-prop`, and the breakpoint object, the one spelling, draws nothing. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
… flat column keys as retired (objectui#11505) One changeset for the retirement (minor, breaking meaning stated). Dated, append-only notes on the pending entries whose readings this change made false: objectui#11491's (the four registered inputs), objectui#7097's (the designer's flat channel), and the card's riders on objectui#8516/#8556's CLI output and objectui#11441's `gap` migration line. The grid docs page and the schema reference name the retirement; the surface-parity gate's intersection-spelling comment points at a live example. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Review of PR #11510 for card #11505 (triage ruling A ① Derived judgmentsEach accept-set or public-surface change the diff implies, named right or wrong against ruling A:
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #11505
Clause-②: no (narrowing)
Dev run for objectui#11505 under the
domain:specseat's claim (comment5961122544), sessionhttps://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC. It executes triage's ruling A (comment5960494324): thegridnode's flatsmColumns/mdColumns/lgColumns/xlColumnschannel is retired, and the breakpoint object ofcolumnsis the one spelling. No alias, no dual spelling, no deprecation window.Note on spelling: GitHub strips tag-shaped text from bodies, so the SDUI node tag and placeholders below are written as words (GRID-TAG, N, C).
The accept-set change, key by key
fcdc8ec9, measured)StrictAnyComponentSchema)unrecognized_keysat the node rootinvalid_type, with the RETIRED message namingcolumns: { md: N }(per key's breakpoint)safeValidateSchema, whatobjectui validateruns)BaseSchema.passthrough(), unexamined (mdColumns: 'wide'validated)GridSchemainpackages/types/src/layout.ts)anythrough theBaseSchemaindex signature?: nevertombstone with a RETIRED docblock, sotscrefuses it by namegridregistration inputscolumns,smColumns,mdColumns,lgColumns,xlColumns,gap,className,childrencolumns,gap,className,childrengridregistrationdefaultPropscolumns: 1,mdColumns: 2,lgColumns: 4,gap: 4columns: { xs: 1, md: 2, lg: 4 },gap: 4grid.tsx)validateTreeover the live registry)smColumns: 13drewinvalid-enum(registered input)warning/unknown-prop, "GRID-TAG has no prop" naming the keyWidening: none. Narrowing: the four keys, which the tolerant face accepted at any value.
objectui validate's printer, read through the CLI's ownvalidatecommand on this branch (a one-off probe, not committed):{ "type": "grid", "columns": 4, "mdColumns": 2 }and{ "type": "grid", "mdColumns": "wide" }both exit 1 withPath: mdColumns,Code: invalid_typeand the messageRETIRED (objectui#11505, ADR-0049) — mdColumns on grid was a second spelling of the md member of columns: … Instead: write the count, 1 to 12, as the md member of the breakpoint object, columns: { md: N }, and delete the key. A bare columns: C beside it becomes the object's xs: C; with no columns at all, add xs: 2 to keep the two columns the grid drew below md.The migrated{ "type": "grid", "columns": { "xs": 4, "md": 2 } }exits 0.Zone 2 readings, measured before trusting them
H1, the seed renders identically: confirmed. Through the real
SchemaRenderer, the base registration's seed (columns: 1,mdColumns: 2,lgColumns: 4,gap: 4) drewgrid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4, and the new seedcolumns: { xs: 1, md: 2, lg: 4 }draws the same string. The pin row ("the seeded grid draws the classes the flat seed drew") is green on the base and on this change. The bare1never ramps (the ramp needs a count above 1), so the flat overrides had nothing to interact with here.The migration the refusal prescribes was measured the same way, flat document on the base against the object document on this branch:
columns: 1, mdColumns: 2, lgColumns: 4grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4{ xs: 1, md: 2, lg: 4 }columns: 4, mdColumns: 2grid grid-cols-4 md:grid-cols-2 gap-4(ramp switched off){ xs: 4, md: 2 }smColumns: 3(nocolumns)grid grid-cols-2 sm:grid-cols-3 gap-4{ xs: 2, sm: 3 }columns: { xs: 1, md: 3 }, mdColumns: 2, xlColumns: 6grid grid-cols-1 md:grid-cols-2 xl:grid-cols-6 gap-4{ xs: 1, md: 2, xl: 6 }columns: 2and all four flat keys (1, 2, 3, 4)grid grid-cols-2 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4{ xs: 2, sm: 1, md: 2, lg: 3, xl: 4 }This is why the refusal and the changeset say "a bare
columns: Cbecomesxs: C" and "with nocolumns, addxs: 2": an object withoutxsdraws one base column, while an absentcolumnsdrew two.H2, refusal by name on the tolerant face: done as objectui#11465 did, both faces. Zod: a local
retiredGridColumnsKey(key, breakpoint)over the houseretirementTombstone, messageRETIRED (objectui#11505, ADR-0049) — KEY on grid … Instead: …. TypeScript:?: neverplus a RETIRED docblock. Measured that the TS half is needed: withpackages/types/src/layout.tsreverted to the base,tsc -p tsconfig.test.jsoninpackages/typesreports 10 errors (4Expectrows, 4 unused@ts-expect-errorrows, and 2 inzod-mirror-parity.test.ts, whose drift ledger catches a zod-only declaration), so without the tombstones{ type: 'grid', mdColumns: 2 }compiles.H3, producers: the registration was the only one, re-measured. Census of
\b(sm|md|lg|xl)Columns\bover every tracked file, plus the lowercase attribute spellings:schema.KEYinpackages/*/src)grid.tsxgrid.tsxDEFAULT_PALETTE, and no designer, shell or console code reads a registration'sinputsordefaultProps(ComponentRegistry.getConfig/getMetainplugin-designer,app-shell,apps/console: zero hits)examples/schema-catalogdocumentscontent/docs,skills/, READMEs,apps/site)grid.mdx,schema-reference.md)grid-dom-attribute-whitelist.test.tsx(canary),layout-spacing-sets-11474.test.tsx(ledger), one prose line in the catalog'sgrid-columns-key.test.tsxcheck-component-surface-parity.mjssdui.manifest.json, the recorded console manifest (see Acceptance notes)No corpus document authored a flat key, so none needed fixing.
Fixtures and documents re-judged
grid-dom-attribute-whitelist.test.tsx(objectui#4787): the canary keeps its four flat keys, re-labelled as retired keys a document that skipped validation still carries; they must still not reach the DOM. Case 1b no longer clears them (they no longer override the object). Case 2's positive control now expectsmd:grid-cols-4(the bare count's ramp) and notmd:grid-cols-2: the flatmdColumns: 2is read by nothing.layout-spacing-sets-11474.test.tsx:REGISTERED_NOT_DECLAREDis empty, and its two-way population row now holds it empty; the fourgrid.*Columnspositions leave the enumeration because the inputs are gone.examples/schema-catalog/test/grid-columns-key.test.tsx: its docblock said the registration exposes the five column inputs; it now sayscolumnsalone.content/docs/components/layout/grid.mdx,content/docs/api/schema-reference.md: one sentence each naming the retirement and the object form.scripts/check-component-surface-parity.mjs: the comment that illustrated the intersection-typedschemaparameter with the grid's flat-key intersection now citesUIActionSchema & { actionType?: string }(action-button.tsx), a live one. Comment only; the script's own suite ran (below).Pins
packages/types/src/__tests__/grid-flat-columns-retired-11505.test.ts: type level, each key readsundefinedon both faces and a@ts-expect-errorper key; runtime, every former value refused at the key's own path on the strict face, the tolerant face and the mirror; the message is the RETIRED one withInstead:andcolumns: { BP: N }; the migrated documents parse on both faces; lit controls (the node without the keys parses everywhere, an undeclared key stays green on the tolerant face and isunrecognized_keyson the strict one).packages/components/src/__tests__/grid-flat-columns-retired-11505.test.tsx: the registration's only column input iscolumns; the seed is the breakpoint object with no flat key; the seeded grid drawsgrid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4; each flat key is read by nothing (five shapes); each prescribed object draws what its flat form drew on the base; the SDUI manifest answers each key withunknown-prop, and the object form with nothing; a flat key no longer switches the ramp off.Reverse verification (committed fix, base restored, then HEAD restored)
From the committed head
4d08cf87,grid.tsx,zod/layout.zod.tsandlayout.tswere checked out from the basefcdc8ec9(on-disk check:retiredGridColumnsKey0 hits, theif (schema.mdColumns)read 1 hit,mdColumns?: never0 hits) and the four pin files run. Vitest resolves@object-ui/*tosrcthrough the root config's aliases, so no rebuild was involved. Result:Tests 27 failed | 26 passed (53), exit 1. Red: every flat-key row in both new pins (registration, seed shape, read-by-nothing, the manifest rows, the ramp row, the zod refusals), the enumeration ledger row plus the fourgrid.*Columnspositions, and whitelist cases 1b and 2. Green on the base, as intended: the seeded-classes row, every migrated-object row, the manifest's object-form control and the lit controls. Restore:git checkout HEAD --on the three paths, proved by blob hashes equal to HEAD's and an emptygit diff HEAD, under an EXIT/INT/TERM trap.Pending changesets swept (read as text against what this diff moves)
Each gets a dated, append-only note in the house form:
.changeset/11491-grid-columns-set.md: its components bullet named the four inputs andvalidateTreeansweringsmColumns: 13withinvalid-enum..changeset/7097-grid-2xl-breakpoint.md: "the designer's flatsmColumns…xlColumnschannel are unchanged"..changeset/8516-8556-mirror-partial-record-narrowing.md(the card's rider): it says the CLI reports{ xxl: 6 }asPath: columns → xxl,Code: invalid_key. Measured through the CLI's printer on this branch, it reportsUnrecognized key: "xxl",Path: columns,Code: unrecognized_keys, a top-level issue. The note attributes the change to objectui#11073's zod 4.6 resolution, as the rider does; this run measured the present answer, not the transition..changeset/11441-known-types-retired-layout-keys.md(the optional rider): its migration line namesgapwith no objectui#11474 note; the note mirrors its sibling's. EveryResponsiveGridgap step (0 to 6 and 8, read offGAP_CLASSES) is one ofgrid's ten.Left alone, each still true as written:
grid-dom-attribute-whitelist-4787.md: itsmdcolumns/smcolumnsare a leak measurement taken at that change.8505-grid-columns-breakpoint-narrowing.md: it is about the six keys of thecolumnsobject.11441-retire-nav-responsive-grid-layout.md: it already carries the objectui#11474 and objectui#11491 notes, and thecolumnsobject it names is unchanged.11474-layout-spacing-sets.md:gaponly.7735-zod-mirrors-stop-authoring-defaults.md: thegrid.columnsdefault row is stilllet baseCols = 2.3965-mint-box-neutral-container.md,9910-children-slot-declare-and-pin.md,6740-flex-is-container.md,layout-renderers-dom-props-5574.md,dom-leak-sweep-components-5574.md: grid containment, DOM whitelist and the object spelling, which are unaffected.New entry:
.changeset/11505-grid-flat-columns-retired.md,minorfor@object-ui/typesand@object-ui/components, with the breaking meaning and the migration stated.Gates, all at
4d08cf87pnpm --filter '@object-ui/components^...' build(closure, includestypes)pnpm --filter @object-ui/types run type-check(three legs; new pin confirmed in the test program with--listFilesOnly)pnpm --filter @object-ui/components run type-check(both new or edited pins confirmed in the program)pnpm --filter @object-ui/example-schema-catalog run type-checkpnpm exec vitest run packages/types/pnpm exec vitest run packages/components/skipIf), 3612 tests passed, 24 skippedexamples/schema-catalog/,packages/cli/,packages/sdui-parser/,scripts/__tests__/check-component-surface-parity.test.ts,check-doc-component-types.test.ts,check-doc-snippet-types.test.ts, coreschema-validator.test.ts, reactSchemaRenderer.dataPropArm-9571.test.tsx, consoleregistry-inputs-spec-parity.test.tspnpm check:doc-snippets(closure built with its own--build-filter)pnpm check:doc-examplespnpm check:doc-types,pnpm check:doc-fencespnpm check:component-surface-parity(report-only)ui:gridreads, interface and inputs now agree:columns,gap,children(plusstyle/className)node scripts/check-changeset-no-major.mjs,check-changeset-presence.mjs,check-changeset-fixed.mjspnpm check:changeset-claims,pnpm check:pending-changeset-literalspnpm check:new-line-citations,pnpm check:control-bytes--no-inline-config --format json)no-explicit-anyon the renderer's props type, present at the same line on the base)pnpm check:sdui-registration-pinssideEffectsarray keeps at bundle time; this diff moves no array and no key, onlygrid's inputs and seed. Left to CI.The eslint narrowing: the population is the 9 touched
.ts/.tsx/.mjsfiles (eslint's own JSON output counts 9); the rooteslint.config.jsis the only config and enables no type-aware linting (projectService/parserOptions.projectabsent), so this diff cannot move any untouched file's verdict. The repo-wide lint is CI's.Deviations
SHASUMS256.txt) went onPATHfrom this run's scratch directory. Nothing system-wide.Acceptance notes
sdui.manifest.json(the recorded console manifest the CLI and lint validate against) still listssmColumns…xlColumnsongrid, astype: number, so it predates objectui#11491's enums too. It is re-recorded when objectstack bumps its objectui console pin; that bump carries this change there. Carrier: the next objectstack console-pin bump.grid.tsx's whitelist comment and whitelist case 3 quote themdcolumns/smcolumnsattributes as measured under objectui#4787. Those are historical readings, not claims about today.Generated by Claude Code