Repository navigation
fix(plugin-view): the registered object-view reads a named view's grid members (objectui#10885) - #10937
Conversation
…amed view (objectui#10885) The registered object-view renderer passes no renderListView, so an authored node and the Studio ViewPreview land on the object-grid node ObjectView builds for ObjectGrid. That node now reads the bucket-1 members the protocol declares on both a named view and object-grid (pagination, selection, rowHeight, resizable, searchableFields, conditionalFormatting, rowActions, bulkActions, bulkActionDefs, exportOptions) off the named view first, then the node only where it already read the node (table.pagination, table.selection). A named view's hiddenFields is subtracted from the resolved column projection. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…view's grid members; changeset (objectui#10885) Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
…clared shape (objectui#10885)
A named view's exportOptions may be the protocol's legacy bare format
array, which the protocol lifts to { formats } at parse; the grid reads
exportOptions.formats, so the array is lifted here the way ListView
lifts it for the host delegation. The conditionalFormatting and
bulkActionDefs rungs assert the grid's declared element type: the
protocol's expression wire is wider than it, and ObjectGrid hands both
to the shared evaluator that reads it.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
… sets apart (objectui#10885) Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
|
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: ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: FAIL The code, pins, fence, census and semver hold. Only the wording must change before landing.
|
… declared-on-both set (objectui#10885) Contract review round 1, wording only. The changeset, README and docs paragraphs presented the ten members route 2 now reads as the whole set the protocol declares on both a named view and object-grid; label, data and navigation meet the same test and are still not read off the named view on that path, and now say so. The withoutHiddenFields docblock states the one way its subtraction differs from ListView's: an entry with no field identity is kept. No behaviour change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN
✅ 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: This is an in-seat delta review of fix round 1 ( ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…0885-object-view-route2-named-grid Claude-Session: https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN Co-authored-by: Claude <noreply@anthropic.com>
✅ 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
|
…e` read the named view expression slots by reference (objectui#10946) (objectstack-ai#10977) Fixes objectstack-ai#10946 Clause-②: yes — widens two published types to the spec's expression-input wire (triage execution note 3). ## What changed `SpecConditionalFormattingRule.condition` and `BulkActionDef.visible` in `@object-ui/types` now read the named view's own expression slots BY REFERENCE, from the authoring (`z.input`) face of `ObjectListViewSchema`. That is the derivation `ObjectViewSchema.listViews` already uses (objectui#7928). There is no hand-written copy of the spec wire. | Member | Before | After | |---|---|---| | `SpecConditionalFormattingRule.condition` | `string` | `string`, or the slot type of `ObjectListViewSchema.conditionalFormatting[].condition` | | `BulkActionDef.visible` | `string \| { dialect?: string; source: string }`, spelled inline | `ExpressionWire` (the same union, now by name), or the slot type of `ObjectListViewSchema.bulkActionDefs[].visible` | - **Zod mirror.** The mirror moves with the type. Two mirrors carried `condition: z.string()`: the list view's rule union and `KanbanConditionalFormattingRuleSchema`. Both now read one module-private `SpecRuleConditionSchema`. Its first arm is `z.string()`, so a string condition parses exactly as before: it is not canonicalized into an envelope, and `''` is still accepted. The spec slot alone would do both of those things to a string. Its second arm is the spec's own slot schema, taken by reference; a pin asserts reference identity. The `zod-mirror-parity` ledger rows name keys, not value types, and no key moved, so the ledger is untouched. `BulkActionDef` has no standalone zod mirror. The list view's `bulkActionDefs` is already the spec's schema by reference. - **Relays.** `ObjectView` route 2 drops the two assertions PR objectstack-ai#10937 added: `conditionalFormatting … as ObjectGridSchema['conditionalFormatting']` and `bulkActionDefs … as ObjectGridSchema['bulkActionDefs']`. Both relays now type-check as written. - **No runtime behaviour change.** No evaluator, renderer or relay changed. A type assertion compiles to nothing. - **Changeset.** `@object-ui/types: minor`. It is breaking for TypeScript readers of these members, and the changeset says so. ## Assertions the PM listed that stay, and why (measured) - **`plugin-list` `ListView`: kept.** The four casts are `schema.conditionalFormatting as unknown[] | undefined` and the three `(schema as any).bulkActionDefs` reads. With all four removed, `plugin-list` `tsc --noEmit` exits 0 even against BASE-shaped types (ablation leg A[4] below). Their targets are `readonly unknown[]` parameters or an untyped node literal, so this gap never forced them. They are outside this card and untouched (see Acceptance notes). - **`plugin-grid` `resolveBulkActions`: kept.** `action.visible as BulkActionDef['visible']` stays because `action` is `NamedActionDef`, an `unknown` pass-through bag. Removing the cast is red WITH the widened types (leg C: TS2322, `visible?: {}`), so it exists for a different reason. ## The two spec lines differ on these slots | | `condition` / `visible` slot | `ast`-only envelope | |---|---|---| | installed `@objectstack/spec` 17.4.0 (the pin) | `ExpressionInputSchema`, where `source` is optional | admitted | | spec `main` at `dbddf02c` (what the Spec Main Shape Gate compiles against) | `EvaluatedExpressionInputSchema`, where a non-blank `source` is required | refused | - Because the members index the slot rather than naming `ExpressionInput`, they follow whichever line is installed. They narrow with the next spec bump, with no local edit. - **Local spec-main probe, not the CI gate.** I compiled the pin file plus the ObjectView-shaped relays against spec `main` SOURCE, with `@objectstack/spec` mapped to `git archive origin/main packages/spec/src`. The installed 17.4.0 was absent from the program. Result: 0 errors in objectui files or pins. Of the 8 errors, 5 are `React` namespace errors from the probe's empty `types` and 3 are in spec source (missing `pg-connection-string` and node types). A `@ts-expect-error` on an `ast`-only value was consumed, which confirms spec `main` refuses that value on the slot. - **Runtime answer for the `ast`-only envelope the installed line admits.** It is an evaluation fault. The formatting rule does not match, the bulk def qualifies no record, and the fault is warned. Both paths are pinned. ## Verification at `6f5bfdcb0` - **type-check.** `turbo run type-check --continue`, locally, over `types`, `core`, `plugin-grid`, `plugin-view`, `plugin-list`, `plugin-kanban`, `app-shell` and `plugin-report`. All 8 scripts ran, 0 `error TS`, VERDICT command-exit 0. - **vitest.** The whole `packages/types/` suite plus the 37 other test files that name `conditionalFormatting`, `bulkActionDefs`, `BulkActionDef` or the rule types: `Test Files 306 passed (306)`, `Tests 6765 passed (6765)`. - **New pins.** `spec-expression-wire-slots-10946.test.ts` (types, 14 tests) and `specExpressionWire-10946.test.tsx` (plugin-grid, 5 tests) are green. Their type halves are compiled by each package's `tsconfig.test.json`. - **Gates.** Each of these exits 0: `check-control-bytes`, `check-new-cross-file-line-citations` (0 new), `check-spec-symbol-derivation`, `check-changeset-presence`, `check-changeset-fixed`, `check-changeset-no-major`, `check-changeset-claims`, `check-changeset-overwrite`, `check-pending-changeset-literals`, `check-type-check-coverage`, `check-test-path-roots`, `check-vi-mock-override-shape`, `check-phantom-dependencies`, `check-package-self-import`, `check-unreferenced-sources`, `check-node-esm-load --specifiers-only`. `check-governed-queue-guard --test`: NOT GOVERNED. - **Lint, narrowed and declared.** I ran `eslint --no-inline-config --format json` over the 5 changed TS files. It reported 5 files, 0 errors and 95 warnings, all on untouched lines (none in the added lines or the two new files). The population is the root `eslint.config.js` `**/*.{ts,tsx}` block, which includes all 5 files. That config enables no type-aware linting (no `parserOptions.project` or `projectService`), and no rule in `eslint-rules/` reads the filesystem. So this diff cannot move a verdict on an untouched file. The repo-wide `pnpm lint` belongs to CI. ## Reverse verification (ablations; each leg mutated with `ablation-replace.mjs`, anchor hit proven on disk, `@object-ui/types` rebuilt, dist marker counted) **Leg A** reverts all three derivations to the BASE shapes: the rule alias to `{ condition: string }`, the bulk alias to `{ visible?: never }`, and `SpecRuleConditionSchema` to `z.string()`. It also removes the four `ListView` casts. 1. `plugin-view` `tsc --noEmit`: exit 2. TS2322 on the route-2 grid schema: `conditionalFormatting`, then `condition`, is not assignable to `string`. TS names only the first incompatible member. 2. `types` `tsc -p tsconfig.test.json`: exit 2, with 7 errors, all in the new pin: the five relays, the envelope rule, and the `ast` excess property. 3. `plugin-grid` `tsc -p tsconfig.test.json`: exit 2, with 2 errors in the new grid pin. 4. `plugin-list` `tsc --noEmit` with the `ListView` casts removed: exit 0. This is the control showing those casts are not this gap's. 5. vitest on the types pin: 7 failed and 7 passed. The failures are envelope acceptance on both mirrors, the envelope-refusal cases on both mirrors (their valid-envelope control fails), the reference identity on both mirrors, and the reference control. That control throws on a `z.string()` that has no `.options`. The string and empty-string controls stay green. **Leg B** reverts only the `visible` arm. `plugin-view` `tsc --noEmit` exits 2: `bulkActionDefs` is incompatible, then `visible`, then `source`. **Leg C** keeps the widened types and removes the `resolveBulkActions` cast. `plugin-grid` `tsc --noEmit` exits 2 (TS2322). **Restore.** Every leg was restored with `git checkout HEAD -- PATH`, and each restore was checked: blob equal to the HEAD blob, and `git diff HEAD` empty. `@object-ui/types` was rebuilt, all 3 mutation markers counted 0 in dist, and `git status --porcelain` came back empty. The plugin-grid runtime cases characterize pre-existing behaviour, so they stay green under a type-only ablation by construction. Their type half is leg A[3]. ## Declared surface extension `packages/plugin-grid/src/__tests__/specExpressionWire-10946.test.tsx` is a new file outside the claim's file surface. The card's "evaluates" pin needs the real grid, and `@object-ui/types` has no evaluator to import. It is a new file only; no existing file outside the claim was edited. ## Not measured locally (CI owns) - The Spec Main Shape Gate. It is covered only by the source probe above. - Full `pnpm test` (8 shards). - Full `pnpm lint`. - `pnpm type-check` for the packages not listed above. ## Acceptance notes - **`ListView` casts (polish, not filed; carrier: none).** The four casts are redundant, as leg A[4] measures, but for a reason outside this card. They were left untouched. - **`@object-ui/core` `FieldRulePredicate` (observation, not filed).** It declares `source` as required, which is narrower than the installed slot. Every call site that hands it these members already casts, and it converges with spec `main`'s narrowing. - **Model-named trailer on `17393ae3c`.** That commit carries a model-named `Co-Authored-By` trailer. The dispatch contract asks for model-free trailers. History was not rewritten, because the branch is never force-pushed. `6f5bfdcb0` is model-free. --- _Generated by [Claude Code](https://claude.ai/code/session_012UwY3ahMixEFkfTUxMVkYm)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
Part of #10885
Clause-②: no
Member 1 of objectui#10885: route 2, the registered
object-viewrenderer's own grid path, reads a named grid view's grid members off the named view. Member 2 is not taken and member 3 is not in this PR (see Acceptance notes), so #10885 remains open.Claim
5865109811, seatdomain:ui#2, PM sessionsession_014mXUNuFomfj24w7s1pZzhN(https://claude.ai/code/session_014mXUNuFomfj24w7s1pZzhN), modesubagent.What changed
packages/plugin-view/src/ObjectView.tsx, thegridSchemamemo: theobject-gridnodeObjectViewhandsObjectGridwhen no host passesrenderListView.paginationandselectionthen fall back to the node'stable, as they did before.rowHeight,resizable,searchableFields,conditionalFormatting,rowActions,bulkActions,bulkActionDefsandexportOptionsare named-view sourced, likegrouping/rowColorbeside them. There is noactiveViewrung and no new node read.hiddenFieldsis subtracted from the resolved column projection, in both thefieldsand thecolumnsslot (new helperwithoutHiddenFields). It is not relayed as a key:object-griddoes not declare it, andObjectGridhas no read of it.exportOptionswritten in the protocol's legacy bare-array spelling is lifted to{ formats }(new helpergridExportOptions). That is the lift the protocol's own parse makes, and the oneListViewmakes for the delegation.ObjectGridreadsexportOptions.formats.conditionalFormattingandbulkActionDefscarry a type assertion to the grid's declared element type. The protocol's expression wire is wider than that type (measured bytsc), andObjectGridhands both to the shared evaluator, which reads the wire.#regionmarkers hashes to40bc2292on the base and on the head.packages/plugin-view/README.mdandcontent/docs/plugins/plugin-view.mdx, beside the objectui#10758 paragraph. Neither gains a code fence..changeset/10885-object-view-route2-named-grid.md:'@object-ui/plugin-view': patch, with the claim'sClause-②: noline.@object-ui/app-shellgains only a test file, so it is not listed;check-changeset-presencepasses.objectViewHostSurface.test.tsxsection 1b derives the fence's named-view read set by name from the fence text, and walks the rungs of therenderListViewliteral. Moving the reads out of the fence changes both derivations, so those pins would have to be edited. The two sinks also differ:ListViewsubtractshiddenFieldsand liftsexportOptionsitself, andObjectGriddoes neither. So the two routes share the precedence, not the code.H1: reproduced on
main(733fd5ac65)Read from the DOM through the real stack: the real
ViewPreview, the realSchemaRendererand registry, the registeredobject-viewrenderer and the realObjectGrid. The pin fileViewPreview.routeTwoGridMembers-10885.test.tsxwas run on an untouched base tree.{ type: 'grid', columns: ['name', 'amount', 'stage'], hiddenFields: ['amount'] }still draws the hidden column. The header span readingBudget Amountis rendered (expected SPAN to be null).rowHeight: 'compact'draws no row-height control:Unable to find an element with the title: Row height: compact.columns: ['name', 'stage']off the same named view IS honoured on route 2.Pipeline Stageis drawn andRecord Owner, which is not projected, is not.Members, per route
The measured set is bucket ① of the objectui#7924 ruling, all 23 members. Route 2 takes a member when three things hold: the installed
@objectstack/spec17.4.0 declares it under the same name on a named view (ObjectListViewSchema) and onobject-grid(ComponentPropsMap['object-grid']), andObjectGridreads it. The pin re-derives both declarations.paginationtable.paginationtable.paginationselectiontable.selectiontable.selectionrowHeightresizablesearchableFieldsconditionalFormattingrowActionsbulkActionsbulkActionDefsexportOptions{ formats })hiddenFieldsnavigationinlineEditdescriptionobject-griddoes not declare itemptyStateobject-griddoes not declare itaddRecord,allowPrinting,aria,compactToolbar,filterableFields,sharing,showRecordCount,userFiltersobject-gridslotRoute 2's named-view reads on the grid node go from 5 (
columns,filter,sort,grouping,rowColor) to 16.The ten are not the whole set that meets the test. Outside bucket ①,
labelanddataare also declared on both and read byObjectGrid, andnavigationmeets it too; none of the three is read off the named view on route 2 (Acceptance notes).Pins and ablation
Red on the base
733fd5ac65(the two new files copied onto an untouched base worktree), green on the head56ad7e8774.packages/plugin-view/src/__tests__/ObjectView.routeTwoNamedGridMembers-10885.test.tsx, 11 tests. It mounts throughSchemaRendererand the registered renderer, withObjectGridmocked as the sink.hiddenFieldsis declared on the named view and not onobject-grid; the full fixture parses under the strictObjectListViewSchema. The control isallowExport, which is on neither.pagination did not arrive from the named view: expected { pageSize: 100 } to deeply equal { pageSize: 5, …(1) }. The bare-arrayexportOptionslift is also red on the base.table.paginationandtable.selectionapply when the named view omits them, and the other eight stay undefined although the node'stablecarries them.hiddenFields, 5 tests. Four are red on the base: both slots lose the hidden field and nohiddenFieldskey reaches the grid; an object-shaped column keeps its shape; the node'stable.columnsis narrowed too; hiding every projected field keeps[]. One is green on both: with no projection anywhere, nothing is invented.packages/app-shell/src/views/metadata-admin/previews/ViewPreview.routeTwoGridMembers-10885.test.tsx, 4 tests, the whole real stack with DOM readings.hiddenFieldsandrowHeightare red on the base. The litcolumnscontrol and the neither-declared control are green on both.ObjectView.namedViewProtocolKeys-8980.test.tsx,objectViewHostSurface.test.tsx) are untouched and green.Ablation, run with
ablation-replace.mjson the committed head695a6ce635(the later56ad7e8774changes one test-header comment only). The directions were predicted before the run.tablerungs back in place of the ten member rungs: anchor 1 → 0, blobdcce880456e3→57515b34b699.hiddenFieldsread: anchor 1 → 0, blob →a01a7bdbbcf4.rowHeightreads went 2 → 1 (the fence's own stays) and thegridExportOptionscall 1 → 0.packages/plugin-view/suite, both ViewPreview pin files and three types census files. Result: 8 failed, 789 passed, 59 files. The 8 are exactly the new rows.dcce880456e3) andgit diff HEADis empty.Consumer sweep
git grepover test files for'object-view',ObjectViewmounts and imports,ViewPreview, and the tests that read plugin-view'sObjectView.tsx, plus the objectui#7924 / objectui#7779 census tests. Everything ran on the head under the verify lock.VERDICT command-exit 0, at695a6ce635. It covers the wholepackages/plugin-view/suite and the tenpackages/typestests that read named views or the object-view docs. The censusobject-view-unmirrored-keys-7779,schema-reference-named-list-view-keys-7923andobject-view-listviews-by-reference-7928are among those ten. The rest are from plugin-map, plugin-list, plugin-grid, core, react, examples andscripts.VERDICT command-exit 0, at695a6ce635. It covers app-shell'sViewPreview,StudioDesignSurface,ResourceEditPageandAppContenttests, theObjectView.*tests (the relay censusObjectView.relayRungCensus-7559among them), and fiveapps/consoletests.scripts/markdown-test-inputs.mjs --list): 829 tests passed.Gates
Each exit was captured redirect-first.
56ad7e8774:check-changeset-presence("3 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)"),check-changeset-no-major,check-changeset-fixed,check-changeset-overwrite, andcheck-changeset-claims(6 pending paragraphs name a touched file; each was read, and none is made false);check:pending-changeset-literals,check:new-line-citations("0 new citation(s)"),check:control-bytes,check:test-path-roots, and the threecheck:vi-mock-*gates;check:spec-symbols,check:phantom-depsandcheck:handler-key-reads;check:doc-types,check:doc-fences,check:doc-example-ids,check:doc-example-readers,check-doc-expression-carriageandcheck-doc-links;check-governed-queue-guard --teston the 6 paths: "An ordinary pull request".type-checkexit 0 at695a6ce635for@object-ui/plugin-viewand for@object-ui/app-shell. Each runstsc --noEmit && tsc -p tsconfig.test.json, after its dependency closure was built.--listFilesOnlyfinds each new test file in its package's test program. The app-shell run used a 6144 MB heap, because its test program is the largest in the repo.--no-inline-configon the 3 edited TS/TSX files, which is the whole population:eslint.config.jscovers them withfiles: ['**/*.{ts,tsx}'], and--format jsonreports 3 files.ObjectView.tsxhas 60 warnings, per rule identical to the base (53 / 4 / 3). The new pins have 6 and 1no-explicit-anywarnings.projectService/parserOptionshave 0 hits against alanguageOptionscontrol of 1, so no untouched file's verdict can move.check:readme-exports, reason: prerequisite not met. 86 self-imports could not be judged because the workspace dists are not all built. This diff adds no fenced block to any README.check:doc-snippetsandcheck:doc-examples: not run, because no fenced block was added.Serial
2b3d2061a2) editsObjectView.tsxin one comment of the view-switcher icon map. This PR's hunks are the column helpers andgridSchema.git merge-tree --write-treeagainst its head is clean (tree4a03a230b6). Against a freshorigin/main(733fd5ac65) it is clean too (tree749f02ef74).ViewPreview.tsxis not edited (PR objectui#10906). The pin is a new file.packages/plugin-grid/src/ObjectGrid.tsxis not edited (PR objectui#10278).Fix round 1
The contract review of
56ad7e8774failed on wording only. The code, the precedence, thehiddenFieldscomposition, theexportOptionslift, the fence, the census, the pins, the ablation and the semver level all held. One commit,097ba79141, text only:label,dataandnavigation, also declared on both a named view andobject-grid, are still not read off the named view on this path.label,dataandnavigation, also declared on both, are not read off the named view on this path.withoutHiddenFieldsdocblock now states its one divergence fromListView: an entry with no field identity is kept, whereListViewdrops such an entry wheneverhiddenFieldsis non-empty. Comment only: the diff ofObjectView.tsxchanges no code line.097ba79141, under the verify lock:object-view-unmirrored-keys-7779and the 18 tests that read the changed markdown: 21 files, 1077 tests passed,VERDICT command-exit 0;packages/plugin-view/suite and every test that reads plugin-view'sObjectView.tsx): 75 files, 1882 tests passed,VERDICT command-exit 0.097ba79141, exit 0 each:check-changeset-claims,check:pending-changeset-literals,check:control-bytes,check:new-line-citations("0 new citation(s)"),check-doc-links,check:doc-fences,check-changeset-presence,check-changeset-overwriteandcheck:handler-key-reads.#regionmarkers still hashes to40bc2292.git merge-tree --write-treeis clean against a freshorigin/main(733fd5ac65, tree46037fd4fc) and against PR objectui#10914's head (2b3d2061a2, tree605c556b1d).Acceptance notes
ObjectGridreads each of the eight members. Measured: it reads seven. It has nohiddenFieldsread, andobject-griddoes not declare the key.hiddenFieldsis therefore honoured the way the protocol composes it (objectstack#15184 ruling B:columnsprojects,hiddenFieldssubtracts). It is subtracted from a declared projection, asListViewdoes for the delegation.columnsanywhere, the grid derives its own columns and the hidden field still shows.ListViewhas the same limit.searchableFields,bulkActionDefsandexportOptionsare also taken: each is declared on both schemas and read byObjectGrid.navigationis excluded. It is declared on both schemas, butObjectViewpassesObjectGridits ownonRowClick, anduseNavigationOverlayobeys anonRowClickfirst. Relayed, the member would be read by nothing.ObjectView'snavigationConfig, which reads the node'snavigation.ListViewthe samehandleRowClick. That is outside this rung.inlineEditis excluded.ObjectGridreadseditable, notinlineEdit.ListViewtranslates one into the other under its objectui#4647 grant gate. That is a key translation with a permission contract, a new host path, not the named-view-first rung.fieldOrder,labelanddata, which are not in bucket ①. The delegation reads all three off a named view, and route 2 reads none of them.fieldOrderis the composition's third key, so route 2 does not apply a named view's order.ObjectGridreadslabelfor its caption and export filename, while route 2 passestable.title.ObjectGridreadsdatafor its fetch source; route 2 passes none.fieldOrder,label,data,navigationandinlineEditon route 2 are member 4 of objectui#10885, recorded by the seat on the card.objectViewHostSurface.test.tsxsection 1b), and this order keeps both untouched.listViewsandrenderListView.conditionalFormattingrule'sconditionas an expression input, which admits the{ dialect, source }wire, and abulkActionDefsvisiblewire that may carryastand nosource.ObjectGridSchemain@object-ui/typesspells neither; the spec'sobject-griddeclares both slots loosely (conditionalFormattingas unknown,bulkActionDefsas an array of unknown), so the gap is against the named view's wire, not againstobject-grid. The runtime reads both through the shared evaluator. The two rungs assert the declared type. Widening the declaredconditiontype would be a Clause-② type move, so it belongs on the backlog; not filed here.object-gridalso acceptsexportOptionsas a bare format array, and keeps it an array at parse.ObjectGridreads onlyexportOptions.formats. This is a source reading, not a measured render. Carrier: PR objectui#10278, which holdsObjectGrid.tsx.ViewPreviewpin).Generated by Claude Code