Repository navigation
Say a caller's filter and a grant on one path into a list must meet in one element - #177
Conversation
…n one element Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Staging Workspace Sync SuccessfulSuccessfully synced changes to staging workspace Sync Details |
habdelra
left a comment
There was a problem hiding this comment.
[Claude Code 🤖] I checked the paragraph against the engine: how the table-valued tree aliases are keyed in expression.ts, composePolicyScopedFilter and its callers (including the saved-search path in handle-search.ts), the membership shapes a grant compiles to (asMembership in policy-filter.ts), and the boxel pinning tests. I also compared it with the realm-policy-authoring §7 rewrite on the open companion PR and with the surrounding section's style.
No blocking issues. The claims match the engine. The tree alias is keyed tree_<column>_<fieldPath> on the full dotted path, so two conditions on one path share one element, and different paths fan out independently. A grant compiles only .list | any(. == v) or .links | any(.id == v), so the parenthetical "the list itself, or the same field of the cards it links to" covers every list shape a grant can produce. The paragraph agrees with the §7 rewrite on substance. It reads in the section's bold-lead style.
- One wording nit: "no classroom at all" holds only for a single grant (inline thread).
- Unverified: the boxel pinning tests ("a caller filter and a grant on the same list") have not run green in CI yet. Every earlier run on that branch was cancelled, and the current run is still in progress. Consider merging this after those tests pass, since the paragraph cites them as the pin.
| teacher whose grant reads `.teacherIds | any(. == actor())` finds every | ||
| classroom they teach by searching `teacherIds` for themselves, and no classroom | ||
| at all by searching `teacherIds` for a colleague, not even one that lists them | ||
| both. Write such a search against another field. A saved search's own filter is |
There was a problem hiding this comment.
[Claude Code 🤖] "No classroom at all" is true only when this is the teacher's only query grant. Could it say "no classroom this grant admits" instead? The grants compose as any: [...] and share the one teacherIds alias, so a policy that also grants .ownerId == actor() still returns a classroom the teacher owns whose teacherIds lists the colleague. The element is the colleague and the owner branch holds. As written, a reader whose policy pairs ownership with membership will think the doc is wrong when that row comes back.
Non-blocking wording fix. It's not a regression; the same sentence is in the realm-policy-authoring §7 rewrite on the other open PR, so the two should change together.
There was a problem hiding this comment.
[Claude Code 🤖] Fixed in c882c1b (reflowed in 26f2cf1). The example now says the teacher finds none of the classrooms the membership grant admits, and that a classroom another of their query grants admits, such as one they own, is still found. The matching §7 sentence in #174 is with that PR's author.
…mits 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. This adds a paragraph to
card-operations-authoring, under "What a policy does to a search", for a limit a caller writing a search will hit. When the caller's filter and aquerygrant test the same path into a list, one element of the list must satisfy both. So a teacher whose grant reads.teacherIds | any(. == actor())finds no classroom by searchingteacherIdsfor a colleague. Conditions on different fields of a list's items are each met by any element.The index query engine shares one alias per path into a list, so both conditions test the same element. cardstack/boxel#6561 pins this with tests. The policy author's side of the same limit is in
realm-policy-authoring§7 in #174.Linear: CS-13344
🤖 Generated with Claude Code