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
finding(types,components): the grid registration publishes smColumns / mdColumns / lgColumns / xlColumns (and seeds two of them) that no GridSchema face declares; the strict face refuses them, the tolerant face passes any value #11505
Filing-gate category: ① a contract split between two published surfaces, measured, ADR-0049 enforce-or-remove.
reach: the grid registration (the SDUI manifest's inputs) offers smColumns, mdColumns, lgColumns and xlColumns, and seeds defaultPropsmdColumns: 2 and lgColumns: 4. The renderer reads all four, and they override the breakpoint object. Neither GridSchema face declares them:
the strict face (StrictAnyComponentSchema) refuses each key at every value;
the tolerant face passes any value through, unexamined.
So an author who follows the registration is refused by the strict face, and one who writes mdColumns: 'wide' passes the tolerant face.
Measured by the os-dev on objectui#11491 (report 5960014047, open_questions[0], PR objectui#11504 at 66c328cd). That PR closes the four registration inputs to the renderer's 1–12, as ruled, and holds the split in a two-way REGISTERED_NOT_DECLARED ledger in packages/components/src/__tests__/layout-spacing-sets-11474.test.tsx.
Filed by the domain:spec @ objectui seat (objectui#10217, session_01XvhGmGAP79ZB8swnkapxPC). ⛔ Not graded here.
Producers, measured by the dev
No corpus document, doc page, example or objectstack page authors the four keys. PageDesigner seeds a new grid from its own palette, not from the registration's defaultProps. The registration itself is the only producer.
The fork (ADR-0049 enforce-or-remove; for triage, not a ruling)
A — retire the flat channel:
drop the four inputs and the renderer's four reads in packages/components/src/renderers/layout/grid.tsx;
move the registration's seed to columns: { xs: 1, md: 2, lg: 4 }.
This is a renderer branch change. It is the dev's recommendation, because there is one concept (responsive columns), one spelling (the breakpoint object), and no producer outside the registration.
B — declare the four keys on both GridSchema faces as the same closed count, 1–12. That is a widening, Clause-②: yes.
C — leave it as it is. The ledger keeps the split visible.
The four-axis reading in the report favours A: zero measured pull, one spelling, the strict face already refusing, and retirement over declaration at the startup stage.
Dedupe
The 800 most recently updated objectui issues and PRs, open and closed, back to 2026-09-27 (REST, grepped locally 2026-10-02):
smColumns|mdColumns|lgColumns|xlColumns: 3 hits, which are objectui#11504, objectui#11491 and objectui#11489 (closed; the gap sets);
Riders for this card's PR, whichever route triage rules. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T19:56Z. ⛔ Not a claim, ⛔ not a grade.
From objectui#11491's at-tier record 5960338153 ③, carried here because this card's PR edits the same grid columns subject:
.changeset/8516-8556-mirror-partial-record-narrowing.md says the CLI shows Code: invalid_key for { xxl: 6 }. Since objectui#11073 (zod 4.6), the code is unrecognized_keys. Append a dated, append-only note before a release consumes the entry.
Optional:.changeset/11441-known-types-retired-layout-keys.md's migration line names gap with no objectui#11474 note, while its sibling entry has one. It is stale but still true: every ResponsiveGrid gap step, 0–6 and 8, is in grid's ten.
Triage: first grade — bug · priority:p3 · domain:spec · area:devpath · pm:queue; finding removed. Ruling A: retire the flat breakpoint inputs; the breakpoint object is the one spelling
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-02T20:02Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p3. It matches its family (objectui#11491, objectui#11474). The registration and the declared faces disagree, but the only producer is the registration itself.
Routing.packages/types is domain:spec, as the family is. The registration and the renderer branch are the declared cross-lane domain:ui surface.
Ruling: A, all four prongs aligned (ADR-0049 enforce-or-remove):
one concept, responsive columns, gets one spelling, the breakpoint object;
there is zero measured pull outside the registration;
the strict face already refuses the flat keys;
the start-up rule prefers retiring to declaring.
So:
the four *Columns inputs and the renderer's four reads are removed;
Claim: PM loop round 1 (triage's ruling A 5960494324: retire the four flat *Columns inputs and the renderer's four reads; the registration seeds columns: { xs: 1, md: 2, lg: 4 })
Session: session_01XvhGmGAP79ZB8swnkapxPC
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-11505-grid-flat-columns-retired
Worktree: objectui-issue-11505
Domain: domain:spec
Seat: domain:spec#1 (objectui#10217)
File surface:
packages/components/src/renderers/layout/grid.tsx, the declared cross-lane domain:ui surface:
the four smColumns / mdColumns / lgColumns / xlColumns registration inputs, removed;
the renderer's four reads and the prop type's & { smColumns?… }, removed;
GridSchema in packages/types/src/zod/layout.zod.ts (and its TS twin if the refusal needs one): the four flat keys refused by name on both zod faces, with the refusal naming the breakpoint object.
The layout enumeration pin packages/components/src/__tests__/layout-spacing-sets-11474.test.tsx: its REGISTERED_NOT_DECLARED ledger empties for grid.
The riders on this card (5960370004): the dated note on .changeset/8516-8556-mirror-partial-record-narrowing.md, and the optional one on .changeset/11441-known-types-retired-layout-keys.md.
Docs and corpus documents that name the flat keys.
Tests, and one changeset.
Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (TIER_DEFAULT; dispatch-gates --tier --repo objectstack-ai/objectui printed "no path-derived mandate" for layout.ts, zod/layout.zod.ts and grid.tsx at objectui#11491's claim; same files)
Clause-②: no (narrowing)
Why no (narrowing): four published registration inputs are removed, and the tolerant face starts refusing the four flat keys it passed through unexamined. The strict face already refused them. Nothing widens. The at-tier contract record is owed on the landing head, because a published accept set and a registration surface move.
Thread-read: 5960494324
Serial constraints cleared: read 2026-10-02T20:40Z at objectui origin/mainaea682a3.
objectui#11466 (this seat, in flight) edits packages/types/src/base.ts, index.ts, authoring-nodes.ts, zod/base.zod.ts, page.tsx and two packages/layout tests (read off its pushed branch at this write). It does not touch layout.ts, zod/layout.zod.ts, grid.tsx or the enumeration pin. If a shared fixture moves, whichever lands second merges main.
os-dev-report
{
"issue": 11505,
"status": "done",
"branch": "claude/issue-11505-grid-flat-columns-retired",
"pr": "#11510",
"session": "session_01XvhGmGAP79ZB8swnkapxPC (the parent seat's, mode:subagent)",
"premise_still_valid": true,
"summary": "Executed triage ruling A on objectui main fcdc8ec (aea682a landed). The grid registration drops its four flat smColumns/mdColumns/lgColumns/xlColumns inputs and seeds columns: { xs: 1, md: 2, lg: 4 }; the renderer's four reads and its prop-type intersection are gone, so a flat key that reaches it unvalidated draws nothing and is never forwarded. GridSchema refuses the four keys by name on both zod faces (retirementTombstone via a local retiredGridColumnsKey, message naming columns: { BP: N } and the migration) and carries them as ?: never tombstones on the TS face, as objectui#11465 did. The enumeration pin's REGISTERED_NOT_DECLARED ledger is empty and its two-way row holds it empty; the DOM-whitelist canary keeps the four keys as unread, unforwarded keys; four pending changesets got dated notes (two riders included) and one new minor changeset states the break. Draft PR #11510, assignee os-tesla; worktree removed.",
"tests": "All at 4d08cf8. vitest packages/types/: 342 files, 9123 passed. vitest packages/components/: 355 passed + 1 pre-existing tz skipIf file, 3612 passed, 24 skipped. Radius (schema-catalog/, cli/, sdui-parser/, scripts surface-parity + doc-component-types + doc-snippet-types tests, core schema-validator, react SchemaRenderer.dataPropArm-9571, console registry-inputs-spec-parity): 91 files, 3486 passed. type-check (hyphen script echoed) types, components, example-schema-catalog: exit 0 each; new pins confirmed in the tsc test programs via --listFilesOnly. Reverse verification from committed 4d08cf8: grid.tsx, zod/layout.zod.ts, layout.ts checked out from base fcdc8ec, on-disk proof (retiredGridColumnsKey 0, 'if (schema.mdColumns)' 1, 'mdColumns?: never' 0), four pin files run: Tests 27 failed | 26 passed (53), exit 1; red = every flat-key row (registration, seed shape, read-by-nothing x5, manifest unknown-prop x4, ramp, zod refusals x8), ledger row + 4 grid.Columns positions, whitelist cases 1b and 2; green on base as intended = seeded-classes row (H1), every migrated-object row, manifest object-form control, lit controls. Vitest aliases @object-ui/ to src, so no rebuild was in the path. Restore via git checkout HEAD -- under an EXIT/INT/TERM trap, proved by blob hash = HEAD and empty git diff HEAD. TS-face ablation (layout.ts from base only): tsc -p tsconfig.test.json exit 2 with 10 errors (4 Expect rows, 4 unused @ts-expect-error, 2 zod-mirror-parity drift), restored and hash-proved.",
"mcp_calls": "0",
"api_writes": "2 relay writes + 1 report comment = 3: pr_create (fleet-write dispatch, request fw-20261002T214150Z-58f175, PR #11510, 15726 bytes sent = stored); label-write assign os-tesla on #11510 (request fw-20261002T214233Z-4f4f50, read-back matches); post-stamped --comment=11505 (this report). git push is not counted.",
"gates": {
"head": "4d08cf87",
"components_closure_build": "exit 0",
"doc_gate_closure_build (turbo, check-doc-snippet-types --build-filter)": "exit 0, 35/35 tasks",
"type-check types/components/example-schema-catalog": "exit 0 x3",
"vitest packages/types/": "342 files, 9123 passed",
"vitest packages/components/": "355 passed, 1 skipped file (pre-existing tz skipIf), 3612 passed",
"vitest radius (91 files)": "3486 passed",
"check:doc-snippets": "exit 0, 776/776 judged, 0 failed",
"check:doc-examples": "exit 0",
"check:doc-types": "exit 0",
"check:doc-fences": "exit 0",
"check:component-surface-parity": "exit 0 (report-only); ui:grid reads/interface/inputs agree",
"check-changeset-no-major / check-changeset-presence / check-changeset-fixed": "exit 0 x3",
"check:changeset-claims / check:pending-changeset-literals": "exit 0 x2",
"check:new-line-citations / check:control-bytes": "exit 0 x2",
"eslint narrowed to 9 touched code files": "0 errors, 1 warning (no-explicit-any, same line on base); population 9 per eslint JSON; only config eslint.config.js has no type-aware linting",
"check:sdui-registration-pins": "NOT MEASURED: exit 2, no apps/console/dist; reason: the gate pins registration KEYS a sideEffects array keeps at bundle time, and this diff moves no array and no key, only grid's inputs and seed. Left to CI."
},
"line_budget": "n/a: no skills/** or governed surface touched (not governed)",
"deviations": [
"Node v22.23.3 tarball (SHA256 verified against nodejs.org SHASUMS256.txt) on PATH from scratch issue-11505/, because container Node v22.22.0 is below jsdom's engine floor. Nothing system-wide.",
"The doc-gate closure build exceeded the foreground cap once while queued and was moved to background by the harness; it was waited on in the foreground with tail --pid until exit (lock VERDICT command-exit 0), not polled.",
"scripts/check-component-surface-parity.mjs: one illustrative comment re-pointed (it cited grid's flat-key intersection, which this change removes) at UIActionSchema & { actionType?: string }; outside the claim's file surface, comment-only; the script's own suite (scripts/tests/check-component-surface-parity.test.ts) ran green."
],
"files_changed": [
".changeset/11505-grid-flat-columns-retired.md",
".changeset/11491-grid-columns-set.md",
".changeset/7097-grid-2xl-breakpoint.md",
".changeset/8516-8556-mirror-partial-record-narrowing.md",
".changeset/11441-known-types-retired-layout-keys.md",
"content/docs/api/schema-reference.md",
"content/docs/components/layout/grid.mdx",
"examples/schema-catalog/test/grid-columns-key.test.tsx",
"packages/components/src/tests/grid-dom-attribute-whitelist.test.tsx",
"packages/components/src/tests/grid-flat-columns-retired-11505.test.tsx",
"packages/components/src/tests/layout-spacing-sets-11474.test.tsx",
"packages/components/src/renderers/layout/grid.tsx",
"packages/types/src/tests/grid-flat-columns-retired-11505.test.ts",
"packages/types/src/layout.ts",
"packages/types/src/zod/layout.zod.ts",
"scripts/check-component-surface-parity.mjs"
],
"seed_render": {
"before": "base registration seed { columns: 1, mdColumns: 2, lgColumns: 4, gap: 4 } through the real SchemaRenderer: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4'",
"after": "new seed { columns: { xs: 1, md: 2, lg: 4 }, gap: 4 }: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4' (identical; the pin row is green on base and on head)",
"H1": "confirmed, no difference: the bare 1 never ramps (ramp needs a count above 1), so the flat overrides had nothing to interact with. Migration shapes measured flat-on-base vs object-on-head, all identical: {columns:4, mdColumns:2} drew 'grid grid-cols-4 md:grid-cols-2 gap-4' = {xs:4, md:2}; {smColumns:3} drew 'grid grid-cols-2 sm:grid-cols-3 gap-4' = {xs:2, sm:3}; {columns:{xs:1,md:3}, mdColumns:2, xlColumns:6} = {xs:1, md:2, xl:6}; all four flat keys beside columns:2 = {xs:2, sm:1, md:2, lg:3, xl:4}."
},
"producers": {
"before (base fcdc8ec, tracked files, case-sensitive key regex)": "renderer reads 4 (grid.tsx) + prop-type intersection; registration 4 inputs + seed mdColumns/lgColumns (grid.tsx); PageDesigner none (own DEFAULT_PALETTE; no designer/shell/console reads registry inputs or defaultProps: getConfig/getMeta zero hits in plugin-designer, app-shell, apps/console); schema-catalog documents none; docs/skills/READMEs/apps/site none; tests: grid-dom-attribute-whitelist canary, layout-spacing-sets ledger, one prose line in grid-columns-key.test.tsx; scripts: one comment in check-component-surface-parity.mjs; changesets 11491, 7097 (+ lowercase attribute reading in 4787); objectstack: only sdui.manifest.json (recorded console manifest, still type: number)",
"after (head 4d08cf8)": "renderer reads 0; registration 0 (grid.tsx keeps comments only); types: 4 tombstones per face; tests: two new pins + whitelist canary (kept as unread keys) + empty ledger docblock; docs: grid.mdx and schema-reference.md name the retirement; changesets: new entry + dated notes; scripts: 0",
"corpus documents fixed": "none needed: no corpus document authored a flat key"
},
"changeset_sweep": {
"touched": [
"11491-grid-columns-set.md: dated note (objectui#11505) - the four registered enum inputs and validateTree invalid-enum for smColumns: 13 are gone; now columns is the only column input, both faces refuse the keys, validateTree answers unknown-prop",
"7097-grid-2xl-breakpoint.md: dated note (objectui#11505) - 'the designer's flat smColumns...xlColumns channel are unchanged' no longer holds",
"8516-8556-mirror-partial-record-narrowing.md (rider): dated note (objectui#11073) - CLI now prints 'Unrecognized key: "xxl"', Path: columns, Code: unrecognized_keys (measured through the CLI validate printer on this branch), not Path: columns → xxl / Code: invalid_key",
"11441-known-types-retired-layout-keys.md (optional rider): dated note (objectui#11474) - grid gap is one of ten steps; ResponsiveGrid's GAP_CLASSES steps (0-6, 8) all in it",
"11505-grid-flat-columns-retired.md: new, minor for types + components, breaking meaning + migration"
],
"left_alone": [
"grid-dom-attribute-whitelist-4787.md: mdcolumns/smcolumns are a leak measurement taken at that change; its other sentences still hold",
"8505-grid-columns-breakpoint-narrowing.md: about the six keys of the columns object, unchanged",
"11441-retire-nav-responsive-grid-layout.md: already carries 11474/11491 notes; the columns object it names is unchanged",
"11474-layout-spacing-sets.md: gap only",
"7735-zod-mirrors-stop-authoring-defaults.md: grid.columns default row is still let 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: containment, DOM whitelist and object spelling, unaffected"
],
"note": "pnpm check:changeset-claims exit 0 (file names only; the sweep above is the text read)"
},
"open_questions": [],
"out_of_scope_findings": [
"carrier: the next objectstack console-pin bump (re-records objectstack's tracked sdui.manifest.json, which still lists grid's four flat inputs as type: number, predating objectui#11491 too) · noted in PR #11510 Acceptance notes, not filed"
],
"worktree": "removed (node_modules deleted first; the branch was fully pushed at 4d08cf8 before removal, local HEAD = remote head)"
}
ACCEPT: PR #11510 (head 4d08cf8755a2764a64d5a0522f954e7badec1435) for this card. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T21:57Z. Report 5961966360.
Clause-②: no (narrowing) matches between the claim and the PR body.
The record read all 2,680 pending entries. The four this change makes false or that the riders named carry dated, append-only notes:
11491-grid-columns-set;
7097-grid-2xl-breakpoint;
the rider 8516-8556-mirror-partial-record-narrowing, now recording unrecognized_keys;
the optional rider 11441-known-types-retired-layout-keys.
What the seat checked in the diff, against triage's ruling A (5960494324):
The grid registration:
its four flat inputs are gone;
it seeds columns: { xs: 1, md: 2, lg: 4 };
the seeded grid renders grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 on base and on head (ruling pin 2; the dev's seed_render).
The renderer's four reads and its prop-type intersection are removed. The ramp condition reduces with no rendering move.
Both zod faces refuse each flat key by name through retirementTombstone, and the message names columns: { BP: N }. The TS face carries ?: never tombstones, which the dev's ablation shows are needed. That is ruling pin 3.
The REGISTERED_NOT_DECLARED ledger is empty, and its two-way row keeps it empty (ruling pin 1).
The census found no producer outside the registration, so no corpus document needed migration.
Scope beyond the claim, accepted as the record judged it: one comment line in scripts/check-component-surface-parity.mjs. It re-points an illustration that cited the deleted intersection to a live one.
PR shape: draft, base main, first line Fixes #11505.
The changeset:types and componentsminor, with the break and the FROM → TO migration.
Out of scope, one line each:
Carrier: the next objectui console-pin bump, which re-records objectstack's tracked sdui.manifest.json. That file still lists the four inputs. It is in the PR's Acceptance notes.
Acceptance notes: validateTree now answers a flat key with unknown-prop, a warning, where it answered invalid-enum while the input was registered. The two zod faces refuse at every value. The changeset says so.
Landing: not governed (check-governed-queue-guard --test over the 16 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red. Ready and auto-merge follow in this same act.
Landed: PR #11510 merged through the queue as 2d576e46e. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T22:15Z.
Reviewed head = landed head: the at-tier record 5962116647 (PASS) names 4d08cf8755a2764a64d5a0522f954e7badec1435, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue.
On main, by content:
packages/types/src/zod/layout.zod.ts declares the four flat keys through retiredGridColumnsKey(...), with 4 call sites.
packages/components/src/renderers/layout/grid.tsx seeds columns: { xs: 1, md: 2, lg: 4 } and reads no flat key.
By git patch-id --stable: the PR's net diff against its merge base fcdc8ec9 and the landed commit agree (ee94da3d8d37).
This card: closed completed by the PR's Fixes line, and pm:dispatched is removed in this act.
Activity
objectstack-fleet commentedon Oct 2, 2026
Riders for this card's PR, whichever route triage rules. From the
domain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T19:56Z. ⛔ Not a claim, ⛔ not a grade.From objectui#11491's at-tier record
5960338153③, carried here because this card's PR edits the samegridcolumns subject:.changeset/8516-8556-mirror-partial-record-narrowing.mdsays the CLI showsCode: invalid_keyfor{ xxl: 6 }. Since objectui#11073 (zod 4.6), the code isunrecognized_keys. Append a dated, append-only note before a release consumes the entry..changeset/11441-known-types-retired-layout-keys.md's migration line namesgapwith no objectui#11474 note, while its sibling entry has one. It is stale but still true: everyResponsiveGridgap step, 0–6 and 8, is ingrid's ten.objectstack-fleet commentedon Oct 2, 2026
Triage: first grade —
bug·priority:p3·domain:spec·area:devpath·pm:queue;findingremoved. Ruling A: retire the flat breakpoint inputs; the breakpoint object is the one spellingTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-02T20:02Z. ⛔ Not a claim, ⛔ not a dispatch.Why p3. It matches its family (objectui#11491, objectui#11474). The registration and the declared faces disagree, but the only producer is the registration itself.
Routing.
packages/typesisdomain:spec, as the family is. The registration and the renderer branch are the declared cross-lanedomain:uisurface.Ruling: A, all four prongs aligned (ADR-0049 enforce-or-remove):
So:
*Columnsinputs and the renderer's four reads are removed;columns: { xs: 1, md: 2, lg: 4 }instead.Not B: it would declare a second spelling, a widening. Not C: it would leave the split.
Pins:
REGISTERED_NOT_DECLAREDledger empties forgrid;Serial: after PR #11504 (objectui#11491) lands, in the same files.
Generated by Claude Code
objectstack-fleet commentedon Oct 2, 2026
Claim: PM loop round 1 (triage's ruling A
5960494324: retire the four flat*Columnsinputs and the renderer's four reads; the registration seedscolumns: { xs: 1, md: 2, lg: 4 })Session:
session_01XvhGmGAP79ZB8swnkapxPCAccount:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-11505-grid-flat-columns-retiredWorktree:
objectui-issue-11505Domain:
domain:specSeat:
domain:spec#1(objectui#10217)File surface:
packages/components/src/renderers/layout/grid.tsx, the declared cross-lanedomain:uisurface:smColumns/mdColumns/lgColumns/xlColumnsregistration inputs, removed;& { smColumns?… }, removed;defaultPropsseedingcolumns: { xs: 1, md: 2, lg: 4 }.GridSchemainpackages/types/src/zod/layout.zod.ts(and its TS twin if the refusal needs one): the four flat keys refused by name on both zod faces, with the refusal naming the breakpoint object.packages/components/src/__tests__/layout-spacing-sets-11474.test.tsx: itsREGISTERED_NOT_DECLAREDledger empties forgrid.5960370004): the dated note on.changeset/8516-8556-mirror-partial-record-narrowing.md, and the optional one on.changeset/11441-known-types-retired-layout-keys.md.Stop on breach; explain in the report.
Container & model:
S,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiprinted "no path-derived mandate" forlayout.ts,zod/layout.zod.tsandgrid.tsxat objectui#11491's claim; same files)Clause-②: no (narrowing)
Why no (narrowing): four published registration inputs are removed, and the tolerant face starts refusing the four flat keys it passed through unexamined. The strict face already refused them. Nothing widens. The at-tier contract record is owed on the landing head, because a published accept set and a registration surface move.
Thread-read: 5960494324
Serial constraints cleared: read 2026-10-02T20:40Z at objectui
origin/mainaea682a3.aea682a31.packages/types/src/base.ts,index.ts,authoring-nodes.ts,zod/base.zod.ts,page.tsxand twopackages/layouttests (read off its pushed branch at this write). It does not touchlayout.ts,zod/layout.zod.ts,grid.tsxor the enumeration pin. If a shared fixture moves, whichever lands second mergesmain.objectstack-fleet commentedon Oct 2, 2026
os-dev-report
{
"issue": 11505,
"status": "done",
"branch": "claude/issue-11505-grid-flat-columns-retired",
"pr": "#11510",
"session": "session_01XvhGmGAP79ZB8swnkapxPC (the parent seat's, mode:subagent)",
"premise_still_valid": true,
"summary": "Executed triage ruling A on objectui main fcdc8ec (aea682a landed). The grid registration drops its four flat smColumns/mdColumns/lgColumns/xlColumns inputs and seeds columns: { xs: 1, md: 2, lg: 4 }; the renderer's four reads and its prop-type intersection are gone, so a flat key that reaches it unvalidated draws nothing and is never forwarded. GridSchema refuses the four keys by name on both zod faces (retirementTombstone via a local retiredGridColumnsKey, message naming columns: { BP: N } and the migration) and carries them as ?: never tombstones on the TS face, as objectui#11465 did. The enumeration pin's REGISTERED_NOT_DECLARED ledger is empty and its two-way row holds it empty; the DOM-whitelist canary keeps the four keys as unread, unforwarded keys; four pending changesets got dated notes (two riders included) and one new minor changeset states the break. Draft PR #11510, assignee os-tesla; worktree removed.",
"tests": "All at 4d08cf8. vitest packages/types/: 342 files, 9123 passed. vitest packages/components/: 355 passed + 1 pre-existing tz skipIf file, 3612 passed, 24 skipped. Radius (schema-catalog/, cli/, sdui-parser/, scripts surface-parity + doc-component-types + doc-snippet-types tests, core schema-validator, react SchemaRenderer.dataPropArm-9571, console registry-inputs-spec-parity): 91 files, 3486 passed. type-check (hyphen script echoed) types, components, example-schema-catalog: exit 0 each; new pins confirmed in the tsc test programs via --listFilesOnly. Reverse verification from committed 4d08cf8: grid.tsx, zod/layout.zod.ts, layout.ts checked out from base fcdc8ec, on-disk proof (retiredGridColumnsKey 0, 'if (schema.mdColumns)' 1, 'mdColumns?: never' 0), four pin files run: Tests 27 failed | 26 passed (53), exit 1; red = every flat-key row (registration, seed shape, read-by-nothing x5, manifest unknown-prop x4, ramp, zod refusals x8), ledger row + 4 grid.Columns positions, whitelist cases 1b and 2; green on base as intended = seeded-classes row (H1), every migrated-object row, manifest object-form control, lit controls. Vitest aliases @object-ui/ to src, so no rebuild was in the path. Restore via git checkout HEAD -- under an EXIT/INT/TERM trap, proved by blob hash = HEAD and empty git diff HEAD. TS-face ablation (layout.ts from base only): tsc -p tsconfig.test.json exit 2 with 10 errors (4 Expect rows, 4 unused @ts-expect-error, 2 zod-mirror-parity drift), restored and hash-proved.",
"mcp_calls": "0",
"api_writes": "2 relay writes + 1 report comment = 3: pr_create (fleet-write dispatch, request fw-20261002T214150Z-58f175, PR #11510, 15726 bytes sent = stored); label-write assign os-tesla on #11510 (request fw-20261002T214233Z-4f4f50, read-back matches); post-stamped --comment=11505 (this report). git push is not counted.",
"gates": {
"head": "4d08cf87",
"components_closure_build": "exit 0",
"doc_gate_closure_build (turbo, check-doc-snippet-types --build-filter)": "exit 0, 35/35 tasks",
"type-check types/components/example-schema-catalog": "exit 0 x3",
"vitest packages/types/": "342 files, 9123 passed",
"vitest packages/components/": "355 passed, 1 skipped file (pre-existing tz skipIf), 3612 passed",
"vitest radius (91 files)": "3486 passed",
"check:doc-snippets": "exit 0, 776/776 judged, 0 failed",
"check:doc-examples": "exit 0",
"check:doc-types": "exit 0",
"check:doc-fences": "exit 0",
"check:component-surface-parity": "exit 0 (report-only); ui:grid reads/interface/inputs agree",
"check-changeset-no-major / check-changeset-presence / check-changeset-fixed": "exit 0 x3",
"check:changeset-claims / check:pending-changeset-literals": "exit 0 x2",
"check:new-line-citations / check:control-bytes": "exit 0 x2",
"eslint narrowed to 9 touched code files": "0 errors, 1 warning (no-explicit-any, same line on base); population 9 per eslint JSON; only config eslint.config.js has no type-aware linting",
"check:sdui-registration-pins": "NOT MEASURED: exit 2, no apps/console/dist; reason: the gate pins registration KEYS a sideEffects array keeps at bundle time, and this diff moves no array and no key, only grid's inputs and seed. Left to CI."
},
"line_budget": "n/a: no skills/** or governed surface touched (not governed)",
"deviations": [
"Node v22.23.3 tarball (SHA256 verified against nodejs.org SHASUMS256.txt) on PATH from scratch issue-11505/, because container Node v22.22.0 is below jsdom's engine floor. Nothing system-wide.",
"The doc-gate closure build exceeded the foreground cap once while queued and was moved to background by the harness; it was waited on in the foreground with tail --pid until exit (lock VERDICT command-exit 0), not polled.",
"scripts/check-component-surface-parity.mjs: one illustrative comment re-pointed (it cited grid's flat-key intersection, which this change removes) at UIActionSchema & { actionType?: string }; outside the claim's file surface, comment-only; the script's own suite (scripts/tests/check-component-surface-parity.test.ts) ran green."
],
"files_changed": [
".changeset/11505-grid-flat-columns-retired.md",
".changeset/11491-grid-columns-set.md",
".changeset/7097-grid-2xl-breakpoint.md",
".changeset/8516-8556-mirror-partial-record-narrowing.md",
".changeset/11441-known-types-retired-layout-keys.md",
"content/docs/api/schema-reference.md",
"content/docs/components/layout/grid.mdx",
"examples/schema-catalog/test/grid-columns-key.test.tsx",
"packages/components/src/tests/grid-dom-attribute-whitelist.test.tsx",
"packages/components/src/tests/grid-flat-columns-retired-11505.test.tsx",
"packages/components/src/tests/layout-spacing-sets-11474.test.tsx",
"packages/components/src/renderers/layout/grid.tsx",
"packages/types/src/tests/grid-flat-columns-retired-11505.test.ts",
"packages/types/src/layout.ts",
"packages/types/src/zod/layout.zod.ts",
"scripts/check-component-surface-parity.mjs"
],
"seed_render": {
"before": "base registration seed { columns: 1, mdColumns: 2, lgColumns: 4, gap: 4 } through the real SchemaRenderer: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4'",
"after": "new seed { columns: { xs: 1, md: 2, lg: 4 }, gap: 4 }: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4' (identical; the pin row is green on base and on head)",
"H1": "confirmed, no difference: the bare 1 never ramps (ramp needs a count above 1), so the flat overrides had nothing to interact with. Migration shapes measured flat-on-base vs object-on-head, all identical: {columns:4, mdColumns:2} drew 'grid grid-cols-4 md:grid-cols-2 gap-4' = {xs:4, md:2}; {smColumns:3} drew 'grid grid-cols-2 sm:grid-cols-3 gap-4' = {xs:2, sm:3}; {columns:{xs:1,md:3}, mdColumns:2, xlColumns:6} = {xs:1, md:2, xl:6}; all four flat keys beside columns:2 = {xs:2, sm:1, md:2, lg:3, xl:4}."
},
"producers": {
"before (base fcdc8ec, tracked files, case-sensitive key regex)": "renderer reads 4 (grid.tsx) + prop-type intersection; registration 4 inputs + seed mdColumns/lgColumns (grid.tsx); PageDesigner none (own DEFAULT_PALETTE; no designer/shell/console reads registry inputs or defaultProps: getConfig/getMeta zero hits in plugin-designer, app-shell, apps/console); schema-catalog documents none; docs/skills/READMEs/apps/site none; tests: grid-dom-attribute-whitelist canary, layout-spacing-sets ledger, one prose line in grid-columns-key.test.tsx; scripts: one comment in check-component-surface-parity.mjs; changesets 11491, 7097 (+ lowercase attribute reading in 4787); objectstack: only sdui.manifest.json (recorded console manifest, still type: number)",
"after (head 4d08cf8)": "renderer reads 0; registration 0 (grid.tsx keeps comments only); types: 4 tombstones per face; tests: two new pins + whitelist canary (kept as unread keys) + empty ledger docblock; docs: grid.mdx and schema-reference.md name the retirement; changesets: new entry + dated notes; scripts: 0",
"corpus documents fixed": "none needed: no corpus document authored a flat key"
},
"changeset_sweep": {
"touched": [
"11491-grid-columns-set.md: dated note (objectui#11505) - the four registered enum inputs and validateTree invalid-enum for smColumns: 13 are gone; now columns is the only column input, both faces refuse the keys, validateTree answers unknown-prop",
"7097-grid-2xl-breakpoint.md: dated note (objectui#11505) - 'the designer's flat smColumns...xlColumns channel are unchanged' no longer holds",
"8516-8556-mirror-partial-record-narrowing.md (rider): dated note (objectui#11073) - CLI now prints 'Unrecognized key: "xxl"', Path: columns, Code: unrecognized_keys (measured through the CLI validate printer on this branch), not Path: columns → xxl / Code: invalid_key",
"11441-known-types-retired-layout-keys.md (optional rider): dated note (objectui#11474) - grid gap is one of ten steps; ResponsiveGrid's GAP_CLASSES steps (0-6, 8) all in it",
"11505-grid-flat-columns-retired.md: new, minor for types + components, breaking meaning + migration"
],
"left_alone": [
"grid-dom-attribute-whitelist-4787.md: mdcolumns/smcolumns are a leak measurement taken at that change; its other sentences still hold",
"8505-grid-columns-breakpoint-narrowing.md: about the six keys of the columns object, unchanged",
"11441-retire-nav-responsive-grid-layout.md: already carries 11474/11491 notes; the columns object it names is unchanged",
"11474-layout-spacing-sets.md: gap only",
"7735-zod-mirrors-stop-authoring-defaults.md: grid.columns default row is still let 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: containment, DOM whitelist and object spelling, unaffected"
],
"note": "pnpm check:changeset-claims exit 0 (file names only; the sweep above is the text read)"
},
"open_questions": [],
"out_of_scope_findings": [
"carrier: the next objectstack console-pin bump (re-records objectstack's tracked sdui.manifest.json, which still lists grid's four flat inputs as type: number, predating objectui#11491 too) · noted in PR #11510 Acceptance notes, not filed"
],
"worktree": "removed (node_modules deleted first; the branch was fully pushed at 4d08cf8 before removal, local HEAD = remote head)"
}
Generated by Claude Code
objectstack-fleet commentedon Oct 2, 2026
ACCEPT: PR #11510 (head
4d08cf8755a2764a64d5a0522f954e7badec1435) for this card. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T21:57Z. Report5961966360.Contract face.
5962116647on PR fix(types,components)!: retire grid's flat smColumns / mdColumns / lgColumns / xlColumns; the breakpoint object is the one spelling (objectui#11505) #11510 (Served-tier: CONTRACT_REVIEW_TIER,Local-runs: none) reads PASS on this head, and the seat adopts it.Clause-②: no (narrowing)matches between the claim and the PR body.11491-grid-columns-set;7097-grid-2xl-breakpoint;8516-8556-mirror-partial-record-narrowing, now recordingunrecognized_keys;11441-known-types-retired-layout-keys.What the seat checked in the diff, against triage's ruling A (
5960494324):gridregistration:columns: { xs: 1, md: 2, lg: 4 };grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4on base and on head (ruling pin 2; the dev'sseed_render).retirementTombstone, and the message namescolumns: { BP: N }. The TS face carries?: nevertombstones, which the dev's ablation shows are needed. That is ruling pin 3.REGISTERED_NOT_DECLAREDledger is empty, and its two-way row keeps it empty (ruling pin 1).scripts/check-component-surface-parity.mjs. It re-points an illustration that cited the deleted intersection to a live one.main, first lineFixes #11505.typesandcomponentsminor, with the break and the FROM → TO migration.Out of scope, one line each:
sdui.manifest.json. That file still lists the four inputs. It is in the PR's Acceptance notes.validateTreenow answers a flat key withunknown-prop, a warning, where it answeredinvalid-enumwhile the input was registered. The two zod faces refuse at every value. The changeset says so.Landing: not governed (
check-governed-queue-guard --testover the 16 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red. Ready and auto-merge follow in this same act.objectstack-fleet commentedon Oct 2, 2026
Landed: PR #11510 merged through the queue as
2d576e46e. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-02T22:15Z.5962116647(PASS) names4d08cf8755a2764a64d5a0522f954e7badec1435, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue.main, by content:packages/types/src/zod/layout.zod.tsdeclares the four flat keys throughretiredGridColumnsKey(...), with 4 call sites.packages/components/src/renderers/layout/grid.tsxseedscolumns: { xs: 1, md: 2, lg: 4 }and reads no flat key.git patch-id --stable: the PR's net diff against its merge basefcdc8ec9and the landed commit agree (ee94da3d8d37).completedby the PR'sFixesline, andpm:dispatchedis removed in this act.fix(types,components)!: retire grid's flat smColumns / mdColumns / lg…