fix(language): require an object on every tuple filter - #8
Merged
Merged
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Two moderate parser issues and one documentation nit remain unresolved.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR requires an object on every tuple filter and updates validation, documentation, tests, and fixtures accordingly.
Changes:
- Added object-required tuple-filter validation.
- Updated parser tests and example fixtures.
- Revised language documentation and specifications.
File summaries
| File | Summary |
|---|---|
rules_test.go |
Updated tuple-filter fixtures with objects. |
language/README.md |
Documents the object requirement; the exported GoDoc still needs updating (nit, 2 votes). |
language/parser.go |
Adds validation, but field-specific diagnostic positioning and concrete object format validation need changes (moderate, 1 vote each). |
language/parser_test.go |
Adds tests for object-required validation. |
docs/language-spec.md |
Updates tuple-filter syntax and constraints. |
Review details
Suppressed comments (2)
language/parser.go:523
- The new diagnostic is attached to the whole filter item rather than the missing field:
Fieldpoints at.object, butPositionresolvesfilterLookupwithout the.objectsuffix. This makes source-aware consumers highlight the list entry instead of the object field; use the same field-specific lookup as the other tuple-field validations.
Position: nodePosition(resolveNodePath(root, filterLookup)),
language/parser.go:519
- This only checks that the YAML value is non-empty, so a static filter such as
object: org(orobject: 123) still compiles even though it has notype:idobject type and will be rejected when the consumer sends the Read request. The new contract and error text say the value must provide at least an object type prefix; please validate concrete object values against that format (and add a regression test), while retaining a separate path for dynamic templates.
if f.Object == "" {
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ewanharris
approved these changes
Sep 10, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sergiught
force-pushed
the
fix-language
branch
from
September 10, 2026 14:40
41905df to
de31c27
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.
Description
A
tuple_filtersentry that setuserand/orrelationbut leftobjectempty used to pass mapping validation and integration save, then fail every FGA Read at runtime. FGA's Read API needs an object type (the id may be empty, the type may not), so a filter with no object can never match. The failure was worse than one broken rule:readAllreturns on the first failed read, so a single object-less filter also discards the writes of unrelated valid rules that matched the same event.This is statically detectable, so the check moves to validation.
validateTupleFiltersnow rejects any filter with noobject, names the rule and the field, and tells the author to set at least a type prefix likedocument:. The error surfaces fromvalidate,test, and integration save rather than only appearing as a failed Read against a live store.The old "at least one field set" check is replaced, not kept alongside: object-required subsumes it and the old message would now point authors in the wrong direction. The separate
expect_tuple_filtersmatcher keeps its own "at least one field" rule, since that is a partial matcher for tests, not an FGA read.Two shipped example mappings relied on the now-rejected pattern in their delete filters, so
user.yamlandgroup.yamlgained an object type prefix (user:,group:) plus the matchingexpect_tuple_filters.References
Review Checklist
main