Repository navigation
feat(types): ObjectGridSchema's zod mirror declares ten members its TypeScript twin declares (objectui#6152 round 6) - #11492
Conversation
…ui#6152 round 6) `aggregations`, `bulkActionDefs`, `conditionalFormatting`, `grouping`, `navigation`, `operations`, `reorderableColumns`, `rowColor`, `rowHeight` and `singleClickEdit` gain their zod members on the flat `ObjectGridSchema` mirror, each measured read by `ObjectGrid` and each a member of the spec's `object-grid` row. `grouping`, `navigation`, `rowColor` and `rowHeight` take the spec schemas the TypeScript twin names, by reference; `reorderableColumns` and `singleClickEdit` take the row's own members; the other four restate the twin's local shapes, the conditional-formatting rule now shared with `ListViewSchema`'s mirror. `UnmirroredDeclared` keeps `resizableColumns` on the entry: its ruled retirement is open again since the authored node moved to the spec's `properties` bag (objectui#11276). The TypeScript `singleClickEdit` comment said `@default false`; the renderer and the spec row both default it to true. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
… the table slot; changeset - `unmirrored-declared-round6-6152.test.ts` drives each of the ten mirrored keys through the mirror, the `object-view` `table` slot (tolerant and strict faces) and the authored `object-grid` node, which does not move. - `grouping-field-padded-refused-7347.test.ts`: the census now finds `table.grouping` on `object-view`, so the table slot gets its own row and carries the padded-field refusal on every face. - `imported-defaults-8317.test.ts` registers the four new spec crossings, and the mirror reads the row's boolean members through the boundary. - One changeset (`@object-ui/types` minor), and a dated, append-only correction on the pending objectui#11276 changeset, whose list of keys "the flat mirror does not" declare this change makes false for ten. Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
Brings in objectui#11485, #11486 and #11482; the parity ledger merged without a conflict (#11485 moved rows in other blocks). Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC Co-authored-by: Claude <noreply@anthropic.com>
`tsc -p tsconfig.test.json` refused spreading the readonly `NOT_COVERED` lists into a `Record<string, string[]>`; copy each list instead. 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: PR objectui#11492, round 6 of card objectui#6152 (draft, not ready, no auto-merge; head repo is the base repo). Inputs, and nothing else: the card body and all 46 comments (the claim 5956749997, the dev report 5957803718, the seat's answer 5957903936 to the round's one open question, the 7347 evidence comment 5908681663, and the carried items of the round-1 to round-5 records), the PR body, its 8-file list, the net diff against ① Derived judgmentsPublished TypeScript face (
Zod accept sets (
Test-only ledger moves (no published face):
File surface against the claim 5956749997: all 8 files sit inside the named surface or a dev-declared widening forced by a pin ( ② Semver level
③ Boundary flagsDev-declared deviations (report 5957803718), each answered:
Noted, not flagged:
Escalations: none. No maintainer decision is needed for this head to land. Implemented-by: VERDICT: PASS Rendered 2026-10-02T17:57Z · a read-only contract review of PR objectui#11492 on the head named above; the newest record naming this head governs, and any push after it voids it. |
Part of #6152 (round 6). The card stays open:
ObjectGridSchema.resizableColumnsstops here with an open question (below), the three spec-derived pairs route to objectui#2231, and the two chatbotdisplayModeentries stay by decision (objectui#7654 ruling B).Clause-②: yes
Why yes (mixed): the strict face widens on an
object-view'stableslot, where nine keys it refused as unknown are now declared. The tolerant face narrows there and on the flat mirror: a wrongly typed value it kept unexamined is now refused at the key. No TypeScript declaration changes shape.Round 6 in one paragraph
ObjectGridSchema'sUnmirroredDeclaredentry held eleven keys. Each was measured first: authored writers in both repositories, readers by a type-checker census and a runtime probe through the realSchemaRendererand registry, and the member of the spec'sComponentPropsMap['object-grid']row. Ten are MIRRORED on the flat zodObjectGridSchema:aggregations,bulkActionDefs,conditionalFormatting,grouping,navigation,operations,reorderableColumns,rowColor,rowHeightandsingleClickEdit. The eleventh,resizableColumns, is NOT retired: the seat's answer A predates objectui#11276, which moved the authored node into the spec'spropertiesbag, and executing it now would leave that bag accepting a key nothing reads (open question below).UnmirroredDeclaredgoes from 5 entries / 16 keys to 5 / 6 (spec-derived 3 / 14 to 3 / 4; local 2 / 2 unchanged).Measured first (base
50c73fed0)H1 held. A TypeScript-parser count of
interface UnmirroredDeclaredat the base reads 5 entries / 16 keys, with 11 onobjectql.zod.ts#ObjectGridSchema, the eleven the claim names.KnownDrift49 / 86,RuntimeOnlyDeclared5 / 30 andRuntimeOnlyNamedAllowList4 / 23 read the same at the base, atmain401611b2and at this head.H2: the authoring side is the spec's for all eleven. A one-off probe through the built faces (
AnyComponentSchema,StrictAnyComponentSchema, the spec row, the flat mirror):object-gridnode, every one of the eleven is refused by name on both faces, towardproperties.KEY(flatPropRefusals);reorderableColumns,resizableColumnsandsingleClickEditas booleans,bulkActionDefsas an array of unknown entries, and the other seven asunknown(aproperties.grouping: 42parses on both faces);object-view'stableslot, which is built from the flat mirror: nine keys were kept unexamined by the tolerant face and refused as unknown keys by the strict face, whilenavigationandresizableColumnsare refused by name (withheld).So the remaining question per key is the hoisted node's parity (the TypeScript
ObjectGridSchema, whichObjectGridreads) and thetableslot that inherits the mirror.H3: every key is read. Type-checker census over
packages/*/srcandapps/*/src(5697 files; controlsobjectName58 reads,columns13,resizable2): every key has a src read inObjectGrid, andObjectViewreadstable.operationsand relays six more throughtableRelay. The first census run read 0 for theobjectNamecontrol: its file list had dropped every file directly under asrc/root. That run was discarded and the enumeration fixed. Runtime probe (one-off, deleted): an authored node{ type: 'object-grid', properties: { … } }through the real registry, varying one key, with a fetch double recording every request. Every key changed the drawn markup or the adapter calls:aggregationssumofamount, and the header draws itbulkActionDefsconditionalFormattingbackground-colorgroupingqueryGroupHeadersand draws grouped sectionsnavigationoperationsexport: falseremoves the export button thatexportOptionsdrawsreorderableColumnsdraggable="true"resizableColumnsfalseremoves the column resize handle (noresizablewritten)rowColorrowHeightsingleClickEditfalse, it does notControls: the same document rendered twice is byte-identical;
columnschanged (the lit control) differs. A first run was stopped by the repository's network-escape guard (a permission read reached a real socket) and its readings were discarded; the recorded run stubsfetchand records each request in the compared log.H4:
singleClickEditonobject-gridis authored, not host-paired. UnlikeDataTableSchema(round 5), the spec'sobject-gridrow declares it ("Enter cell edit on single click (default true when editable)"), and the grid supplies its own save path. So it is mirrored here, by reference to the row member, and round 5's runtime-only filing was not copied across.Authored census. objectui: an AST and JSON walk over 497 JSON files, 1561 Markdown fences and 6083 TS/TSX files, with controls
object-gridbagobjectName31 andtable.columns15. It found no document writing any of the eleven in anobject-viewtableslot (two typed tests only). In anobject-gridbag, three doc fences write keys this round mirrors:operationsinREADME.mdandcontent/docs/api/schema-reference.md,singleClickEditincontent/docs/plugins/plugin-grid.mdx. The in-code producers areObjectView(the relayed keys),FieldDesigner/ObjectManager(operations) and the plugin-grid demo.resizableColumnsis written nowhere. objectstackmain3a6d92f7(read bygit grepon a self-named ref): its two authoredobject-gridnodes, the showcase work queues, writeobjectName/columns/filteronly, and nothing in it authors anobject-view.What changed
packages/types/src/zod/objectql.zod.ts, the flatObjectGridSchemamirror:groupingGroupingConfigSchema, by referencenavigationNavigationConfigSchema, by referencetableslot still refuses it by name)rowColorRowColorConfigSchema, by referencerowHeightRowHeightSchema, by referencereorderableColumns,singleClickEditaggregations{ field, type }entry, restating the twinoperationsbulkActionDefsBulkActionDef;operationandvisible's second arm by reference to the specconditionalFormattingListViewSchema's mirrorNarrowerThanDeclaredandWiderThanDeclaredKeysmeasure nothing new, and noKnownDriftorWiderThanDeclaredrow was added. The spec row types seven of the ten asunknown. Binding those would have mirrored nothing, so each member takes the spec schema the twin names, or the twin's own shape.bulkActionDefsis NOT the spec'sBulkActionDefSchemaby reference. Measured against the twin, that schema is narrower onparams(a strict entry with a closedtype) and onvisible(noExpressionWirearm), so binding it would have needed aKnownDriftrow.ListViewSchema'sconditionalFormattingnow reads the hoisted rule. Its accept set is unchanged, and the zodListViewSchemamember is the same union.packages/types/src/objectql.ts: onlysingleClickEdit's comment. It said@default false, butObjectGridreadsschema.singleClickEdit ?? trueand the spec row says the default is true.packages/types/src/__tests__/zod-mirror-parity.test.ts: theObjectGridSchemaentry goes from eleven keys toresizableColumns, with the round's route written on it. The four pinned figure sites and the history sentences moved with it (header bullet 5 / 6; both ledger docstrings 6 keys; totals line 5 / 6 with 3 / 4 and 2 / 2; the spec-derived bullet 3 / 4).Doors, before and after:
object-grid(propertiesbag)object-gridprop written flat on the nodeobject-viewtable, strict face (objectui validate)object-viewtable, tolerant face (safeValidateSchema)ObjectGridSchema.safeParsedirectlyPins
packages/types/src/__tests__/unmirrored-declared-round6-6152.test.ts(49 rows). For each key it checks that the mirror accepts the declared value and refuses a wrong one at the key, then drives the nine slot keys through thetableslot on both faces. It holds thattable.navigation/table.resizableColumnsstay refused by name, and that the authored node does not move (flat refused by name, bag parses). It pins the two row members by identity, the spec's padded-name rule reachinggrouping, the shared conditional-formatting rule by identity withListViewSchema's, and the strict entries naming unknown members. It also holds thatresizableColumnsis not a member.grouping-field-padded-refused-7347.test.ts: the census now findstable.groupingonobject-view, as the 2026-09-30 evidence comment on 121 declared-but-unmirrored keys across 16 schema pairs — the lane #6058's new UnmirroredDeclared ledger made visible #6152 predicted for the first round that mirrored this key. The table slot gets its own row and so carries the padded-field refusal on every face (the row type gained an optionaltypeso one arm can own two paths).imported-defaults-8317.test.ts: the four new spec crossings are registered, and the mirror reads the row's members through the boundary (stripImportedDefaults(SpecObjectGridPropsSchema).shape.KEY).Corpus and pending changesets re-judged
object-gridbag, which the spec judges and this round does not touch.content/docs/plugins/plugin-view.mdx'stablesection lists the relayed keys as declared, and the validator now agrees with it. No corpus document needed a change..changeset/11276-object-grid-properties-bag.md(pending) said the row declares eleven keys "the flat mirror does not". This round makes that false for ten, so it gets a dated, append-only correction note (+2 / -0, frontmatter and every prior line byte-identical, checked bycmp).check:changeset-claimsnamed 41 more pending changesets. Their paragraphs about the grid, the table slot and the ledgers were re-read, and none is made false.Reverse verification (predictions written first; objectstack
scripts/ablation-replace.mjs, wrap mode, on committed437408ce; each restore proven by blob == HEAD and an emptygit diff HEAD)groupingmember deleted from the mirror (anchor x1 to x0, blob36a2f818todd46877a):tsc -p tsconfig.test.jsonexit 2 with exactly one TS2322,"objectql.zod.ts#ObjectGridSchema"not assignable toneverat the ledger reconciliation. vitest 22 failed, exactly as predicted: 4 in the round-6 pin, and 18 in the 7347 file (the census plus the table row on four faces).groupingput back in the ledger entry with the mirror intact (bloba93e249dtod0959519):tscexit 2 at the same reconciliation. The parity file had 2 runtime failures, the objectui#7279 split/totals pin and the objectui#8243 docstring pin. The prediction named finding: #6058's SPEC-DERIVED remedy split routesObjectViewSchema's unmirrored keys on a scanner false positive — it references no spec schema #7279 and "possibly" finding(types): zod-mirror-parity's header says KnownDrift holds 62 keys; two instruments measure 63 — wrong since objectui#7664, and the sibling half of #7733 #8222; the second one to fire was finding(types): zod-mirror-parity's two ledger docstrings say UnmirroredDeclared records 94 keys; two instruments measure 87 — unmoved since objectui#7779, and outside every pin in the file #8243.No dist leg: every subject here resolves to source (relative imports in the types tests, and the root vitest alias for consumers).
Tests and gates (final head
437408ce; heavy runs throughos-verify-lock.sh; each exit code captured before any pipe)pnpm --filter @object-ui/types run type-check(tsc --noEmit,-p tsconfig.examples.json,-p tsconfig.test.json, which judges the ledgers): exit 0.pnpm exec vitest run packages/types/:Test Files 336 passed (336),Tests 8904 passed (8904).packages/types: every test file that imports@object-ui/types/zodor namessafeValidateSchema/AnyComponentSchema/StrictAnyComponentSchema. That is 115 files (schema-catalog, cli, app-shell previews, apps/console, components, scripts and twelve plugin packages), run in two halves:58 passed (58)/1286 passed, then57 passed (57)/1015 passed.turbo run build --concurrency=2, the filtercheck-doc-snippet-types.mjs --build-filterprints):Tasks: 35 successful, 35 total. Thencheck:doc-snippets("776 of 776 block(s) judged, 0 failed"),check:doc-examples, andcheck:readme-exports: all exit 0.check-changeset-presence("6 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)"),check-changeset-no-major,check-changeset-fixed,check-changeset-overwrite(report-only; the one appended note),check:changeset-claims(report-only),check:pending-changeset-literals,check:control-bytes,check:new-line-citations("0 new citation(s)"),check:spec-symbols,check:handler-key-reads,check:element-data-source-declaration,check:test-path-roots,check:unreferenced-sources,check-type-check-coverage("43/43"),check:doc-types,check:doc-fences,check:component-surface-parity(report-only),check-governed-queue-guard --testover the diff (NOT GOVERNED).eslint --no-inline-config --format jsonover the 6 changed TS files. The JSON judged 6 files with no ignore notice: 0 errors, and 38 warnings, every one on a pre-existing line (0 on an added line).eslint.config.jssets noparserOptions/projectService, and noeslint-rules/file reads the disk, so the diff cannot move an untouched file's verdict. The repo-widepnpm lintis CI's.mainwas merged once before this PR (54be4dda, bringing in objectui#11485, fix(types): AnySchema includes every declared node type, pinned by an enumeration (objectui#11478) #11486 and feat(types)!: the widget slot's metric-card arm declares MetricCard's registered inputs, and the widgetcomponentslot takes the arm (objectui#11467) #11482); the parity file merged with no conflict.NOT MEASURED:
check:sdui-registration-pins(it needs a console build, and no registration input moved); the fullpnpm testfarm and the repo-wide lint (CI's);plugin-grid/plugin-viewbehaviour suites (no runtime file changed). The contract record is the seat's to owe on the landing head.Open question:
resizableColumnsThe seat's answer A on #6152 ("
resizableis canonical; the local half tombstonesresizableColumns; its spec half forks to objectstack") was given while the flat mirror was the authoredobject-gridarm. Since objectui#11276 the authored node's props live in the spec'spropertiesbag, which isComponentPropsMap['object-grid']by reference and still declaresresizableColumns("Alternate spelling ofresizable"). Pinned by objectui#11276: "the bag is the spec row by reference". So the local half as written would tombstone the TypeScript member and the mirror, and dropObjectGrid's?? schema.resizableColumnsread. That leavesobjectui validateandos validateboth acceptingproperties.resizableColumns, with the flat refusal pointing at it, and nothing reading it. Measured: no document in either repository writes the key. The options, with four axes, are in the report on the card; this PR leaves the key in the ledger.Acceptance notes (noted, not filed here)
object-gridrow types seven of these keys asunknown, so the authored bag acceptsproperties: { rowHeight: 'comfortable' }orgrouping: 42on both faces.ObjectGridthen falls back silently (forrowHeight, tocompact). objectui#11276's PR already reported the row'sunknownmembers as a spec-row finding. The report on the card names it for the seat with its measured reach.BulkActionDef/BulkActionParam(the TypeScript twin) are wider than the spec'sBulkActionDefSchema: open params with anytype,ExpressionWirepredicates, and the runtimeactionDef. The mirror follows the twin. A narrowing of the twin would be its own question.bulkActionDefsparam's catch-all that the twin and the tolerant face keep. That is the strict face's own construction, not this member's.Generated by Claude Code