Filed from the post-hoc contract audit of merged PR #7391 (verbatim at objectui#7391 comment 5527977938; auditor tier-verified claude-fable-5-1, 75/75 turns, no fallback). That PR landed without its Clause-② review — three consecutive HTTP 529 deaths killed the commissioned review and another actor flipped it ready and merged it — so the review ran afterwards as an audit and its findings are already in main.
This card carries the unforked correctives. The one genuine design fork the audit raised — the five symbols published on @object-ui/react's sole entry, against ruling a′'s "the constant is internal" — is a separate card and is ⛔ not part of this one.
⏳ Time-critical: (1) closes at the next release
Both .changeset/ files are still pending on origin/main. Once released, the semver level is frozen into the per-package CHANGELOG and cannot be corrected without a lie or a note. Do (1) first.
(1) Changeset level and copy — .changeset/7210-non-grid-row-ceiling.md
plugin-gantt / plugin-calendar / plugin-map / plugin-tree declare patch, but they carry the user-visible break: result sets above 2000 rows are no longer fully drawn. Policy is minor-with-the-break-spelled-out. The fixed group makes the released version identical either way — the defect is that the CHANGELOG will file a behaviour break under "Patch Changes". ⇒ flip the four to minor.- The example reads
Showing the first 2,000 of 41,234 records — separators the note never renders. The i18next config carries no format, and the provider-less fallback uses String(v); the unit test's toContain('41234') passing is the proof. ⇒ change the example to the rendered copy: Showing the first 2000 of 41234 records. - The export list omits the type
NonGridCeilingResult. ⇒ add it.
(2) Two row-ceiling pins do not grade the cap they are named for
packages/plugin-map/src/ObjectMap.rowCeiling-7210.test.tsx and packages/plugin-calendar/src/ObjectCalendar.rowCeiling-7210.test.tsx.
Measured: mutating setData(capped.rows) → setData((result as any).data ?? capped.rows) in both — so 2001 rows are drawn while $top and the note stay intact — leaves both pins green, 4/4. They pin the $top and the footnote, not "draws at most N". Ruling a′'s pin is explicit: "the DOM row count equals the ceiling".
⇒ Assert the count handed to the child equals NON_GRID_ROW_CEILING in the above-ceiling case — marker/cluster input for the map, events for the calendar — the way the gantt pin already does via its stubbed child. The mutation above is the ablation: state the prediction first, then show both pins going red under it and green after restore.
(3) Two pin docblocks state a reverse-verification mechanism that is false
packages/plugin-gantt/src/…/ObjectGantt.rowCeiling-7210.test.tsx:29-33 predicts that deleting $top fails "at the FOOTNOTE assertion". Measured: it fails at the $top assertion (:128). The adapter returns everything, the helper slices, and the note still renders.ObjectTree.rowCeiling-7210.test.tsx:24-28 predicts failure "at BOTH the row count and the footnote". Measured: :98 ($top) only — the row count stays 2000.- The calendar and map docblocks make the same "red at the footnote" claim.
The pins are not vacuous; the stated mechanism is simply wrong, which is worse than silence because the next reader trusts it. ⇒ rewrite to what actually happens: red at the $top assertion; the note still renders because the helper slices whatever arrives.
(4) Calendar external-data sync leaves rowCeiling stale
packages/plugin-calendar/src/ObjectCalendar.tsx:344-347 is the one setData path that does not also setRowCeiling({ truncated: false }). Latent today (ObjectView passes data from mount, so the stale state is never reached), one-line corrective. Pin it: a component that first draws a truncated fetch and then receives a short external data must drop the note.
(5) The false dependency comment — packages/react/src/index.ts:100-104
It reads that @object-ui/react is "the only package all four already depend on". Measured false: packages/plugin-{gantt,calendar,map,tree}/package.json each also list @object-ui/core, @object-ui/components and @object-ui/types.
The real reason was the dispatching seat's same-round barrel fence (#7210 comment 5511301369 — core owned by #7349, types+components by #7182). ⇒ rewrite the comment to state the true reason, and cross-link the decision card below so the next reader finds the open question rather than a settled-sounding rationale.
⚠️Comment only. ⛔ Do not move, rename or unpublish any of the five symbols in this PR — that is the decision card's scope.
(6) Stale headroom comment
packages/i18n/src/locales/*.ts still says "~1 KB of headroom"; #7399 moved the framework chunk to ~8.3 KB of headroom against its ceiling. One-line refresh.
Fences
- ⛔ Nothing in this card touches the published surface of
@object-ui/react. Findings ①(b), ② and ③ of the audit — relocating the non-React half to @object-ui/core, retiring NON_GRID_ROW_CEILING_TOP behind a query helper, reshaping NonGridRowCeilingNote to take NonGridCeilingResult — are all on the decision card and are ⛔ out of scope here. - ⛔ No test may be skipped, disabled or quarantined to get green.
- The audit's finding ⑥ (the merge-reshaped
expandFls-7230 assertion) is a resolution, not a weakening — verified in both directions, no FLS regression can pass it silently. ⛔ No action; do not "fix" it. - Boundary notes recorded by the audit, not defects and not in scope:
ObjectMap still runs two queries per load (schema in deps); under ObjectView/ListView the calendar and map draw the host's $top: 100 page and never engage the ceiling; applyNonGridRowCeiling's total is not provenance-safe against a server that omits total (data-objectstack fabricates total = records.length, so such a server would render "first 2000 of 2001").
Filed from the post-hoc contract audit of merged PR #7391 (verbatim at objectui#7391 comment 5527977938; auditor tier-verified
claude-fable-5-1, 75/75 turns, no fallback). That PR landed without its Clause-② review — three consecutiveHTTP 529deaths killed the commissioned review and another actor flipped it ready and merged it — so the review ran afterwards as an audit and its findings are already inmain.This card carries the unforked correctives. The one genuine design fork the audit raised — the five symbols published on
@object-ui/react's sole entry, against ruling a′'s "the constant is internal" — is a separate card and is ⛔ not part of this one.⏳ Time-critical: (1) closes at the next release
Both
.changeset/files are still pending onorigin/main. Once released, the semver level is frozen into the per-package CHANGELOG and cannot be corrected without a lie or a note. Do (1) first.(1) Changeset level and copy —
.changeset/7210-non-grid-row-ceiling.mdplugin-gantt/plugin-calendar/plugin-map/plugin-treedeclarepatch, but they carry the user-visible break: result sets above 2000 rows are no longer fully drawn. Policy is minor-with-the-break-spelled-out. The fixed group makes the released version identical either way — the defect is that the CHANGELOG will file a behaviour break under "Patch Changes". ⇒ flip the four tominor.Showing the first 2,000 of 41,234 records— separators the note never renders. The i18next config carries noformat, and the provider-less fallback usesString(v); the unit test'stoContain('41234')passing is the proof. ⇒ change the example to the rendered copy:Showing the first 2000 of 41234 records.NonGridCeilingResult. ⇒ add it.(2) Two row-ceiling pins do not grade the cap they are named for
packages/plugin-map/src/ObjectMap.rowCeiling-7210.test.tsxandpackages/plugin-calendar/src/ObjectCalendar.rowCeiling-7210.test.tsx.Measured: mutating
setData(capped.rows)→setData((result as any).data ?? capped.rows)in both — so 2001 rows are drawn while$topand the note stay intact — leaves both pins green, 4/4. They pin the$topand the footnote, not "draws at most N". Ruling a′'s pin is explicit: "the DOM row count equals the ceiling".⇒ Assert the count handed to the child equals
NON_GRID_ROW_CEILINGin the above-ceiling case — marker/cluster input for the map, events for the calendar — the way the gantt pin already does via its stubbed child. The mutation above is the ablation: state the prediction first, then show both pins going red under it and green after restore.(3) Two pin docblocks state a reverse-verification mechanism that is false
packages/plugin-gantt/src/…/ObjectGantt.rowCeiling-7210.test.tsx:29-33predicts that deleting$topfails "at the FOOTNOTE assertion". Measured: it fails at the$topassertion (:128). The adapter returns everything, the helper slices, and the note still renders.ObjectTree.rowCeiling-7210.test.tsx:24-28predicts failure "at BOTH the row count and the footnote". Measured::98($top) only — the row count stays 2000.The pins are not vacuous; the stated mechanism is simply wrong, which is worse than silence because the next reader trusts it. ⇒ rewrite to what actually happens: red at the
$topassertion; the note still renders because the helper slices whatever arrives.(4) Calendar external-
datasync leavesrowCeilingstalepackages/plugin-calendar/src/ObjectCalendar.tsx:344-347is the onesetDatapath that does not alsosetRowCeiling({ truncated: false }). Latent today (ObjectViewpassesdatafrom mount, so the stale state is never reached), one-line corrective. Pin it: a component that first draws a truncated fetch and then receives a short externaldatamust drop the note.(5) The false dependency comment —
packages/react/src/index.ts:100-104It reads that
@object-ui/reactis "the only package all four already depend on". Measured false:packages/plugin-{gantt,calendar,map,tree}/package.jsoneach also list@object-ui/core,@object-ui/componentsand@object-ui/types.The real reason was the dispatching seat's same-round barrel fence (#7210 comment 5511301369 —
coreowned by #7349,types+componentsby #7182). ⇒ rewrite the comment to state the true reason, and cross-link the decision card below so the next reader finds the open question rather than a settled-sounding rationale.(6) Stale headroom comment
packages/i18n/src/locales/*.tsstill says "~1 KB of headroom"; #7399 moved theframeworkchunk to ~8.3 KB of headroom against its ceiling. One-line refresh.Fences
@object-ui/react. Findings ①(b), ② and ③ of the audit — relocating the non-React half to@object-ui/core, retiringNON_GRID_ROW_CEILING_TOPbehind a query helper, reshapingNonGridRowCeilingNoteto takeNonGridCeilingResult— are all on the decision card and are ⛔ out of scope here.expandFls-7230assertion) is a resolution, not a weakening — verified in both directions, no FLS regression can pass it silently. ⛔ No action; do not "fix" it.ObjectMapstill runs two queries per load (schema in deps); underObjectView/ListViewthe calendar and map draw the host's$top: 100page and never engage the ceiling;applyNonGridRowCeiling'stotalis not provenance-safe against a server that omitstotal(data-objectstackfabricatestotal = records.length, so such a server would render "first 2000 of 2001").