Repository navigation
Pin that a caller's filter and a grant on one path into a list match through one element - #6561
Conversation
…ust match one element Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
habdelra
left a comment
There was a problem hiding this comment.
[Claude Code 🤖] This review checked two things. First, whether the documented limit is the one the engine and the policy composition actually produce. Second, whether the new tests would fail if that behavior changed. It did not cover the rest of the test file.
No blocking issues. The limit holds as stated, and the colleague test would go red if the engine ever stopped sharing the alias. That test also covers the realm's own search path.
- Doc precision: the rule applies per path, not per list. For a list of links, conditions on different fields of the linked cards are not tied to one element. See the inline comment on the
docs/card-operations.mdparagraph.
| The caller's filter and the grants run as one query, and when both test the | ||
| same list field, one element of the list must satisfy both. A teacher whose |
There was a problem hiding this comment.
[Claude Code 🤖] Could this say "the same path" instead of "the same list field"? As written it overstates the limit for a list of links. The engine shares one alias per full dotted path (tree_<column>_<fieldPath> in expression.ts), not per list. A linksToMany grant, .students | any(.id == actor()), compiles to students.id. A caller filter on students.grade therefore gets its own alias and is tested against any element, independently of the grant's.
That matters in both directions:
- A reader told "the same list field" will avoid a
students.gradefilter that actually works. - Worse, they may expect that filter to apply to their own linked entry, the one the grant matched. It doesn't, because the two conditions aren't tied to one element.
Suggested wording: "…and when both test the same path into a list (the list itself, or the same field of the cards it links to), one element must satisfy both. Conditions on different fields of a list's items are each met by any element, not necessarily the same one."
Non-blocking. The test pins the case that's documented correctly.
There was a problem hiding this comment.
[Claude Code 🤖] Fixed in 7bfefed. The paragraph now says one element has to satisfy both only when they test the same path into a list (the list itself, or the same field of the cards it links to), and that conditions on different fields of a list's items are each met by any element. This matches tree_${column}_${fieldPath} keying the alias by the full path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In service of the operation-permission policies, which scope a search to what a caller's grants admit by composing the grants into the caller's own query. When a caller's filter and a
querygrant test the same path into a list, one element of the list has to satisfy both. The index query engine gives each path into a list one shared alias, so in{ every: [callerFilter, { any: grants }] }both conditions test the same element. A teacher whose grant is.teacherIds | any(. == actor())and who searchesteacherIdsfor a colleague therefore finds nothing, not even a classroom that lists them both. Searching for their own id works, and so does searching on any other field.We're keeping the engine as it is. The limit only removes rows and never adds one. Lifting it would change the shared-alias rule in the query engine, in both adapters and in the client-side matcher, for every search and not only policy-scoped ones. This PR pins the behavior in
policy-scoped-search-test.ts. A new Rosters realm there grants a query over classrooms byteacherIds. The tests check three things: searching for the caller's own id finds both classrooms; searching for a colleague finds nothing, through both the federated and the realm's own search, while the realm owner does find the shared classroom; and a filter on another field finds it. A later engine change to this behavior would then have to be deliberate. The school example realm already avoids the pattern (its README says not to filter on the list a grant reads).No search's SQL changes; the diff is tests only. The limit is written up in the skills rather than in this repo: for a caller writing a search in cardstack/boxel-skills#177 (
card-operations-authoring), and for a policy author in cardstack/boxel-skills#174 (realm-policy-authoring§7).Linear: CS-13344
🤖 Generated with Claude Code