Repository navigation
fix(types): declare the six spec members on record:details sections (objectui#8583, item 1) - #8601
Merged
os-warren merged 2 commits intoSep 8, 2026
Conversation
…objectui#8583, item 1)
`RecordDetailsComponentProps.sections[]` omitted six member keys the installed
`@objectstack/spec` 17.3.0 `RecordDetailsProps.sections[]` declares — `columns`,
`icon`, `description`, `showBorder`, `defaultCollapsed`, `headerColor` — while
`RecordDetailsRenderer` spread every authored section through to `DetailSection`,
which reads all six. A spec-valid section such as `{ group: 'terms', columns: 2 }`
rendered correctly and was refused by `tsc` alone.
The six now carry the spec's authoring types, all optional. Pinned compile-time
(reached by the package's `tsc -p tsconfig.test.json` leg) and at runtime by a
two-control probe on the installed spec: a canonical section carrying all six
parses with no issues, and the same section plus an undeclared key draws
`unrecognized_keys` naming exactly that key.
Additive only; no existing member moves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
Contributor
✅ 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
|
This was referenced Sep 8, 2026
…(objectui#8583) Contract review on PR #8601 (card comment 5587871554) failed the semver axis only: six new members on an exported interface of a published type-only package are backwards-compatible new public-API surface (semver section 7), not an internal fix. The repository's own precedents for a standalone TypeScript-face widening agree — 7767, 7952, 7697, 7083 all graded `minor`; the cited #8497 `patch` rode inside a runtime crash fix and was never graded as a widening. One line: `'@object-ui/types': patch` to `minor`. No code change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
This was referenced Sep 8, 2026
Contributor
✅ 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
|
This was referenced Sep 8, 2026
os-warren
marked this pull request as ready for review
September 8, 2026 16:15
os-warren
deleted the
claude/issue-8583-record-details-sections-member-parity
branch
September 8, 2026 16:32
os-justin
pushed a commit
that referenced
this pull request
Sep 8, 2026
Second sync during the same run: #8601, #8607 and #8608 landed while this branch was being re-verified. None of them touches `packages/types/src/__tests__/zod-mirror-parity.test.ts`, so this merge is clean; #8601 does move a DECLARATION the parity ledger reads (`packages/types/src/record-components.ts`), which is why the branch is re-measured on top of it rather than left behind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YBWFb5YgMU5dw8p2VKj16S
This was referenced Sep 8, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #8583 (item 1: the six omitted members)
RecordDetailsComponentProps.sections[]in@object-ui/typesnow declares the six member keys the installed@objectstack/spec17.3.0RecordDetailsProps.sections[]declares and this type omitted:columns,icon,description,showBorder,defaultCollapsed,headerColor. Contract-first: the code moves to the contract. Additive only — no existing member moves; thecollapsedmember that item 2 of the card is about is untouched and its disposition stays on the card, so#8583remains open after this merges.What changed
packages/types/src/record-components.ts— the six members, each optional and typed as the spec's authoring surface types them (columnsa number,icon/descriptionstrings,showBorder/defaultCollapsedbooleans,headerColorthe closed six-token vocabularymuted|muted/50|accent|primary/10|secondary/10|destructive/10), each with a short docblock naming the spec key it tracks and whether the spec permits it besidegroup.packages/types/src/__tests__/record-details-section-members-8583.test.ts— ONE new pin. Compile-time half: invariantEqualbetween each local member type and the spec's z.input type for asections[]entry, four@ts-expect-errordirection proofs (the instrument refusesfalse,never,any, and an undeclared key), the card's own repro literal{ group: 'terms', columns: 2 }, and an excess-key literal that must not compile. Runtime half: the two-control probe on the installed spec (below)..changeset/8583-record-details-section-members.md—@object-ui/types: minor.patch, citing objectui#8497 as precedent; a contract review atCONTRACT_REVIEW_TIERfailed that grade and it was corrected inf299618. Adding six members to an exported interface of a published package is backwards-compatible new public-API surface — semver §7 MINOR — not an internal fix. The#8497precedent is the weak one: its types move rode inside aplugin-detailruntime crash fix and was graded as that fix, never reviewed as a standalone widening. Four counter-precedents grade a standalone TypeScript-face wideningminor:7767-collapsible-trigger-union.md(which explicitly rejects the same "declaration catching up with what ships" argument),7952-dashboard-widgets-component-arm.md,7697,7083. Verdicts: objectui#8583 comments5587871554(FAIL) and5588057698(PASS on the corrected head).Zone 2 — the PM's mechanism assumptions, measured
(a) Live reader for each of the six — HOLDS.
RecordDetailsRenderer(packages/plugin-detail/src/renderers/record-details.tsx) maps every authored entry as{ ...s, title, showBorder: s.showBorder ?? derived, fields }— the spread carries every authored key — andDetailViewpasses each entry verbatim as thesectionprop ofDetailSection(DetailView.tsxlines 1559 and 1748).DetailSection.tsxreads:section.defaultCollapsed(the initial open state),section.columns(throughapplyDetailAutoLayout, which honours an explicit value),section.showBorder(the flat render and theborder-nonevariant),section.headerColor(throughheaderColorClass),section.icon(theSectionIconin both header variants) andsection.description(the sub-heading paragraph in both header variants). Six of six have a reader; none is declared without one.(b) Spec member list and types re-derived from the INSTALLED spec — HOLDS, with one extra row.
@objectstack/specis installed at 17.3.0 as seen frompackages/types(node_modules/.pnpm/@objectstack+spec@17.3.0_ai@7.0.65_zod@4.4.3_). Thesections[]element is a strict object (catchallnever) with 12 keys:name,label,columns,group,fields,hideEmpty,collapsible,showBorder,defaultCollapsed,icon,description,headerColor. Two-control probe on that call shape: a canonical section carrying all six parsed with zero issues (control A); the same section plus__objectui_8583_probe__failed withunrecognized_keysnaming exactly that key (control B). Value probes:columnsis an integer 1..4 (too_bigat 5,too_smallat 0,invalid_typeat 2.5 and at the string"2");headerColorrefusesbg-mutedwithinvalid_valueand acceptsaccent; the other four refuse the wrong primitive withinvalid_type. Besidegroup:columns/showBorder/headerColoraccepted,iconrefused by the spec's group-reference refinement — the docblocks say which. The extra row: the spec-only set is seven, not six —hideEmptyis declared upstream at 17.3.0 (it parsed green), but it has NO reader by maintainer ruling (objectui#7129, 2026-09-01:DetailSectiondeliberately reads it nowhere) and is already recorded as the one deliberately-unread key in therecord:detailsregistry description; it fails Zone 2(a) and is not declared here.(c) No parity-ledger row moves — HOLDS, measured.
packages/types/src/__tests__/zod-mirror-parity.test.tscontains noRecordDetails/record-componentsreference (grep: 0 hits; there is no.zod.tsmirror for this file), and the real instrument agrees: the third type-check leg compiles that ledger (it is in the--listFilesoutput) and passed.check:spec-symbolsstayed at 19 unbacked claims / 14 untriaged collisions —RecordDetailsComponentPropskeeps its existingCLAIM_DEBTrow, unchanged.Validation (code measurements on
88ee0c7;f299618differs by the one changeset line only)pnpm --filter @object-ui/types build— exit 0;dist completeness: 1 package(s) complete (124 emitted files verified).pnpm --filter @object-ui/types type-check(all three legs) — exit 0. Leg-3 evidence:tsc -p tsconfig.test.json --listFileslists 149 test files, the new pin among them.pnpm exec vitest run packages/types/ --maxWorkers=2—Test Files 149 passed (149),Tests 2849 passed (2849). The pin alone: 6 passed.packages/plugin-detailtsc --noEmit(the only importer ofRecordDetailsComponentProps, by grep) — exit 0.packages/types/src/record-components.tswas reverted on disk to the branch base3e71b26(blob6f29bb7, proven bygit hash-object; theheaderColor?:declaration anchor went 1 to 0) and leg 3 re-run: exit 2, 9 errors, all in the new pin, 0 elsewhere — TS2339 on each of the six member reads, TS2353 on both literals. Restored withgit checkout HEAD -- path; disk blob6a26170equals the HEAD blob,git diff HEADempty. The contract reviewer reproduced this ablation independently.headerColoroccurrence, and the base file already mentions the word once in thegroupdocblock, so the script refused to run); the anchor was corrected to the declaration line and the run above is the one that counts.no-explicit-anywarnings, one on an untouched line).package.jsoncheck:*and every.github/workflows/*.ymlrun:line, exit code captured before any pipe — all exit 0:control-bytes,changeset-presence,changeset-no-major,changeset-overwrite,changeset-fixed,shell-escape-residue,phantom-deps,self-import,published-tsconfig-exclude,vi-mock-specifiers,vi-mock-inherit,readme-exports(after the tree was built; the first run was a prerequisite-not-met, not a measurement),unreferenced-sources,handler-key-reads,designer-field-key-parity,icon-record-names,side-effects-array,element-data-source-declaration,action-forward-parity,doc-example-readers,comment-mask-corpus,action-ref-convention,spec-symbols,esm-specifiers,governed-queue-guard --test(NOT GOVERNED).check:published-dist(a release-time/nightly gate by ruling objectui#4846; the reviewer measured its criterion on the types tarball — 128 files, 0 tooling paths, nodist/__tests__),check:dist-completeness --all, repo-widepnpm lint,pnpm check, thedoc-*gates andtype-checkfor packages other thantypesandplugin-detail.pnpm checkis run by CI —.github/workflows/lint.yml:481, step "Verify the CLI's own check command passes on this repository"; theLintjob log onf299618shows it executing and passing (Analyzing 627 files... ✓ All checks passed). A contrary claim in the first review verdict was falsified and is corrected at objectui#8583 comment5587960301.验收备注
packages/types/src/__tests__/p1-spec-alignment.test.tslines 525-532 describe the pre-fix state ({ group: 'terms', columns: 2 }does NOT compile) and name this card as the follow-up; the sentence is now dated by this PR. Outside the dispatched file surface (record-components.tsplus one new pin), so left as is. 承接者: the seat that lands item 2 of this card, which touches the same interface.hideEmptyretirement was ruled on the premise that the spec refuses the key, and the pin moved to 17.3.0 six days later, where it is declared with adescribe()promising the behaviour this repo removed. objectui#8604 — the top-levelRecordDetailsComponentProps.columnsisnumberwhile the spec declaresz.enum(['1','2','3','4']), so{ columns: 2 }type-checks here and is refused at publish.sections[].columnsreally isnumberand this PR is correct on it.collapsedremainder (not acted on, not annotated): on therecord:detailsrender path (RecordDetailsRenderer→DetailView→DetailSection) nothing reads a section'scollapsed;DetailSectionseeds its open state fromdefaultCollapsedonly, and the installed spec answersunrecognized_keysnamingcollapsed. A repo-wide census of other readers was not run, and that gap belongs in the decision block for item 2.Dispatch and identity: the PM claim comment on the card, session
session_01Jmxdo7bmeqCQHLSfmLVX9w, branchclaude/issue-8583-record-details-sections-member-parity.🤖 Generated with Claude Code
https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w