docs(core): re-state the dataSource.filter note for the two populations the convergence split (objectui#8945) - #11286
Conversation
…two populations The note said three filter shapes "legitimately reach a renderer here" and typed filter as unknown "rather than the spec's FilterCondition". Since the spec's filter doors converged on the ViewFilterRule array (objectui#6206), that mixes what an author may write (the rule array alone; the record form and AST tuple arrays are refused at ElementDataSourceSchema) with what a renderer may still receive (all three, because metadata at rest is not rewritten). The note now states both, names the spec type as ViewFilterRule[], and keeps the unknown type and its reason. The module example binding writes a rule array instead of the record form. Comments and a patch changeset only. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT 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
|
…used on 17.5.0
The pending objectui#7297 changeset teaches { "assignee": "{record_id}" }
as an element:number filter. @objectstack/spec 17.5.0 refuses that record
form at the filter key (invalid_type, expected array) and accepts the
ViewFilterRule array spelling. Append a dated correction giving the
accepted spelling; frontmatter and existing sentences are unchanged.
Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT
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
|
Contract reviewServed-tier: Inputs, and nothing else: card #8945 (body and all 11 comments, through the seat's ACCEPT ① Derived judgmentsThe diff publishes no type, export, runtime or accept-set change:
⇒ ①-8 fails the record. What flips it, inside the claim's surface and comments-only: re-word the reason in the ② Semver level
③ Boundary flags
Implemented-by: VERDICT: FAIL Rendered 2026-09-30T23:33Z at CONTRACT_REVIEW_TIER by the isolated reviewer inside |
…rers still see all three filter shapes The re-stated ElementDataSourceConfig note and its changeset said the convergence does not rewrite metadata at rest. The migration entry they cite says the opposite: the D2 conversion page-component-filter-record-to-rule-array rewrites the losslessly mappable record forms and single-level AST tuple arrays on every ObjectStack stored-row read and under os migrate meta --stored, and leaves combinator records, parts with no lossless rule spelling and inline-row components' filters as stored. The reason now says that, plus that this backend-agnostic renderer replays no conversion itself. The conclusion, the unknown type and its cast argument are unchanged. Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT 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
|
Contract reviewServed-tier: Inputs, and nothing else: card #8945 (body and all 13 comments, through the seat's round-3 acceptance ① Derived judgmentsThe diff publishes no type, export, runtime or accept-set change:
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Rendered 2026-09-30T23:49Z at CONTRACT_REVIEW_TIER by the isolated reviewer inside |
Fixes #8945
Clause-②: no
This PR re-states the
ElementDataSourceConfigdocblock in@object-ui/corefor the two populations that the upstreamfilterconvergence split apart. It changes comments and adds a patch changeset. No type, export, runtime behaviour or accepted set moves. Dispatched by thedomain:spec @ objectuiseat, sessionhttps://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT.What changed
packages/core/src/data-scope/element-data-source.ts, theElementDataSourceConfigdocblock. It said three shapes "legitimately reach a renderer here". It also typedfilterasunknown"rather than the spec'sFilterCondition". The docblock now separates two populations:ViewFilterRulearray alone.ElementDataSourceSchemarefuses the record form by kind. It refuses an AST tuple array at its first member, because each member must be a rule object.page-component-filter-record-to-rule-arrayrewrites a storedfilteronly where the rule array spells it losslessly (a flat record, an operator object whose operators the rule vocabulary spells, several such keys, or a single-level AST tuple array), on every ObjectStack stored-row read and underos migrate meta --stored. It leaves exactly as stored a filter carrying$and/$or/$not, any filter with a part that has no lossless rule spelling, and every filter of a component whose rows are inline. This renderer is backend-agnostic and replays no conversion itself, so all three shapes may still arrive, andmergeFilterNodesstill lowers each shape. (Corrected in round 3 ata9dd51ca0, answering contract review5921608196①-8.)unknowntype stays, and so does its reason: narrowing the type would only move the cast. The spec's type is now namedViewFilterRule[], notFilterCondition."filter": { … }, which is the record form. It now writes"filter": [ … ]. This is a bounded in-place fix outside the docblock the claim named. See "File surface" below..changeset/8945-element-datasource-filter-note.mdadds a patch changeset for@object-ui/core.Premises, measured on this worktree's install
The install is
@objectstack/spec17.5.0, and the branch is based one420df310.Restart-when:probe, run as written from the worktree root, exits 0. Its controls are inside the predicate, so a dark instrument would have exited 9. A widerElementDataSourceSchema.safeParsereading:{object}is ACCEPTED. This is a control.unrecognized_keys. This is a control.{ status: 'open' }is REFUSED withinvalid_typeatfilter, expected an array.{ amount: { $gt: 5 } }is REFUSED the same way.[{ field, operator, value }]is ACCEPTED.[['status','=','open']]is REFUSED withinvalid_typeatfilter.0, expected an object.e420df310. The installed.d.tsdeclaresfilteras an optional array ofViewFilterRuleobjects, and the spec's owndescribe()text for the key names the rule array and says the record form is refused.record-picker.tsxis untouched. I read the three sites the card named, at the card's pin and onmain:filterinput is DECLARED carries no shape claim.filterinput was the site that describedFilterConditionat the pin. It now declarestype: 'array'and a rule-array description.ElementRecordPickerPropsSchemaon 17.5.0. The rule array is ACCEPTED. The record form and$andrecord are REFUSED atfilter, expected an array. A tuple member is REFUSED atfilter.0. The controls are{object}, ACCEPTED, and an unknown key, REFUSED. No sentence there misstates the door.File surface
The claim's surface is the
ElementDataSourceConfigdocblock, arecord-picker.tsxsentence only if one still misstates the door, and one patch changeset. The diff also touches one token in the same file's module docblock: the example binding's"filter": { … }becomes[ … ]. All four bounded-fix conditions hold:Leaving the example as it was would have made the file contradict its own re-stated note. The seat owes a same-round addition of this site to the claim's file surface.
Gates, all run at HEAD
4837c74e6pnpm --filter '@object-ui/core^...' build, under the verify lock: VERDICT command-exit 0. The scope was 2 of 47 projects.pnpm --filter @object-ui/core type-check, under the lock: exit 0. The script name is echoed and bothtsclegs ran, with 0 TS errors.pnpm exec vitest run --maxWorkers=2 packages/core/, under the lock: exit 0.Test Files 193 passed (193),Tests 3797 passed | 27 skipped (3824).pnpm --filter @object-ui/core lint: exit 0. It reported 0 errors and 568 pre-existing warnings, none of them in the touched file.check:*gates all exited 0:check:control-bytescheck:new-line-citations, which printed0 new citation(s), compared against merge basee420df310over 2 files.check:element-data-source-declarationcheck:spec-symbolscheck:installed-pin-claimscheck:changeset-claims, which printedNo pending changeset names a file this change touches.check:pending-changeset-literalscheck:comment-mask-corpus. Its one disagreement is inapps/console/src/pages/DocsIndex.tsx, not in this diff.node scripts/check-changeset-presence.mjs: exit 0. It found 1 released source file and 1 changeset added.node scripts/check-changeset-no-major.mjs: exit 0.node scripts/check-governed-queue-guard.mjs --teston both paths printedNOT GOVERNED.Author population: the card's open measurement
This is a historical reading at HEAD
4837c74e6on spec 17.5.0. Nothing re-derives it.Method. It parses candidates, and no regex is involved.
git ls-tree -r HEADwith a clean-tree assertion. That gives 6742.ts/.tsx/.js/.jsx/.mjs/.cjs/.mts/.cts/.jsonfiles; all 6742 parsed and 0 failed.dataSourceproperty, adataSource={{…}}JSX attribute, or anX.dataSource =assignment, and that carries afilterkey.ElementDataSourceSchema.safeParsethree times: on the value withfilterremoved, which decides whether it is a binding at all; on the full value; and onfilteralone.The instrument controls, rule array ACCEPTED and record REFUSED, are lit. A positive control is also lit: the eight fixtures listed on objectui#11117 were all found, 8 of 8.
Reading. There are 36 candidates, all in test sources and none in non-test source.
equalswith an array comparand. It is a deliberate objectui#8557 fixture, not an orthography author.filterand were not measured.invalid_typeatobject, deliberately..mdand.mdxfences are outside this instrument; they belong to objectui#11117.The upstream entry's "seventeen (fifteen tuple arrays, two records)" was taken at a different pin. It is not comparable, and this PR does not assert a rival reading of it.
These are the 18 files and how many retired-orthography fixtures each holds:
packages/components/src/__tests__/record-picker-element-data-source.test.tsx: 2 tuplepackages/components/src/__tests__/record-picker-malformed-filter-10789.test.tsx: 2 recordpackages/plugin-charts/src/ObjectChart.elementDataSource.test.tsx: 1 tuplepackages/plugin-dashboard/src/ObjectPivot.elementDataSource.test.tsx: 1 tuplepackages/plugin-detail/src/__tests__/RecordRelatedListRenderer.elementDataSource.test.tsx: 1 tuplepackages/plugin-detail/src/renderers/__tests__/record-related-list.propsRefusal-9963.test.tsx: 1 tuplepackages/plugin-form/src/EmbeddableForm.elementDataSource.test.tsx: 1 tuplepackages/plugin-form/src/LineItemsPanel.elementDataSource.test.tsx: 1 tuplepackages/plugin-form/src/MasterDetailForm.elementDataSource.test.tsx: 1 tuplepackages/plugin-gantt/src/ObjectGantt.elementDataSource.test.tsx: 1 tuplepackages/plugin-grid/src/__tests__/ObjectGrid.elementDataSource.test.tsx: 2 tuplepackages/plugin-kanban/src/ObjectKanban.elementDataSource.test.tsx: 2 tuplepackages/plugin-list/src/__tests__/ListView.elementDataSource.test.tsx: 1 recordpackages/plugin-list/src/__tests__/ListView.sharedGate.test.tsx: 1 recordpackages/plugin-map/src/ObjectMap.elementDataSource.test.tsx: 1 tuplepackages/plugin-timeline/src/ObjectTimeline.elementDataSource.test.tsx: 2 tuplepackages/react/src/element-data-source/__tests__/ElementDataSourceGate.malformedFilter-10789.test.tsx: 1 recordpackages/react/src/element-data-source/__tests__/ElementDataSourceGate.test.tsx: 2 tuplePatch round 2, at HEAD
0b4445d5a(written by the seat).changeset/7297-record-id-filter-token.mdgains a dated correction, append-only (+2/−0), with frontmatter md52935e1e656cbeb29b6093519d07dde85before and after.element:numberfilter example{ "assignee": "{record_id}" }is refused on@objectstack/spec17.5.0 (invalid_typeatfilter, expected array).ViewFilterRulearray,[{ "field": "assignee", "operator": "equals", "value": "{record_id}" }]. It was measured withElementNumberPropsSchema.safeParseandElementDataSourceSchema.safeParsebefore writing, with both controls lit.5921413381.0b4445d5a:check:changeset-claims,check:pending-changeset-literals,check-changeset-presence,check-changeset-no-major,check:control-bytesandcheck:new-line-citationseach exit 0. No package source changed since4837c74e6, so round 1's@object-ui/corebuild, type-check, test and lint still stand.Acceptance notes
toFilterNodedoc inpackages/core/src/utils/filter-converter.tssays "three shapes in circulation, all legitimate" about what a view hands a renderer. That statement is about the renderer population and stays accurate, so it is not edited.record-picker.tsxis unchanged because H3 held.Generated by Claude Code