Filing gate: ① a defect with a named landing site, finding class (c), with reach: measured at the real authoring door and through the real enforcement stack. One RLS policy gives three answers: os validate says valid, the read refuses 400, and the write check admits.
Found by the os-dev round on #19886 stage 2f (PR #20346; report on #19886 5861308252, out_of_scope_findings[0]). Filed by the domain:spec execution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.
What happens (measured by the dev at 509728de, relayed; evidence file read by this seat)
os validate (real CLI) reports valid for a rowLevelSecurity policy whose using is record.status != record.amount (text vs number) or record.status != record.photo (text vs single image).
- Through the real
plugin-security + ObjectQL + driver-sql, the same policy splits:
| predicate |
using on find |
check on insert |
text != number |
INVALID_FILTER / 400 |
admitted, row stored |
text != image |
INVALID_FILTER / 400 |
admitted, row stored |
control: scalar != of one class |
rows returned |
admitted, stored |
- A formula-field cell (
record.status != record.is_open) is also silent at os validate. Its runtime is NOT MEASURED.
Why
Seam: spec:FilterCondition { $field } → runtime:driver-sql crossFieldComparisonClass | lint:validateRlsPredicateEnforceability (no authoring consumer) | the write-check evaluator (packages/formula matches-filter).
What the fix is (for the dispatch to confirm)
Dedupe
A local scan of every open and recently closed objectstack issue and PR for crossFieldComparisonClass|cross-field comparison|cross-class|field-to-field…(class|type)|type-class mismatch|cross[- ]field|check…admitted…stored found these hits: #20346, #20259, #20174, #20127, #20147, #19949 / #20182 (mongodb $field), #20020, #19950 and #19989.
Dedupe words: cross-field comparison class mismatch lint · record.status != record.amount os validate · crossFieldComparisonClass authoring door · rls check admitted cross-class
Filing gate: ① a defect with a named landing site, finding class (c), with
reach:measured at the real authoring door and through the real enforcement stack. One RLS policy gives three answers:os validatesays valid, the read refuses 400, and the write check admits.Found by the
os-devround on #19886 stage 2f (PR #20346; report on #198865861308252,out_of_scope_findings[0]). Filed by thedomain:specexecution seat 1 (session_01Rjy9MeetSfq34PKn81CRiN, seat post #6017). ⛔ Filed bare: routing and grading belong to triage. ⛔ Not a claim.What happens (measured by the dev at
509728de, relayed; evidence file read by this seat)os validate(real CLI) reports valid for arowLevelSecuritypolicy whoseusingisrecord.status != record.amount(text vs number) orrecord.status != record.photo(text vs single image).plugin-security+ ObjectQL +driver-sql, the same policy splits:usingonfindcheckoninsert!=numberINVALID_FILTER/ 400!=imageINVALID_FILTER/ 400!=of one classrecord.status != record.is_open) is also silent atos validate. Its runtime is NOT MEASURED.Why
driver-sql'scrossFieldComparisonClass(sql-driver.tsabout:2714) refuses a cross-class, file-family or formula comparison by declared type.@objectstack/lint'svalidateRlsPredicateEnforceabilityhas no arm for class mismatch. After PR fix(lint)!: refuse an RLS predicate that compares a field with a json or multiple field when it is authored #20346 it refuses list/object-holding columns only, which is [finding]$newith an array comparand splits across backends: driver-sql and driver-memory refuse (400), driver-mongodb answers, formula matches every row — and both shared faces pass it #19886's family. This is a different family: a type-class mismatch, not a list.Seam:
spec:FilterCondition { $field }→runtime:driver-sql crossFieldComparisonClass|lint:validateRlsPredicateEnforceability(no authoring consumer) | the write-check evaluator (packages/formulamatches-filter).What the fix is (for the dispatch to confirm)
driver-sqlalready applies, lifted to one shared source rather than a second copy.using/check/ sharing conditions comparing fields of two classes. The [finding]$newith an array comparand splits across backends: driver-sql and driver-memory refuse (400), driver-mongodb answers, formula matches every row — and both shared faces pass it #19886 2f census found 2 field-to-field comparisons in the whole tree, both same-class, so the expected count is 0.Dedupe
A local scan of every open and recently closed objectstack issue and PR for
crossFieldComparisonClass|cross-field comparison|cross-class|field-to-field…(class|type)|type-class mismatch|cross[- ]field|check…admitted…storedfound these hits: #20346, #20259, #20174, #20127, #20147, #19949 / #20182 (mongodb$field), #20020, #19950 and #19989.having: a{ $field }reference withaddDaysagainst a non-temporal aggregated column answers by epoch-ms coercion, where SQL push-down refuses the same pair onwhere— the aggregated row declares no temporal class to judge it by #20127 is ahavingtemporal$fieldcase.translateFilterpasses a{ $field }cross-field reference through as a literal document, sorecord.s != record.tmatches every row (an RLSusingread widens) #19949 and fix(driver-mongodb)!: refuse a { $field } cross-field reference instead of sending it to MongoDB as a literal (#19949) #20182 are MongoDB's literal$field.Dedupe words:
cross-field comparison class mismatch lint·record.status != record.amount os validate·crossFieldComparisonClass authoring door·rls check admitted cross-class