fix(fields,plugin-detail,plugin-list,app-shell,console): read count/value answers as the contract declares them (objectui#6917) - #8624
Merged
Conversation
…alue answers as the contract declares them Six sites outside the fences of objectui#6726 / #6840 / #6839 still carried a `count` or `value` arm. Each got its OWN in-repo producer census, with the control sitting on the producer->consumer JOIN rather than on the word -- objectui#6840's zero is seam-local and is not transferable (the same sweep read 0 producers for `value` at one seam and 5 at another in one pass). ARM A -- a real precedence inversion, repaired WITHOUT deleting the arm. `packages/fields`' lookup chip read `result?.value || result?.data || []`: `value` ahead of `data`, the one rows member `QueryResult` declares. It now delegates to `@object-ui/core`'s `extractRecords` -- same accepted set (bare array, `data`, `value`), contract order. The `value` arm STAYS: its census found 8 live `find()` doubles emitting `{ value: [...] }` (3 plugin-kanban, 3 plugin-calendar, 2 plugin-grid), so deleting it -- the plausible wrong fix -- would have broken them. 0 producers emit BOTH members, which is why this was a "potentially answers wrong" and graded p2 rather than p1. FIVE DEAD ARMS deleted, each on its own measured zero: `count` at the DataSource.find() seam -- plugin-detail's reference rail and plugin-list's ListView. 0 / 592 find() producers emit `count`; controls `data` (312) and `total` (150) lit on the same pass, plus a superset sweep over all 418 producer-bearing files adjudicated to zero envelope members. `value` at the client.meta.getItems() seam -- app-shell's help menu, and the console's Public Forms and Flow Runs pages. These three do NOT sit on the find()/QueryResult seam at all, contrary to how the card described them, so they were measured on their own join: 0 / 28 meta.getItems producers emit `value`; control `items` (18) lit. The canonical readers of that envelope (`MetadataProvider.extractItems`, `MetadataService.getItems`) have never had a `value` arm either. `QueryResult` is NOT widened to bless `count` or `value` -- a published-type change and the maintainer's call, the floor #6726 / #6840 / #6839 all held. One refusal pin per module (`*.contractEnvelope-6917.*`), each keeping the live arms green beside the deleted one, and -- only where an inversion existed -- a case feeding both members with different contents, the sole input that separates the two orders. Also repaired: two plugin-grid test doubles answered `{ value: [], '@odata.count': 0 }` while ObjectGrid reads `result.data` / `result.total`. Inert only while the arrays were empty; the first row put in one would have been silently dropped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YBWFb5YgMU5dw8p2VKj16S
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
|
os-justin
marked this pull request as ready for review
September 8, 2026 17:58
This was referenced Sep 8, 2026
os-justin
enabled auto-merge
September 8, 2026 17:59
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.
Fixes #6917
Six sites outside the fences of objectui#6726 / #6840 / #6839 still carried a
countorvaluearm. Each got its own in-repo producer census, with the control sitting on the producer→consumer
JOIN — because #6840's zero is seam-local and is not transferable. Arms were deleted only on a
zero; the one site whose census came back non-zero kept its arm and got a precedence repair
instead.
QueryResultis not widened to blesscountorvalue.Two premises of the card, falsified
1. Three of the six sites are not on the
DataSource.find()seam at all.The card files all six as "the same arm #6840 removed", i.e. a non-
QueryResultkey at theDataSource.find()seam.app-shell'sAppHeader, and the console'sPublicFormsPageandFlowRunsPage, callclient.meta.getItems(type), whose envelope is{ type, items: [...] }(or a bare array on the ADR-0037 preview path).
QueryResultnever reaches them, anddatais nota member of that envelope either —
MetadataProvider.extractItemspins{ data: […] } → [], andMetadataService.getItemsreadsitemsand nothing else. The contract member there isitems,not
data.That is the card's own central rule turned back on the card, so those three were measured on
their own join, not the one the card named.
2. Arm A's census is NON-ZERO — so the arm was kept.
packages/fields' lookup chip readresult?.value || result?.data || []—valueahead ofdata.The inversion is real and confirmed. But
valueis live at that seam: 8 in-repofind()doubles emit
{ value: [...] }. Deleting the arm is exactly the plausible wrong fix the card'snon-regression axis names, so only the rank changed. Per the card's route this is a stop-and-
report on that site; it is reported here rather than deleted.
Censuses
Both run by a bracket-balancing extractor over all 4406 tracked
.ts/.tsxfiles —packages/**,apps/**,examples/**,e2e/**,scripts/**, soapps/consoleis inside thepopulation. Controls are the same extraction on the same population, differing only in the key,
so a lit control proves the pass reaches the join rather than merely finding the word.
Seam 1 —
DataSource.find()→QueryResultdatatotalcountvaluevalueanddataboth, as envelope membersThe last row is why the inversion is a potentially answers-wrong, not an answers-wrong — which is
triage's own reason for grading this p2 and not p1.
Seam 2 —
client.meta.getItems()→ metadata envelopeitemsvalueGuards against a false zero
stopped at
vi.fn()and never saw.mockResolvedValue({…}); a second draft missed ES6 shorthand{ items }. Both were caught by a named control going dark, and both are fixed —datarose312 from 138 once they were.
outside a producer body still surfaces. All 25
count:-bearing files were adjudicated by hand:every one is the DataSource's own sibling
count()method, a row field, an i18n interpolationparameter, an aggregate function name, React state, a DOM assertion, a comment, or finding(components,plugin-view): two more non-
QueryResultarms survive on the seams #6726 repaired —res?.countandresults.value#6840's ownrefusal pin. Same for the 6
value:files on seam 2 (filter values, select options, a DOM helperparameter, a storage shim).
'@odata.count'is a different key —res?.countcannot read it — so it does not answer thisquestion. The 2 producers emitting it are the plugin-grid fixtures repaired below.
What changed
fields/src/index.tsxfind()value@object-ui/core'sextractRecordsplugin-detail/…/record-reference-rail.tsxfind()countplugin-list/src/ListView.tsxfind()countapp-shell/…/AppHeader.tsxmeta.getItems()valueconsole/…/PublicFormsPage.tsxmeta.getItems()valueconsole/…/FlowRunsPage.tsxmeta.getItems()valuePlus the two
plugin-griddoubles that answered{ value: [], '@odata.count': 0 }whileObjectGridreadsresult.data/result.total— fixtures that read as though they supplied rowsand supplied none. Repaired to
{ data: [], total: 0 }.Pins — one per module
*.contractEnvelope-6917.*, following #6840's form: the header carries the measurement, the livearms stay pinned beside the dead one, and a precedence case is written only where an inversion
actually exists. 29 new tests.
Reverse verification — every pin observed RED, classified per-test from vitest's JSON reporter
(not the text reporter). Every failure is an
[assertion]; zero suite deaths. Each leg provedits mutation reached disk (injected/removed text counted before and after) and each restore was
proved by content —
git diff HEADempty and all blob hashes equal toHEAD.countarmexpected '7' to be '0',expected '7' to be '2')countarmexpected '7 records' to be '3 records','99 records')valuearmvaluearm on both pagesObjectGridto readvalueextractRecordsalways returns[]In every leg the "always correct" control case (
totaloutrankscount;itemsstill read) stayedgreen, so each red is a reading of this change and not of a module that stopped working.
that pin's subject is
ObjectGrid's read, not fixtures it does not use. The leg was retargeted atthe real subject. Stated plainly: reverting those two fixtures alone is not detected by any test,
by construction — a fixture is an input to a suite, not its subject. What is guarded is the contract
that makes the repair correct.
Verification
packages/fields/ packages/plugin-detail/ packages/plugin-grid/ packages/plugin-list/—479 files, 5718 tests passed
packages/app-shell/ apps/console/— 746 files, 7414 passed, 1 skippedturbo run type-checkover the six packages — 41/41 successful (each package echoestsc --noEmit && tsc -p tsconfig.test.json, so the new pins are typechecked too)eslint .whole repo — 4539 files, 0 errors (12319 pre-existing warnings; no--max-warnings, no warning ratchet). Not a narrowed run: the full population was linted.check-changeset-presence✅ ·check-changeset-no-major✅ ·check-control-bytes✅(6813 files scanned)
All at
c71bbff9f.Out of scope — reported, not touched
packages/plugin-list/src/ListView.tsxcarries a SEVENTH arm the card does not enumerate:Array.isArray((results as any).value)in the same fetch effect, on the samefind()call as thecountarm. It sits in adata → records → valueladder — therecords/valuetolerance setowned by objectui#6839's
extractRecordsfamily, not this card's residue. Deleting onlyvaluefrom that triple would be half ofextractRecordsreadsrecordsAHEAD ofdataonDataSource.find()answers — the shared-helper copy of the #5945/#6726 inversion, live in 9 renderers #6839's job. ForextractRecordsreadsrecordsAHEAD ofdataonDataSource.find()answers — the shared-helper copy of the #5945/#6726 inversion, live in 9 renderers #6839.extract-records.ts's own header undercounts by one. It says "fivefind()doubles emit{ value: [...] }… three inplugin-kanban, two inplugin-calendar". This census findsthree in plugin-calendar — the third is
packages/plugin-calendar/src/__tests__/ObjectCalendar.expandGate-6453.test.tsx:174. ForextractRecordsreadsrecordsAHEAD ofdataonDataSource.find()answers — the shared-helper copy of the #5945/#6726 inversion, live in 9 renderers #6839.packages/core/src/data-scope/ViewDataProvider.ts's second privateextractRecords— fenced toextractRecordsreadsrecordsAHEAD ofdataonDataSource.find()answers — the shared-helper copy of the #5945/#6726 inversion, live in 9 renderers #6839 by the card; not touched, nothing new learned.Line numbers, re-located by content
fields:250unchanged ·rail:196unchanged · ListView 1816 → 2077 · AppHeader 182 → 186 ·PublicFormsPage 134 → 135 ·
FlowRunsPage:155unchanged.Fence collisions re-checked against the live open-PR list: zero open PRs touch any of the six
files (app-shell's two open PRs, #8615 and #8164, are the flow-node inspector and record-scope
conditional formatting).
🤖 Generated with Claude Code
https://claude.ai/code/session_01YBWFb5YgMU5dw8p2VKj16S
Generated by Claude Code