Repository navigation
fix(components)!: the filter builder's list value holds the spec list's entries, so a boolean switched to In is a rule the spec accepts - #26380
Merged
Conversation
…'s entries, so a boolean switched to In is a rule the spec accepts WIP: implementation and pins; changeset and manifest records follow. Claude-Session: https://claude.ai/code/session_01ADHkmPyFNmACDisa4w6cr1 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ADHkmPyFNmACDisa4w6cr1 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ADHkmPyFNmACDisa4w6cr1 Co-authored-by: Claude <noreply@anthropic.com>
…-g33h31 # Conflicts: # scripts/sdui-manifest.sources/components.json
Claude-Session: https://claude.ai/code/session_01ADHkmPyFNmACDisa4w6cr1 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
席位核对 · ACCEPT · seat
|
…-g33h31 # Conflicts: # scripts/sdui-manifest.sources/components.json # scripts/sdui-manifest.sources/plugin-list.json
This was referenced Oct 27, 2026
Contributor
Author
席位核对 · ACCEPT · seat
|
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.
Requested by Steve · project thread
Fixes #26348
Clause-②: yes (narrowing)
Metadata-protocol: none
维护者速读
[true],而是["true"];构建器行值的列表成员收窄为 spec 的字符串/数字列表。ViewFilterRuleSchema拒收,保存视图时才报错;这是 components: the filter-builder renderer hands an authoredFilterGroupto a builder typed onFilterBuilderRowGroup, and the two row shapes are assignable in neither direction (hidden byanyuntil #26293) #26306 留下的半截。filter-builder.tsx的toFilterListEntry/normalizeToArray;UserFilters.tsx的lookupPickerValue;changeset。pnpm --dir ui exec vitest run packages/components/src/__tests__/filter-builder-boolean-list-26348.test.tsx,应 4 条全绿。What changes
FilterBuilderRow.value(ui/packages/components/src/custom/filter-builder.tsx) is now exactlyViewFilterRule['value']. The builder's own wider list member(string | number | boolean)[]is gone. A module-privateFilterListEntryreads the list element from the spec's value type instead of restating it.toFilterListEntry: a boolean becomes its string spelling (truebecomes"true"). It is called bynormalizeToArray(soreshapeFilterValue's list and pair arms), byretypeFilterValue's list and pair arms, byMultiValueInput's commit and by the range input'ssetBound. That is the conversion the builder already made for a boolean that reaches a text column, and every bucket offering a list operator is a text-family column (select/lookup). The list controls compare entries withString(), so the option whose value is"true"stays ticked.UserFilters(ui/packages/plugin-list/src/UserFilters.tsx) hands a lookup chip's selection toLookupValuePickerthroughlookupPickerValue, the same conversion. The selection map stays typed for every control kind, because a boolean chip's selection really is[true]. The two casts in the picker'sonChangeare gone, since the narrowed value no longer needs them.docs/FilterBuilder.mdshows the new member. No sdui record. The per-package records were retired by ci(sdui): retire the per-package SDUI manifest records; CI's regeneration holds freshness (#26137 PR B) #26367 while this PR was open. The main merge took the modify/delete withgit rm, and CI's Build & E2E UI regenerates the manifest. Changeset:.changeset/26348-filter-builder-boolean-list-entry.md(patchfor both packages, BREAKING banner, prose migration for writers).Writers measured (the card's step 1)
changeOperator→reshapeFilterValue→normalizeToArrayequals true→ingave[true]; →betweengave[true, ""]["true"],["true", ""]retypeFilterValuelist / pair armstoFilterListEntryMultiValueInputcommit, rangesetBoundtoFilterListEntryLookupValuePicker.toggleIdUserFilterslookup chip →LookupValuePickerdefaultValues: [true]on a lookup filter field reached the query as[true, id]["true", id]The compiler confirmed the list: narrowing the member first left exactly one more site red (the range writer, TS2322), fixed here.
ADR-0087 stop-check (the card's step 3)
Run before the narrowing edit, against a throwaway probe commit (the narrowing line plus a probe changeset with a prose migration), with
node scripts/check-adr-0087-registration.mjs --base origin/main --head PROBE_SHA: exit 0,not-required (runtime-interface-only) -- verified: ui/packages/components/src/custom/filter-builder.tsx#FilterBuilderRow (interface). No literal FROM → TO is needed for writers, so no ADR wording and no decision were needed. The real changeset carries the same disposition and passes the gate on this head.Tests
ui/packages/components/src/__tests__/filter-builder-boolean-list-26348.test.tsx: type pins (FilterBuilderRow['value']equals the spec value; a boolean list is a@ts-expect-error; a boolean scalar stays admitted), the schema refusing[true]and accepting["true"](non-vacuity), the real operator dropdown drivingequals true→ In andequals false→ Not in with the emitted rule parsed byViewFilterRuleSchema, and the helpers.ui/packages/plugin-list/src/__tests__/UserFilters.lookupBooleanEntry-26348.test.tsx: a lookup chip with an authoredtruedefault; a picked id joins it as["true", "acc_1"]; string and number ids pass through untouched.filter-builder-spec-row-26306.test.tsx(theEqualpin and its docblock row) andfilter-builder-name-authority-9306.test.tsx(theEqualpin and its comment).Acceptance notes
["true", ""]: a spec-valid shape, but not a date the range input can show. Reaching it needs a host to hand a date column a boolean in the first place, and a field switch to a date column already clears it. Noted, not filed (no defect class: the builder never authors that row).FilterBuilderSchema.onChangesignature mismatch (out of scope by the card). Measured on this head:FilterBuilderSchemainui/packages/types/src/complex.tsdeclaresonChange?: (filter: FilterGroup) => void, while thefilter-builderrenderer callsonChangewith a{ target: { name, value } }event shape. Reported to the seat in the report'sout_of_scope_findings; not touched here.Verification
All readings on head
80dc2dca(after mergingorigin/mainat6390fe52), underscripts/pm/os-verify-lock.sh.Type-check and tests
pnpm --filter @object-ui/components type-checkandpnpm --filter @object-ui/plugin-list type-check(bothtsc --noEmit && tsc -p tsconfig.test.json): green before and after the merge. The new@ts-expect-errorpin compiles only because the boolean list is refused.pnpm --dir ui exec vitest run --maxWorkers=2 packages/components/ packages/plugin-list/: Test Files 600 passed, 1 skipped; Tests 5913 passed, 24 skipped; VERDICT command-exit 0.componentsrenderers):packages/components/src/__tests__/pluspackages/plugin-list/src/__tests__/UserFilters*: Test Files 259 passed, 1 skipped; Tests 2528 passed; VERDICT command-exit 0.pnpm exec turbo run build --filter=@object-ui/console --concurrency=2: 71 of 71 tasks, VERDICT command-exit 0.Ablation (one-shot, not kept)
Through
node scripts/ablation-replace.mjs, each restored to the HEAD blob withgit diff HEADempty:normalizeToArrayback to keeping the boolean:filter-builder-boolean-list-26348.test.tsxgoes 3 failed, 1 passed (the schema non-vacuity case stays green).lookupPickerValueback to the identity:UserFilters.lookupBooleanEntry-26348.test.tsxgoes 1 failed, 1 passed (the pass-through case stays green).Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 45 families on this head; all 45 ran with exit 0, and--ranreconciles 45 run, 0 NOT-MEASURED, 0 UNRUN. Among themnode scripts/check-adr-0087-registration.mjs --base origin/mainverifies theruntime-interface-onlydisposition, andnode scripts/check-sdui-manifest.mjsis green on the re-recorded sources.Dogfood battery (owed by the narrowing arm)
pnpm --filter @objectstack/dogfood testafter building its closure: Test Files 2 failed, 297 passed, 3 skipped; Tests 10 failed, 2521 passed, 18 skipped. Every failure is intest/authz-conformance.test.ts(the #17111 ledger-figure pins: "packages/rest/src/rest-route-ledger.ts: docblock says 80 rows, the table holds 81") andtest/authz-probe-blind-spot.test.ts(the #13260 census overrest-route-ledger.tsandrest-server.ts). This diff touches no file underpackages/rest; both files last changed onmainin #26361 (the record-anchored approval lock read), so this is a main-side red, reported to the seat, not fixed here.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01ADHkmPyFNmACDisa4w6cr1