feat(types): four zod mirrors declare members their TypeScript twins declared, and pagination retires page (objectui#6152, round 3) - #11229
Conversation
…re (objectui#6152 round 3) - ObjectFormSchema.open / submitHandler move to RuntimeOnlyDeclared by NAME, through a new RuntimeOnlyNamedAllowList that carries each key's reason; the shape pin widens from the on* spelling to that spelling plus the named list. - PaginationSchema.currentPage is mirrored; page retires on both faces (tombstone) and the renderer's page fallback is dropped. - FormSchema's eight layout keys are mirrored. - ReportComponentSchema.conditionalFormatting is mirrored. - DetailViewSchema's six configuration keys are mirrored. Ledger figures follow in the next commit. Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh Co-authored-by: Claude <noreply@anthropic.com>
…(objectui#6152) UnmirroredDeclared 12 / 62 -> 9 / 44 (3 / 14 spec-derived, 6 / 30 local); RuntimeOnlyDeclared 3 / 7 -> 4 / 9. Two pairs are now runtime-only and nothing else, so the cross-ledger sentence states the difference again, in a spelling that holds at any size, and its pin reads all three figures. Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh Co-authored-by: Claude <noreply@anthropic.com>
…etirement (objectui#6152) Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh Co-authored-by: Claude <noreply@anthropic.com>
…ing changesets it made false Both corrections are appended, dated notes; no existing line or frontmatter is edited (the maintainer's append-only ruling for pending changesets). Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh Co-authored-by: Claude <noreply@anthropic.com>
…which round 3 made false (objectui#6152) An appended, dated note; no existing line or frontmatter is edited. Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh Co-authored-by: Claude <noreply@anthropic.com>
…fix a route count (objectui#6152) Claude-Session: https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHh 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 #11229 (draft, same-repo head, 12 files, +753/-100 against merge base ① Derived judgments
② Semver level
③ Boundary flagsDev flags (report
Implemented-by: VERDICT: PASS Reading time: 2026-09-30T15:54Z Generated by Claude Code |
Refs #6152
Clause-②: yes (narrowing). The diff widens and narrows at once. A declared-but-unmirrored key gains its mirror, so
@object-ui/types/zodaccepts what the TypeScript face already invited.page→currentPageretires one spelling (refused at the key on both faces, which is the narrowing) under the startup no-gradualism rule, and is priced in the changeset. Arm corrected from(widening)per the contract record5914849079.Round 3 of objectui#6152, dispatched under claim
5912572626(thedomain:devxseat 2, sessionsession_01TdiauJaVCHuj45EzZGUxHh, on the maintainer's direct order). ⛔ Draft for the director seat's contract review. Do not mark it ready, and do not enable auto-merge. The card stays open:ObjectGridSchemaand the spec-derived pairs are not this round's.What changed
ObjectFormSchema.openandsubmitHandlergo toRuntimeOnlyDeclaredby NAME. The shape pin widens from theon*spelling to that spelling plus a newRuntimeOnlyNamedAllowList, one row per key, each row carrying its reason as a string-literal type. Three pins hold the list: a non-callback key without a row is red, a row whose key has left the ledger (or that names a callback) is red, and a row without a reason is red. Each pin also has a synthetic recognition case. The comparison is unchanged:assertionUnmirroredMatchesLedgerstill reconciles one measurement against the union of both ledgers. Neither key is mirrored, and neither declaration moved.PaginationSchema.currentPageis mirrored, andpageretires at once.pagebecomes?: neveron the interface andretirementTombstone()on the mirror, whose message says to rename it tocurrentPage. Thepaginationrenderer drops itspagefallback.FormSchemalayout keys,ReportComponentSchema.conditionalFormatting, and sixDetailViewSchemaconfiguration keys. The nested entries (fieldTabs,fieldPanes,sectionGroups,highlightFields, the formatting rules) use module-private schemas that restate their TypeScript element types member for member. One exception is stated in its docblock:sectionGroups[].sectionsisz.array(z.any()). BindingDetailViewSectionSchemathere would import that pair's ownKnownDriftrows as a new drifted key, and growingKnownDriftis never the remedy. This is the same exception round 1 took forsections[].fields.@object-ui/typesand@object-ui/components, bothminor; the break is spelled out). Also, three dated correction notes are appended to pending changesets that this change made false (see Deviations).Ledger totals, before → after (read by the file's own pins, not by hand)
52bf34824)UnmirroredDeclaredRuntimeOnlyDeclaredUnmirroredDeclared; the union is 12KnownDrift,WiderThanDeclared,MirroredUndeclaredH1 held: 12 / 62 with the 4 / 16 and 8 / 46 split on
main. One correction to the dispatch:ObjectGridSchemacarries 11 keys, not 14, because objectui#11068 closed three.Per-key table
The read census is a type-checker walk over every package's sources. It covers property access, element access,
in, destructures, and object-literal producers, all resolved to the interface member through root symbols, plus a separate list of untyped (any) reads. Its controls fired on every pair (for examplePaginationSchema.totalPages1 read,DetailViewSchema.objectName45). The authored census covers 493 tracked JSON files, 352 Markdown JSON fences, and 3118 TS/TSX files that carry a string-literaltype.object-form·openObjectForm(open: schema.open, drawer and modal variants); written only by in-code hosts:AppContent,useActionModal,ObjectManager,FieldDesigner, thebyo-backend-consoleexample; 0 documentsRuntimeOnlyDeclared, allow-list row + reasonobject-form·submitHandlerObjectFormcallsawait schema.submitHandler(writePayload); supplied only byMasterDetailForm; 0 documentsRuntimeOnlyDeclared, allow-list row + reasonpagination·currentPageschema.currentPage); authored 3 times (two catalog documents, the site playground)pagination·pageschema.currentPageorschema.page; authored 0 timesform·fieldTabs,defaultFieldTab,fieldTabsPositionrenderers/form/form.tsx(schema.fieldTabs,schema.defaultFieldTab,schema.fieldTabsPosition)form·fieldPanes,fieldPanesOrientation,fieldPanesResizablerenderers/form/form.tsx(schema.fieldPanes,schema.fieldPanesOrientation,schema.fieldPanesResizable)form·fieldContainerClass,mobileStickyActionsrenderers/form/form.tsx; also produced byObjectFormwhen it builds aformnodereport·conditionalFormattingReportViewerevaluates the rules per cell on the report areport-viewernode carriesdetail-view·primaryField,summaryFields,autoTabs,sectionGroups,highlightFieldsDetailView(schema.*)detail-view·defaultTabDetailView, through its own(schema as any).defaultTabcast at the one read siteStays in the ledger, each with its route written on its entry:
report·chartConfigreport·reportTypedetail-view·activities,comments,historydetail-view·recordNavigationonNavigate)detail-view·autoDiscoverRelatedlabel·contenttext,label,content; authored once (a test)pagecensus (pagination nodes only)pagerenderers/basic/pagination.tsx)pagecurrentPage(control)So no corpus document needed correcting. The data-table's own
pagekey (DataTableSchema.page) is a different member and is untouched.Verification
Heavy runs went through the shared verify lock. Each exit code was captured before any pipe.
@object-ui/typesat the final head1371bca:type-check(tsc --noEmit,tsconfig.examples.json,tsconfig.test.json) exit 0, no diagnostics;vitest run packages/types/gives 290 files / 6941 tests passed.buildexit 0 ("dist completeness: 1 package(s) complete").@object-ui/componentsowns the pagination and form renderers and thepageTypeScript change.@object-ui/plugin-detailand@object-ui/plugin-reportown the readers.@object-ui/plugin-formproduces two of the form keys. The zod-face validators cover the schema-catalog corpus, app-shell previews and the CLI. Their dependency closure was built first.type-checkexit 0 for components, plugin-detail, plugin-report and plugin-form. Tests: components 341 files passed + 1 skipped (four shards); plugin-detail 225 + 1 skipped; plugin-report 24; plugin-form 153;examples/schema-catalog/test/+ app-shellpreviews/122;packages/cli/src/__tests__/23;block-config-schema-parity-821615 tests passed.ablation-replacedid the mutations, and each restore was proven by blob == HEAD and an emptygit diff HEAD.openwas renamed.tsc -p tsconfig.test.jsonexit 2 with exactly two TS2344, atassertionRuntimeOnlyIsCallbackShapedOrNamedandassertionNamedAllowListRowsAreFiled. The comparison stayed green, as predicted: the list is not in the comparison.page: 2was written onto aPaginationSchemainside components. Itstsc --noEmitexit 2 with one TS2322, so the consumer reads the rebuiltpage?: never. A first A3 attempt was refused by the tool before any run: the replacement contained the anchor.check-changeset-presence,check-changeset-no-major,check-changeset-fixed,check:changeset-claims(report-only; every named paragraph read, see Deviations),check:pending-changeset-literals,check-changeset-overwrite(report-only; case 2, frontmatter unchanged),check:control-bytes,check:new-line-citations(0 new),check:handler-key-reads,check:element-data-source-declaration,check:spec-symbols,check:test-path-roots,check:unreferenced-sources,check-type-check-coverage, andcheck-governed-queue-guard --test(NOT GOVERNED over the 12 paths).eslint --no-inline-config --format jsonran over the 8 touched TS files; the JSON has 8 entries and none of them is an ignore notice. It found 0 errors. The 3 warnings sit on untouched lines.eslint.config.jsenables no type-aware linting (emptyparserOptions), so this diff cannot move a verdict in an untouched file. The repo-widepnpm lintbelongs to CI.Deviations (declared)
The claim's file surface does not name three pending changesets. Commits
b3c93e0and3b77588append a dated Correction, 2026-09-30 note to each, in the maintainer's append-only shape (numstat2 0each; frontmatter and every existing line unchanged):.changeset/6152-object-form-unmirrored-members.mdsaid the routes ofopenandsubmitHandlerare open;.changeset/6150-undeclared-but-consumed-keys.mdand.changeset/7804-tree-view-handler-slot.mdsaid the two unmirrored ledgers are in a containment relation.Each became false with this change. The seat is asked to widen the claim's file surface to these three paths.
Not this round (the round-4 worklist)
data-display.zod.ts#DataTableSchema, 17 keys, cut at the pair boundary by the size guard. Every key is read inrenderers/complex/data-table.tsx(mostly by destructure), 15 of them are produced byObjectGrid's in-codedataTableSchema, and almost no document authors any of them. So they fall under the round-1 "class (b)" question too.complex.zod.ts#ChatbotSchemaand#ChatbotFloatingSchema.displayMode's runtime tombstone was deliberately withheld by objectui#7654 (stored designer documents carry it, andchatbot-display-mode-retired.test.tspins that as a tripwire).floatingConfigneeds aFloatingChatbotConfigmirror, with its own tripwire.requestBodyis read by all three registrations and is mirrorable.ObjectGridSchema(11) and the spec-derived pairs, excluded by the claim.Acceptance notes
examples/schema-catalog/.../components-basic-pagination/with-item-count.jsonauthorspageSizeandtotalItems, which neither face declares and nothing reads. The tolerant face keeps them and the strict face refuses them, measured. It is reported, not changed here..changeset/6639-objectgrid-title-mirrored.mdsays what "121" "now means". That went stale before this round, and it is not corrected here.DetailViewSchemamirror'sonNavigatedocblock calls the nestedrecordNavigation.onNavigate"authorable where it lives". A function is not authorable; this is prose only, and noted.Session:
https://claude.ai/code/session_01TdiauJaVCHuj45EzZGUxHhGenerated by Claude Code