docs(spec): state the RLS using grammar by what pushes down, not by a count (#6919) - #7444
Conversation
… a count (#6919) The TSDoc block above `RowLevelSecurityPolicySchema`'s `using` property still claimed "Exactly four forms compile" and "no support for ... comparison operators other than `=`". That contradicted the `.describe()` on the SAME property (corrected in #6762 / PR #6918) and it contradicted the compiler. Measured against `isSupportedRlsExpression` (`@objectstack/formula`, `src/rls-predicate.ts`) at 07383fe: `!=` and the full ordering comparisons, `in` over a `current_user.*` array AND over an inline CEL list literal, string `startsWith`/`endsWith`/`contains`, `&&`, `||`, parenthesised grouping, and a bare `true` all lower to a filter and enforce. SQL `AND`/`OR`/`NOT`, `NOT IN`, `IS NULL`, `LIKE`, regex, arithmetic, subqueries, cross-object traversal and a bare truthy field all fail closed. Rewritten in terms of the forms that push down, with no count anywhere — replacing "four" with the current number would be the same defect. Canonical CEL leads; the SQL spelling is stated as the deprecated transitional bridge it is (`sqlPredicateToCel`, ADR-0058 D1), covering only `=` -> `==` and `IN` -> `in`. The `⚠️ STALE` marker PR #6918 parked on the block is removed with the rewrite. The property's five `@example` strings, all SQL dialect, are now CEL. Two boundaries the old prose got wrong in the permissive direction are now explicit, both silent fail-closed traps: SQL's parenthesised value list does not survive the bridge (`status IN ('draft', 'pending')` fails closed, where `status in ['draft', 'pending']` lowers), and `!` negates a parenthesised comparison but cannot negate a bare field. Adds `rls-predicate-grammar-docs.pin.test.ts`: the file states this grammar on three faces — the published module docblock line, the property TSDoc, and the property's `.describe()` — and nothing compared them, which is how the same under-statement drifted twice. The pin holds all three to one story: no face may re-assert a fixed-count or closed-set grammar, all must keep stating the fail-closed contract, and the two operator-listing faces must name the same operator set. Scope is the claim shape, not the wording. No generated output changes: `gen:docs` never renders property-level TSDoc, so `check:docs` reports all 231 files still in sync. Fixes #6919 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016XdGuLGuJaDfQidXjbU7wJ
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
Fixes #6919
The TSDoc block above
RowLevelSecurityPolicySchema'susingproperty still claimed "Exactly four forms compile" and "no support for ... comparison operators other than=". That contradicted the.describe()on the SAME property (corrected in #6762 / PR #6918) and it contradicted the compiler.Measured against
isSupportedRlsExpression(@objectstack/formula,src/rls-predicate.ts) at07383fe:!=and the full ordering comparisons,inover acurrent_user.*array AND over an inline CEL list literal, stringstartsWith/endsWith/contains,&&,||, parenthesised grouping, and a baretrueall lower to a filter and enforce. SQLAND/OR/NOT,NOT IN,IS NULL,LIKE, regex, arithmetic, subqueries, cross-object traversal and a bare truthy field all fail closed.Rewritten in terms of the forms that push down, with no count anywhere — replacing "four" with the current number would be the same defect. Canonical CEL leads; the SQL spelling is stated as the deprecated transitional bridge it is (
sqlPredicateToCel, ADR-0058 D1), covering only=→==andIN→in. The⚠️ STALEmarker PR #6918 parked on the block is removed with the rewrite. The property's five@examplestrings, all SQL dialect, are now CEL.Two boundaries the old prose got wrong in the permissive direction are now explicit, both silent fail-closed traps: SQL's parenthesised value list does not survive the bridge (
status IN ('draft', 'pending')fails closed, wherestatus in ['draft', 'pending']lowers), and!negates a parenthesised comparison but cannot negate a bare field.Adds
rls-predicate-grammar-docs.pin.test.ts: the file states this grammar on three faces — the published module docblock line, the property TSDoc, and the property's.describe()— and nothing compared them, which is how the same under-statement drifted twice. The pin holds all three to one story: no face may re-assert a fixed-count or closed-set grammar, all must keep stating the fail-closed contract, and the two operator-listing faces must name the same operator set. Scope is the claim shape, not the wording.No generated output changes:
gen:docsnever renders property-level TSDoc, socheck:docsreports all 231 files still in sync.Generated by Claude Code