Match type filters through re-export spellings via canonical code refs - #5800
Draft
lukemelia wants to merge 1 commit into
Draft
Match type filters through re-export spellings via canonical code refs#5800lukemelia wants to merge 1 commit into
lukemelia wants to merge 1 commit into
Conversation
Contributor
Preview deploymentsHost Test Results 1 files ± 0 1 suites ±0 1h 54m 21s ⏱️ + 23m 5s Results for commit 7921aea. ± Comparison against earlier commit bcbbc1f. Realm Server Test Results 1 files ±0 1 suites ±0 15m 17s ⏱️ -23s Results for commit 7921aea. ± Comparison against earlier commit bcbbc1f. |
A filter whose `type`/`on` ref named a type through a re-exporting module (e.g. file-api's FileDef, re-exported from card-api) silently matched nothing: index rows stamp `types` with the canonical (defining-module) key from identifyCard, so only the canonical spelling joined the membership keys. Filtering on base FileDef via its documented file-api module returned zero rows while subtype filters matched. The query engine now resolves each type condition's ref through the definition lookup and unions the canonical ref's spelling-tolerant keys with the as-given ref's, so both spellings compile to the same `types` membership predicates. The type condition becomes a deferred expression node (pass-1-resolved) since the definition lookup is async. The host's search resource applies the same rewrite before client-side matching — the matcher compares against identifyCard of the instance's class, so an uncanonicalized re-export spelling would strip the server's correct results during reconciliation. Until the rewrite settles for the active filter (or when a ref doesn't resolve), the search stays a server-only passthrough. The shared canonicalization walker single-flights duplicate ref spellings by memoizing the in-flight promise: sibling filter nodes are walked concurrently, and a value-memo would let both siblings miss. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lukemelia
force-pushed
the
cs-12168-type-filtered-search-expands-the-adoption-chain-for-card
branch
from
August 18, 2026 20:58
bcbbc1f to
7921aea
Compare
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.
What this does
A
filter.type/oncode ref that names a type through a re-exporting module — the canonical example being baseFileDefaddressed via its documentedfile-apimodule, which re-exports it fromcard-api— silently matched nothing. Index rows stamptypeswith the canonical (defining-module) key fromidentifyCard, so only the canonical spelling ever joined the membership keys: filtering on baseFileDefreturned zero rows while concrete subtype filters matched, making the base-type filter a silent dead end.Two halves, kept in agreement:
typesmembership predicates union the canonical ref's spelling-tolerant keys (RRI / real-URL / virtual-alias) with the as-given ref's. Because the definition lookup is async, the type condition becomes a deferred expression node resolved in pass 1, alongside the existing deferred kinds. A ref whose definition doesn't resolve keeps only its spelling-based keys and matches nothing, exactly as before.identifyCard) before client-side matching — the matcher compares refs againstidentifyCardof an instance's class, so an uncanonicalized re-export spelling would strip the server's correct results during live reconciliation. Until the rewrite settles for the active filter, or when a ref doesn't resolve, the search stays a server-only passthrough so the two evaluations can't disagree.The shared walker (
runtime-common/query-canonicalization.ts) rewritestype/onrefs throughany/every/notwithout mutating the input tree, and single-flights duplicate ref spellings by memoizing the in-flight promise — sibling nodes are walked concurrently, so a value-memo would double-resolve.Test plan
packages/realm-server/tests/search-entries-engine-test.ts: a pure base-FileDef filter matches every file row across subtypes, and thefile-apire-export spelling matches the same rows as the canonicalcard-apispelling (36/36 pass locally).packages/host/tests/unit/query-canonicalization-test.ts: rewrite of top-level and nested refs, input-tree immutability, unresolvable refs marking the result incomplete, and duplicate refs resolving once (8/8 pass locally via the dev test page).🤖 Generated with Claude Code